pax_global_header00006660000000000000000000000064141645473200014520gustar00rootroot0000000000000052 comment=c78557118d2aed9415be36e6eef6adfa922d753d Eqonomize-1.5.3/000077500000000000000000000000001416454732000134745ustar00rootroot00000000000000Eqonomize-1.5.3/.gitignore000066400000000000000000000000651416454732000154650ustar00rootroot00000000000000build/* Makefile *.qm changes eqonomize .qmake.stash Eqonomize-1.5.3/.travis.yml000066400000000000000000000021161416454732000156050ustar00rootroot00000000000000language: cpp compiler: gcc sudo: require dist: trusty before_install: - sudo add-apt-repository ppa:beineri/opt-qt-5.10.1-trusty -y - sudo apt-get update -qq install: - sudo apt-get -y install qt510base qt510charts-no-lgpl - source /opt/qt*/bin/qt*-env.sh script: - qmake CONFIG+=release COMPILE_RESOURCES=yes INSTALL_THEME_ICONS=no PREFIX=/usr - lrelease Eqonomize.pro - make -j$(nproc) - make INSTALL_ROOT=appdir -j$(nproc) install ; find appdir/ - wget -c "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" - chmod a+x linuxdeployqt*.AppImage - unset QTDIR; unset QT_PLUGIN_PATH; unset LD_LIBRARY_PATH - ./linuxdeployqt*.AppImage ./appdir/usr/share/applications/*.desktop -bundle-non-qt-libs - ./linuxdeployqt*.AppImage ./appdir/usr/share/applications/*.desktop -appimage after_success: - find ./appdir -executable -type f -exec ldd {} \; | grep " => /usr" | cut -d " " -f 2-3 | sort | uniq - mv Eqonomize*.AppImage Eqonomize.AppImage - curl -F "file=@./Eqonomize.AppImage" https://file.io Eqonomize-1.5.3/AUTHORS000066400000000000000000000000571416454732000145460ustar00rootroot00000000000000Hanna Knutsson Eqonomize-1.5.3/COPYING000066400000000000000000001045131416454732000145330ustar00rootroot00000000000000 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 . Eqonomize-1.5.3/ChangeLog000066400000000000000000001065421416454732000152560ustar00rootroot000000000000002022-01-02 Hanna Knutsson * Fix compilation errors with Qt 6 2021-12-23 Hanna Knutsson * Dark mode option in settings menu * If category is empty in CSV file row, use "Uncategorized" as name * Fix empty/missing category (in CSV file) error message 2021-11-05 Hanna Knutsson * Add extra space between after right aligned values in lists * Add option to left align values in lists 2021-09-10 Hanna Knutsson * Fix tab focus for dialog buttons 2021-09-04 Hanna Knutsson * Fix "Ignore duplicate transactions" for reinvested dividend when importing eqz file 2021-09-03 Hanna Knutsson * Fix saving of scheduled reinvested dividend * Disable join and edit actions when one of multiple selected transactions is a reinvested dividend 2021-07-30 Hanna Knutsson * Fix importing of data format YYYYMMDD and improve support for six character date formats without separator * Use a multiple lines for comments field in dialogs * Clear edit fields after modification of transaction in list * Preserve position and current item after update of ledger 2021-03-18 Hanna Knutsson * Remove total security rate value * Fix security rate for future dates 2021-03-17 Hanna Knutsson * Fix segfault with scheduled security transaction without recurrence 2021-01-07 Hanna Knutsson * Fix handling parentheses when calculating expression in value entry * Fix initial state of "Bank" entry when initial account type is not "Cash" 2020-12-14 Hanna Knutsson * Danish translation (from Tag Valdemar) 2020-12-10 Hanna Knutsson * Open ledger on account double click regardless of column 2020-08-30 Hanna Knutsson * Allow separate comments for each transaction in an expense/income with multiple accounts/payments * Add payee/payer column to dialog for transaction with multiple accounts/payments * Add payee/payer field to refund/repayment dialog 2020-08-12 Hanna Knutsson * Fixes for reccuring transactions with multiple accounts/payments 2020-08-11 Hanna Knutsson * Use actual text width to determine if description fits in "part of split" label 2020-08-02 Hanna Knutsson * Fix segfault when syncing unsaved file * Fix window title with empty file 2020-07-30 Hanna Knutsson * Fix importing if split transactions from eqz file 2020-07-26 Hanna Knutsson * Fix recurrence on day of year * Stop after 100 years when searching for previous or next monthly occurrence * Remove fifth last week of month option 2020-07-20 fabianski7 <47755037+fabianski7@users.noreply.github.com> * Portuguese (Brazil) translation 2020-07-20 Hanna Knutsson * Change "Quantity" to "Returned quantity" in refund dialog 2020-07-19 Hanna Knutsson * Support for links between transactions 2020-07-14 Hanna Knutsson * Option to join refund to original transaction (as transaction with multiple payments) * Split up option for transactions with multiple payments * Merge associated files when joining transactions * Join transaction as transaction with multiply payments when appropriate (ask when uncertain) 2020-07-13 Hanna Knutsson * Make the "part of split" label clickable 2020-07-07 Hanna Knutsson * Add a man page * Replace code deprecated in Qt 5.15 2020-04-18 Hanna Knutsson * Fix segfault in categories comparison report with payee and quantity properties are hidden 2020-04-13 Hanna Knutsson * Fix monthly recurrence with end date (or occurrence count), when year of end date and start date differs * Expand parent category after creation of new sub category * Fix segfault when opening file after creating a new sub category 2020-03-20 Hanna Knutsson * Fix order of transactions in ledger when split transaction has same date as single transaction 2020-02-04 Hanna Knutsson * Do not change account group when type is selected if custom group is set 2019-09-01 Hanna Knutsson * Fix segfault when editing a scheduled transaction (primarily with current date) present in the expenses, incomes and/or transfers view 2019-08-24 Hanna Knutsson * Make it possible to select multiple categories, tags, accounts, descriptions, and payees/payers in categories and report 2019-08-19 Hanna Knutsson * Option to display absolute values instead of percent in pie chart 2019-08-17 Hanna Knutsson * Security quotes import and export, in quotes dialog * Ctrl + Home shortcut in date fields, and Home shortcut and context menu item in calendar popup, for current date selection 2019-08-13 Hanna Knutsson * Fix set single transaction in edit widget for transaction with multiple accounts/payments and multiple currencies 2019-08-06 Hanna Knutsson * Save import CSV settings as presets * Show name with parent name for categories in CSV import dialog 2019-08-05 Hanna Knutsson * Allow fixed category (add income category selection) when importing both expenses and incomes from CSV file 2019-06-16 Hanna Knutsson * Allow translation of key Qt strings (OK, Cancel, etc.), when Qt translation is not available for a language 2019-06-15 Hanna Knutsson * Do not show "from date is after to date" and similar messages (pick an appropriate to date instead) * Icons for all menu items * Load Qt translations when selecting a specific language 2019-06-13 Hanna Knutsson * Wrap around (with month/year change) support for days and months in date fields * Change month or year on page up/down in day or month section of date field * Fixes month conversion when first month of budget year is not 1 2019-06-11 Hanna Knutsson * Focus transaction list when opening ledger with selected account 2019-06-06 Hanna Knutsson * Tags 2019-06-04 Hanna Knutsson * Option to show categories as columns in over time report 2019-06-01 Hanna Knutsson * Duplicate transaction option * Show lists as focused when not focused (fixes color of selected transaction) and allow moving in lists with keyboard in some cases when not focused 2019-05-30 Hanna Knutsson * Show tooltips for cut off text in lists * Configurable visible columns for expenses, incomes and transfers views * Fix row colors for reconciled items ledger when not reconciling 2019-05-27 Hanna Knutsson * Preserve order of imported transactions (with equal date) * Timestamp edit dialog 2019-05-24 Hanna Knutsson * Custom account groups * Hide group if all accounts are in the same group * Fix account group change color 2019-05-22 Hanna Knutsson * Improved account/category combo box searching 2019-05-20 Hanna Knutsson * Option to show separate months or years in categories comparison report * Make ledger behave as a non-modal window instead of modal dialog * Search in ledger * Make it possible to select multiple associated files * Add option to sort ledger ascending 2019-05-19 Hanna Knutsson * Fix assets and liabilities total in over time report * Fix segfault when editing reinvested dividend without income category 2019-05-18 Hanna Knutsson * Show icon when transaction has associated file * Update save state when associated file selected 2019-05-02 Hanna Knutsson * Font selection 2019-04-29 Hanna Knutsson * Fix updating of account values when a scheduled transaction has been edited in dialog and changed to a non-scheduled transaction 2019-04-26 Hanna Knutsson * Fix segfault in over time chart with no accounts * Fix segfault in ledger with no accounts * Fix Ctrl+Q shortcut 2019-04-25 Hanna Knutsson * Do not show guesstimate for future security values in accounts view (but use estimate for values between quotes) * Fix calculation of quote between recorded security quotes * Button for clearing values in new/edit transaction 2019-04-23 Hanna Knutsson * Fix updating of account values when a transaction has been edited in dialog and posponed to future date * Fix segfault when transaction is split up 2019-04-21 Hanna Knutsson * Group assets and liabilities with the same type in accounts view 2019-04-06 Hanna Knutsson * Use localeconv() for number format (improves sign and currency symbol placement, and fixes locales where number format differs between general and monetary numbers) 2019-04-05 Hanna Knutsson * Use dot as alternative decimal separator for locales with decimal comma and without dot as group separator 2019-03-01 Hanna Knutsson * Language selection from within the application 2019-02-18 Hanna Knutsson * Do not use deprecated QtCharts axis functions 2019-02-02 Hanna Knutsson * Schedule confirmation time setting 2019-01-30 Hanna Knutsson * Fix filter min and max currency * Fix crash on CSV import of quoted value containing delimiter 2019-01-15 Hanna Knutsson * Update revision of schedule on confirmed occurrence 2019-01-14 svedie * Improved German translation 2019-01-05 Hanna Knutsson * Description of eqz file format 2019-01-16 Michael F. Schönitzer * Some German translation improvements 2018-11-14 Hanna Knutsson * Make eqz-file parsing more flexible (do not require transaction type, accept value property for expenses and incomes, allow to/from instead of category propery, etc.) * Timestamp in seconds instead of microseconds 2018-11-01 Hanna Knutsson * Better handling of unknown transaction or category type encountered in file 2018-11-01 Hanna Knutsson * Budget day fixes 2018-10-31 Hanna Knutsson * Option to specify first budget month of year (financial year) 2018-10-07 Hanna Knutsson * Fix saving of recurring expense with multiple payments * Remove recurrence tab from expense paid with loan dialog * "Payed" => "Paid" 2018-09-11 Hanna Knutsson * Improved Enter/Return key actions and input focus 2018-09-06 Hanna Knutsson * Option to sort transactions by timestamp (in header context menu) 2018-09-05 Hanna Knutsson * Select whole number on double click in value field * Scroll to added/modified transaction 2018-08-04 Hanna Knutsson * Add comments field to split transaction dialog 2018-07-22 Nils VAN ZUIJLEN * Added translations for French 2018-06-20 Hanna Knutsson * Fix value field conversion with dollar sign 2018-06-12 Hanna Knutsson * Fix last date in yearly assets and liabilities bar chart hover info 2018-06-10 Hanna Knutsson * Fix categories comparison report description selection list * Fix Qt Charts < 5.7.0 compability 2018-06-09 Hanna Knutsson * Use mycurrency.net html instead of the json data, which has not been for a month 2018-06-08 Hanna Knutsson * Never show more than nine slices in pie chart and combine very small category posts * Set spacing between bars to half the bar width (unless many bars in groups) * Reverse order of horizontal bar chart * Many minor chart fixes/improvements (especially without Qt Charts) 2018-06-07 Hanna Knutsson * Add new default chart theme * Use the same color for all bars in categories comparison bar chart, show x-axis labels, and remove vertical bar chart * Use budgeted values for more over time chart data * Allow user to set last month for yearly value in over time chart * Sort categories and accounts using total value and hide categories with zero value in charts * Yearly "Assets and Liabilies" bars * Add "Edit Account" button to ledger * Show incomes and expenses in profit report 2018-06-04 Hanna Knutsson * Alternative to show all accounts separately in the same over time chart * Disable "Close Account" for accounts with no associated transactions 2018-06-03 Hanna Knutsson * Account filter in charts and reports * Assets & Liabilities in over time report 2018-05-17 Hanna Knutsson * Add flags to currency lists 2018-04-26 Hanna Knutsson * Allow value field conversion using $, £, €, ¥, and local currency symbol, even if not default currency 2018-04-15 Fabian Wolff * Remove deprecated Encoding key from the .desktop file * Bump DocBook version 2018-04-01 Fabian Wolff * Fix spelling errors involving "recurrance" and "occurrance" 2018-02-03 Hanna Knutsson * Case insensitive descriptions and payees in charts report 2018-02-01 Hanna Knutsson * Cloud synchronization 2018-01-14 Hanna Knutsson * Annual total for over time chart 2018-01-13 Hanna Knutsson * Restore possibility to specify payee/payer for each separate transaction in a split transaction 2018-01-09 Hanna Knutsson * Fix debt payment value edits behavior 2018-01-06 Hanna Knutsson * Include subcategories in over time report * Option to merge changes when saving a file that has been modified after saving/loading * Id, first revision and last revision transaction, account and security properties, and revision and last id file properties 2017-12-30 Hanna Knutsson * "All payees/payers" in categories comparison report 2017-12-27 Hanna Knutsson * Only assume negative income/expense if the category is defined in the QIF file 2017-12-18 Hanna Knutsson * Fix editing of transfer part of split transaction * Fix split transaction account selection when joining transfers * Set split values from input fields when clicking "Edit..." in a transactions view * Fix segfault on export of transaction with multiple accounts/payments 2017-12-17 Hanna Knutsson * Allow account creation from loan payment dialog * Update logic for when confirm schedule dialog is shown or transaction is automatically added when scheduled transaction is added/edited 2017-12-15 Hanna Knutsson * Allow account creation from edit security dialog 2017-12-15 Hanna Knutsson * Allow security creation from security transactions dialog 2017-12-14 Hanna Knutsson * Remember state of set quote checkbox * Fix segfault on edit multiple transactions from ledger * Show statistics for selection in ledger * Calculate average balance correctly 2017-12-13 Hanna Knutsson * Set last used category/account for new transaction dialogs * Ledger popup menu * Add warning message to adjust balance dialog 2017-12-09 Hanna Knutsson * Reconciliation 2017-12-08 Hanna Knutsson * Ledger list header popup menu to show/hide type, account/category, payee/payer and comments columns * Revised reinvested dividends 2017-10-26 Hanna Knutsson * Fix sum in categories comparison report with subcategories * Fix categories comparison chart for incomes with subcategories 2017-10-24 Hanna Knutsson * Fix "All Incomes, without subcategories" in categories comparison chart 2017-10-23 Hanna Knutsson * Fix crash when trying to create new debt payment without any debt (possible fix for issue #33) * Do not allow zero value for new loan 2017-10-18 Hanna Knutsson * Fix account value when joining transactions with different accounts 2017-10-16 Hanna Knutsson * Add close account menu item and add extra warning text in delete account dialog (related to issue #32) 2017-10-11 Hanna Knutsson * List income/expense categories for shares bough/sold in addition to accounts * Manual completed 2017-10-10 Hanna Knutsson * Check for new versions 2017-10-09 Hanna Knutsson * Exchange rates from mycurrency.net (more than 100 additional currencies) 2017-10-08 Hanna Knutsson * Eqonomize! file import alternatives for duplicates handling * Fix assets and liabilities line chart months * Set black text color for line chart hover box * Set currency in budget edit field to main currency * Use parent category of subcategory as default parent when creating new account from context menu 2017-10-05 Hanna Knutsson * Fix crash when account with associated transactions is remove 2017-10-04 Hanna Knutsson * Do not allow negative debt value in new loan dialog 2017-09-04 Hanna Knutsson * Fix new currency does not appear in the currency converter after application reopened (part of issue #27) * Fix new currency dialog reopens when creating new currency from set main currency dialog 2017-07-21 Hanna Knutsson * Support for parentheses for calculation in input fields 2017-07-20 Hanna Knutsson * Show statistics for selected transactions (if more than one is selected) 2017-07-07 Hanna Knutsson * Batch editing of date and payee/payer of split transactions * CSV import dialog layout fixes * Fix import of expenses from CSV files with separate columns for cost and income 2017-07-05 Hanna Knutsson * Fix reading of negative values and values beginning with decimal separator during CSV import * Fix the CSV import date/number format dialog * Fix import of expenses when importing all types of transactions from CSV file * Fix reading of year with less than four digits in CSV or QIF file 2017-06-25 Hanna Knutsson * Remove blank space at beginning and end of payee/payer, comments, etc. 2017-06-01 Hanna Knutsson * Fix payee lost when split transaction copied (affects scheduled split transactions) 2017-05-21 Hanna Knutsson * Fix account list html export (and print preview) 2017-04-25 Hanna Knutsson * Italicize scheduled transactions in expenses, incomes and transactions lists 2017-04-07 Hanna Knutsson * Security transactions enhancements and fixes 2017-04-02 Hanna Knutsson * Account drag and drop fixes 2017-03-23 Hanna Knutsson * Import/merge Eqonomize! files 2017-03-21 Hanna Knutsson * Add timestamp property for transactions to be able to consistently sort transactions in the order they were added 2017-03-21 Hanna Knutsson * Artithmetic expression and currency conversion in input fields (spin boxes) * Currency converter * "Associated file" transaction property 2017-03-18 Hanna Knutsson * Support multiple currencies 2017-01-25 Hanna Knutsson * Fix text editing in filter, reset selection on filtering and focus description entry when changing edit/filter tab 2016-09-30 Hanna Knutsson * Fix text colors and background of top level items in account tree * Enhance visibility of icons with dark theme 2016-09-06 Hanna Knutsson * Fix yearly recurrence 2016-09-05 Hanna Knutsson * Fix and enhance exceptions dialog 2016-09-01 Hanna Knutsson * Fix include subcategories in filtering and remove the button for transfers and when extra properties is disabled (for improved layout) * Remove quantity from incomes edit * Add tooltip to description and quantity * Fix not all transactions being listed in confirm schedule dialog 2016-08-29 Hanna Knutsson * Fix charts withput extra properties * Fix charts without QtCharts 2016-08-25 Hanna Knutsson * Fix value column in multi-account transaction dialog * Fix multiple duplicate completion items when removing, than adding transaction with unique description * Use extra properties by default 2016-08-24 Hanna Knutsson * Place "All" last in export QIF dialog account combo (it is not a appropriate default option) * Common payee/payer for multi item transactions 2016-08-21 Hanna Knutsson * Import/export sub categories from/to QIF files 2016-08-16 Hanna Knutsson * Import sub categories, payees and quantity from CSV files 2016-08-15 Hanna Knutsson * Autocomplete transaction also when selecting category or payee 2016-08-14 Hanna Knutsson * Loans, multi account transactions, scheduled split transactions, debt payments, etc. * Bold summary/parent items with icons in account view 2016-07-08 Hanna Knutsson * Export transactions to CSV file with a more compatible number format 2016-07-06 Hanna Knutsson * Assets over time chart * Show expenses as negative values in stacked bar chart for incomes and expenses 2016-07-05 Hanna Knutsson * Completely remove dependency on Qt Xml by using QXmlStreamWriter instead of QDom* * Colors for securities 2016-07-04 Hanna Knutsson * Create new account/category from selection combo box * Fix crash when deleting all transactions with a particular description and then adding a new * Colored values in lists * Do not show negative values in pie chart and hide zero values in category comparison charts * Add missing label in edit expense category dialog * Set minimum width for empty lists 2016-07-03 Hanna Knutsson * New Chart types 2016-07-02 Hanna Knutsson * Custom budget month start 2016-07-01 Hanna Knutsson * Use QtCharts 2016-06-29 Hanna Knutsson * Subcategories * New Icons 2016-06-28 Hanna Knutsson * File backups * Backup frequency option 2016-06-27 Hanna Knutsson * Fix copying to backup '~' file (remove existing file first) 2016-06-26 Hanna Knutsson * Move cursor to day in dates 2016-06-25 Hanna Knutsson * Move from QDom* in Qt Xml to QXmlStreamReader 2016-06-23 Hanna Knutsson * List layout enhancements and save/restore state of lists * Simplify and enhance EqonomizeValueEdit (restrictions of KDoubleSpinBox removed) 2016-06-22 Hanna Knutsson * New icons * File save handling fixes 2016-06-21 Hanna Knutsson * Fix csv import of categories * Decimals in quotations option and set default decimals in shares from previous securities * Make chart and report non-modal again * Initialize locale to fix number of decimal signs and currency placement 2016-06-20 Hanna Knutsson * Print preview 2016-06-19 Hanna Knutsson * Chart/report dialog layout enhancements * Max 10 descriptions in categories chart and 6 items in over time chart 2016-06-18 Hanna Knutsson * New Icons 2016-06-16 Hanna Knutsson * Remove all KDE dependencies and use qmake instead of CMake 2016-06-14 Hanna Knutsson * Make sure save filename ends with ".eqz" * Fix "scheduled operations don't go further than next year if range is other than 'no end'" * Search whole description and payer/payee when filtering and add exact match option 2014-07-21 Hanna Knutsson * Restore remote file access 2014-07-11 Hanna Knutsson * Port to Qt 5 and KDE Framework 5 * Minor accumulated enhancements and fixes 2009-07-03 Hanna Knutsson * Fix transaction not added on date edit enter (missing signal) * Fix csv export (change text/x-csv to text/csv) 2008-11-12 Hanna Knutsson * KDE4 version commited 2008-03-04 Hanna Knutsson * Fix mysterious crash when two scheduled transactions have the same date and description 2007-08-20 Hanna Knutsson * Fix saving of weekly recurrence 2007-07-30 Hanna Knutsson * Fix positive net result of split transaction displayed in wrong column 2007-05-04 Hanna Knutsson * Fix calculation of scheduled transactions after a scheduled transaction has been confirmed * Fix calculation of scheduled transaction after the date has changed to before the current date * Sort scheduled transactions list after date changes * Fix security transaction joining 2007-03-30 Hanna Knutsson * Allow user to select initial period * Do not limit sold shares to current number of shares * Fixes for the new value input widget 2007-03-29 Hanna Knutsson * Keep permissions of exisiting files 2007-03-28 Hanna Knutsson * Make it possible to join security transactions and add ability to create new security transaction from edit split dialog * Do not require a selected security to be able to create a security transaction and make it possible to change security from edit transaction dialogs * Execute different actions when double clicking on security row depending on clicked column 2007-03-26 Hanna Knutsson * Future statistics in over time chart 2006-11-28 Hanna Knutsson * New value input with support for zero decimals 2006-11-27 Hanna Knutsson * Spanish and Italian translations * Update French translations * Some bug fixes 2006-10-22 Hanna Knutsson * Fix "Edit..." button for split transaction in list * Show extra properties when editing transaction from split transaction edit dialog 2006-10-07 Hanna Knutsson * Reset quantity to 1.0 2006-09-19 Hanna Knutsson * Fix balancing 2006-09-03 Hanna Knutsson * Manual updates * Minor polishing 2006-09-02 Hanna Knutsson * Updated icons 2006-09-01 Hanna Knutsson * German translation (Martin F. Hohenberg , Elias Probst ) * Update cvs.sh for autoconf 2.6 * Fix de.po 2006-08-27 Hanna Knutsson * Miscellaneous fixes * Postpone option in confirm schedule dialog * Manual updates * Close confirm schedule dialog if no transactions are left 2006-08-22 Hanna Knutsson * QIF export fixes * Handle non-standard (local) QIF type names * Fix QIF import and export of splits * Update Swedish translation * Updated french translation (Jérôme Rapinat , Antoine Rodriguez ) * Minor fixes and polishing 2006-08-21 Hanna Knutsson * QIF import of securities * Securities type "Other" * QIF export * Require unique and non-empty names for accounts of the same type * Fix crash when selecting initial balance item in ledger dialog * Fix and extend date update when current date changes 2006-08-20 Hanna Knutsson * Enhanced splits * Join and split up actions * Enhanced account ledger * Possibility to specify price of share separately, so the total cost/income can include fees * Add quantity input to refund/repayment dialog * Add percents to legend texts and decrease margins in categories comparison chart * QIF import of splits 2006-08-19 Hanna Knutsson * Splits 2006-08-18 Hanna Knutsson * Add comments entry to refund/repayment dialog 2006-08-17 Hanna Knutsson * Refunds and repayments * Enhanced date and number format handling for csv import * Enhanced QIF import * Ask save on quit (use close() instead of kapp->quit()) 2006-08-16 Hanna Knutsson * Update securities when account has been deleted * Auto-save with crash recovery * Fix crash when removing account with security transactions * Backup on save * Add do not ask again option to save? dialog on exit * Revert menu item 2006-08-15 Hanna Knutsson * Continue QIF import work * Account ledger dialog * Fix balancing crash when to date is in the same month as but before current date * Switch securities and accounts period to date to current date if date changes and to date was current date * Fix move to account selection 2006-08-14 Hanna Knutsson * Update change column when transaction added or changed * Fix changing date of transaction with future date 2006-08-13 Hanna Knutsson * Work on QIF import begun * Updated french translation (Jérôme Rapinat ) * French manual (Jérôme Rapinat ) * Use pow(10, x) instead of exp10(x) * Fix crash with no from date in accounts view and empty (or no) accounts 2006-08-11 Hanna Knutsson * French translation (Jérôme Rapinat ) * Alternative for credit and debit in different columns * Auto first row option for csv import * More flexible value and date reading in csv file * Miscellaneous... 2006-08-08 Hanna Knutsson * Begin documentation * Add option to show Profits line in over time chart 2006-08-07 Hanna Knutsson * i18n fixes * Finish Swedish translation 2006-08-04 Hanna Knutsson * Fix calculation of remaining budget when from date is after current date * Display as previous budget result the result for the month before selected month 2006-08-03 Hanna Knutsson * Use button menus for period selection, schedule buttons, and security transactions * Move next/previous year/month buttons up in accounts view * Payees/payers for over time chart 2006-08-02 Hanna Knutsson * Change focus order to put quantity after value * Call layout() for KButtonBox 2006-07-31 Hanna Knutsson * Use quantity instead of count * Replace "Daily" with "Average" statistic * Fix resizing issues * More flexible reports 2006-07-30 Hanna Knutsson * More flexible charts * Optional Payee/Payer and Quantity parameters for expenses/incomes 2006-07-29 Hanna Knutsson * Budget edit tab in accounts view * Select period combo * By default set to date to current date * Lots more... 2006-07-27 Hanna Knutsson * Normally do not show incomplete months (possibly first and current) in development over time report * Ability to set budget separately for each month * Budget account property for accounts * Show budgeted value (if greater than scheduled transactions) for future value and change of accounts 2006-07-26 Hanna Knutsson * Add option to compare accounts in categories comparison chart 2006-07-25 Hanna Knutsson * Work around Hebrew, Hijri and Jalali addMonths() bug * Check length of month names * Fix calculation of total change for securities accounts * Fix checking of todays schedule 2006-07-24 Hanna Knutsson * Change name to Eqonomize! * Make report and chart dialogs non-modal * Month selector instead of date edit for over time chart * Only confirm scheduled transactions occurring the current date if time is after 18.00 * Some bug and tweaks fixes 2006-07-23 Hanna Knutsson * Categories comparison chart * Over time chart * Don't use "words" in date picker popup as future dates is not very useful 2006-07-22 Hanna Knutsson * Use KCalenderSystem everywhere and avoid assumptions based on the gregorian calendar * Add some more valid recurrence checks * Security trade (buy and sell in the same transaction) 2006-07-21 Hanna Knutsson * Use comma as delimiter and put values in quotes, when saving csv file * Import of CSV files 2006-07-20 Hanna Knutsson * "Development Over Time" and "Categories Comparison" reports 2006-07-19 Hanna Knutsson * Add daily average to transactions statisitcs * Printing Eqonomize-1.5.3/Eqonomize.pro000066400000000000000000000323551416454732000161740ustar00rootroot00000000000000VERSION = 1.5.3 isEmpty(PREFIX) { PREFIX = /usr/local } isEmpty(DESKTOP_DIR) { DESKTOP_DIR = $$PREFIX/share/applications } isEmpty(DESKTOP_ICON_DIR) { DESKTOP_ICON_DIR = $$PREFIX/share/icons } equals(INSTALL_THEME_ICONS,"no") { DEFINES += LOAD_EQZICONS_FROM_FILE=1 } unix:!equals(COMPILE_RESOURCES,"yes"):!android:!macx { isEmpty(DOCUMENTATION_DIR) { DOCUMENTATION_DIR = $$PREFIX/share/doc/eqonomize/html } isEmpty(TRANSLATIONS_DIR) { TRANSLATIONS_DIR = $$PREFIX/share/eqonomize/translations } isEmpty(DATA_DIR) { DATA_DIR = $$PREFIX/share/eqonomize } isEmpty(MIME_DIR) { MIME_DIR = $$PREFIX/share/mime/packages } isEmpty(ICON_DIR) { equals(INSTALL_THEME_ICONS,"no") { ICON_DIR = $$PREFIX/share/eqonomize/icons } else { ICON_DIR = $$PREFIX/share/icons } } } else { TRANSLATIONS_DIR = ":/translations" ICON_DIR = ":/icons" DATA_DIR = ":/data" DOCUMENTATION_DIR = ":/doc/html" DEFINES += RESOURCES_COMPILED=1 } isEmpty(MAN_DIR) { MAN_DIR = $$PREFIX/share/man } TEMPLATE = app TARGET = eqonomize INCLUDEPATH += src CONFIG += qt QT += widgets network printsupport !equals(DISABLE_QTCHARTS,"yes"):!equals(ENABLE_QTCHARTS,"no") { qtHaveModule(charts) { QT += charts } else { warning("Qt Charts module is missing") } } else { equals(DISABLE_QTCHARTS,"no"):!equals(ENABLE_QTCHARTS,"yes") { QT += charts } } MOC_DIR = build OBJECTS_DIR = build DEFINES += TRANSLATIONS_DIR=\\\"$$TRANSLATIONS_DIR\\\" DEFINES += DOCUMENTATION_DIR=\\\"$$DOCUMENTATION_DIR\\\" DEFINES += DATA_DIR=\\\"$$DATA_DIR\\\" DEFINES += ICON_DIR=\\\"$$ICON_DIR\\\" DEFINES += VERSION=\\\"$$VERSION\\\" HEADERS += src/account.h \ src/accountcombobox.h \ src/budget.h \ src/categoriescomparisonchart.h \ src/categoriescomparisonreport.h \ #src/currencies.xml.h \ src/currency.h \ src/currencyconversiondialog.h \ src/editaccountdialogs.h \ src/editcurrencydialog.h \ src/editscheduledtransactiondialog.h \ src/editsplitdialog.h \ src/eqonomize.h \ src/eqonomizelist.h \ src/eqonomizemonthselector.h \ src/eqonomizevalueedit.h \ src/importcsvdialog.h \ src/ledgerdialog.h \ src/overtimechart.h \ src/overtimereport.h \ src/qifimportexport.h \ src/recurrence.h \ src/recurrenceeditwidget.h \ src/security.h \ src/transaction.h \ src/transactioneditwidget.h \ src/transactionfilterwidget.h \ src/transactionlistwidget.h SOURCES += src/account.cpp \ src/accountcombobox.cpp \ src/budget.cpp \ src/categoriescomparisonchart.cpp \ src/categoriescomparisonreport.cpp \ src/currency.cpp \ src/currencyconversiondialog.cpp \ src/editaccountdialogs.cpp \ src/editcurrencydialog.cpp \ src/editscheduledtransactiondialog.cpp \ src/editsplitdialog.cpp \ src/eqonomize.cpp \ src/eqonomizemonthselector.cpp \ src/eqonomizevalueedit.cpp \ src/importcsvdialog.cpp \ src/ledgerdialog.cpp \ src/main.cpp \ src/overtimechart.cpp \ src/overtimereport.cpp \ src/qifimportexport.cpp \ src/recurrence.cpp \ src/recurrenceeditwidget.cpp \ src/security.cpp \ src/transaction.cpp \ src/transactioneditwidget.cpp \ src/transactionfilterwidget.cpp \ src/transactionlistwidget.cpp unix:!equals(COMPILE_RESOURCES,"yes"):!android:!macx { TRANSLATIONS = translations/eqonomize_bg.ts \ translations/eqonomize_cs.ts \ translations/eqonomize_da.ts \ translations/eqonomize_de.ts \ translations/eqonomize_es.ts \ translations/eqonomize_fr.ts \ translations/eqonomize_hu.ts \ translations/eqonomize_it.ts \ translations/eqonomize_nl.ts \ translations/eqonomize_pt.ts \ translations/eqonomize_pt_BR.ts \ translations/eqonomize_ro.ts \ translations/eqonomize_ru.ts \ translations/eqonomize_sk.ts \ translations/eqonomize_sv.ts target.path = $$PREFIX/bin qm.files = translations/eqonomize_bg.qm \ translations/eqonomize_cs.qm \ translations/eqonomize_da.qm \ translations/eqonomize_de.qm \ translations/eqonomize_es.qm \ translations/eqonomize_fr.qm \ translations/eqonomize_hu.qm \ translations/eqonomize_it.qm \ translations/eqonomize_nl.qm \ translations/eqonomize_pt.qm \ translations/eqonomize_pt_BR.qm \ translations/eqonomize_ro.qm \ translations/eqonomize_ru.qm \ translations/eqonomize_sk.qm \ translations/eqonomize_sv.qm qm.path = $$TRANSLATIONS_DIR data.files = data/currencies.xml data.path = $$DATA_DIR doc.files = doc/html/* doc.path = $$DOCUMENTATION_DIR desktop.files = data/eqonomize.desktop desktop.path = $$DESKTOP_DIR mime.files = data/eqonomize.xml mime.path = $$MIME_DIR appicon16.files = data/16/eqonomize.png appicon16.path = $$ICON_DIR/hicolor/16x16/apps appicon22.files = data/22/eqonomize.png appicon22.path = $$ICON_DIR/hicolor/22x22/apps appicon32.files = data/32/eqonomize.png appicon32.path = $$ICON_DIR/hicolor/32x32/apps appicon64.files = data/64/eqonomize.png appicon64.path = $$ICON_DIR/hicolor/64x64/apps appicon128.files = data/128/eqonomize.png appicon128.path = $$ICON_DIR/hicolor/128x128/apps appiconsvg.files = data/scalable/eqonomize.svg appiconsvg.path = $$ICON_DIR/hicolor/scalable/apps mimeicon16.files = data/16/application-x-eqonomize.png mimeicon16.path = $$ICON_DIR/hicolor/16x16/mimetypes mimeicon22.files = data/22/application-x-eqonomize.png mimeicon22.path = $$ICON_DIR/hicolor/22x22/mimetypes mimeicon32.files = data/32/application-x-eqonomize.png mimeicon32.path = $$ICON_DIR/hicolor/32x32/mimetypes mimeicon48.files = data/48/application-x-eqonomize.png mimeicon48.path = $$ICON_DIR/hicolor/48x48/mimetypes mimeicon64.files = data/64/application-x-eqonomize.png mimeicon64.path = $$ICON_DIR/hicolor/64x64/mimetypes mimeicon128.files = data/128/application-x-eqonomize.png mimeicon128.path = $$ICON_DIR/hicolor/128x128/mimetypes mimeiconsvg.files = data/scalable/application-x-eqonomize.svg mimeiconsvg.path = $$ICON_DIR/hicolor/scalable/mimetypes actioniconssvg.files = data/scalable/eqz-account.svg \ data/scalable/eqz-liabilities.svg \ data/scalable/eqz-expense.svg \ data/scalable/eqz-income.svg \ data/scalable/eqz-transfer.svg \ data/scalable/eqz-refund-repayment.svg \ data/scalable/eqz-debt-payment.svg \ data/scalable/eqz-debt-interest.svg \ data/scalable/eqz-security.svg \ data/scalable/eqz-schedule.svg \ data/scalable/eqz-split-transaction.svg \ data/scalable/eqz-join-transactions.svg \ data/scalable/eqz-export.svg \ data/scalable/eqz-import.svg \ data/scalable/eqz-edit.svg \ data/scalable/eqz-tag.svg \ data/scalable/eqz-balance.svg \ data/scalable/eqz-ledger.svg \ data/scalable/eqz-transactions.svg \ data/scalable/eqz-previous-year.svg \ data/scalable/eqz-previous-month.svg \ data/scalable/eqz-next-month.svg \ data/scalable/eqz-next-year.svg \ data/scalable/eqz-categories-chart.svg \ data/scalable/eqz-overtime-chart.svg \ data/scalable/eqz-categories-report.svg \ data/scalable/eqz-currency.svg \ data/scalable/eqz-overtime-report.svg actioniconssvg.path = $$ICON_DIR/hicolor/scalable/actions actionicons16.files = data/16/eqz-account.png \ data/16/eqz-liabilities.png \ data/16/eqz-expense.png \ data/16/eqz-income.png \ data/16/eqz-transfer.png \ data/16/eqz-refund-repayment.png \ data/16/eqz-debt-payment.png \ data/16/eqz-debt-interest.png \ data/16/eqz-security.png \ data/16/eqz-schedule.png \ data/16/eqz-split-transaction.png \ data/16/eqz-join-transactions.png \ data/16/eqz-export.png \ data/16/eqz-import.png \ data/16/eqz-edit.png \ data/16/eqz-tag.png \ data/16/eqz-balance.png \ data/16/eqz-ledger.png \ data/16/eqz-transactions.png \ data/16/eqz-previous-year.png \ data/16/eqz-previous-month.png \ data/16/eqz-next-month.png \ data/16/eqz-next-year.png \ data/16/eqz-categories-chart.png \ data/16/eqz-overtime-chart.png \ data/16/eqz-categories-report.png \ data/16/eqz-currency.png \ data/16/eqz-overtime-report.png actionicons16.path = $$ICON_DIR/hicolor/16x16/actions actionicons22.files = data/22/eqz-account.png \ data/22/eqz-liabilities.png \ data/22/eqz-expense.png \ data/22/eqz-income.png \ data/22/eqz-transfer.png \ data/22/eqz-refund-repayment.png \ data/22/eqz-debt-payment.png \ data/22/eqz-debt-interest.png \ data/22/eqz-security.png \ data/22/eqz-schedule.png \ data/22/eqz-split-transaction.png \ data/22/eqz-join-transactions.png \ data/22/eqz-export.png \ data/22/eqz-import.png \ data/22/eqz-edit.png \ data/22/eqz-tag.png \ data/22/eqz-balance.png \ data/22/eqz-ledger.png \ data/22/eqz-transactions.png \ data/22/eqz-previous-year.png \ data/22/eqz-previous-month.png \ data/22/eqz-next-month.png \ data/22/eqz-next-year.png \ data/22/eqz-categories-chart.png \ data/22/eqz-overtime-chart.png \ data/22/eqz-categories-report.png \ data/22/eqz-currency.png \ data/22/eqz-overtime-report.png actionicons22.path = $$ICON_DIR/hicolor/22x22/actions actionicons32.files = data/32/eqz-account.png \ data/32/eqz-liabilities.png \ data/32/eqz-expense.png \ data/32/eqz-income.png \ data/32/eqz-transfer.png \ data/32/eqz-refund-repayment.png \ data/32/eqz-debt-payment.png \ data/32/eqz-debt-interest.png \ data/32/eqz-security.png \ data/32/eqz-schedule.png \ data/32/eqz-split-transaction.png \ data/32/eqz-join-transactions.png \ data/32/eqz-export.png \ data/32/eqz-import.png \ data/32/eqz-edit.png \ data/32/eqz-tag.png \ data/32/eqz-balance.png \ data/32/eqz-ledger.png \ data/32/eqz-transactions.png \ data/32/eqz-previous-year.png \ data/32/eqz-previous-month.png \ data/32/eqz-next-month.png \ data/32/eqz-next-year.png \ data/32/eqz-categories-chart.png \ data/32/eqz-overtime-chart.png \ data/32/eqz-categories-report.png \ data/32/eqz-currency.png \ data/32/eqz-overtime-report.png actionicons32.path = $$ICON_DIR/hicolor/32x32/actions actionicons48.files = data/48/eqz-account.png \ data/48/eqz-liabilities.png \ data/48/eqz-expense.png \ data/48/eqz-income.png \ data/48/eqz-transfer.png \ data/48/eqz-refund-repayment.png \ data/48/eqz-debt-payment.png \ data/48/eqz-debt-interest.png \ data/48/eqz-security.png \ data/48/eqz-schedule.png \ data/48/eqz-split-transaction.png \ data/48/eqz-join-transactions.png \ data/48/eqz-export.png \ data/48/eqz-import.png \ data/48/eqz-edit.png \ data/48/eqz-tag.png \ data/48/eqz-balance.png \ data/48/eqz-ledger.png \ data/48/eqz-transactions.png \ data/48/eqz-previous-year.png \ data/48/eqz-previous-month.png \ data/48/eqz-next-month.png \ data/48/eqz-next-year.png \ data/48/eqz-categories-chart.png \ data/48/eqz-overtime-chart.png \ data/48/eqz-categories-report.png \ data/48/eqz-currency.png \ data/48/eqz-overtime-report.png actionicons48.path = $$ICON_DIR/hicolor/48x48/actions actionicons64.files = data/64/eqz-account.png \ data/64/eqz-liabilities.png \ data/64/eqz-expense.png \ data/64/eqz-income.png \ data/64/eqz-transfer.png \ data/64/eqz-refund-repayment.png \ data/64/eqz-debt-payment.png \ data/64/eqz-debt-interest.png \ data/64/eqz-security.png \ data/64/eqz-schedule.png \ data/64/eqz-split-transaction.png \ data/64/eqz-join-transactions.png \ data/64/eqz-export.png \ data/64/eqz-import.png \ data/64/eqz-edit.png \ data/64/eqz-tag.png \ data/64/eqz-balance.png \ data/64/eqz-ledger.png \ data/64/eqz-transactions.png \ data/64/eqz-previous-year.png \ data/64/eqz-previous-month.png \ data/64/eqz-next-month.png \ data/64/eqz-next-year.png \ data/64/eqz-categories-chart.png \ data/64/eqz-overtime-chart.png \ data/64/eqz-categories-report.png \ data/64/eqz-currency.png \ data/64/eqz-overtime-report.png actionicons64.path = $$ICON_DIR/hicolor/64x64/actions INSTALLS += target qm data doc desktop mime \ appicon16 appicon22 appicon32 appicon64 appicon128 appiconsvg \ mimeicon16 mimeicon22 mimeicon32 mimeicon48 mimeicon64 mimeicon128 mimeiconsvg \ actionicons16 actionicons22 actionicons32 actionicons48 actionicons64 actioniconssvg !equals($$DESKTOP_ICON_DIR, $$ICON_DIR) { desktopappicon64.files = data/64/eqonomize.png desktopappicon64.path = $$DESKTOP_ICON_DIR/hicolor/64x64/apps INSTALLS += desktopappicon64 } RESOURCES = flags.qrc } else { RESOURCES = data.qrc doc.qrc flags.qrc icons.qrc translations.qrc target.path = $$PREFIX/bin desktop.files = data/eqonomize.desktop desktop.path = $$DESKTOP_DIR appicon64.files = data/64/eqonomize.png appicon64.path = $$DESKTOP_ICON_DIR/hicolor/64x64/apps INSTALLS += target desktop appicon64 } unix:!android:!macx { man.files = data/eqonomize.1 man.path = $$MAN_DIR/man1 INSTALLS += man } win32: RC_FILE = winicon.rc Eqonomize-1.5.3/README.md000066400000000000000000000077561416454732000147720ustar00rootroot00000000000000# Eqonomize Eqonomize! is a personal accounting software, with focus on efficiency and ease of use for small households. Eqonomize! provides a complete solution, with bookkeeping by double entry and support for scheduled recurring transactions, security investments, and budgeting. It gives a clear overview of past and present transactions, and development of incomes and expenses, with descriptive tables and charts, as well as an approximation of future account values. ![Image of Eqonomize](https://github.com/Eqonomize/eqonomize.github.io/blob/master/images/accounts.png?raw=true) ## Requirements * Qt 5 (preferably with Qt Charts module) ## Installation Instructions and download links for installers, binaries packages, and the source code of released versions of Eqonomize! are available at https://eqonomize.github.io/downloads.html. In a terminal window in the top source code directory run * `qmake` * `lrelease Eqonomize.pro` *(not required if using a release source tarball, only if using the git version)* * `make` *(or `nmake` for Microsoft Windows)* * `make install` *(as root, e.g. `sudo make install`)* ## Features * Bookkeeping * Bookkeeping by double entry * Transactions: expenses, incomes, transfers, and security transactions * Transaction properties: description, value, quantity, date, payee/payer, from/to account/category, tags, associated files, and comments (plus specific properties for transactions related to securities and loans) * Split transactions * Refunds and repayments * Explicit support for loans/debts with interest and fee payments * Scheduled transactions, with support for a wide range of recurrency schemes, and confirmation of occurrences * Support for multiple currencies, with selectable currency for each account (included currencies are automatically updated) * Reconciliation * Parameters of the last entered transaction, with the same description (or category or payee/payer), is automatically filled in when a description (or category/payer/payee) is entered (with auto-completion) * Value input fields support arithmetics and currency conversion * Budgeting * Monthly budget for incomes and expenses categories * Ability to exclude categories from the budget * Custom start day of budget month * Displays previous months performance * Predicts future account values based on the budget and scheduled transactions * Securities * Stocks, bonds, and mutual funds * Supported transactions: buy and sell of shares, trade of shares between different securities, dividends, and reinvested dividends * Displays value, cost, profit and yearly rate, with present total or for a specific period * Estimates future value and profit based on previous quotation changes and dividends * Statistics * The main account view displays total values of accounts and categories for at present or a specified date, and value change, as well as budget/remaining budget, for a period * Each transaction list displays basic descriptive statistics and supports filtering of transactions based on date, value, category/account, description, and payee/payer * Line charts, bar charts and tables for display of change of profits, incomes and expenses over time, for all categories, a specific category, or a specific description within a category * Pie charts, bar charts, and tables for comparison of expenses or incomes between different categories, descriptions or payees/payers * Charts and reports can display total value, daily average, monthly averge, yearly average, quantity, and/or average value per quantity * Saving, import, and export * Data is saved in a human readable and editable xml file * Flexible QIF import and export * Displayed data can be saved to a html or csv file, for display online and editing in a spreadsheet * Can import transactions from a csv file, for example a spreadsheet file, with a customizable number of variable transaction parameters * Tables can be saved as html files and charts in a number of different image formats, including png and jpeg Eqonomize-1.5.3/TODO000066400000000000000000000020341416454732000141630ustar00rootroot00000000000000BUGS: - sometimes accounts aren't selectable after renaming etc. (?) - second combo in time development diagram (on "Source:" line) is not updated when the first combo is changed. Thus it is possible that the graphic doesn't correspond to the items selected in this combo (?) - charts need meaningful window titles. - saving in .eqz is very slow (?) - changing the year in the graph view is VERY long (?) - crash when trying to delete an operation from an account view. - schedules don't always function (vague but reproducible) (?) FEATURES: - Security: encrypt files? - Import and export more file types: OFX, Gnucash, kmymoney2, etc. - Test QIF import/export (I have not been able to do any real world testing) - Load quotations from external sources - A beautiful summary view (with summary of assets, pending payments, recent transactions, etc.) - Undo - Enhance manual - support for saving views in eqz format (e.g. splitting data in separate files) - make ledgers similar to expense/income views - Option to carry over budget to next month Eqonomize-1.5.3/budget.eqz000066400000000000000000000421501416454732000154710ustar00rootroot00000000000000 web download upload -1 3 Eqonomize-1.5.3/data.qrc000066400000000000000000000001431416454732000151120ustar00rootroot00000000000000 data/currencies.xml Eqonomize-1.5.3/data/000077500000000000000000000000001416454732000144055ustar00rootroot00000000000000Eqonomize-1.5.3/data/128/000077500000000000000000000000001416454732000147175ustar00rootroot00000000000000Eqonomize-1.5.3/data/128/application-x-eqonomize.png000066400000000000000000000212271416454732000222050ustar00rootroot00000000000000PNG  IHDR>asBIT|dtEXtSoftwarewww.inkscape.org< IDATxyչUg왦FA((ш`!`0z+Fd%yI35I5ĠxA#" t7=w>C:UNOw+_UkW7{*EJ<#6ϻƹƟDǟ Ey:t+9sfA7+5vpqI@JI0ltZvJP( L.mM"qKF^ 3\*=)NX|\%S.\..L`L5߿ͤ ?!7 lNl>0~.zztAQ 0ls4~qq\!%grn@_tvӃq.ΎtPuyEǛֽTEδv_fq!~M*>4g6,FQ<2!H$S iVqT6,W{8e*w987 SjT7FůBhy)% WgT?~?="A¼iAAV-HI, ^> ,oQqYCgQcM4n+jذ|ǚizbe\5rOP()l\vm ]( ="Δ!2M :&\({Ȳ*9הHu&Ǔ*}x%e,YFmA8Wϫ ,nJg?onlt?rf7ޠhIy5f#Zӣp4!t>Hh:AN\Ku.$x/4rtI+kCTY\jxf*|kʪ|gs#Hɏߜd?{<ۢ4} E]H. +ЄD>*O]Si~' $]FG-t]lnϿju\qi7+,鷅Am:OY$5Nʰ¦=7#dV,GgK\ͦ=:N|PQJ}̵υ^+/+cAcWOԙ`f}.kq$hbJuM-|Wʰ+jˡS,4l:'3X4 mo~6\5/%0 Zg@[ V/( T{s0&yP?*SLbJOB7"lKw-14]2VXUeFd89olpם)Sp꺴kw܉.&(Y^jGΝ SSAHRWe<}xRAQu4Q|*8p@{@C߻[Ww-_gݻols@;̪)5>i2ohT,5v`fvh,tL}pÁ:oobٲyW§Kp( aAܹstvvLag%K)&W}qV0_x '.!:: JN&0O1`L|a\;10`,_(80wԧ=M5B ̿|;ǟ69a\:ĉ8p{OIggakkk|~ m_~%/_mcٲeiLi@H)d/ӱq|2y΍7a\2t]gΝ<.kBz*ˮ$Cudj'*TW_>BMl~6?qkO;#}LV4\bKa;!Hc{'_9{ ө|fRjyh il5[IW'CХI:%5ݒ+ k~?2z!?w8p9F~/~L3pP"I$ :.ATPЋZBK2Dנ~e>fS7\2O<~o# QQ`l\@ # JH)9x 8y ƒ`܅4LQ I$}H`pP"ė*T%B`ϓ:D3/ַeALFH$?:` c_aU 4MG??Oέ0}>04!А[&DzNH0拨jU*!QU@0o2K.tvo1M0~IїoL?0. qFv͒şeeI(D$!I[:m=4]~m<_itg֬|K_xZ8\inc;D/K<@HZGjG>0 igسg7As_DJE%gZGy~5/ԙ4f2kF)//#GOHCE3t=C_M6N_OE|]H~Sdf.ݙLy]jIcB>ϳcl sܰ.HYBo`}e1iRGXf uuui9{,`7ӭ_&иYt)`HҥKYl L}4ɖ=L|;O!hJ?р}klٲ7ׯի}.x^vy)q,YAjMFCC FyQ; /ꌵ`뮻3f== 0%߮ ̈@"tHCS3qy(ɷxth}; z饗Y~>3g>o#tt Q|>f͚ł 6mZ6v"n:n|>cХyE޾|ԧIbSI1ڒo˜!~uu3ǾˢE>|~K k_ X͙3UVQVVS;&z!Gdɒ46w`#((Rqnvhb8$F7m.V|0_Q.Yߧ~Orw1|*++Yfs \}wCUUK(TWv}lItFc@{>|cr:}#9Г<w]._>Z!୷4)mmop=XįeÆ  Xnv@&Xv-ڥ@zZ` ډ--9*7ܱ~Y&>عs'S_ Mrx~ %x~ʔ)lذ!4#(- uT%n%ү&xJl}33iz /PHAסSo[(//K1kv6i@u8cch$5J޽6Eu'kؼTV[bEK8Ĝ xPFXG}OQ3=^0nGwI<cŪM=GG_ H*-U FcU9%LLz&c(N /Wߛln_r(xggμ{}`˘itvtq'oR `#$@dWIiSOSN`/>{^|iu u.7X 8mN]U%'GTLsa{Z8p ;k縷֬`k0.2x[OgB.SmRm@JɡCc RJ:::4_|* /^uno&\zJtmFN^nAGi;u/Zf)am&\E dJJɃ_&֭C$Ȅ&On5-OxlIflD~07<yJy3>`0Ֆf Lm~z$݋]ۘ!1' 0MC?a1y3(hijeͰw&ϨAh7B\uHgCGg;r.ُzeov!`3a&!bb1~?`Кw]|6s1mӝGliv*6G55!ADI`>X'`'yljωy:B8Ny־L{E&}X@P _ >@ X EQ, klA+uhocH#K{9&N޹f87CLfv/; !QJLH1 SSZA4'aYk]{ L)*Cb(}1&`8MjK#bz21T Xۤo350ғB3앢@ 6A<\+UE5~bL] L0CA8G5:vW( uBld M}ebLeywՌ c^Z^+$sN6DE3 PK#t- #4nN^xI|/-`4ҫL@N( +@]s|1i~xkዔ)a74 1 MD.c^N ɤ Oc#~ ҟO!muib|n0 ti{CM65KHw'q`%Ld"m1L`ox GOh]6=G\F!N<3sq DL )Lfri/1*gKܫPI}>Wjvi26Io<[E5@yd{JXE%Ay[/%v-Aq4@RėHXvI{?n*>hKWi|3M)> CO=,ph ۫bm8{k\N8TPoϦq89Vن.&CgP}db D~UUyxOҖ6 9#yn`)n&iCʐIr( @tpŠ@j2cG7^FvAUUh4k:<)1ǙԿ!} }H@uH}r@3s9e~4]v!{/S$OBM1{L=E*{1P4;&H~>4K1֭[ٝwluK<'d ߇IS^4 Wlf&UM~x@&oXvflBEEoo_ZHh'|%t"Cxm_S;aewyB&0=+#.3kJf j?o/__I x8cB8 eb% Uj8Rypphx2_\q~[W!ɏBih"ԉ[u͇!GrK|( PT<%!u C]`70`Prn&_1ć2H)_@ qϦ6lbJ?8 Qg-Lponnf۶mEJ(> Ix eL`+k3I( '} `Mm&`LۇE|(%"or8ؤf) 4 p/id3#---l߾aJ Tk VKQOfp.BF"1_'G3? 8ϟwy簈%4Oϸ ,`v%m> m8Ջ}nffv1bć. S>cٷHZ5.z%5>~)a>5AHGB&&e?|D%T%ؿk?I2寀 ʊjg* Խ%rn&GPJ05AGMk16&y.y}ADF #\POP.Ԍ6g"'|p8kĉ%b[6o>57眧6R0˻'oն&kZUi< 0yꩧBF|( |/ȣ1|.jIg}P({g̉$`&y80~T"MMMpFΝ;Ƕm%":lݺD"qx$>dDlǎرyW9  i߻{.KPFzEX>8*{/IENDB`Eqonomize-1.5.3/data/128/eqonomize.png000066400000000000000000000217701416454732000174420ustar00rootroot00000000000000PNG  IHDR>asBIT|dtEXtSoftwarewww.inkscape.org< IDATx{U4I:!yBb!FT.gTt1(gFw?| #*Byx5"! $NgtGuuSu^]_SUvUk^k]JD8/nQ.2Ge 2Qx(̑ JVɦ\WqiyyoBb(\ |LDRhKÈD _PU"lqׯVТZ[xCDci'^o_c7DӢ_Wyް8szR"wr{/E~/PY&_oޛ #/fʔ)rԏRíSQ(pkK}OTJ+i9_ 6t.|y_R*JE'"x!H!MXIԺs}֗(0ie[y?@kk"|&:Q5[IjQy~w/ p30nB^߸g٭R?lF%hh4T%PVOoy\K2..d22ڏ[QJ}X:޺D$$6BFC^ rqnz6}/*|z7ķ!1ecRR+R(6(:p )ӮS/^<M)uRL أfzz3Pb#o^,ֺQp݉%2Cq2Kw/r>,"q!N4/4 4:$[rFsMi`@)58A".XG%M842\g23GMQAex %Y{u'ΜϏnO(>*"wĵ0!x'`bZ=D2Q#f.>\/d&0eҙLta݂@{l)mv%HL0qB4h J񓯎߹sJ7׊Ƞi"kt#ai2Rj,aZ`.drh@25xE(!ܐPP=R}C~MWdq©sq]H+S_q?YjXe"Ѵո]mGusTK\*49l :1[Z&0X8?vŸq ( Aa(AQQ 8Z!'t{hpD_ܕw̓.pzm{–-[L=v{m(TػjD!Lj1ǃ FR-qxk?Wr섉L0e Cxi(Af}ͧK}8 i}lJ@Y<mK4tH~4$4 gD 0o;yob_֮ y4xߐ ]BoXu@Q(P@Qiי# B-I 5 a`#0T)_P> :hJK}!y)(;7#: /W: xBrBAa_GAPBa^MwjvS(R(P,iEL.|oI5[E EK=}X~K I~FCcz/l5a_]jC* :pXrFN}uRtwi|kcu v'T0"R{\umILOObj.DPрCO?;7) R@˩.WaL-4XVxu|=~7HB{6,^]4?5,0 !Qbs&j_>X-SiH?˯Ӧe=} 6oլ]S$OwQI"ADzm@x QqX/ B('8wvSTj(J/\)S;E@o̳E֬ eLu;G ٱu(L>`̱Wa 'G*:luԇJf9^ʼn3]ɳn]kdkBA1BRD(fY-b$YtI!_![vI6I6 uԏ@)u>>qyű&Q E:ʕD~/@ e R9ǭn mq#.j~j66F:ձ&#p_ ;޽[#ܻS( 'K=d29Qأ8CFoG ,Adc^9x mR3srioWa^ss߰IO|bNh&'쫒]T0єy74 hVPNa_Prϊ6e'~R ~  ľ$0B@ =9-c:AS<\hkSں#3I&` ^vvϟ~hR)X;VEORv=Cu׉H߰[} !"~{۽kߴaSHwyK6D' فNn)u]@Q8 dOKry?ܠن * s.#_D+pjݯ؁7s-0PG EZ\\#m4/<|Qh(C52V[Ay*{~Khg٦ܠƤXhq&DN/ .y G6b7~XB`#t)F%tqi_})Cqg =ޏ */ lM%! (hk?)Q 붷7\& aODeqD,PtXﭏT::R 2 oWb;mu{ӭE @0&:ч 0i 'ej(ÎEU+ Hzg´N5M1տ>8d|l px[) س\t@:(mz]Hq]3<@6[5a>cA&F[MK + E~{7FJ:a4znʶDMPJMßTrzM3 &V]é )+"1ĸa zҔ Nj g7 #؏< d<: %v8=x4Aw=/E+"W(EΙ}<9y9my:<+Ӟ9o?`䩖n]I4f1q9^Ͷ,y1yS>LL:z#n* Ĝ`PC,[8`n f-FȓX7&ڪ" n2vZD{Wk1J)RF_eIU2 {uU+3!8ABNn N œ_\?ڍޮ<Pko$Ck p TXHExSMh`8KUHn"v*zB %bvEHLjF{鬝`P0 FSTI%4[,fp{}˙II6e18gI7pu5t9 2I0Y)rhOhyE=fdЫ{ˉ3r a.Y&Y Fq{6y؋E[_!g2_$ h$(K&0^_GRP 7/g~'P3yZhVTf@e4 /R1/ :S:L1q#!F\" _Á$<]S"j)MCI / 3@ J01;OPMWL1`MPw48ZNn_G:#x l:n@015e}ykОƅ!_ =֣!~G,x;f1Lxθ%|&T a.& 3UnSǛ@w[SeOw~Cmں?`dCz~Áoo")Oצ.~Ōf0i$83(kAŘa`s8Wdk7={`_Wc0bQCWEyv}tmn{0Ky0 `}5h&:)6n' m%K ZLHPHDD&Ar^cs:9?i FW!J3ܼZSO{;o# #HtYo/K (lG{#͛%\ҥK9s&yf~an_v͖-[{*{]/QN; 0'  4򢄏j!Pz~Pnu,O׾584zⱩ鯚ow\Vݹo|tu9cE.9IDˎGxw 1@ PC R틆~M"=^qmKK +V(#?~_冥]բ8M7q>qθR ,Fu$o}Etº#ďFES E7vҁznݏE-Zėc7ggTFh[pqp:<Ov}NiŔ] \Xа HOkm !UF!/"?ƾHS9@z+"Q7!*MQ/-%Vu&]i_q6Y6BgnP` 6Dv}ݟH: 6nl j4tp{+jPo[>zIQ@5W б2 ?xK 9,(]kp8{蠣ßk%bdv|&B˴kTqD3`toMQ)l";O. 儯A}!gϼ }kׇ˻\BqblQŠ3v…7S%FZQǏ);6辧uU.p!XHZ^ 6^@Dz-)@yٲF@S&O0spU.7Tn瞲~WWgYsG_= JX f؍ԐP o)Qg_' -[peqf1S'NEu,(?̚5Гd ]Y)|_6;d$z-CbTL+ `2a}a=v]KF2d_ ӟĬYؾJDcUZ20QR*2 _1 !W'(Os m0I?Iuq+ӟVS9zm̫iWfp=?,l/s~`* X$"*#DL D(hx{%?q 34'lb{ fxQ),:||.\)<:~+Ox-]RD `-k`Gb ,yl;Fzn+c揩>ׯ-qa?&7qhl}~EkBH!8 ^E?%ATGE~H`f:8*0!{ iVqmPK/OMT0haggK.aN˜u3d~^r)I?IכP1m)`ƺLxӄ7nE]ĤI\~uMb~ȎAK$,oMǨcRy6u3R' `PmhXeͳwJ@ )SN8.8gn rrCN = =70"~{㗌'#;e"X~=׎(ژ7o+0Ϻ :d"f֯W_S :x!tm(Ɵ=+f3nQRo ꫯ'([\̫\ <fZxd{A¶χ  UW6ffŌ`┉ wҥ@L_q|P_{|X*AY̑`~IDATz4=%V~VZ>3}  X[#G8|Aȸ%/4 qhԅTQ-eE FF W <CݸIRD~фZ'lrF'\ōՉYm&Y*,MrB JPs"+Uc?mDz}&:x P𖼴EgH? ICrC%f f*_GՈ":N+af%\3kGЈt(c@;/|:\11#p빮=DF Ti㱝>u3 PMfo=^O틚D Pfh{zza >7.* cD{}5 =? ?$&e*KbPg{(x}% l/X¼Q@JXrtCw OVew|l[5NS-lb܇#^B fr9{cX 'j2g"R HLRgG9#RŽ%Umċ:L=H @)\JNJh⥃*e 2Qx=IENDB`Eqonomize-1.5.3/data/16/000077500000000000000000000000001416454732000146335ustar00rootroot00000000000000Eqonomize-1.5.3/data/16/application-x-eqonomize.png000066400000000000000000000014071416454732000221170ustar00rootroot00000000000000PNG  IHDRasBIT|dtEXtSoftwarewww.inkscape.org<IDAT8}]k\U90ʠ@CAn~Cѿ?Ћ{Uz؎AHj%vpsI9콖C / ^]fggg=ZQuP@ |JȝU/DFEB, YaqB<o3+=\G}*. Q(DQ}`k<" yhGPK sk4j z{ 'CB(ʕ+ε~*Ɯ 5e|s;\ۥQ}}fkm k' !pOlw{ 'SLibHc9%LJzUnyTR5'=}L3s𼅪rUJ_2 #; tiz—\3d:yp3VU3p/FؽzhW,#rnP1!0` =]0 AHt r&ZKbb.ZK=s\Ӝ6n Ʉ(t:gsKw(gPԣ:!Ensཧ9C_l2YC< J4i(sst:u眖eEQhe.B˲,˴`0ݮr,b2uG94n䫣UIENDB`Eqonomize-1.5.3/data/16/eqonomize.png000066400000000000000000000014011416454732000173430ustar00rootroot00000000000000PNG  IHDRasBIT|dtEXtSoftwarewww.inkscape.org<IDAT8}Mh\e{g:whj1J)i U E()%!(n܉Bw Ut C,.LiU R)M3)%3w|d2縈F's1ԁ>0^vs+}2??-b]X7e gmlHFc%W;vmNLmFwfnjU |+ŗQ$x:[oy7fθ"ֿkm\MTO[۴]AΎGiiw㟖W2[Xor3B$m )s]" Qp8 e4Hs%)}LTSrO^и hiJ\,N}V;@-3p8qum!}$rځ06>&%;MѠ@XU Ca%pjw>Fu%IX8+ _! FU1<g<61O=U3$IENDB`Eqonomize-1.5.3/data/16/eqz-account.png000066400000000000000000000012021416454732000175650ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYsnrtEXtSoftwarewww.inkscape.org<XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/IDAT8ݒ?k"Q{"t`aѠv +~-S+l`ia5FFx[ *0k&iϹ?\7( Ga|c}\,?8/D"a|ᰯl.\q_eOIVӓ|2@J;!~(x<B\.^ٺezpο՞?)VF!lּ^/Ku]WBBDlH)/~۶LgV+L(Dq0nЃWT*'2ߏؓH$1sHR h4Mt:{Jr].}>Rj@DFQQno4E)][_+PȦIENDB`Eqonomize-1.5.3/data/16/eqz-balance.png000066400000000000000000000020331416454732000175210ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs|4ktEXtSoftwarewww.inkscape.org<tEXtTitlescales of justicekYtEXtAuthorjohnny_automaticbM!tEXtCreation Time2009-06-26T04:35:18QtEXtSourcehttps://openclipart.org/detail/26849/scales-of-justice-by-johnny_automatic>zXtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/dIDAT8]Hage6*(4XQM/ /F]-ԛ. bt#X*,H/tP6"x0>g n{8]u9sϘ|277%~]ltgud2{z{{mjuu D|4;;R|M#J(f=jii)pd'###t]+I(v9Ŏmmm7t]?311,djD6["xriH=r,{)K%)C4 Z6+i^;0?:4 J@>e2-Fy@;,+*\BH! zZ yu!-+ju`"KiomV /B<Pe" :a!t:7'8ޛ%Fە$f^~;NAz=$gtݮ(3vgc}~ D?@ R< jw f=M ve/s>R\ߙy0mۓeA|8 KDZoy3R_>9&l۴N}^,/D D ,n52[R,#_YoVJ[c<s p%2H=(Jq d2`6i뢫rQ2;;ېR*TXT+)R*ui!d2AS~Z>tֆP5T|h?or80plV?hZ3\bu{ov<эQLEZRw7+;^IENDB`Eqonomize-1.5.3/data/16/eqz-currency.png000066400000000000000000000013111416454732000177640ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYsnrtEXtSoftwarewww.inkscape.org<FIDAT8KTq?߽:G,SH0]6H A)1vA.HzY Enj1c*|:Y*{)|?GI著$\uewIFPLx8>3&qynNfUA4 &8>=s6\P~7ZR^^=okSnnk?d±0iRgg|;:VKjХs#ڔDB}"cȲ4EÉX+斦jY]UU1b#^H"xtJI= |erT#/b )_l+y]/)*\pn7mUfg -8]0cT B1CZ6yH7^okJ"tw+^辩'm z<d5-Nli _M#/p(IENDB`Eqonomize-1.5.3/data/16/eqz-debt-interest.png000066400000000000000000000013341416454732000207100ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs|4ktEXtSoftwarewww.inkscape.org<YIDAT8őKqǿ?x9XEZA 4VE!E<bcWC(WW ]8 ,!6y"|!e`{u.yD;:!lQyVoF=k־uvXڟ17OOO_ ^":Y*K/U065)迈[]L&;:TʇK&p+jQ8:ZZQ*ut:@@y‚v Jkg?8 |>"Rq+DS@ouuU{ ׷ښF7 UōёbxpL$4MK6uF"SXj>M&ᩩl$˲d...jPhd`` y{{{ۨBeq~~:^{?$=z0000~g.̀?>yVI?;dE~wl>820hbca`8O+OIENDB`Eqonomize-1.5.3/data/16/eqz-edit.png000066400000000000000000000007571416454732000170740ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs|4ktEXtSoftwarewww.inkscape.org<lIDAT8c`hL͂$J>{/\<0 B:s=啴Vy_W k&+l\ _귧+aaXSRٽ /|8Y=G6%a.vֳT$o_?/;?}8wtx{9-b}-tWݵM1>Ah(~kO?HeY`!=(.hQnʙ!kϓ/;7}۷oCϟֆ7 ,߿"ŀ'O~f``h"b߿{ޑ+RؤIENDB`Eqonomize-1.5.3/data/16/eqz-expense.png000066400000000000000000000011301416454732000176000ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs|4ktEXtSoftwarewww.inkscape.org<IDAT8Œ=HqƟ}hLzOU48CvPXZR*XZ ]DEɡE]]JE-bmIL/w],cv} \ p8؋&Dz{,\Y0yfRhYCE- #%9.h"b[bpt~T\b`vŅBI}{SV,HdB{V0?[^_p\]^7b~Ѱ\/r(ּodari0FSˈ(\hmiTTѨnmeՈE Fx3WIH݉SCm]NCDM 6>]qQ8]q~5'?["d'}%QTBPjja?E|s}Ay<ш䕼OTg}djuf@+5_:q7 IENDB`Eqonomize-1.5.3/data/16/eqz-export.png000066400000000000000000000013341416454732000174600ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs|4ktEXtSoftwarewww.inkscape.org<tEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/IDAT8A:.Bd"v[ e4\l+K[@? ]촻"(ƅ]gMzjfW/6c싮 !R 0sq0L~80Ms躎La" ˡP(}eyer]RʋK_# cpαnlz!z~$A2D:iHRH$ @)% cc~Oݾ=-Kt:PJ14 axjvH$RFw,c&nRD\~lR`0|f7 Hڶ(Aam"$=zlM&-ՊFut|>u!4BeYR>W[tvx<~Dz,ĽwAZAL1YE I-WIM73jP /|0yw+=&Hj*8X|xy{n ٛ6ݽjO]1ѹ& /MM[lyz$i8a,$3Qhiכ'8Zգ_IENDB`Eqonomize-1.5.3/data/16/eqz-join-transactions.png000066400000000000000000000012351416454732000216040ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs|4ktEXtSoftwarewww.inkscape.org<6tEXtCopyrightOpen Font License http://scripts.sil.org/OFLIDAT8c`0"sfJ՘׃7?d@oyn_~PW `b```9E}87=]]/G-Zׅ %NEQLÏ h2ܽ33{%޽[͛x PQQ`1߹}"':~"&&&guYg12p  C۷oٽccc '' 7o֫wKDUQ˗_?1V< Ժ޿// `mX?]w A޳1 <aAW L F jkksttt=Sga 蠶Ș߿L唴߹F~KA.IENDB`Eqonomize-1.5.3/data/16/eqz-ledger.png000066400000000000000000000014101416454732000173740ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs|4ktEXtSoftwarewww.inkscape.org<tEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/IDAT8R=Q=o}h! ] ")V)".X6  ڌg{Vkù <RSث{%IzV?z=8NPhFUU.^9We]=4@Ry;nPJ=UU ˲( K? xN&/loO(bxZN5M Y1 H`ZvB<B$Y*>z=\.aX2Bfft8~Fm۪g1"In6龽c߶Nf2E"q wvOP.l6Sq6z.; \]e}Xny!w=͞%x<pXrMӤP(䣔>k6L&_!wj ^tIENDB`Eqonomize-1.5.3/data/16/eqz-liabilities.png000066400000000000000000000013341416454732000204310ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYsnrtEXtSoftwarewww.inkscape.org<XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/IDAT8oaǿ=D) L ZFe vu`|p hu !`HCj¥;-)imݞ|"ki}H)42~ j4 m{;Ba% ry8`0uÉM6~sqy)L.{*8˲Jfs\ l(>Fw5Ma!]oVWc3g֐ϟ(&m~R2.Y.`4Z8ׯO$I眘9m=ؓ7"ZeX,t]75e,3J1n"^ícY _,;R$Dn\PJOvϠ2Lpz<v]xR0ƐJ`Y:#ZV[rl,ض-B8p)!7T/z@Uը [v]>t%IENDB`Eqonomize-1.5.3/data/16/eqz-next-month.png000066400000000000000000000005171416454732000202420ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs : :dJtEXtSoftwarewww.inkscape.org<IDAT8c`]ӧOĨe*4/_tr ْo ;w|իWﴵY.RSSlC=<<~<Z}#MӇmOLz,ac0x%l&/b$2oID|,y~)2Ja܀ީ ;!,&&o000$%'y8:aa```yFH2cgJzÜaIENDB`Eqonomize-1.5.3/data/16/eqz-overtime-report.png000066400000000000000000000014001416454732000212740ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs|4ktEXtSoftwarewww.inkscape.org<}IDAT8OSQ?k!:Hj(ᇡ`*1ƍĕɰ`dӁk\ L hPBk[b)}}ס4!x9s?xϳҹ@JBK_x5~?# =n:4gGA*mPP:vSu* + * &zwuAZ\<)[jҼk{{8tG)mۖBommnt2OiP*ڹp5pxx8ll6K8&@UU rQbr4`YaXYYazzH$B^GQ4M#Jٶ8.@a677Bi-šP{]kGGGa4ѧQTUaff D `?EQB! 4M]Q˲r(wK*BU5"եs||mqeYZM\.h4eY=111d*nw7xD"d2oo`~~<440@Jd2$d>'l_u}J!/..$UD>DIENDB`Eqonomize-1.5.3/data/16/eqz-previous-month.png000066400000000000000000000004751416454732000211430ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs : :dJtEXtSoftwarewww.inkscape.org<IDAT8Ŏ 0E"(S0>>Ŧ(2HR[8@!~ywOJ̜ijy޶B<סs1脈zcnʲևqüןMӴ߂O_$DqPJmTU!9BAJ)c! kEዢDC>fY4wc)qIENDB`Eqonomize-1.5.3/data/16/eqz-previous-year.png000066400000000000000000000007461416454732000207570ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs : :dJtEXtSoftwarewww.inkscape.org<cIDAT8c`hKٳ?rktCi={˗_i~zpoo_~e=|g$%%˰|m_+hvMII緍$%% ,ԟ~~~۱jw+Tftϟ?w?443ܹ㑐+ `/^8ۍM3çO000AWGׯ_3իb.\0LJJݏ׮]+ۏ!?{ڵkAAA|}}2$22r/ن;w266Wxx>~8N@711!0 d28X5<22R:99[{zz|,[fff|F2@-// ~7RX lIRvMZdxx7;;766l!StTzv\.5/ ;P(O:6M)0q,m0JR\.׹ot:=x):m>㿲#aIENDB`Eqonomize-1.5.3/data/16/eqz-security.png000066400000000000000000000012701416454732000200050ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs|4ktEXtSoftwarewww.inkscape.org<tEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/IDAT8P9$)"[Jy,d/@QD=[,/ ̼'t& \[֚nw?}4M>xsR$IZv ðiZ/AYM)|>ZG)ZkR(8h\.EAQZk\}!f0 I۶mqJqWs8Ē^1J)4e:r:(^|m'2nvN} IEшjE$B<aX^^6Ah`&"p8$2#^Y˲PJyJ)?""aU;rCl67/NА{75pIENDB`Eqonomize-1.5.3/data/16/eqz-split-transaction.png000066400000000000000000000013371416454732000216200ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs|4ktEXtSoftwarewww.inkscape.org<6tEXtCopyrightOpen Font License http://scripts.sil.org/OFLIDAT8c`.\`zt|jεa'ᵄƘo[Ƿ{W222?#A2UiUaM;?010000e#?'+? {aO7ٔX%Ba.:Ձ\_!v)o_ 4>2U330k΅sE,_xt!n+/A1QQN6f2pq0q>v^1w>100D30ƌF?ӟ>nuҦsgg=>64)9.'omhmwLjޮWZk-o{}WypՂ-aFfCݯů{l?]IS*"Q%^0;,;mz>]3[CeDQ()&לbV%SwXMuyAtڢJʤ +Abk# v5ގ6ˣY%C)ҡXg)V,p)bb-/cSy7(% 39Y !)46D\`.! #D" )eN?tO2ѵw3ZTfo8 icp[IENDB`Eqonomize-1.5.3/data/16/eqz-transactions.png000066400000000000000000000013341416454732000206470ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs|4ktEXtSoftwarewww.inkscape.org<tEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/IDAT8Œ=hSQszn5dТ)J19 !wN Tpq:dH(KpI½9)Jͤt>y +)a9.se da% 3F0 ˔xXk9(h4.W* |Yq`&[wYvW-.w /g^ˈ_v?dvmLz?!L:}t&jk`2\a^BX)Qb3/_l}+o7Ĝ::j>F>X7#Hu͝*Z5b~] TMlVjr9"k !LFcLDQ4u]oϳWB*IENDB`Eqonomize-1.5.3/data/16/eqz-transfer.png000066400000000000000000000013601416454732000177620ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs|4ktEXtSoftwarewww.inkscape.org<mIDAT8]HS/7%],$z ȇ a/B}<EJHAVT:*v\ݽ=b5v9?;1sOJB:W;V9ߤ=([$o̒}{% =|Kb7 /YTX"R2C} RG'twrcEy,,_}x_n: GG #ce6osE E"{{S> z.j7V(.PBzrte 8' MDTD"f\Q}Umee鴦\0I"Ox,A %g0Jv# ` أDkk;=WRS(c  Nqг'ɩ/ބ_6kbt YȘoh; pprBW\zlduu50OzϘL)3bl4 Ą\%$bSэt@qq;||O;V҅5u!K< ZHӹx~ '8)IENDB`Eqonomize-1.5.3/data/22/000077500000000000000000000000001416454732000146305ustar00rootroot00000000000000Eqonomize-1.5.3/data/22/application-x-eqonomize.png000066400000000000000000000020501416454732000221070ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|dtEXtSoftwarewww.inkscape.org<IDAT8oE?q4C) T~TU-EEܑ9pġU\z@HPAH(*JI^{8vhgwo4FUY] v9egۊlvV:7?1LcQP:=!s>ne0;#J,QbJu-۝=W> o &>7QD#8DazGU3> c'nj S.{P VyTUED98nxbIcppZ;Ƙ'B~v /Оiqg1+},\܀`H" 8oϳ.uioJ:7~aPhB˵ ֳuP@QhTU1|Kh)D!ZMs\ĉ! bv}؞{^j$s igr[} pΑ%5t vzѰ ߬$Jn܄Vhc Jd#ڶwPpc=Ed6CSL PU$ ܁Z6u@7>sU=08irΝUv~G K籟#O.CZ]^\\|kO+6P~ڪqώ"cmKK/vXk pyaa؀j a$I(#<#G "!"$I|x_U'v)+KKKo0IENDB`Eqonomize-1.5.3/data/22/eqonomize.png000066400000000000000000000021261416454732000173450ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|dtEXtSoftwarewww.inkscape.org<IDAT8MlU T)bRlGbPK  ,]hb`bąƅ 0acʇ>m{3o|{ymk1Lnf17?sۆ^`۞yyAsIH'.-R]ڵfڳw澮~:u&c >xǷo ]M۽~|hB*Uzɨa*bhh뎗^位mp쫣~qkO{hJB2SmA{CwrxUx_~]ѣI:=٫,_+Մ*]tv&.?C[F֛{LMW՛-kvj2uXcO}upUmw:uޞ\/> _cLuTtbcedIe% !!t+2 *(~ͯݾym6[}٬p7ff*OyaGpt1-S.GLdVݵmP :o/pxǀQ.I;I.9-l n_Ո`B6ό&*)ᣧqpQs<$ w%XQ kTBB98%hwC;mkRŶXP|,Dh@ns6h@< nho_G><5{`&>Xn(,7]* 9ԲD`˲4Jh)-vvvp~~l6 j `uu`w]$Iz5MR){ZYYtod2~yy%W9d'#jӜsp]sc}SJ!j6wㅅsss,n}NOOy'''8>>m{3rX,VrR<hmq/ŨOre"jO`jjuǧoQ[oIENDB`Eqonomize-1.5.3/data/22/eqz-balance.png000066400000000000000000000025361416454732000175260ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|d pHYsXXtEXtSoftwarewww.inkscape.org<tEXtTitlescales of justicekYtEXtAuthorjohnny_automaticbM!tEXtCreation Time2009-06-26T04:35:18QtEXtSourcehttps://openclipart.org/detail/26849/scales-of-justice-by-johnny_automatic>zXtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/IDAT8]L[eo9--]iR> B 8r)a#1D0@oH&p2bc K Tb!Yc-NASgs%|jg7yy>޼%"*<@;N Aډ===I"2N`~vDPf'FSp80bDTvzʔjvvv^oii1v`"R\.O0\hnn޲*&&&<<xH<4 ھc:AWWgkkkwAbV`___]]][^^~bW'ɷkwjZGDY$I: ,uJݏ %eOY_Ec`6kwvv

"-o0{c3꣥kx$bc lVl7;|M<dZu[H&_ nȲle\5_z8=)eff)rPRa~H$'fO?s%&1&c "IR}<Y,ca@&)㌈c "b yP=++clUq(J$\.SmPP^bWE)J&*:"|X\MLN?-~_+pݷ:::y*p:V2RDM(%/8D"QfU xhԃ?OTJd 1DITzppA.sԷƆvzzgEQ @VXVjp|Yϝhy$L&錔P(4HDwc|O':(:IENDB`Eqonomize-1.5.3/data/22/eqz-categories-chart.png000066400000000000000000000017011416454732000213560ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|d pHYsXXtEXtSoftwarewww.inkscape.org<>IDAT8OhwǿٙC2[d!&C(,TK҃ ^zho^ZăQ= \P"*MKD)Q6Yldbvy3n[}}'<2b[ﱮ T,.i7Kum߮ZwZ[%%P.W , 0MRiSf2}'Ύh]]NB5S @//X ~LKXM;)'4}f3-(@i,4ӟ3CIRi&TWw?M/ %\w:60g&p |d;b~^(,o>>h{^H$)t0=Pj@Tei7 - >`%(^5@HJ x˱g,\=.#CSs_uqN`xDe`<̱([XB{թx{avuהiW'鐁\_QgR"H"HI\{uY4)-1Nz]ѧVRv=+W}\Tv3&9:Ǜ I2^]TNacƫ=ɺi*%D:j=u(Šy7ѕOWa/ ry܁IENDB`Eqonomize-1.5.3/data/22/eqz-categories-report.png000066400000000000000000000017051416454732000215740ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|d pHYsXXtEXtSoftwarewww.inkscape.org<BIDAT8AhUodM꒍R ڃdB9x h{у C/P*ړRH% 6VjRijdٝy3Nv2 ؃~7?:3Rk<>@!rGZ3FcBa$yZS, O2qP+˕(Llۂ"ϗ&v H-~jA&4;^/sεF>`E :bPk}(||Yy]]`PShVo9{ `Nw3sj(d3l SFKG)Q.LZ,vK瞠T*e+ 3>>NyoqAcnnez,rF@m7xMT!ǴA Tǿ5o+>Bpuƀ֘L:^XXH:XYYa}}=DAFo(RP.3+_䟟!^'&7YaӲ6TJ)/"(JRJ.>T*pswG e>L!\.cR&/9Rn 1dao*KKK(z1ړw|Fʘggg?Fk\:7M333Afj8XERftc ZE>O :D.^1fll`GkX `at:&p7xun61'^gض:9z!E6; UCk:HQuXg_}~IENDB`Eqonomize-1.5.3/data/22/eqz-currency.png000066400000000000000000000020731416454732000177670ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|d pHYstEXtSoftwarewww.inkscape.org<IDAT8ՔYh\Uνsgo3MڔXmX* \RD$H"VE(%yQ54mub2[23̝{=>d 3m#88||ߤܠ *l@TV;lp)RHğ o V+]]o5)B$ROˤ'O4P4נ`*^泜:%esTZsGqw*fa9h.|+n&9řB Q;}94Z|Qi77mbRh*)XP~K;@րhrG[ʮw߉]ȅT+ lMFxZ|Yv׃%`t<ƶo-Yķj+EqzRł\7\0MqD4,c C'qzwa6n*KΟ~<T-@tdO>wX,F<1Gm$KFHŇH/(dIE g4Mm]3/2`KadTqM*t5:9Ǒ"cF"(%PLrij$횈uC~L%޳eب.7ffZ[$nwO>,g)@HD[_r& FF."nCw viMµ&OkGL&S$ÖY"11AGϞ73WbVj__{k{sW)PM}A4MEf>3/YvNgB~&Vj.R k`^y{kA)jȖ6^UnѴrk]\w8\QTpeTIENDB`Eqonomize-1.5.3/data/22/eqz-debt-interest.png000066400000000000000000000020151416454732000207020ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|d pHYsXXtEXtSoftwarewww.inkscape.org<IDAT8_H[W'v1vht8!^!IJ.-dN4֍2 a"$2u׫#HKB6q,`еn3+177g/fdm>a;o }\\J!C=w^-1J B>yzTUU$qA8]1 cz_Pu<XFB"X(@Ҥό_fzS̲ TWxXc---Gen׈b^9n. Q̷bU1+ 8v{eLX`Yf \~= ;>-s6NZ`X[[@PdM&O!YZh4_kkk3 <[t5JJͽn}38R-088wB醆L&+zTd]]]N~ra P(e"+{{{{/O#Hc`Nwssskfff:H$Fqh4nDI-˥sX쥡~Mӯ p4+ v8WvggY~( /bZ?qww(:;;j?qw455D d622<ϫjuFRqųA&.ٷ:#eIDwBş$( 1&e2Y"HnZ?(jqd2; 4rx5BL$|MP$ABp a"cZp]׭olK_O'y_9ߒնwHިm"O/ f1C#w'N%cݚ`lw5DMjd Yuk#ۡěg |Z[@(_N%X@Y qZ~?~r;׹ =*[5( #}M;'3ڙ6o9Nz؞^rw VB9\>xPrOy2?c<}gbu=߼ڳm2g_0t3# H`,3RJq\\ܤ5C"`12La E[fH} p͕EȥaWUIENDB`Eqonomize-1.5.3/data/22/eqz-edit.png000066400000000000000000000012331416454732000170570ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|d pHYsXXtEXtSoftwarewww.inkscape.org<IDAT8c`PHt/~C _>pyG|1kh/XGtVk[ޢ"24H&:{ <M 3f2| õ_:k~kb';gw>_aw Q\@qμr[}̙>g _߽|sM˰z^jjJ }4~C>?o҇_a'-Vr_ax% 'fip`E'n>|_|ח|52pY~~~܍O\#Upz.?` 1KPd+^o_xg˜]k N[9~29m;;;;1000ٳg10 qFFFŗ/_)1}ٳg7PbA_|Q0%)w@wzL"dIENDB`Eqonomize-1.5.3/data/22/eqz-expense.png000066400000000000000000000014451416454732000176060ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|d pHYsXXtEXtSoftwarewww.inkscape.org<IDAT8OHqǿM2mS)LŨ%ZNA'C' H*?)!z%$5J9L7tw:Ay>|y}H%MD=V#e] u}`$l\Q:dYxDt=f4(Q ѫ(X*̻*Ul*+G3]9v9E4-ket]^cEn%iY`,ŅYxOWn;>~X樮̨#dN^n& &KPegթFjk*k4{sGkZ.#H8=\~Y4XnUU7J_8 Fs>xD01apx,*>F1͊wCMHNQ: E3xBt`{NjԮF9yVP^Q -E=TN!L6ε% ~t͋n R! "ên3[ a:c݉Nȩj$ކz G'#$q7=&u=| L(E:G1 B  kWK)ÈA4fXSCgtvb!Sjj %yB гG5ƴ;g_f>OXD;IENDB`Eqonomize-1.5.3/data/22/eqz-export.png000066400000000000000000000016441416454732000174610ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|d pHYsXXtEXtSoftwarewww.inkscape.org<tEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/pIDAT8KA?ɺ%ZЪx"RCŃPT(xP{nZ*zSw!'&lL5^fSE 7gx S8OF ժz>33󥣣#p\^^4-222b mmmXXX`ee%򯍃0X,ۋibx<ࣣ#<Q|qqq7pgg'X B---[iH)RzẮrppieYe* R ۶}jw/zoz``Oaww![[[uRJqVyup>XUPdp;ߏIIENDB`Eqonomize-1.5.3/data/22/eqz-import.png000066400000000000000000000015051416454732000174460ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|d pHYstEXtSoftwarewww.inkscape.org<tEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/IDAT8ՓPO"AL ~CNTN])袮nEBp,"8u1.. *B k"M:J֏Xx<=HԵf$ynXh0EQp*8}M&a ?V|dX\xVpQr !Hh4^-e ǚM Fg}>E8c$ɳ^[{u3iPU4MK,cc6p8`ٜ)g,fe9B9 /N'($Ih6( lv]Zz`0xUVRt:Ϳ4 Z >T@ RZ M4!d0|X,mXV(H$9|~m6DQA&A4$I!zq8O=;>d2l6tݳvk QUUJ%)W(WcPda:~2_aϜ&|IENDB`Eqonomize-1.5.3/data/22/eqz-income.png000066400000000000000000000017351416454732000174130ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|d pHYsXXtEXtSoftwarewww.inkscape.org<ZIDAT8_L[U?ۖJ6aȟ H![Dt&&3Lgun,t31L^&d& uC&8Z ZRJm_j)nv~;9swr6X.\SBs9Q5??ki65>M %eS;``AA7@o S|C mQѶw8K[=˧EGl}-p区XP '[L dXS\b@H $P|E8ٶlYӨ_a$r/ CCz%~rmJ^&S#S*9Dl2D&@_W]-6쭮[ 6YI_=|MW]y==݊_2OW?1C\.v{N>sh?=<!Y& Tvwd4b;i[k5qPMȒN[QydCe ʍOн5Q/+qKx<^R+IJ8vW=͔3v;}W~sCVȒjkEUhU~/_a3MNME4#Gc A*[&֎lMҾkDBr2XV|8B7ʊBy&~MBRX ~균GTIǑ {F-۩]W幋/~p yշ@n +G 9V/A`R,y24 pK#[aڲ|O3;C_q+࿢|w \TNIENDB`Eqonomize-1.5.3/data/22/eqz-join-transactions.png000066400000000000000000000015751416454732000216100ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|d pHYsXXtEXtSoftwarewww.inkscape.org<6tEXtCopyrightOpen Font License http://scripts.sil.org/OFLIDAT8]HQ9^lbj&-RiC$I0tU؅( ڷ]4bd63 VFcͽ{Q17y_ /ܼc 9\L n<;bFsV\\C9AKqD*;ey^.o2^Ɏܜ, ك܃djpqONĶAgeХ_qnQ TSTN:.*V{zzFGGd :q3EEEgt:?q:˘_].W|UTT ÀRxdNw%iwLM5D[itnElE1È>@lی|ҼIENDB`Eqonomize-1.5.3/data/22/eqz-ledger.png000066400000000000000000000016261416454732000174020ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|d pHYsXXtEXtSoftwarewww.inkscape.org<tEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/bIDAT8?HQǿ޽ӣlhJ pR.]l.] ]tBAL%P*trTHP\D#$уSݽh&K3|8_$JɃMƘԊp]/ ʕs%N7VVVVoÝ !??Bݕc}}T*~k bT,Uuq||,٬hZ Fm6qȥ%Y.c)[[[VɩoI;qRy~NJpMM.t](8lggGua/js&'' -&4v:h\.?ۋ]%amEq]Wmacգo z4M? T*u!8#[SfyPFijIENDB`Eqonomize-1.5.3/data/22/eqz-liabilities.png000066400000000000000000000015571416454732000204350ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|d pHYstEXtSoftwarewww.inkscape.org<XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/IDAT8ݔMHTQsʼ^ݒmy7#p< -˺i TWW311a'IӶ/} $4f(z,ڪ+pɲ,4###߲aO xdvqaWQɯRJsss 4ٶё*7H >ۇ/++?{\YQАnxh D[Z10PT !̃94+Hp̢Ŧ29RJp'ܦ~^#T*SUU18ߜˎK&uEyal#VF nrxtAĂAqPmߕ8+GJ]%J`2;; q mx<߇ݪPUUVTT8eYX]]죩·F;0|Zsi#&_v()7OVryuER<~%zzRZ{`0FϏB\@2IENDB`Eqonomize-1.5.3/data/22/eqz-overtime-chart.png000066400000000000000000000013211416454732000210610ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|d pHYsXXtEXtSoftwarewww.inkscape.org<NIDAT8MhAw6Mݤ-T!QP=Tb6Rr(^ P$^,JjۤIhI4Vtw5U閅$o6La o:mjQXu/P>m{^x. U;[Vk5 RqER@f$V_TJ 0:6AbMS(-Jv8 =*ˋ/$5):P;chAS鄱8ihAHs[Tzƞ`SiV !@qv]3 U IXƖ#_Գ ҆cvBׯ_ɓ'2"ERE+JRJk766d>aϊa7UUģhkx>ݣhEa'x t:(iqX,i!P .KDžBQqX+XZZZ*r=J__/A:KKKs.]'ONcܹsZF.رcݎzbXr9qƄmy}u.AB*CCCd2 RJLB9qa3==Zl($I$#Du?~L^'200SE&4;T*il͛7-Q%>={>r 9sMp6nŶm|#>}۶cܺu艮\UU\Ų,0D44]G7BJڶy4X=T*jgϞ0+5&TUU,²,i' FFFmuqR鴚:i8x!fFATbttl6cVVV(!~|ʾ4(bk6[8t=ﮭicccfrݻw8Bk^T t]rM\7͞j5ZAoHfsBMӇm?BuP>IENDB`Eqonomize-1.5.3/data/22/eqz-refund-repayment.png000066400000000000000000000020511416454732000214160ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|d pHYsXXtEXtSoftwarewww.inkscape.org<IDAT8Ք]LUƟs{, 0cuMt}yecfG\Lf&~@M5ۅ$KeC [^] c-o~x1YB;9wMd(H/ǭpLMd/@Bo7VTӎb %͙!@#aR)Ƕ/k#&YNbY^ƼbL"!I"Z @4E(륌ToR(m뱹9S'oXꦔ[VdA%ǚDF^:0nʤnƤ&X;+)v 9\~&рMSk;)2&txt?@6mZM`|d>~ L7RFUȾOguoFw)*VW @wCOg,n𐿴dTz_>b`T2@AjAw[Ƌ-}ހ鑚? -дC:!/77` XpG#܃L0 pzA Y6ҷ~K )pctaab1lLr!M i Ϭ]i-K# G᫯.O]>d"XqLn$®jWbhhGur EpSHOQշsBs e2h(VpH%gq ) ǿOt{\ޕ&:E=OI8w+BbFkN Z*Hn$S:fqxl3yG=vb&Af02*e $,6v2&ڏopa@SYzƢIENDB`Eqonomize-1.5.3/data/22/eqz-schedule.png000066400000000000000000000026131416454732000177310ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|d pHYsXXtEXtSoftwarewww.inkscape.org<tEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/WIDAT8K[gǿ眘hr!&3 kD-l*XfC Bo9,bvRF[Gz!$Ĝ֬Y.{~xx'Pa;6N"l:Hggg߇ufL&Cl6 hqt:]A_|䯗w~ޞFRv $IB2 Iǝ|311 ޽{@ зnjjBgg' 0 ^>,#UC} <00p>Uu4_P 4MZ-\.L&>&}>Z-۠i _I(SsENֆV CU@l6PT: ,6Iʔ ~]]]GPL 7j @ @jJY.BVEhooNٹ(eE]pP(btׂ23D"AOOOYvyVN@.jkkˌGGG,nw'Ipd2^O_X6 sssGhP2 N*Uf}xܶ@ P2uwwW^hkk 0ͻB^]]]zJ}}Xp:0Le#,Cx kkk_E"bcr={ Vf$IxEQ`2]ȲmD"x^<66l N4%$IA ьL&]DQg>yxzkчB!2J=|4MT `,#beYHn||9~+I9eYEQ4\*'JAKoo' }m5IENDB`Eqonomize-1.5.3/data/22/eqz-security.png000066400000000000000000000016441416454732000200070ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|d pHYsXXtEXtSoftwarewww.inkscape.org<tEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/pIDAT8KA?ovtw^NDB"* ZXX i;\buW,{I!sޙK ޼_yD!"7rc@)UxiAq/^LLL|#h2zc :ZnQY'ʤd$hP1ưI\9<\-"MSNOOamm\Ƙ7 :cAE :gggR +1&g4::T*JR_Х"MSR8]w#Fv!nooi6A@EK74R=j5<0 q/ ""-n.?r֦1IE4MR] q|SՈvyqlllPT888:d2>>z"\]]Q*X__v\WWWY^^Z299I5/+AXajtZuނ2ɖNkm I<::>==jbu~)jd8IENDB`Eqonomize-1.5.3/data/22/eqz-split-transaction.png000066400000000000000000000017401416454732000216130ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|d pHYsXXtEXtSoftwarewww.inkscape.org<6tEXtCopyrightOpen Font License http://scripts.sil.org/OFLIDAT8]HSaﻏs֎֬eQjlvy%]uQ0>,뢋(R0L4jv69op`Ϗ?bƘ15\1f%Oc{<v_R0Ē׎\9UV^pwޱo7pBCJʜyysV8oL@ 6zt,}Vx!(c-|ԘŞdV`47,(OcNj]@!hc'pui~1*4ں]e'5nwF$ I'/ESqbNHVtVCfpTI:dߵז%z̫ (c#M 秭Ip̅Ʋ *%X_>.#Bxhƫ` VԖl/h!S@gֵ͠`@\keT+xJLvrA!N]@F<0k G9[W8fg/slWXxY |KcD-K"3ѡf]%@1[k*vzj'qUl5&RB` nh^QV$Y ,`j̢oY'6& <LPشkJ{o#<8(*֦k~A ::ڔP]?;.&VE& -%oe@~QǢyF9pzTS,ɊIENDB`Eqonomize-1.5.3/data/22/eqz-tag.png000066400000000000000000000024721416454732000167130ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|d pHYscqtEXtSoftwarewww.inkscape.org<IDAT8[LG9}{dEXXBKC_LӦć>5}k>4ML5&& Jj\K날\  5[cӇu *=$s93& Hu%&X,rJKKK~z5]L>kt>6PBr$X_*#]bCdH$ ۚƯ7̝+@hߒZ#9eoKuY\,@6 -^FSRPII0uD"<}HL9i{ɓgƮOaOc4PhI$(ztqeJE%% Z3^Vy15C~>ȏ>L&g9v/Z\ww,[ ˷#&9kndFdl"-IhI%- MBK@%[OkiLR'B 'pA-! m ~Hۆm r,a:p,@m$`mW>/.B3: 3rZdFL|'Pp& ဘ.@ i@sl}@NC7gti.2gd֠X3!3!0!pwo8 Jå5u7g*DlR,A#W# 袈$b%Ғȑ: 8WVV[iHO]SI/ HZ"iHI* G%&d'G+SWp\oz>f s s-+^L'IIICm/:z12 *⪎u R\tai(l$^灋쟮Ccc>^ _W \m3j)3> pmE#Md(~y~coœQpB5̝aa&]S. יw VT5~+Z@D5ܘ54JGUCLý_=X pa(q"r*Ne+*T@^ǁ#& `$HJjktx+ZWUeV՞6H6l^+?L]ÐnIENDB`Eqonomize-1.5.3/data/22/eqz-transactions.png000066400000000000000000000016021416454732000206420ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|d pHYsXXtEXtSoftwarewww.inkscape.org<tEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/NIDAT8?hSA?w]^Ҵi-TE)BkqPp(8 " AJZ:C v#-k^JCfxv><'^g񼞉~F(7) p䯈=jg &ql$U.U@x;1<*vXl y=-7RaVqx,yTleeoZ@H`@}=`‡; @e$X1cd= Bԧؑ3wȜ 3x63e{iσbU.?^U=H a&9#3`Cn*O^kw[;/ϯ^mS!/[*7p`X(Xy4@xwZ %R Ӳuk -Qy7gK>>;ެؠ_fˬ %y@$ھwESU94.~<DiB7\y1 2"&xZ.Ƅ˟v$xҤ3⡄JW b*n-Y]e]xrQ˜OyS\qm)ټ~c9hČ ۄjhk-&>7JHrkxN& >w𕡎mnP*x\v-GKkk[v: ^7d \'@Wj4*VW{PS] 9 , 6]M%=^$@Xl! FmC$+I)W.Nt9bٮw=A ))IJP<{@|"^E נ5}+L_rX,"ޔ32)o *+0464*D4??~nᬈ-IENDB`Eqonomize-1.5.3/data/32/000077500000000000000000000000001416454732000146315ustar00rootroot00000000000000Eqonomize-1.5.3/data/32/application-x-eqonomize.png000066400000000000000000000032441416454732000221160ustar00rootroot00000000000000PNG  IHDR szzsBIT|dtEXtSoftwarewww.inkscape.org<6IDATX_lW3w;qSgi҈P '2)Eq(UI'$B*AU>4E ^d*"$FHPkS{kνx;^qo4{Ι;*ׯ_#}Gq \T[T46u'᪹=ϟI N'́Cs.-YfaXh\@6-I7jV gpQ{,ؓFP<@RXD dG|\V$w39O]W$0n+&(TքcIs!Pv,FŐ( !}{XQU:\V $P\TAQ%}Lx "vt";G[**cܤ@Gipvdm:w/"Zqncbmv833C.Gwy; QAUD\wνa~ګ<ԗַc=eʔD<=O&ӆTqvwk, !S  PJRc֟% æq@>_}/Vy2d,WrB,Jn7J`ee7qӗ7WIt}?૏G 4yȅHxSْ?%}䫌ŋ#8qqdz9|xAF:/>ztEV5 lf@DÍ~ŋ/>PӪ'8{}gVg^D\ŷ206v7Ϛq9Z&ֳM5=>NP )˵/N@+&z l`UVU _:/ #QBŢcykv*8ntߔ>eS<ࣱp7( ?y@k)@%ߚ$͸'km̪Rě/2T*QEuv"*ͽJQa؜S.sΥSNJ~[ #Gw'=ZǡC?GimZӅ=i븮K\fzzӧYiGUz+ïYkcz5r]d2!w<ǎ<* Bҙ3gw NoK $liֲgn %_j~~^ ,RKg̝{9>~̰@bgrr<zN˧Z0:&ς-U{!E $Z$I".w]nZo|}/8>=lW}c9ր $H$9ɁT&_U6ڲ۳}WW_zt "h.۝i{*myb  Lgz(.EpqJO|ro֏~ݱǂ{R}y.w/em88ĉ!"K?uV`2Ew?GbɃ]AsJ[o#8%h -.SrV W\V|z v, ކ`!t:J@əⱸj5Ϭ}:uj{+}a*RncE‰ƕB1l <$--l&yS,d0>^%bkM?DLк}#5OKg ;ZwNɤ"gW7 R@~hLT 5 ,b"#83Ub#+ٕ55@,W44{=_l( {ڭA(7TJnfjr\}$J:u}CD^xsLۥIENDB`Eqonomize-1.5.3/data/32/eqz-account.png000066400000000000000000000017101416454732000175670ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs ǠtEXtSoftwarewww.inkscape.org<XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/IDATXMHTQs}aDUh | ø+.r*Z(Ԣ6m]Q! ȕA1>ЕQ%Prf|T~L~L{sJ:\8q,˺s~GJyFӴr4ͷ0۶B{Dt\vuuq4166&5M>I)H)fffM]ApAvwwk(++˯(MNNB)z{캮w,۶WӴJ)#H'ڊP`5LLL`dd$X__猱J4_={44DB,AqNJ%@ `߯1*bEZZZDL02F:~;־oL<QUU*rb8m^__oASS|߇F:~,Isssu{{{fvvh-J&۶pvI.C𚈾ܻﴤu|IENDB`Eqonomize-1.5.3/data/32/eqz-balance.png000066400000000000000000000035601416454732000175250ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs : :dJtEXtSoftwarewww.inkscape.org<tEXtTitlescales of justicekYtEXtAuthorjohnny_automaticbM!tEXtCreation Time2009-06-26T04:35:18QtEXtSourcehttps://openclipart.org/detail/26849/scales-of-justice-by-johnny_automatic>zXtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/IDATXkLSgǟXbKE$谛! 7}M}0Jhe&Kьl 4/ 8%)6 Ҟ9pIw;='J1SSSYz,"p`uEDq8s̙eeeh2{^]Znhhp[/1#//ϲyf6%%Ų^hׯ_D>#[n3͟8qmsjHJJB zEVcp\͛O>mSաP}}C"Ry}}}j嶵MVVVjniZeeeݮA,B D46B/[ Wù`08??OJeKNNίRi èFrߟlx"D }& >86˗/ܾ@D !>˲RaC7I͍;\Dҫǻmy@"JreY)˲0 o4͕?S$NPTTdXDDSo߾C333YI$^^^(˛j`088n@FFVXFfDjj7t귬"DB 4,nkeY1"f+X,~RS} [b.DZ$|u^LP yX ɲ7[1::r~>yN>y3ټozch3~tƔE@i~pb^6WjIIIC<ؠj JQR)!&@fݝIӝ7ͻv8T* ;+**+ʳK |uB4y_Bޢ`-A>}0 `#xrmjjaFch刘VS᤼K.>00PaZN3Wp(ؒouuuJ:V&i/EQ!X @ x<m56;Q,lX(Bcǽ*GB IENDB`Eqonomize-1.5.3/data/32/eqz-categories-chart.png000066400000000000000000000027261416454732000213670ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs : :dJtEXtSoftwarewww.inkscape.org<SIDATX]hUwӴ̭d)8ʼnccc"ӡK E7DtTSD8p67]նilm6MMޯs/cy9<Qb4'1F3v?!(^t0Y>?K~}g "=9 IaA0^0"5; iډ7>ecpx@V֭'$/dvw&ː o133*擁>t~D"b501HP؊G];a[;w| 5: Z[k CD`NNlvXJ[%kp)sCkfg!sZ>Xlr ;l3oABT'Bvm}|l P(r6;v="VWiP) j M#R7Ԟɜj0T'Z CJS`My]@Ԥ,`l5 0 I:  k>!TjCg^ Sg$å(CLQ`emrѲR͌1]UTj/&vUd#40Q)&2MeٯX |+ݛ1tPX"ˀ ;(RU1WHyHb wu(見|2 @l9#w]Wϛ'N#2TYX^WU==n{dtT> \ji90rs"!pϪmWQyF%B6mn Y1v>X ;Z7CWKp= OPB_Du>PMjhAp,!sojRgҺcAUAl/Ru0;#-fsϜn e״U@[^n{YA* T- 7aYNpn/&;]Pc:8$Bv~38~ mL[]_nYr",ys'ZҢSOZ-GWWZ OK|c T1w[ݤn "_R5!#H.7vlћz;>Nn'{wW?q6/s! TG\XЩeoIENDB`Eqonomize-1.5.3/data/32/eqz-categories-report.png000066400000000000000000000024751416454732000216020ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs : :dJtEXtSoftwarewww.inkscape.org<IDATX_TUޙ3u L?$JTԃ aO-|@z%ȗ!H@,"!m02]\w[wa?;̽Oܙ{f}0p}ssb>8sxb*}HkmkJĊ7?Gg / QJ!"jE|:!%OyyWw9GBrׯ |Q2Mac],#b]IJH.t#$FF qhh-֔]Iy8,W"bl#+-1 Ytw4*858%R*FE4YZEy4V/2 rX(/ K[8xp_h|!/_f׮]4roqzWR=&gY^[)DkRH &2i\8çͱdLW +Gmr{jDY (rL%i[S>ìoAvQ׹%?od2TsYxknCAzNxZ \r% =7~ {T:_M5w)e0jI5&a4ڮ럢a?ʎۑJrak\[enǻy0 Vl|d'ґx !P)MZkbX`p۶+ P-I۶Bhttt:3JR 300@gg'ŜNdUHX'֚I^D RP|>gFzDY¥(rKٯ:8yh&ArJ%}@2,n @u?07VJmj@cnhy*0MyB&].yoݺwa흜PD"g ~ћ*v5dx0MI&ehYΝ KIk,H䗊 [H$9lO"`bb"ԡ[(rǮ]+Ct̶[k=}ךkJMwIPJ3 &˒[piB|_\Pw=QҬfٲe;LBaЦřiNz!B~/6"9+WC@m+0 ͦŷpE0 ;O6:S!K1<RHVg\)ͷ) ՊTFh6J]>^FB֙KCEm\h5k'A:Φ$0d0F%R(!СKT;QzisBL^ۧeh5.%aq~\6 Bli%|Rh%=_sr mj5_0X|y?},0k6P$yFTEru*'t&-9w/T*rHl9BUQv7BF-EWw\isE+Nt ^__zJ:cll!"xўNk2:9pQ׎͟E8|0[^ %4=W^} Z BZ)J!Dz?~ݥסyQkn8 }D- Z5gfe17J7.P'>ns_i DJK7Z^8yֽM"];$нiSvz r`]p|svKw:B IENDB`Eqonomize-1.5.3/data/32/eqz-debt-interest.png000066400000000000000000000031561416454732000207120ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs : :dJtEXtSoftwarewww.inkscape.org<IDATXmLSgOi/+딺(e{5+UX\ԨK]dsnhtH H`fD@ަP:'-ig_`Xn{s'zYdJc$)11Yo- rW0NՂY?aؽ_E &6D3X LՄDA Q4:z!(F~ss㸝@ H!$A⃃9rdݾ}{d*$^OpRhr[>6qNCrA%Ҭ;򄄄{j !H$w(k|1* JQoҲE**d6߈yh6m RJ_m޼9@)}x0CwFGG|<!9954ΙׯZjՎ9ٳ``` -6"33ӯD 'L-^#BH R^jjjݹsg8/2hRQ5 QPS@WV:lvnfk)-NʁٛZ+쒽97FWl5˴NS ȡźeUr+37-rxnƙAz풽9$pت7zZ;^1۫!>&","tp֓fĝI ʷ#~qi̖.KJTTdk 4%P-RQ`B@g+=҅~wz)t eZ5  ]4uqR';~hPL-xl'ͶĨX4Z!,Ǒ<%E8'--X,.*SdC ;.dnK eOp*c@Q5wK,UG,¹k"2c] @ fhqs IdJr!b`]cF/Ogb@Kc}p?-}i,Dhj_[כRN>H Zf߶>0jMS(?A @iKS6{-:%>2@EȺQ1o>=c?w2glEIENDB`Eqonomize-1.5.3/data/32/eqz-edit.png000066400000000000000000000020441416454732000170610ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs : :dJtEXtSoftwarewww.inkscape.org<IDATX_LSW:.3QFM3̌9F̘!-8`[75f%&Lće{dN"13a1YZIX`X!P(^Ti)ܜ|ιsϳf&i5 2Q _fChԂt-חwKG8}.L =܏PZ}m+t/!͊kW\Y ڍƼ|HN=|0qgQkL]aFZ+I 7kr{p LJӛ _1JݬA=q\6a9.؜Z*IOsf `L0֋'\9.\skѠzj$6aF$sPUc]Q~qWPD4y}|+tRu#Zwߖn*שׁ e!t1,@&Ųsl-֛oEz ?.`|/7i͌ZٰFXWKvDYnvQG:`TFm.wӱJ dDD g<xfEY-[*֋P(=% ?Angއ5;S w'Ds]trK sYeh*y(-N,0:cHòI}]qv'x-|1*W8c+~ L`;r#W@tlلOe}"^:'NTmWPVVVCCU B`Z0+j `?&#@EEy@@@xN9 Hd$I~hA_DBe}i=؏R?IENDB`Eqonomize-1.5.3/data/32/eqz-expense.png000066400000000000000000000024261416454732000176070ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs : :dJtEXtSoftwarewww.inkscape.org<IDATX]lTE3snwn[JKŒB "BBb'xHL4!b4L ~DMԄD|Ø$iA~v{\ l?Mfr̙9c#ZK1v*ԇýO=S J,&g(uVza-x9[/i[eci[8? CQƶm ,Kspus~߼e~<%;WUS}}XwwnBb͚ʊYLqSt676"|6Qީ{{ VΎGij\L6uAI̫`2w)杽{_YQ{)N32VxDJJQWL>3]L('XLZ n|%|xvd,5Omوp)rHp4B9*5$Z@W2@2ո-Lf \;G&4 HQU tQf5..d vLzyXg]ecULf5׮ ! jΟ ?u[ .،7Њ 2HT1{=Œ24mK*cq9>?vgD#bQ Ʊs}v8:cGK.<y 1=6ٴD3k¥f2±F^fIwD{&PW@1G".## _pbC{_>j`l xof,Bg`T=i+58<:::vqPO,/㍍hǵnuggg, mqP`&LDXM,(~~,KR_%IzGQyKtͦy088X13̃ǵx@8 2XM`Y,BiW[[0'D"Z<_~(Bk'!0XZZZM&o`~~ cccdbb},[|N3==}tty___U;I>uww(ʹki nbQ|চM*!Um*JEq-022n IhU; e_L8cڶ ['۶qqqQn@tI:Vt/ I2,IENDB`Eqonomize-1.5.3/data/32/eqz-import.png000066400000000000000000000020461416454732000174500ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs ǠtEXtSoftwarewww.inkscape.org<tEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/IDATX헿Kaǿr^HhU0VPũKFE)TNNR(n2D?ࠃDqp9.LKvlqBw|>~<n&&&R~׆1'nLsssWrfvvv>w b|jj*>dYv^a H`tt4=r NȈ퇪h6psb{qW$!k& xsP 4 GGGcfsyGaFL&L&XX!333\.4;>7ϡOOn-˂Pj`Y* WUUAo(>.X,Zgz=L)]__7dY 4ӷR iZ`AQlnnX,baah=d2O{{{ l6p嶶( ן<: H P/%b46N)MהRhBDQD. buuUs NsJJ?J%1 I\5S0885HJ})G>!),b'\M8;;͍u[T044 Jaxx¡#;z)es&B0wH4p[򏍍7>c4:~4|tRIENDB`Eqonomize-1.5.3/data/32/eqz-income.png000066400000000000000000000027041416454732000174110ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs : :dJtEXtSoftwarewww.inkscape.org<AIDATXŖ[hE=6I&MZMmjl-D>j-"F+h5R|PAxmhTksknٝY6i.hٙ3?fvg<)wg>bmM#%eö?/1@L_/|ya;} @!Il;R|iugV802nJV55 !7 ,a#>,0 % ̢fxL{/0U)0f- }d& =sM<0 5prC (MV+ IumG3+ s F$AO>ndN$)CJ]/7F,:Jc}G;Rt4е@: ;^xw/;GʊJbǎAKE$xD")#q-tUeIAgWMJRt#ncFQ^p-RjT8>3x,[繙@8"Vz%`o!t n~ohR'3H4]w*xSJJ4bJJV`\QF՛m@eelߴ_*ˎb1L] e3 *z-}SU:M'l-S9ƅ\Cccݯu}oP*RgPcgf1i=1AX'IENDB`Eqonomize-1.5.3/data/32/eqz-join-transactions.png000066400000000000000000000025701416454732000216050ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs : :dJtEXtSoftwarewww.inkscape.org<6tEXtCopyrightOpen Font License http://scripts.sil.org/OFLIDATXklU罴}we::::f-m9/x%FTBApDA5*N(kV캍pC7w+=~aXdžX6yy>9m1.\*u0^~:WNQ JIMeJC$r;+[)XRhl}A)}k=8 f^BIENDB`Eqonomize-1.5.3/data/32/eqz-liabilities.png000066400000000000000000000022021416454732000204220ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs ǠtEXtSoftwarewww.inkscape.org<XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/IDATXOh#Uǿy&c&-%8jP%I\Ԃazj^vAZԃuAŴdB֊K6~RM4˼g~oop a<}j.rB<(J\1KKK`PeT__/FFFX\\(!>B|JD```ɲTU}϶:;;2<<¼u,,,220HU% 袢(oJ)p81G?ޙLX g(ubs,S s?B c pmmm^pB\J$7T cMH4U, nm;LlBt=Va333T+8E"'璨o{׮F,HYa`ʕǮJQLuߕ_eC*Ih 9 >'FuUr6cvi!Yf{"m-|7w 4 ݒ4a Dm\W/\DQ8rnn {df%2tò**x "cb`@K^?9c||peG ;@'1u+,(d)_ oDjJJ+""NAv o+MIIENDB`Eqonomize-1.5.3/data/32/eqz-next-year.png000066400000000000000000000013301416454732000200450ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsttfxtEXtSoftwarewww.inkscape.org<UIDATX핽OSQO:jedֵ38A{gM\(uP@JMPФ1M[& .,8=\<MνŸݟ<9_W瘆d"w`r\(~<77M^RTjfNk=di-ɑA<@l4mߕڊɻD\2֚z}`dy>ZkQ8}ߓ?_l!0whIENDB`Eqonomize-1.5.3/data/32/eqz-overtime-chart.png000066400000000000000000000020271416454732000210660ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs : :dJtEXtSoftwarewww.inkscape.org<IDATXohW&MJkZd5mV:1(L m ,nC7nnX,⊴*NT9Z˟&M˄5+&<}/D%1._}ՖN%`x&#YH>9kV6[=$+PZVVծݞ;4 3Q5v)¹3&3,1"(U,6eE==*sjIh.y7\wqhʦW'P(tqTUVrUrs5 @W$7~GoF/E#H~B[_cr!~FϙhE^u#3G$w۷R~GUkw^K5_` <z Aё\;>6I5O#FIWT圢^Y8>2<67E&;cDs%3ZhuNTZhj[8}=~fbL=!PR|Z>,KGfUF;h3J!; X O62\7yDTPQ,~hC0Srvw]GQ3^!2',As3+юzSdxUj3 πh>ֵn,;b' [RJD}:!yŧڱrp^A~p9mfo:nݻi_㲦dT349hJF9~|[* -f󙊊VJ@233ono 9c2]L'݀\ =IENDB`Eqonomize-1.5.3/data/32/eqz-overtime-report.png000066400000000000000000000033421416454732000213010ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs : :dJtEXtSoftwarewww.inkscape.org<_IDATXWMhYHrd)(UW@nNaSRn!_ 9uq҅$0@%XlCBɡĐ6d]9򗨜b}XѼ`4H ?x0~y;?O5\xE4BN}϶7R קT"1P%ZL:R8{_*[~d?}'ّ:,|3.|~Nʪmʸ.[zU5 FFl]F!pp,U5fQf -ޠ4S.AACM5P&AU$T՘4`Cm0RAyR&Fa'~/( بVMF 2םb`RFiMXI:@THXu8,c X Y0H]d mbBarrF^xܹf v\9Q猱A8hix&(5o!D"4M!(Be0:Nb1w&6p{{<@Tij܄ P$rbll!w׮]u@*B>7-L&by333"N#cxx `kk L󶡡J/~611 p.ҺP+j2J<Μ9{^-$`W90==-h6z…7nƔCve>}ZSJ199J`0ǏCe]v!I6;888χǏcyy?FEQsqhFfv販)PJt:q1<cn/LQr[[[Ƙa R)߿p\rNv;8T*E.paZ!I>Z!IGٳ/_իWD@ѣG!XXXUU~bd(b@0ީ~Yqyܺu 8y|}~vA 8x <@Pqd2pѷdkX077ӉH$b$]q SS Cڊm6AxdPVt+&&&zq|>ݻPT &L}yc " EQt<8 }x|>_Rgh ˲>Z!2nN˗}oo/޽qqxEA&:}ӧZ&'Q155%Iœ'O^^3m~lp}-X?dυvaf{ĉ: Y8{pPr9ܾ}`%n޼hP:uJ BBСUra rZ@ *\.#LÇ E9FD()ׇuG.v`'|$H$bׯ_ =G;wnn}0 q!b]U|:{\""FI6`9s+twK=&9IENDB`Eqonomize-1.5.3/data/32/eqz-previous-month.png000066400000000000000000000011351416454732000211330ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsttfxtEXtSoftwarewww.inkscape.org<IDATXMk@4Nt{h,[FQ |S7=,=Vvv>\ [zF[)E志<,T0 B-+f[<?`gG0真J`0@!Bx>ɣ2X,&:"^=Kt:t: RF JL&MN1viGQq_=f@)X,?rN. m/zN1vꎰmGByD~#;O4mۋgam(Iҳ0IQJ; hrE)]+s1r "L&DV!5E xA Է"\iFc?@ϒ$]0>u[3XkۗaZ|>_^Z L!t]jFx2X,:J44d2yD6[0 hlIENDB`Eqonomize-1.5.3/data/32/eqz-previous-year.png000066400000000000000000000014211416454732000207440ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsttfxtEXtSoftwarewww.inkscape.org<IDATXoAVM6R1!Є} a@MYrorx3K-v M..%ŤiVcw|L2 jP\0W`i{{QUu$˲ UU/Zz\$I|>0mD^?33a~R1`!(r㛛,z-|rmm#<x("Kf ;ORTUUA @ `}#\^__DF6mnA8 h4qX,-{GWշ`}!U wQӴp8Lμqij0+0EJM6"INLZf)fS#g.OMM5+y~,sWcϛ^Fn|NwwwU1B85MBEB+Ka 2A SrWǃǦ,/% B+l6{(Mvc,>U"cX|JHʌD:F$y7 Ah%DQ<=IJ ȲbSJ̋oדkOݥJR,˒;1ߋĩL&'cbH&8cO c<:q,ANa~IENDB`Eqonomize-1.5.3/data/32/eqz-refund-repayment.png000066400000000000000000000033101416454732000214160ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs : :dJtEXtSoftwarewww.inkscape.org<EIDATXlUg?{0RuPQm2tlT?p&LP2H3"eX1G ڎB\._`k㛼~~=>M]nA f {o*zNBrA @T^??\k.s@B[:l2WpCܻʀ]h"J>`oYѶI[PDEhh i^PtY,"JzGd}`M}+!P{V7Vhm~}m!fLs$lvHhz݋Dwv& I4%7~}Էb11MWee'E^v "Z?ם0_ GQQ K;jc8FkZ.Aog?3}hzy`nj޷tUU( ZDs]gȄ*jYɉGBp6ڞ9~hc}]z%%FiE]q+us:ތ.ѬЖrVOmZ8sdI`(&Eɩ28vo,h( 0s|&3 yńwBv!Pl)=o^4pƀװh-ӎzɦ'eqMY ~"3x[B['&i ƣKnys۰ǶɹI:;n-f DKle2(ܒGO\"UO<|Bҏ6od&ΑIMK|*KYuPXҪ)plg3 !L?&: Gg~`-<lU}"rn/x@?şd+'FūN,15GMKTUG>NhL`"@p o 6\)vt])FOiL)R;TL j,"xQؒPo*tv)n&Eyb"V9É.r,#)`uUhpuu=tw֦e_ [񤖂/v`|[;:0P4 HI}d3ĉ= 'f0̠v<#9 ~tQٳ23C(kQ #?@n!-vwuem;#IjkYt'ixϟzTWx$ԤI3g8(8@%Nښe,Z|tQ }co/Lϛ#3V%GF {N U7PT?48q1HC!epx; Z `lkjΙ2^M0"baGQI~gPk@[p*pv̬0[f\vb!U?~aStq?hі98u5 iqr;vIENDB`Eqonomize-1.5.3/data/32/eqz-schedule.png000066400000000000000000000042521416454732000177330ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs : :dJtEXtSoftwarewww.inkscape.org<tEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/vIDATXW[LS[*`BE0&cMpHƨ@Ľ̋<0ɨxLb'93R[i ۡʦ{ÁXrf'aekl.PPU e"˲DteXIIɿ6f?'4?y>8JRBJ҂ d \;,Vf3sb1D",..BPPZZb$gFA8}{?H@{{6??+ިhT~ssstX,tPՠ( tDX\\`fW<-~SNT555YH$ lݺըRD*˰`  !all 0$Iz{{g?* ܼ@Eڵ ())-,σ<=5p/_7||ܹWfVҫݴ,_777WnpСCkf0 es"h2t:qQd2x^455hj=/^0thmmE垔BS4 QTTY)ly~Ή@{{VNNN---b|(qa`0Zڲ"vӧZp:( 8y$>H1  ߏ򂂂/sp3I%TWW#//PVV[nܹs}QPP{bffyyy OeX,[Z WLx<FLLLI>7of3FFF 6p^zH$Fa41>> @Z(" A}?`۶mGUU'A,IeRBo?޺cǎ@MMM?x&''100={  F%I\6}}}o"_z=aYwE8l-r(Jxr}#!xA,--AE:4vJBYȲJb]סi3)N0cYX X__(ّhX#2>>p8'a~~>-n  58y^5˲odpi)@upW-`nd.f ;p{{{`ǻUUAv?i?T EpIENDB`Eqonomize-1.5.3/data/32/eqz-split-transaction.png000066400000000000000000000030131416454732000216070ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs : :dJtEXtSoftwarewww.inkscape.org<6tEXtCopyrightOpen Font License http://scripts.sil.org/OFLFIDATXݖ[LWƿsfv.,,rSrH\USAiizM&KИ֦j$omƐ4Bl۪`(MZY63{NDb[!˙oLSstkLucR[[{i۶mJKK˦q֡` EfB`fs>e1=+(UK#D5DwO4;ȬD-E;Tfe(T ^/Y8;"(rZԔ0st3@@߲F=3!HCWI2 +3eudEy>DAW{ PVPٌ'@)rhWρ Q  UvC}F#@egݮ2T`Idp}'7kP16rxTp4]{$p#ٮ*Ng{S ) t1u?r}p-8/{)r}ryD%?)))_ mwfM@KՇRXy[tw$cT4rg8%DK3l!YS,qh`YNo*K9YO r[,Ahv0%OP@UM9XbnR7 =uv'hHA@ s tXh4fvCWBٛW*MaVKfVrxOW(&ޱFfZ] pCi@)#F!B@^VUEJTGD@>L*ZHۧ}&uſhu컞?.s! =]</àU%%uʸ9pΧeOO3 _MRg^C3>}ީ#O, w~|HJH ѯ텅 PJO#0$Sgjmm}fL7xIENDB`Eqonomize-1.5.3/data/32/eqz-tag.png000066400000000000000000000040441416454732000167110ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs~tEXtSoftwarewww.inkscape.org<IDATX[lT{x񽦨-! &NB@JJHM/%U_J0Q[[;8 zX`MctРח ?XZ/DSߔMM_&-+,z {_b;FdMM8 TWW7 _hf&ͩL,^Z8Dlǘu&~ظwܸu[}x!4KnNNnʨ5w_b%+WdUr$X8wU6N-!Yܲe: *\+/dtKhhgg襫:}4n!7KUeM\TXήĽBI\(X/DBN}֭~[/ڽA§2y9*$UuHP7,<2_ 1k@V{[l5BbE;J$-{vO|LL]ZZ•+;SEfv5VΏQgWgfrJ "1``6qV&dLq+CW=ظxBDV 238֐IuF(`NO TB;' ^PaXkdㇹq60d8 Y-1t?w@\5 b=(7 L"cvy0dϞÛ*:w-PBtL$ "XdX 6Tb,@y//M[s4EDVvܩuLa@,,!>,ڳf` )53yʀ]ɇBBH'Zh"Wr7/ T[Pѧ+K*~=dZ;';}!'7g&dbܲ-A ݒ$ jD MM-?O::{>6[եe }DӝHə4FdрhxDEl۞Ur-}۹s)hn927q*/ zbnz ccNu dq`0C3y 4׈H4)ѿ{?{s%UIPPUD߼g7 [pGόlO؉  201xGFտkwLRL Wr^]6Ӝe庛'OB"Hhx0b~~fiCc*LFM`ryE=}c/ΜOʂ Yp2^!9u&mSw`*"Bq[eWgo7 %N)E0[-"z̢]-?SC@Ղyk Bv4y64B|H,e|~ c^ 7noۭ}_P u2 ˑyNy0)lDgͰ'1^Yf=;1:z'+P}Q~*@f5/,Bܩ|[\oF/]gȯkܼă6@bš`Pl րE+^p i{?U ]]]aO~vK,"k3~ [o;|HyqȼP `[ۅyx,b|^lm۱w:xg|x3 [V<6IENDB`Eqonomize-1.5.3/data/32/eqz-transactions.png000066400000000000000000000022541416454732000206470ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs : :dJtEXtSoftwarewww.inkscape.org<tEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/xIDATXMh\UydN62J]46.YTb BW.,"h6n\"ԅB `a?&DU iNw{d&Lyv=s; n/25lCTn'9kE%K,\ky~n[F>xc~;"7:s/iM5&H2r/ON0ӫF~xB.{68 GksP)/Dwħ' *ґ~Dƀ$3Kϔľ'[eI)g:>T8Z &z,L|do(I& /]f->YrqhćZؒ/pF7|Dy7z``/ю(RbΔc]ގ q6}1_ gywz%mG>}y&O$v իsM![099\.;+@K5 --9o "HͶ-A Rq\۶u縮twt0j@=K(`%D@$6ѪL} ◉ROj|Wv=0!x<^ks܀xo !L"PRʈ#YX<j7]WtX*N>q!*!DBtұ1&nqB3 E& YPih{SSSmJJBcLv"H$8}e(V7̜/ a] @@ZIENDB`Eqonomize-1.5.3/data/32/eqz-transfer.png000066400000000000000000000035221416454732000177620ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs : :dJtEXtSoftwarewww.inkscape.org<IDATXWmPT~]`X(E>J%J&q0ΠF;6ti3vNg43162ӵ4Zc c&hIe{9 00>3w}9 NS 'r 1~[:XoO58R,:ch0<2QN}4u6HȲ쇋]Vt@)e `,B? 0쫛+amM5:S(c`qzQ^IQnu_tjWV5틩 n*MwUpx8rrן{nv`CUvso_Z?}a-C&EQYE;(N]'|n,[x99|sD03/LrGsÞܼvEN'ܐD}#u?֋+< GbzL%*^cf>b]am7C;m7Zyt GufgZ-ZW5KOҍ19Ѱ+5kor\0 N .uʰȪT\?B @Z@Im7N|~c\pYlk&-~K,c)!RnSżU$vb1wAyZ}_Ėע "Mnq"^.w[yQ1p4>f+;JKE#+H^ Ul+AIPtO8` +.LO1kyb F)tjѵ[WZnf09kgXzn^1"cb>耮z_ YTRy;cϺ̗ĘWA)DoeYg"Cczh/еmd)8*0- |qɁ0¿O?s40aXÖ,w0{qkl&[U F V0Z q dE Ƙ|Jh/oa`#HY=y`@Xb L} WjJ/Ăo@%0"oz]cʛpeN9^bՔg tkT_<>'p>qJKOw-"K &JA_9xԻ@h* r}>RzzsrXIf\;UN.z`?p8 ޿7O9e2EX_X[ >o4:#NY]g36?DǍ&B·K+xւVH_-q߳eF^%X6_ DoăZTCwt'[n0@ƴ0B8%׮w1 550Ia|-ڐa=<<} 8 DAD(ePC(JZ2MP]D0[lXPP@LF3 w)\W[[+4j'qx1 `F0f|`H?= ߏ‚h/x Ic87\plo7k]QE}pdo H6g)Pb\nEhPޅKcS_0*+!nm_.J)Ҥ?˰ ʲy4gΜ)+T1.=w_Oh2,gLflX,Ͽ"upȐ1b8Ĉa9͏oq90Z0_;i D3IUH`2j۶ൿdÃ/.e}0MT㹭o3mFfٲe̜9h8qo)0=JB{d2l~6m-w7x ,Z&xjI/_N}}}iωmivWiD5knnj/ٻ<؃\h4_.]ʢEL3Zkl"4.wջ Pn @q%I=y7[bŊ|A)HK[llqa˛7C%dT,Umg//``Zih-63s(BյD V\n&}'W ;lH`$zm|K$0w ZM3{ΜS.pK94{}Ķd II$B'SΛ9sJ{>!%\AQk ۨ8f7S 4ԃax  ̼bbW-98¢Kul˄$pH$B8V!d F{ޯׄ\ vHo h=ud2%sؠ V:u↮z{A0a@}nwgNTJjF (FBZkH 퀌 \}ZXb!Ha@Z)1E '8oBJZkQG;S!U*J@9H&=$|QJ>ZU 0 T(2!Ӏc'< K@̠ ZREYB\Ȣ-=ҪplKV|)fWgBZð ]󁻠0:q(.ظ; Od0\d4iii){.$#x&$aHk7JM Nc&0bn#O]2}}}HR2ʁWy̐w?_$i3b$%&oF#N^߿_6=oJqpmp6l;a(%2Cޡ&:fЪUwUaP^?H>P|~?PXk<tAikkx}}U&d?))-ca5bap!ikkx/ Pi PCC't<1 U&댦g۱sH Tڻ>q]t>,Is7[m @ .\)[hy f*+fn 0 9"Ν۸z $[#n>_opfjkk"4_#@5i$k $|@ N)/)ρ@¢ \RH䆪_f:;;T< 277wRnjjBUS9DM8)}h)@aa!r8::S5\.IyzzG_WW'Ղ狹#g dL5i2M@4 r0\^t/0;;ީñ5M|>"}I} t%KB󟛚 I8V5_NiiKߜXx<n3%4`2nJ)]~KbFFFd81t:Ս۪ʊ qէv]x^fkZXXwZl&EQ~LB|X# &#uIÙ֐%K4/OA}L4IENDB`Eqonomize-1.5.3/data/48/eqz-balance.png000066400000000000000000000057231416454732000175370ustar00rootroot00000000000000PNG  IHDR00WsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<tEXtTitlescales of justicekYtEXtAuthorjohnny_automaticbM!tEXtCreation Time2009-06-26T04:35:18QtEXtSourcehttps://openclipart.org/detail/26849/scales-of-justice-by-johnny_automatic>zXtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/ IDAThPǿ pHT4V#9C" SJhD;flөLD3jӚXF)eRdD! ӑ#r{{p-J;3>ϳg}];}]#"&R\\|l6f2~ǎ(''8ȍrɓ':!MD4s<" \e2(AKM^Hq83mMMM?ڽ{W^y~AJD ӓOppe:D nh47r*Ų6*IIIpBQ7-_,""B(--cVVVIhhfƘ[ PŋM G mkMMڊ YKK Cbb7&&Fb4\pᷢ(:###1w)d677o]U^^,Ak֬,Yriڵ{3Ɯwf\:t"=ȇDmǎTYY)y6l]l=Ś*"􈈂}]?Çߛ۷hsgg?@ڶm=󔟟﩯?MDYD< zzzV+ Bqt:]bYGDcL ஶlpZBa`ptN # [ZZ2~|iZillYTO?TTT϶6|zII @egg{ [" &"]XXH/y8 .kelliV(Ղ xAXƟooooz|R__Ko>(f??h4ZZ]:BIVk7rA@>?ŢT*o P]]\||<83:j NSv!HT*LqD4\9s|yU9uhߪK ӟ?ZGf{XTk4_:$)QHXXX}6YԵk3Eĕ[n6 t:}|/Ο?ppt>9eׯgj4jWRxp=R?EIL"ۑXn6G>%ƔALdyOL(tJgϞr߼"$HE! 2C ^rab  <i4Ȱ`4xxJ uq=8& ((1%.rv<~G=+ @MM33gya4V?t@}v|VWZ}1d Vuq{y=jа`02z1FJ~nDQ|"??vBoo/L&{fȹa;B"jD6ʕ+pΟ?O+V;>: 044$P͉zut{zzz~uu1"k  Ɏ/Zh{nnrjkkp#NGsε8y(!`%]]]**H./%I`y(ȑ#9s˹nٜ1hdggWi͌1nw0 ڲtRGћY7E,d|Ꝝk===OS@D mٲej\|\. ]ACCC|ZVU?!.9i.܂w^m4w_$"5c`H?lS 2p:QbIIn{㖦f}DXxxv JLED<n8{s Uc SA  bt:|M"p\l<' 2v=Uxhu4!(D8U޾~`ZNh[>(6i4QQQuO7kQk Ů\.uLS[[[8(gBݛz7fW^ Lv5=Cč~DQdTPP0l0"czcxx$={/r`<|[w}e]=qv)g|()y x<#SDtܹs{ffn78*Jի9x1::z;cq r|(Y3Q,eD z%1fV=p.ٌiCCC7jx^ф hvַzq [6_9铯:ۚ6qˠy~܏;Ѵ }<88Dtfb"0ƍ +**~_I۶mLMMkxxZ_;p:?uԛed]*c ҬY $sFF.ر0e/tfÔ={FGG?;Y)Od]]]{͛Gz^j d2 1&;WpT|}N77|&IENDB`Eqonomize-1.5.3/data/48/eqz-categories-chart.png000066400000000000000000000045701416454732000213750ustar00rootroot00000000000000PNG  IHDR00WsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDAThY[lWsfvv_u8%*P hC+T S%jA ԗ$>P((hn;K8q^̙3^@tv?;)23<AT+;׎:5 >ѝ8 Ŭ`Wu[&FF00*Z[ A38b NqLF Wlw?*ԑ#hF 0" @8N,8*`&PK DWDGPz}nv[g]3=w: zm||f$RD'h&P4i%_'>6U|T^1GFEk[@3!e@R"BP0!z.'m[ADU#.f2 AXJ$u!, ,׶5?I &eUza3e˂z&).aYp骉uiM:p`&\˺ARBr ԌV5**5Kr iYCP^]T*oȆ0N tq\{7+ "+ ( ;6+&JڒJm:>IoÛj^۞$ ǮK4s^xj[}"85a:Q۟0݌%+]mʕ_Ä˟-k SWN^6Ь0\*)Ƽ7ɢХ0RVgs!%r:ޒT֜U31@"DtʻI7zGڶmvͪ_[`L~>(F[oܷ^ cyyŪ>RyhAjw7@o#&`.ĐbG^S* }55.W H?pC B.A$8o](<l@жJM֙-eobo$g] 9D'M$&Om?Loo)N"JtS]HX$_M?v?%m?S B W0;\W*ʧ_oaJ9(d]V_pݳ D8 &Z |6 ɿC77& L ܖ~=0){88(ժJSE"mӞF9U:dJWЙnvE&ʩdZ)55Uő 2fU?S k:ASU629|' ˏC]m(UzZPZX1LCBza 3W~ʯ&8L_r30@`\õ\7毃'^BL؅&(cEymu6yx,t)%T1 1ʕb=~ۈa^(1SDJd~*T7  Hr04^u (>~o>vݯ̸ZcF;tATUa7!Tyc"` $!xm>6?gOU>t?s{E-X;/LR 8,п򳃿|;<8=`-IENDB`Eqonomize-1.5.3/data/48/eqz-categories-report.png000066400000000000000000000036171416454732000216100ustar00rootroot00000000000000PNG  IHDR00WsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org< IDAThYm\W~$iڵk$!h#HDXE71C-ZVâ? j?%$,#͏Rl1H*$ntgfw33s>1{;q(yss{n6RQR/pⱣpx7Vzض}$Wi0L3HJ !NRض BhRk?x߀zewq'>?XkWqE|S%|q!835=Y4[7_c5<qv| BBeag3;CcnCMѭ&CB&H[c֘`<B #m{31K# \±tئ2B Fr S05T D脀:(4B*(pCB?. x('6Jm4\-pkƛw$nRu7bhKQV:-T Xf~ ޮ;-|Uy{08Zi96*ZJ"Ϗ۵)`˨}$Ň> _>4ց%3 `N̻tmćNp樗,3 )bXXw4g*@ip^lBl0~< /4q4mOz  )dw'M@n!{?i) JaxRJH!!e7`kBR<~=JHI(+q\#9 a_n⳧H@pg]9Bq42r ⾋t|@ !#^ĕ~Pցf!`hۣ*%2@D u:lloP|+++jV&Ve7.$<9s&2q { @ u{utCfBU% '@6\b .$x[-k sJ5`aʑn'q}:&Q- NhnelÛ"RPJ#Qw?CĶ, m?#?x/~=!BtK m.ǥQcG >0Ά[va΃)EOk!0RfF8^iޫiݒ!j$4GBIAu=8F)=r WBR---T*%( (J( y $z 4MȒx~ey+6qk?_1躎\.&pb\. c?5B czzG>_ lс`f"ϏJVÇίj|>oy i[ɪnG2LR ¯ Fw c ϶t#Z?)a a!o< ̳x$8 )OOIҗF h~ai7OnaFO]?Z ZPMJr:}XY7h4u]Xk4~1waBI0B&m/_YZP'|B RR+L \ .*pȑbxҙdWF>Hy D΋|k)E4rkFkD U⣐Wߓn=I`IENDB`Eqonomize-1.5.3/data/48/eqz-currency.png000066400000000000000000000057111416454732000200010ustar00rootroot00000000000000PNG  IHDR00WsBIT|d pHYs+tEXtSoftwarewww.inkscape.org< FIDAThk]Wu{s91x$cg$0~@0P ҢF}HUTZRY.E*Җ *)4q(Ƒ'v qlzTO.L> k Mڿkw B B#E9R(BHBnO_ůU_Լ޳gp( !u $um߭Q7ߩ9\ok,i ß۹W)HW^͝Y)EyCً~lBH=ܑޯ?65Nb uHzwl= t fWt!nH b>J=O~o'6VYQ:5B@Wgr xW(L!X+s?Z+`9f| W gl[,O&CvHðX̣GUK7 z^׮mv`WJ5¸zvX~[vn#H_u_$uLb19hs2䮻6S{5U ^|?h!^CI\O\\ Wᅯ/}ykmZu)W̗)]dnn(Rf"l8rmhtzvTH4vs 4_RTNcwSus^Z )W5R :;|ZD.ׅ):{GЪN4$H"i=9Q!(?|yȶn@Q*噙~Z=4hIF\{bi0UF;[sYwˌZt%r%WGŃZqRuTgRw'߷ߵ5\.OAC\qF=E2wIrRˑd\5煸n@2[w@Ds}=GaoPǏϸknV ,4 )8׭[і5ԣ߻<ܒbJ%a, f>V k3rVR*i  /U+ G%*%](*|?$b0]1B:ӑJ[3W*׈{ϓ<}C`O^8^l> PqФWް(\YԈF!1RNL )MQPiĊ><=>= ڦKG!K4xak7+M$*88NШ#.,cg]!M~(peM@zt=œ* KK CxO0h8jA*9n˱kVua3,cjU#/08Ӗ/LğR0 vx/J-XҶvl0S= t18qL.r+Ig:8u'_E)8j$)Sa;B=ִj03W͗[kKCՙAHc+Zo| `}mkй\iJ,S>ccONQ*MTJH`+:AD8l=iJNfO: 쪽G+KŊZYA2~u֭߀@0J1iZ !4BZFa-^K!xr Q-{oY?t(,/5 1A}7Z°~Tf#Ճab] ֻ&/s.oѲ:e( e3eIzˢmlc/&6u#g}H%GLאRbRMTSk3I 0DY]n7l#;oGV"4L b8HhLβ8T3)]NkQꕱ[Bf]Q*B @ \!ַ/I溅ߝOX~܃}Zuhjv%ə8Vv,YV̿<i潻{n۸kkzd"GH͢&sloXŋlZϷ-;$ҲIENDB`Eqonomize-1.5.3/data/48/eqz-debt-interest.png000066400000000000000000000051311416454732000207140ustar00rootroot00000000000000PNG  IHDR00WsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org< IDAThXP}:@*bϞ=P/pB `4/_ GaB'_ \.%w 򾬬_-r/B  wbJ)v ̙3 HOO!IJ}"Zby/@(FǏot())WbbbvSFcLp\pL&INN!d#a`ٖ9ȩp @&˗/&2Cff>MYwԩ'?vRij>KNטz bbb'&&0<Z\\< +]VnM*mogggɓ' ++˕}V,ʻ~D"RSSH$ccbbnwyWK)!\N- V+W^f3@R¬R.gnv8 8x5kT~7oޔ@ZZ{)X6\fƍEEE[| t:ݿ[ZZ4444@&aǎ[5==Eے755mnn@iipbbkj@L+ʠM_TTlY, xRZjMsR>722rXVWD"NUUU*nܸVP s:}cB0,BN.+g[ xAgΝ;jEXXnk7| b|io&Tb0}+#@0|&pýS",e~.lUUU:h4O~~_d2Yo0.5;;+VaDU㡼=%%7i!Y00i&?[4RhjllT}4 yr 3*덤Riߢ t'NȠBR VA>b+*^oa2񦧧7 .ټccc<SSS+CY~˖-f'&`Y@aaH$bPJ.\ݻw'%%$BF}kmm`26r@*BѴBs[UUUqm۶}T*o>BB~&y]]]ܲe.vtt߸\{/MC`LLLtҕXBN% K9IENDB`Eqonomize-1.5.3/data/48/eqz-debt-payment.png000066400000000000000000000047401416454732000205410ustar00rootroot00000000000000PNG  IHDR00WsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org< ]IDAThX{pTsfA KBx%(!2V(:!--uӎZN;chA)_TZG<@H؄1.cmѨ^Ev˵@w}QӴKtyvS73&K"7O@Cќ)Vzë !0Zۧ s'M=|Rm(]VዱݶY6KyidRÀ^i ݚ 3wAم ى"ݒh](WVtal ~6a`0ph㪲?S%]j.Hd W¦-qe}ų[<ڊi,DȮ{Rn2h0@<3޸ru큻fg{R@00sJQQV] 3; ] җ.J}bfw%ʩj}ZѺ-'Gwt봔ǦgZ^/.a)!Lt>^}e-% G`0~Usrw eNp8l2h@vt7n9oD}ei HDyo! Dtx&9Wurʟ g`}j$jʛ= 9)Ț: x;;j(RQ PQ!rȼTBBVUF$g/]pݽ#!p%~jmE$QI^h)dR@4"DXǰ۝HqKJ$/`%o.1Y)kEhWpEFb|,$})99p$CvAlh!HRqQًזOoHwȊ g]i!v& e,\P5Bҳ@([.X lF}2Ήhks: vw @p"= 6bs@2q.7ytMcGj<l6+Fz%T HLqeW7&K.`j:@)ī%ݵ)N>ѸxFlDO#;'a4ЛhDZW&$: !tAI*j'7Js$+ٮd͢3fo:(s?p~D KP J(5B2&A@]:⹌ie.~ttÊ3'f㬹3SW*$\xFEdWJ(ԙBJLPύ֦`,'Ge~KK"@ ה,f(еN!vD54\Ў+-fƶ\8X N.~J`8>% dCA¹{e;9Bgn 3>5Y`!dL@'PAi9w]-dPHgj|:69M-L L}tnư/a??| m1{ CWō"]m}:c]sņ; `B@w~8c`v_y\>y5ϡu}R9g7쁛g:8]ƌ0>AlBkOkIC\"ߍqc8|wdIENDB`Eqonomize-1.5.3/data/48/eqz-edit.png000066400000000000000000000031771416454732000171000ustar00rootroot00000000000000PNG  IHDR00WsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDAThklU8c A݀B6DH_0Qc4 1@@`@qѹZnv}`mekG~Iy 2 27YxLGl>HU-Bn((u.6>/-9Z(~@@G樤h]ñkN0:m|3ϛ jh]'RPʊ+nܺ^k γe 05ٙ! -_C*|2k(yW/5 /p`-Y0K&!6 fpdx[1Jbe_K&^.5Kti>0 E1fY GVJ QO/vݱjnʅSRy@8JQ{Y$ :de(w -HЈI֬(t4@ 7:t6K 7|qZ}FOO ,f jU_E'JҊȞ~^68EoP1"NjQ0mP๦P(o`rv\"ؓNP63qI#j0/C&1o&8 Z4:LV {:r$)J ip-dQa0Bj2*L)wW/[)`?W` vP$%C$\cI`ȇ%xvEU9LYU{u@ ?U@<]letS+zwP~X(F4o"x6=Ы*̶ LH>sYƃlȄ%Q#U_ Q 7XrHBJ۵kW]bzOJJ6wc,X@K r;] 191&=j~C\^^cǎ=Fv?}!NfBbkBȹdF#IENDB`Eqonomize-1.5.3/data/48/eqz-expense.png000066400000000000000000000041571416454732000176210ustar00rootroot00000000000000PNG  IHDR00WsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDAThklWcgv6q󨝤NhP |P> $Z A@@%)ZV⡶U$BH *h$*ji؛č}alN|i4ߜ;saE+ZъV,1saAڃmqFR\6,[7n !\)=4T6;s1ԧ!Yyc*b7 , $Iq`DkBf 0 J،kڠjhJEv (1Ơ啚S1WFclVkJ@7}]สfWa 8<+ߣ| JuMSgL@Zԟp݇5|=[iJ)ŒZes FYb xHoJa0a"g) :ӧf)r yO>_ˆ&z{zY ?@ o34Eo8w|4@w/5dVmH*l&\'E8_)VZ?s%N,ܹqg_ AzӦnGCT'Ջi o$isb"k7*]3TJNDUJZIT40HivCɵ4q^.? \%xG،4՚uHEI*s]5^r-V0*5p$#n<6WqBv455 <,ZUi\@X_!Lg8^#h,xrTѷ;RkGfbpcq"ίS7OaLP36'dnO=d[3>vF!JQ^Zy0 [\SLO#ׁ![6ih#7>댎Tԧ\ӬYou7K_tH,BtPSX'ivc,6(r\|IҲ ?_FuxAۀn=BZsoN+/jO3E| ad85g@T/  'ތ H&}-W z6q۸i:z6q]w6-(Jţ'{<6&}`I燇G(Wjh5K!$f:+B~RBGGnٓ(mP a&;t1$:{>Z{ vt׈tW-u8~g!ƉJh8K >*d٦\^}8-"Hou8^*! ~z+5[M674wlhD>l|A`^hm_<jarql Sx.CmCCX`YRiɯ|q9A44!Hv`̜:Cbu~UR@Tڎ笵.L#~"8XSV+PǘBXO|㱳e2@LC]އ5uR:K:{h[;lK%~}݃]- a/W~_'6:Xd'ff?Kc ^N+^K-JMA*|KIENDB`Eqonomize-1.5.3/data/48/eqz-export.png000066400000000000000000000026011416454732000174630ustar00rootroot00000000000000PNG  IHDR00WsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<tEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/MIDAThMH#go&I(#&X`J"HY(R*{P/=x"R{ yPЃ~j4~TT*+ظљLy{؍$:wm<}2dCVo,YP`NCzLOOӺ۳,L&M (&RJE=Rt:0 BQ oЦNNN܌E]0 eUhiiQ{t: u aTx<(..VM;@),WEQD$ICEH:O$I䤢Fj(WDJZzEii)UAaa<%;1pd 7Y(RԓY0T]Tb1;;;OHixLLjn$cccsJoYY`ExW9hljgzhi$I>x</+++'D.=w@L]]]_ŸኄaHX,Y0 @$PJ:<$I*A@SS9YQ%ǏD"~pii!D1SSSfo]݆w?\\\lR>BJBPSSd ;t:v!2X!:xRp 7˗yfGGGA6qH!,rOgyGgg^$߈BU@ QRRy NLL|w>v@UUI[[DEESB1pBFAkk.GR\ڙ8H`kkKQ?<<.U7wppܴ1}p8X,)}i'2aPTTAXV}`Hr-OxY+}gT&co.) c{{[uK)˲Qԣ(BUD"(((PDJzCCC7R6omߟbxLuuϯEqO~{tW53d8ǿ7ReIENDB`Eqonomize-1.5.3/data/48/eqz-import.png000066400000000000000000000024061416454732000174570ustar00rootroot00000000000000PNG  IHDR00WsBIT|d pHYs+tEXtSoftwarewww.inkscape.org<tEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/IDATh홿K+YǿsWBL&XQB+j;%baAD+F? ba KE$1{g|$n&o9gs4h>844rP9!韢h`@ϣ#-y?*4R ]q!T#1v"ٟP`ssh}M*,)T %_%~?2 @Q84x8NY’ 躎l6ۢ~LcDWWWxzz*4 byQrY"󡧧l AŊc/,,k!4ԛo^}vA)#cPPysa[^\l[[[lhjj!d@Ȳ悍1S,--aff$د`kV^.6q}}my; cdY8"iZ1k&<Bx]׵|>/^^^~Nq~~Án QA)}lD"8>> a٬(ʏsssr9K X\\D(B(25a얯R^/FGGjt^~RU5G$!DA4BEQ!B c ZΏ>V`  ...J)(y0 I122Rr\Zq 1>>nj?d2H&boj&["nv`ecccuk'5BV~ͯFMC@i7!@Q~񸩙Mw)P% æ~p<_`0`0hEy5@);H$j$ٙAzn3dYTݳI2%RV?}nX+1@//]dty[pxD+%CTAGkU3 C/(!F I,_o>}r_Dt)R)skx}SɕRhj80GD\{m nԑMHk)USH*?gHVK +Wybb!Zt6 ̂ c}y@0~ѲZc OyR)[VH4M.jZ²hYt AӢP=!Ĝի* 第ww书u61 ,| \ >~B)CPĒ󨬿ip l{qf/?3 ePLr'J͊R屋m_ s&BS[3hݨC7KOԲ|ť߻JfௌSGʙe C #"Y5N6aXF 2a04CIzNBp "TtH8 *R;fΡXLEL*j.D&P@jTsm{wIc0-xb37l@]}#L=Ⱥ Bw޹ضlaoCn86! s_c}4:a$*@ 8L&Bݹ? % t0Pz`X xN7^Klx`,IJc< !7}gB'' 1y)\/{D?6&'n-qϵy#0P*JlB 'V׿| ^v\ikò砋o6Z ߚzÀ|~PHV4>9&}<X 7v"5Bnx+4SH3ȦaP]5y3{NSDn`Ibtx{]ר@]>m @ܼ˞Ŋ"1c = ӮƲgc%V%J+^{y2^3Deɖrl\۔RHi!LCҟNsfƎ%0j kB)4qxCo!@gC/<@A憽MmFLoZeD28Lao>|j"露]:F֍=UwY1s#ZR(jjI$RQC3vCC̛⩮L#=,N-K8 Ã{:DJ>:Pz)n"$W^PBj1!Bh _ez& N6wX@ΛXS_4X$ ]%N+ypzHq6?|pe2*1$ U^# jO r\Iw7IENDB`Eqonomize-1.5.3/data/48/eqz-join-transactions.png000066400000000000000000000043211416454732000216100ustar00rootroot00000000000000PNG  IHDR00WsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<6tEXtCopyrightOpen Font License http://scripts.sil.org/OFL IDATh}LUǿs/ r^_&Lֶ,ҩm-[:glYltmi;.ILLNb h2n:\@}9oϳ?{`@ڄOrs{~<b)Ґe]Sl@3hĩ>o,*OȑA~ڲwV^3]a2tv F$~r_{~/ܜ  A)! ](/?9LN4缸?CtA<i_.8ɑXKt<#4RA] UE_W TD`&!7o)"A9?9_9_9OpGBވhP *ؠ)LF\1͋\I/;v""n9"L썞L] P RsB`{YY١R DQ<?0EE:G:t V+o,`͇C[ FP@'@3njf;x-OHj*_| LK.Eeɞ sB ЛAQ-a2oob mUё3! ӈdf}N:Pd޿l92!^}8rZZQ+/{F{gwĹ6P$ׇ7pi]'f t:sS^w9^@EEũݻw˅'N,'\_숳ѡ{pYcĎ@vvv^?!Xd X,&vL)979~`08bl{{;]mNc~n[ٴiӎ?FӰ{AX9O)º͛70B7@=!$2ZMc20!@H1ӆ%\o;wX.uka2|V )ۗ򶷨R>c@@~0{άKt9fo/oJG6'5^nO,ܰނdVP鳌6˵_[aL

Mc!хXdJ8}\v#*jx2`W$-V5`ɨ EJ0܎@YV]Bb`0PU,B ,٥;7?pg5~y>H MҤXP6翂8gd_xv;1χ|wqUb@XIENDB`Eqonomize-1.5.3/data/48/eqz-ledger.png000066400000000000000000000027621416454732000174140ustar00rootroot00000000000000PNG  IHDR00WsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<tEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/IDAThAhTW}sg|,L"B zqb:]DqełtY(Y+)jTԡ+ X) T’itH&8y=]3̛ɌɌ%0ww;E;*|[G-YR?}u[ӫy$p&9#ߏYܿGFF1&kgϞ@,gBX,]ZZn߾[XXB_۳gw @!zBtT{FDyR|IGGGiE|ǣGp~ٶ=u]/^sJ ׯݼyRb"+͔r(٬Z[[y?OMM*S*<{cǎmRq%>} GݻǍ`~~=^UiDRy˗/1>>mCT 8kM `mm'ccc*"_,VVV@D["y׌1p]L$L+Kk<::ZkyOOkʕ+E4kYk]`Kg H@ZJRKe\pGmrP4B:mL(r~ #А:wsq:E"ҋ{2m8qT*U"ڞ~z@xR`2`梬L&S/,,tYOOϐ1kd6 *f뺰,kC)yl.̌l6 ff/OKijoo@ fffb3477w'& \fnܸPP-ɿ)Q$IENDB`Eqonomize-1.5.3/data/48/eqz-liabilities.png000066400000000000000000000027161416454732000204430ustar00rootroot00000000000000PNG  IHDR00WsBIT|d pHYs+tEXtSoftwarewww.inkscape.org<XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/IDAThmh[Uf-1mYc-]K? C l?ԂPP(SVV(ՂUnJVk@F-˽?ƵMҗݬA >ɽ@ oD|M5RP(t:4MkTJ=3+-!aTMG P [ɕ+WÕ8b׀e@u  ''۷ Y~=RJ àgϢT\0pԶO?^7v7(^B<;^RRB Ǔ˗/ΩS}tM!Dp8<۶m[+|<iAb#nJo#p+0u"dQWWݻ)..^D^CGi.@YYYNVVVP9k׮f7i.\8ɒ !Vd R~ SH'4M洨KFOO!^7 c@&K:Ph|PQQ+I=ڽ6ހKٷoIB 6mb)ՒgNL;aM6Mu_V ;f7t)2-RI9D)?LX#7`K[R+%+IĶ%7\k ,D6>߻w))l˕y܀6˲D–6VSQQ}555\\zu)emoooʡ0m6MEiRa+m6!`e΢ӧϫH$|5,R"!H%7e/m%V;L9Ci+f>;ht͚=]pqNVL͛7V)bxx8ހnǷD#mmܹsӡw/&c`Xn2yߴ+++WZq4eNeYΝc|||FcǎgPu( 7S9/!ĥ gΜŤכ+xH>|8}tvvNDn>Ԫ={qFE'O*˲d)ŋ\.*--Up/z{{}>_M$>QLij4M.}s0n &X,v_Gˉc5dȐ!M z^IENDB`Eqonomize-1.5.3/data/48/eqz-next-month.png000066400000000000000000000020261416454732000202440ustar00rootroot00000000000000PNG  IHDR00WsBIT|d pHYs^tEXtSoftwarewww.inkscape.org<IDAThMheƟlۺ]A]0`B}g)VE)$I/D$7;Q<_F+~܊a$! q! إZ[НZλns; 4h`h"yh/f[aREџ$5!U7֯k(֮\"]b߁)`ii $y_7zFDEfbEjsk@X\\b+Nuk gI bzzh4ۼ5P/(qVV9s\n)LɬJc$Hd2 uqVDޫ6. (Yud)y;;;ϊ&/zDD.z^DfSb|"1yWM|@TP%mp!hiiA.cOOϤIy ض}6yuJ^yFpg<}/X" @.]KZ~xB" (--Zyar;ҏ$CD{hxn#ߍ4e9":&BKKKɓI%&8FI i0aZZZz_!F<#b4m/-/*Ν;GY1LӴ߈hQZZԵk~d#~],f-((Ν;{L&KD5TQy &NUUeggLD&4HZ xd2%?c ,=!LUUʚODv i_1ssaŊwcg fE󡼼rƍ&^T@ӴٳC8b 3FDի(//tvvafW4Q׻ QYYy޽<=6iv#!,]]]G9n'̙33g 6ċG,vc۶m%Dtш$IopS ''޶lsx1]^w+>}4?yF<5MDݺu(3K^WSPSSloo? B===#Mi̼^O<gؾ|2-[6cAhCx p^0ꙒbǠ3DtFr:6 I*hAZ5k6nܸl6l\DQ,Û`ܸqhnnFNNN-5tݫC:...ƦMfse QIdAژ DTgr z̙k4+[b,=k.&~˖-;M&Ӱ0*F,KdN m~r\+nuuuMfÑƴgdd@UU~Srj-KE4>Ċ~&-<PEd6〇yyykhcz$ {ӗG3p:Eiiix<6mZ<Ձ@EPEZ0NgQ(zuxݾ6VX'lA# FEbmz]TT}V=#0[HB l`Xx0}<a X ,JC D8 |  lfD3 Quiii Q3fȐe}}ϟw}r8c$In…W3sBJe[qq̯&3///p2J*_#iH>IENDB`Eqonomize-1.5.3/data/48/eqz-overtime-chart.png000066400000000000000000000030541416454732000210760ustar00rootroot00000000000000PNG  IHDR00WsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDATh{lSeƟݭ&&(KO ƀ 2ŌƸV\F-sAQqpAllXo[sʹA]K5&>y|mz u4D>K1ñ`97o,P${(Jwzy$ 6-=MOqYZ31 Z&* |KP,j#r p —EL|&*ynmc,CuͶ^[r(0za'iYbAT7mjsCnGU:UՒ~6ׁnA˙܃%U-}NgUj%'uW]ۣUyGUՆ[Og""0ܺGL%K zԴ3SL#oL7Shz}}>Hjp|LHa3g@Q` IJTQ G/.ݨEWX`kQ -iҎ2ıO. y_׻F[v$8((*.t[ zO>RV^?`)((*$pjDD,zYy,MSss"ZOKO=|xZ8zz9C3ysX`.x4z՚J3c)#'`})YhA2.^ܤkn*4-íi\ZriЉ`ۜNV}ai橲#\KwTID044~TD*SXZf>=^!TU]b6$iH.Gk~IU p6ւF!ɔ&%@86mѐ`lm텊?(91h/ `'f D PX 2Db'E4;!g6AXB-@d Q"9‚D!IrwQ mx^-Oݷ C/Rh5,85e JrjxB20Vb TNR6,! !ݷ!Cd9(ɩ Ld MaCr{Pd (S4 9y @Htyy|"VO Qw¥h KGf3:T9!FP1IFE#'Cܯƒ҂;D&4*/'/oVr#&t+ML,LJjMnzڶQ3wѣn,B*dg!nf$);@QJAr(&93,3$dY) ~1== BJKKaX`X 3X-H!$5JJ)fff+@l6CѤ8LS{{{G{{Td0!$7}vI\|OFuu58._X,3 v4666ٳY|֭[D0T䉢wyEEE+W`P__NBxG40`4H$rgGYYٮ"1|GqH&W>\.\.477+?>>UV͛pݨCuu5QZZ B:RLMMadd}}}nGmm-=wI6|M!dMIr!7m۶R\t ?0(hjjBkk+Fcpytz4^#ڵkx(>}\iiikZB& [nUvuvv===jhiiuVEɜl6& ǏիWɺuΜ9=I^FFF FGGŰf_>fWhX Ų,cALNNjkk{9gH$t.pwwuuj֭[Xz56n܈ttt|!`ٲeؾ};PUUUSl$?JQ̟?@SSE0 AȾJeQ[[x[V(@RAVg=J< ǃZxO=}Qڵ @E`ӦMp:lFY) 9 Àe٬g6!6ǃH$N fq7oތ^z O<K@R "zOYyx^EgIV ݎꜶ555޽{w^^PVuNVb)fՁN$Ik7k.*d eYܾ}v;w0Ͼ$ ڵ H0Lx嗳xR'](67 . e˲yG/ݩab1t:k?!nfvqZ-x p{^6-75P?4\Պ7ol6kX-`4eE˗/Zy<8qjRjTUV!$+$L&tRLLL`޼yY|-@B04 ADH> NEEEH$0 y k,˸qڰb <0 Yp!\t ˗/KG0(,YHww%dYFII <Ng^ċ/^x# d2]nd\FJJՇfAvCŜnO)g}ٌ`0(RJ X K566tbʕ8<r޿?Ξ=Μ9z$g@ Qthr, XVŋaZR#!侂bA<Gg 8n?r…QJ1<<&|'(//GKKKE& YbdyF~x<>NOMgL$()ݮ]vZթSH$ܜ5PN-p.`0'O… ذazzzXl[wwwܟ"~SQQZ]]ٳ͛QUUiY1v`KyѣAKK _yСd/&\rZMMM_ 2orr1~?ju뛹jX,}]{X,hhhᘜ~_f ~Vt-YAͦ 00Le@hncQJё|҄|B& ={<(I! zQeb$IQBia:xȷwޒ1}|3D|(%D^3x$e6omm]  Ȇ{9]~.R;]X Bb=N+g6EP(TufLSHߢ,>cnnNm*OT dpؘיVyy+x""v xQ2TGQњUUeYGngx,|b``$,x"x⃃oNMMVLUՏdyDtwhhIʄ'|ߞ8|%۶e#sDtddf||\?S,QRY{}& HߍFccc:33^ Y"D"())E,wE+{e_qȲ, ?1si?755֧EkJm/;cqcoRT _+i[&4k6LoBU7E=?u+3IBc.Dcch}fg!Xx<~8˲d<˲Ƣ!,..]VVi^nnNGZgNHLH>N?j42@ pb;|dB *sSqˌ Y7lA"xf{Ʋ˲ |>dfas0:&33mvYz QHF2 )0-:rkIENDB`Eqonomize-1.5.3/data/48/eqz-refund-repayment.png000066400000000000000000000055501416454732000214350ustar00rootroot00000000000000PNG  IHDR00WsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org< IDAThip\Օ%%cdȲ8$15d!50L$T\$SɤLb&5)R!0*X- %oKޝݲBlK Y9G}Dvf@>lY餄y 9*xV -o|?:);Q/ ` 89%urý.X* \b 83,Ió|SYVgHL ;'RyR)E [ &3l $e=BB JT]ef63R @)AWȳ[E %;?1_<*6+D1TSءg 6{k-%]>A-rՖSoMW魨Wi@sJkI1_ߊkD#$HĘ`rC&1 {VJQ\h|0IK6 i"E]+MvnNe S]7eGϊ&^QR景>1SMxll ߙdJ0<3]zϸ}cjQOzQBɤ(pU;| )JI=> љ+_Hd*m_^n:?C?'"2m_pe]WkF_DovnEO\ ݇S%~/ /\_18=_yrVrPk%7\3lX:=(/R9hz!rym@V@N*wӵOe;Da,l0B oJ .ZtBV"v Hhu}}Oϓ%@඿[1̶uzwv=>O1u)t[ilEI(Zж011~Sж|# Q߈RA䦚.w١oY/UzVf(¸Ƹ#cֿV▃8;ƟJkueh"<}xT|㭭4"g0ڗj1Ejk >D Q%stw=}x9SNc{sB#ٴb}حzɢ ϋ`G{Gs>B 9r{0oo߳HS*cO"+?QSc,S_m~^qACwR,ˇ1<7x!W~W=Z[hŧ%FhBEM3TZ\;Wηŝ"ZsOT9i;dyOGP.ܶaiUP *^#޵",1 `N=sy=/TWY ˒{L-Pz9x~D,:D&|;|P8iH7 ܃AfDVcx.sE sE O9\GSrl:u9p=D*0Gu38(eZhwp=32`5W6bJgo\z{F0`W C6`ߞb-5u^tց"`tm}~5hD]ymbEDFGGy'<8+ADE>%2k/>B>H>D1k1,5P@2%%̑xhg?CCёaGympOcip+Y:PU0q21 TX4Oñ3T0Q̼Wd.W׳MMaRuJ ZX"ɐNA7PUۼFZ{PZtCJ<Dak*XO˹ZejYh q @"AY5Q~r4uyHL8EIŬD Yc<3giD>jk*WhA`V5ZW$Qv<$Q"###8SDggcѤ D ˖SWLPZp 9,cc S@q;)N3gbGE_?P1kD ZAY F+.)e$b`{y݇R;S[BP;Wө`ߏy8Ao\GP6?,qk Vw1 2y={ &L|KWoJ[ʜ%3z S􀦛Lt3;|'*/~3IENDB`Eqonomize-1.5.3/data/48/eqz-schedule.png000066400000000000000000000071401416454732000177410ustar00rootroot00000000000000PNG  IHDR00WsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<tEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/ ,IDAThklWznmc&_ajB.DtE|Z&`C JUBE6Vhs!TEh5 %&/c{ox๽N 7=y{{7nܘ݀8)((`hh}}}7yLEQ~^V]]mTfzzzrrt:, VBJJ HQFGG  (n***ٳ,{޼k[l(]ZZj---|Wx<t:N'F,X@FF&7~~h4)..۫jkw*AMMl6sQ Z233)..f<)%c#:]lA|>~zRp8Xv-^W;wn֟ e˖Z'>)r18,Y n7BL5sWjܻ~ 1XNO'55{ ϩScX]Lmۖ/bڵX,ѣGQU"JKKYnQUŊl2FQ,~?twwS^^lNp}wܹȜjkku+VpYVg!r֬YVX+WpK~7g˗trŊڏ?H$Bqq1TUU6ϳ#/gaar5v;gpp!y5^7mVu֥={Ovv6eeeZjN'+Lpp=躺p.;e;^t>pez=nիWˮ]Dݒw,FCnn.6lofr,agh4YRR455l2{nY ,]xFCZZ3:y'9|0۶mw޹6jCqƍW+t*׮]#FNNάNyؾ};ΈgVr( ###`Xv׮]t `…| 322r 4 H)z*x<^6@JYtnHKK#Lcc#TWWs^}U{9>.@ f!!2F#x}]ttoLkO~zXl{aΝs mdll$@0d2''xUUM)))=(l}=\uIكcΝ^VV /@vvF7h\`hϪ5!Z'h4NCJ +("HVKKjAl|/lK.v^Jԉߥ&SO!UUh4Y&G+L'E{PUUEccc2 ǃ㡤ǽx GfrB!`FQ9-$LLL8RSS@%+,[ l6)++ԩSٳ6ܜ0\z'&&S@ P8y PhNNo套^BUUn݊7t(; a۫ !Z!nܸ… 50! ()%۷o' SOoL&---7d|1zt"`ppĥ6Ws1] ~ddp8hh42<16lO.\%`XrqYK)>p[d29+++M- lG餰\Z[[iii E"fEQf917n̟?樂M&~ɒ%Z-\~@ @(" @c42(tvv_Jsoڱc><%|Xb ,0v)  ˾8+?+jul)ZUU !*\(K)E(p 8'8>?xiӦMi<iQu0-IENDB`Eqonomize-1.5.3/data/48/eqz-security.png000066400000000000000000000035371416454732000200220ustar00rootroot00000000000000PNG  IHDR00WsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<tEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/+IDAThk1lkMb(6VA (XVA6,lWlJVԶњj/Ej+_-9t_N3~ 7oz+"^fv^tc8\.?"r5 ('bzzY8D"ttD"A[[NS={衤_xX,FSSrtu kA)U-@NN2$JaXd2шdd2177ܜW|>QlN޽+ )U ͩݻˉ'pCtb~>!$ dYVVVJlb5{JBZ?fdd,Ϟ=wEcccYrWD;y&333ΓkOB򶩩)V+<.YZZbjj;vڪ@Yχ͛7sel6|HSUbDLE<իXVVWW'dyyo`0X*DJ"~? 9~8dy l۶ml6K&W9qT*UgٰlϳaEݻGoo{H,f+]:2122«W+wvs/-{RjOӊUL> 288ȋ/D"'b065L\~5\@UPM6cܹbHsEurrz**+ѣr}x^v4~߾}Z"YH͆_1(>$LH$p\\t ]b%V$V+===d2# :VQ  h ,//;0pʃp8RskEhX& ljbׯ?& N~|v^v;ڵkFΞ=K>tri޾}KGGhQ0Tuyh4ʧOvx<ҎWharrRw[l#GwrbkV\ռxb'NIt$a:b1AK, `6,҇`"FykhDx Uʽ3m\).^w~?Hq`Pg]d,yb3 @;[ʛX/Ku`cuˬT. @8UUӡIQlێH;g_{#V/?ﲔmxQY]33gCJDq9sQ[[ f7_%e!'  3`c0}|҈uoF,-[8SBSc`<2"uf "zC9 NAFaA 55PHk1=5ȇ F~$@A&<04r + p>`(V9FA+C~b N&%)@!5 TfBȜB#.i ;C>14̀MRԽ= IBp Hۺ'JJAPtOJpn ԩ:3]TQ {gL²FTN-i:ka$;ڇ];`H(55ꉆdy<O8'H}~q>m֠yxH㾣1H=;B@:fP[&g09\Ӝ[qj)9֡ pŚPJA{U"Nv((@YXݳ {.~+h2rQH u^vB7+7KV (|^ *<1NN45;uxPV;W^NJ" `(( o`\t7H! 1H^YZaxzf'p>hf)dd1!  "޽9B0A o_uO5Ͷm/PRYg}_r)7rb9߈қV>8(\u }="n4D R* D{. _z pUufaΜzL>c*y!aƬ9[)I{CFM?R ϡyTOJl-0;}ogHU^_*FP\Z;ف/7 ֵʎh,fΜ ,kC>zuܼn >k} H%:݃ݭo7C<~/-m/e@nPTTR !%"o.X"!X0|2J9=@CtVX4}xҼvU鑢 nn<(k`bA1c)/Pe: &s W J&>=4(B r{A`ӠIu?,X#$02-F&8+^x `FgA:tC:VH#-(=ec'A µ|أsr ->R[ 4"01!eRۂZ!%uJ<8Z\h=k7e\_WjʹL:bkR'._xKk XcܑHR/w H=ؐ?_x'="Sh׷=+XN֜(]/q[OأZ..wO1'aH03[|yy]]]SG{L,f0e\2c9: 9IENDB`Eqonomize-1.5.3/data/48/eqz-tag.png000066400000000000000000000065021416454732000167210ustar00rootroot00000000000000PNG  IHDR00WsBIT|d pHYs+z+zlmtEXtSoftwarewww.inkscape.org< IDATh{p\}ǿsv/dl&rl#ّemI+aL&ӆ!mi6$L)$m tHڌ ¢cCcRlc,KZI{{>dIm;< i 3wǁ*ސW1#߉ɤt[[}-Dg%z0߼eJAX蜇4HYDlJJ)M\++4m Mօ_ŝݚB;wZT(B-mE@|~QGĊH["Җ eA' /;sUʤ{V(a1:;7ssC |#S&4_V,*[M,!$- m i냪9B2W\U֢kEظ>"?zrljlJ=H::: 7o Umݘ[V$I-N_H{&xJ?HpߕĖ6?{~G"t -]V-[<&XAi ZVV"Ѭ7`**ƚuuwwe jΠ!#FkƾXܾ9[WWUUL分VN=kk5ZSa{x59ݗ"9}JW&ƽ$!;]GD 0@sьwwFτۿzm͛209U}3 Q,<,-{v =֭D"xG6bal /~?]͎`"plDרuMΜ'g5ߍ D dv}PiA8Դb/*_nܰvF*DRA`&rN\/i 謻_oN<ȡ;fjoFFNeM_ Oխ['N{7L^Nj)`沢Froeqq053O-;9ĖMΘ^vQn:l1ig\!eu ♒HĿ\)k@M,` pmݘ'ׯL}PC_^dyόɍ'ZNL.p/\h5HxӦ~9x_|fmggfa盃@Ū@@y}AtQa fh.1@AL`fvCEkM (_.Aěc ~W8ML fe7iOdzpLyߪщ,["aT5>>֩-`f`W839-ͮhP&[4DV 9mKw)Euuu¥E~X ȼl2^pL]`@!&AL8;hH)Iy_s;@u>f #]Rqɨr&0F!ػ, 9+e!m0bGl`0>ĜzngW, h2(Һ8Ɯ;ag(M<!fNG߻l;=YvMrflQoj+k33;G/| vFfW][W+6'*63: Nn^CVқjUH@iESh"N=+NX B+Az_bM__74467taDW0Դ9]#zTLco9^NJȪsxʚ{#& i`b.++Hs['><<;eww7746h0*7n E>o%8o ]x+/VVLI ^kM-${^#-iO;0b ήĎj*|+{ވfךYbIkr- AiMވ<ܞDFM 鮃^lk6BYC{ЬX/qxx٬| %nOLxЧM/Lmo*|gȚJ`EJPmtjY'FY^B@iлEuXq@c4,zMvOZKYىuO0ԝCCC7.`δAKR--g7A^bZw@_aj1Mȵk3 mft *yxD>:sԽ"@n<+!XUW ;bLo!m?=ECԚn2|Z 8t:/̿~!_0 f5 VczvJLE n!䧇~G+VT=7@%0#YVM|&bOC=%YB̳'ȃݰxURZM#Gۊ몞돈(NZ`TrA#~-vܾ@HwoGh-J-ox״tb|ѣGO677WEwطP-W0bϭ!?9U'Tx (m i%kԛRGGaå蟧K_2{ikkK˿t3/_J1/|OT)"m4kooe}ɦOuUCDNɧEeg<;6>.k ?Q5 x"J3w]b HCDՍ)ݙ(KOߏ%w/x` Dodr{ ڲR ?N$u.x*|k h3 5X@دmzƆIENDB`Eqonomize-1.5.3/data/48/eqz-transactions.png000066400000000000000000000027211416454732000206550ustar00rootroot00000000000000PNG  IHDR00WsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<tEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/IDAThOhU?fIܤBBJPiKbA'(*"xVQ""'\lCbKhKZmcov2Mft[ =} p%%gB}I>Y^8Ba_$ *qAio gUI6""9ze2[ͷUG@FR JZ nڀ2JLr|9T@TZ. eiUjn$SR4k-R+6qlh'x.#"ny[=)#Pfg?Ej2yyu8ūp P};oPUk J--BqFt Bt$$4$R<::gkZt |׾մyˉV}s@Y^>9@6p(:tgi`X& "XIɂ*Fݸg8$!s-q'Ǔ[y8w, Uʱ!J< ^Y荦yC*;qG׭ez%.=Ƀf>7_CY5ab ng[d#fya'FJP^Z׾[ dvty"Mܪp K);ߨx-i^)J);M8cLVN81\oݧb畠Jc3}?AEd(KJ53?_K[Sf?NS{}!Ă5%1ؾ=Xή0<̙SKY~/i+מ8iJ쳞 qN?` l ~Jb^k[B f+A[#+7NM3VXe]'Zk7R( ?)XDv mmqrd y^:yƚ6,]{\Y0KcN׷ !ðAڭ5a,0 |yޏ >Jܷ,8La 4[~_U;ti/(#~ϩսU~u >g󆸔ߵPs/zMFT /P42Wr^Td'0뎧 \~K??W>4{pY[% uĬG[cɔݜM;\?5y0ʢqC\ T  @$b艔hXb&`ڪ\3ډE,aRJ=po?NeݱG.w 8G\T9OP87wu?7 u8v7`輠Oh`(PKЉD{W\" h爟(WYl&Q5'>ϖ-$¸Nܰt9Uxwufx*iBV~زL"ϴeACXJ)YHb椑v:/ށU"\hOQ;|;{M%Kv~WKW &SYbT\ An==ݞw#78uw׮@6FtdjÚxz0~txiu gΉ%#ϹThbk"]koW>9Դ';Y~@c *`?>QGm3֯lxFbp5utxa}ۊ8U=D75Æ)e޶y1A8+JUV@.ܲ3ŷGr<:sZ*l|^7*+fT?1-=Lk$ʎnlB0*'.$ q.H]ʯ]v+qM]u'LV$Gq1j莥mO>| }ͼ-ϙoԔroX[v誻6pʘһǎoZAIE~u"l_ޣL@p}SoTdahut)97vXҚf1CЅe˳0&-E>6k۱|mMΥkމu>}.UUYͨ(,'o^,oyeiuM7^U5hXf 1EKAnnE+o-YzL^B|mjm[&+Ez 7$dcsX} #*jj/tJ2c{IP3}'r#Ϻ㩂9l|z܈go_60#k kp%_ P)9!e#F!E" B dZ 9]Aggfh+7aY@3n*wQAX[8dr.Z"e9k/ޞK2c\1"\!!(9ѸpW+%j"ӗ3x'z%k$&6 XX#NlűSIZzJLÑK픏,c)LXKr^/njZvvrfg`PU }}0_&_M(l‘s@ブEEG,4M|ʆC*8;ݚi/*5o˛dNC̈́QL2`  CggzZ[B ipH}8 B@?f #7F&+;{s`g;R'N nW=VW~瞊yyw5Rd#zwæ(x8Rq:FWW2MC:)b;H%K2;B4ͿWӏ &|!so_% $ #in R555$pع!8Vv6R[W*g՗G,z>NmMCGd3$S=_P6v݋TCyE hO5$}x?TJ8/W.EoV4ė3]@wtW!.o-=8:D?.{I8.? G8 p.w.B(4$B¡^ڴ +},"ݿ5GIK=ׇah8vL:IK[H6EםǾ~ze w~!u?n4),*еD&" agc:G^|y;.ׯA L ]Q24ې b_zzSIΌi̪+,^xؿXpu64>Huycl X}֚UW8 ȥg{ENa/3|?+IENDB`Eqonomize-1.5.3/data/64/000077500000000000000000000000001416454732000146365ustar00rootroot00000000000000Eqonomize-1.5.3/data/64/application-x-eqonomize.png000066400000000000000000000073751416454732000221340ustar00rootroot00000000000000PNG  IHDR@@iqsBIT|dtEXtSoftwarewww.inkscape.org<IDATx՛y}?ogjW+еʠH6*s2ILp`@l* BlTȁ1 Bʉ&q\$Q$ˎP.$YVf=3=ήdgz^}w׽B)'۶m{\{sƸT=еw?ܹs뮻ne4a!L_s/2_{~eIUxwF}sjXYe  ٺu/}tȮѤBJpđ đ*ӤT8T9R-rr}uZyy {YW(j"QS?YCGAu4xtanl{"1h!},'yv~t gk[8՟↕t315,l Hrx=>YJݪ%ՅC-Rbբ BO5 ba}'\ Z,r&⒔eM#ދrnwϧg`^Ƨ' 5B!9/C [DY_@@\ E$1ayZ4£6;̩3d5ȜZI9:=C&IS1iiX" o, L_{/ Zu`sKKȄta) , 6GcAƾ4 nZUFIl9Z9g SM4蘣30n!"i*Rbn߃XfEJ$-lBL$/(x'طw\^Tu40?т!b9r!\M9Njʱ8C8aO09]x~=֭ꫯ!Rr??xC*D'IʣZz xo{>ongrb?⦅oRG@4Z̸%zll. {V8fZ1m1{fpa+_3֬YSޓzRu5KZ7)̌5q>4ɿTά~*8p+nBuӹt /k)[r|`e,[uRvO1N>C[ qIGYy9K.ܤ@[4Rg~9 t9K,d޼yU|U>𵸊+{3TJkavl!,X!S һ9 m[.]78}GR} \o,e`.PfGHId"J&{L$P2鳽Ǐ BAiMp g9_ŋaS4uhhH7mAݦiÇkx,`*]dXf_,4M`0H P|8W{َ)IB&rNXنۆ^3gV 3*[z/tt*Y<sHuTh\*a78X@BLdhhhL%0 džhԝqo8! nADcn~Hh۹ 0 6ol?_ $.x;XzAG@P*aa$({0{b;vpFFF>gUW [$XJJ]@D:]D$ɢ8NN:-9 ޴iɂSfhՄ G x^I* V}옶m@wkbAв, (˲ؿW?cMGb@sstSP(T-N__ߴExMRgeq!*[J;}g``j0)JqQgpppFli~\q6oޜD"x/~^|ŧ4M[ oH)E"}4I;l,IENDB`Eqonomize-1.5.3/data/64/eqonomize.png000066400000000000000000000077231416454732000173630ustar00rootroot00000000000000PNG  IHDR@@iqsBIT|dtEXtSoftwarewww.inkscape.org<eIDATx{U}?k}p/   1&Z-I2Z#36q: c[N|L(&2cŴ^QB½k>{}=s/`H{}c^k>JD]=߶ƕRO0ȇ5=1@);D$S^'~B`D1F11ƠHt,qĈ!8r{'ĕ{j{AWJSS"TJu_:V=xq)P% k<[)刈_Ntv;ӧfw+Nq[x QƎU{N)¹<(>_K-gRMŏ_ *.:8qu"yt` X*Rɤ)=[=k/\|5"AG c`б-~vv(ZVbmRʞ5.5#N}Ǟ8i)W$LiS?s?R]"ʰ-%I6\FdL(pm"1a4͞yS.q&5ۚ{ nӴTh/9L>GV?Jr6MhBˀTj`ʬQ:+l:}s/sS! yG8z;x.xuVO[w+0 0xOHUlY_rnqq}w%e93$NӃ# ]928x~ NVXx ?H jjY_ɐ8 H[tꃋM_<&4+ [ٲemBO^ҶR9ڸH)׋@eqHJǥ"J`{9rEVI.1W\q=b?|tfpwkxԘ}_+"USbGq 4HR 8(mvFȈ%@)rnYhSG >u3UDjCD>)^D/~4oc"Uzf#dJ= r睇1g!Z|~iw=2x,'r?"" r[S\2\b(n^[)޻ϋm;;N`DѢ`n-,>0_/~0){R6W~i!~B! ;fu$UҁK WATR)5ᴩ#ڏNVcp""hxxX|7tKw}`,prTS!Ha d2]v'u}X$ Zt٧fy \ eYKk8Nr]cBYGsK,lUb/b9eZd|/D,@iA/{/()M!a,PN e.O. Xb Ҟ 4o`B= 0Җuςs|G/1ZZ{Į}_|ߧ7w>_o0e04 #gc6ʺ?J^`A(P(|w+įnpRi#  LgcG(sR. =::a'<` ]  @`AzV٘AA3.AfW51[_q 9l wuAYqH5x`hp{Zxix,<^]E?5P5 Оh *'#@>:V^MUx og۱ldctݒEh}60D@<0-(dlzh~:O?4v'7tƈ=ǔSx{y2Rm(T<▰qS~JFpf<Xt)MMM}iqQ_LulV{.븀[!|KC+ NBЂth-P,p8~׳D(t*1#X0*ŧ0P`cMaY<{=k @P[ xhB QAL;Pyc V;W2w\nhd< q yc* Dڧah.ʬfq_… YjPR '>&(l\@fTXAuAH0$ Y޷<ĤIqܡqVP-r&Eb փ^tJXґ]@5Q%[}uT_fͧ%BVbQD!A'%@´iQ6E#J) yN[t:ض͒%K?uCJGY))C 1רf>Y O9sLdN:@kͲeyNgG-Z<ʕqW2}Akd|cʎ ?k/"~^xSMViL{~JP&6$ԍ һ?xDԸ@+V`IIc{<~owGGhbyT5x͙! ǀ(i6Ls2mmm~1a[X||ߞ .`}@Kx T`Fa8-=od6eXf {as͠=2ng{@Ê+Lu c'N:˽\$(#+D)_e#FřOI\Ɏ;Wvp_g_p1j$ >7zD6WKʉ*Bl.BR>Nsog+i)H#FG ؐHB, >VB^Q5 G/)Xb/a^ngg3C7^YZILg/ctЀF`UzZ-ÔP[@ ~}Uˬ ֫PPPON1Q%V"XV0*!@*W1(HDoY7UJ P^>z?.>5,GX4_p*pH B ~@; TSe_"?U"Դ`P\zADdgFc`IENDB`Eqonomize-1.5.3/data/64/eqz-account.png000066400000000000000000000027341416454732000176030ustar00rootroot00000000000000PNG  IHDR@@iqsBIT|d pHYsctEXtSoftwarewww.inkscape.org<XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/IDATx]hSgIl\q7-9aADžEj ` cc/aQ/6G901LRZ伻$Iy~W<{9o󀋋p-gL 7@4/,)| dT̀^6`PS +WͶY7@UՕBSٱ@ @8ܹs䗎G=ϡfK߬ .\QJKJ~vxtiz*Ǐt:Rݙ<#hxhc555lڴ,X`{d2IOO'N`tt4?|8fYXl֮])G옢(N[[k֬A}.pFQ//gB cͣ@9z 8{,L&?|IJyDaiEӴ7w~?466R]]meH$D"?˲J)Rbbs2@Ӵ. NrOQU %)6'{yU_&yXRU)6!n`e˨UZQn޼ɭ[]w܉XE˲~+8ɓ0ة{ oq pZӸ8-ixJ1O27oFQw?e͐J)[Kq˲bE;%CPXQM 6Ϟ=ܿp8S& zzzrƶo>d2=0db匭[n}|BtvvN{ hoogS nwt p pZӸ8-i\4N p8k5iNy (PUuu^7nܘ6xx10|Sg?lB< v:CMuc)姥8@n+  VK)wxޜ#tNCS~m>Ho/d3LJ,k1 )xB}MԩS,Zniػw/O}!lݺaObk6کe0bd0BZd#d4%-RUui?J*=z;אR~fB9Ex<~WO3'"ǜ2NCD'hIENDB`Eqonomize-1.5.3/data/64/eqz-balance.png000066400000000000000000000102201416454732000175210ustar00rootroot00000000000000PNG  IHDR@@iqsBIT|d pHYsttfxtEXtSoftwarewww.inkscape.org<tEXtTitlescales of justicekYtEXtAuthorjohnny_automaticbM!tEXtCreation Time2009-06-26T04:35:18QtEXtSourcehttps://openclipart.org/detail/26849/scales-of-justice-by-johnny_automatic>zXtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/IDATx{pTUǿvw$$ $AJ fkdQN%b\èlhQ(EȣC!B!Nn?o4Cl򩺕s&7Mә7rZ??o߾}=̼|4Yafz_z%zafeZqVRf3ӧ;1ȏw%|m۶?~͆{1{T8FDOi :t@QQlll6Vf$d,X @κuJ&TuuuܫpWW HLLtXL %":-8u ))I> u M.ލ7ĉOMKVZ,rĉ$d2OLL%~UzΞ=͙K.EFFF(fcD|G=5ki2f `iwwʚr`@jj*RRR`2:RRR?bŊ%IJ!"L%߷rJnoo{{{㉨-0-Zeee\QQAhI5tweff3_| 3,jkk?.--ef.Pq_3[gg穝;wO>KKKc|X|(͵O턿Gɓ;03o`ś6mbA |3ommmk*yyyHKKիW+%%%JGG>f53 8pL!Qӹ5DSAD̻W^Q|ښw񨆆8p7n$A̜9sܹsfAD@ca9hӦM^cefvqb03g@ot*,˘yKWWױ W^͹sΝ;eX) o`p8p8C Q;94++k,YsZZZf9rDWTTPŅӦM|^"`(//dϞ=+1s¦MX#iiifk^oIccc[oUVq}}3 cϜ9FD'###;;;ݑ 5h(KF0 Pm3Bz}l6^YYIWt:\࠮k׮c2 ެڀ'N<2aHʲ3f=Vv{8ZխHIIAoo/^> ~X,GQWdY^̒ZMnǹ233l*w\&`jt:l6ۭQQQwu7555h2fݧAx{gͿϖliڼ{<\P ⧳g~0 U|z N྅yyyDDD){ qWp5V X_I(,r>32ɓb#Γr}w>D Zblzk󣣣9FP 45gΜHJJKDSL9{ԩ(ju5%Lxli"A,5k'f(r0XV 0K( fXT?Pa#GGGGhm508Cx$! Z ث^jvn4jԩS!C&O\bZxրYYYiŏv@Cx2Bǎ|U*t:ne=l6[yZN,/zuGg楹MG~0@7pܹ0 jWJӷ766BQEj5v|I,pb0Bq$q\.|>TVV]YhʉeY~'2_^TEbccyƌ?:?1ej_f 5(--=yر;f^5" }/:=RPPСjh:?^"AMD#oS3H+Yo/))yl6/H /Nl`O/^b}o$ t!iz騫ݿxۯ·vuu0+j(LDD#Z^?CקH4"ڣ:^W?HsfyHNp c?4s|^#3& ~J3(s&hV 1 Z$BP]Ǿa4cf u\$E*++ f͚_I%.h4CX"Z D ζG?#"v?¿cf@www'z 3*t:CDhu GE8oߵLÇ 0zcf@___v 0$fvJ$ Pֹ˟c5NX}8}%~h:ޑj3O Tq#Z veEQvtt7n̅ i;fȾ-nݷ ZxgEpp @t:/3z} >} ő,?:kijjBAAKTAD+p8]q\"r޺uk=""z)駟n$鑫-C *N'HD̜m۶eJvCt:q^^?52W2K{ټ>j8PtUX[JDם̌6 P1!""O 3f}lq@3\.e9Ñ$FGlKG ̀uN>OU*{4Yeg\.(2z\U O~.7@ufxN>ڿvp>3ht Wķ%+..mjz5k8?NQߨ̢ίmSSSٳghiiZW^m111/CBB %%%΍qǒ%Kh~35G^{;O,˨()Uo9??7ZEbٲe&jMpݕ/&#] hIENDB`Eqonomize-1.5.3/data/64/eqz-categories-chart.png000066400000000000000000000070321416454732000213670ustar00rootroot00000000000000PNG  IHDR@@iqsBIT|d pHYsttfxtEXtSoftwarewww.inkscape.org< IDATxil]u3;EI(يb2R . u@OI]$PiSFS$l85\4m+7%=˽3#} )`w̜9sf#ܖ+-cHx^UD[x tggL"C $AWYP8 ߏy3BR)̥Kȵk`5" _>wnfmiC _WJ8;vكD$vb35Ҋw1Qz.Tg'cFG$7c TZ,{H`Ο6]Az6ϜAy'Nd׃c] ou` ٳ˗4oF ᎌfgp#[OY+5puxxoqǹ3?Y_&HR>̕+ 2o;6vSSz`g1˗2V1~YjɴՄT/=GG\پ{yl-#ҁpⱑdqB\T&Oq'O"3_8 =oEp0 fnqh.I+LwQ`yBXP8&\ukizj6@MRM1ؙtg'Z)R 8mpq.33ku@"Zng'u/w_JwEP,MC5RSKN#YSѕ&+mCr9l>bi> CV)T$I&{uֶϷ": `:G67Cj7i۰R+yF5$T iq0.oW&3ͷFIi&"RA>}{o]䔺q PXB)Z}T<[߰Oݠ>+3J*NUB4XC$Ռیj0"&dVZxa V$Ռ0/+WN"rꫳfna z\ϸsl6O&G߼YSGcmƊ`YN0gUEH+t) \nͻQ%Fڭ{ZG񼤍D0P|[X}N!6/|ܻ@j/OS U3 +o|5H)7[;NR*Mk<1Br.haM$>G{/#&`i HRU kTK4}֮:6[dPB+zCQrw-!G/GG.um\c޶"ET$Jw)ISFHm_zb}Z.}5!"E+ *m ,u!ߧ*.PdǍ2FbaWSe,L9Ňۙ-RTzZ]jJł7}9&t=قcOFN0`Mʦ֧A+u4|SPٔ|f _٫e5L:z=$>׌AGRRƞjK W[R i\rũsD)/^ηf~'yO>ѳp1}}eF@߼%٨kEЎ!ҩt:QRJ}`} 3bOBb36KӷVZe ǟ-#!-j"VbDd.|⥗Z[J@}+=}be@\݃/>H-ɐWޘ}vݖr[n˯-IENDB`Eqonomize-1.5.3/data/64/eqz-categories-report.png000066400000000000000000000045421416454732000216040ustar00rootroot00000000000000PNG  IHDR@@iqsBIT|d pHYsttfxtEXtSoftwarewww.inkscape.org<IDATx]lWwfl;ƩLD8#HP ՕRH !jHQ)UUQ)QShҤqHR'$Xk3sawݝݙ88࿴wf=s=w X"!*]oh)h Ճw_oC[f߷dr2ڸjw>z3J/m0tzB&R"p7L6 @KsK=z`m G#RIɤW?XM,3@R7}}3zu^o| ?Bϳvztyɉq,kh.8RP t^ ħ~ 2*7417;JVCdF卯t-[>#. !F*͍d%=Z֌!fT9xbƷh %`UXb*m{}=F4d2[heY bU‘*#TstN嗀Үgu=' ٸ a+`% 7趣4Z4y:Y9PK6oo pMs4Ds gYsT!`4l 5jiTY:P +(TP޲5Hql\ '6>&޽!V^:6YBI˲*QJLϹ0|?B qƏLO'n2=?&n"\MS&stMn\piB1UXave;4B3( n5a(86~y ֦;X(0 ]囦Ñ x;Xݽ%+B;J?eK з"[l7LG_z ^^{-˃ngrV&A*WS% z|ZE&DBVG)rFUnօ8U i\:0M#*!,GJFbt 5y[&UI"cv;,ə[5@HI٬EYB(ܹn%GQ6<*53T:^o188Y LKjoC+4kLU ?J ad%-¶HR(<\2Dx{رc:t7Ǐ{Zvr ōKy<QR= ʕ+}3?uB֮][o2Rc@0 nZN,!;@TI>%דqSvL֚BCaA-lx"uz6i] M<$; SkѢ/5 P+U؀9%l-!B~H?A[kk=F/ 1N9;0x3u/U4@mۮ:h4b˲| =4 {zfŊض,;. ,/@-($.jZt~x!ZvD"< F,E{=w}5Ϋŀz.,L7d2"M)dD"AGGƮ0QFJN<@iGra|8y${MSx<ŋdժ9ӎ0yGxï̻* lh:nd(>5ҊkٳԟW vvv[3gr'Q}}}iJg͚5[3}$\bD%>}0ؼyssM:f۶mtuu;OJ[ӥzNЗ<.j èifO/c (A\2D*ITk555%P 5}1Ycboʼn#G8ԄeM*߽-dߎb@4N:?3LXv/wuY;\  5 *"utZl*u@oapK 4 ׹jR! ]H]eB,u)g BilpT>+=k2D} $Jy3@Ȣ}Dۿ333;NF뀖jO Z5H)QR*رcKP:ҲE) g)m%Y,yο/Bi` 2iN\qnl'q<|)#ď$z8-~࿈E,{VIENDB`Eqonomize-1.5.3/data/64/eqz-currency.png000066400000000000000000000101141416454732000177700ustar00rootroot00000000000000PNG  IHDR@@iqsBIT|d pHYsctEXtSoftwarewww.inkscape.org<IDATxy]}?oxlmL %B! 6T$jKhB!E!DRuI.**QT*"68,xxόw{Ox3JWz,{~g,,1ħ]qM}\梐9h dӯ$c Wjj= '@Q IiWF Zӯ֔ Qs]k+i(5 ]eWҽpi 0-jtP*ٺJo`DŽ)PN0+bEgˢHM@W*4Tݟ"Ӣcag} 4lhu I77~c_^bUUʫ}A1&eo­ƭĭƷ'2D ٥(jFeЭ0`$ZyA? 0./YX ǐ ɈO,BoEk&N62xtO,]?I D\6y]wF+# ڏEZi>LJ]K:n+[xsBӏbVW#BDH Q9HpE(jCtTK2ݺ%Ӳ $pa.%.GUM.7?S ' >O>agOqHIP*ֽpI*l"eX3ɡЌu !z>A4ZTӞΆK% H$ %HF~Q[P([axДbbMb,l|ZEL1cDFIQar7͵`Y.bU]l;JvJ*j-L26mC(i1B-\: U̅dߔoqbB\kd[,rXm36z0JW}ttF<5ZLanu_Jnv jtקA m @>ytw!Ԧ[Wo4ǭ[.lˡRrqё8CՑT!´g38zd?-[Ycd: adXEX Rc(ފP3)݆v"eTt")J)0#\E0tE,_ #'>q|lGRm({MQ hEfn^W. &v Sw6 I`F׉nMޥ\0l˪Pً8X5L}lݺё TUoIV|oTֳ4"7XK ݋qvmb?zPK+ڒnsTmYlyv2#jbdͤJH)*Ef8Z*=~tu NGʅDh&䨔m=I\k ? hu]K7@&$],=g1TN&;CC49ԝ|YƊ}DՊ^~#[*i@)mRB!yj.2Z.d) :/*)^#^4z УO~|.0-Q[I")q] ##0jR(bEzZ*XW'hCẕ i1/`['RiQDs/q㧿D4 +W("K/Xj%FaklB@l0Vn|(e1r|f@>߁ak$;t.Аr_ ߷R?`[@k|R%3weRR,q'V^J$:^z9veJ~4{,݉2rC #Qo= 4Oiƍʆׅ0 ϥD>~Аi*)OPꋲ\ɶCG+ɷ>|h`-+^%i[f0 Dv( H0=ZpXHӌ68kݎM]%EU2u]NV((o0)E`KaCS~ !jNj޽X{re3TXFZ+= %= ۑRR)V\Q@7 =mK1t`woںo, Eo~Q~^kϪ@tM'N( ֶ)@Q4D EIr[/WQD_v]Rfߴi˫76d*1U<7?t{Uo,"rF-=#=\jthm|}'OW% d⭐Yar_5 hؖ;Pm/Y@(z|9SElJ;9߬pw_gVszģu}&1 d(Em״2Z)r>:@bQ<߷ItGO{sE@q,;XU2MhRc!]](d2VUe! =Yƪo7撀ŧw3I~3gSC|T Kv~s<̝4| [:wgFU_O66_K!diW*=shNk7UI#'#u\i߾vԯ#>#e1E*0 xw'<7xFq:=HM'Г Ѣϳp1k3xXɀX[s|sE1IE6=ɿA+=h dӯ>$1SgT88 /NF`6IENDB`Eqonomize-1.5.3/data/64/eqz-debt-interest.png000066400000000000000000000067711416454732000207250ustar00rootroot00000000000000PNG  IHDR@@iqsBIT|d pHYsttfxtEXtSoftwarewww.inkscape.org< vIDATxZ{PTξwYwY@'4ڠCc錒4 t ƩV#&J$Wu&1i Nj`"h$٬wyw=ee ;w~{ $@ $@ $ dzzQ w:cঌe6_$`t -e4_$WZo\N?ECAfZ@Лt}@3YHJqxv| YCcb ŜL"zPg,,ˎ, ,;_Eyz 'a2#0 3 ?02,9O>䡎ް"I)0"aY`1 l1ttt8p333kBxcIv `GSEQWVVf0zj$⭩0 &, 1 2[ldddD(NƁ'Xu`<7kW]]] '+**feeBuM510cّ)pO0J:Ljܾ}{MVa͚5]iii[n'1hA(<"V`4ӧO/mkk͛?G1'7Co H ݸ~A` ˴7GsB<'sY|k_0no~ pf"[d2{w?sR->L&=>55571Ƌ'3av{/ŧl~^9ۥKbtc,zrľMaNj&P |{ppP<Ϣ֢+W~7l`'9P 'B\0 # md2|11\.a(1lz-'{Gw4E˲ab@0S:ߏ<OTV]ve{<P(n:`(' l`*ǶV\ ͉nܫW}_ޙBѢU  # TR Hc7رCϟ;wn\."dp!eLq i3soobqTgh|0If.ghhl$70$P=f(aNeggFѡP(vVзz~j9p.WpKW_={UCӭAy0ƈ]---OWUUݨD"QzQQѽW~L&#R.fgg?w}Dv2Tjv֭[8ٳ KNN X,{=ZvH ^z9fcm$fZ|ѢEΖb4`fN4E V*T*-l6ۦ D7na0~ ,ohhXGg\"!~#Gò,úurkjj>[jծ 8Y[[c|Du8Zcckj{:K.|}5d2|m۶}e0V !>v]6 555{ޥrPqBǜ9sf0X8^r]x1[z)J8d𨧧dEEق % n; IZѼK,̃1MI////?VvlbTF{{>/^Lk4[f[{ر{D"شiS7I/Zd2Qb8;466[ S&`0TQ_M$Ҧ~`d!ۺu9##cdBp899eA(*ٌBvæH$ `M }}}U{%%%.^!C)))! MI !V+{BakǴ@QԡJDgߎU|!Z|1233Bao w7o577?W$*Sbֽ^αKjnn.e]%cp8jw_/_?1vTPP_oϜ9t:;Zgu H999![]#>ve*oZt:ݪTy>!hjjw:FU'OSإT*on cf;P]]?7;;T1>B.Fs).\>1)xqooK9S(rnV-N%`Xm߾ҥKb3fÇ233"byIsF#`y3f]~]ue?b1ZfϞ\"v ismƍʶhѢHncuOO{Jzضm H:wtݛr\%%%"I;GbXvzUp8 F|rk^^133:xiR_!DG߮?Z100cqBH1d+:x V $@ $)IENDB`Eqonomize-1.5.3/data/64/eqz-debt-payment.png000066400000000000000000000071661416454732000205440ustar00rootroot00000000000000PNG  IHDR@@iqsBIT|d pHYsttfxtEXtSoftwarewww.inkscape.org< IDATx{tU՝?<"F8R[_) *v8S3vftf9C:N,tA $@Hȋ$&q{&$$@YZg{g~{ 0B5C[E3''ѰȮJJJh'odi,~x3w -TC/uMu͜ ޙGHP Rw%x1gF4=# w=-Om`8/kk(r^dB(4k4'xP)+-gH.@E6aJzTig$-'E麃4tL]@]%c> B WiNĻd e~,n]@%K!Rϻ(W20"_WמX0l[f'o}D8' (_i0^u\_0mIjHZXozU!GJ$eټT"aRrXKK!1W[|7𰷦wjɔkNUt<^Ц9)˦+>S'eȬ%,~_͛~X7ˇ=`sW=G4ٴoݗ=~uֹjli!~mvif+H3h+n۝J|hhĠX޹s+?=LWϸ_,I96/2L}moi_~NXqe/Sxgmےڰӵ?;F-W_k co^P4U]z0PQͭ=O\]6^5XoOZm;ZdE9>N{w(KVң6;wV~Fm0c*41wQQ!+-W+wi~x WT 4K:~Gg{67wcy5y%0A 00p&_zi d¨mG0Zbe_4ڶc_:'h1P32XKS,=i.j鋷zy#?U:+wRKmK)6 ~_^[[o\0~*]b:eyl`"Ƒ] p,rߵsƙm }v! HRxW({y@𓱊Sw\_t=G¨M!R)X䱅뮚T7B#mKW7&<xТ;p̾"cCN˦clR[itlp/SJ}r󗦄FF9֒LzOQ9> ͝C{U;hίLXP^cOEӔЄB}WR6M>p嫟G^r3BK~tl۱_.b0kx}3ir!ЅhN\kF ʛ˛6YYd䝁 P_ewOt͝Vl'lʲK%J!KGxwWu5xݮ0XΔ ?yduG52~B)>$k]44cb9GX@j"cu,_R2zdTiLtoH]8oKNCXJ{W,7v<W9@:Ŋ -D¶xSڃg@|gĠ4i2ќ@Nʘ&JZ%H0z줣E\13lf^е_/+1L-p D&)ˡ)as۹ tZmJ)?fҝ5}z3 'uBLJ/Gf0+@ܿkU+ު;xgL؉D<(YjWB`t7SR6ʉ?1ӎkFJ̽ ^ |iʤJ`zO:͢tPaڌ֎[S[޳ޭv\bfD(aϼ {hHiMh5k?ByP=6|͠"V}愌l[^7y}ux]~=iwm<)4M(ǃĦ*7 Q@,'J'1<YWu#f~k(U+V  v;/`M}퇟Y#D}M>@L%n:6,׾e\U Ԅ'ٔWk:8#D&BCB:hoq{{Q=+Ā1[[C˺Mbrf̈H격H ٹn)PWA1N1m,߶N'1B?CGL^Rh+>~|cg;Sdv7UgS??nnNuyw7[d/R)Qx .8uW?D}h23@ B Q[@/|zjE?Jqw1 AujPF.G_1a c01a cT@Q3IENDB`Eqonomize-1.5.3/data/64/eqz-edit.png000066400000000000000000000044211416454732000170670ustar00rootroot00000000000000PNG  IHDR@@iqsBIT|d pHYsttfxtEXtSoftwarewww.inkscape.org<IDATxkl3ۻ(` uRhi 4)m B QJE*D"*5"vڤji(+B[`l휯? _vm#V3w7g &M4iҤI o#cs1Ve2?<;_% ʟnD/ QQ 5#g@3^޼_ΏMv7͖xCx@5$Ӣ>hJ>)ՂNGnXy^~@[fd5cT$$Q1_c/,g-Q&gi(h<_k;ok|  0` D&"g.lzX m,gJ*>{FA ꉀS1'g}>tzofd%15`Bke'.dkM0+y|_ZMG2ԁ6]W73p)D|7ܾ݀k9>ʧcΐ܉_*'I7¡zTX2Dދ]}aKwb 5Hɘ}b֕0[^֔`2*}gV~M WO&SPH;2(&JBBJmWCSv+*O,-!)$vhE12Krm$aOseWC !^#1!^qN3*$˧%߂xrCFpg?wte'x> d8ٸ^E2p&\|GhI5v-T}ψ><3y X4͢Kfr\,Y`J4&1F"V[է#W-8ٌȀ`!B<Yp &2Neb0lfX8kIJT#$z{<'3a5d9 5 Spyq-G.G#M䑰lb|,Ť؉_'',oF dYίK`3Bw؄I3N$dY;bRu'\yJx(**Zjd|7Q<G9s$۠5ƚc,ӤI۰~IENDB`Eqonomize-1.5.3/data/64/eqz-expense.png000066400000000000000000000060551416454732000176160ustar00rootroot00000000000000PNG  IHDR@@iqsBIT|d pHYsttfxtEXtSoftwarewww.inkscape.org< IDATx{\]?̾]Ǐ#^?N  JڀhT(4-F TJUSZې)I[۱w>gf}{;z("+]31sw.bX*VUb/!0 8`+)sqOXB֯?UVv2V?0>Z+6n|Z:xSZ6!W x_2sX1B|]"hBk]TK,?h YA!ZE(ZJF@V m :h1J@˜3t е)n̙JQ?* [6[ ma4@kh2+`LZUW["d.Kx\;ai/ M|%ֵ2.3~Y;[s~C4`=__&C o1xqnlс8L s%p-Qײ C[Sp9NK[h!L3YG>K a%Pzצ{{pcK FH Dt`+#o=v|䛀Gd $aP|y-_뤬 CwO$4x^lvCDaՏ)"k% + >}g_⟅ !b6va`` xA4XAkQ^pR1Ԧ\6'" V f߱yh]B@ߚ^Qm5XsRJS=lz۱F8|PFG?i);0rqܚ?MXf0òXvNb5vs  S^>;S}V8Ã'HDZ8QEPAR+# Ҩ`XvYE,`:uo"/f 7^b+tW~Ց0walKZڹ7 G12mdV E2qq瀧bHh9O)?.mJlm`0s\t$6VDZv.΍tvM=v_?759+ʩr%<`j@g^JH$ڣ9TX鿄ɊAvןwX[f_̡OeI8Jrp^z,?+!J5Sy܎UQ^hlEpfˏV0vT!B\Lxޘ9ꅖӅ۶M6^+upn7>mf}e |84BI I IncAv0hb[vS1sŢG.B&}\JdLR*3{-F{ϽF `}Q Bt҉^N˲U18pO.WffP,Xv|3y(`;n#܊ 00b \mr>x1ahpYW'?{Rr,UA\w؆̓|>ɓ_erb p :r+s_j\΄_Y# jC~*^@ύU |O?# n_r̷uXfЏpdž8ea6RRhUJaPeb?y5?kC T:ƩT^@4{3>1F\, #Lm 1Ԧ.ّș ](akZ=,c@Ch $ B|_QD b>x'\d߮4uZdjaPIV>F.~h=s/Nen(6RkPJ* ]67MWJZs;^-yKd/$`B{DV'>  &BN% yGǮѷ~3JB?0hW JJHqiDS_Fy%1|cϿ0u(pN}[G" %=3 Ơtx&V{ }ޑGڶrFd21=S|@CneOPΝ{7BZ5vGIc{;GHC8ݴ%{*K<+ӟ"߲D٠߳mmIT9{ aTJ\v:nxWZmQcbTRZx^3Yڤ ,4;v6ߑٖ4cQLϤGFFd0nbBX1AlrK]2w0WLI%qhQ6gs}/cU$Qضm޵H'y7Bl'Q=jaoT 93hz% &x׿?- !H$\ ˗_=AWW7R `;ss+5N:I6} X~"(qeo>Z/ J3`;.BRjy7!HsmA ,y20}lj<%@^::ܗ%c\R PrTqjj>Q/?7*Ѳ{]`?wG1ƍv{SƶAb/|}7t~%uvﮝCۓ#9lc>eҖ7OG_&Z4{n&(}6nscbwUNW/?#Y0+W DyGz[+tA,~[_bXB_k׮@ `k"=s6ISSzn5]F[[[#z^/%%Yp8TWcbqq.KUp: ӣK\h 8Ԩbl6[AV(R.)ۍVU رcZZZt1DPYYK|dƶ@O !ƍq9AuM(J)DQLQ}ASnnׯSs|ǶfF03  hz!II>8Mw("bjjJUH$4i/_}zzgOt?)R8թ>} ˅@ lA`Z5iYU\vSNSJ$Sh!()))hapͦt!˲%0 n߾]699Kn~z9tqX,+ z9 ̙3y~o9@ӧ?wD("נ>D"e,g2T d˲yɲ`0ݞiNeY$IZEybc077'O~x'\|W^ջ, ۷K,EQpݻw;Ο??!1wXXYY)fu(\+`- %,犺v˳:n!k+**B`۳ٽ{7={wĉ'~!B|flxs:;;qpt?X{,Ӥ=xbjj cccbOOw@)U' g^`Xpܹ/nA*joCt}466 NF-40L?z |.W9#,:::=z譝;w~E)J)dYNQȲ I4.TOQj?0z $IbxⅪ.Lb~~=L&H$ WPEE-4`ZvРyUUU2::U80\]]CѼ?@y f}H3  hFc`10ڀh/ <=zZؘ.Xq8x.r)ǏCł/KGQb.VZ@[[[QMɶY&է1[D"at^ٿNsOUUUq_$<ϗx^5s~5l~@c!ޟMLL4 {˨IENDB`Eqonomize-1.5.3/data/64/eqz-import.png000066400000000000000000000031061416454732000174530ustar00rootroot00000000000000PNG  IHDR@@iqsBIT|d pHYsctEXtSoftwarewww.inkscape.org<tEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/IDATxOHyǿ̌3I$nY"5^C!,taE= USoxaERP,"8L3o7Ns˼{̼>>>>W:;;$IR]ChvS$I 8{qU˲`Y*J]?0`Y!T~: !IܹSouu,ӧTfY95MMM^>OrP(غ,^~#T*y*qp||UA qFX,baalnn"LRQ**@00|3e$all 0B,˂an:Ǒ!lhnnF"gEDdsHtiy;`oow44y>0LTUU4MEQ(B{{{|cc# ,B{{;ɤZUUܞibvvKKK@kkz'O|oYOxᙶud2LNN׮]s-[^]˺yTSTpxxHKt`̻y PSDQ  O]D"D"g&033v|0*d384444ai qv0 ²}M 0߆VX5#Jx9C '}6FGGqun4D.Nݺu 3pLvww@{=DQt^qcUUi.IEQ (6JK"p֏$޾}˕rHT'B7׽ D"WVVhcqjIENDB`Eqonomize-1.5.3/data/64/eqz-income.png000066400000000000000000000066521416454732000174240ustar00rootroot00000000000000PNG  IHDR@@iqsBIT|d pHYsttfxtEXtSoftwarewww.inkscape.org< 'IDATxyp]W}?ml-dɒŖ9C;Bvh3aM(5 4q,Ȕ$e4-NChm!Iš8%l˲,=w?[$[OS,ˆ|gs={9w 1Nl S;u%quɋOo;U)1e 7kśj;dS|յY|>2g|}9Wuh,Y>4u pw%@ _P=OGׯTOWϧR0AyϛU&jCe~-]@0qPx-`w>4us!Z*['-Hxx?9̍]ۢWbx~2K}f>\PL'JP8}G#Z j{HOŬ$̘D4@ݲ;Wr-0#́|鑙;**|3XHP&4^L&O*ɃЦ(VW+=\3<*Q^TVNQ P/p^,BI㖺6h6uY8{(|dnl0cۦ[ojn쩽Fp GY0X ʊGvvE ,B]'hR G=q{4DH&瀢>ݽnkuC݊@T' [`>І?'XŴT/&f*sLu7ml'5 B)immeժ.[B!Y-?׻"/xZJ!5f!}q|/{ɽЉN̥*<7^:k\_jٵBW,N&M-[3t!cƢ~~na U~TDJXLd! xb >r|󖍬[\.O"cTg+78ElkzRɤIFGI]RZcltƦVq;N,v`D 4MAA}w(|){tYB)6oe0z8c#$StGH=HCG #hz v5![ PP<Eo M#:: q]ČsDt'֑G^9K0*F!J)ڰ,rH#W$S~)nݱ6:;WǏ yKh̚iY:.|y'I.~c3}g WCp20l\d`,lݺ.gϞ"J Ќ&FGGUp` |L,Ré b^ʺR wmpr D"lܸIeˆY-g%<ܥc2v'#,*TߩS c'O i74iR3э@i/ u(`?d<tq~If\ '3n ! 24::!b!SsO&>?MC._orP|q==wCk mDc/HP(\7o#P8:a7vD\1g/yz( RM%S&M2`qI_ 9> qg/?qϺ,Pxܲu!c劚J&PxcY ;mg[ 2!'[ .~HS.00kjѤR*.0Bٚ/gXHѱck=z=1QJ\<$n`y!tݰ08z&ۏb3-8|pѠz9# /,HX6kl&M )BX?}pV`r;C !9v={`իHR*$- ~`|&N ~>MPYYG S(?44r\XGS[Jz3|xҩpd)@ITRTS,6iiik'7DM_( !BI#GI%:LKn<\.z\ LqRڇROzD1q5 !6CPdo8ӣ~l[?]2?\A8<3MKFfUUURNNN4??#4!hM`DH)mur=y& Sy}u7l(/nhhO&//|y !>k^~Vʝmo:poV^<AE>{ѢE5oCU~;Y)Kˆ[oPJB4%oc='aBgƌ?ؔ=.@Zͻ͚5nhPpBbŊy\sݻw?WYYYH$㺮yOYYgNƎiĉ-X{B}w'C際7.Yў֬YzᇭKUa3)#V۶]4|Xۂ!'nso47f eREsϞӷv{W.-,(zQqk4yCA91~x,BzOPS Ѳ|6ZWu `[L<%OQW6>4M)y?U{@5 {>;Mŷb:I-BһS<\q ߿Oc]-'H3D$jys0 d`g+I#30˲4E2>c/oMO-.6f)*)7M{ٵDJRXXʕ+)r~+E)@F&\3;|Qx.SͤgLZ2hYhrCf(ȒŷYv+On!4\躎ۿЄ3NgxJJOΙSo:a-;xbGM(3Ys tkC"@ Ho`FW:v |'L ⌣z͏nB)7qЄYP izL+))]q˯c_\>?R.=&0|t~`  5H8o]2?.[*#0#0D/?7XIENDB`Eqonomize-1.5.3/data/64/eqz-ledger.png000066400000000000000000000033631416454732000174100ustar00rootroot00000000000000PNG  IHDR@@iqsBIT|d pHYsttfxtEXtSoftwarewww.inkscape.org<tEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/IDATx_H[Wǿ?Ʈe0ѮqvmQhRA{+sKA}hS }LڲvTi-"faVۃ55{cM#~˗=w,,,,,,,>p};󆑑B0s1%3"R:8[bjiiiqƇXtEQH98N\av ?===ICCd%V5/ׄ_0k&s4v &BD[ݥpEEvӹ=͘HI&^SJ6#;)e>fnlp~a=[ܹǭ 4m͐KlTd188?==}^NNch,U6[1ݞp: R;vTe%[5X-Q >3aa43"adaaayz/--- BZ(*++=4Q+^4IDfgg/=xz}ojTUS":%B۷D###`fQDt~xxx*Q>9 Ԅ2'Oۋ˗/s4%FGGE*R Ϙؽ{7=Cb1>\niƲn\ϧB̊nSss3*++s566n Dg" ]['gfp̦:fVzQ__TK(µkאHV  㗛7o6d DDp"l6K䉉Mp) _ِA>ֺsԩSu>^__o Z$c`˅p |sرE!SYV` u9#C?S~WWכ]]]cp?SGh0`CCCCz*{IaX9rx솁,U0!S`hhhNUȑ#P)bhm}I}-DJ)2.:G  8pD\nGJ*4my;*WDWӫ̼Hg~~>P221WѣG۝.+ Lc3!^ U.W@9{,޽{.zfvKJxp||@lD4`0 j[~(tvXܻw/2ӧOSϑH$mL=3$]#r(dg_C(&?VwlZq:s7P.~_NMM}SUUUUU(PUnڼ^/]x18im>YWx힞_rk( >F~ߕ-ͬIENDB`Eqonomize-1.5.3/data/64/eqz-liabilities.png000066400000000000000000000034151416454732000204360ustar00rootroot00000000000000PNG  IHDR@@iqsBIT|d pHYsctEXtSoftwarewww.inkscape.org<XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/&IDATx[lUgKk)`jDZ!ن%ZUH<@0h%$x01mvlD #rQ χ^lw/dg;?9;g@9r\(7;,k!\D GАu,RωȽç5ɖfzލ3@Y_w?=|pdtLӼK)P LRUUŁ8w\riy7)TTTϘ1QyQ)uwrz/_!r! ZDځ`k2|{d˲JRO3BcܹqvIkk+X,9F? М,Z<ceeeZ5k0}tmvww̮]I Z ~ilٲE`a|0 ~?k׮eҥ(ϑH6Jk0uvv~N4 ԓS@q|+Wn:JKKѓcضQDWJ}qڦS ˲juŬ^j6'ON%"{PDm92`]Z01Uᰱ;3 (ڶ}DIy%Fk#/QiV9}4ϟhpBD5'ŋ/ZJqqD%Yg֭޽)<-e8n,+[zh?3OoEAAw0>嵵C.`%%O%Fev|QPА6`@moZ OVsk:EaIɤL[_n˛ͷCmm6l+ck (ZK=kgg審Sg$;vfe[kd؀~.dsZ/&b+#1NܜiӦqXtwwǟx8 TCTVn[dtT<ę3mڴK۷/= :xH6h7ٌ7C3 &DhavBzPt-9x Lzȇ10&G" kj(fpۀWlwH ̙Ϗ|WJn!|>̟?t`̪d _2f1L}"k>޶m7az{{Gﮯ'HKdp/s-mr-mr-mr-mr-mr-my.?ne$:qĸǏ}(,,d@8nZhQ!5N~"Ը)>!#"_D^zŻ'վX,96H$ĽMնm #,.6識a47*>x<0k,Yc˖-ݻxyyMMMw< *^XbUyׯٓX~رG824JjeΜ9TUUzI9@) mloo=mY4 ?Jp|S^oܫ y+ *g~"R9iY!&";#G9r\VLǮIENDB`Eqonomize-1.5.3/data/64/eqz-next-month.png000066400000000000000000000025041416454732000202430ustar00rootroot00000000000000PNG  IHDR@@iqsBIT|d pHYs$$P$tEXtSoftwarewww.inkscape.org<IDATxMlTUS2(!؀{ Z-`_HƠV](ѕ(;:3.41hLwӰ# RZ֠s19Ts ͻ;g.\([v]UDN 6R㶼*mjjED>D"> UUUN>* 7 f{rrn:kq7Rݦr466~ܫ:@V>/<Bi o8kEQq]|m8kR 9<\2GQ4w*+w9|2\Z'־R(oW]S]]Moo/ͣ.!u#|Eà p]wo2FƒKPDndʙ߼y3˖-tZZkYtMW֛V\&"_sCBBBBBBBB ;s{NIENDB`Eqonomize-1.5.3/data/64/eqz-next-year.png000066400000000000000000000043421416454732000200600ustar00rootroot00000000000000PNG  IHDR@@iqsBIT|d pHYs$$P$tEXtSoftwarewww.inkscape.org<_IDATx}pTWMBBI,֖{w3Vi V-N)-_ " d13emmP 88Nn#Gu:jX q׹Y6{>s>},GyGyU- GXQQ1p8JE\.m{ɓ3TAY..TTTL(**:,"G^zpJU˲joB Z+=)H? l߾ڣG~xSU4^q[ڵJ5U"eƍ w,c˖-tuu] Y߿ z^ !".788HCCǎ8qΩ{sΉ\utѶUxB1c;"{aǁ… Yb?"#,HWt6lԩS7OULoo Ø OGGDkT`Tկ"n7OUPOO["2 `޽U/QF?GAgtwwD<~DzEd&I!ٳ}} Cq HiDdhnnff$Vt_`Y tK.eɒ%hiEd/I!0mڴEUU x 'Xx{CUmKTxB(..`0[!%Ӣu/[EGmLH$=1@]ҥK^[ dTa|8矿L(qp!ܖ(jR'猈|pC]G|ǘ,G 4=޹JJJhkköVDžeYӀ@ˉk׮e$02hX.^ȪUp3q8OT>_.ٙ,ETՔ!Dۉ^@4=m\˩*tvv1m| QT𔗻p+WRիSN===]"2rn/˜7gYɰ,)[^p8Lyy[?hO=:#eDzFݜ.yNUy>-[ٳg+wU>Sչ$uBSSG@4mr}}},_sUGU!.غu+-J²oO{2v͔)SRNmת@Acc#555IbΟ?ɓ'9 y+I&]L6gUi!"ǁ ^~< ,ҳm{yE;ոt@0MD!:֬Y"<{mK6_ZZJ{{kpc}  688x14oUUD~K9=>#<#<:/!3IENDB`Eqonomize-1.5.3/data/64/eqz-overtime-chart.png000066400000000000000000000042271416454732000210770ustar00rootroot00000000000000PNG  IHDR@@iqsBIT|d pHYsttfxtEXtSoftwarewww.inkscape.org<IDATxklSϱ'vK i5>4\0R \DYڢu֭\J˨26ƀAU5mQ%\@*YC ķlQx/{^ A $B-2s.ψo[#-/Gp1~cp?nl?on`I0 4 &!@kLzo8lEFI鯚/8lDtPH!6?B ~DDWN+d龮 }*++k5׏dyn_֏>!kH "'Ij%CmQ_ }"K7_=nrԔx v3}Z}}%˯1邁{\A f{x= NY~~ Q{3+7.$TS7iP ` $N=.Lο @">Tj.q^ Б"ZIJǀyiSό-6Ss@T L *vde }'}~|Biњe~-Vh̽\MnpjҀc%wDC]^W!h W,?k/l;]<BP;}?ۇ-^M[Nf74 A!N{=ţ+*I" &#6[^,J]E( ˠa"x2Z..[4 50hD/4`Iaխ"6@;L0A xujՆN_G%c!:B ᆪMU>U'簦&`&l2!kKCF}k#(~/5zs-ZHiJCMv5 sMADONHn4P)E;}7$QF51$SD0POrwn]uXr|+B XIћҪnx| 0DʒkkgJcR?cҌŭuMRR :b[6q/Ҫn&Oͪ)o 0)[;0<2XZT]V |IF<0 K~mUXHNl6gJfx Jeo:r* 0oJYoǽv_n7dMm6ۛ+8:pl[|~KZmY]ojĭ.N164y!9̷=9dzĥ6GVUV"fZq'SCHm*zɵ)7dm9+V Y?|#sť/)%'//dO V8.%; {<,%xް,] SӃzATĹag Qy;|2G#+ɸ$ ٫0lu0 HO! %;g وH`32n\|;g4hѨ$XItVŤ%xdrU3KtWt(_WA@xE s'>ubA70= : ]`ߙӘAPШE}M` 83 V K705 Yq# s'.^ك Kb":`|l=Hn pkƌ߼25aHnwLe?7{*"3%Ĥ wjD%s5kLfj+SCk0 z՞pus@IݙiS ! Jp"Iw,\q'?sRSCwZi B, …J89E7ߙl_$ qfS5[,hAU*A;P۷ocZq:FAדxoX1ldd&Z[[q8$IncXA$v$)x-P*KQ:::dllL*++x8:իWIOO'77Zv;F,JJJəHv]=CvVRRRe˗300@CCe˖ձ555XȎ0 nAisrl><̣d``T._LLL /r*222زe \tlVY]]=[uuuڊ(I ^wAAEILLJR577GƲe0L!\bjkk7 󆹟3_uv^v g)))>Ooy}Jbll?ѱҖe̎;7`ӦM߿? dYf𦙜|j( ,lrss\rQwIt&%p I)Ae9{1=m9}z1&""Y_pþzAv;. @ڊioozO?wy'()5 SwYY`b,˸-199Nj266}xf֭TTTpiJKKÒ( z&&&BgnY|Gw6Sp84FQ1ܾ};dkkk裏ذa_i$,(@3ܣ,PXX(iiiȲf c޽t::tWGq Bp$IA[(| \rټѯü닞$ T*].! V*8`jZ0300@zzzÍٻwoXDgg'<]=u1mܹs婪⭷/vǏ#"Vk_͛7R,/I(;''.Aׇ=Pvϱl^ٌfȑ#_h9@R Һ}z/}vf3uuu$$$P\\F )j:n,ӧ1 [dY~z6ݼ)h4KhZ.^?=>q]]]LM |YxvsU}]"""xihhrݿ=z ?ɿe4E蒓SN!I;w$;; _Ge3G,Q%??__TT$wAh4Crr2힮.,/9r$xg$Iڱ|謬,u||(0UUU1( (J$I QW.EQ7 i(wIENDB`Eqonomize-1.5.3/data/64/eqz-previous-month.png000066400000000000000000000024531416454732000211440ustar00rootroot00000000000000PNG  IHDR@@iqsBIT|d pHYs$$P$tEXtSoftwarewww.inkscape.org<IDATxKL\UߔX&j|%4R.;G>Bfa+@Ia0Wܰ1ZP[jh9g ܸp#@ w> ¹w&m;`ccccccccpBn~0Oj|ZZo\ߡr10FGG?;L)f>`|ddt0_|IJ L@<<@Y Rn̜ `,BF:]R;j!0pl ޲c!*5Sf`'&&cgggoYgO߫M߽{\]]e CGSIN3`|rr%o4\&0<0s2kkkLX~ ̇#χ}eBof~@xvv6yfRZf|WP-ڪ~X2f~hDt]1}`/VVV0K8 SO$<`bb]X[[3փR6S3?he۽x r;X(:;}}}ZZZ$bL@B0W`˒|-NbKZdFݳ{w.@ $@ $@"³BM׮]-I{BgL>=)##Cotfp(It}9998E/[[aNx5>|gժUpU r5! bknܸ1R!JKK U> {7%.͛"g1pԩ/S)M45 ʕ+,zoSJUUU/B^dX=888BH۔)Sx=tI{{;KF)͕eNܧ%D\744T[XX/^d㩩uttx9E)YUU%eJi>O 2oRJwVWW2ap|r… XCZjp{Rjرc,}tuu]. r/POEY3CkL﷔ҿlذA8z(KO<A æ pZSSDQO<@ bi4py>zb`V ޚÇYsA6Z$mF"4`iFmVu!vj_@ķ^o` yD=IՉ1hiiInmmeGp8UcF1 BHp>(|}*~ NJJƍfggp~('%I6Btԩ7 %%-RV(!.F p~&O̙sm۶mA! bN{Vxqr;K %8bplweYC)& e6BH CVRR*wdYRxmx!D34|X^^>]!iRiii*eYU'B`rr†ܹs8D'kƴBV{+IXu"yB}}=###|s 2Z-̆@`K!D+p tT<^?Ip:+++c?2YFv{))) 8J5k Ѷh]}ZZ-[@rrr hڎiWi&)dg^6A! bS4!|.0B$!-^!CRRRM:(6yt v?2Y*b'!dBD!իad$Xi8!$)؞9%gffihhZ@6I 'G'O3LNLJrҺͻc2…P0^;/HdCSc“y !nF1==V:@AI:E PPuzq_:YZZ:7h;  ={v5kB ;wn[/!RSSf̙3YM)qԺ¤IhD\Ǐ\'IJt<+++yQiF{pLVH:SI$q"ު$nyy%7H Hk%'w9IENDB`Eqonomize-1.5.3/data/64/eqz-refund-repayment.png000066400000000000000000000101261416454732000214260ustar00rootroot00000000000000PNG  IHDR@@iqsBIT|d pHYsttfxtEXtSoftwarewww.inkscape.org<IDATxypՕv۟v Y xo gc$NB`&CJ1 5I2)B@Bd 0ɤȾԄ8!@6%d[%Y_w{z%[FqUuV/s=6 y/>jK!9;Ux<ra kܭYx">Ti^DjxG٥, 5>.u@Mu(EK{r &ȦZ['S"ݤ:3UJ[' S" ۀ1XKOWcpw^ eE?=v0n?d]/Zyw8~1iRͻ79M}VEO|O"|? ~X4l\2Q{='yZayȿFQb(_N$|v h ew+DQъw0+xҵ: _PD$F IЫVEADCMV&~.zR:4E' }/#B@\8.X\?DQ6w7"='ёF>C䶢 "ߞ+o ѫ@h"?|d(6YL g5+/L %tV%nxzSQq("2_u.5jM>H_Dգ=.kbkQ*zsVP<4}jMMi%PcI@ؤㇹ֞fs겿x}Z:L*͠U"adu@~:쯫[2"uG9F^=СSWkt:|uc̣~&c~x@xrϘQMУ\Co:5&\Xt8~Ev|&>o457'EdXȠ+\97qoXkLXe_ʼn9{3E9/EqbHq~`UMd3j1GĔZH1 EKCs{kZdz`޼J47ջwZgqă-Yޚ*})+ֈhш6؅WF{Z'R@ oG1[\_ Zwk Ԓ%XHa~n\llrvИF.Zu "g_ϑ~ZHօU'dAM z" \3vf|֒d;}[H_#|lsd"FSsEF) m}qfPĭ;*^,p)j`BVkL ]ҲWcnȹ\Yw|hDW^E4Z$%up/;deÅjiY;G\5>p (gc㌒\q _pno͂ 7[Zf拗(+ښ/sfdC 3 z;GVU;?gDϥbIb* TE"G[B@0/@/& $Hmxmf'G6q|oV ^)P`5Õ Nf E*+L_G&?RI7*|3nHbD!-K&G:(ʕ0O0f.Մ8xp? .0@x.0q}h7Cz9JA(aXPXbtLNHglD  aՄB!zwJy_odݶ߃ ,@FDy. yshCWWx8}r1ѨP ˗H=K7"hk}͛X-[})'&8YxY36Kh [i73[Pml>H%]+h< 8= (GPa|2E%QBCX养0<\2!CNa:~Wxrv>y9k++|?m)(C%6]3$=d3=Ӕ¾9,o^rM8h/pQQC >_:O>gJ!L}#m;Vç $onys;TD_J;x"nk}i}zN(N缧2bZQi>]_}z{+.B< $\`rr111@ @(Bhh4z|>2'o]7oϖͳBO?=Grd2dgg;w.~_wz| ݎngΜ9( 444ȋ/J)eU޽{j-i&_fstAA1//EQhll˗/ygUUIMM%++>@m۾ngy&IJG`yffRRR3gP[[?qFEEaX0 TU@4 CCC|>6rssȑ#ZKKZ^(//_(bbblk֬1̛7ӧOSYYI0TU%66st:Qٌfd2a6u~?`)%###tttF__"JKKIMM9r$ TU}: xRJ---MZJ|>+zzztBjj*XV222'..EQnxr ph˥j*FFF/^"ŋ)--&^Ig@EEE)%"YXff&^ )..U禋Ѳ:>>SNEaa!@@\ZTTVuutyi8pZZUUUH)B`-ZDLL8z 6 /Lp\$&&DJgRTTFUU7L6nYBEEEv0gl6999K޽w}xmZPX~=>u&,M& H)7 3==?ٿ?gϞeʕ444̦ӂljh"pdggĶ}1yt46617--r!l6V׎2xv{Hĵ(//SSSikkcx8f$$$1e%ȗ_~Ɋ+x衇صk׭4#L&Νܹshmm%jܴi8'_( @[[I?̙CzzZٳ_|r^xq@AA?(+?)NX,zm0 z! vf`wH< !D(+{^H)Tkyݴ1<}^5] WшjRܱc @餿_v[2h|ׄB!V\ɉ'W_?$!veaB,+ŧzj`_-?Gb*j'0z~򓟰f4cϞ=3Zk  0M&1w\\cikk;^BDVѱO#** 9Rp=~odhhbFp8w`ݺu455QUUɓ'BӟtFeX SUsqt\nBX& `\;H`kK#~͍6v{%>>7|S'6%%7xGR[[;m]zcE4.4SUUC'@4DRʱB}1Ѵ7Q__O^^ބ… 1 ??ζgc(4G?]eDָP(@jJh4rGڴEvv6uuu BIk!~^"1ȌB53cf޽zŦSiڠ(BqhWxNw c8fљ.}Q~_csN, nSZZ… V2jRDEXn=JK">8E& 38rCCC|'PXXHaa!;wN+瀢tNp`0p X,Ѧg7o///z ,^/3sRtuu\7%p}MN F#]]nGBqY׻jքZ}a} ?ӣ. )%)qc/ǻpxxp8>3%gSݻl{:|}7=SN,Yw}7 z">>2)OZ:;;pF3F?oxbO`@Ӵ߰WUUu8gThnnfdd.33)d.4 Paߴ\^{5uLOOgʕ|455 );v8p#S֞QQQgx<[Nﵝ>}>ng3f/^WYf uuu>}:}7e[رc}Bvݖ 5??VFFFx<9s DvLh{>bTvZn7 _{ +-[<=gsO>dOH)BA٬+NILL ɄiB!x AA$W90~:N)FJ}5"S)A-$H2p(_nٲ}lNų> 9&jfB!RA) |v.rE@$ϻIENDB`Eqonomize-1.5.3/data/64/eqz-security.png000066400000000000000000000051241416454732000200120ustar00rootroot00000000000000PNG  IHDR@@iqsBIT|d pHYsttfxtEXtSoftwarewww.inkscape.org<tEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/ IDATx]HT:3~LhN3'RL.Njx%N^H7RvcJAptuӁ"(讋  % i1ь2Ӛ4?0}.dO{f}9?Shb!11VGK!'^TTPjDZ)bz[D ANF>\ZJND )<- 5iJ `~~>@fbbO>@rr2ׄlٲ%>! DywǏܼywޅ顶r=fhn䕮}>ׯ_gllLφ X^^իWr],KHcVh-KfllIMM 99={0??ׯyk׮ { ) 5>''߿@MM v=Dj222BZZ۶mmG "ń߿377ǏG'&&d0>>rssW=+{%~c޿ 6mb1OW=nxnnxiJ233CF0@n.fN< ݬYn۷o/.ytĥs^0@RRŸn֭[dʔ 7  6,.\`vvXϟ@qqq9ZlPڊ!&IOO'11|>%Fq͇`ǎV+---SNH~~~X=NUeH `ii 4 HWm H!fwz``3gpfQA JϤVzN'<~FRRRe]BFR*p8TWWFOOL^/nχfc֭ uJ ;weV BqwGII ?fddϟ?c0l޽*Uu+r6FDVVx<Fc@PTZRݻǁ(,,Y<  W_Lf`` _GRw 2AG^^ݣ۷<|>055@{{;R]]rz7IfqqQ󒙙l[n!VbFGGevv>ijj"DW$ 8P{'_߾}f._LSSի"7n`nn.$] FS@jjA2pÁc۷/Ddȑ#yE__UUU^祿%QNKK `S@oj1@*SPP.+DNZf[,..xT夰X,vN'gϞeΝ3336dddVBK1==mZ ))>N'NV(..&'''niiiD (X 5Eq8133p`hjj z#1)B+ n/r16mƍ_gq?3\烱n:*++iiin#O<\_ QlvVVEEE9r n" b`_zkx<477op\$%%`ͳnDU=:!f ^&$$/^ĉ ׯ3ٳgʫ5,td\taΝ;޽{Y$r0L2Nmm-.?2::JWWvm۶QRR͛zs_D\:`jj*<@|ZTTDjj*]]]߿ f*F\`ZUs-ABB~RK +41@0:Vj/m.qz0۹\5 mM!KliF7W~kY|mKw<Xa㺇f[qJдk+[6!xtGĿ< PEV?0{m>|SD2UW]›oeg2}tJPU7A8n3TF7zwxQϣfd=1 s{yg;A!๲-z7~aSTXb bH&r]TUV0kSIR*ƍʶQͯM: ,Ow/_Z6uF{;Cbqh\chYc@Zںuknj3\9s&7ȯ?W==ہ[R:gϵ1eb%Da8N/^K_b&iB&cW-@䖥;KVq(s_aD$HuxqscN(܈83c &_Li'ȵi{(*vݹݔVqKh=/Xp-j{|Cy *=O`DJ8.ٮYdڷPV=q8|ly(歹~=_[~闪Jc,e5X*\CDcU8G`{#ԌĈE8c=1EPbR(BD(1iGذ 'Jp)VN>V0q19@ii K,Q;ҏ{[^m 7#ݑeUFcc6/}W;N9M"BJ葙 %ɄmDQUSJ.A@HI(Z^Wr}E6\+32wן6gO>kD6ӌ?rb'ѠQCbz7.~b$b}AC^=W/*A`-"F9jNѣ.u0=złOE{|D, YEmmP\/El%31C5b[ۋwrf;3S|G Vs={>޻0 l۶ k˼@YChmy{'J&`VlTĔ+'# V#]JJo=`<\a9R#yk{G!":L4k[9Lk/迿N;wl('c/_} k qpx8qpbu4zv-w˳'VZe̸+H&L#F#tl9:'@**5J(ֆSg;"y-% ATD)MT(]/`6Cu4ONvuD6 xTְqkt$/hhkGU}pxL6U/)?|بFD (%8^)5 Fqل ōFmucEseo[O%ͱ,b1J,"Fɖ2s- << Nd/)r,)KcDNWYbZ^B;q DfoUQDLw@عw3'\Y`UWEluEg@0 Q%Ja $/$Ӻk#TvN{GⱾ@|"1zLp8|".hgqjACJK8ؠAqFqA( b!zoozgaDP-D?^_2tumJ4'tk>3dàt.h(J'xID,{*]} Z144KW^a}Xqj>Kt "J}|#DU9#^,VƌLY6q+GT\ o\כ"FQu^#Na;YBS>w ;4e -Z㧿X=5A'IUT3fE$KP5tvu2n@p'J}ѽ_L{gm #oGw,^Psb}t<d}uuu߿$mHw| hq%j% g∬ olg̚3ZUջNwgj(:l20> 8,N8~#3fP3i7Uظd]lYn˖-zc:#z-vY;ke0_hIENDB`Eqonomize-1.5.3/data/64/eqz-tag.png000066400000000000000000000107601416454732000167200ustar00rootroot00000000000000PNG  IHDR@@iqsBIT|d pHYs99ـtEXtSoftwarewww.inkscape.org<mIDATx͛{tU՝ǿ}}!@"ޛ hx*`BPcuN5˱tuGC+Xk;3 -X@"VbR€&qy~9so$!`Z p{g͟?Bf^YPjYr&yfǎxޙ4BGte*=S?+yieZj @]]]xW3"(l[;gq+cpeJKKZvqa4 A$8Ζ^Y!=G>k0TDl ai~_eL| N `8ۊVmئm7+"DaAH@6jwSɠvDDFYO. a(U"!'8.K(q,GƍvF1cxlg qc5\qY4r*MSaKZ6t81L7,,Θ>cDHm89u Rlc;}]Fֈrۦjhh͋^rR+RFO/4L~X)[]{MӬ47ovDJtR5{"&Km9%v^H%Xe}<˛w])gQ薦Lᘺ)ш7/.,`G)O Al+ŶBX6uXۨ. L&4-ѧ]Fygzj :::>_߼ݹs̈*.g@!&ܿB? Lf!au]NEN4]x<[QQNgg'gԆUǝo677o?Ս;Ο\֩fx@ &L+.0)0z}<}*w]"z[U{ѡȪjۆ,y'҂)^LS^J^?"H߱$7_ H$,/}ıu7\kdYqq䣆/͞=;4w[Lg\t:5HBⱁP0v>.tN8?2 d-3. GtJHP.I)B. ! (;wqlOE'>F TUjZ(DӬ Dt_]]ݔS8t_TY7+ڷd ?ˁ $ٱ"D,8wٻV.ػ(/-L>8kzm6M f1R/V,YD=}k 7o* +rMu^6, f0{YY92?)?{}ٜtǍߖ:Cw*ߓH$VTTdjhho-ŊUG/ѿÊW֟ҢlR"2!!*tDdʤ[?+Aq܂/HB<&Ύ!ʑHlQKU=GHlEb(XY6{Ӗ+, D?鮖u 0Jn^\ωe{9,cFipnV^Ȑ$"WN=wDyB vpUQ[@"Ǿol][/o@M#R#:pX۾˸~RuOI[1ZM@Qmq %/17艸 aӟ,^X R,qf|?+dr\H'iϿ{*,!*(D}$Q?ߍJ@SUQ +safpJJJ^=f*gE~-LnF`ws>*47= #Qo.t|50R_!/0ķjAc&朰Y ByZo Xنjęq:LK]s5fku]cnE$3R}@$% |{V9FNk ͓F=~@ 83bɻwApe@R~|a|F(/Sq Jg˸.YPJ@mx䊠Tg.7\C^`Ͼ0jf~&÷DJ0DqJ(126l(P@?9Z fgV~0|Qg B{re_fɀ; Πζs5{﮶Cۢĉ {>s.4tvßWk&$JiXdI؊kX rvlݍVgyw#U}Y+..}IӣvGKjzmX촧w9,:OJ~驔ަA\H$ě#  2E o*rgǞyzڑ#Gҟkz~.#1碈~X s~ÞmX8_Wm<0Jv< ^Iō]d_h-u䏑xV #gb;::!!-peQ}|`@m3wR8-[) vAdCyA,պ0" lلe?*3w[[[~ WXP#a56/4.7M_D~t:9M|={6kK 5R>E0J+AJfy7'!?xqr۩/@X0{zD͘]=ֽDHs@/ :NJ\aX03A/.Մg D~ZLXDh Fat/HP* ۶ٕԏ:xD 9A L06ŋ:ƁWOٽ7t@J /casӦ-_uzC1Ax唖Cy WӮ (s9߭IXk O `01jj73x<+M%?fL5l?[Y?w E^ !ȝI E{B u8oPk[㫻eB&}mUQ ċ J /o",XdՃ DB$ju?'lu8U5D2icx/d2#Gx"k_jwuA "!kZ2dq-[>W0q4|*d`A/^@ @ [' 3A4`(dk:ӢK$p/)LڰW(+ct+~AkH$+ʱd]u~r }ضx"y} .hlR{}WQP†I'%WEC0Z E K2W_NGPQ,'lkkk)&mўTqJz8#I vkBJ`yX !8kqlA|Ncl[RS*u"ի6]^$QŽ9mZzy&34&,X֌5=e (:?V':TyG흢tKKa$fӦZ*F["UJO 9?~ ?<ס e{%-щbׯ_ i[\/"<96@>oS1*uhi%ٸUZKmB6.nnnWWWWH$_~!~ZSSS(tCwȿewGD8V)@>q'[n=p&gkKJFRzt[s/ #:t+n?_{vnlmm5}z(:ﭷ͚3C"PBNK MKN C rkgaք93uFP=+>%Ջ*6DS?ؓ:7kxk}KL,Z_v 5=)q Nml.D\9ۋ8a^vr% |q  s%8ж`(ȑ4zzeQ |F (,G(IENDB`Eqonomize-1.5.3/data/64/eqz-transactions.png000066400000000000000000000034511416454732000206540ustar00rootroot00000000000000PNG  IHDR@@iqsBIT|d pHYsttfxtEXtSoftwarewww.inkscape.org<tEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/IDATx]hUdwmATZ,-i" VڇbED--REh'-jAE-bV[*Vb[S櫻^v73ْ}sϜ9sǹg䰰;Zk$+(pzf n^ g?ASRO}k3a:G02צI/ c0O IR@뽀ޖzt֛P#*B4>T6@A"@Ea^ zET?CrsrG#g_  >]Q<@:?C: U`|7l)u566Kti靨,e07a 0K ) ;ȿQk֬n5HdHs^TJ]n%&'2 1tvN0vVnc#4QZ$W+ek׭]<>q0 HG& $gYNs\@JW{w^q;v >s;v%Qcv\& iHc m ""MTzC6no$1|Jٗt_Z \ /Ti~.[aU< !\68eC`.e@lL,^;)E `@ ciœᆀe4 5F.~=qam*%}N/bc cKXEDJ8qAWJ9g(ٸqݓYU MaIiRL[*@ueYb1t:=1pu8f=-PضݗH$R0Z]Fryr`ا%جx.\'˖T(,2VHsu[H7-j}?ulH%B̘s9t *@;@$ǡT B@$!IB {~&HAD\'"$B) ·BAI)md>q 'iޟ="@(RU Q~hj:TPKy4%NtF;0sh *_H&zF|ĉCNlw}K)PD\K\*SQZA)O'Z ic #M4is?P:%mYuֹ !ޫ]&bD&U RU}wk6^iWc+{' K.c! ,MJ)m.M]QV: N7><WRo.?obtXI)pI M))JkF 0<}lzI.lY%Ś,B !d]Ir.wcKt Y7C=KgZS;@,d"bDQTW+Fx8~. /W~pĂߚ%(STXH$]|Ce_hLuCkJ@C͓ 45  YB'" eeނ`bt՗GaeDd[&SM{x+'C4@32=,4 O 7ۈً"\0M1E8N[D4bwӧK=9Dxi!Vă/ZT*:+;]7VJAeGtG"V` $ LjnfON5Tߑ(FhFvfZܩѫc Z:k *ˌٓF)uR $"&Qܩ1spT8g˔R!Qcp-dn 6fR^`@L$H#ƚ}ڏ"Z;zxWq ]lK簫?JAvkੁ&c&@b:@(&M`G`XCPEy#D92ܰ E#CpCHML];띴$>J>YE@H8PjAɇ=* scF%zյhSڻw{C?yZw*`JY҂ !˜EGMkG3<|Rnqz B+JSA"V~_]%-;5x>n̪kBAӚ>~X`!ڼqEldNWCTbͩʎ ثY;M0"z%;Cz׍Q@G[(U/=5ظbźK7W rفCijcbnwjgU[ЄcƎbf|ȫ5@d4B" !=d'w_]y"ϯ2aCI#Hoݿ+G*G5[IH$0Cz%RJR- z&yr߀󁪪 v;S*Jꑎ}̖^r"#bթ ,dV y9T_ǐ100L$yv&M6N]F|IZ{{׹+RZ!X ±K$6f0VWݧ'}npdٿ¥egkBPNL2vt:M&M.ɶ=ۄ.Vw޶-rYM3ң̿#UB(++e)TTLd9)RfH]rم)pd/,;B)BѾ;݊e vTkH%Q?vt}hR4 >ё ,_~!ӧWRT4p8F  Dtq 4/X|V/'A2Hm8seW 4MƵ{w=@yKw%O@8{8oLG{@-bL$Y;E[Am҃ihyBs{yș3P"Nt6SegGd B!M` |TG_۹{7÷wv \_p]WN,K?z)`wHle^--)"J <t-_Vtvh vX>L_4T\='z79"g=QQUUaV7w3fF)M8PGH%1t̙Ȗ-5G P;W?Z;3 tXKg{t߻/^:CiY),^@ nN6։K "ƍ+'`Y @/M8&!ؿ%)5#6ڟ MnہDޓqWS /@)N5sOǑhEl#դZ^uvכ(b"=oy|q|0#ܪMm K )&k}@6czECS;N索d샸](?%q`Nz]>Ut0!\u|ϧ9纚8"#VN3@) `$= 2Du:|)JLjF]Ќ(Yjذ1GRE?yɰQ oYM\ΥX_Mk'_H+ C}F {8& Td2?Q6}Gӭ֐C0ܾCRO'aXKhhhduV5nDfDЌXo{!tt4#7=Vx0O7e,+4DiSYh1\-0h 򡸛'!lՎv|rnj p^UT ($F^|{;/,ɜ3x4! D>RPdz>C{[33 'x_h@~V$ڑ; 0}5Iqƌ0 Mq,٬M[{IlٍPfNp6" }ڴE!hHBHo6(`N8CK~)p&~$@Fi4Zp)%P(B 4-P>%kw{q\[g'H~DOW+ouyR2Sxw=@-s~z A.[ ~dYYY_24TH h(*e-ۖOJ&c ( _$sʮNzyb'2&3p)GIENDB`Eqonomize-1.5.3/data/application-x-eqonomize.ico000066400000000000000000001264231416454732000216650ustar00rootroot00000000000000 (h h&  v  00'00 %n6 P\( ^AzpgZSil11澤l x. x0 x~0 xN xN.S9{Nn}N,̝Na}N.f}N̙,ʪ(   *4GGG%(KP,%UUUPS_fOJg@4bbbn(RKJAYOhau}|z ~xsjܔfyqxhhhhggffeellҟyӣ~ԣrrק''**ǯ((,,..&&ee,,빗޺::ĝ뽛,,00Ǥ,,ɫîNN::ȴ̹ɷ˺ͷ½ffкнӽddJ{_>8i CDE1r==79!R"sCDEIJLJ%YrLO, 3"lRUq c]UXVg;1I:d&{\[}iB3^_d!{|"`bfl!B; cbH<o'r*P@cj&WMkkzknkkw0kiw3((4+zE|DrqZRrqd^ր?69wx}x|uv?Brp|xHBj\~~{KNkcSVseyr[\0(cc#)wrbsoomtz}q$x䩁}})#⭊ꯇ#.*굊(#괒 22,)?1%켗컞(%¤BGǜ-.þOIXTǪǯɭǴӧc`XUͱ͵͹nlVTowѾԸlk__xvpehhqqwwŀR ' &%%O)';tD';ttO-)'*tLBB$+tβOWk*CSk}'1//(8ȳr{|ДF::/(@꧹{zzguwy:.>֦??( @ {{{8xxx8xxx8xxx8xxx8~}-(ccd R }|{qxxx8xwB7%bbc((55++++!!yyy8tr6+/'aab!!22++++!!{{{8sqG;D"-(%/ppmm008bdEJyzssuubb228~km}}nnYY**88888Ҽкƫʴҽ͸ȯ鲑켝˪껗䬈Fr.n(j"fb_[ x68κw먇ӺDZ̴깞꼜Ȫ鵌㭌|Aw6s0p*l&hea|>8ȭѼҽ̲쬇쵕뮈꫁컞e~y紏䪂䭇z?o*k$gd_\ Xu26?(0`J ;+;$&V$#3)) +j$**(7,+45K-28!"&y-. 56;D69#77A+1]9;p;=19~;CKCB2)4-aIEUOLNpJM%MPN, 3"[FXbD[GC>@`?=b=oUXOQUZM]o[[:0[^\e%A2W`j`\SLn%n7H@`ht-okn^Ygfnqox6ibzEZPjrowvywa`aUpl~|uq}vld|z؋`ujْ[2+ĉ{sܔqٙl{73nޗ斘%w ߠ|64檆)!䮁A<,($.鵉鱘곑)$21BE縒#PO,* 1긞68>B)$_Z齥CIF=-.ekNLnjĤ:?ũžȶZWǰxxɱFN˳ΫefβͺμomVTwxbaٻonxxƷ_X謨wXrXƹƨ p wX5%""""" Xs5%%"" `~{oX'("""""" `~{so5?%%"" `x{sx_??'"""""" VxsoII5%""" `xxrXTT?%%%"" \o{oiii[,P-YcI'%%"%"% Vxso,_-chY('%%"%% `x{x.L)56656+yyyi1)=3&!"('5HH33++++++,,!!úwwwi'8.'!  *)6BB<<++++++++!!Ž777 i2'1)" ))6<<77,,++++++!!Ǿxxxi<2@9&))65500,,++++++ xxxi$J?NG/(!))6//..11++++++ ;;; i.%WM]U;3$ ))6))3377,,++++!!ȷ]]]i7/eZldI@&# "))6));;??--++++((::997733F[F}}};i@9rhzs[R* &#!!"%))600BBHH..++++++******&&A^Axxx8iIB~tph1&* '%$%()(666IIQQ//++++++++++++''A^Axxx8iRK8-.#+") ( ) +!))6<b>xxx8i||T$%afjqOX1=*6 / 0HS001tthhRR@b@xxx8ilqqL.0x,1&,NUnZ\zznnaaNNDbDxxx8iUYoussggZZGGCaCxxx8i1&(||oobbUUAAaaxxx8iOROPSPPRPOQOOOONONNNNNMNNLNMKMKIKxxx8ixxx8ixxx8ixxx8ixxx8iҿоϽϼͺ͹˷ʵȲxxx8iæȱﳐ˰ǰzĭ챇겔qƩ괕f븖櫊굋y鴏ū絗귍軛⨃x9s/p+m(k$i fca_\ UՔaxxx8iŧлũ¥˼ͰƭǸغ鲕غ豏ٌ[㯔ޛo{=x6u2r/p+n(k%i fdb[ ֗gxxx8iŧǮﺥɳxΪƯշݕnm蹝ޟ}ڎ[z K#΃8$v8ɏ+6I8s8q/8ܶlKI+ !J{]?szfgfggKLuuUuO}oU jw󝗤ף4k4&XZe},w}IzZ;R^sZk\kqLkD `ܹ\rI"FVy% 2HR O<;wL\T 1s4"E:ZƑ"EqH12)&0Fr(џ,@X2!~d=jj2X~O]Cޯԗ`j{Ș֋C~i?xafM}3nIޓ gs<~f轗ÜS7Wф#~dN ː˖HY~@;vՕW^[_ iL.qǎ~L5?Cu oŌ/|Nq7x|ᅳȄ'>9u&@)Hb#e)RL` X-Y{QnC_[̀`,NɰpI:%~=lQ`p؝vX(Ǚ2tRѤx۞gP>}v.f ɎrOo@p xLޫ?6?@.V,bs'kL@`rXxn0wgMR& C7|7c8<m[ۻ#|Yε]ħOOCgbs3+W{2|)FDƲe]\@7ƌ3fd8oq[7 ȫ%Bt u:}rsf3;%LulkA N;;mhgI+eWL=ge򍧣Cg.E^x(P.uT9I.o⦲Dh!Q0MP#M%%?u.~S+f * ]cL%}\zd=r;"s%Sy﬏f߻ 38,WLn:::9g5@sȾX:I|]XgWkFJ-q0ߥ~ɫ#lе˒Qct9NqM2vצּҧwrqfw3Ru.PƳfq~N.{eGcff7hزz~Ѩ~˻&2~]֬Nl;K# 7Sw, %z u^t_拼B;;VEsOئ8nW Ƣys ]luj:KgB~Hm{ZY%; POb?<Ǟ}߲;{$8e|">1}RyPy3ޣ S*Sb !Su䚫.@598VdO)0 .` ;oCf4}r'E}dYbg\3R $rKxG 2S_;k#!S @ e}2СĬ͂VJɰB}ٜ@]J;F^{vv:r̲1wG=ɬVqI`#ɀBcɳծdI8ˑYen>Wi}|'VdY1qm+n0Ps̞7yy ۊ=,W_Ŵ 7/'OJFWXf;X:OəFT?¶ Fdm'{Z̑yl:E1aW^L !_li/-`RXHFvA'OVM[iP~?C|˫?_pCZJ=NIo6:!ֽ̅B,2{ I!Xx\>qV%ґ> %f, 1?ڕ49x:|u VmJ>6`b&GvfW :GOą${6:]͢(:3K(Or}όI#dsn|Ƃ~gmK-{CҖSgWvfda{ru +h,@h9':2=[у5KekdrjNiavr9. ;,\cێF< #8<}JDL+Eqـt1 7z<^ mV7+as"11eF$ ^>~? @]W^B[5rv7tNr=|d$;LHfq<{v?|/K8=c{+8l>]6+"SOQBmGM\aC@t^Hrs)Bbi51*zYNq..;:wb1D0}NJ&7ع(ЙLᆳr0M/ܯNN|G%ku9;J?/E{P*cGokJ)X|7Vp,96:h3VBϖ#ơSLԼ"??iƵ^n[evLβ.7֕(,5MwN6tWd}Ռ/b~^0y3:~#U?)הB?N*TKRm}V}I6[=YZϤh>70%D6FJ<էè_uZe"Gm}:R"Zy"E㝁R-1&riBD-*#e4۽F1zJhw(9>iC€ihMӬR `1֓ lSfHg/ARHLfHHaODǨ@ /R⩭JCl Ri>b4}6` HgٌqE%;D>;kV;H@ 'Xg3Rhپ};BY[+ӧ3gΜp9H#d)J}kZRJַcǎQ9^GG}ۍ s Bo[nv0 G-{k֬cҥM`ʔ)}وpӖD˜p=P~ݏ$pû~GeRʦ9&@hIˊ+WyYg{쒘FgDVUވqDoh-!5f&M}C1ɤh'PsE bڵU+[բҿ0&e]ƒ%K׿Υ^Jooohz^ #FvҶƐzBMI^H@,GQFq5\CGG6mbʕ{ ӵoZ^_eضm??>m+RТTaf'8qM73oU @""+iQ%k Ьwl"$t]G@'1}I&yfVX~͔&+ $TN$"λqT*)-&@P5MM]tgq300G>ġjLL9Z/MZCzN*M,@C5Ȟé'wB/7zlo *)*5*k `+aBB]Lf&˝wIOO7ofժUQJP}01+p=Q?CVvʍ:4\C $,R{{nvݻ9v'N0 9oWtfs9}2-[G>O???ՕxlaZ ڵkYfo׮]UB)E6@&^ 4 NV/LWqo /pDI!ehMLttOD EI +bTjQV2NlCJO=?0?8۶mU|M[ uB frW{83͆ x̗e>$~07N:z2H - }ETjQO~3я3xLUmGwv-R>F߽ZICjiOoǑtt)=1t_ \2444|hJ@u˜&MbYO€kIqUrAOb;׆~/88{כ&^L_tMٳ-fe2Lv%] ÒF̌떔W~ %C&aU-h|Å?h5ٳgSN9 6~*&Oya>j AN=g,?iH3F#[Yw1R/};3b:wj鞴n9̚Q*Y*>RbiJtLRM!09rDgRQB|XIAa Q(G&g) >Z^ a|Srs7>|gZ.d ;r?#la d4'QRJyՉR'Np-ef}E ߆KYaBӴw][݇'$9dR,~B@tD@/Cû%_8Dx(tlBd윃Z$ϑ8F6=yW^yeh|իW{v|?qRZԋZG$)!}5Ζ ZGBpAz֮]-8r}2gi ]]* 4]I8lu=MD?<g9xYw6HGG u?g>q)D6pBVX>9dJY=aڒLS. )kFIRoRݻزe]"?wBd K1 0JҕRWyàT;x}coH<]!͢' R+f@OgK.GWi˗/\S ⥿+(kQG$rܭ(xWص˒ʚʲ7a,Jʱ& d(}Ǐ|gGGOf̝;iӦ1e&Oz{ {_X ϾrtS꫙={vjCws=a!FY>?8@0¤xUm޽{t|ŋN$==TR[b&b ~6~ 08'O.c,Y%KpꩧieKxbPꩧrJ:::"8{B :D(Žl+,9HҟVhM>A\yE#,ݢLҒK}>0yu}Ďaw]x|\:_|1˖-ϟ%.uaW7IsxYo @T⦛n_ 1)+WfH tæ^5-Q*}ӎ IDAT#^~ڴi\s5\22& Bzzz1c===ɬJ}v,SLUW]̙3)j|]MJW [Iaiv.?O 3 <`ݍ7SpYrrNJ0 / ebE{ox/!M$fΜ;N7diK]]]̝;y1k,MF&Sy<k_Ɩ]epd{mΜ9|g-Z+Vf0@w$4PEx3@]x aB3|w_{_ޔ!Ay=aɓ,rɉ;x?ʾ}/wvv򶷽-.aMӧssi1mڴ.4c?a$Υ^9SPxÀQH|-j}(BQZs;6߃&;^1aC'>~puytuYL@$ӖZ~x t_lr SN%Kpg2}tI$ٺ/{ȫeժUm9*Y<>Szpy兵-WE>/y|O(LXO}ʍO:E/ҙ:U]:/ah"AɎOs#moxGT'ɓ9sYxq@Z˒ϟG?QN9ȶ?'opJS%+J)ubt<$aGe0{3fh̛gEXȈd۶'ioͧ?iN?Ⱦ:::89sC}]jzM7q7r뺮s%T'ӳ1o]@[6`{=@0 a1-r 7\}w`…Y'2>q_ ޱUǪ2ZA6l[PV4P,7 ヒL6I'io70Mx㍗/˗sE5LBd2X_p!+W !? @_yl^zx|]rWNj1a>JN7Dg{EX$6V=[1Mki%KkC۾K9/_l;W16Vڵh+?ĤIG[vaaG5ׄ.9Ӹ+XziQۂ;גH\_=ϙ0%FBwfm1s)L,o_#c-9i$VZjc%էz2Pa6H&r'9Hu)Ϛφ NGk DW~I]LkB p[ꫯ]ʻj*77 :f"|@]/L jQh%^Խ~;>Nkk< 1aO%ϯL:uKz?(N$l eQI{1dv'Ѷ _'7A0W\w@Zok0Y1 [+m'!2 o}kW^y*"q{CUGa/d먚A&m?@RTC+IꅭC*eC~Q>cIFȍzuwme<3^bGr_җF;4ZW\e]VÀR>@x/C}1V(b ac,Cwwcw+஻0hb_?~߽^ALV$=lkg4GUW#ٽ Kdm!GͣD=R g:\_ð2L0 /캔Ժ /7 0e"ESH(o 94 &GѐAUUW1}ڂ\3mub>ҪaV/jKEТ KhҺ20-8#?a =7#JIQ} !aV2a_4qi52 l a@###Y^uMbsjx JM*{,1([> rQ:Ze)Jﰋfl=Xk >L"4Ͽi&~0k,n6tT{qxؑ`2$ʣL (&@(Li&e?JY2"\z0*k "kԼ#Dn һ矚+p6ښLa\3ؕkLۮQauD%_Ad917:;COǥUO fqA,栢Ne0D0 P]Zhvb+&BPM%}+% T\f L0Su.$kQc{sπGuR3B*]}~ pQ]'FCV\NbTKL1 8Um; BU7_zm|V Aq*tTCNc"###rOҷ[I @lUZkGih ?hW '"AJ ̘ 0AL0&ϻAS1"[[,tQHhva»ێP. @.0MFFFfr9jCg /]5P<& -F:'L6o`}#4%|g*6儅5`X i1ASbbi.3F+5¤Xyxn30bR@|)a16J@w)eđ`vH U=(iyZ &@C@`3(M=>+P^FkTWj/apĊ;á0<ކۖ?2Gw A'#1?3p6^N$]F,kD߾ z| s59u_D "y[جdc d9Q}2:Җ[_5/öa$#VYd~h;C2R?  ZAApeĪͲ۟j5{J@T(Sj{oߕRB6BoœУU|"eLzq <ɉu"3ǵ)\W0l& P"ږXx7 2BxiebWOO!_d >_~AP&z{RhcY!OB}mvQRK Q/mrcD? 1 `y L7`,MTwђȵ@db{~fğCq@~8x€vaۂ a,4HX `:mWR-laWR> ;UF$%5E eP>,G5@kIWO0F00 jD )>$~a+=~u#{:pĊ ҷ)&PZ5S+J@c!H@6 uR~Gm!!$UR# =)DH*GkԪu[W/pVF J -J۹ğ?U&f:50HZ9 (ɣK'[C7mW%v| (P @zW5"E}8V=rpTOerp0hX p!A|U&PUjPߑAHJ<1 Ύ?A'N]yGįe@ܷq_L*k}8 Fh[ Yh0uM\/{N#v?i2o =گ2&X.k0φs D$%!$ڇKmLð@dM.*GCoFbz `#1lޕrjb")(ɒxz;RyԵl C3iJsޑ5G+t%K}6E ޿ eC`GK_j0݁#Z5 1tf2#@&.!tKQfk4z'Gyj@ukpρ~O1S?6fa6믕 \3qz5A#'@9y &$^'hg>[ [ 8;4X> rg@n@3F,G퇠P-+BSv d R6BUKg_I Veh "tMqZ!bGؔj8ez}~?*/&1`̣cXuF6^OuL`mM$Vkke~e DAg~Q \(;ڀTC͝G pÃB%J&"&& aA'(2_nT*12bf:'N(sb fdk{e'Жߵ%hOe~#|S~hRrW2Boc(9P$%zwP0 yk'#]!ɤ slT ^#@gE'Gj!ȁ۳1,}m|vҡ %Jя]VP-Ru?mL >[IDATgoWwl~Q^D44;?A 4cpʜ9nя*S@uH6Y sqzBIį'ږXc MtDDY$ a 2{L5>? 8՛/447S#'o)BD-rՑ)E )%d2 ~_hDE$jm7Ŕ?iU8~R FY2sF28H_rOp̱Mr@CJc>ޯ x?F w*}Fl瞪hv#=!}q @JIWWfͪk׮eڵH)ߚe `KL]XI>^8 дBM@ohWR M5jWs)T$̀~k׮塇r{O@Pj1\{6tp Xj0dk3J"L'08įJo. E4 Rjhc @14J) kٯӅ$$(n?h(u( Jzoo5' 6C0`U%'D1LJOvmU?5ÀsO#ȲV L)҅MBx4¿Ԇ{?*?0gtA] t3_Ү'zI@je NQ'z̹)U @Z]+/ LG ,A RyA*#}{^.2E5le@ De viFWRFJqZ $~h0,&&ʒ]s|吠‚ xi(e>3#8a@1lS@WC 58'`RM`<0z?`F(Ra΢ @aB%|Ũ@& xwE8j*H߀"jȌDNy3 Z!ԭzu=m[P>&|!vi1Da!I>,WпMOz{>7+S@IH#T)$qJܭGhC;3' h ,b3-D_cT_7_h- 4-Uqj5 %4u}%n'8 Kk(|DOpVB|a>OO@Oj;N>) 4 i3&@}Bڙ8?D Wŷh'df@23J]Q%WGL&* j")'oD2Jfw=k֬n(C4&ri3Of9 =꿏KEahh# ۦ 4 3&wJOz:6 (tݶ% )h ۈIC4(@zBGڇJa0⏑QuLGsϚ5kxG\F&M&vSwQҰoD fJZÀ0#0n @Uv%[vڦ?3DY2Ca)Da}&ԫx7G{8]oaL0:ĭTƚ+nݺ?4 B׭=RBԷ5)3 : H~{<"VP[3y)m*pk裏"$oK}5a'hN 2( #D{ U_08lSp~w0T#+u(H~\.;i5%GH{Pg`a %1>ȏ!f@L$u g:Y$ZG_̣e*h[n>j54u\/ @;JaE Tlޒq=i(gk0 Hw@>woEݺuiNk \XqP-|DFI4PwQ`ZG_{Es%&|.#LZrm<@k?5}Lak6 LAJ_Rf0C>)_C:YYIlJnV`W^i96f#r8)[Z$z"('&?$_c>ƠBpXWhi\L`4qjio-I @8a@|QHԭjT֐Y)l/]psWR}5 <B .Z񘵪^W^y'x\.wQB2' ȔئHu*}NQ]a7@J _ pVzl44NSTg ca?o'S/pwsH`Uj Q)_s[]Ec0B0Óc_F'W-T׷&~:,gA y/OBQ"ׯm(sޟ?1 !ն=LwUZD_] `H~@ Q=pC48'3vd 66>Pw5H6{RuUW \UşG%j5 5a-38d(CaT`[?Gjw380ȉYM;7]7 6iMF?! Fat@F;\mcʅK+3hݿ~z~_߷z fѶ zA4VRDi411lTLjݿa|I"nm\?1HA#7[6cg?@CܐL;#սK/uֺW R!|{{{5C1ni3#1cFhi䝖J%ʠ qFz)`?HF.wtt[ LªUzMEWWWC?35kVCCPDZsNv \SQ C駟,-a]]],^xV={6gnz|Gߏ?i3A0A@z*gٶ ~H@6FՀI4?ymA2m*2M6~vw+ Ebv͛ۚ!e)almv6`c<[ XIؼy3կ&~H5mZ~;;;vm-CR)jI޸q#W&CR97n^&CR)I흐)HH <RQiUߋ/@GGǃvۻ>1FR%* i&~!e)q6m⥗^&6CR1H@DX*poo/o E[Ÿ yflJ6Rm0͛7frOwZ )HіpL-[ "E#PR?ͦm"E#!;3%&@ի$\.;xH-THVXz5?8 E@%~!)WFjh lܸÇ }cKgg<̢洹cqe rB 0DDDDDaUH Ő('cDDH"X\)P& !$016%{_4@fZTY25Xfߞ)eׁkC;WqSܤ"\+5ƒJh˧FXٮbiͺkZ90N(iۯ}y3ýB*Lp,ŖFM3dƂ>WQ͉B'Ϡ/D{ f[lpּ(hI%ᯐ`7$#W{SkDP^Cu^M L^ZھqrŒUy+6G~p鿰e/ɱ!JNA3cksD gl7v֐:xA&V* d v*{ D!= fh_$%cbq|j=qЂ^:H&iVOYqZ֕dֵkZֵkZֵq(!1P02Q"34A`aq?/m۝,S1_L8X6u, Dj q4fR:Lbfx56ҡ*CM1o'A׿ɪ٨/*1P!0234`q?&(fg) wֹh;xWiWn!o)Mڑr|ȝűM?><~ۯjm(c@|sX+XRfB;,Ջ1:oMLd:>XFta)R\>kSWVv8XH_EBqaS=u62PNUi< !1"2AQq#PRr3Bat$`b?e"nآ"9q0>ݝӖjBۡKַhae|sSlɯO>{Q&W*HA4%n.+lG$jWWӍcCS}m% eSOsz{6Y4kLg߄JP5tzZfHt!ɮ{y+#E`Hk{7\TYm}^6LJ3wXb֒yjȅ׏.褴3qJ0 HiQHyPMIqhS姞*IzoŴ8}j+~IN ܪ!p,0bgkH-%( k.43)HHwc"2:50N8O 7sZ-)R.d¬4 <*|,u̟kq\g :|z{vc ۇ^9kHa7j0]E0vl=bB}O:-(㸒<Ț_O +qy0x۞)nFl80Fk}vƴW: x3W`7_ȯpil"F(8zUesns~ϟ:I%8Z#G9bu竞i="lۜ[c$Vpn#UĜic[f!U~]EĖڵ鑋O0#xegƧkX&wܓ(!1AQPaq 0@?!ZWxfIKKYЏӎڌ˚^:;B9ttxvRkhtKӅ4[SǤ3YIUv67 uRѫB!s ¯KqL &2ЌUN' {Dڠŵ(yq %Yeh5,@@STJ.C}_ԈQg0ìĺ|X D[dYv*SMR*K pZa&>T>b6[%w1GA EsVG2*W2}:r݈_5 00/-Q~ nI{^0iɈ&їdDp%{ټyt,Ԯ$Q"`.01%](7͖ܞFj{`YKK9z(ւ:ժMhԢNYX6+ߘ?jfa[)*97AeFwKfqV tD0%%%%%%ee`!! %gm$M,H m?Y$$$m%Wi$@[mv7$ 5iY%mAdI-K-I%&[mԲ b]oie&Id3,43k}m{m~Y ,:f$'[mCII`' 'mZIH]E@&d%m4m$H&oI"1!PA0Qaq?Apoq ^7w2 18Q8"[GCЂ*d^FP] ?#zqX }R6NᄆC L>ýHlΣ\ym0ڎżKj*ұe]:y`EsygzNeǿ}18j-5>_V^VgjrWq}DŽa9{ @@a!Ѝ:*LVq1?/LZb,xp"!1AQaq?""";""#DGGDDDDDuǩJ +ʃ?qDGGpDDGDDDGD]"""""# 5 V)x[ǒ8&;apDDDwpu"""#Q DGDGiԃWQtٕr@.X1q"""":8""#"""7仳'b4kd$N 9.4{,3{A Wʚ3b""9""#,>l~a1;E|̣ c<@zc? .{$g"8""""""#@mdRj:Ƣ_ ziL\iJ*xLqmڪaK0% u=ov|.3(>_eWGGaIQI=ÒI&&{?u<(2#%nJ4QN}DCcNr 7I1,"""88=N= ]H p:{*4:h.RgھgYϝ65`3BM{ {kb@ɑG 9.r:(EVϗ~kQ.v㴢(ryu #JӰk"Fn=@a8:ȚU?&Xg d8XsA9ys贋5,M.g:]ZqZTlPnYŰ `2+F|1x8Lˆ9,vEtgeuM9AЩƴ80Z(<㚕߱jO*sC hP2aeBzsab.#8!7DCb (X Eqonomize-1.5.3/data/banner.xcf000066400000000000000000007232641416454732000163720ustar00rootroot00000000000000gimp xcf fileFBBgimp-image-grid(style solid) (fgcolor (color-rgba 0.000000 0.000000 0.000000 1.000000)) (bgcolor (color-rgba 1.000000 1.000000 1.000000 1.000000)) (xspacing 10.000000) (yspacing 10.000000) (spacing-unit inches) (xoffset 0.000000) (yoffset 0.000000) (offset-unit inches)  =y{ Eqonomize!     K$gimp-text-layert(markup "Eqonomize!") (font "Sans") (font-size 18.000000) (font-size-unit pixels) (antialias yes) (language "sv-se") (base-direction ltr) (color (color-rgb 0.000000 0.000000 0.000000)) (justify left) (box-mode dynamic) (box-unit pixels) (hinting yes) { 1{ X l64PX\__Tt50ZyqC$Tt4UsURt43\Rt4>]Rt4C^#Rt4D^4Rt4@]Rt46\Rt4 ZlRt5<\jqYRGXt5 @SZ`jZOt;Qt;Rt;Rt;Rt:5RZ`j"X 6  5  4  4  4  3  3  3  4  4  4    5 ; ; ; ; : "X@6zrnkur@4UlH7qp@4pAp@4lp@3x` p@3sYp@3sXp@3u_ p@3lp@4pIp@4oY]u|p@5$vphZq@;q@;p@;p@;p@9zpgK#@123I "'2e23/23/23/+6b%3/ fe$SVze$3/$$a K7wV K3/OYATFTF3eA`;P`3P((n5A=nL=3/*#A /L /3/!A /L /3/M 5A>lL>3/ iAb:Lb3/7| ASILSI3I  !&2gRhI6LI1jdޙ#ASdޙ#>:A:A:A8 "999>I,rb[" R5C54\T4ixE%7ʟɠ8HVn "N }r_: ; EwV n As-?<7 As> AsZ1[l Ask A : AsSZs  As09Ie=6 AsރI7uOSknLIrMVJF& ~ۛ3>(= 4Drop Shadow #1R     @ 44(    2 /*'&            !!      !$&''&%"    "&)+--,*'%"  &*.1221/,)&#  #).2566530-*'$"    &,269::9630-*(&%$$%$$#"#$%&''& !(.49<==<9630.,*))*+*)()*++,-..//.. "*06;>@@><9631/../0112210/0112345665 #+28=@BB@>;8642234567899876556789:;;<<; $+29>ACCA?<:86556689:<=>>??>>=<;;::;<=>?@AABBAA $+39>ACCB@=;9889:<=?@ABCDDCCBA@?>>?@@BCDDEFFE $+29>ACCB@><::;=?@BDEFGHHGGFEDBBAABCDEFGHH #+28=@BB@><;:;<=?ACEGHIJJKJIHGFDCCBCCDEFGHHII "*07@BDFHIKLLKJIHFEDCCDEEFGHHIIH !(/59=??=<;::;<>@BDFHJKLLJIGFDCBAABCDDEFF &,26:;<<;9889:<>ACEGIJKLKKIGFDB@??@ABBCC #).36887655689<>ACEGIIJIHGEC@>=<;::;;<<==>>  &*.1344322123468;=@BDFFGFECA><:87655678 "&),..-./1368;>@ABCB@><:753100//00121 !$'())()*,.0368;<=>=;9741/-+*))* !"##"#$&(*-0357887631.+)'%$#""#  "$'),/0221/-+(%#!  #&(*++*)'$"  "#$%$#!                        *0 3   d4   1                               !""##$%$#"!!  !&%$#"!!"#$%%&'()**++*+*)(('&& %&'-,+*)((''()*+,-./012210/.-, ,+,,43210//../01234567899:9876543221122 32:9876554456789:;<=>??@@?>=<;:987789876@?>=<;;:99:;<=>@ABCDDEEDCBA@?>=<;;<=>?>=<;9DDCBA@?>>==>?@BCDEFGGHHGFEDCBA@??>??@@AABBCBA?=;GGFEDCCBAA@@AABCDFGHIIJJIHGFECBBAABBCCDDEEFEDCA?;8CBBA@??>>?@@ABBCCDEDCBA ABA@?=:74>>==<;;::9::;<<==>>?@A@@?>=>>=;:85208876554567789:;:9876420-+110/./01234543210.,*(%**)()*+,- .-,+*)(&$" ## "#$%& '&%$#"!                  & !C%_            !  "#$%%$#  '())(&# ,--,*($  10.,)&! 54320-*&" 86530.*&! 97530-)%! :752/,($ 9631-*&" 741.+($  41.+(%" 1.+(%" -*'$" (%#! #!          K% eqonomize.png     xxxYBUlnrlQwf K'}>Vs E{Юw'D1oO4cuuuux]xmxxپſ۾ý    ʸ̿ۿþٽľھ&kqlhc_ZVQLHD?:62.* %?{tmf_WPJ9  VU'>yrkd]VO< Z}D h`YS? ` *2/-+(&#! ld^W@ %0 Yvy#|yske^WPIB=,ha[@   *Qjni&I':17*»xph_WP;f_> a)szB&'{skcZT=ia9>pc__pc__al'xpg_X?n]. Md^nnd^nnb_f&|tlc]>pO'a[a[k[:$yqib;`6#V`Y`YiY ~umc37+$"^W^WfW"ytZ(*,$%͠ZUZUdU!{n@#+,$s×-WSWSaS xlB-#+,$^TQQ^TQQ_QQSZpK3*,#+,$UO\\UO\\f\\RPt=))*+,#+,$QMQMZMd)'++,#+,$OJ||OJ||WJy+)++,#+,$NIyyNIyyUIF*++,#+,$KFuuKFuuRF5++,#+,$IDrrIDrrPDg/++,#+,$HBBHBBnMBBD,#+,$MDDMDDA@jjJ@DDEJ +,$7B>ggB>ggH>Ssez+,$6?;cc?;ccE;O셔7+,$4>:``>:``C:;;{,$ 4:7\\:7\\A7Ӫr,$ 395YY95YY>5猑ﲤ$ 17337334mm# 0>544>54459Х / yꥥ. ߌ~~پſ۾ý       ȷ翼˾پ¼׽ýؽĿܾ1y%N $ PO&O $ S{xC $  Y:JIIGFEEDCBA@??@4$ "+ Nlo*ѩ$  'Mdg`$D%-"(4 $ ^&jtA2 $>1 # Na3 # 30#U,##ȗ뗍/#&͟蔋0#tė-哉0"ס"ِ"ݎ"ڊ"׉"Ԉ"}ц}}"||||||!|zz !-yɁyy)\z|m!+~w~ww)||,!(|u|uu(11q! &{s{ss(ěe! $yqyqq炆礓! "zppzppuwcwc喔! |xuu|xuuvytyt| m.#"#$$%|tu|tuun~ޔ y'"$#""#vtxvtx蔔 پſ۾ýʸĿپſ۾&kqlhc_ZVQLHD?:62.* ;?{tmf_WPJ9  0>yrkd]VO< V h`YS? 9 *2/-+(&#! ld^W@ El#|yske^WPIB=,ha[@ aG6*»xph_WP;f_>CMU'{skcZT=ia9 z 'xpg_X?n]. &&|tlc]>pO' !$yqib;`6#4 ~umc37+$B"ytZ(*,$D!{n@#+,$,U xlB-#+,$ڭpK3*,#+,$ۨt=))*+,#+,$d)'++,#+,$y+)++,#+,$F*++,#+,$5++,#+,$g/++,#+,$,#+,$ +,$.¹Ss(,.*"+,$,ļO3365320/.* +,$)º88877FNF3.,*!,$ '::::fi;+(,$ %;;>B)($ #3/=;3/=;wfJGE`-'"# ! 82-*82-*4312>312ZtvF;C;U;܀<=???1pc__al1d^nnb_5a[k[5`YiY5^WfW5ZUdU5WSaS.^TQQ_QQ*UO\\f\\*QM*OJ||*NIyy*KFuu*IDrr*HBBnMBB*MDDA@jjJ@DD1B>ggH>5?;ccE;5>:``C:5:7\\A7595YY>5573345>54459;:~9}<>;C;U;܀<=??7666666666678888888888881155555.******}*||||*|zz1yy5~ww5|uu5{ss5yqq5zppu5|xuuv;|t:vtx9xs<>;C;U;܀<=1666666/********16666668;;4/:>3129@62>N{ë됊Յԉ㑣R󶃔YqҨ퓉ԉ֋哢—Q󺊍pOe뭡Аߑ왜Plę頒鲪oekۍ͗ܳɼαƝշ~uϔmÈݠ㶮ý鼲в¶×(츲::;V)  4 4 4 4ʢҦҼ˾ñƸˎʵtحΟ̫޾Ұǣjߤw꩝㣖鮗sf{Ȁ쬎𸒿VW{품΀֋񯌼咠IM{鏈тч򲍺OP{둇Іԉ򴒿⑟aQ{͍܏阙U||析尨빩xdl˕ذƹ񽕼ʮěѴ캄wјt콥ٝᴬ纯ԴŹ궰   3 ^+fֽ^TQQSZ Ө姁~y̿ıǸUO\\RP ՗кݧͫӱQMZM o꿳쩞壖OJ||WJ ׁf۳┝NIyyUI bXĽ罸׊󰋼璠KFuuRF TMʭӇ⎡IDrrPD [OجՈ䐟HBBDpRގ뗙MDDEJ]xŗ螏豩ezgߔƺ˯Śҵ셔7|ʐ۞䵭¼輱;{Ӫr췲ﲤmڋХ$yꥥ$د Ͽ N{ë됊Յԉ㑣R󶃔YqҨ퓉ԉ֋哢—Q󺊍pOe뭡Аߑ왜Plę頒鲪oekۍ͗ܳɼαƝշ~uϔmÈݠ㶮ý鼲в¶×(츲::;V?#    Ɵͣθǻ̿´ƋŰʼrөʜȨٻϮágڠv槛ޠ䬖pdz~ے稌隝봐TVz萆~҈쬊﹎GKz㋆̀͆܍𻏶MOz卄ͅχݎ𽓹_Oy헂Ɋ؍鱘啖ډSyz𽓿⛎᭥綦vcjƒԭ¶칒Ǭβ綂u͕q湢՛ݰⷭα䲭(Rֽ١ Ө姁~y̿ıǸ ՗кݧͫӱȎ o꿳쩞壖늃 ׁf۳┝ bXĽ罸׊󰋼璠 TMʭӇ⎡}} [OجՈ䐟||pRގ뗙􋄃]xŗ螏豩\z|mgߔƺ˯Śҵ|,|ʐ۞䵭¼輱1qěe췲礓wc喔관yt|$ɰuun~ޔ$ɴ蔔"ڱƷ甕 㷪N{ë됊Յԉ㑣R󶃔YqҨ퓉ԉ֋哢—Q󺊍pOe뭡Аߑ왜Plę頒鲪oekۍ͗ܳɼαƝշ~uϔmÈݠ㶮ý鼲в¶×(츲::;  ͤըվųȹΐ̶ÐuڮРέԲȤky夗믙tg}Ɂ╞ﭐWXý|Ё؋󱌽瓢IM|쏉ӃԈ㏢OP|품ԈՊ䑠–cQ|Ўސ옚U|ٺ~ė韑豪zem̖۲Ȼ̰ƜӶxՙtܟ䶮¼鼱 ַǻ–(츲::gֽӨ姁~y̿ıǸ ՗кݧͫӱ o꿳쩞壖 ׁf۳┝ bXĽ罸׊󰋼璠 TMʭӇ⎡ [OجՈ䐟pRގ뗙]xŗ螏豩(,.*"gߔƺ˯Śҵ365320/.* |ʐ۞䵭¼輱8877FNF3.,*!::fi;+(췲;;>B)(3/=;wfJGE`-'"2-*4uuRFդ:rrPDߵ9BBnMBBDΤ7DDA@jjJ@DDEJת~>B>ggH>ezϾٯz?;ccE;ޅ7׳>:``C:;{յ:7\\A7Ӫrִ95YY>5ﲤ ٴ7334m ٴ>54459蓋Хٴ yꥥٴ 勁~ٵ 䀂}Ͽش |ʸ䥦سƾ2ïǵӸ1´ݽ1µɱ߿1öú߿1ظ1ֽ1?-(  ˬ О਷ߧߧߧº幼ߧݱ¾ߧ֫ÿਸծן²뽹ӦĻګٽ̺ϪƓ  Ѯү¬"ԱĮ"ԱĮ"ԱĮ"ԱĮԱĮ}ԱĮ|| ԱĮ| ԱĮ.Dg2!! ԰.:d3  ~̥η,1]?|ٴª.IQ{}ߵİ+2])y||||ɍ~+,FGz|zzЋ|*/T(|yy\z|mϾՑx+8L~ww|,ٟ+@8|uu1qڰ,G({ssěeڹ$+JƲyqq礓ڹ$,Gzppuwc喔ڹ$-B|xuuv臀yt|ڹ",> |tuun~ޔڹ!*= vtx蔔ڹ &< xsƷ甕ٸ$5 ryٔط$/2ïǵӸ1´ݽ1µɱ߿1öú߿1ظ1ֽ1% &ϭ &ՠ '媺%㩹%㩹%㪸Ľ黽%㪸ᳺ%㪸٭%䪹ذ%۠Ŵ%֧Ǿÿ%===# Ż ° μ  ðϿɭعѿ  ﲭ聯 .Dg2!! v벡.:d3   xt񬧰,1]? l{ﲰ.IQ g|𰦊q+2])ix쯨u+,FGsk~xy*/T( (,.*"|pz+8L365320/.* yt+@88877FNF3.,*!y,G(::fi;+($+JƲ;>B)($,G3/=;wfJGE`-'"$-B82-*4 ;4/.+(8312ZtvFyiCggH>ez;ccE;텔7 :``C:;{ 7\\A7Ӫr 5YY>5錑ﲤ 34m 54459哋Х yꥥ ዁~ }Ͽ |ʸ䥦 |͸}z{˽|Ĥuyű}|ž y{ܫĿ+ xw{ֲ0 zq}{ή هrt|{܍ ޿ &#     ϼ ߸ ļ ۽ Ǻ 疧Ͻ 癔       +" -.- nP3/1 FgrP1.3 }''>ih:0,|||&&)QnDzz%%yy##$\z|mww""#|, uu!!1q ss  ěe qq邆礓 puwc喔 xuuv䇀yt| |tuun~ޔ vtx蔔 xsƷ甕 ryٔ wrĮ~s~뫔prsuܹmp}ssڴ p~~q̝& }onxqģ) phtqǼ yiksq~ ޿ .ҽǾ޿ȻѾ+++++$$+"-.- nP3/1FgrP1.3'>ih:0,&)QnD%#$(,.*""#365320/.* !8877FNF3.,*!  ::fi;+( ;>B)( 3/=;wfJGE`-'" 82-*4312ZtvFyiCgp)'>4?t742lk;:8Xn0)&>3B}l74IgA:8QwwU.+( =35ym84r}MKA8759@:/.,) @4/ck74eMKIGD7320/-& '6/4d64`MKI_jfZe{"!Ǭ **+++++ # #$$$$$ H   :osK o6 & 6 ZHW !z#^ N [<?J! G(4 , ܀}}Ͽ * ܊|Њ|ʸ䥦 ) ܂|͂|͸} ( ݒz{˒z{˽|Ĥu' yōyű}|ž& ׌yy{ܫĿ+$% xwxw{ֲ0$# zqzq}{ή,$! rtrt|{܍,$! wlgwlg~{ԍ*+$ tgtgx{񨍎'0$! utut{|껌~o`#" x|x||}´x!$ x}x}}f]!& ͌>v~v~w\2#' >hhW#*+$ V >jj^+,$=+$,        ˸ܿĿپſ۾þ   ̸̿ۿþٽľھ qC#"!! !"xsxsƷ甕 j{|"$"  ryƀryٔ csz[" wrwrĮ~s~뫔 [kr{> prprsuܹm Tcjsr.p}p}ssڴ  L[aka&p~p~~q̝&  DSYcQ"}on}onxqģ) >JQZAphphtqǼ5BGO5yikyiksq~.9?D+oc`oc`uq~'/68$zj^zj^oq}'(--  }jk}jkqs߮}~n-(%#  ymsymssw} 4.$  mtmtst}\ <6(  ltlttu}{|~mA;( `w`wtvwxyz{}Q 0!   ^^vy|{ySr         ˸ܿĿپſ۾þ       ʷ˾پ¼׽ýؽĿݾ yO+/-,+**+,@62>@62>yiCgp)'^ms{z9)'$"  !>4?>4?t742lk;:8Xn0)&Vejti0'%# >3B}>3B}l74IgA:8QwwU.+( $ P^bkY+%# =35y=35ym84r}MKA8759@:/.,) $ IVZcI'# @4/c@4/ck74eMKIGD7320/-&,$AMQX<$!6/4d6/4d64`MKI_jfZe{"!,$:DHM4#:1,-:1,-84tMKTljifp" *+$2;@@,!5.(5.(34UzB"'0$2476& 5,05,042\`#"o`# 83/,$ 3-33-3212Rx{}yrbM+#"x! >9.'# /3/31/LWVUTSG+$#]!E@2&" 1212/.8@B=0&%%\2#KD0%!(1(1.-,+)(&'#*+$ 5(   ##,,+*(+,$+$    ˸ܿĿپſ۾þ̸ܿĿپƿ۾       ߫м n}弽 }յ µ Ķ䰨ȴ ޠźݬׯ ǿܮ뽬 㵽ö Ȼ  峰           䯇ҽ |罾 ꞈֶ ޹ö￯ ܪŷ屨ɵ ܸƺޭٯ ɻޯ 嶾ķ ʼ             Ѽ ߧ弽 յ µ Ķ㰨ȴ źݬد ǿܮ뽭        کκ n|㻼ɿ {鿷Ӵ 񾪓뽮 񾻹µⰧƳ ٞøګխ ž٭軬 ഻ Ǻ 鳰 Ⱝ         ܣ 䯇Hҽ | 罾 ꞙֶ  ö￯ xŷ屨ɵ iƺޭٯ w8ޯ J嶾ķ hHʼ #x   z\e^" [ t} yx v{ A i  Y XϺ )8ݥ㻼ȿ 鿶Ҵ 꽭 µᯧƳ øګ֮ tžڭ輬 l   ୂҽ n~罾 Î~ֶ íö ŷ屨ɵ ƺޭٯ ޯ 嶾ķ ʼ  赱    ܣ 䯇Hҽ | 罾 ꞙֶ  ö￯ xŷ屨ɵ iƺޭٯ w8ޯ J嶾ķ hHʼ #x   z\e^"]w|zy~C k  [ [ҽ *:罾 ý¸ֶ ö￯ ŷ屨ɵ ƺޭٯ wޯ p   ̉ `rԞiԿ~ʸߺոȾџ꾼ʪߚwʛЇެľъԏ᜛}xԻr̴sыݐ΄}⃉m͢Ѣ~ł{冋fý⏋Ԇ҆懊žgݿԂ槁¤nyy|ˍ֣ŐЃٰʵ     , 0 -==<媡߬䳝s}n鮠׷ibkokӶ¼nظlkٵĘѐʲܒ\|پz]kelkyՖ_k\Z~mrޗҬͮ푉ؐwϥvŗhkvnoV}ڏ~Ŋ갵ډpyŜɥpnvpLx~᥌px~ljхpRt}궁plӜ\`з[vc䵖nčز̈||ux{y҅gֶ~יӘsͻ̹ļƶǷøĘ4ڟ4٩465&<  xػ?ĸü౫ϫ˶ƐɞIJϼƧӚɭڎyàzwzƅՆym\i읂Ɇȁۇʆo~k}ҹ~gݧbgzҁцߊĞooy`xǿv٫iYunH gt{6uzyv PȈD쳯_qG½͞hԼ|kv۶ѴĺӜ{Ȧikۘvř˅٨ӉɢkЋܚjvϷpǰqӉiڌʃ"Jډ݀kȞӟrd݌}#HydþĂ3ލЅH΄ᄇe$Ё~᥀@<}lwvz}ժ'NjҠ.ḱ}ӫ98.oݿƲ=9{y9 9yz9 =0}5 _][ n}1 mV m)_ lM*T* j*l j*j i*j %{_3E媡߬a䳝76 s}n鮠.6 ׷ib`DkokӶ^g¼nظlkǎٵĘΑVcʲܒ\|پz]kel𭖍}kvkyՖ_k\Z~mrޗҬͮvpؐwϥvŗhkvnoV}vڏ~ŏziHډpyŜɥpnvpLxh~ᦐnypx~ljхpRt橌ea궁plӜ\`з[vcʤ䵖|WOز̈||ux{y҅gֶ~יu Ouͻ̹ļƶǷøĘ;<ُ4eТ4٩S4ǨF6Y' v yyv{f   %wԸd1?y˾ͼٻۭ˨ȴrrŽśʷϗĨ֌xz%uwЃwj[h皁Ƅ$ֆƂm}iz͵{eפ`dw霋΄$ڈ㿚~mlw^v}sҦfWyr1J k1x81y~1}z1S ΋F `sI Ԣiny⻱غԠ~Ϋlny̝ӉᮨԌΧn֏㞛myֽrϷtԌmц#M⍈儊nϤԣug㐋%K|釋fȄ4同ևJՈ鈌şg%ׄ詂B>ozzĻ}( Ύ٥0oȒӅ۱;:/s͸? ;-}; ;}-}; ?1,7 b+`_ r+3 o+W n*_ lM*T* j*l j*j i*j %{_3E媡߬a䳝76 s}n鮠.6 ׷ib`DkokӶ^g¼nظlkǎٵĘΑVcʲܒ\|پz]kel𭖍}kvkyՖ_k\Z~mrޗҬͮvpؐwϥvŗhkvnoV}vڏ~ŏziHډpyŜɥpnvpLxh~ᦐnypx~ljхpRt橌ea궁plӜ\`з[vcʤ䵖|WOز̈||ux{y҅gֶ~יu Ouͻ̹ļƶǷøĘ;<ُ4eТ4٩S4ǨF6Y:w:{{:y:j:;;& & &%xڼ h2%‡ƺ}Ŀü¾‡ⳭҬκuuɒ̡ƵҾȨל̰‡ݏzĢ{&x{ɇ؈zn]kˈ˃$މ͇pl}ռhci|ԁԈ%⌃Ɵpp{aywۭjZ??1򺳧ܽ1򻾋{㥊1k~d1Φ͞Uav1բz]O1ݷel1Ύ1xÚ1󳲾Ⱦs??========================?1򺳧ܽ1򻾋{㥊1k~d1Φ͞Uav1բz]O1ݷel1Ύ1xÚ1󳲾Ⱦs??==============@1򺳧ܽ1򻾋{㥊1k~d1Φ͞Uav1բz]O1ݷel1Ύ1xÚ1󳲾Ⱦs:|9|͸8z{˽8yű8y8xw8zq}9rt|9wlg~9tgx:ut;x<>?????:ry9wrĮ8pr8p}8p~~8}onx8pht9yiks9oc`u9zj^o:}jk;ym;;;<<<<<<<<<??>:;38973gq8B43}K8>4?t78>3B}l78=35ym88@4/ck796/4d69:1,-895.(3:5,0;3-<> 鸣䥦!霊}!|Ĥu }|ž!{ܫĿ+{ֲ0ҿ{ήϢкȻΰ{܍Ϳq֪Νʩ޾Ы{ԍu~馛㡓ȟ{񨍎y}ޑ쪋햓ͥ{|껌~x폅}Ո񮈹䎕Щ||}´x錅ф򯊹ѫx}}fx뎄σӆ񱏻ۉЪv~wx̋܍ڎΪhWz杍宨ٙʦj^iʓ֮ö񼓹Ȭկ· Жr콤ך⴪ǨԵźƺ鳯    / 0 1 1 1 1 1Ϲͽʵѥך~շӔѺ̛ۯ|԰l̷{Բ~b˷Բ_Ţ񮓳Ա QJӪpХԵ XMؙi᳻ǿζ nOx潿͢YtƐ¾̨τcֻķ㬉ȴƺƎzǥڛЎwίݼ·ŵ%뵱&&331  !Ļśȱ͵ƹ̲Ƈ˴˘ʡРШǦ߾ΫƮcy飙⟐Ȝl_joqtގ쨉얘֢OP`ݖYk^ԅ𬆸㍛᥆AF҆oeԒuiς򮇷߉﵆HIѤ֫҄񯌻ዚ\JɛѢۊ蓓񽔭鯘ٔˤ~s~뫔Үsuܹmssڴбq̝&񾫭qģ)뺘qǼʟ̶ŸΏ{yq~ȻoѦʚƦڻ͝nuq~۞r|夙ޞsvfq}w{ڏ禉k|aqs߮}~nv獃{Ѕ쪇tm`~ssw}v∃}̂^la~mtst}\v䋁˂΄_jdlttu}{|~mv~Lj׋鯖efi`wtvwxyz{}Qx𼑾ᙋ૦ɸoc}r^vy|{ySgƐҫ鿳츐Īګh~z ̓p湡Әݰإ~wϱ䰬೪إ ٥ Ϧ ¨  /ĭ 1Ǯ 1¯ 1ӫ 1ԫ 1֬Ϲͽūѥך~kabdbnӔѺ̛ۯnozl̷ev~b˷qw_Ţ񱄐x}us QJӪpЧxzr`[s XMؙi᳼ůe[ nOx潿Ǯ{aYtƐ¾Ŭqτcֻķ㬉ŽƎzǥڛЎwwݼ·%뵱&̯&鬱3몱3ư Ϯ &ڪ¬㭪೫վ蝏íɲ¶ɖyw}ǰǕŝ̜̥ģڻʩlraw}~䡖ޜ繁ʟsci]gmorٌ椆甖w`MO^ؒXiݠ\σ먄ފ{]|@D}̄ldϏsgڇ[{FGˡѨ́쭊܉l}ZGř͟׈謓向칂rM5<gp)'!ƭ42lk;:8Xn0)&"׷4IgA:8QwwU.+( !ű4r}MKA8759@:/.,) 4eMKIGD7320/-&ҥӼ˾İӓ|4`MKI_jfZe{"!Žrثў̫ӡpw4tMKTljifp" v쨜䢔uxh4UzB"z~ᒜmd42\`#"z~׈󯉼wob3212Rx{}yrbM+#"z댆Ӏ҅`oc/31/LWVUTSG+$#z폅҅Շamf12/.8@B=0&%%zΌލgil(1.-,+)(&'ֹ{•蝎簪Ͼset#,,+*(iٰ͕Ÿʯ᱉k} Ԙs₩ڜ䵬߫z׷ȼǯ%춱踰&૱ &૱ 1֬ 1ɮ 1Ů 1Ʈ 1Ʈ 1¯ 1ӫ 1ԫ 1֬Ϲͽūѥך~kabdbnӔѺ̛ۯnozl̷ev~b˷qw_Ţ񱄐x}us QJӪpЧxzr`[s XMؙi᳼ůe[ nOx潿Ǯ{aYtƐ¾Ŭqτcֻķ㬉ŽƎzǥڛЎwwݼ·%뵱&̯&鬱3몱3ư3а3߯44Ȳ4곰55繱ȝʳз¹ȼîϚ|yɈζΙ̣ӡӪʨЭouez󶁱즚䠒ФwfmakprvzaOQaߗ[l_Ն󭇺卝~_BFӇpfדvjт⊝]IIӧٮԅ㌚n^J̞ԣދ디 |͸}س z{˽|Ĥuس yű}|žس y{ܫĿ+س xw{ֲ0س zq}{ήس rt|{܍س wlg~{ԍش tgx{񨍎س ut{|껌~د x||}´՝ x}}ḟ v~w}} hWy{ j^{y  ߺz~  ڱ 鬬       * + + , ,!̽˱ŴüҵŴǝºԻλǹɱӷͯãŴԹƺѸƩϫöř¢ѺͨҭѰѦѺӮϭȷɩʩ̳׾IJūʵʲϹƽžɿ n.... ²;θδ¹ӽǽպğԻͣßѴÕßɶʬßж¢ʭÖß˪ͨѷ̢ßȧѫҸ wrĮ~s~뫔ӵ )% prsuܹm#,   p}ssڴֱ(   p~~q̝&ֱ #   }onxqģ)ֱ#   phtqǼֱ  yiksq~ֱ oc`uq~޹ֲ zj^oq}ֱ }jkqs߮}~n֭ ymssw}қ  mtst}\ʆ  lttu}{|~m⫸|| `wtvwxyz{}Qxz^vy|{yS㬮{y 䩸Ɋx~ 容ֿ碅紮ֱ ֱ ֱֱֲ߬س)ﰴڵ+Դ,,!̹粭氥ȱܱtԱvr갯Ʊiy鲰ez갦pz|hv毨u}}ݲri{ux{}ުiynyx|ްuxs~߯y沫 $$  t}s૑tyx{l鮪xzno쮬xtjo쮬xzvnl쮬x{z}zf뮭xyy~ 73gq=517gp)'#,   >4?t742lk;:8Xn0)&(   >3B}l74IgA:8QwwU.+(  #   =35ym84r}MKA8759@:/.,) #   @4/ck74eMKIGD7320/-&󰩟  6/4d64`MKI_jfZe{"!󯥎v| :1,-84tMKTljifp" mw 5.(34UzB"貰t 5,042\`#"岯t~ 3-3212Rx{}yrbM+#"岯t~  /31/LWVUTSG+$#鲯t~  12/.8@B=0&%%岯t~ (1.-,+)(&'岯s~#,,+*(岯t 殗mv 欕sx%殢& . . . - α-λ-ű-ϰ0߾1麯3۽(˷(ȳ(򰥖)tvr갯iy鲰ez갦pz|hv毨u}}ܲri{ux{}ުiynyx|ްuxs~߯y沫 .#u벨tv{鲤y|n鲮y{pq첰yukq첰y{von첰y|{~|gyz{{wlg~{ԍ {tgx{񨍎 |{{ut{|껌~ {{x||}´ҁ{{x}}fկ{{xv~w{{FhW {{DDj^ {{QBB |{{q@@A[ {{>>??AGD8Ỹ{{==?BD:5c~|{{|F=?@92Br fhw}}|}j94-7^q }gRU_ekmmje_X*Cbw न|tkebbemuzp ᔚ ᝠ +,,# $&?νؕטؾϻŦ˭ŹѺǾص˹бʴͽúĻ ȼʽù!%'((̺ʭƾѯִѳǿ ˳Ͷʲſ ͳͲҳҼı մˮӸӴƲԺʷ ִͰӹӴdzľ Foc`uq~㏿zj^oq} '}jkqs߮}~n rymssw} mtst}\ Uylttu}{|~m  u`wtvwxyz{}Q 7tt^vy|{yS trr vppqqI fooquoYF$  mmnpqbP=  MmmnpcTF3 mtf[NE7 fmyYC;2" ࢦh\^ekggi`WK)  ᛟ  Կ Ǽͽ ӽ ؽɱ  Ƕؽ׽ƻο̷ɻȴҷ̴˱ǶĵɻسƹѺѶÿױӻӸ½û䴳ֽӷȷסϳȵ؎θŹٙ ﰯ񯮮      է֘y ֞z ׯ ױ *:1,-84tMKTljifp" ҩ #*5.(34UzB"ì  **5,042\`#"Ӹ  **3-3212Rx{}yrbM+#"  )**/31/LWVUTSG+$# **]12/.8@B=0&%% %**9(1.-,+)(&' **#,,+*( **  )**`i **:򭰥g7 &**)﫬wY .,**왪~iL ',--,-exiT  #%&''&$#,h\O3 = ɣ ഔ ׵߹$̶'˺((*,,,--ؕחحرڟﯭס؎ٙ++++**(((' ֪ ך{ ס{ ز ٴ 0} OP s 2  hK" @,$Aȶ1 & * þ     ̸ܿĿپƿ۾Ŀ   ͸̿۾þٽľھܭÿ  ½      ̸ܿĿپƿ۾Ŀ      ˷˿پ¼׽ýؽĿݾþ        ľ̸ܿĿپƿ۾Ŀ͸½ܿĿپƿ۾Ŀ㵽ö ҿɻ               ଀ӽ o~罾 Ï~¸ն îö￯ ŷ屨ʶ ᣸ƺޭگ ǻޯ 嶾ķ ˼ ﵴ 趲     ƍҼ~漽ىԵ׈µ׈ѷĶ㰨ɵ׈źܬٯ׈̺ܮ뾭׈¿䶽öىӿʻ|廋   ᴻ pоǺ _ ?ܨ , . / Rc o! a  j  H6a \ [Y Fp 6| 9w଀ӽ ;o~罾 g@Ï~¸ն Dîö￯ #Cŷ屨ʶ "D᣸ƺޭگ pǻޯ 嶾ķ ˼ ﵴ VO趲  "_r m h z b e f 2   ‹к  }㻼 ՇҴ O*ӆ꼭 oӆεµᯧdz mӆøګ׮ oӆȹſڭ輬 Tӆᴻ M4ՇѾȺ 7)z <(Ṋ 68 #n p q r  l~ jklnu嶾ķ tʼ b A - /1Ufr"dlI6a \ [Y Fp 6| 9w଀ӽ ;o~罾 g@Ï~¸ն Dîö￯ #Cŷ屨ʶ "D᣸ƺޭگ pǻޯ 嶾ķ ˼ ﵴ VO趲  "_qnk~dhh 4   Ȏӽ  罾 ۉ¸ն Q+ىö￯ qىӷŷ屨ʶ pىƺޭگ qىλޯ Vى巾ķ P6ۊ˼ 8*| =)轌 89 $qtuu olllnuˋӥjoft{vny⒃𯁨ݻ˶nj;޽qpjʵљךݨ£lƲ˕|v̟ε۾# $<==i͇`tՠj¦Ʒ⺯ȿԟۿ̫дxӈ୨Œԋ֏㜜~yrζtԌߐЅ㎇慊nΥԥ㐋ƃ|釋fǏ䐌׈։鈌Šh姅փ髂ݶoyyü~Яΐڧɕԇܴϻ0===>/   =    ƶ ۵׶ ؋ ɓž»ſr ׿ϰоԣ}zߘa~ ޟ碘颅Ψt}e ަ~Ԍʧթ딂z חЅﮃ| ǎݎ{ 뻄ᯈtsv 氌ڰ٠󨂽ѐ н      0 <<꜏ۊNJ$}ϡhldr}xںskyݐٷ:Ӳmiɺٹongı˖ӘإLjïǒzsǜ-`ɱպؼƻ-/ cU !q d l  7J!b;]!;] ;Z;sH( 7͇ }<`t ~0ՠj%¦Ʒ⺯2rȿԟۿ̫дxCkӈ୨Œԋ֏㜜~yQrζtԌߐЅ㎇Y慊nΥԥ㐋ƃ|х 舋fǏ䐌׈։艌Šh姅փ髂ݶozyü~Яΐڧɕ҈ܴjϻ/a:\ :\ :X9* by z{)q~fbggnô Q$ײҲԊ񹆯zƑ޿¼pـ ӻʬ̺Ϡzxڔ`|Jܝ㟖柃˦r{ݘdoܣ|ЊƤѧxoԕ̈́ꪂzoČٌ땀y~t渃ܬsrtJ|⮋֬՝͎~'2ʿ̹,<*< 0: v r t;r p o;p;l⍂΍%Ԁקlpgv}xpz䓃󱂪ཥ;ڸplrqj͹ԜˆڛટOmɴϗ~wТ/cѷ/<0;,>;2<;z;w;x;;1;7;L;|<=OtܶὬ囋䬥鶢v]Ӽ񻐶ƫ×Ͱt֗⳩湭ն鲮*] 3U ƛϠиǻ¬̿ijȇϵn֨ќȧ⿖ϫǞcq{뤙䟐꫑k_vz򵋼MPuzՄ󬆹匜@Eu눂|сቜGHu틁сӃ㋙\Hu~͈ފ듓Msٶw~蚊欥춦w\c͒խǫŗαsҖq¦ؗ䵪黮 عȾ(봰::5 4 (('(ԽҶǭoڔnpvvni̵ķȻy}ɰ|VҚzҤϚƤྔ̨Ɯ[Ɖd߲x衖✍討\ˡpͪx݋륅딗ﳉLϻq۰슀w҂𩃶⊙󷆴A|o캤膀y򬄵߆FtqIbȝ~~с񮉺ሗ󺌷DﷃeBY㢙{Ɇڈ쯓鑐Cuc|噇⪣鳣hW[~ʐҩ񻎳éÕʮ{nǍf~콢ԔⲨ繫г·籮  &]7ڇMrײܺᗈߩ젋嵘t\ηѽ輰췍¨񿔲ɮѺ綁rľѕݯᵪްϲ㮫  2 I ƛϠиǻ¬̿ijȇϵn֨ќȧ⿖ϫǞcq{뤙䟐꫑k_vz򵋼MPuzՄ󬆹匜@Eu눂|сቜGHu틁сӃ㋙\Hu~͈ފ듓Msٶw~蚊欥춦w\c͒խǫŗαsҖq¦ؗ䵪黮 عȾ(봰::5  θ˲èlՒlnsskgȱŸv{ëyUΘwΡʗۺȥšYbڮw㞓ݚ練㦍YŜnȦu؉梃撔ꯇKɷ߫o֬}u΀릁݈?yܴl綠}w|لﶆDqnG_Ú||~뫈ۆ﷊B검c@Vܝxăֆ竐䎎붓Arߜ`𮄪y︍ݧ있䯡fVY||ōͦ繭췌ֿ򾒯ǫxkd{򹀣渞Вݯ⵨ˮҽ󶌭᭪     & Pu߹蛋武칛x_վúõȭŘβuؙ䵫黯ع%뵰::^ ƛϠиǻ¬̿ijȇϵn֨ќȧ⿖ϫǞcq{뤙䟐꫑k_vz򵋼MPuzՄ󬆹匜@Eu눂|сቜGHu틁сӃ㋙\Hu~͈ފ듓Msٶw~蚊欥춦w\c͒խǫŗαsҖq¦ؗ䵪黮 عȾ(봰::%*׿Թ˯pݖoqwwnjϷƹ˽ò{̲~W֜|զќǥ⿖ͪȝ\Nje㵰z뢗䞎ꪐ]̢qЬxߌ򴊻NҾqݱxԂ󫃸勛A~oꇁ{FurJcʟ튀Ѐӂ㉘E󸅇fCY壚|̇܈둒Dvd}皈櫥뵥jX\Ӏ͒իŪĕͰ}oʎg𿤯ז嵪麭ӵĹ(곰::ԸğͮΫӷͰҼʻչ̸͹ɸ«ȼǽľ - - , , +3543 1   Ļ ʴ վ й ė × ×Կøȫй ×˨˫Ǥ̫×ǿϫҵÖҺЫ–ȹԱ!Ȓʳಮ%գƽ꾹%U)'))))ٲμ㮡Ȥ﹬۰˿Ȱйˬ췧׳ٴ︰ش鰠ѷϫ湩е(('?'એmmxu~ᣇrvq|{{࣐|w~让 Ȱ꼦 翥  "¬"5ҷ3ӷ3 忮1 Ը  㶭 Һrx DZit p}򮫩ʹ p|񫠚Ǹ p|𭘋˴p|ﰤ~}~ʸ岯p|w{ήo|䀘ryƵlysv!޶ҩ%ئѶ%??     ױ˺ୠƣ츪ٯ귨ɾ긢Ư͸긢Ӿɫ귨鵦ղ귩ֳ뷪췯ֳ察϶ͪ㷧γ   " ௓onywಧtxs}}| ߰~y貮!϶:¬:ū9Ǫ8Ƭ7Į55ҷ3ӷ3 忮1 Ը  㶭 Һrx DZit p}򮫩ʹ p|񫠚Ǹ p|𭘋˴p|ﰤ~}~ʸ岯p|w{ήo|䀘ryƵlysv!޶ҩ%ئѶ%10ܴϽ0尢ʤ1ܰ11ʱк1̬1ٴ1¦ڵ1ڵ1걠ҸЫ1蹩ѵ1׳ͰԹԵdzʸ έ̭дʯDZ̷ ٽůϴͷʶɴ Ŵ¿ Կ Ի ǻ  ȸ˴Ż޺ࢧκѽึڼӾ̿۹ܺ˽ѿỿ̼͸0   !  ҷ긻׵ߺߺߺӼߺߺо跴ֲཻӺRر ٣{ ٕ ٝ 󬗑 󬓎   㗙Ż޺{ѽؽӾ̿պݺ˽ѿỿ̼͸('    ෿ж跺ִ޹ᄐݹᄐݹᄐݹѻᄐݹ߾ᄐݹ޹μ浳Ա޼Ѻ     ( (ٵ ڦ| ڗ ڟ    㗙Ż޺{ѽؽӾ̿պݺ˽ѿỿ̼͸S((ҷ'빻ٵ' Խ º о 鷵ײ ὼԻ * ͸½ܿĿپƿ۾ܱĿ  ι½ھþٽĿھĿ   θ½ڼ¼స֬ԯۮŮЮﺳ͸½ܿĿپƿ۾ܱĿ      ſ̷˿پ¼׽ýؽĿݾþ       θ½ڼ¼స֬ԯۮŮЮﺳ͸½ܿĿپƿ۾ܱĿθ½ܿĿپƿ۾Ŀθ½ڼ¼స֬ԯۮŮЮﺳ  оӽ Ϭ罾 쯖¸ն ꦆöᆵ 񼄍ŷ屨ʶ 潞ƺޭۯ ϻޯ 巽ķ ˼  Ţ                廉Ӽ ~漽 ىԵ ׈µ ׈Ķ㰨ɵ ׈źܬگ ׈ܮ쾭 ؉¿䶼÷ 㔆ӿʻ 񵆜 ߱       גJ>̘OXVA,)   x`#u}tǃ Lpkm  ӞϽԽ ά羾 쮕¸Զ ꦆ´ョ 񻁊괪%ۥ)us v" >6оӽ )=Ϭ罾 +9쯖¸ն 3Jꦆöᆵ T񼄍ŷ屨ʶ p潞ƺޭۯ pϻޯ k巽ķ 0˼  Ţ   j h d    h m c 2    C[Ḉк |㻼 ՇѴ ӆ꼭 ӆµᯧǴ @"ӆøګخ B"ӆſڭ鼬 E!Ոᴻ !ߒѾɺ _ yܮ w; v5 ~A      גJ>̘OXVA,)   x`#u}tǃ Lpkm  ӞϽԽ ά羾 쮕¸Զ ꦆ´ョ 񻁊괪%ۥ)us v" >6оӽ )=Ϭ罾 +9쯖¸ն 3Jꦆöᆵ T񼄍ŷ屨ʶ p潞ƺޭۯ pϻޯ k巽ķ 0˼  Ţ   j h d   j p e 4    E]轊Խ ~罾 ۉ¸ն ىöᆵ ىŷ屨ʶ B#ىƺޭ۰ C#ىޯ G"ۋ淽ĸ "啇̼  a | ⳛ z<  y6 C      ϽԽ ά羾 쮕¸Զ ꦆ´ョ 񻁊괪%ۥ) 2$ߺ$ˀ$~%퐊ȽƳ돊ӯʾ돊Ůَž돇ȰxٹڍҊՙl~ŀpӈۏ΍gmĝzǛ䔆ԓy푀ֽzȔ䲤븖ύϛ@';$%% ǵդ ~讬w?½Ϻǯ׿sȪ۪ڽ~j𺡾˦jᛅڍӟ̈́䒀ꮘtօφʲɯmt[ਹpύՉnѸཻuŌgDzڃYЎ~fǕ9^|s{R¼ӶяԂxo~ܱ69thH5!<*FRokTƱ~xrњes}E"-%@Ȳn# |\nmț캌Й÷xc- JjiدcO5Ohs||ɥe= )>9[>&Qɴwf`ƙn#UquAۂ 2h v Ó+Cx d٠IDNvD]RY8"aθΧw}zQ)$"8[ D,a3!_5ᳶ5ᖑ57ľ|ݴƟӮν˦ʷ׶š¡ٽѦкϾ K1lLߺpFˀpG~mI퐊~=ȽƳ돊ʛ(ӯʾ돊Ů+'َž돇Ȱx:)ٹڍҊՙl~ŀuv8ӈۏ΍gmĞC yǛ䔆ԓy푀vcֽzȔu䲤븖ύϛpq/=<< < <ҪaM4NfqܧyyĢb< (<8>Y=%Oɴtc^+@•k#U ܡnr@b&ր} &Ykpp s*Au X 8^fdiM՝HBLs Q 'SNMMI [PW7!`˵ͥv|yQ)$"8\ˌrrpxD,a3!_5ᳶ5ᖑ57ľ|ݴƟӮν˦ʷ׶š¡ٽѦкϾ K1lLߺpFˀpG~mI퐊~=ȽƳ돊ʛ(ӯʾ돊Ů+'َž돇Ȱx:)ٹڍҊՙl~ŀuv8ӈۏ΍gmĞC yǛ䔆ԓy푀vcֽzȔu䲤븖ύϛpq/=<< < <*˱nu[䫻rÿя؊oԺG-vȎiʵޅZҏĂg>atu}SĿոԑփyp{UޜqmUȲxs՜gٖ$\ކWpn˜Ӛٞ 7Ŕ~}@ѻ-B e' jss&  [ 8_i_T )WQQP̌rrpx85ᳶ5ᖑ57ľ|ݴƟӮν˦ʷ׶š¡ٽѦкϾ??,*ڷ)~{[y)aUyBU{)~ۼUrUl(̙brZ(i\t\([qôPQIs'FȃmxW`}%,.ζϰθ%Ju%?2)Ns&z`Q$'B"I!S (>s!4֎_?~ NsР\7<#iV ˞m3 8Vz h5T< p$x|@#F0w:\Hd%#tP tG-v `"} ДJ,("!)y# ľRZX98[c>g =$,¿6| ޣx.di8k !諄}P  $<?========+,Ꞿղ){}ںxXެ|v)_SuܔASx){շRnRi(ƕ_nX(fZqY(ߟXnNOGp'Dʆpb^z%+,ˬaw´%HrnYbW*\%=0rGQ4p'Lp\0%w^1qi b"& A !GR &g ]_"W=$,¿6| w+YOޣx.di8k IwK諄}P!]h%|KNk?>OSl*޺*¯}\賁{*cVzCW}*뚀߿VrVm*ϛcs\*j]u].\rŷQRIt*ҌuĈgb*ҳf}˼+s]f[,`,vJU6u+]2(m f( $ ==- r/oaBEo7<!< 73 1 U]  8!πA ]_"Ww+YOIwK  !]h%|KNk?>OSl?? 87vjd4{e3_ښA2Z%[A6"_Uʅ^4v}XKa`Pz$21ݷZ4a !J   !di Ci5%w gWц{(h+ Z2; I\&ҡ7&܏U{Mu ѽR, "ҋ:E(d& (w"* -b/NJ/M7\4ǂ;N4 )ź6\JU;I ;+;쿇;?? 87shb)xb,]Ԗ?0X"Đ\Yݨ@5}*"]Sāu4 [3szUI^ٽwW7&B]Nv#|z9(A10ײX3_̶D<0^ I +( afnuuvs;M |Ao;-̫&_j t et   Um=;<<;=BKLOMM11h'=&0100,D̩a'7A!Mc_^e}X1}J9 GY&.I̝6%ތ9@֋Sx+Kr 7 ͹Q* |Eы:DI'd& dS&w"* p )bp-NJ..M/\+3ǂ;N3 )ź5\JU;I :+;쿇; ;>)̖` ,$ z6 š|[9'D ƀ;*D  վƟG?2c -*rzz{x>P 쮅(cn z  r@>>@DIIE`@(22.GC#Pgdbi#M 1M7R*9)93 8b,t#ӻ/tƏB˴÷Ǻx}αȺ|bkdhѡҚâ俒ʦȚ\dGluꞔ㛊꧋<en|r݆폓򰃷Wr%w{Յ󭆹卝MAӾ@ٺL4\QJ#.R!x0ԥ v]m3LDcϰ,+ɰ ׏~rqͶĸʼñł~ѵ⪝ucԤқƤ㿔̩Ȝ`dy롖䝍꩎g[xwߋ퓗񳈹IL틀wԁ󪂷䉙<@~ؠꇀy~DD峥~~Ӏ󮉼㈗ZE麯z˅܇ﯓ됐Jo{瘇媤봤vZv͑ӪĪĔ˯s؋enyz{𿣮֕嵩麭 ںIJ(鳰::'|}} tԻy'; ҥahX$!g+ MWXTGglW]. kkr7 5 /lxF 97иļR)軐t#JŮBr¶|yȮٰ`16͝˖^"iž۹ޘ߈[Ըڼ^"{ʩsmSܘ㤉aV8:K`{r/ֆ栀厑ꭃEG봄Rr|~܅߈9=xϙVrpG7yفﴃ@A۫I47Sw\({멅ۃT@ನpGՃ橎䑏ڄFj㶪ޢwك(:ߓܤg]hJ80-FqUp~ŋIx=mɸ "L踁nυ`ituvD>֛UD𼲞h^P-/(Q_Ѵݼکm&IYX! "8R*9)93 8b,t#ӻ/tƏB˴÷Ǻx}αȺ|bkdhѡҚâ俒ʦȚ\dGluꞔ㛊꧋<en|r݆폓򰃷Wr%w{Յ󭆹卝MAӾ@ٺL4\QJ#.R!x0ԥ v]m3LDcϰ,+ɰ ׏~rqͶĸʼñł~ѵ⪝ucԤқƤ㿔̩Ȝ`dy롖䝍꩎g[xwߋ퓗񳈹IL틀wԁ󪂷䉙<@~ؠꇀy~DD峥~~Ӏ󮉼㈗ZE麯z˅܇ﯓ됐Jo{瘇媤봤vZv͑ӪĪĔ˯s؋enyz{𿣮֕嵩麭 ںIJ(鳰::>1~)=0l[%"k-kq[`07)1p}I ٿU –y%M̴÷ȻðĀ}ѵⷑd38ԣқŢ㿓̧ț^a#ѯvꠕ䜌ꨍeZ99;;&ӻƏ㟄˴÷Ǻs~αȺ|b̉gѡҚâ俒ʦȚddluꞔ㛊꧋fn|r݆폓򰃷pw{Յ󭆹卝Ӷٺ 0=6/m/.ϥ ɲأҤ㪻Ժﯙ⪻ȭᛞ⪻콢ܕ⪻̵୺쿥⪻컯βﰐ⪻궬дқߥγ ƤƯհҮ!ӺпἸ".300ʥ|D253;s ·R$4:995*l\4++6VomkþC (BHAf>ٯ{ .{; ~h ;͢ `Tưס QFϢ᩹Z?ਹ 0ޙਹٿ꺜`<ʗਹɳު꽣$mਹ鸬ﵪ˰_lߨ紩̱܊\਺¦ﹸ˰]RӝԮϫʠ+TϨϽ߻-)I1 6 m  r"W Om* 3A8a$}}|{)DAA@;m,曡X&))+.0GY>骖ݧs:  /ۘݧ־溮|: J ߫_;ǕݧDZ۩輥K 7u| #kݧ涫봩ʯX^kݧ䳨˰؈\ާ콢츶ɯ [Qћѭͪ ƞ*Rþͧͻݹ ,)H 0 5 l    q!U  Ml 2@~&a$||{z)DAA@;m,曡X&))+8;;;=yXpR!H <% A8'C8 _Y)' @*rU%+7D! ,cOn q.L.T-a;3.%j3;+84}1(778_<:<yXpR!H <% A8'C8 _Y)' @*rU%+7D! ,cOn q.L.T-a;3.%j3;+84}1(778_<:<2FX6P$2FX6P$ ;}E>"IJ Drop ShadowR     yIJyIJy4/,)'  $  !     !$%&&$!  "'+/1220,(#  %,27;>??<83-&    (/7>EJNONKF@91)"  !)1:CLSY]_^ZUME<3*"  !)24+#  !)3=HT_isz~{tkaVJ?5+"   )2=HUamxzocWK?4*"  '13)   %/:FSao|qcVI<1'   !+6BP^l{~paSF9.$  &1=KYhx{l]OA5*!   *6CRaq¹ufWH;0&  "-:HWhx}m^OB6,#  $/72/,*(&$"  "-9GVfw¸wj_TLE@<:86530-)%   )5BQ`oļvkaYRMJHFFECA>:60*$  %03)   %-6>GPW^dhjjhd_XOF<3)!  #*19@GMQUWWVRNG@90(!   &,28=ADEFEB>93-&   !&*.2466530,'"  #%'()(&$!       @@@W  #'*. 7YYYY$%FLager     FF*ɥ r.CPzrn*3                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               8#}>Eqonomize-1.5.3/data/currencies.xml000066400000000000000000000512431416454732000172760ustar00rootroot00000000000000 Eqonomize-1.5.3/data/eqonomize.1000066400000000000000000000023551416454732000165020ustar00rootroot00000000000000.TH EQONOMIZE 1 "7 July 2020" .SH NAME eqonomize \- A personal accounting software .SH SYNOPSIS .B eqonomize .RI [ options ] .RI [ url ] .SH DESCRIPTION Eqonomize! is a cross-platform personal accounting software, with focus on efficiency and ease of use for small households. Eqonomize! provides a complete solution, with bookkeeping by double entry and support for scheduled recurring transactions, security investments, and budgeting. It gives a clear overview of past and present transactions, and development of incomes and expenses, with descriptive tables and charts, as well as an approximation of future account values. .SH OPTIONS .PP .TP 8 .B \-e, \-\-expenses Start with expenses list displayed .PP .TP 8 .B \-i, \-\-incomes Start with incomes list displayed .PP .TP 8 .B \-\-transfers Start with transfers list displayed .PP .TP 8 .B \-s, \-\-sync Synchronize file .PP There are additional general options (not specific for the application) which can be listed with .B \-\-help\-all .SH "SEE ALSO" Full documentation at .I https://eqonomize.github.io/manual/ or in the Help menu .SH BUGS Please report any bugs at .I https://github.com/Eqonomize/eqonomize/issues .SH AUTHORS eqonomize was written by Hanna Knutsson . Eqonomize-1.5.3/data/eqonomize.desktop000066400000000000000000000015351416454732000200120ustar00rootroot00000000000000[Desktop Entry] Name=Eqonomize! GenericName=Personal Accounting GenericName[sv]=Bokföring GenericName[de]=Buchhaltung GenericName[ro]=Contabilitate Personala GenericName[pt_BR]=Contabilidade Pessoal Exec=eqonomize %U Icon=eqonomize Type=Application MimeType=application/x-eqonomize; X-DocPath=eqonomize/index.html Categories=Qt;KDE;Office;Finance; X-KDE-StartupNotify=true #X-DBUS-StartupType=Unique #X-DBUS-ServiceName=eqonomize Terminal=false Comment=Manage your personal finances Comment[sv]=Hantera din privatekonomi Comment[de]=Verwaltung der persönlichen Finanzen Comment[ro]=Gerează finanțele personale Comment[pt_BR]=Gerencia suas finanças pessoais Keywords=Accounting;Household;Bookkeep;Investment;Budget;Income;Expense;Personal;Financial;Planning; Keywords[pt_BR]=Contabilidade;Investimento;Finanças;Orçamento;Despesas;Planejamento;Financeiro; Eqonomize-1.5.3/data/eqonomize.ico000066400000000000000000001412771416454732000171230ustar00rootroot00000000000000 (h h&  v  00'00 %n6 f\( .'746O8cŸ́@BDE'%UU? UU?kuU? uU?iU? U?i? OO  !߃( +'   6  H"#z '303 422($z(! 3<2&/B/8B561# b !":3(E@*!.#,$1&4,9/TPegab_0/WNptpn!!nw(*57}!!qfskul,.''99יMM*)/0&&aa44YYvv%&'(,,,,Î--**++))++88''**67++RRRV--{ڀ----Z_//VVjjTT\\oodevv}}$RFLMN2& "bA5m9*#%eVWY!C0)(><`#>:q0,nHs))++--J`EB>}!s''**--Jי+U#rVV//JKk13' '+"TTJ6z nwpt"vv\\J3 " yÎvvaaMM99:y( @4d14#>H5Y6oh堢,*qrDDDAwwwwwDDDDAʪzDDDDAaDDDDAp DDDA!ʧzDDDA ʪDDDA`DDDADDDAbamDAwzDDA DDAA Aʪʪ ꪪꪪ0쪪ʪ쪪93SUQ5UUS9̪1̪ffffgWWꫀuр( @   Oi$0'(s-P"'A%#1"+ 32,%7=,+69 $) =[3/ ">&/2)@%_59,C(T=9BA6Q[=</E16H1"o@@8H9:J:tF>6I:<>MCBHbINE`$%b&`!, NQO(a,3".b*5%5b0n_fSIRI)*vklt36\RYPswA9dZqxbZvj\kcoeIMse!vkuk$wr|t~s1*ҏy&#1.*##-("1'!1/)%@Cg`!;=+(]W1 2-% .-GL)'23>/:>#,,FM02\c))BHmjɼVRB9Žec`^MHmkZXltVTihpndcpxwu__nmzyhhuuqqxxQ77'#'##.'yuuoouuy^KCCC((C+E!^KHCC((++ClSxMYKCC+C(C0!U3^a_CC+++CCu`jjEDC0000ӜissEECCCC0@ 2t{EEDCC0DhzYHHEEEHXIIIq{KHEHHHhuuuKHHKHHfʼnZKHKK!v՝;wZKoOôd"٦ôsp%ۦŷtmc%驭,뺨1)׫1/𳭳;)}/\9Ѷ&g 9ܹb*$6?R<<]nV68k>- >[TTPNLJGBFWWꫀuр( @ 5rw  Pk@9$   -22!!""""""""""""""##E<3*$! 7KK--++++**54==*+*),,:00&'  5BB00++**B>^X^_i,,5)=33+  4::..&'zQ01@5KAD<# 32255(1,&FL++,,#$1,-.NCYPVM%    2 //[_tuopBD++++,,\Qh_ia&$ "  0 a AB5('++,,g^vmx('$"!"$  1 >>+/ 011100--++,,tjz?4,"(&&&( 2u +"OPPHMHHMHy**,,vrj/$-#+!* ) ," 4DE37ɿ"! &%*+,,0$1%/$.#.#/$ 6TTbdum##(('(qh00?31%1%2&3' 7[[hhGMfg 2 00qg@37) 8ccoonnn((,,{rSG :jjvvyy))*+))**++++,,|soedY <rr~~''++++++++++,,þ~upfcXUJ !>!zz((++++++++++,,_N$>$FF++++++++++,,&Z>< '@'yy++++++++++,,V<9$1)B),,++++++++,,rECS,C,ZZ((++++++,,LӐ>/E/ii88&&++,,A$#[[N r.1E1zz33,,Z22mp dMPfT4G4qq..!1_e.4q ""1W6H6yyllBB{Q#$BHJT7D9FT`p{TZs9J9rreeQQBm?BtvQ  !(0`      ' 3 N  u T"" "}e#sG ""$", A%#($:('+#-'3+* : n'.8%+092+<#$M/4H10(#w%9 )#0=w76I1/u9:&J%+"N9@IC;422>VX1L/PHG3.\>P9:Id $^%@D>3BJ, k+b,3#\UM0c3D>3-~YU:0>j<Z[V^B3|RKGmHvaaRg[nVOqQI>_fVqW]WJFbeVKQHoj{ufjnlpDEaUkdZQtq%&x|bYligmi\|{d`=<pd{ld~y~ukyv'{u!"~tjj푐{;1!`l♗-8) !>946')$⥥%/,"1>6,*$ 2EN:=++TZIF95y{\cXUObSOG>gtELNPU]εdbԲxTQnnwv_^ggppxx >>;@(꪿???????????????_?? ?A@?@??ʊ(0` %$$$$$$$$$$$$$& %$$$$$$$$$$$$$(8x}#w3.v1,    S2<++ys@9NE:1( $ #1'a'SS55,,,,,,,,,,,,**))**,,,,,,%%s81C96,( #!1"]"NN;;,,++++++)*+)LJZZEG#$&%++$$s1*;1/&+#$ 1 [ HH;;,,++++,,<:caj~i[e'&$$s+#5*4*5-( 1[BB66--++()O fv s&9->3A9,$"1Z==11..)) ; %,$~  9 ̬zs*!B7G>NF3+$1Y88..54pMEDy~13,,--+,b-%RX!!s1)LAQGYQ?6&! 1Y33--03MU ""$$,,**))('$$s90UJZQbZME)!#  1X./ldam71.x~#$++++++$$s>7_Td[kd]U,#&" "1Z" %%%"""yti>I)(++++$$sE>g]ndulpi0&(%"! !$1Y12"#" <63PtU eeh ! )(++++++$$sLEoevn}u5+*!'%#"""#&1X>>_\ S(|OUVVVVTTIK12++++$$sSLwmv~G=,"+!(&%%%&( 1Z24HD,%IB>jkllllywnw*+++$$sYSv~e].#-"+!) ( '((+!1]68;  *1,***2D@=?++++$$s`Z~0#0%.#,"+!+!*!*!-#1[MMUU8>3.+SZ)(****++++++**$$sgaJ?0$0%/$.#-#-#-#0%1\RRYXY_.1****++()<7UZ!!smg>2/"1%1%0%0%0%3'1!^!XX]]kj*e4[TOLO>>9: |۷sto]S:..!/"0$3&5)1$^$\\bbkkim5QKJjl+]0θS^!!szvþyg^L@5(7)1&_&bbggppyx9: S   n@?+,$$s|ÿ~qgD61)`)gglluu}}HH((%%y'&++++++$$swypeZ!1+b+llqqzzUU''++,,,,,,++++++++$$swxnoel`& 1.c.rrvvcc&&++++++++++++++++$$syyopfh]cW-'10d0ww{{tt$$++++++++++++++++$$uywpofe\\RUJ)#ve13e3{{''++++++++++++++++$$X         E16f644**++++++++++++++$$ P {v  18g8II((++++++++++++++$$rI31`\L31  1:h:cc&&++++++++++++++$$WYUlh < 1=i=--++++++++++++++$$(I32}y"d 1?j?HH))++++++++++++$$ 率8"!o6 1BkB00++++++++++++$$ ro¿TSb 1DlD99//++**++++$$$B+*A$#Y"E,?  1GlGuuPP99**++$$\ZG c9J 1ImIxxNN**$$tt䥥|79]H;>6 Ӧ("W1 0KnKvvEE""(ؿmnjnp(,/ '3 -P gF 5OoO{{rree$$ɀ;=됒iqCK+3 &&$1-&v  t`RqRvvmmdd44w% Ԏ:>W\_fZbFQ4B0=;H3@9GTbu6; .SpSzzqqhh^^>>cNer {19x{8(*- /VqV~~uullccZZBB 0;ZO/1ztab~ 1XqXyyppgg^^UU@@X03mt3*+F 1[r[}}ttkkbbYYPP<< ! 1YmY{{ssjjbbYYPPHH66c(#=P=7L74L42K2/K/,K,)J)&J&#I# I IHHG;????PNG  IHDR\rf IDATxwGy?{jmـ 4:!$$Ĵ ͐@HP@BPCƦ7p[%˒eIV}Uv3?ffwvvvo{ :=ߧ30hD#шF4hD#шF4hD#шF4hD#шF4hD#шF4hD#шF4hD#шF4hD#шFb0""@. z+sz?^ЃWZAK5z 5t#ʑBdDx4г3z #šB`D9ZlF,PehIR J;r AwöQ(|RIT1~d ;UE#h&}OOX ۰^vXrG!͟ݶ @m}m~mk:UQ~gܸ02KvKz >Y!J{̾}eC5XT_5 M#h\>4,m DB8pq鷿l]AwjEDw2ۿD")kڶ }~g:n,w p>oGWfЈR1NZn^$^q95= 28C!炀/Cv]ו,}C6=^#d*hy 3:Y9'<ou;aFN`b*&-WT|m׬j_v}:F0Dk_VZ6}p7pP!AoMLR[ 1u/)ch|5B W/?>i (""6 EűʱzAx:$x0:}{y)X˰!pq?2]`i #!"(E]V]//9q}#UIU P_P UIEQpDEQDd~aEQ,o=?a}4Xr{ It@̈́s?0Uo:U]j,UmD tᅦ4(a>D1D/h}cgyxqt@RM#v\mu:!t:״F RJ! @ { `iq,{7n7=+gT;Buqz۸klgЉCߘ/gZfHb\q3 ~Aɬnf7u3mG_ rfZdl7͉##$91 $KZ#[/zxvǁ?\=.R-S 3nn.@zM:m}`*ώ)NLѱ0fh@dZ@ 6DhaKKv chgu"qtQtq8BI=c-NX@"!r? z[k R190SO _RJР1;)18PPPyLu^m7E3\*m\~^2;[?4NG;Mck˒38zՓXY'#D&HE%%R*Ҍ*ͻRbi;so$> Hfbq6ct~m8ta!ttY{wo<3ˀ7Gն۟obߎE h|Лf[>0E8 ]AuN1s"N>Ф5#K dxN!@  oH&pvi: 8&Mi> `Z,_|;8< (|_ rQ4orHZ/߿/L#f_dxWQuyڋװləDrPݜG7M562i-mR:$vF7ܧ}l ba4 .9t_91]—e׹@~D0UFbPȫuT2PzJqgla&/"|x.:_J tΛ8'j!.R)Ps{pFMW" D BE >fg'uxymZ-hؘ`.?)a罒ŊV N:%I絙Uw')h8򒗼K.*Mx<޸e}g+,S SULN_a9ORC\o.4ބ揗5jse/ԓlgtJI8c@(FO*]B|t@uњ-4xRs 1; tTL8(%8tP~]nNgyڴb[ޘ(ReXb6W]}6nho(Njг K|O >҄:ظʲЫ?; |ʕx-߅t;H%tf=&X*b @A ݎyuIW*L = D5lalul0I;K|  $mt;}y O|lE .a-g͖-[t:-'psVToB lTсM!2 ) 7Q2=VVמz +R$4`28U͔I#bE@%v&"4*7?9S_g#̞ċ9d{Wt;Ƿ81K4l޼l5WUؐoC>ELxe!;x~T9e۰KLiMhQ* ~P:8܏d-ͤ$I`j}36.PJvqR/QJv X9&kSO#@:G ,ga^Y 5t.}W3>QvށrIlPp@ܡx}%u(.sHZ*KKYD$unP |W3N:}8Gΐ$(?#cVׯ8H;ez qswbvEz.(fg~#S?.R-@Q@\LoULR-5t_uj}LV^'(}S JG:/:E߁ .u4w` p 1,4<?o Xl|9g33{nweoiGt:ZJ']&&f [v0=8_qhЌg@@ÿ́ ab8 )07 >R h3|/E-݄^xex!p9:*$w֟R|*.h4PU.86}uBC7zrE-~Qoᱏk:Svd9 av1E8*S.AXWz_j L~`d̜fK%6`:/{dB_OJ9T n2w c&wCMk ^@ ?ц@]ezȲ$EgҲ!& PEnW~Aٸ]HS!Jb? 8 R*d <-9'h^-1:nl'IÁJAʶm|_(PvY%98Coz&dٙ{&tLN!hlGkX'WH!g>H5ɖ$QB 9Zߒd㶌2sC_1u(%71Ue)8=&E`q;Й|<i$I'F< mH"ԓZ!2-$x{Ž{%ݎZk)Gc(]mع2f;{I)A]JBR&OdZu:qo?C'C՝vO^% o>J\PР;(?@W?m9j-V4O/G>E6'I=̮/\Mm[%&T D8^ʾ/cU<ɩ-R1;9@ 2CLWYGw)B 5ÃUTk";CR6ml3{9F1?,Nsy6/xW$v9Ĉ~Uͤ-SlK7|ُtgٱܳlKLO7yP:zvyq/Y_3B' ߵmPUJPɶzeU6_yFcJ¯bxsƓ}'$BCящ;ֱiXwk@EH%9txk}ccNY4C͢JBљvorA@v hqp*6~v=9B=(\+ke/ ^xUv(jFT>G4c(nN57X $Pw_ ֬y I2E$#4YG(o>GoqԷZɢw$p혼>HgȼYݟ%۲B&l\~e <Wd cvەv+8TLM8 Gb;([Ԗ Dn'~-sJgl\ 4fl~nZu%]:Z·/ _ڙZעl0ǒk4!avu1%rIOU ۮa~N;wbd~X t=C(ykoa5H)YL 9Wx-80껳L 8Q$]kYwu*@DK^R/ XC/D# ?BKx"tߥ QHO0JmzWx*|vo>N{kNM9Urg"gj%DF͏jM7&\wM8R_7~\^c mI# ycvL|ߦsmnwzX;>9R9mC8W)}8tAOhIm}6 ^|իcB)Rir4;+Kfط_16REL]df;ʮ-jhzZRD8` Q]OezPyLg/KM3FOvf \U4CpC&di~UWwqWch. W㏿31+(HfK"_ͷgյoNy  ُ ɩ[Χ!hz"Ogsz.3Cq:Y2Rsyo~o_ӀhAhf@Vџv/O&ѠcnŜ;'|^e|_@A fAY肄 $HT"vP$$WQ#5]@ CmI]t362Zش\ Cz\:f, ]uGN VPN([=Ce>(Ar{TVR7Į.pw@5.To1q94pZC "[n?檨zNB˔!1 $Ty6K6kZ3&dQCb!m8nҗ}$Ic8xq|js釡7IP+3_cu YN;nΌg.i*\y-,_hUV 6lʯ*7' j٪C֡͗J}1tH#lU[d{i!|Xw~$YHl[8o_+Nm~I0Uft]DY1 IDATe Q";\^0dcqIr ??,$&ha ǹ+Wi?cea33z]!k讀g#:B6x>"J:)!gcоWDfPCܥ%#(_v?}%Vt~Cv]dz`v __}^f2_C}#޶\gm ێ.Ot͟oռ388i~SQHVi߭{xR9e?'C~jW3F4d4g l>S嵋Pe3B=eܪ57kך j Ǘq*-= ݡ%KpťmѽyTO +&&\@`iw2^Sh0㷟vP_R$f]?L+,WwȒR )d4\*S,H@'ۢ;oOÔ#fMSaWyO{9q1Q"}2 .}~芻!?F  %>[ U{0h.xASi]w1JR<Vt@)fflƟ$)usW}~ۻ.;##_ezNplzwچ̇`5 ׿%Z\-f*)YF2 l~ ^~8"U!U8?ضm-q茾w7#Me>x_G/d@f6VhUn/`Ѱ` w}A3V~;f^w}J=+19RCH~;Uv?Rk}аt𼔹gfRꧥ}dzZ{~~ƈDfXۦ_''ܖ6 _ZD4,8zkfgIo4#.e’$l tY Tz  Âu-Z|E]m bXXÙg=!v.ٔt0'tr姀%׺-sO&Tj;/_״^gYCI ؔq005g=nwH|1pJnk~(sOқTɒ.{B3 ?xSo KxSɥb̀SN~4>(_EXOй# <*/sZeCW z>Vԥ˄rbаT '^rP|_2A/ E`//~Ѝ@pI#·co;;?qMpFb'Dk#M=}F׿ #.Wu?Ǿ/C6 ;;@\`z:X)v1_r1 U;z3\)4 8߱lxSPUz}* G4r~f/) D"Z@9ge` ;6w-ng@l!"&Y<@8SK}YJ0l>⑎Id΃SUPsy56sw-sah9}iAʰ:@Jt~l!0:ҁ>aRUsжWYX*I$eL쿢oØEcRՆkܻ}Ǘ!eH X8Aozd5 +i}_er rmo`4t7q/W^q,Ra WV<|r}磯. 0 RF0D*sC Q;pu@ImcD<z:D+`"B{~AP?SЦ\3]GɭTx50apF C;ʺ#'rUupϑWYV‹s7Mk7ɚLoW= 8>}"*zD MueRWK8U@>UMQSB>RSdv^F1z3 T}G Ӌjx$L?~/j0H4 ¡ (!vrsnKBB_ݑhHRSIj&O}~ x[rBa_S!o/s8/nISl/rAg; @nOK#=!L)SFu>4OeHA'2Ws&>4pwbU3]LߎdGmTl_ڼ7L) ƀD2" 2J%u2jˤ 0\t}Ub?E&&Yzߡd,.10m-XݞL#'Og4OC6-}N/6&ÝjƯGv  2 DB3d8ҔheH R!@$ٱ(2 FVn883{sMeǂj&Xua}8 |7Th"D wHZ3 4 0_aE.Q(TJ A.j]m{ ڍG ZVGt" . b hPxU-Xes|CzZV1_r R&u0O1zeK~bssܨ>M0%2?5dOfg 3pd>dLJD1kRMT#GuULl \)y }fAZД,MhVIXgW1T}ND&}-IOi*_):cq} xR>e|sW[Jap *`@DX Mn+ M?G-++ afÈXj8 8@䂀cdžRfI{L}.8ZW ւMe=kL+̹BRޕ$Jv3meD`J:͛%-0F`,/헢:\h8 v?pȌY5U3,PW z-&nӧ8++AwN0]΃_+ICiv3aH %w;MN*R1@ ûFG" Bh"2¢x\8>5;Ɏ_a_Nt,1-vFT~LnB%}r; {,uu";X0=" bhu(qI:}.6_W})o9{iL`F\hGHY`G7;]5 ~i]`_ܞp^V礨 In\_Ar4 ;n_Gy)oƖmg2v=f%.P`hL2MLTÓ -N28yJjV>%O%8R>z=@k6Eg.MؙهBkiwZ~3D >sc@-!f! 9% <@*1j3mOJ@D!)RSZh/yU [Cˊ9‡!o&j@B"ˀ2tޭ&ei`Ћ+Wʻ6#]7)&/y`sZ uE8*'),avA "C309)4:+\ϫsnRN@nb#mF_#)!pU]U_z;3$%iA0|(҄"p|`H vM7*K k$~x!l/r)(^-s:Nœ̄hc?|1N4De/u"cn~Fh/_:ܶP9s - ^f3B*ah+R7lʘ,mU!spmo!Pf?MQ; "Lnb&GSiLmv~?*EDRd:\R% HCLdj}̌<@ S٥pZ(iC +@ ~ys+R3ĎQߡ Jt`UHsܕ~U11Y}Pf>Rl0d&Q&d2]};ZA|M0r%z~\ο3)b*#`*KS\8,W3iL5 Hk 4M˃Uͺ Dt`oƜkKpsmx?Aȳ8;Wcchl?G^8n{?( f,[+M݄D& KSPze e̹c c Q#X~ǹ( 8 K5*[><=.:5_e;hN@l\ƴ \FIyM0qQʗ@KycVȽsoZbZw?c|wARS$nكA3H^& s}k 86;ȱH#^:0*o0ϒW-C(Iw^u'~aZ,D 2 : ZunpGʌe6DpnE>)〤s72~n0k_pBPREBdEO7}ya3yMN}$C:@e}7 y@ї+NSp@KZ( &.9Փto Yم3L]}oB|V<(VhV8rJhoi&##)Xn LC:)3>PbvQ[A:KQeYL?un 線APA.HeB%íl& R[oj lӌ~6LU&RQ+$.bSJё5.7u &l|z l<S,G&oιGƌGjZ4k;ϩ (㌳;6_ZX[4ة#񫄸 ӻ99p'T-b͉.B,c3a$1pؤ8KϷx'dX/n#pA\52u=]i-Dݶj{?F͟:gkuNum JWҠ_CivPoÇt@[0{?o0sWy Wsŝ[syᯱ"5ӇSȪ‘D2k.,*u!DEl8"{u2yslWK~6ܩo<⧚: i %_ǎ^~i"],+f/yc,]1ڭQL$ni&vo+^lg?vlWlcK羖}[x#"("rS)RH)IM4ֿҟ߅Lóqװnξ/{ d'Im$|tҐm@]w?[`=IChY.z|FԞWgWO("*s1@(8|OX18 |7p?y>vV@(j16>cG|޳~?%(41i*aD 00q if__֞{5 TcvT/>!S])n==N6H9j$cmj]|9sʪ%si/;d7S%|}NYįi=x"S@0D /(J@H2U?'SТ, $l`mh;N=TR߮~*k)SWUf?g= \[ɞ>{Nzpյ_vj7;iz w5~9-81>#^$.{x3e?qu~ Dmml=2ۼq\eZE |'"& 7>y=u?AxaU8!?yIUz:JD̞Kỗh0MgLsbE2m;h|ηWwEHLHiq||PY`)$UY"YaDt~ $[z=R筊CL?ןȏG} '?!!&&&+þư? `-9$7z"?{Gn6Qr>hmw>+k+rNnȧC}'_ηGO/t|lP/=\_3)-n+>YW?x3/S%!~ӈC}UQ3p?o06=ERyxԏZe?TX.=-Uwv'߰:x x~ʆ%T0}af:;7f~&mW$눒ieZA3ɪCRDg{e?毿v 'Tn+~٥O"~j{iDC=7q<h&+<T}GS(,x >\x<P˼&P+B@,Iu+)E[cy',hяBF IDATݿUD+}>׽6<ҀaX?AǷC JUq?~_;NO yޣ1pAl;%mL.|Xq\T\iszt(Ec8EmK7; Pl&k0]U5r@ @Ref[=>?hm@Unadws ˮ}EOvU>/3@v}ޏ 4c<T9>OC0ֆo]fˆs?')qŕ9g`r`v_ 9ȃ%>#Nlg~Y'KԝKێ?"G(j#|M@%u/iQ汷c" yئxMwBOd~Ud 7'rA@xNMYAfBhmu:=EO<<~~ l S7~_ڡ lNA`aD:(@Bm\ yna"{0ngن?$U KP ~( iv~*)rS|߷#ï.UWe &\e1,ʙ{h5xWVI0!H WiwZKhnЌ~>f*=v3_.^"*6[KK>SGDv`lV]% wbѪU{w|Hs%?[6L NɬOl|ܶ&'!6)K|HϕA_F0J=Dq'gypZ_?gs2:>v'D,dP8[ Ieb=Bt hmW)_ћMVNݥ`cYp\T@|ϠMW2Nu<4*(GKͬ9`jٲa63<, S/ϭg=aUҽJPp:* 4RϼVpKm~w;lv\)=X\d/4TG7a6JT}wϜ, fjSFY/d6򟫴#y>Xǟ!4ԁKQ0h:ߨRKc[y2=nnG.y,L4[apa\6 N#Vz2//@-}5-S vƟ30\ ZG "O[{5?V|剿yi6рo =ssG`3|Xk(a+ 2/)0fT`p{}ۏ~ U"ոqqC\vUAoN!'K<> 8R]s8QYĖ1R]nšFG„OԤ^ϖd^0' 4\(PDyc%!85ߥ^@@|M4̖HLG͋֠ H0lsجE"4l0S"^eZ6ƒfuIjEBatx%]Ei0Rzp$d27nb_"+(~)z n-5lݼ'zL3r w?Eմd)}P=+k\cAP7ʘRlTZ޿aּC=>d.$ro딤*@HܜvmYd>EW 3Va٥T 4d̑z> &)ϵڀuE$0f{ꂟe}_`1~%B  |@؇Bk pJp%o'o. њ'.$o(j>n p&gF ]G@ l:pݤkp_`|s+SE098Dha@3@N`#4ZU+y;]k=#+^SY!L%~Iuwio;_KN 8 cw)瘶J_I^[0ϙ.4(r+:G@q \&H%/e2}qEű/R4cǮ +iv_Z 4|w2s`gx?~wٗwHv_h P("|g(B-tj^'nLxg3L:Sյb| &fHsAnIa*E"aޟSˤ/i^CLAT[l[ YWC$U3$(._/٨s~ \sސgNPj p12mж%_.ί"QOnO2Y"TJ&u.},Rߥ_3 JWYL*Dkg_cr~|6Q45.WG"?2HKPR%(Æf x "c|sI/D04kwg`r&e8۹$+ I))RS -S Q}F&5ͅ#1aV"c+؉g}X @+!5'sx.t[ U<'CWW7y@&$ N5jH];gt_9eZA/!9ǟǵIzofncCX0J@yg"a< mg~(]M!KTJ_u9yڡ8 DH,c0I@K#v{6YKHT8Q> !0ah_sӥ;'@hgalRh`ٽ^)'ξ=_b T|{?hu(@Z$~ޱ-ם곰z/;$B}|rsL{$0P0$Dt_cw+<k(3!j1 *!JKO h7bȦ覚q2dɏ>#gn"P]BYpo@{nz,gH3Ib"1Y 7̝x< ;M(@ȉJRm)v~vq7 2]Sx~ AaL81R]8Q,c̋cv?鶿b:_+U#OР_!e)pԻu] Hr؋kv} q¯׺ֲ7)'>KKآL+5!H][l ~X[?8 yMLxLnE2`PK h>isf$E,:Onq (o׃ӉLqaKի r(~]l"`IbIx٘/g晏y{yz)}i;ءT򺏣@CL"< G'/3a.ҋٝ\5 0nߪ/_3rlfQ)n5\ %KPkI{S! N` 1=پЯ-x@S%Yf/h*lo(ƞFׂC{?Ϸnڝb/d7WƭۦeN4PxW̡gC*Y#IPR` Ex*Bޥ A/o?2Uy:rO (sim@"V,c??]9 m?HE0LI}W=Of2psҿ8B-yM*"9\Σj_wW_o{ުߤ-K `P0}\!@x"D (pMY"?0>8W|ۼPkؚ |Y9_ Th=݋.|}~ x TSo:%v??oata@OBjahBk]D}Ty9R?x/F@dAj& HM9]<qs׾Ϋ~dCnߋ~9ӽ[?]m$twi/S _.a[_7T#B0p LSy'L W}鯒~?d8Yp$ع2ړE]9Wۧ)r Agtw_-A(NFR“YQ7-캁3~Mϫ, /=^G׸%8op&*+$3OuS @>B`m?7w.]>D irܱyuq]껎L-JԋOko yekN-4R$ t'[_5IqqE s~*!.hLaZB$P~ }QA YN@z\(EGsovOqIۦ@r! #l|:bAr4xڕFa\^A!"r3<@ D3P,Km |@t^k/ I|( )8<ua˲}2<ԣW'%tI)D[7):H%Mq ={~kkj"{jb _{k;5Z$QDf~[T.-YDb ($}ޓ==>|n_^q̞׮@IhՖK}!KH҂( D$}%^ PE_Ҁ mZi'Ilvwxؙٙۻ=g~;g&X.ar8x8AH2WOE@b@>)uvx3f>7f.San?:]c}_h\Ee,{K7G~gq#ّ5jx*1IK@0uHF*vVWrE +uXc?b@!`$,(߁>_p0aLr僃~Q)FzZ`MBTM'j!Q@bmtJ ڀRqlǶnXD{ VΣQ݀5t3ĵB؀Xد ~+zLFqޯCY|?s_}Q@(_" Ǡ(~Eۄ!ب*f1Ot(Q $>L&Z!'&O6㖙[qb(|UcG1WveWb8 vi"&JhĶ gGS(T}YaYx^M h/sFd]la݃aӱ[4~X߃{sr2ؔ}{-.j8?0`q-A8"8fR3 9?"NtPCL)=|Y:2uPG~p'e̟‰7_7wYm=s'زe Mk.'/=.2׸K=4y(?L)( v=^y$:}@'~Q̢$m}5:!=9xw1w;vw~ 0Æu vӋqpx1R@g! ` ,Z/!ᾁLtJ| O&7I;P` #zC::_ؙ}g9|f#:rSl26G5j5g b= 2(`,q-4SjV '$PUn47¯/~`.Z3LIDAT:܇/Nއ{ƶa4ЀZ*g>\𘋓tjDX~ӡZ R>$0 |e0m2'ߌQ`$x-WbWvÿ? 8_?!P4H8 x`.s&5%Ni> QAd z)ܣIݶ+fa?Np"I)@I[ 1N}aDa_!\j48L#Uql5Fj}eyV"uI/ C̥Uz5=V!D})=_ϑ#@ hM3B-#ˢFЭgoG (L| _1)7Dh(=i$I5]_&@i_F*+=-Cˁc{(^Σ$p.-3rzM}-9f@.g*d @cD_ߧ>n}0$Jyat:L>"A!&BzUOȋ|Ԙ^ :,e-!S^-/yJˁc^. vrflSikOO%W2m&-^=IN10,x zs/_$%Wd=ḱS|6@+/\6]ԴDʫ^ȍ?ghOUY;_iS^Z(\(Z>DTPU}U NP͟ 6@+ռ,:&UA@9|!=o$_^gu5>0_ {q@LwFz{ v@ kUj Z|Gq=--U,:VsI!8(<^NI岣E%$Q%S+/ksacmcn; *aWm)R0}U;L, ?_G4*oaa%zmbð5lQZx r`c^K876_lwZBp]A[_P N8Zeue,1[L(|_{ |#jw-~=|9ưFfsQCIENDB`Eqonomize-1.5.3/data/eqonomize.xml000066400000000000000000000005621416454732000171400ustar00rootroot00000000000000 Eqonomize! Accounting File Eqonomize! bokföringsfil Eqonomize-1.5.3/data/flags/000077500000000000000000000000001416454732000155015ustar00rootroot00000000000000Eqonomize-1.5.3/data/flags/AED.png000066400000000000000000000011201416454732000165720ustar00rootroot00000000000000PNG  IHDR @ލkgAMA a cHRMz&u0`:pQ<PLTE&&"*EII&"*EII&"*EJJ%*8Ĭݾ$.A$.@$.A%#5&"&!&!:bKGDr + pHYs B(xtIME7"6kIDAT(ϭGPoAAA@ҥ78fs[+p(E iَ Q~Bs=! IDUuQh~a0!F%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:55:18+02:00=tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/AFN.png000066400000000000000000000020661416454732000166170ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<PLTEDDcD  DcD99II@A@@--DcD>.F<6475LB@1DcCuZ6*3-▊ᓈ3,6)uZCaDP?ۀr-%YP⚎㚎YO,%ۀrP?DeEt\ތ}LBU@eT8)N:LBތ}t\EiDn\ᙇ3,QB㩒ڄnE73,ᙇo\DeC3%~baSrm~x}ukf`R~b4%CaD vhޖ`RIHHH^Pߖvh DbD dS鰨圙␍稠dT DcD)).,/.-,Dc6TWbKGDCd pHYs^tIME- Yd-IDAT(c`F&fV0`c:+Ʈ@DTL\BRJZFVNE%eU5u M-ml tt ML-,(wptrvqusǢ? 0(8$ȨظĤd, RR32sr ((*.)-+Ǣ[8O8iӦϘ5f͞3w -^{\,[bk֮[?E(2`%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:45:11+02:00+RtEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/ALL.png000066400000000000000000000024641416454732000166250ustar00rootroot00000000000000PNG  IHDR ]۽gAMA a cHRMz&u0`:pQ<PLTE                      f I I f   uZ ] q11q] Z u tc  Z Z  c t xc   c x |\  \ | |tt| o^ J J ^ o uu::uu ;> > ;  ii   b b        C C       X X          Q/bKGDkj pHYsw0tIME-'ސ?IDAT(c`.`db``b./@PHXDTL\BRJZFVN^CC#cS3s K+k[;{C N.n^>~ CB#"cb1'$&%gdfea(/(,*.)-+PP]S[WYIL6}Ffϙ;o/YlLt+W^v 7m޲u+Uعk8xv`XqSϜ=wK\=5F]q;p?x] <}:r%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:45:06+02:00&ltEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/AMD.png000066400000000000000000000006231416454732000166110ustar00rootroot00000000000000PNG  IHDR .`jgAMA a cHRMz&u0`:pQ<$PLTEM!n431V\gLG4bKGD  pHYs B(xtIME- 72IDATc` %4`\C(HC h 0D axU~1%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:45:12+02:00HatEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/ANG.png000066400000000000000000000017301416454732000166150ustar00rootroot00000000000000PNG  IHDR )3gAMA a cHRMz&u0`:pQ<PLTE+-,++++)~DԖ16/`{0R(}+++)~EEJ-:[ FC0++)~Eim+(}'K7Y)~+EDz툌%++*~8Lj>*~+E<@))(&()'CƲӻ̰t)Yn Qo R1Pj1Pj1Pj1Pj1Pj1Pj0OiKf~ӭͦȓ(L***9ۓՖ|7(***Ib`Ga__usYt,)***(&B3T(**)~DB'** 4bKGD^Ӿ pHYs  tIME6RxIDATc``dbfaevN.n^>`*ER 'UWo`hdlb S`fnaiemckg N.n0^>~A Q1q I) 9yE%eP**kj!wtvuC0q)SM l(`sΛC4i* %tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-30T18:08:54+02:00IENDB`Eqonomize-1.5.3/data/flags/AOA.png000066400000000000000000000021031416454732000166030ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<PLTE&&&&&&&&&&&&&&&="wG"&&&&&&&K!r%&&&&%R!Q!!%V N!&&&&9#9# &e2#&&''&#%st%')%;#''g e+opg h foڪgeg!ӷ{l §3-]P˯z j[ ѳ*$,&% t ZNNCrb yh  F<o n^ % XK~l *$  .(q  bKGDCd pHYs$$P$tIME0dVgIDAT(c`?`dbf#̓S/iQ1q I)iY9y UT54+7042615 # K+k[;{G'g pus1"аȨXC'$&%gdfeaSPQYU]S[W܂MAk[{GgWwOo_L~Nd1BdFY9yE%eU$A5P7@DV``hdlbjfn4UK+k[;{d+#%&$Ho{xzqz%TXYPj(P%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:48:28+02:00*›|tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/ATS.png000066400000000000000000000005711416454732000166410ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<PLTE)9'7CQ.JbKGDo pHYsttfxtIME0"V]*IDATc`D Jh 0P4@`å%1%tEXtdate:create2018-05-17T15:57:56+02:00}%tEXtdate:modify2018-04-27T13:48:34+02:00!tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/AUD.png000066400000000000000000000023141416454732000166200ustar00rootroot00000000000000PNG  IHDR bgAMA a cHRMz&u0`:pQ<bKGD pHYs oytIME0%zIDAT8˅_lUƿst*%UZ[)&Z)5MkK % 4mLHm" CyP 64R^ @)<(4ݙ{S-{d=Kq3vm*͛? M;?P_zԉXSV~UzoN8\PѴ)/ }vᙗo.1;0p@ 0!D@TQQɓ;ZZ>Ԛuԗ{s%X⣟}]gS[Og}ㅃU[>ֶW7tt`yZ|x 0 VcP,49P$,fIzR ϋ"{sftvn&a Bah%AH$,f($yi@aahbbt3t 3?S[Sb?$garI ƣIIJ9E {t/)- 'J@&K^"(m; -a(RӿVk-_idDLG=vl t#1={*D"w%F 8deIqXVq_ YQ'F -0V4& ǩu%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:48:37+02:00 IENDB`Eqonomize-1.5.3/data/flags/AWG.png000066400000000000000000000014151416454732000166260ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<YPLTEAAAB=@AAAAB=bK?AAAABD2㿣k5DAAAB>8V_i7BAAAAAA@AAAAAAAAAAAAAAAAB=M YĽE_0DA(<bKGDr6 XtIME)IDAT(c``dbfaecg88yxq(@VN^AQIYEUM M-m]=}C# ML-,ml+wptrvqus? 0(7BB#"pCtLl\|B"n I)i83L!`&r\!`' B!*5D%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T14:21:41+02:000IENDB`Eqonomize-1.5.3/data/flags/AZN.png000066400000000000000000000012721416454732000166410ustar00rootroot00000000000000PNG  IHDR @ލkgAMA a cHRMz&u0`:pQ<PLTE‘6g6g6f9ipZ8h5f6g6g210]~.XG@ =2143 ?3]/6}H3/6}H3332\-ZIA ?43>E>E=EAHxsbb@G=D>E>EeeebbceeeeCbKGDQi|* pHYs B(xtIME09nߟIDAT(ϵ5ADfq_mqww]"ⅿ> (h2[6;'r{RDHGx"Jg("+|X*W5Cl;EiNjNjNcM2C)A)A:DhNjNbKGDj%b pHYs!8!8E1`tIME04n IDAT(c` 021s&/*&.!)%-#+'E!#'gW7w+EWd!a ""c b$%Z@ZzF&&tA_ !I8.& ?2 K%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:48:52+02:00w+tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/BEF.png000066400000000000000000000005751416454732000166120ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<$PLTEYOBBBBBj<&9)9IibKGD  pHYs$$P$tIME1/IDATc`FeаYaT`Ǐ՞%tEXtdate:create2018-05-17T15:57:57+02:00 |%tEXtdate:modify2018-04-27T13:49:04+02:00@KtEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/BGN.png000066400000000000000000000006211416454732000166140ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<!PLTEZknpLnM&&&H*&bKGDH pHYs&:4tIME1*z.3IDATc`D Jh 0P4@@`(G ha&`XdK%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:49:42+02:00tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/BHD.png000066400000000000000000000013451416454732000166070ustar00rootroot00000000000000PNG  IHDR JgAMA a cHRMz&u0`:pQ<PLTE|3E'$&&&ꛤ9J%&x,>&&ﰷJZ, "$&&镞L\1&&&DT%&ꛤRa3&&줬7H # !%&&r~2E*&&GX%&bKGDH pHYs  tIME03 vIDAT(c`F&fV6vN.tgƥ@DTL\BRJZY9yE%eU\ 54utp)70426153ǥG'gW7wO\ }|p) &n @0$ $p(*0A%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:48:51+02:00׶tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/BIF.png000066400000000000000000000026721416454732000166160ustar00rootroot00000000000000PNG  IHDR ~gAMA a cHRMz&u0`:pQ<bKGD pHYs oytIME1.+7IDAT8˥[LGƿ3geeRX*bژTjV%iy(mcF4)DMDH#m j/%hISIEQve׽>Ry9GZk6m٭qÙR_1b3ej㺩Mnc ]q;( ;i[gf1!i>d*Q5sU 3z/S,’;-cr1(|J!&9@cޡ%ܚ}%woCv7|-iHּAዿʱ "2ARR1q832x>u+{.Pz#.m8qvX`xp AF&bZˋdz;g7'|qծ됫z>1ҽm{|oI!VddpN{*_r;A3֔Z|e&xH3Mn{a16bx4Λ-vlb iNY5[wɁi)7܂I PVD|iC@WqN1H;ά׳2ڸn"!1J .R M R@RCjigSwcBy롧f䶿yRn @# [d^{o(/L . h bx4c sݶy2a_˼;Au)q#1hww@# 4g0%$ߞ%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T14:26:06+02:00IENDB`Eqonomize-1.5.3/data/flags/BND.png000066400000000000000000000021431416454732000166120ustar00rootroot00000000000000PNG  IHDR w}YgAMA a cHRMz&u0`:pQ<bKGD pHYs 7˭tIME1'˓-IDATHǽoUڍc}׎*NGMc" Bl0tС[A #6݆ډ'N!N+JO:Õ{sT Dy_Dt dw iA (5R/@Dʹoя0Nq[BS:PN f* @wL Bo .JU*eD"Bcg|ATVcj+7yC@?hi[WbW)4TyPhxسZpŕA+w E~afA5 r ͏c(~:A]#L :&ylE'j:}~NO݃S~$BEoZtZ ӆ+süfm]fh9E0 ;'˃8`ynα|gO3o+12X>7}`_Yh #} wĦh5]zځ ,+o+^v_uk/xpmltL_M^LEG&2l{>m<4 B>)xw}X?$\d7; ([njnk۲5 FcWuo'4icHI@idc}uطͱ]<v!.]T1@fz|mk+Ǡ0Yƚ}-¡ j㺞1--Y{~[8vÙD6hiԀ0$Lm eziK>[kO6-U$8f&q*6aߦ1R^N)Yi֭Z?չ0=6y[9TV}'7n;*d)cUwEUwk <VROڕ\Z*KDn}[dn(y$_/((V,g9kECYK79nX!PDb S|t-bb%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:49:31+02:002IENDB`Eqonomize-1.5.3/data/flags/BSD.png000066400000000000000000000012651416454732000166230ustar00rootroot00000000000000PNG  IHDR @ލkgAMA a cHRMz&u0`:pQ<PLTE2;Ve#)q:EUe$'L[psrrr ZM̳2@@@@~q!>BBbKGDOnfAI pHYs^tIME07gIDAT(c``dbfae 98yxp*ǥ@BRJZFVN^AQI`PQQUS7@**F&fV@E@{xzyb# x`@ jE(F* b%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:48:55+02:00AtEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/BTC.png000066400000000000000000000030041416454732000166140ustar00rootroot00000000000000PNG  IHDR szzgAMA a cHRMz%u0`:o_FbKGD pHYs  tIME 1!$bIDATXå]lTEoٶlBk h~hcML L&hb ĨHwhz!TB`$@CC6-mgόsv]v|&ݙ3|{lˀ* ǁt }aQ28%#O^"p 8bTOڔy )Lxǿz8ܞ 3=:D )'Wu7mN U~ǎV"3*W mM`80NO0#ɗNݳ qs{T=k9b+`:X똤M5w(wZ .O2gkGD9m6sԛ<"RB:`)l{J Sl'hL%tEXtdate:create2018-05-17T15:56:28+02:00EȲ%tEXtdate:modify2018-04-28T07:49:15+02:00zIENDB`Eqonomize-1.5.3/data/flags/BWP.png000066400000000000000000000005721416454732000166430ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<PLTEus۔歱>݊bKGDaf} pHYs B(xtIME1(IDATc` D Jh 0P4 [0Aw%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:49:30+02:00:EtEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/BYN.png000066400000000000000000000013621416454732000166410ustar00rootroot00000000000000PNG  IHDR @ލkgAMA a cHRMz&u0`:pQ<PLTE秬⒙kt1>1>1>垤⒙dn1>1>䚠魳栦py1>1>䙟魲埥py1>1>_iރhqU`1>1>Ꮦfoރcm1>1>祪᎕㗞s|/<1>髰㗞js1>1>髰㗞js㘞r|-/>߂up[GZGZGfqkIWKWKW睥IWJWJW螥IWJWJW䐘yIWJW䐙IWJW:bKGDV pHYsttfxtIME1 Q\IDAT(}S`?TڶJgs0B2Mf  ‘h 9H(l._@Պrjhhw=T?l4d:/hjٲѡvFϗ덍u<_xQER%tEXtdate:create2018-05-17T15:58:31+02:00羽L%tEXtdate:modify2018-04-27T13:49:09+02:00!RtEXtSoftwarewww.inkscape.org<tEXtTitleFlag of BelarusIENDB`Eqonomize-1.5.3/data/flags/BYR.png000066400000000000000000000013621416454732000166450ustar00rootroot00000000000000PNG  IHDR @ލkgAMA a cHRMz&u0`:pQ<PLTE秬⒙kt1>1>1>垤⒙dn1>1>䚠魳栦py1>1>䙟魲埥py1>1>_iރhqU`1>1>Ꮦfoރcm1>1>祪᎕㗞s|/<1>髰㗞js1>1>髰㗞js㘞r|-/>߂up[GZGZGfqkIWKWKW睥IWJWJW螥IWJWJW䐘yIWJW䐙IWJW:bKGDV pHYsttfxtIME1 Q\IDAT(}S`?TڶJgs0B2Mf  ‘h 9H(l._@Պrjhhw=T?l4d:/hjٲѡvFϗ덍u<_xQER%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:49:09+02:00!RtEXtSoftwarewww.inkscape.org<tEXtTitleFlag of BelarusIENDB`Eqonomize-1.5.3/data/flags/BZD.png000066400000000000000000000026371416454732000166360ustar00rootroot00000000000000PNG  IHDR {gAMA a cHRMz&u0`:pQ<bKGD pHYs oytIME1[IDAT8ˍUYLW>822 3(*uA6jH_tmkmӘM66mj%ڴV"b  2 o0y|g"rR*eY}/_G0T$c (S,I/  c@Ʉ;oKk*Dɉ8Xv~\zBT8Q؞]/=1% \\8P/·HUTe8UkTU?.±6SC_G Hyڱi~@YkSo AM~Wg{+qy_잼b_tj^:]Լ|c+N,5yjK]:z9 FҌнKJej.Y23xA) 1P_֪IOh}f)ZmXXr2IƦv}xf!Y@,| xAF*9K 3V;3I)CvggYW`:cyZ•/vԯ\̲+O2TV93{]\q햣V\b|z$ غ\~[Sht;XU} (@kF?<+6 sIZڗQHQ@l=7kȮZA2kv9!|b7t+# 4e5i Jjus7(p s7labb}ߴݹ; T϶6T;y:ӄ(uߖO ]w%FY]yooxh7ld^7-;<{m 2s|ɦŠ``2lZ_{Hçǀ8جzsKEtj鄡qH3άU%hC"2f%AQ!0MFP6 Mx%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:49:07+02:00qmIENDB`Eqonomize-1.5.3/data/flags/CAD.png000066400000000000000000000017061416454732000166020ustar00rootroot00000000000000PNG  IHDR @ލkgAMA a cHRMz&u0`:pQ<PLTEwwwwRR dd&&dd RRllRRXXss88LLPPPPLL88';bKGDo pHYs&:4tIME15~rIDAT(c`F&fV `cgg,L ^>~A!a D%$edD(WPTRVQUSWVPPo`ghC=/o_??_o/ A!a a!A "cbcc"1!%5-=#3+;'7=-5kHҲʪR\qZS[W'6YYQ2LR%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:49:53+02:00­tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/CDF.png000066400000000000000000000020561416454732000166060ustar00rootroot00000000000000PNG  IHDR S4gAMA a cHRMz&u0`:pQ<bKGD pHYspMBtIME2[e_IDATHǽKlLQΝ;mgV]E=:) .<"b!QJАRB BƂE*L3^ŌVGv=w:m㪡~{ι;GP)%c! X)J>7YBuڛD7УI3dW* ~M4$H؜']4JA8Ee˯fNoUB.@{Y?n? 1܋r?UT`Pȋ2cIA# 2xƎL< 5= ]X:A:iA cúKRfi],:ˎxU҇DgOxWm *ap뭮!J d.7H AsUdB.b4|-b $kK6Bjڷ: 05?*2︄4v@˳`sug"4m㋞7Mx",<=70 ` 8$4,0D 8%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:50:05+02:00ibtEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/CNY.png000066400000000000000000000021341416454732000166400ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<OPLTE))))*))))%*))))))(%*)(,y C&+)))))(2T &+'-N %*))))-I &,(!#e H $*)*$I 0(+&e +))*$T 4'*)("*)))*"E"*)*(O =&)))*"V I b =%*$#k +)))*$#, ()*E1,,()))))**)+*'.W *))))))))))))8.())))))%())))))*)))bKGD  pHYs oytIME2IDAT(c```dbfaece|B"bR2 UT54ut[XZY٣+pptrvqus@W )9%5-=#3+;'7/]AqIiYyEeUuMm]}CcS3ֶή޾ 'M`3fΚ=g .Zd)F@,[bk֮[a[p۶عk\ {?paQ Js~%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:50:02+02:00\{IENDB`Eqonomize-1.5.3/data/flags/COP.png000066400000000000000000000006151416454732000166320ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<!PLTE~U689;-t(&&b)bKGD hV pHYsttfxtIME2u;/IDATc`@ 0(c40BC`(G ha& ,G1#@%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:50:00+02:00QMRtEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/CRC.png000066400000000000000000000006271416454732000166230ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<PLTE+* 5es "&\?`bKGD ٥ pHYs&:4tIME2 9%Qwtgiii+*9L죬Pa+++)+D,!v&&&+++愐ﯷ2+++,\lO`et4*)+,-(,+(+@++++)!6mzlbKGDj pHYspMBtIME2?IDAT(c``dbfae 98yxqA!aQ1q I)AZFVN^AQIYEU `V704 &fV6vN? 0( 0GDFE'$&%Դ̬\\ KJqY!]V^QYU]Sˑu M-8I05"`ߐBE%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:50:23+02:00PtEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/CVE.png000066400000000000000000000020461416454732000166260ustar00rootroot00000000000000PNG  IHDR JgAMA a cHRMz&u0`:pQ<PLTE888888877888887785Wt5Wt87787(O|Rgd:MefMef:Rgd(O|785554(OyWj]8668Wj](Oy45ʀʀĀˀʀʀˀÀhh5G5G5D385D5G5G5D385D5Gcqcqbj_Hbhcqcqbh_HbjcqxxIqIqIqIoMsRvIqIqIqRvMsIoIqIq55544VqpxN8;;8pxN4Vq4587F0Tw9]n]]n]90TwF788778HH8778877bKGDߌ pHYs etIME13GIDAT(c`T,3 +;'73vy^>~A!aQ^ %$edѤ@@YEUM]CSK[GWO_Y 02`;{G'ggW7wO[d>~ F@`Pp2`(#:&6.>0$@bRrJjZzzZFfVvN2`¢⒒Ҳʪ\dP 5u M-m5]=}&N܉5$L6}Y̝:Wt͛`y:e %tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:49:51+02:00Z]tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/CYP.png000066400000000000000000000015441416454732000166460ustar00rootroot00000000000000PNG  IHDR 'gAMA a cHRMz&u0`:pQ<bKGD pHYsttfxtIME2n1.IDATH͖KOSA9\ ZJ@-mM!hbBh_ƅ?[5q!h",4Q[mB/9aʩo7>mfRAS:)_tgY|gAHؘw߭?j z@i7jPLB![bw.<ǒGk8gH/4"kNiu?̡жa({K#%dA6vuimoCI&hf^nGܗ6լ֦4v{p~cOX@xzǰ3 pc̦a"tZ `E았9zY>JM`no)K$ZOIqGR-smPBpl}%'ēDc_f20tWLTcqzlhOQY|L'vy (=&\)0rҋגmt7F0%tEXtdate:create2018-05-17T15:57:58+02:00EB%tEXtdate:modify2018-04-27T13:50:21+02:00mAtEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/CZK.png000066400000000000000000000022071416454732000166370ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<4PLTE^D}4aE~C}IbE~E~E~C|/]E~E~E~C}H]E~E~C|,ZE~E~C}GX|E~E~B|)XE~E~D}FRxE~E~B|&UE~E~D~E~}g艌늍늍E~E~F"Auv,K E~E~EE}G8b1E~E~F%@t{+H E~E~ED}L6`/E~E~F'?s)FE~E~ED|P5^-E~E~F*?q(CE~ED|U4\,E~.>o'AQ5^->bKGDaf} pHYsttfxtIME26FIDAT(c``dbfae 98yxq+å@\BRJZFVN^EE%eU5u M-m ut Mp)P453á@QEO/o_?@ CB#"Pظ$ 9%5-=#3+ʪں2l [Z;:˰*0qRY6L6}YaS >w -^ +`X|U׬]WC 7m޲ `ض}]qʗI+p%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:50:20+02:00tJ/tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/DEM.png000066400000000000000000000006241416454732000166160ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<$PLTEI^(r bKGD  pHYs&:4tIME3I3IDATc`D Jh 0P4@@`(G ha&`XdK%tEXtdate:create2018-05-17T15:57:58+02:00EB%tEXtdate:modify2018-04-27T13:51:19+02:00?c!tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/DJF.png000066400000000000000000000016121416454732000166120ustar00rootroot00000000000000PNG  IHDR 'gAMA a cHRMz&u0`:pQ<bKGD pHYs^tIME2mTIDATHǽMOA j"14r(@?_ī&`$Ѡķ< Z(Bݶp EdoGL!KA&8RRJe\׸M2ダJ)U0r|q",cKy_HY_*&R.,3ǎErddc4G7UQ@F>c6kDT); H Jo_EsL8Uǎ I򥒱TL^q~O&1wZ0@stMc|[uHX䞊YA@60߼C>Ҳ8s&#PxJSi~%I#ڦqLzv@ŲMU=mN&)iY4޹V_O!.G(5DtGp.4z S6quuہcu',az1[QsII4!Tt{h ?8$.}Kt02/}4Um"%%P(Fc<7"gz].ߒtչr>X#Ϙľ&T;a~A!aQnT R2r bAUT54Qswp4G N |!? 0(8$4,0D@@dTtLl\|BbR*`HԴ̬dTE%ey`P&l^Pj#%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:50:26+02:00IENDB`Eqonomize-1.5.3/data/flags/DOP.png000066400000000000000000000013011416454732000166240ustar00rootroot00000000000000PNG  IHDR O}gAMA a cHRMz&u0`:pQ<PLTE-b)_Po\j "&*`']NmZi #5Y2Vu~?PBSݟƮ|¡{x|uկӰ?P~u2VZiNmCubKGDPnL pHYs&:4tIME2HXIDAT(EG؉-vv7NK9"!pE>  (T:U(ʕjN VCFc{2\n\7c OgryqIz~,ܐy(=%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:50:30+02:00JtEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/DZD.png000066400000000000000000000015721416454732000166350ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<PLTEb3a1uLb3b3a1uLb3b3c3b1!sKb3b3b3,Q3m73.:Um腗b3b3`3^=3430@ޏ온b3c3QB344^;2'rLb3[344}14`2sJc38L3442N3b2sJϒmB_c3HF344V3b1xN׺@6_wb2sJϒmB_`2sJ^;2'rL온ÔA#bKGDo pHYsttfxtIME-mIDAT(c`@L,( 98yp*î@\BRJZFVN^AQ eU5u M-m]=}, ML-,ml(wptrvqus? 0(8$4,<"2 ظĤԴ \&dfec5솂¢2n/PW=$ 4JQ.?2%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:45:08+02:00tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/EEK.png000066400000000000000000000006211416454732000166120ustar00rootroot00000000000000PNG  IHDR "|gAMA a cHRMz&u0`:pQ<!PLTEHI.^~bKGD hV pHYsFtIME3mt3IDATc`D Jh 0P4)C`Vj,MjA@~r%tEXtdate:create2018-05-17T15:57:59+02:005!%tEXtdate:modify2018-04-27T13:51:01+02:00-tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/EGP.png000066400000000000000000000013651416454732000166270ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ< PLTE&$$$%$$.@.@.@.@+;,=.@.@.@ҿ޲ؼ`ђАؼ`޲۪ҲIΌ͉ҲI۩נڿiӗӗjנޮҒғޯʫĝĞɪ< bKGD"]e\ pHYsttfxtIME20%5EIDAT(CE߱mul۶m2M% B0$LPH:h2[u{`(b x"Jg\P,+UPFt{بx2ͱ,Wv?`#8/F/~axVt+%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:50:48+02:00> tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/ERN.png000066400000000000000000000016721416454732000166410ustar00rootroot00000000000000PNG  IHDR w}YgAMA a cHRMz&u0`:pQ<bKGD pHYs&:4tIME2*WIDATHǵOIg{& =.`^͋=x2?D;.P0ʰ$:]a8Nա}yzY~l20XSr `;Wd^Qre9Ugf"0[,Fr|BpWv%Ryf̳4|B=ЅKY549o2}$<. ))T 3uAF,RhO@ *~/mt_6_B;%~!; &=DJQDt=0֝Θ|EAPNMœÃQ@@V% a]%9FPY* HQ$Ċn XHE"H[Z^Qv|q+e]^`.+qӯتGN(9!gq}PlVSG2'XXL.'xc1=%Ph=.PdnZ)AtCb+ ~x@X5h?qH{]N{#L(&mx,I |tQBc(eqvc،+4R/~b8[d~ 9'xsr͸؀?%-%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:50:42+02:00RtEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/ESP.png000066400000000000000000000015771416454732000166500ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<PLTE    ғ ͍ߤ ܝXTR ܑO P/`رFˠ ɞJ_CUMʤ̟E" zM]AgINw}Ēo~EԐ% ʖUˏ X J%ThқGٚ( F͘e a(Vn ;ӯ$ Ī* ϫ3ܣͯ$ܶ  ĀtbKGDeh pHYs%%IR$tIME6%,dxIDAT(c`=`$f`aecb `/ ($,DA@L\BRJZFVN^A @(*)khjicWo`hdlbjfU3V.n^>~XGDFEcUٌ̬ܼ¢bpWIiYyEeUuMm]=zH I{jt.aR2%tEXtdate:create2018-05-17T15:57:59+02:005!%tEXtdate:modify2018-04-27T13:54:37+02:00˒EtEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/ETB.png000066400000000000000000000020311416454732000166150ustar00rootroot00000000000000PNG  IHDR @ލkgAMA a cHRMz&u0`:pQ<PLTE0000/..00/3 }H sZ sZ }H000/~F ^LKKL00/ ~E S"RIAfEiI"R3k} CQ1]b|uc|t1]Q C3k}''U?eNohq|c`f~rLnmj/vXu4%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:50:59+02:00T)tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/EUR.png000066400000000000000000000033461416454732000166500ustar00rootroot00000000000000PNG  IHDR {gAMA a cHRMz&u0`:pQ<bKGD pHYs )ItIME,I]^tEXtRaw profile type iptc iptc 28 3842494d040400000000000f1c015a00031b25471c02000002000000 2orNTϢwIDAT8˥U=kQ={3]k2Ŷv&JK6"Z#RB讓lvg̻Fٕjry. p+\ja2352~:~Cd"zʊ;.(+*[V+) BY.VnM +=|yrtaXA(0i5w~;@p7 l( ZA+ARmr|N\Ks w.JiO@hjFDZ8H+VSئ P 6%bnnފܙd[CvLL2[D$3 3zÅ*|ġO~#Ff)V Qz>l5~{v}0]y|-X\_+.NJ( \2D#1&olOl+)d2dz[.T>!5eXIfII*  (1$2iKKAdobe Photoshop CC 2014 (Macintosh)2015:07:06 09:17:090221; (L%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T14:05:44+02:00YtEXtexif:BitsPerSample8, 8, 8>'tEXtexif:ColorSpace655353{n!tEXtexif:DateTime2015:07:06 09:17:09VtEXtexif:ExifImageLength1576#/stEXtexif:ExifImageWidth2363BtEXtexif:ExifOffset224QPItEXtexif:ExifVersion48, 50, 50, 49c tEXtexif:ImageLength800rHtEXtexif:ImageWidth1200dtEXtexif:SamplesPerPixel31tEXtexif:SoftwareAdobe Photoshop CC 2014 (Macintosh)x\IENDB`Eqonomize-1.5.3/data/flags/FIM.png000066400000000000000000000010611416454732000166200ustar00rootroot00000000000000PNG  IHDR O}gAMA a cHRMz&u0`:pQ<PLTEC455;C45;C45;NsOs?g95579bOt2~2~2~55553~2~3gbKGDH pHYs : :dJtIME25U_jIDAT(c`F&fV6vN`@pA7/+`Q1qV I)ia4 r J*2hA54YutU+@XA+:7 `MB G%tEXtdate:create2018-05-17T15:58:00+02:00F%tEXtdate:modify2018-04-27T13:50:53+02:00YYtEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/FJD.png000066400000000000000000000023361416454732000166160ustar00rootroot00000000000000PNG  IHDR w}YgAMA a cHRMz&u0`:pQ<bKGD pHYs&:4tIME29\3IDATHǵMlTU潙73-)4-XЂ h`w&,taƅ_]B+ݐ1$,,D5lVhmigNg޻.~ m!Nι9w3ã8}nw&Ͼ7=t8mm:ZZGZ9hՐ@pwugG9mkinmb4f?Uԣ岼X+%XN!0]^@E=>q=wqc<~^\G&:i&2tBd>(AF?OJ!DR@b Cs=|GHKB)& bO4rCYBsPB!MUpK)o\ I `]71 .Xn@x۫a lgoZ"W7BOE7;xoҊi\ ti#j ~ HgjFgz!/->+C˟y%~tGOMtc&FKؾ]WxW*vi>1]osEK>}Qd5͡Y.23`$&LSlްwnṶ6 q< a  . E#ZuUN6o|uYyRcI.W@Ŵ4(s$uLP},Ӡ2Q7o~:K>[Nb0 KdpC+r9I!pE(m- AQs7:0%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:50:57+02:00}tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/FKP.png000066400000000000000000000023551416454732000166340ustar00rootroot00000000000000PNG  IHDR bgAMA a cHRMz&u0`:pQ<bKGDtIME!~rIDAT8˥TMlTU=߽y3CqR .j 6&L‚(FD,pA$dVbbIjVEK `-Lg{*;,{s٦؂wz|붖δ 8{4.vU6F<33!D +:iK_ǖG76_ξΩGDd" W*px,afh `6)g7pXxrq`oH?ұ`cSK>9t~ԱBF8#DZ}eJN6)OrAמ@Z 2&SD VĕeT,ܒ|Abn%)i -, ${ڥ8n^ |n) |` qs2gģڱ*Tҭ^36{d/MSKݶD]So>6FLWΟ2*_ 0? j;;g p'z1xkӲ猺{]ʿߧV^9qlu=ɏv{v Kv#fc'wwt'SMjDHAo_ ;[J,1u5K{i'G[nQ31 ^^vL_iVjICë=a4J*+'cf4%xD\nRsF24ANR9TW=F;\gun}_[jB3!OCk |_$2<:%`1`!1L97Uq VBNr(BvSi@E@!EnZXyx=yt8Ԙ&+WVQ6 r"6ML^Tt&VoXT??edNOcgE7we.O[4}{:ZE _Qաx24xY3u]Ҕf[aࣚt Md 1#+52#5tݦ.D<*MpTO N=z~g]IC[k44Sޫj]es^mRAIWUaCf%MVD~츠a/tOؤ/GtO]6(?khqo>p@` p6kMCo1Ơ2zmi/Ī ֣6iäqƖ_75ZOAQSa8JVC%)UuESgWdž覇) =dY8N+ ^ϭFA P(*pn*xx`jAUA(Ƙa0*Xo1RP ܧ0>^j0"!CQ@m Ȓ#z!Da(yΠ!^I$LD|mO,Cr4CziqOv&2]8znݡ 3E?ː&O(1[C yN5KKzԒW%~vԶ<|>t^__SOLbi9Ѷ╖w~}AYs~XnѫS#5TWGnKH?|\5<94ϱ1׵ݓ2}[XyjʔF7(Ą/f|Tʛ2&n5%6iP*xp_aC.Ӫf 9ZVlYs\ݴ蓲jvL "\O RJ^8':#jA߳BQ%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:55:16+02:00IENDB`Eqonomize-1.5.3/data/flags/GEL.png000066400000000000000000000017271416454732000166250ustar00rootroot00000000000000PNG  IHDR {gAMA a cHRMz&u0`:pQ<bKGD pHYs oytIME3cIDAT8˵U=hSQν)m0ZJEDG@ RЂH$]tj)nJE1C.* 6HcMB޻:$%1[<;pw~Hk|\Ѕ-'ޢTaZ ZCãXA*Ev*HNf 8.%O%F'r讪H̿>|R{q0ux$%2˯VS%b2>HeV4V,]?Ugr+M3)wݝE-̐M U@@f9(; ,YtÓTR Z)R>CL7^i;iQ*T;-BEj@>;$ERR )IPiirA&sjwMh)AT@M٬SÇJj]g#Wk^9젱_ G>aX_S]w@)R3Tb(^bEt$ J%0!SK`^dJR^`,|)9>CaKkc33(ws+{Z).J%Wng,ED>%m_yn$"d^k"h#1ܙ;# ng߾N:*/YLLE l1BSP%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:51:04+02:00IENDB`Eqonomize-1.5.3/data/flags/GGP.png000066400000000000000000000025601416454732000166270ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<PLTE`s 00 `sbs!22!bs[t/g'g'/[t[tas  as_s  _scvWh!.-.-./////.///.-.--, -&*W%[$Z$Z$Z%[%Z$[$W%&* -,...,,.., -&*W%[$Z$Z$[$W%&* -,-.-./////.-.-_s  _sas  as[t[t[t/g'g'/bs!22!bs`s 00 `sĐbKGDHtIME&[IDAT(c`F&fV6vN.&Fl_@PHXQ1q I)iY9 UT5p(704BV` &fV6&Q;wptrvquspwsK1@@`PpHhXxDdTTdDxXtLl\|X!SR32sr2s R % PZV^QYU]S[W__W[bhή޾ 'M8oӦKAL9kLXp%KAL[|U׬a 7m-[m߱]ݷ h889 á@^y=L>~iZ2%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T14:38:06+02:00lIENDB`Eqonomize-1.5.3/data/flags/GHS.png000066400000000000000000000014421416454732000166310ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<>PLTE&&&&&&($($'$'$($ʕl[ n ѭ #/'۵kY {f WHcR >3WGSDB6wսӼvw:w:t:x:x:x:x:t:w:j?j?j?j?j?j?j?j?j?k?dAobKGDikĴ pHYs$$P$tIME3#+IDAT(c` 010vN.Tnd/ " "bR2rQy8PPTRVQUSF")70426153ǪI pusAcE~A!b aH <"2*:&6Y! $$&%#1dA}$FU%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:51:22+02:00)08tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/GIP.png000066400000000000000000000023031416454732000166240ustar00rootroot00000000000000PNG  IHDR @ލkgAMA a cHRMz&u0`:pQ<PLTEՖՖej+2txtx+2ejy~紷紷y~IV V I֟"ZIQ}}IQZ"֟           7<77sxPWFM-9#~A!a> cbSR32YP_PXT\RZV^QYgںƦֶήn8CO8iӦϘ9k8\(7E,]|U׬36nڼe;vڽg>8~8p#G?qI$8us/\DCQp׮@: 4%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T14:36:39+02:00 >IENDB`Eqonomize-1.5.3/data/flags/GMD.png000066400000000000000000000007231416454732000166200ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<'PLTE$/ACQDPRB8v&&  :w(/tRNSsѳbKGD Qc pHYs^tIME3j7IDATc@ hA 0haTBC`(G 5śq6O%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:51:05+02:004 tEXtSoftwarewww.inkscape.org<tEXtTitleFlag of The GambiaGHIENDB`Eqonomize-1.5.3/data/flags/GNF.png000066400000000000000000000005741416454732000166270ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<$PLTE&&U YFa`FebKGD  pHYs$$P$tIME3 ,IDATc`FeаYaTkcv%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:51:24+02:00tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/GRD.png000066400000000000000000000015721416454732000166300ustar00rootroot00000000000000PNG  IHDR 'gAMA a cHRMz&u0`:pQ<bKGD pHYsQ'tIME3N52DIDATHŕKTQg1CRӁ҈Zi)*ej&mڵkmZBEAP9m*(E}` =-8$ 57{}s4PNrݱOyUELD&P5xI2e!%MaZ\WqzBzQPB+!88(ˑ[ع1U;plƔ6ќcs F'W\8TU|}Gs<}3Idj"p؎`5Ks.R Y[e5А8_r>i藐'm<5JkS֦,S31o'~(~$:/Cv_{^2Yvӆ { /%AᢊNTWA=C ک]bT죗_IuFAPU\P'?cR دv_Xk%tEXtdate:create2018-05-17T15:58:01+02:00i1%tEXtdate:modify2018-04-27T13:51:18+02:00htEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/GTQ.png000066400000000000000000000014601416454732000166430ustar00rootroot00000000000000PNG  IHDR O}gAMA a cHRMz&u0`:pQ<8PLTEIFϊί㰿ҙѳ¥ʺȮߗݿƪԱ޷ԨȦΙxӦϵ~!bKGDo pHYs'SstIME3@TIDAT(c`F&fV0`afbdC;'7/B"b8HJI+(*PC9vV6v8Lprvqusơ? 0(8$Ȩظx\!>c,?%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:51:16+02:00tEXtSoftwarewww.inkscape.org<tEXtTitleFlag of GuatemalaYIENDB`Eqonomize-1.5.3/data/flags/GYD.png000066400000000000000000000023161416454732000166340ustar00rootroot00000000000000PNG  IHDR JgAMA a cHRMz&u0`:pQ<yPLTE)=2_|V!cLFGIIIIn:!sytбܰcđ*k QGGHIII& W@-Eށ쬹z̟=xXIFHIII&&& @ SB£=o巒ԫRbMFGHII&&&'$x6s`ܷ0\質ܳiƕ/o SGFHIII&&&&![;% $J}驿ⷁϣC|[JFGIII&&&& C N>:j淙׮Y$fNFGHIII&&'$}7m[ ش,W鱰޵pə5rUHFHI&&&&"`;"{ "Ex㶈УI}]N&&'&o o VKbKGDخ pHYs!8!8E1`tIME3 !dIDAT(c``dbfaec yxED%(WPTRVQUSDWo`hdlbjfnaiemc? 0(8$.,<"2*:&6.>!1)9%5-=#3+;'7.ήIL6}Y̝7E ,]|U׬]~Mlݶ}]ݷC=v'O>s 5P8 IqA06 B) N%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:51:32+02:000tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/HKD.png000066400000000000000000000015611416454732000166200ustar00rootroot00000000000000PNG  IHDR {gAMA a cHRMz&u0`:pQ<bKGDtIME8V|aVuIDAT8˵MHTQ9ysf7B 8`&BDDU6R6eD@C( Hv@jǢZ  mty㼙q{U4js֗8s..Pˢ@LY"^4}f$?D͌t Nr 572 9lÅoHk밗NrMd3@["}8z2#FEE&w=N 3UP:H" ^኷ +k>+2Attt|y:~^bg "pu {y1p903> ofĪ|@mi[yKaMFD5NfaU535n=BE"IsK.e]K6"f8?QuQ}Y̹73J̐X&X1&-t`Ҵz56hvaewumHYJB1 ݝG%/H/|Z>?†似BÂ$rK9.M;t؜I#_]I/'pt\; u"8N9f(9gtЧo5nRVz!%**(ǬYef[5@X5:=߲E=S,w%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T14:15:56+02:00ȒIENDB`Eqonomize-1.5.3/data/flags/HNL.png000066400000000000000000000014161416454732000166320ustar00rootroot00000000000000PNG  IHDR @ލkgAMA a cHRMz&u0`:pQ<,PLTEsstttttttttϥtttttttobKGD'-# pHYs&:4tIME3畽IDAT(c`=`$``b 3p/8\A$edUT 0o`hdlb F(03wpt2C(аȨ#OH1c$P 6f%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:51:26+02:00Gf+tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/HRK.png000066400000000000000000000017601416454732000166370ustar00rootroot00000000000000PNG  IHDR @ލkgAMA a cHRMz&u0`:pQ<PLTE$4@NATC'VlGwX[qCRFsOqUeAV?'_Hi{Pqy=h{k4?GP~PQPQ|HQ[[xxxx\[SSSSKKrrssKKqqqqڭڬҮsqsrүǬح9#fqgq9#=(=(ƎbKGDPnL pHYs B(xtIME2 z0͟IDAT(c`@L,l '7/V"bR2rHpeЁ]=}C#cS3s (%XY;8:9X!D\I!CB#"D'$&% +HE̬ܼ|$A(,*.)-+BdFںƦV$A6h럀$0 L~AN ED%$E@FVN^AQIYEIA 54ut  Il]\ݐ{xzyPCV0N+5%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:51:28+02:00YovtEXtSoftwarewww.inkscape.org<tEXtTitleFlag of HaitiIENDB`Eqonomize-1.5.3/data/flags/HUF.png000066400000000000000000000006201416454732000166270ustar00rootroot00000000000000PNG  IHDR .`jgAMA a cHRMz&u0`:pQ<!PLTE&&'RQQ^bKGDo pHYs B(xtIME3*L2IDATc` %4`\C(HC h 0D axU~1%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:51:42+02:00uF9tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/IDR.png000066400000000000000000000005501416454732000166250ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<PLTE&#爓%hbKGDhQ pHYs B(xtIME3&IDATc`@ 0(c46,_j%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:51:38+02:00otEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/IEP.png000066400000000000000000000005701416454732000166260ustar00rootroot00000000000000PNG  IHDR .`jgAMA a cHRMz&u0`:pQ<!PLTEHEZZwybKGDo pHYs B(xtIME3/&y#IDATc`FeаYad }R1;%tEXtdate:create2018-05-17T15:58:02+02:00X٠2%tEXtdate:modify2018-04-27T13:51:47+02:00'~tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/ILS.png000066400000000000000000000012221416454732000166330ustar00rootroot00000000000000PNG  IHDR ]۽gAMA a cHRMz&u0`:pQ<PLTE7c55IqIqJrJrqq?i?iɰ@jGp%UJrJr%UGp@j;fss;fȅNNGbKGDi pHYs**ˆ>tIME35LDYIDAT(c`  &``!XQ;'2BbA!aQ1qa!A(HJI+HKI"D(*)khj))bUo`hdlbUy&t_ !I0.&@0ELWj$q %tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:51:53+02:002tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/INR.png000066400000000000000000000012361416454732000166410ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<PLTE31LLLLMǺǺӳݳݞԽː˽ԳNNNNܤԽː˽Ե޵ޠתƪ/$/$/$0%2&uGibKGDi pHYs N Nw#tIME3%Q=IDAT(@DѧdL`A% r kzT8$˒( jzhꚊ"lw4P!C5Olq=:{e@hXÆ n8E83q^{(,< Su%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:51:37+02:00-tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/IQD.png000066400000000000000000000020641416454732000166260ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<PLTE$.@.@.A.A.@.@.@.A.@.@.@ެz &ԸȽӾu}shuut僾kffpdçPzS|^ho[tRNSW˂bKGD\ pHYsttfxtIME31K)D@IDAT(c&YX98

R6gW) D}YIFim.=NdgCW 9kb3ot{jxM%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:51:35+02:00$(tEXtSoftwarewww.inkscape.org<tEXtTitleFlag of IranI IENDB`Eqonomize-1.5.3/data/flags/ISK.png000066400000000000000000000011351416454732000166350ustar00rootroot00000000000000PNG  IHDR ]۽gAMA a cHRMz&u0`:pQ<PLTE86%Uee!!_^+Z664"See_^)X4'W%UFoee!!^^Ks%Ubb""\\bbbbbb``88&&66__bbbb!!!!""&&((&&""!!DbKGD9@ pHYstIME3(/BrIDAT(c`F&fV6vN`+n^>V~A!.4 "bR2hAUTd:hhjiC(0261530DM  !h"?7'%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:51:40+02:00(tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/ITL.png000066400000000000000000000005711416454732000166420ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<!PLTEFCZv~'4+7 _bKGDo pHYs  tIME33'%lIDATc`FeаYaTkcv%tEXtdate:create2018-05-17T15:58:02+02:00X٠2%tEXtdate:modify2018-04-27T13:51:51+02:00#tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/JMD.png000066400000000000000000000014671416454732000166310ustar00rootroot00000000000000PNG  IHDR bgAMA a cHRMz&u0`:pQ<bKGD pHYs oytIME3;^&IDAT8˥JQGwo*Ƙѝ-]B$.E ݵ 54\>F(d"I".&):I &3 &&zWp9gsH6\lgЁn#$+B9#ߺNW=/`y3I%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:51:59+02:00mIENDB`Eqonomize-1.5.3/data/flags/JOD.png000066400000000000000000000021541416454732000166250ustar00rootroot00000000000000PNG  IHDR @ލkgAMA a cHRMz&u0`:pQ<(PLTE G &$ = &&'% > &&&&'% > &&> &&&&&&$$]c&&''&&&&3]k&)r~es&&&&%#.Ud&)zly'&&&)(&&&&&2Zj&&&&&&&&54yDzӽѻккк&&&'0->[6 w=~A{>{>{>{>&'0->[6v<|=z=z=z=z=&&>[6v<|=z=z=z=z=&'1-=[6v<|=z=z=z=*+GV5 v<|=z=z=z=w bKGDaL pHYs B(xtIME3:IDAT(c``dbfaec88yxp)Ʈ@FVN^AQIYEUM]C0jiM704B@&f V6v]? DDFE'$Դt< 22sr KJ+PPAeUuMm]}CcSsKk[{*y3IΩuӦϘ9k0@ -^trlaU׬]~ra[n۾#Y{,%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:51:58+02:00fotEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/JPY.png000066400000000000000000000012741416454732000166550ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<PLTE鬻fEff鬻Nm2)*)2Nm7[*------*i*---B,-,B骹/--/骹䘪,--,䘪nbKGDH pHYsttfxtIME4̿IDAT(c`*`dbfaafb!ƊM_@PHHXD1q I)iY9y q1LyE%eU5u M-me%E :zF@`h -,1XA5'gW7w'M  Cp\ML!2%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:52:03+02:00LtEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/KES.png000066400000000000000000000020321416454732000166260ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<PLTE!!!...k!!jjjqqqYbbbbYqqqjjjbbbbcc6666L^^^^L<<ssLLababbd6767bdabͫͫͫб  бhhg'w(0y/Z3bbbbZ30y/'w(gfff1x1i _kR!ffffffeffffff@bKGDgJ pHYsttfxtIME4"+IDAT(c` 021hf&F X9889X*F!aQ1qq Ia!(H+(*)H#DT@M]CSK[GWO_] !`F&fFH `emckg$n^>H CBp(nuavvQ1nCĤԴ $AL8/(,*B2AiYyEeUuMm]})B[ZZ[ pفER?aɓ'M߇Uv@P}#]G%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:52:01+02:00+ӖtEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/KGS.png000066400000000000000000000022421416454732000166330ustar00rootroot00000000000000PNG  IHDR JgAMA a cHRMz&u0`:pQ<dPLTE-------------,,-------,*(F"VWG",(,-----,?$s uB#,----9%~ <$----*c l||k f *----.'G"E" 1'----4& |rq{ 8%----.'bcf]1'----*d W W h!*----;%  >$----,B#v xD#+-----,-'I"ZZJ!.',--------,,,------------bKGD˄p pHYs&:4tIME4 c;IDAT(c`*`dbfaec%/ (UZXDTL\BRJZFVN^E%eU5u M-m]=, ML-,m0m]\=<}0GDFE`(OHLJNIMKP_PXT\RZV^QYU]ӕ}&NŰv‰†tʿƲ!?#%$7Ʈǰ8$%#+G¯ð,H#%$2ߨߨ2$"ZoZo44+SEi?c<`DhDh>b>bDhDh<`?cEi((&%%%%%%%%%%%%=hDbKGDP6 pHYspMBtIME19wĮIDAT(c`=`$P3 +;pprq  #DD@TL\BRJZFVN^!ʠJ*jZ:zpaC#cS3s K+k[, ]\=<1GDF`(OHLJNIMKȌFW_PXT\RZV^QSMUuMm]}CcSsKk[{Ggư0q)SM (hΜ5{y,\xegϚ jE{ M|%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:49:57+02:009tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/KMF.png000066400000000000000000000025021416454732000166230ustar00rootroot00000000000000PNG  IHDR JgAMA a cHRMz&u0`:pQ<PLTEu-и#<3P1) =3<3<3b/&=3=3=3;3B2z,ӹ#=3<2:0>5A;N2*Ga____=3<2C:xЫUM=4^Qҫ<2E;ΧVNE;:1@7vo:0ͥ=3B8TK?5=3=3:0JAB9kc9/PGE;=3=3=3<2;1[RѫJ@ZR;1B9TK?5=3=3=3:1A5f刑爓爓9/PGE;=3=3=3<3<3S{1D+$ ###=3B8TK?5=3=3;3G2|W-"(&&&&&VNE;;2@3hi/0)&&&&&ЫVL>3S{4D/*)***<2:0?4D8=@IDAT(c``dbfae 98yxp*ǥ@BRJZFVN^AQI`PQUS7 F&fV6v? 0GDFE'$&%Դ̬ܼ¢2P^QYU]S[W/!֎&ttvuO8iP g̜5{y,\xRŲ+VZf6nBpؼe;vڽg/:|'NbSϜ=wK` W]q;wa <|gp)xoA*%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:50:14+02:00itEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/KPW.png000066400000000000000000000014721416454732000166540ustar00rootroot00000000000000PNG  IHDR @ލkgAMA a cHRMz&u0`:pQ<PPLTEOM[~[~[~[~[~FOFOFOENBLDMBLDMFOFO$%#)4kr{=F#$$''&5?[c%'''@I,6&&(3|1;('2X`PX$&'1U] +5OX$'&X`~R[-7&'&5?Zb%'#)4mt=G#$FOENBLCLBLDMFOFOyg+bKGDoUa pHYs a aJ%tIME5 EIDAT(c`  &`faec `/@HXDTL\BRJZ 0Ȁ (704®;{G'gW7w <}|+ Pf|BbRrJj7P`d[1*T)%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:53:12+02:009StEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/KRW.png000066400000000000000000000025371416454732000166610ustar00rootroot00000000000000PNG  IHDR 'gAMA a cHRMz&u0`:pQ<bKGD pHYsttfxtIME6t(iIDATHŖMH\WcQ_ϏqjTvhƂ1tBPҖ4 nhDp.,]JFE51~FęqTyo^00\{Ϲ?ϹG0M .1եO_NuzQUfv>p8LGG \$屼LSSuuuiOOO322`MMMMRۤ)x^988`qq4 L8wyP4{{{E z$Ǵ@5>$NjIfUyMQ ܺum4McffUU ܻwQSD"Ȳ(hh=?s4g$o\lsrss}6wEUULDe"'uuuu%XVjkkbuuMKK g^`ADG8%A*4McccP(DKK dggKp8P^bIJѩdX D"PVVZ,D<(`$f(EVq}y( HM qN +n`6.i^Gr9]l?g'`b Dse+cjK1W75Aw.d்灔ΦYN]\_x3?-T\]%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:54:24+02:006FtEXtSoftwarewww.inkscape.org<tEXtTitleFlag of South KoreaNIENDB`Eqonomize-1.5.3/data/flags/KWD.png000066400000000000000000000015251416454732000166370ustar00rootroot00000000000000PNG  IHDR @ލkgAMA a cHRMz&u0`:pQ<bPLTE(d2|>z=z=z=z= M'w;{>z=z=-g4{>z=z= M&w;{>z=z=z=-g4{>{>{>&Ѽк2ؗדּL ''' %&&&&L &&&&&  %&&&D &&&v0mbKGD=mQY pHYs B(xtIME4 \IDAT(c``dbfae 98yxq+eV(ja &fXD-V@;{G'g+*  B#"cbĤԴL!+;'7/ `(,*.)) ɟsMb6%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:52:12+02:00֑tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/KYD.png000066400000000000000000000023371416454732000166430ustar00rootroot00000000000000PNG  IHDR bgAMA a cHRMz&u0`:pQ<bKGDtIME:ٝAIDAT8˥T[lTU]ss/:łE( ) Q& >DM ~`b*?FD1hQI}J`K)j<<=g1!Z{CY~bkыDfӮoыj߬{:Y St4m_>q}d*GD~_mc˟lM>Е%R\DOk6= v=bW?4\7ߵ\1?p'.Z.AiV"e`R{=ts]3j%w')k h MK-I𒪤7^4k5e>W}OƮ c=g}EGU宱mWc., ynٳP ~~B'S*yBCݷD?u vLF`YvM?_P[۳jዳkNiHc-GlS8kH5j:B*%YJ::7R?yRxŠ)gvPIpa&6Dhf0"I`KHs6vm1>#ܼ?2>P,1u5L5DtC$~n._9OopܶĨ'9W`%%UbtiY$h؝ngh؜:D  ehrVl#;A0E,%\7w0_@D@;Gy?%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T14:28:58+02:00^~IENDB`Eqonomize-1.5.3/data/flags/KZT.png000066400000000000000000000024701416454732000166620ustar00rootroot00000000000000PNG  IHDR @ލkgAMA a cHRMz&u0`:pQ<PLTEyojz\i wqg} %-~lowRh\pv6eyp >W *pv rubU/ [-a{n:MK? h8^a{n_\8pv?.VQXEru Y79PVH3H_eyp '&*?>6%A~l N:OU wqg}2-\iyojzbKGD_Ϧ pHYs^tIME-^ f41IDAT(c``dbfa 98|n^>~B"0,9yE%(GYEUM]CSK[I!cdlbjfnaiemP`kga;9{xzy!aQ1q pI)i`fzFfVvNn^~AaQq \AiYyE%YU]S[W֎# 0q)SMW0s9GΝ7E,]|Up诅zs 7m޲u;w޳w,8xǎ8SϜ=瞿p+W!7ow޻iQo4%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:45:15+02:000dvtEXtSoftwarewww.inkscape.org<tEXtTitleFlag of KazakhstancIENDB`Eqonomize-1.5.3/data/flags/LAK.png000066400000000000000000000010771416454732000166230ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<~PLTE&&'''';!U;!U;!U: T8S<"U(i(i(i'h>xi(h(h&g*L'h 0m%f3S%fIf7bKGD% pHYs^tIME4[mZIDAT(ϵ 0 EޫYWd+(x$$EUT@e;m "I("҄[!PMQڵM]=afin;;ٷu6 '.6a! z%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:52:08+02:00KtEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/LBP.png000066400000000000000000000020631416454732000166250ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<PLTE$$$$$$!)!)!)"*!*!)!)Աf1vٰZŎ(lf#irΟ4u!g&k6vװWčd Z]!g'lٵ~ҧG ZafT`m̛k˚%ja]Ud>{[Əٵcɕ+o%ja X&kfVȢ۹|ѥL\ء޿tҤE„f긵Ƭ۳񻺻ᵰ!)!(!*"*!)"+!* '!)$$$$$$$$$0—bKGD!l  pHYs%%IR$tIME4IDAT(c`=`DL," lȀE  !1# I)iY9y$1E8PRVQUSA*")70426153W7wO/o_? , CB#"cb(HLJNIMKâ ںƦֶ.D8IL6}"$}sΛ`!J\ EܢK.[b*ؤ=FP"%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:52:14+02:00AtEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/LKR.png000066400000000000000000000021111416454732000166320ustar00rootroot00000000000000PNG  IHDR w}YgAMA a cHRMz&u0`:pQ<bKGD pHYs B(xtIME6#MIDATHŕnES]}'2D  $ Še R"KLl2mϥgqY`H9__UN<# %tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:54:35+02:00\ ltEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/LRD.png000066400000000000000000000016631416454732000166360ustar00rootroot00000000000000PNG  IHDR @ލkgAMA a cHRMz&u0`:pQ<ePLTE'g(h(h---*i(h'g␡␡⏠+j(h6r(g'g#E}@@@*i(h)h礲礲碱*i(h+j+j+j+j<<<ѲԲ(h'g(h(h%b 6--*i=w'g'g3n䑢␡=\*L 0n9tҿ޴6r&cE?@}Xr$e5pǓ饳礲>w /m=w'g8sϳ*j+j*j,k*fC<<ԲԸP'3tRNSYXYXZYYXZYZYYXYYYbKGDv1cA pHYs &tIME4IDAT(c``d26153, l6vN  2 xaQ1q Iа(L -# ' TTՒSR320&NvvvNn^~&g004*,,,*.)š@SC= 'Y)+#).&JP '57N,Vf+ _r%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:52:18+02:00rӖtEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/LSL.png000066400000000000000000000016631416454732000166470ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<PLTE ####  ###ⱻⰺ}}谺ᱻtrkwunssunnpHHHAAA&&&DFEDFEI@EXOTSJOVMRZQVRINűưĸֽ̩xcxfzzռͰı9998<EGGE<799EEEEDCBBCDEEECCwWbKGD1rtIME)6ruIDAT(c`=`$3 +;'7FcAbR2b H@N^AQIYEYA 54ut  !/o_?P$apeHԴ̬ܼ|(CWTVU Djᠮ!=}&NCbKGDo pHYs&:4tIME4?O3IDATc`D Jh 0P4@@`(G ha&`XdK%tEXtdate:create2018-05-17T15:58:03+02:00%tEXtdate:modify2018-04-27T13:52:17+02:00tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/LVL.png000066400000000000000000000005631416454732000166500ustar00rootroot00000000000000PNG  IHDR .`jgAMA a cHRMz&u0`:pQ<PLTE0909/8תOlbKGDo pHYs B(xtIME4w$IDATc`D Jh 0L -bXKKA%tEXtdate:create2018-05-17T15:58:04+02:00; %tEXtdate:modify2018-04-27T13:52:06+02:00tUtEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/LYD.png000066400000000000000000000012261416454732000166400ustar00rootroot00000000000000PNG  IHDR @ލkgAMA a cHRMz&u0`:pQ<PLTEOOOaaa$$$ BBB:::BBB:::$$$ >#G#FkbKGDG`{ pHYs&:4tIME4FJIDAT(c`0 L32`aecDbB<|B"1Q$ &.!)%-#+'CQG.N + Q0B&fV61[d`g"B0 nA?z~9`%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:52:24+02:00;ξtEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/MAD.png000066400000000000000000000012531416454732000166110ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<PLTE'-'-'-'-'-'-'-'-'-'-'-&-2.2.&-'-'-'-'-'-&-eC0eC0&-'-'-'-'-+-nA0\F0:P1:P1\F0nA0+-'-'-'-3.@N1[F0[F0@N13.'-'-'-'-&-hB00S20S2hB0&-'-'-'-*-XG08/8/XG0*-'-'-)-,-&-&-,-)-'-'-'-'-'-'-'-'-'-0ibKGDQi|* pHYsttfxtIME41h҇xIDAT(c`zV6vܲ\<|8 KHJP -#+'CF&f\iiemckgN.n8xzyƃ; %tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:52:49+02:00vFtEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/MDL.png000066400000000000000000000016301416454732000166230ustar00rootroot00000000000000PNG  IHDR @ލkgAMA a cHRMz&u0`:pQ<PLTEFDZxpP0 /ϥ ܵ"ƟױZxpfL%idibnT"PZxp۴a4?%33C*i/PZxp uZ8UIs!j)WJm5ٳPЯZS*`h\qq7XdP[cnr-P`V#m}9{:x!r! } n3s, ٲs"y/bKGDa& pHYs : :dJtIME-/egFIDAT(c`F&fV0`c<|x  R !)%-#+'C6v:zF&fXXXZY;8:9cU݊а(쎌OHLJNԴ̬< KJ+p(ohl-mx"`lbQ+ᩆ0%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:45:47+02:00itEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/MGA.png000066400000000000000000000010031416454732000166050ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<PLTE1&@5=2=23&A5>2>2,%;48181ɼvT*`9~^6~^6ս{/=;;ӽu.<}:}:Խv.=~:~:bKGDH pHYs oytIME4"֓YUIDAT(ʵ00f4o~!?DIVXP50-พ!N,/JBUӦz0Nn8yF)V5h-%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:52:34+02:00dIENDB`Eqonomize-1.5.3/data/flags/MKD.png000066400000000000000000000022751416454732000166300ustar00rootroot00000000000000PNG  IHDR @ލkgAMA a cHRMz&u0`:pQ<UPLTE6l F6C6 Ek  k E.. Eb xx bE G% PP %G |iUB1" EUUE "1BUi|kJIIJkVT#;bKGDz pHYs ~tIME46d+IDAT(c``dbfaec`gceafbd`WPTgPVQUS7042243615PWSUQf2wptrvquuqs򶵱0bT  OHLJV OIMcH/(,*.)-+ohljnimch0q)SM1s9s_p%K1,_r5k׭߰q-[m۾c{GV@ $ME0 F-aڃ%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:52:29+02:00ZtEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/MMK.png000066400000000000000000000017621416454732000166410ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<PLTEW$$L-L-L,J*J*J*J*G'ttG'J*2323>?]__`^_^_^_^_^_4332?>ו433276vu434310QQ333333/0QQJ4J4G1w9898:9뵲'9'9%8?Ony*;(9(9%6iuHW%7(9(9(9CR3C&7(9(9(9(9'8'8(9(9ѓbKGDNaq pHYs : :dJtIME1(t,IDAT(ϭE[BQEKbSR4"%-)Hr8q 93X 8|[F o%9Om`DPiG'g4*L r`W7wlA 3BI"y>;T&W(UjVQ L FbZ&A:x]Ng `( }iop$cHxZ'$L3\.I 8?/<|7w%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:49:40+02:000tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/MNT.png000066400000000000000000000016331416454732000166500ustar00rootroot00000000000000PNG  IHDR @ލkgAMA a cHRMz&u0`:pQ<PLTE'/'/'/&/'/'/&-6TQQQ'/)/0-'/'/&/A(t.-'/'/%/I&0-&/'/'/v O$%0'/'/'/&/.-f&/'/&-'/'/*.2,rX",.)/&-'/&/s_ V"N%$.'/&/ ss[!#.'/&/ qZ!#.  Z! juZ!'/&/ |[!#.'/&/cnF'dD'E'%.'/'/&/&/&/%0&/&/'/&-'/'/'/'/'/'/'/'/&-bKGDa& pHYsu85tIME48}j#IDAT(c````dbfae`cNv6dǏObRxH+(RC)fV6v888:9{xPSAHhXxDdn1q $%gdfeP_PXT\RCAYyEeUuMm]= eM-mWH-P9I%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:52:56+02:001tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/MOP.png000066400000000000000000000015641416454732000166500ustar00rootroot00000000000000PNG  IHDR {gAMA a cHRMz&u0`:pQ<bKGDtIME+rxIDAT8˵UKKTa~\梨ij/eN!T$ZF_Ъвm(pQB**tF1)ә9mqh1sƨwu>\x?­k#+  QLTN`W0Z`[JĤJ@'mũXnhqwqnh*R@d-I[R[aI@ cЙYw n޽p2ND*4tr09u|(A+÷ZS--',f@rOE~;p$`(n&9ˍBr9Br!CGCy[ϖv 4cciD`"@n0Fj{ +? L2ղb+BO#{j2ޮ4ځ%m-m,d;d6&bmfc_Ib%MhJIjl>RLpVfs^4u$+t$B,}pɉc>Z"A0=o_g6k͉s vagh:n6|x1wl{+?;TZsETk-RsMyC/rg!YJ3IVL$(Y.4B>ƱKZHFS$"R`)*%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:52:44+02:00IENDB`Eqonomize-1.5.3/data/flags/MRU.png000066400000000000000000000015341416454732000166550ustar00rootroot00000000000000PNG  IHDR {gAMA a cHRMz&u0`:pQ<bKGD pHYs oytIME4,gn^KIDAT8TMkQ=y3IgԶ(("Е ҟᢘED@;A"V[SKUf{X {>޽p2ND*4tr09u|(A+÷ZS--',f@rOE~;p$`(n&9ˍBr9Br!CGCy[ϖv 4cciD`"@n0Fj{ +? L2ղb+BO#{j2ޮ4ځ%m-m,d;d6&bmfc_Ib%MhJIjl>RLpVfs^4u$+t$B,}pɉc>Z"A0=o_g6k͉s vagh:n6|x1wl{+?;TZsETk-RsMyC/rg!YJ3IVL$(Y.4B>ƱKZHFS$"R`)*%tEXtdate:create2018-05-17T16:01:54+02:00Cap*%tEXtdate:modify2018-04-27T13:52:44+02:00IENDB`Eqonomize-1.5.3/data/flags/MTL.png000066400000000000000000000012131416454732000166400ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<PLTE0E)+ҽͿ͹Ѽ¹˾Ӿ;]CbKGDH pHYsttfxtIME4-isIDAT(c``dbfaecvN.n/ ($,K,.r J*jkhjiR``hdlbjfnKn_0;8:9QʀG U0 ɟ5%tEXtdate:create2018-05-17T15:58:05+02:00~%tEXtdate:modify2018-04-27T13:52:45+02:00[ּ2tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/MUR.png000066400000000000000000000006571416454732000166620ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<0PLTE(9(9(:V"^ n mo{7OQQbKGD pHYsttfxtIME4(`zGBIDATc` %4`\C(HC h 0Dn4p 0E a1pF%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:52:40+02:00 tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/MVR.png000066400000000000000000000012411416454732000166510ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<PLTE4444444444444qC7:`8<^8<^8<^8;^7;^7<^8<^844HX8:::9:JH;:44JW8:~:~:}9Ew#U~:~:~:<ĦK}8~:~:}8(YSz|6~:~:|7Al3a|7~:Ö&bKGDD pHYsgRtIME4QIDAT(c` `dbfa,LPl\ EDL>^n1q I)0WP%%Š UT@@]CSK[GWQUQVBWo`hdlbjSNvNjj@ |A0$ 4(bo6%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:52:27+02:00 &tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/MWK.png000066400000000000000000000017711416454732000166530ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<PLTE#Wu ~ ~ u W#G w UB B Uw  G J T*E ggE *T J) R. %''% . R )ar ( '&&' (r aWB 4 x | { { x 4 A V!!!!!!!!!!!!!!!&&&&&&&&&&&&&&"(E325351bKGD`z pHYsttfxtIME4!IDAT(c`F&fV6vN.n^> / ($,"*&.!)%-#+@^AQIYEUM]CSK[GW]^M@`L&BB#"cbc )_PXT `(Ҳʪ ohlJ04C@Kk[{GgW7t5C?@$a20 :%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:52:33+02:002ÀtEXtSoftwarewww.inkscape.org<tEXtTitleFlag of MalawiAIENDB`Eqonomize-1.5.3/data/flags/MXN.png000066400000000000000000000015121416454732000166500ustar00rootroot00000000000000PNG  IHDR  ,`gAMA a cHRMz&u0`:pQ<hPLTEhGeDZes "&Ĩ˨UO*sM4ZѲ{SpF)|P1r[es[ĕzNqM4}fs[ƵéuYxfºfsZÒ˃ѾesZһмesjn3EbKGDo pHYs ~tIME4&W@IDAT(c`F&fV0`cj+ã_@PHXDT q I)iY9y UT54+704261Ū'gW7wO/o_ CB#"*OHLJNI̬ܼ|\PPXT\RZVN"C$%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:52:38+02:000tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/MYR.png000066400000000000000000000021001416454732000166470ustar00rootroot00000000000000PNG  IHDR @ލkgAMA a cHRMz&u0`:pQ<PLTEfffgd_ bfffffg\fff=0Nu+v^7;/O beefffeq֭fg=0NϦ`L@ cd"YP?FP?F!Yeff dHURRRRfe$&ff]e3߲ ߲ f3]ffk~두鐐f aɡqZ9hf*!V*!Vfffd v+gf\p.p.\fffgM=GҨF7Jfe+"UeP>eP>+"Udfeq֭ffffTCE&kV<2(S bddfgfg`)6//./ ` ` a a [+TZ ` a a a ` `)nڸѣ 47;<;;ﮮﭮﭮop:;+.bKGDl1 pHYsbtIME4ؾHIDAT(c```dbfaecf@ B"bR2r J(AYEUM]CSK[GWO00[XZY;8:9wO/o_?, B#"cbX_PXT\J+*kj[ZQCGGgWwOo_&wL:m 0sY̝75sKe(`V5a :b%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:52:31+02:00\8tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/MZN.png000066400000000000000000000025141416454732000166550ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<PLTE4Hebriqhqhqh4'@0[\rhqhqhqh439UJSogrhqhqh4445}7Igcriqhqh4444'@1Z\rhqhqhqh44439UJSngpgofofof4440345=Ohhijj4440s,.3/48TwIQDDDEDDEDDEDD43sV֫Hz .42 +Q*.7<'kg[z^gk:*443} 2< nkD``\[#/4445t 4/q+,npppn54444uU(@؟bD*)42 +Q40xm.G#$-78VvJTCEGDEGEEGEEG43).445!0"/e)Xkjjj44444 5$/4444A( 4443e4 5%/4A( ^ T(bKGD︰ pHYsttfxtIME47 w?IDAT(c``dbfa 98yp+@TL\BRJZF99yE%eU5u\ 44ut 9cS3s K+k[;{LCB#"cbCBbRrJjZzFfVvNn^~`(,*.)-+oPՍ݄޾ 'M2u3g͞Λ`K.[bau7lܴymw vٻo9z `;~gΞ;"6p׮߸y"vp{<|tO>{E ^~E0O-?/[b%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:52:55+02:00|tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/NAD.png000066400000000000000000000031121416454732000166060ustar00rootroot00000000000000PNG  IHDR {gAMA a cHRMz&u0`:pQ<bKGD pHYs oytIME43f9IDAT8˝{PUϽo>B  Pǘ1Ya) :BQc:`fNIK{i9"<TBa,˲}K:u{>s=A: }"8' Io:=hecqaIλ#zX`0FSk*.yG3e^Džb6)S4fJ GcW5}o9qudZ2D@ pJ8XFQq>EprRͽh,1B)Nc|ϋfd1{乷/_ 'B෷  3#|oJqx4.wX$ .~X;%yUSmʀs$ +vJ8u ܮU&k U[~HܳG,rcƪZ` C/Q6gUgpwW8n,Y"8I</Rgo]ʘuYc6cNfڤG7ͪ;/EDhqjL_I~+dF:tCքgv7Fmv9}Ӓ&?Ag # *jFѻv.gRX-dcI΃F#M\!֨pfg>-X=WwP"EDF(w@޺{ra7G7U׍,s f y6u>7š 3`IV?uFB"%L(^fUµI׫}[޼hֲ<Y;Iek_Yu,wKl2rƸB@!ͪ0 γcyͦֈ `@ *qզ_qtJMNh78x;(7o]cIr@XG+GSc踔US*N5&#+lֈ? * pChiFT"Ԧ J$]n'/kr>ZZ7+|[PI*:P8c;#ݱ<ֹEgOSzc>S0Wlr2gbC SX8%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:52:51+02:00c3IENDB`Eqonomize-1.5.3/data/flags/NGN.png000066400000000000000000000005471416454732000166370ustar00rootroot00000000000000PNG  IHDR .`jgAMA a cHRMz&u0`:pQ<PLTEQNZߔbKGDo pHYsu85tIME5mIDATc`Fe#ZS6 %tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:53:15+02:00htEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/NIO.png000066400000000000000000000015331416454732000166360ustar00rootroot00000000000000PNG  IHDR JgAMA a cHRMz&u0`:pQ<PLTEggiiiiiiiiiii^^^^^^__^^^^^éܨۧީ޿z{ěLJÏ٤ק^^^^__^^^^iiiiiiiiiibKGDAlNtIME0/qέIDAT(c`=`$IED%$ Rp -#+'eP M-m]=}C#c( [XZY; D!d@`PpHhXxD$ ۢcbSR܀poZzFfVvNn^~A/>-,*.)-+BDںƦ$i<j?%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T14:48:47+02:00gJIENDB`Eqonomize-1.5.3/data/flags/NLG.png000066400000000000000000000006211416454732000166260ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<!PLTE(&7B<\E!Fh1bKGDo pHYsttfxtIME5;j3IDATc`D Jh 0P4@@`(G ha&`X!oq¹!%tEXtdate:create2018-05-17T15:58:05+02:00~%tEXtdate:modify2018-04-27T13:53:01+02:00tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/NOK.png000066400000000000000000000011521416454732000166350ustar00rootroot00000000000000PNG  IHDR ]۽gAMA a cHRMz&u0`:pQ<PLTE+-'*lm<[$e8t)++-')$&jk<[%'')}~<[$e9t~~7V$e7s(J(J(J&H 0n'h+j!D{(J(J$e$e$e'g(h(h$e$eg#bKGD~V6A!anT bR2r"AUT54Qhk(0536AM  !h%R%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:53:13+02:00$RtEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/NPR.png000066400000000000000000000033631416454732000166530ustar00rootroot00000000000000PNG  IHDR ^8gAMA a cHRMz&u0`:pQ<bKGD pHYs!!K6tIME5<sIDATHǥklWckMl܄45iHmJHԪR mT$hyBԊJ+U !*B<ȣN؎{]~xwf֏:#Qt433;bo?+>"&Y{[ܭv/w.lti H/Un 򛱾S/{? b9sQwZ{憸gg!ʙQ;^:@/~3y陖JOy" v' =C@PVx8Ntyr8jQS5t˱'?fMCv]# nd AX߽~ '0.|2iUδ1s*BWdwaTZa;Ĕq2hn95Vp:Q Ģ=(uGj$2j[8(])v#]Nβq[M+H0N$ Ǿ@G k+]s/\% $yJC;xa˨nVcۺ{%X}p7nYԸb5cS"0(i)lmלNJAL?͂{H:E_%ف֜D{UK%L;E*(&TN3nqc쫨or~XkkZc`YhtY~ K1L1:eOaԮ*]CNd_ @tlq$(&Z}X1\ZU+ج5q^=7򶽰+ A@?UB1~y>l-O-ϒX("&eH5=@?lZw~X]Y xK(77BOZ|{ԉ^@cڼKc ͛{N1ГhPfSo~Txeu=$vjb'6J.Qb_j:`ܳ 8쪀 \EkѣhxΚ6"{wZRtMAJ|7; AB.[iz)4PUfxq܆& } p;ւme-B c-(p8;&ml `ZRU`bjEW!L, f ylY bbgE~*K]T_|Sb/,1&ZKN'3^{̛ ߙ9^y3ZE!‰qk'b5֓~Tk#H.:) 9$~ۙe k4#(_ʔx όǐTWRWmǛ[ C_} C |tLS}-sɋ;"kVI"2w?/KsK;kWh{b#"4^en;D~\[w0#W@Y 7ZOr۹~%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:53:05+02:000^tEXtSoftwarewww.inkscape.org<tEXtTitleFlag of NepalϻWIENDB`Eqonomize-1.5.3/data/flags/NZD.png000066400000000000000000000021371416454732000166450ustar00rootroot00000000000000PNG  IHDR w}YgAMA a cHRMz&u0`:pQ<bKGD pHYs B(xtIME4;;)IDATHŔOlU?͛,nMLk*)-XicR_h"4\Lċ^$Fh#1tAEOvgwvf<.iٍ=>z|F^?~DUyd'xاQws+~fzBo;}9/['FmVn}`!'E|qs>6oZN9쾼Y^bzn 'isznSy9;N IQ-}Pm@JҒ skFP iؠ`2Rg웇}2r&7SBI%I;6%1P,Y-wF+T VYO 8<#c9F'߳ڛ1{=_ DIBpo!Ki*W| h=P'a>9:!D^*QP<)[x@Ǘg98 pY[ *i!0JvFKcadV]+lQ)r+襣JKIc_l|,NajԬ%zh˒ָV?@mm` ۜp 6HS~ą 9}ٯ֏Zk>C` ?W?@{g%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:52:59+02:00PtEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/OMR.png000066400000000000000000000014211416454732000166420ustar00rootroot00000000000000PNG  IHDR @ލkgAMA a cHRMz&u0`:pQ<#PLTE "&#'26?CMQOS?C27$)[^[_#'16.3툋|GK%*16 ]aX\IMGK26$(596;#($_bimil7<<#s#s#s`bKGD hV pHYs^tIME5 x IDAT(c``dbfaec yxp*©@ZFVN^AQIYE+`PS7  ML-,[;{G'gW7 VVU@aPQXTALl\|V@z<|gwi%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:53:10+02:00tEXtSoftwarewww.inkscape.org<tEXtTitleFlag of Oman{߶ IENDB`Eqonomize-1.5.3/data/flags/PAB.png000066400000000000000000000016241416454732000166140ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<tPLTE-L246wWmm*J 0 1Ɍ܋釙鈚PNeRQg炕{=={2QڼbKGDH pHYs$$P$tIME5XIDAT(c`@L,(*ΆG'77'N<|< KH 2AJZFVVFN  J*8khji.voC#cS`-,Q wp'gg'G0`pAn Gyzy{Bc_?` BB#"p*OHL© 9%5--=#ܼ, KJ q*`;%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:53:28+02:00KtEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/PEN.png000066400000000000000000000005511416454732000166320ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<PLTE# eqEHbKGDo pHYsttfxtIME5&fIDATc`Fe#H"u%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:53:38+02:00tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/PGK.png000066400000000000000000000023771416454732000166410ustar00rootroot00000000000000PNG  IHDR S4gAMA a cHRMz&u0`:pQ<bKGD pHYs^tIME5IDATHŖO\U?72Ri c .lٱkW+h1W]-+BS$.3:&h)ft7#`g}s'Kهaם )/pI/x94 \uA:D R74.Vw_ԬቬQ{n>\M >l0[+5;M$hs7 AC نcߩpjM+p' IZ?{HeuBjؐ Y^KpqE g3I!xqfSb 1|zDx[5vBG sӎyyn~SG& HA}p*ptU:xXҷ 6^'Q1668|^+gvv8ۣUrqm;԰J%h/&t:<E BәVVVR1&$94~uZ$+bxx\.*r\(ؠX,=T\V4Dǰ-Lk-Zzbkc# ^o)%RJRA077GRakHYq _Z("̷fY^ YrQXXX`zz- t8c&&&}8 |,3::8 M-T,LOyC5ao23%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:53:26+02:00CtEXtSoftwarewww.inkscape.org<tEXtTitleFlag of Papua New GuineaB,IENDB`Eqonomize-1.5.3/data/flags/PHP.png000066400000000000000000000021741416454732000166420ustar00rootroot00000000000000PNG  IHDR @ލkgAMA a cHRMz&u0`:pQ<"PLTEBl96888"R6788kE5888Mt=68882_8688O6788lncC6888jp쮸Fe333jpK_566n{2#%%%狕,?#%&&&@Q&$&&Yg+#&&u!5#&&&ߵ钙1C$%&&Oa'$&&bbKGD3ZK pHYsttfxtIME5%7IDAT(c``dbfae 98yxp*@RJZFVN^AQIYU5u M-m]=}Cl ML-,ml08:9{xzyаȨظ$4T_VWTVU#kj[Zț]=}&cIL6}Yc s_p%KcW|U׬]׎0߰q-8V/9U%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:53:37+02:00)N<tEXtSoftwarewww.inkscape.org<tEXtTitleFlag of the Philippines/YIENDB`Eqonomize-1.5.3/data/flags/PKR.png000066400000000000000000000023471416454732000166510ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<jPLTE X7@AAAAA@@AAAA?L*%\<CAAAAAAAAAA?-bC-bC@AAB H%?@AAA?#Z:o~?AAA@csYk8jMAAAC!Y9?AAA4gINza?A?*`A H%AAAS2TfDA>Vh H$AAA?$[;Q/BBA>gwU4@AA@@AAA]n>AAAAAAAAA#[;>AAAAA@AAA1eG@>>>>V5/cEAA#Z:厫P|b:lOGuZ}#Z:@A?*`AźǼ-bC?AA?K(S~e»šTfK(?AA@>AF"A>@AAAA/pbKGDH pHYsttfxtIME5&IDAT(c`F&fVtlpprqV/ ($,"*&.!)%@FVN^AQIYEUM]CS S%+k[;{G'gW7wL^>~A!a #"cXcS0gdfeb3[Z;:{IL6}YXa/Xh˖+W^v 7m޲UK\l۾c{ '%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:53:17+02:00kkAtEXtSoftwarewww.inkscape.org<tEXtTitleFlag of Pakistan &IENDB`Eqonomize-1.5.3/data/flags/PLN.png000066400000000000000000000005571416454732000166470ustar00rootroot00000000000000PNG  IHDR "|gAMA a cHRMz&u0`:pQ<PLTE0T:<)&bKGDH pHYs ~tIME5#ʒ IDATc`$@ 0(c4B R5!@?%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:53:35+02:00tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/PTE.png000066400000000000000000000022271416454732000166420ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<XPLTEfh?Mffh?MfffegANfffg.~TgJffjfyFs@Bw9ffnŪ]Z0&sО ,fe$v3Ī߯pe5l hfdLʗE$੾鞓:K yfdb{b#ԎֶWm ӟ"fdOazg˨y{2z {fe$wy VTК☙l%ڊzffi@`կ ؾ3ff kerE~ BS{:fffg1~VjKfffegANffh?Mr-9bKGDǍJ[ pHYs^tIME5!IDAT(c`@F&fVt@El\<  cU !)%-#+'M&fV6v ]\=<}|1GDFEa*OHLJNIMKT_PXT\RZV^QYU]/zz'L4yigĢ`9s_p%K-Ǣ`U׬]~M`۶عk>r- R$j%tEXtdate:create2018-05-17T15:58:06+02:00!%tEXtdate:modify2018-04-27T13:53:33+02:00/tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/PYG.png000066400000000000000000000012751416454732000166530ustar00rootroot00000000000000PNG  IHDR JgAMA a cHRMz&u0`:pQ<PLTE++,,,,믪믪﮷Ĵ˲䔪Ԯ⻡ŶҾ׾ॸॹसߟڟڤߥॸ999988]bKGDi pHYs&:4tIME5_{IDAT(G@DV@1c0E@"= kvo STMS!!Dz$'ܐ"F: En(\&7ahYNgh<° zp$z?nx2}^xK`;Pu;tEXtAuthorCaleb Moore%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:53:24+02:00 ?tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/QAR.png000066400000000000000000000010621416454732000166310ustar00rootroot00000000000000PNG  IHDR .gAMA a cHRMz&u0`:pQ<PLTEʔ6T<==غt,L<=0O<=Ŋ3Q<=ڻx-L<=ܽ|/N<=ŋ3R<=;D7bKGDH pHYs tIME5 \IDATc`F&fV6vtgǭ@@PHXDT q I)iY Up+PUSƭ@GWOЈ/=%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:53:31+02:00JtEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/RON.png000066400000000000000000000005741416454732000166530ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<$PLTE+(YfZU &&^ bKGD  pHYs^tIME5- rIDATc`FeаYaTkcv%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:53:45+02:00 tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/RSD.png000066400000000000000000000024151416454732000166410ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<PLTE6<6<6<5<6<6<6<6<5<6;=:5;6<6<6<6<6<5<>DKJ]GIJ6<6<7C7C7C:CB@<Ŏ8:Ǝ8{==@:C7C"?o"?o!?pLdwztOҟ~vОqQtymHf ?p @v @v ?usXKۥՓbYeb?v @v @v >t؝ϔ̇ܮgu>t >tŁܴ~hu>t >tٰܲen >u ?u ?u=t~sΔˑcb=t)W)W(Vrոȍةȑ׼sg'V޾ˆiwXΉ~yU͊r~[m/ٮ՞k+ҋoхmݶӉrKÙbKGDԶwL pHYs N Nw#tIME6D?IDAT(c`F&fV<$vR2r J*khjiK*`;{G'gW7wO[T>~A!a^!""cbQC gdfe¢Ҳʪj jj[Z@GgWwOo_&) 0u3g͞3wSPBXxeW\zڅa߰q-[m߱s:T ݷC=@?q3gϝpݗ._zvPT9%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:54:05+02:00҂tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/RUB.png000066400000000000000000000006211416454732000166360ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<!PLTEQ7997-.++`İbKGDH pHYsttfxtIME50jtP3IDATc`D Jh 0P4@@`(G ha&`X!oq¹!%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:53:48+02:00ötEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/RWF.png000066400000000000000000000015511416454732000166470ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<\PLTE @K1JN:tn+c$޽L: IQH/ }p}o}p}p}p}p}o%c< `= `=:bKGDsA = pHYsaa?itIME5,~uIDAT(c`YXpvN.n^>~B"b8HI+(*)`W]v6vN.{xzy`W'$&%D3biY@CKVG0 C!PDPF%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:53:44+02:00cܸtEXtSoftwarewww.inkscape.org<tEXtTitleFlag of RwandaXc:0IENDB`Eqonomize-1.5.3/data/flags/SAR.png000066400000000000000000000017021416454732000166340ustar00rootroot00000000000000PNG  IHDR 'gAMA a cHRMz&u0`:pQ<bKGD pHYs%%IR$tIME6%IDATHݖnA/1΢lX !\#p瀸!$"bĎ! q"QIݭimJ]z@Y K)" ADp.(,h6cL"yZ% 2v*> Y-yx.v]tc^٫q52& 1 pPwRv):a,eDZ>ک6˻:Q]e. "&8Ǯ x(m3Px5jc6t^fD8p2S$!ƫ<|DjƁ[jJL!"c c8#*K4u !V\qafhkWxyxdmބ^St*K;$CXezl"W~A!aQ1q I)iY9yETŕ? ,;7/UwP ]7XAwOo_&O: ]7X3g͞3w +XdA+VZf-nu7ldymw+Qt9.GQk7n`{Gb ǎ8yBѾ, %tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:54:28+02:00p2tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/SCR.png000066400000000000000000000015251416454732000166410ustar00rootroot00000000000000PNG  IHDR w}YgAMA a cHRMz&u0`:pQ<bKGD pHYsttfxtIME6IDATHǭOOQG+ Jbjbbt1JU( n vҝѕ6pDRZ;cg3msHn&wO@(?:AFI1'Q~ ;pTSzlC8Y9^;aia6](z-h~oP~6AP3)U6mvgb6]Elr.I c/3 hZ"iBP2!HBF VFo`srls0 .y/~/q<%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:54:49+02:00htEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/SGD.png000066400000000000000000000015761416454732000166350ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<PLTE)9)9)9(8&6+;-=)9)9)9)9)9'7M.>mx'7&6`l,<)9'7ES*:?M9H(8(86EBP*:)9(84C:H+;juCQ!/SR32srWTaں*`h&F@jj%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:54:15+02:00(tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/SIT.png000066400000000000000000000014771416454732000166570ustar00rootroot00000000000000PNG  IHDR @ލkgAMA a cHRMz&u0`:pQ<_PLTE&cWW&c!Zpp!ZVVVUjjUVVSSUKm}m}KUS___aOOa__\\\\^RR^\\\aaaaaddaaaPGyPGyPGyOGyPGyPGy&$$7;$bKGDH pHYs oytIME6 RiIDAT(c````dbfaecddyxɊKHJIʉ`yyyE%eU5u MyLo`hdl LMM-,mlM1&`   aaaQ1q a!111)9%5-=#3+)0dANn^~A^nN6PH0 C @P4$Сq8%tEXtdate:create2018-05-17T15:58:06+02:00!%tEXtdate:modify2018-04-27T13:54:11+02:00gIENDB`Eqonomize-1.5.3/data/flags/SKK.png000066400000000000000000000022451416454732000166420ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<1PLTE{[b[a{`f\c]c+3W^u{W^GN$l[L NMmz3;]d$,k] MMgx9@)16>^d4<7?&m[ MLHqMV#$AZq,&"*yT N NN\wf>sZzK=|TubxM N&H&H%GcsNyN N NM]w6S%G&H"4"4"4%5eu_zTM*eF'$%%%%$#%%bKGDH pHYsttfxtIME6 0IDAT(c``dbfa6vN yxED@@\BRJZFVN^AQIY 0 `0cS3s K+k[;{#N.n^>(CB#"PDALl\|BbRrJjZz6Y9yE%h @ 0@k[{GgWwOo_-(aL2u3g͞3w$T0 ,\xeW\505k׭߰q-L۶عkj pYT-b܆AA@??B@AAATa^qaTAAA@hh@AAA?YY?AAA>]]>A>܅ADݭM߭DAHcC@CcHAAA?AAA?AAAANbKGD`ŷ| pHYs B(xtIME6}ZdBIDAT(c`;`d/̄ON..N<||BXKHJIIJHaQ E66G[XZY[cw{xzzxyPCAhXxDddTtL(q@2>.ap۰0%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:54:20+02:00ŸUtEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/SRD.png000066400000000000000000000012771416454732000166460ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<PLTE7~?7~?>FZrZr_q))*:% - - ----{#--- - -;)Z&^&^&Z&;) - - -)*ى"ى")* - - --,ܒ",- - -, *4&k!(Zrfq^qYrqbKGDEW pHYsttfxtIME6'ŠTIDAT(c`0 L3XXQEQ''2Fb~A!aQ1q~( I)iYY9yE UT54*704402IV66V(@-J8 #JH I0=P ow71%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:54:39+02:00tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/STD.png000066400000000000000000000014721416454732000166450ustar00rootroot00000000000000PNG  IHDR @ލkgAMA a cHRMz&u0`:pQ<8PLTEr^0++++4r^0+++44r^0+++444r^0+,,,4444b+wzyyyz442o443o443q.%.%ԫ' ' ԫݳݳyzzz3bKGDg[ pHYsbtIME57FIDAT(c``dbfX98)ǣ@@PHXDTL`WE%%EdZAABBYEUM]CSKKK[GWO_@F $ ML-,,ml`H8:9{xzyhw @Qa VGDFEDhGj'$&!h#A$P`dnVyA%yf%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:53:55+02:00xגtEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/SVC.png000066400000000000000000000014061416454732000166430ustar00rootroot00000000000000PNG  IHDR  ,`gAMA a cHRMz&u0`:pQ<PLTEG F F F F,],],],],],],],],]Ўѿ˾muhyi|ᡲҫ,],]-^/`/_-^,],] F F F F F F bKGD$ pHYs!2^tIME2.:xIDAT(c`0100"6vN.n^d1>@dD)iY9yE%e$APUSCDVo`hdlbjfn4K+k[;{G'd+͏Hd/x%TBB#"Qj0,p"X%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:50:46+02:00nvtEXtSoftwarewww.inkscape.org<tEXtTitleFlag of El SalvadorGڲ0IENDB`Eqonomize-1.5.3/data/flags/SYP.png000066400000000000000000000015211416454732000166610ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<MPLTE&$.@.@.@.@.@.@PzѻѻPzgw9ErErw9g̵bb̵X"bKGD!l  pHYsttfxtIME6*;yIDAT(c` ``fV6fN.n^(fA!aQ1q IGRJZFVN^A,ŠJ*jZ X ıwptr6FRx@ApHhXxD$0$ARrJjZz0 C0j]93%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:54:42+02:00otEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/SZL.png000066400000000000000000000022521416454732000166600ustar00rootroot00000000000000PNG  IHDR 'gAMA a cHRMz&u0`:pQ<bKGD pHYs^tIME6!+aQIDATHŖkU?}Ic.k; :`@ƘT ݆Bvkat? e.8RK1T&{/*xy9>yޣ^Эp|kZ B2RUI;: @@D@6:.ZKWWR.c ElX9o-gRn^ .EHXyr+CGeEMZW cINӖ=9΁ ${y/իdFGR5 Al6ܜ`wY~RI/B( ~<7M¡  J:r@=DmOsu]D@ p†IL{4Aӏ,WlPڑ ?uD}ک0Pzޢ:xDx<c ;A>uwwYJa~8ɀUwN@Y¯UV7T-}8ñlj*iM*"1;;\ӁX<,}<U8tLQ3ݼY P͐霦c2V6vjܽsT 9c@)Z~v+WefL.bDA@PD+˜s\[iЮ]enU9OETӃ5\Q2##P,.:M,j)nCB 22VYQ\"5]9 ;omgJ"v A$oSym'ܛ~F-hOU&%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:54:33+02:00?VtEXtSoftwarewww.inkscape.org<tEXtTitleFlag of SwazilandWJ؜IENDB`Eqonomize-1.5.3/data/flags/THB.png000066400000000000000000000006271416454732000166310ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<PLTE$!>8d"N$OAݼbKGD ٥ pHYsttfxtIME6:i1ƓlK_7pQr\o}[)EMYU%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:54:44+02:00tEXtSoftwarewww.inkscape.org<tEXtTitleFlag of TajikistanBnIENDB`Eqonomize-1.5.3/data/flags/TMT.png000066400000000000000000000020171416454732000166530ustar00rootroot00000000000000PNG  IHDR 'gAMA a cHRMz&u0`:pQ<bKGD pHYsGGtIME7 Nh`IDATHǽnE@ϭ~zǯd;X(_CذD;Bbؙ{2~eaB28]բoso*X>'|Or\ Q0 Ly?Da-:d[d۫LJ=Ⰷ^%8phlX2nd׏@%0;UF/hq@-X&&t(>1BUьp2 )Zt?1ՊrYoQP.NYؙU|@2?%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:55:10+02:00҆tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/TND.png000066400000000000000000000013441416454732000166360ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<PLTE5D5Dt~s}coz'ESbn(dp(ES6E'`lmxDRZf/.>)Xd aFbKGD[t4 pHYs B(xtIME6513tIDAT(c`/`dbfaecb%]_@PHXDTL*jZ:z*X[XZYaQ`E@`PpHhXxDd9&tA_ !I8.& |X%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:54:53+02:00tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/TOP.png000066400000000000000000000012661416454732000166560ustar00rootroot00000000000000PNG  IHDR @ލkgAMA a cHRMz&u0`:pQ<PLTEZZ챱pp䐐NN믯 mm쳳qq[[PP!!  U%bKGDH pHYsMM9`ctIME7~~IDAT(c`F&fV6vN.ntš@L\BRJZFVNE%eU5u MrBKK[GWOSXZYY;8:a*pW7wOg/o_L~ G$aEL%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:55:00+02:00oxtEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/TRY.png000066400000000000000000000015621416454732000166710ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<}PLTE                 %1rzYa$     HRbkhp\e(     3>#/!(        &2      Q[)  '    $ , &1rz  (  Q[)      ȣkbKGD~?As pHYs B(xtIME7 IXIDAT(c``dbfaec%/ (U^XDTL\BRJZFVN>C#cS3s K+k[;{G4N.n^>~Ah BB#"bbgdfY9yExM(4 %en@EEeU5/P¡3$ /+cH%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:55:11+02:00<tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/TTD.png000066400000000000000000000025041416454732000166430ustar00rootroot00000000000000PNG  IHDR JgAMA a cHRMz&u0`:pQ<pPLTEy`bbHHH醑*%&&&(esmooCDD됚1$&&&$O^щ -..况(;#&&&&#:Lƣ7I#&&&&#*=𭴻***K[$&&&&$2앟>??ruuap&%&&&%+|VXXXZZz*%&&&%&dqprr@AA득1$&&&&$M]ы+,,﫲)<#&&&&#9Jĥ9J##)<M]prrdqXZZVXX|ruu>??$K[Ѝ#7I&#(;<bKGDσi pHYspMBtIME67=0IDAT(c``dbfaecG B"bR2r UT54ut [XZY;8:)wvqus AS?=#3+;'7/U?UuMm]}CcSsKk[{GgW7޾ 'M2u3g͞3M .ZdeK,^byh YzӦNf}=h :;Z[6lT MeEyYiɖ ع++3#U?ZjJ={??$G;~MSmm,-LM 9{NG[KSC]MUEYIQ]~>^n.Nv6Vf&F[/Xw%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:54:55+02:00btEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/TWD.png000066400000000000000000000021271416454732000166470ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<RPLTE ]]XXXX]]\\~~~~[[pppp::qqrr;;vvƢvvwwƄ̄ww  % 9595$   KKKKKKKKKKKJ}LFIbKGDc +wtIME51g'CIDAT(c```dbfaecB "bR2r+(*)khji`Qo`hdlbjfnaiE^>~A!aXGDFE'$&%`*HMK/(,*.)-+GUPQQYU]S[WщIL6}YQ̙3g .Zd+VZUڵk׭߰q-[m߱s={QCŴԕq5ޮ@zu@)B@  Px_`ps!!5r^o#Q嫆oҎ[RPJ!$[= A7ԡQHMWRJo]Ν{3j\:Tb`NHPB D-5ln]eg%fӺ6WxHz8پ%NV'6"Q,Fs&zn\lKJA0.NA@"r-ۑo>[YKQ4O.u& [Jׂg+/?zwޭ0,NBHlM y_ `ܒQ@H >l;Asr\xPPUa}Zu)Θb ߎFľu˷PhbZp'x^ ?e(Ơu>qf{=y-/}=r-5{kNqJ.Nt4UQTu[Y0F8z6rb+{ڃ JEBiVtt4 s3?m.1ddwO;4qq:Ε>BWu_HϽ[8h1/[Ơ$4nIX_ 4Ȝt$gyW BYXU0Q R"3oĔt  >$%%%+rr+%%%"OO"%#E%"|bb%'gC""%%&#%%%%%%73bKGD]0 pHYs B(xtIME7IDAT(c`zfVf|l\lxps@FVN^AQIYEUM]C-m]=}C#cS3-lv[XZY;Xcw#g{xzyxyzPCApHhXxxXhH0Q11Q v[@s'%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:55:29+02:00ĸtEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/VUV.png000066400000000000000000000017461416454732000166770ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<bKGD pHYs^tIME7$IDATHǽKHQ? AdFRiZ EEصZE" 6S{PDT:eRZDE iҼ8m16Xۙ,/}{ιZ{C@x(ZMK1N>1N& *.}*aqj06"Cl658#\(XfYmQD@-ز@W{$+8f"9Y]+%CUqVJA-I#ضd_OAGB2<̊,7hVXTpHI B҅/L0.lod!ӊnSslXh 4m01I#*'$8zn"8'"hmؽ"Kљ ]tCdJLG*ڻ$OGt2Ho?fT~` b: lx8_oI~zLD~55Sga2R(Ɲj~%fsU1F~Nm.5l9JoOe7h(7`%Aagӆ5벫+cYt@2d~.w*㰷]CC#^^y˩`0,ER0VU5iL[(6؞Sˤ0VW5VyLf2 qKxDKK3W(pBEE"W>LɑO՞sm{]l>:*hSۙK,C@$\N]@2+1a6ޚqWYؤ9Թ***@]  4켣U;~;osXf&PY O`Ce`b Չ 6eػ;@tU]iرTu>RrUVAwe2Q-6˗qfqJ|0p,'Y5ae4W޻N$-[QATUe<0;v޹6=;!in1 XKHfN&>_lپR.2=5ű36O2#`)*pzb7߸Gӝ=AVZy@0;{zf֢7p8RvO7 ,HOt+.RQ=FGENeM2Ʈ5SC.݇2 VkFTQB"CU2vAGabċ=Ko@Nn(uv XfthzNrK]ڡxP(Bزm+˗/;8mVZhC ]121fAS|,^^~A^z!q޺̥AbǮEt'FWJ>uHg y9KV*M)L *Ȭ=nR?x#7舏={r&"a; b sKgQ\Yy%Sn)3݊`\z]#EjHPxNK8#@{v*5d,ETu]wgy.Ǯ1Yf\ŬTll231Җ b9RƍQB *2ciYג URaU|qbO>+7L<"gI5yt .ĩ)E8?n4y $]S&[JoWBI-Jߕ>U`0x koqMbeQ(@4ZёuÖ?G@t qjkkN~G@D`.|Bx IGNhEV ^ck9S3~zfIi:?0pՂ <~vdYi$IN|D[ ԑ5RfsB%@$DŽZS^YYDO q.a\"9222{|iA % eP &"^HxٹҌƫ,neVD QI(:=ȏ(J(0g;Ҏ*\Cth^ƳTd+e.%ʴBfqUUSP0smEc z^ % U(i*pT0ٴy#caddYd/D[k3V䁹)&SaM\ZAEc%KmޘN,o]kB %!mea!F !.3#nf!"vOQWoc|4B2玻]^\*kX`S* :t?'$UU)ďzԝ(2ohee4<]캣k];([DX,V,,tl6 ydlQ@͊|Q]GYb.tskK*$z{}`vX0uT*|C&,'&qQ&IEFC*B`gby[K i?Ne} .eU`hB4\;j{t mKXYFrL+I I"(""B$ybqxBw!ko<-?;6ǚ{/_N{} VζKH YU.oVSMFDnd.h4Q^Q۽j'l޼m۷# "Rv'{cɅD̅g =ŁP(gl6fK:>/xQIvՙOco{deQ_^ ىd4b2E`0ȕ+aXo,?crszI$H ?eK ս{~]fddflj⣚[~.괿^%ZVdzXo`g,FۏPI)ԮtG>pZq?(/;;?;̆fonM"LF9|+1ɅiRC6M;Pث=~ԯʊJ"^PS?V@E, 6ndÕCio}ήn]sׯ__][[k5ˬ(#(c!1?abjn˦恖/^p鉟$f͚o^Lj[Xv-=Y\^]T\) i* FGGN _%x|fƁ0HMVs}U&a} R@ @%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-30T17:57:10+02:00IENDB`Eqonomize-1.5.3/data/flags/XCD.png000066400000000000000000000053351416454732000166330ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<bKGD pHYs  tIMEZh{ IDATH}l]Yy{ϽןqN&qi5l¢Z` Icv@ bMn@V&ȄѱJfGqċck_~yg/ cJnm/Pzą5 j#*h<111bPn+艥( $SP*Fd@7b#BcMw,bYDY&[V)'O@,0\8G!sQ0a)Y/8P}[%[ɤFw3>x]@Rc)x7遘,c`Ѓv>$A؎ RU#JjeE0\.DJ4Fa! kQ$@DKVe@Jm[y0ڏ9.9`cn`eG%q\"g?=aAd}hv>顉7B8> Ȩe9SOf o?.-ՓW;&Snp!vO  OȽ_=|R\![C]OΓ2fu|BpݷpdBˏM?YK/IYSB@Y_j[ @Q>p 9U\"|BWKGk{U, " O #ψ##A9*⹓Zmeg2o ܹ0Sy(ΓJp"xҡ?JMO xOpHsa,|/_8fBQIdIX֕(I!Vy9\ %@A}A?s+s<;pw1RڕO:["m~^EÑdnHA)4ĴH!k3/Y2voisv{i?aK~6KW .mR 'qL ͩLo엲 3$ޝ1Wwv_fs/93hC Å'#e.JЙk!`TUY6{oFӷƼ0hLuO|g<ݽrG>nSA/x*Pc1ef`}곳5U#Of +@@˗̖g[Nc?=@TB,= *F@EQܿ0reȍ`׮v;Z{j5Le!4؋z#kK.%DZ)q)<_$OEZno QiW:vx F>Q^qsbIR*L헿}xm:4-IIh[Y:tE33V9.a%>wLgS!:\}=<>kPLDűSzsbSM~k}C=&lmw@ΛF>(Tr)y,]aD@3yF<5+VtG?껭_yvm'>}Oog *J` @sv[%02S^lGo`b3RFz%˺Igo\v\HLԓi,#Y){{*yJ7"d "U@A.u@ҍ]9CAGc5;M>tU^Ƈ^,ajtd3~OqDff!i> 0/~{^I֢ɲ8]S}RdDTTT](1DaCI\l33Xi]NߑRAګ_hQEav7ZU8qdr߲)rqq:h\C!0 `b4Q=ҽڽ#/N'’փQaye=>5Dr8ƚ7#K)}^3!F,B@F Zx2V;Z]56AU+%qkOy[|7?5\?hXT<'Pp ۛspR0,!Ȉ3ͩsۻۋx2g$iHMSlp:<[BT`th|jBP᭱}kKwo^o&M_+E-{Cʨبi$Dcf7AA$NUJEIMB"̰)4 @GQQ5NبO{Z({qAypCD˳&ˈ 2M,`"Hts3t~P1&A: epwSzE+"D=7Z,%ifP#aKt!Dlm9wRW̬Sv?9}1>pEM WŎHDt' 76N'p43O>=|PlD2KK~OxD R#GD):.C Xێ.mo ʇ?AD5Dd|\9XE 5eW@Ύ D䜫W @D7Y#:@Uѝ.qM (s`cT(.t.( 05wF>d@r!L`t42l$I5o}?[$ȵj3ڭN:^O~nwnC(,=͎1 5ε׻v4 jy]ZH&!?l#LT|2ٯ˱D!F1RtT^S|>[XhX_X%:r 5>Dw[yfK sId~Rt47c"/(I+i;l-(JxL=%%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-30T17:53:06+02:00PIENDB`Eqonomize-1.5.3/data/flags/XPF.png000066400000000000000000000022711416454732000166460ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<PLTE&&(((((''(((( "봹檲uScϷd޵5d7rgL,ݰFuRj*&1brGBڧIaV{kzVXyeW?٩Љ-kfťͷǫơkR"яεWfbf~flXcF}Ηt;Iatqr?JtH~>kUV{X}Iv=io\Yoܛ !! ((((''((((9S2bKGDG`{tIME":?+.IDAT(c`0 L̓$ |B"bQ)WPTRVQUS׀ 3h€9\,ml]\ 0+OHLJNIMP_PXT\RZ CA{GgWwOo_&O: 3fΚ=g .Zd)p/[bk֮[a͈pٖ۶عk8ID:|'N:},R\ Eܹ.^|ȱI0=P '@%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T14:34:25+02:00a IENDB`Eqonomize-1.5.3/data/flags/YER.png000066400000000000000000000006211416454732000166450ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<!PLTE&$.@7bKGDo pHYsttfxtIME7H3IDATc`D Jh 0P4@@`(G ha&`X!oq¹!%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:55:27+02:00tEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/ZAR.png000066400000000000000000000022601416454732000166430ustar00rootroot00000000000000PNG  IHDR 'gAMA a cHRMz&u0`:pQ<bKGD pHYsttfxtIME6IEzIDATHǵ{lSU?zoFǢӹ {Y%$>u*#1F4&c6ncm]C$Y[{r߹s,d020ԻFĎ #)0?`% $_Nczv4G-$"(оNq$0B8FXTٲ0~P_i%$t(9l#WnKҡ "rli=R*vqqEܟd&{fxoE$dɔ,xl4nHfŭ Ȉ,ΞvHOAʢHkl i٦2atId%Ph*;7t29%6oO,i5[yyٔ J~!~Ǽ>vnBőB,rjlUypƌن?d8]. BZ7 5d(u&K{v^#TNzQy}|sv4YaȂJ+'p]\qX.+=pĕ@kk H,*Ѕt!K@M<ÜX#"vAAv+ڭjFWr.m^ZJxǶ>>sS`]J5-W<XU wyyܻ ɿ3`(,P:u0WZJ@{vx#UIܹn[ǩX\WjVi;Iaf/9ttT2[%F*u-ts$/9d4G\FrS!yNlZGw?N`,/q>#.Ch%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:54:26+02:00OotEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/ZMK.png000066400000000000000000000015441416454732000166540ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<PLTE$&#UtmqbzzpxM~lvqm.!Xymfooabq[{1iuiyk@z4Qu"Ds|U|U|U8L E EGgtp[Y  ^}o\  X  _}KHbKGDHq pHYsz<@tIME7xIDAT(c`L,l\!1)9%5- ̬ܼ¢"l KJ+*kjFM7Gd~{%tEXtdate:create2018-05-17T15:22:38+02:00L?}%tEXtdate:modify2018-04-27T13:55:26+02:00NQtEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/ZMW.png000066400000000000000000000015441416454732000166700ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<PLTE$&#UtmqbzzpxM~lvqm.!Xymfooabq[{1iuiyk@z4Qu"Ds|U|U|U8L E EGgtp[Y  ^}o\  X  _}KHbKGDHq pHYsz<@tIME7xIDAT(c`L,l\!1)9%5- ̬ܼ¢"l KJ+*kjFM7Gd~{%tEXtdate:create2018-05-17T16:12:18+02:00*2pg%tEXtdate:modify2018-04-27T13:55:26+02:00NQtEXtSoftwarewww.inkscape.org<IENDB`Eqonomize-1.5.3/data/flags/cent.png000066400000000000000000000020661416454732000171440ustar00rootroot00000000000000PNG  IHDR ^gAMA a cHRMz&u0`:pQ< PLTEPP}UTGFvYYCBs]\@?q_^@?q^]A@rZ[c?g%8$6$6GFvZY^]WV__VU``VUa`VU`_TTl`೻績渾QP}^]WV`_TTaaSRbaSRbaTS__o`ڤᩰᨯDCtXW`_TSbaRQ~dcQP~dcQP~ccQR`BkEVFUFUSR_^UTbaRQ~dcPO}eePO}edQP}a`vqCBsWW``SRdcPP}eeON|fePO}edPP~bGoZi\i\iSR_^UTbaRQ~dcPO}eePO}edQP}abmYυ։։DCtXW`_TSbbRQ~dcQP}ddQP~dcPP}ld[Za`SRfdON|ihLKzkjLJyjiMLzfgmLr9J9I9I׈׈׈׈׈׈׈׈׈׈׈׈׈ֈ։t%bKGDk pHYs s s αmtIME-[WIDAT(c``dbfaecG B"bR2rAAQIYEUM]CSK[GWO0[XZY٣G'gW7wO/o_?tSR32srCAaQqIiYyEeUuMm]=:`hhljnimkG &N~;@p7 l( ZA+ARmr|N\Ks w.JiO@hjFDZ8H+VSئ P 6%bnnފܙd[CvLL2[D$3 3zÅ*|ġO~#Ff)V Qz>l5~{v}0]y|-X\_+.NJ( \2D#1&olOl+)d2dz[.T>!5eXIfII*  (1$2iKKAdobe Photoshop CC 2014 (Macintosh)2015:07:06 09:17:090221; (L%tEXtdate:create2018-05-17T15:56:46+02:006h%tEXtdate:modify2018-04-27T14:05:44+02:00YtEXtexif:BitsPerSample8, 8, 8>'tEXtexif:ColorSpace655353{n!tEXtexif:DateTime2015:07:06 09:17:09VtEXtexif:ExifImageLength1576#/stEXtexif:ExifImageWidth2363BtEXtexif:ExifOffset224QPItEXtexif:ExifVersion48, 50, 50, 49c tEXtexif:ImageLength800rHtEXtexif:ImageWidth1200dtEXtexif:SamplesPerPixel31tEXtexif:SoftwareAdobe Photoshop CC 2014 (Macintosh)x\IENDB`Eqonomize-1.5.3/data/index.theme000066400000000000000000000023341416454732000165420ustar00rootroot00000000000000[Icon Theme] Name=EQZ Directories=apps/16x16;actions/16x16;status/16x16;apps/22x22;actions/22x22;status/22x22;apps/32x32;actions/32x32;status/32x32;apps/48x48;actions/48x48;status/48x48;apps/64x64;actions/64x64;status/64x64;apps/scalable;actions/scalable;status/scalable [apps/16x16] Size=16 Type=Fixed Context=Applications [actions/16x16] Size=16 Type=Fixed Context=Actions [status/16x16] Size=16 Type=Fixed Context=Status [apps/22x22] Size=22 Type=Fixed Context=Applications [actions/22x22] Size=22 Type=Fixed Context=Actions [status/22x22] Size=22 Type=Fixed Context=Status [apps/32x32] Size=32 Type=Fixed Context=Applications [actions/32x32] Size=32 Type=Fixed Context=Actions [status/32x32] Size=32 Type=Fixed Context=Status [apps/48x48] Size=48 Type=Fixed Context=Applications [actions/48x48] Size=48 Type=Fixed Context=Actions [apps/64x64] Size=64 Type=Fixed Context=Applications [actions/64x64] Size=64 Type=Fixed Context=Actions [status/64x64] Size=64 Type=Fixed Context=Status [apps/scalable] Size=48 Type=Scalable MinSize=32 MaxSize=256 Context=Applications [actions/scalable] Size=48 Type=Scalable MinSize=32 MaxSize=256 Context=Actions [status/scalable] Size=48 Type=Scalable MinSize=32 MaxSize=256 Context=Status Eqonomize-1.5.3/data/scalable/000077500000000000000000000000001416454732000161535ustar00rootroot00000000000000Eqonomize-1.5.3/data/scalable/application-x-eqonomize.svg000066400000000000000000000745741416454732000234710ustar00rootroot00000000000000 image/svg+xml Eqonomize-1.5.3/data/scalable/eqonomize.svg000066400000000000000000000654431416454732000207160ustar00rootroot00000000000000 image/svg+xml Eqonomize-1.5.3/data/scalable/eqz-account.svg000066400000000000000000000133321416454732000211270ustar00rootroot00000000000000 image/svg+xml Openclipart Eqonomize-1.5.3/data/scalable/eqz-balance.svg000066400000000000000000000266131416454732000210660ustar00rootroot00000000000000 image/svg+xmlOpenclipartscales of justice2009-06-26T04:35:18https://openclipart.org/detail/26849/scales-of-justice-by-johnny_automaticjohnny_automaticjusticelawmeasurementscalessilhouetteweightEqonomize-1.5.3/data/scalable/eqz-categories-chart.svg000066400000000000000000001314011416454732000227150ustar00rootroot00000000000000 image/svg+xml Eqonomize-1.5.3/data/scalable/eqz-categories-report.svg000066400000000000000000000601151416454732000231320ustar00rootroot00000000000000 image/svg+xml Eqonomize-1.5.3/data/scalable/eqz-currency.svg000066400000000000000000000366731416454732000213420ustar00rootroot00000000000000 image/svg+xml Eqonomize-1.5.3/data/scalable/eqz-debt-interest.svg000066400000000000000000000251501416454732000222450ustar00rootroot00000000000000 image/svg+xml Eqonomize-1.5.3/data/scalable/eqz-debt-payment.svg000066400000000000000000000412301416454732000220620ustar00rootroot00000000000000 image/svg+xml Eqonomize-1.5.3/data/scalable/eqz-edit.svg000066400000000000000000000406401416454732000204220ustar00rootroot00000000000000 image/svg+xml Eqonomize-1.5.3/data/scalable/eqz-expense.svg000066400000000000000000000410101416454732000211340ustar00rootroot00000000000000 image/svg+xml Eqonomize-1.5.3/data/scalable/eqz-export.svg000066400000000000000000000417051416454732000210210ustar00rootroot00000000000000 image/svg+xml Jakub Steiner http://jimmac.musichall.cz spreadheet document office Eqonomize-1.5.3/data/scalable/eqz-import.svg000066400000000000000000000421031416454732000210030ustar00rootroot00000000000000 image/svg+xml Jakub Steiner http://jimmac.musichall.cz spreadheet document office Eqonomize-1.5.3/data/scalable/eqz-income.svg000066400000000000000000000424131416454732000207470ustar00rootroot00000000000000 image/svg+xml Eqonomize-1.5.3/data/scalable/eqz-join-transactions.svg000066400000000000000000000301771416454732000231460ustar00rootroot00000000000000 image/svg+xmlEqonomize-1.5.3/data/scalable/eqz-ledger.svg000066400000000000000000000440531416454732000207410ustar00rootroot00000000000000 image/svg+xml Jakub Steiner http://jimmac.musichall.cz spreadheet document office Eqonomize-1.5.3/data/scalable/eqz-liabilities.svg000066400000000000000000000160351416454732000217700ustar00rootroot00000000000000 image/svg+xml Openclipart Eqonomize-1.5.3/data/scalable/eqz-next-month.svg000066400000000000000000000047501416454732000216000ustar00rootroot00000000000000 image/svg+xml Eqonomize-1.5.3/data/scalable/eqz-next-year.svg000066400000000000000000000061631416454732000214130ustar00rootroot00000000000000 image/svg+xml Eqonomize-1.5.3/data/scalable/eqz-overtime-chart.svg000066400000000000000000000152651416454732000224330ustar00rootroot00000000000000 image/svg+xml Eqonomize-1.5.3/data/scalable/eqz-overtime-report.svg000066400000000000000000000613461416454732000226460ustar00rootroot00000000000000 image/svg+xml Eqonomize-1.5.3/data/scalable/eqz-previous-month.svg000066400000000000000000000047551416454732000225030ustar00rootroot00000000000000 image/svg+xml Eqonomize-1.5.3/data/scalable/eqz-previous-year.svg000066400000000000000000000061651416454732000223130ustar00rootroot00000000000000 image/svg+xml Eqonomize-1.5.3/data/scalable/eqz-refund-repayment.svg000066400000000000000000000471731416454732000227720ustar00rootroot00000000000000 image/svg+xml Eqonomize-1.5.3/data/scalable/eqz-schedule.svg000066400000000000000000000206731416454732000212750ustar00rootroot00000000000000 image/svg+xml Jakub Steiner http://jimmac.musichall.cz appointment new meeting rvsp Eqonomize-1.5.3/data/scalable/eqz-security.svg000066400000000000000000000460511416454732000213460ustar00rootroot00000000000000 image/svg+xml document settings preferences properties tweak Jakub Steiner http://jimmac.musichall.cz Eqonomize-1.5.3/data/scalable/eqz-split-transaction.svg000066400000000000000000000244161416454732000231560ustar00rootroot00000000000000 image/svg+xmlEqonomize-1.5.3/data/scalable/eqz-tag.svg000066400000000000000000000054771416454732000202610ustar00rootroot00000000000000 image/svg+xml Eqonomize-1.5.3/data/scalable/eqz-transactions.svg000066400000000000000000000431041416454732000222030ustar00rootroot00000000000000 image/svg+xml Jakub Steiner http://jimmac.musichall.cz spreadheet document office Eqonomize-1.5.3/data/scalable/eqz-transfer.svg000066400000000000000000000472051416454732000213250ustar00rootroot00000000000000 image/svg+xml Eqonomize-1.5.3/data/standard/000077500000000000000000000000001416454732000162055ustar00rootroot00000000000000Eqonomize-1.5.3/data/standard/16/000077500000000000000000000000001416454732000164335ustar00rootroot00000000000000Eqonomize-1.5.3/data/standard/16/application-exit.png000066400000000000000000000014151416454732000224140ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDAT8moLQ?q{CƫBtC%hFbIXHђWPx,+JFxJ0}9s3K$|+w?/ nqRer~/W0>:quC1%˓왚bAƍ/[A%KKfpG86>>\3R(*+5ɋ\B_SK,Ζ(9$Hh}c \v -ׯ~ǣE>EOݭB}7o:[ !{ݮQ~NaT*Uz ɐO`˖d'̨Sj0H$6ZxaP>[W9^a9gim}9}gu'W8J6Ţt bMCrI-׹{K9ɱh`76[q} >_N7:qaQty;}%~CјUg$0v{bK!SYYIvD{W=˭˘  S[ޏTx1B5Rch-,~]t{#9r ˪@Dz*aSzN0>Χ W!"`uns%Oi>5׼̙>qmDZY\Z"iq@kC{U9t'}Fy}#!I2,G+Ԅi|B5tcDxSxBM6 I2ãL, 0񘹼>@l2qoutRf"I:"/-p3f"6+* ~ǝ\_*VcY&k ]eد,W dO.0²,b4\N=@ߣbQIENDB`Eqonomize-1.5.3/data/standard/16/document-open.png000066400000000000000000000012401416454732000217130ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDAT8KQ?}oIkRK?% rjХ7#M+hh!EB-siꛖ`p{9+CCCD͆."@Q""}ݸ\Uo/,-9s@D'&_Lslppp936&N3cxhͳ nTUnH)[fz+D07f cd "BUU]keY"=va#AUM5s}Eιvp5bPRJc MZd;8bL; y/qk"K;ʢX JJ_(H `|LH)YJ pJ[GDY Nq)%SMPPXlb{ט dr4f4ScD$mφI1s̝lNVJa.X33؎l7zԝ, ܉wgm`^Z?q!SKwY^ZôldoKu2IENDB`Eqonomize-1.5.3/data/standard/16/document-print-preview.png000066400000000000000000000014131416454732000235670ustar00rootroot00000000000000PNG  IHDRabKGD pHYs  d_tIME  2+NIDAT8˥[Hs ]Zӭ,5+V. PXa](lқEC](.v!iav!uؖn7}=ȇ9p?Sdcꚪ/6m\GJEQtR*޷Gu$b UTI9^#GSŋ3vrArsh4'J;m.˫"g9 6HMME\.=EԶ~d L tMngǙl6dPb>v8inrfYLQ+YW723xrJ[OfT2Diܹ{{|Ne-?S ((;L43& L @ Du+VSBgpj9AGQq˳2-Y\.f@pcm!7i;=vcOQi1ihxH.v$k.,F>=(;XՋIOT)\ޏ B)::^L&`08{aaatĽRrrMqsu/_1IENDB`Eqonomize-1.5.3/data/standard/16/document-print.png000066400000000000000000000010401416454732000221040ustar00rootroot00000000000000PNG  IHDRabKGD pHYs  d_tIME  /텊IDAT8˥͊A{3@v Y&DŸwg@tD}IFFlLVw*:$N\hDGR|UK~.!;fq_|>+װ֢a(6)$5Tw5"`0 c690d:2L&F#!V_>g3X,Df3|' C$IcBxPUvr zFEְ6{1\Hic ݄ V+p .m  d bP 1 3A("jۤ_tkֽU.EWV !Nk-XO n۸~-~TIkNXҕ-%=ϫTZƇ Ldػ7 $Y6Z>{: 5AaAƠ`r)%,_)2}@|g6&ChB._DWW GKsY91@ZhƂXCJjQR$US[#Rk0@ ň(JS3N$^R3*X g迻|2J(i Rh-m4l#{WbVDkPCA"uol?{gc\8̫kI 5wH) w~?z܆ H_3^U@)dbx 5x!ɇv<(u}]GTLMd 6z9m  x"W%0<-=OJånrF$K`k`0,`(#/~[X1S0L[k:M txq$Iǎq!ϦR鮠5ŘvF~k@wX] 26gat]ǙWxvQF4VrʍD-iDu]=oz2@UUBH͖>W*" ?~2" 6/).f|| AASp8x>,%[4M#=Ϻ]W[~-j{hcc?{IENDB`Eqonomize-1.5.3/data/standard/16/document-save.png000066400000000000000000000016171416454732000217200ustar00rootroot00000000000000PNG  IHDRabKGDC pHYs  tIME 7*ؿtEXtCommentMenu-sized icon ========== (c) 2003 Jakub 'jimmac' Steiner, http://jimmac.musichall.cz created with the GIMP, http://www.gimp.orggGIDAT8˝MHTaL1͑QlQQ4&E.B(,V-*ETR( "((j["DETjܛN al6<=_'?[ظ3 T[&Ÿ?ͻϝ 4wt퍭Uk:#km'-Q7˺; <}۝;ƨf(ce#+s >b$y,%_FDDdsZzD/Hϫ/.wY%<r$qDxXBAA(W'n۱wp=/x|vl_PPP#wҘX̌M4єXi^"2"0e1.XͻǪ Q_ͭ{h\Î,4M9H*|!mkص)i8(m41MCRO-hm aPYYޚ <۶qy!<]s?D30DQ,@.x]:R,Fs4_;3L"bmIENDB`Eqonomize-1.5.3/data/standard/16/edit-clear.png000066400000000000000000000014051416454732000211520ustar00rootroot00000000000000PNG  IHDRasBIT|dtEXtSoftwarewww.inkscape.org<IDAT8KhgLHBHը+& ҂JKvэ" ]Rƅ`Ku 1-i411qFIe?O+Ec!pQG`s8Ʋ @4߯mڰ1zt^`qET*-XHs~SIՙJV|Rt}#ה]K뙋Lɧʕ7M/JDڧNWrUsK;=rT%'_A*vitsGWvjUC3F%њdS}k9$j&]toeQP5~Pν_ ` )RI(r;͵:.iB `dA϶Ր wj2[ԯVI8RwU{#e`g!^̌#^UVJo5RLZ[P">WXPFDJOz'yMwqcLL˥ep)DX6 EЃ18o #z)u=<p ݘܺy%oLe‘ߤYQ{/'e52 CC}Y‘wҀ1t =v咆?jӣkr ;8TR-S>L8xK~C(IENDB`Eqonomize-1.5.3/data/standard/16/edit-copy.png000066400000000000000000000007621416454732000210430ustar00rootroot00000000000000PNG  IHDRabKGDC pHYs  tIME /4IDAT8˕KKQ#3cڀ ZuBEvDDD616e007itFGoy;$3,F(Ͻmwa(z&vj5BЄ'sj^wcfnyu$IBTGE@QNV9TlGr(( ,˞H$?dYv pPRšz-,EA08vaSiJ%K дc,61Ӷ(XY^ePT䮳6֣yyrl;KUUn(zi.y}*($bBYIENDB`Eqonomize-1.5.3/data/standard/16/edit-delete.png000066400000000000000000000012501416454732000213240ustar00rootroot00000000000000PNG  IHDRabKGD!~ pHYs  tIME HtEXtCommentid logowIDAT8˥OqƟw-Z* nnP(8ijMM`RB4F7'u11d08rWzwrCQ|y>| ;YqڍLhs(lEat 岵M$A.f$IBy@f.Ql64EQ ("INyΊт h4`j"úDnKL!Vg"gc8LYd :~E @`P Z_4wqR\}T.)S{&Ъ MiZ7+˲QyGk~C^]7!Ztpi8#Hy~$6 #F ('t)mG^(,+"}߱o_}d$I{= XvT,>L q3s_^y)nr:]ͬ8 +Ϟ:өٶQKKEǏ$d"ݧ( ^zCQtJvM;N!#Lv B]wf2f_Kдkw߾J9zjmŋi+dk&nߌĢ5(4]#Ns ^R>q>sƕ]$ ORpsӶQ %#6Kot Kz Xd4,U~_e% EJvK0n \$[5ܪ-]pi-Nlc5ߣ-F}=kr+Bt4M¹|'+7*|\YT[z,?",+| 0p8TNVdT앬/dߧ>xtXtk뗧d3 ;e+D, Xmك١E&MADEt>S8zVO޼)c>. Q51Qw&zgO/Dk00(nCȽ{[a~5鈴@bLQ= &$dY[AOXZloxz.Ҽ6?_h8|E7sJ*hIENDB`Eqonomize-1.5.3/data/standard/16/go-jump.png000066400000000000000000000013231416454732000205160ustar00rootroot00000000000000PNG  IHDRasBIT|dtEXtSoftwarewww.inkscape.org<eIDAT8}Ka\K iF&J -DDR˨m_("EH&- Di͌:_3iǬgs8JDQ \( "tl}fv%:UQN6nV$'>'{clf ѱ_3;ҺGUW0}[r)2E!pڷKL*1 jj7Ұ{՟|`ZpMC,AHJl6{o@de&\=AoTVUc X hcdc;g?K1Ȥsxn'WByrlSi.K2/;xܘ[tl)sgrvlR@f21GpY@Eǣ9Pv6VUk( x~ԋ+U?cjJZۆ25|I=/b1 lܺ?n%&Fs'0۶К"IENDB`Eqonomize-1.5.3/data/standard/16/help-about.png000066400000000000000000000012351416454732000212020ustar00rootroot00000000000000PNG  IHDR(-SsBITO pHYs B(xtEXtSoftwarewww.inkscape.org</PLTEƜĢǢĠÝâß ŠŠơƣƣǤģƣƢƢƢȣȣǣǣţġġàȩ ˩Ȧ ɧ ̬̮ƢƤǤȧ ȧ ˬ̭!ŢƤĠx{ϲ%в'аֽFDUY`܌݋&)BW<=DScOirjoXbo|voswwxj9tRNS!)+/7@CKSkIDATUm۶m,M?*ID{ P8W||E]2XR_j~^}+fx[-Otюꝥ?le/4gYAݨv<4Bk"6/˩rIENDB`Eqonomize-1.5.3/data/standard/16/help-contents.png000066400000000000000000000012501416454732000217220ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<%IDAT8KTQs&6553"т !BLB M9I -Шh1!3f&YsxZFwuea( )R"VWBH/Fy;E< B{Z댝=ǞX#TVUg^1 !L yw8z8gLOM1=9ISYyw##);KqL0t0-D;ױjp J) ɘeݾ4poEKWb9n9.t= IB .X!F-` Apl7#--Rjl,*q误Ǭ9I, h(ih`p9g3 7gQt@ g=@v\VM7D!wN3O\XIENDB`Eqonomize-1.5.3/data/standard/16/mail-attachment.png000066400000000000000000000012111416454732000222040ustar00rootroot00000000000000PNG  IHDRasBIT|dtEXtSoftwarewww.inkscape.org<IDAT8kQrL/Xp3ƨ ^x@ HDu*lnՅY\9yxZҼ$YT1`H?U5,v3]ѽv676b,->^T<0QW\}1VVWM$Ʉ2IH8fyjk0>>'\mNC'LR\naر`w;c3VcIA4AWiuf f*H@YJ'zl:-@WTi'rZ P*(\W_20iv\ BG9q$VhX Gf( l֠I&d&o^7<>$$-kم&Əm7j4޽KRƵ͡?ڮ _<H}V<@Xk #!ҙt~$j> S40 ~) QLIENDB`Eqonomize-1.5.3/data/standard/16/preferences-desktop-font.png000066400000000000000000000010511416454732000240520ustar00rootroot00000000000000PNG  IHDRabKGDC pHYs B(xtIME   ϝSIDAT8˝1"A4pfbF{y% f?`~0sx%4M]{]-=腏=u]5ݎ|b@k}\EX,h46ZB)u/#l[:Ƅ L7)j5JciV(%c< 7M>V uY^ cIjŵ.KD$Z;A`iP0Df8Df]H\&ɐfy}ӗH'Gq`S*8mFՊJH$v$I:5URy8ym>Bf@DT*E>g6NL&j5*3fqm/,Cxϕ6[IENDB`Eqonomize-1.5.3/data/standard/16/preferences-desktop-locale.png000066400000000000000000000007041416454732000243470ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<AIDAT8;KA#;alkAD"USE0m|F|Atq#,Z$ Ys9p;wFX(Pk_fb: Ԁ=nt?2Oϱ0-"kDJ:8 2N2Hn]luR9P?**kKy֧H~e !=dI05NnZǘRJ<5=4=c%-Ny CTE#+[a?oGRP;@EC'aؾ1Ob&$ƹlq#Yt W2݁ 3fLIENDB`Eqonomize-1.5.3/data/standard/16/system-run.png000066400000000000000000000006361416454732000212740ustar00rootroot00000000000000PNG  IHDR(-SsBITO pHYs B(xtEXtSoftwarewww.inkscape.org<tEXtTitleOptical Drive>g `PLTEX[WX[VstqsuqUWSBCAUWSUWSVXTlnjgtRNS>QCuIDATuY B]PTKC|moʘ"86:f1nEV׈%>OY@y+^V.ec,N<%ڐEy' ׶NIENDB`Eqonomize-1.5.3/data/standard/16/tools-report-bug.png000066400000000000000000000013351416454732000223670ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs:tEXtSoftwarewww.inkscape.org<ZIDATxڅkQƿ{3W2SgkmUZ]h RT*nD/tNܕR7J! nZjb$3\8Yg1g9 c( sB  I@\j."DDP.?:x.y :(ZaTcVBJ7:Hk<4M1xafaءwFȾZkG>Mxpw &"(!j= {D6{<2_`;zA1 ⟡ġh4zMZ6D$a >L&cx|{-;$co]Dpkb_7,{o? ;e>|( KϬUK_ |;lW`l@hkɞxa(===g,67`I?08i^IENDB`Eqonomize-1.5.3/data/standard/16/view-calendar-day.png000066400000000000000000000011341416454732000224340ustar00rootroot00000000000000PNG  IHDRabKGDC pHYs B(xtIME 2MIDAT8˕OkQ3o1 af! o .RH#*"L FPh&H_jUiV pj'ӒE1BgX=7^p\Uv\[fnTWf@h6u%wmǵRJ9޼}B8*R*)ez?<<`i9[[ߨjF?7^izd2Oo4I2dc+ R)opi|2eaYi" x]ױg](!87gx8_@)RjgAsdx8WgrAӿj;d.σ{w dWhp.W f43=gOk40ĭCձž _M^l8l?3]X1/23ǕgƧg^hڷuS( wD-HU/<A2e^ۏ^,}?,az  ,Hc$UgnSui&vn{'v>Eq4Akw_?߼''k'W%߼[0j>AX-/?ԩT=eYcJ奎Go@W!'$_ԓSln\{&?3 DV%r=?JeFmXv@x\qqah=Ѿ2;}З|9r-k5tT2>hMA҄ǡ̖MD, z=*];[x 8wyIuI1MN<-I7, #?[FՕD(̗ˣRmcer-0{ W1oR ]!PՑl.UvjeIENDB`Eqonomize-1.5.3/data/standard/22/000077500000000000000000000000001416454732000164305ustar00rootroot00000000000000Eqonomize-1.5.3/data/standard/22/application-exit.png000066400000000000000000000021031416454732000224040ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDAT8_hE?wkFJKŘ bRDĴTQPꟷbE>6P|bE|PpjR5&Mzir]fpKr;> Q?M`Ʒ6zXpaN)a6uuu)Li~gqX nxwC2==MPu]RxGH)"Ji2rfU`X%ǶBMB>i{w%',ˢiOaUmp<'Hl@R )%e!Jw !*_o @+uW(z)E[P) *[[ugGx;>(QMeVhoo/iNbs:8t jd gffcYVkPg%~| vW[dHERa(ηr,ȍY O6Btmhkk#Wp KKzǎ4L:ll\mEgg',,,ж?I( AiYkPۦ M&y4RJv{;槣/|h/Su|;ɚVd2ǩLp/_]n.YX(ވ wllAmyON6#b 5ew]TTia DJsr)ys\Y^&DjuPJ)d2,Z=ܵF)l%|u惴No'Xubpks&[(UD"6B)`R6)dllc w ]Ϫ V+`B0??]{I$f (*w#y!@ycvOmO"0 "@yEDͰ |>v756{oý:"w\!OQ&_ w!%8IENDB`Eqonomize-1.5.3/data/standard/22/document-new.png000066400000000000000000000012641416454732000215460ustar00rootroot00000000000000PNG  IHDRĴl;bKGDO4ױ pHYs B(xtIME%0C& AIDAT8˭kaTM5IDL-O]abIv^NA)N6j } q޽;H(E j, {SVD42Nlh1D1le4NOьyxI/ NԸ[NI f6ƅUP,c+Ap{պ:˫c #MIENDB`Eqonomize-1.5.3/data/standard/22/document-open-recent.png000066400000000000000000000031211416454732000231660ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org< tEXtTitleClocks J`tEXtAuthorLapo Calamandreiߑ*IDAT8kLWc,ld.6?3-$C7b("C] 0DPZKj,--RF1."{B-rߙm='s9L~잧Vrr,U^!KED^b"u9)H9lD*C]mtua0٪,&9|>4B)7jx*q1.'B=FSS#Rb]`ZSpYWz O37,u5%NfnGUM */ I{)iKPTRDc##x ̗^~Vzc0;sDfDEEax؆V<8yz g#O#""8Q -?a)k2 %^㇞6d ֡AQVE0)@m>BÎ ^>dI߿$:wԍ`<66l:AkQPGRT\ᎣGSyZ{)עNS_/FƆ0<: }ttxd(d~ ;TJ8 1uꍘa 'U}fb-Fth ggg467`ҏ^9ZHJ2"?qek1oDF9 yf3\I* oEXl91Т3vw OCs,H¾@??y8͌,,.`aass}!2=E&0Anq>(аMѱTp`yyKKKX\Z"'"D%b1U1u΢hPPKwǼ5%HLJgJR?ݻwn#'GJbx{oE!@ LB}3![tKR]K{}M^^_7(Mb%.b $CPPSHGDByoVrfb{ f׫ _QgoRnޢ߹ku;wض|馍}O qeNO&+mɍ5WvnƉ / qr=kIENDB`Eqonomize-1.5.3/data/standard/22/document-open.png000066400000000000000000000016271416454732000217210ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDAT8OhU?ofv6Y"h6 EP=GdLsVxEAD̩g(Bjm͡lCI7ݝy{nwӨI1}˲R9sp&4MۻKg~snb,.~q|雥)`ι 63(rTPUN^<ʅIӴ?03TU'".]41'8sw\|`jTUpΑ)W5@FDx)wP!:-H"0r /T5h2cD*B.XDbW'܎_Y뵗;vg,hB|JQtwf3#rcs9׾|ͣClV{zbKGd[6XDKcffV_P{kQua+Uu0H؏ԠEW#:f a:^p# @P@nP#/F7B^ïrP{Q&;+1UD{[zEGy+GT'W"`lw+Z[}?l\;NQYм k1 PVv88n<l$:XDbj[bl6ύz`(@0Sm_#8y寫׫F=+̤Xrݫ Opa,2=eY\n0yT6WwaIENDB`Eqonomize-1.5.3/data/standard/22/document-print-preview.png000066400000000000000000000021531416454732000235660ustar00rootroot00000000000000PNG  IHDRĴl;bKGD pHYs  tIME  'IDAT8˵}LU?K DjkeDd5(? )[[$J%mG\FJs dsPL*x W.{s rX}s=iFk}I wS?:R_S%o+k}2 cTJ)k}gݥ瓖 FR&&&!?@_/r{EEŴLUNbAӴE9 6۽JmH^Lh8 x9L?BUݓIOk27be5q񇝍{l#)SLI8MxuaaؐJ9((KY{``sps_{yf3mmY\½{6Νoe{~>CcS#;^}p3x<^v;,@)Ł*ÐH)1 ]3Rrh 2${0$ 99qp:^}k-@ @HjFpul'8$IP`H9R :AR(i +n{&6p𙧳9}ӿ*N 4xLcc27?b0 }R 5APbyT^U@,Da)}w$; ߙN`!4 *wUoIENDB`Eqonomize-1.5.3/data/standard/22/document-print.png000066400000000000000000000015451416454732000221130ustar00rootroot00000000000000PNG  IHDRĴl;bKGD pHYs  tIME DIDAT8˵kI?$3 Q4Ŭ1N9!]aœzCHzQ$ Iv$o9caM3ɘz$QEWէ^U_=N}̎LƃGZ7tchYrOQJqARضM[[[ɗl`}kk+SSHR$Ia6e5 w.y^C(r^RSN"}',k98X5xвpqH$_!^E횺3ڈmƶmoAgg'e^cϣj83x"bc Zkev޽{ÿ0xiTu]RsGǑ%/_vƍSkBOMOΕr{3;tI::N* Xb: c\JR  AXFk & QƊX)لֆT*E 2JaH!>J.R XM!N9ٌy M%B5--hTN$"cQ˸ tI?G_oƫ/}Q .Dwa_E5%K4!^˽ɼ@﷔ o^|:*uh5/5@"jQ SFY^A>"oIENDB`Eqonomize-1.5.3/data/standard/22/document-revert.png000066400000000000000000000024011416454732000222560ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<tEXtTitlePaper SheetstEXtAuthorLapo Calamandreiߑ*'tEXtDescriptionwith a HUGE help from JakubT IDAT8[lTes.{)mmU H-^bDD#*#F} 6Q4> (&BB&D %)!v['/'ό*~>q( ""P'5T5OU囎;,za8ur,C3}Zc7+k]ڊW!T}ف` LDD<5X*,W3W씃ˁaVJ߱78?N.U$If~S^ k.zӺbzw]%.]j2D|R?F<6L룻:Im㸮W.1:Jո/tx8um"z_sEg9L7?QRM9~Iq12vz;i^:`Ѭ K߉}ԓX\[W|+M˞ܩ)XaxQkX2@uJe2 ?i=a$;­):c=ao)$jj%Iwo韩˕(]6Er%`%Tar noƨif;*lॅUXƘRۖ"yV'M^gƌʲA)kvwZ?60Я6vbP۾wߞX̸Eccmb6}p0%BFK܋/1H&DAŦ  >Tors=s2|?ŽG3IqC˥߼/}[GׅMrJRg(L,h$s#/d%%#so}l|tD;6>^}LO_Ąעȳt鵠~G/|譄E;o[~}ye}SscԩHjG:u}v=ҊJPSC䑏8Ê"DgHƣXDO']+fpR?+c'uog*Y!,6_8ҳ~Y2z]{7熱.~>:N墈Njev#HɉjxH$b>#at5gXH&9{l, s[X !ֳZ.D"ic!j寧@{ؒxs^[?}DBx,BhNwiw8/-CZٜ#-t5ogdAZU9y;7$e0R/r EQ$ IEWF7EAhbth*6م-wlL*R5P$IԹ612O:;6Qn *pXh$6;_nu<%IaG޽r 3Nvgrjo; dK,|B~Mjkku`0=6~j~`2ÕYyIK\N6&V Y3XXh̛,)xX yhC煵p:11ēmgYCLLLp'nJIENDB`Eqonomize-1.5.3/data/standard/22/document-save.png000066400000000000000000000021761416454732000217160ustar00rootroot00000000000000PNG  IHDRĴl;bKGD pHYs B(xtIME 4Her IDAT8˭]lU39meeY>"ڒVX0B4F|5HUR FilD4ȋh 16ƈ4AT%6ݶvggw|hwlPL'7s=3W`{?ƦH\om~8ያ#>1UeNϸT:CdVۻ_;rĖ"U[pm##J+PvutPv=ܹϥ:p+bkw'tO>P+Ft6N<@}A/.yYb5%3}}pG_6G$TUHNeRELhekԡ>;r?Ϫ I۩7/Jrk|ow_&ǎdۺe9bˊX\ *aiESx=* VU=XX< _;H Sc)ue~_`ǎǜDE5l;ey5,ٺR#WK=?gceMÕL9ݻcɊkG3 -GHp;;w\T$x^BJ @e:_ӵ'zݾ O=r=l [l*7S΋=0eьD~?Eͳp'#6.o`k)p긌IS Dom Β֭R Rh9UM\\.UVRsRaOciǸŘOƓLwJ1}=?;e y[VF~|7!mdjw4D%o3Z4=膅?] ǢG~afoY"BqI44=M35/5t/+ Gzc*`{BFlY)eH'aZz(nUO}jR:k5F52R"ۀ "(Ҏ!'yReR(+n#vw8k< IHL섍=Ǒ QT/BUB vo>&' )bRJl'H[+[/bDӹxycXBeGBKMNAQ!{] E$+x%?돗zz`B(Bd>ڳQ*F31<1n~{OܘX(BB(IR_hiPw aq}c ac-]/oL޵v݄7@Yz"#;7Slil_<wٰǀA` ]wX')wq!/m3KE8S]rں D 7)=IFd.X"S?qS |i5@C@H(\ IENDB`Eqonomize-1.5.3/data/standard/22/edit-copy.png000066400000000000000000000013251416454732000210340ustar00rootroot00000000000000PNG  IHDRĴl;bKGD pHYs  tIME 3 EZbIDAT8˕MOQsLt_vc+W&.](Q0&D!qƭ+C $@k]XX"2әNٴ9Tyv1CB4>[q-,O7N\33YQlWdft:r7$I03O n6FGnn "3a}B[hqD{{/fB9ǎ>qm9tzدhoK^o4~=&E_6i||<2||s.!e^Ĕswwvv(3fdXY8紡3u.oml0`6PQ)juT676֊EMbʌd*<֗9s`=&R AQf.ӡ C,( N]B`d2Cn3P&XEL%棋h4zp?챆 [U?`0Ps1C1 0r I-bKIENDB`Eqonomize-1.5.3/data/standard/22/edit-find.png000066400000000000000000000021021416454732000207740ustar00rootroot00000000000000PNG  IHDRĴl;bKGD pHYs B(xtIME .9w IDAT8˵UmLU~Ֆ-v0&-aF`3l| 9bfKe],2"q"Ĩ-1O.ATFZ"ېvRJ{?(2ěܓ> O,}16?0ư'rמ\w)cQJ׼cLk OH"˳kNj ֥aJU)+]6tn,c]~/&2 APYY>wOqY9|uj:tH<AwwƉ+Ycfg8h|(na,dʂ3J;62;zmtTى7O^'cƀNB /㛁)ٚ͸nBR2N! WK,K]$ ߋ-[103|lay0o0иc$;.tɻ%qs>\^.'DQ@ Me ZRG`fHJ`N@(͑A-bhBF(10|0</| ͱW9tpӲAk]ן^,@۶a_a[UNUtD2H$LeYDi/T[lE-Cαe¬ί:9~]y K8tۃPU@.?q ǡPk `AXZijR5- ^x_{"qOxHtRtw3[KOrrfo2"XF 𾤰ɢ"8GXtUXT׌N`f"T^w`ykkB:\XtF,sf}gjw}xswmik)Y3٨. ~G.oƒ}f-8T0_g; Y+2 h{ҁ2+ښ'2@9?ϝK2V4 Jspmhhh t[P}צ+ ꚑzYkFWW#+cQ&o:13Z!~]3R 7;ERM4O׌'1s/ء7%vwV='?㈮I=a/[d1@%Uf>\ϱ=l5L#mަo9""bDW(mk{:7f+əAk*rP.n;;瓫̠5١v#)%y3? tR ID#{jVfWr0{ rMBtIENDB`Eqonomize-1.5.3/data/standard/22/go-up.png000066400000000000000000000015551416454732000201730ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|dtEXtSoftwarewww.inkscape.org<IDAT8Mh\U~y1Fd,m1ŶBЅNRl) #.YKlRAp+?@\u"P BHݸ 2&LN;3ȼRK9p]=+ffF7tl6OMi'K;Ajۻz1b`T~`hihϑbϭ{'֋bp,K(ϒ{tƕVȷoD_޴Gƥz7āgKWjX|=YΝ wxpRSgg{'-.\gx~]FRgzURj~Yk|n)C[wӕQkwCwTObS|`PxYC]=}wU ?f1NaX =i BP0#y}vW'z5 8Vg__W5ϕ`0AUV~f$wFfЈFm ASE y^B +8o0N)6wuWȲ9)dk͸ B(IhJLQD "Jˀ|U8;J ", @$"q6w6u@kz&"g $<4d$S y6;Il3lIs$WI ,IENDB`Eqonomize-1.5.3/data/standard/22/help-about.png000066400000000000000000000017251416454732000212030ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<RIDAT8kU?yϛ4M#M:f7Vn* hAM^0v_ndhZ]: [7f-,M}񢙶.9y/gS{*KI92Ɛ_';t7ğJu?G+xb{!/ukWI$?WI'xjDz 4ҭ^.f٫d'҇!QkGu ڵP 6 ߚّbe=s//0lW9z,O6Dυ#-Iк7Op+(|e2s⅜d/3{*xݦ>* 7؆lC8z^;0apK߬:ڶoX`8/šUیr7Z7D{'{m>sڶUDB{>69PBr(q"~:z@VZzP^8܊Z|O>l:6Ţ4qfEX:tuQRC 1Et M 5oaʊC{0on\ס4ж Vi*{oLbiqGNw3eǗ E+:KYy9ۛ~o;xr].0Һ +#ՁrT1ƅ dF\.893{+|[,Wmn1| %V<8 @u#oW:@TI;+#}Ɠ'r'iEp S}2ջw6vY !Ie"Y,O}%?8CN$e,(ss8~3HٸG=MEy=64/Fj厎XxTu)'B2Ly[OJRHӹ(byg_^$"Xll^UORZ,U]JqĤ?0IENDB`Eqonomize-1.5.3/data/standard/22/mail-attachment.png000066400000000000000000000021701416454732000222060ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|dtEXtSoftwarewww.inkscape.org< IDAT8]LSg9U@H) n|t("L\.n̄%.פ\&ʘebY4EWqR3ç-9Dzi.(/w${<=+h}N{pTtU`nJ ׁ*NZUU 1<<%=Hzt(~ߑ46t"==>ҨM3| ZY%f3fY[*Piڥݥ{9 T['5յt{L&Q(:QX\^. \Bi?6zzȲ|Y>x!pڏegeZwܥx,@cD, -_=t~S֫h pᴏfsefC+@$?w7p`0?o++lu|^r% Ӟ%aSf,o{;\9u;x,F_$K? k€lAUUnlux}݄fB288b6:uϺ]5anIѧ~ZAgW;nKLNN266^ݻKuSOQw M̧g|pXr% /v`43~Dp4hPh%_+tQ{pa?"zN?I$fۯ܅`c8 +[ -fOʲ˵Gf՘( "]<ڨãSTh`0~ TR@[EY{*'SSRkU?3>?4 M[h%ͯ}p9sdѮbrDd6L`/ntn=tU  4M{Hnts#tMXHKD O(KxXֽAб`r=XH*j ?jŮIENDB`Eqonomize-1.5.3/data/standard/22/preferences-desktop-font.png000066400000000000000000000015621416454732000240560ustar00rootroot00000000000000PNG  IHDRĴl;bKGD pHYs B(xtIME ,fCZIDAT8˭MHcWsDJ">,% VEQ:uM] YB ,Jfq7+RhF]da""%wxID{>*~x | ]`;~" *w:ThuF2lm 쟤ib1^:5a! 6\w*`/{!]]]* R*<3XT3fg ԁ5x.cjjq""r (kkk133eYupmbN8Fh܈d~9onnr~~NP `L<::J6e``>_\wYmy[ ϹLx3..z\LeM7doh߼4 g PLTE@@@$$$Q]QUUU11:088UUURRR .44169399/77JJG199#(+ 37;"''X[WX[V7<<;@BDF\^Z05616939;5;<{~}/47/57:?A=AC?DF0683:;7=>8>@7<=7<>.46PSOUWS.4628:38:39;5:;5:<5;=5<=6<<6<>9@@;??UWSVXTikjz}{ƿQ@h2utRNS  !#$%)*-.:<<>@HLQSTVYZ]]blo&B{pIDATc`F &TиbjN-nݹyօTa˨۾~,QElTk\&eDU_xS '4g_r)q$;nXX D9u'Ohyja!Z7mk<}9DsyĄ½Pw{7ωb^XwʺӫOz^>+g2{wXrÑ57ެ/5uߙC *5%c :ZUaf{k酶4j(00] 1IyE\[a6F;S&#n.n^>>^n6&Ff~Y--YAFF& `d8# ;#"(]+XIENDB`Eqonomize-1.5.3/data/standard/22/tools-report-bug.png000066400000000000000000000020701416454732000223610ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|d pHYsaa0UtEXtSoftwarewww.inkscape.org<IDATxڵKlUy;3㩓u┺J[(QQ*E%Bxl+X `UvJQ@U  Ħ*pPmx<K' ~ϽsϽc q\ő$ *3:P(G@0$I^Y~=r8ϛ;EbqZ` ~Xl>mW& ?Ay %㻴dvww_$\ֻg0 a=gd3T\8xBF< C3gH$cT[6{z.JR<+khM\.l̼zmkm;4eJ ]2/en!zi&o(Kȯy1rg$x3%L\|Rj-$+^ Qk"? !<;w;$ }A=Q߄5 [^;E ku4_0CT+? vl' @rH_XX#h'ƿDV2*N* Fg~8X&r "+kWwI"0I>]R7,is/mHl4rTaӄcJ0f4hRPXd Hlw>}:&b luڃ4T*Im0㎿Da}J1 CQZ'5򣪊RE0"L-0JY'8"?K~<=tKt6{᣹\NTJ/a EyU( ڴ-K§-BPzt9۲31f3~rX9)pVƴ/|Y7h 1v#q@9׽? >y 㡤kJ4BBIENDB`Eqonomize-1.5.3/data/standard/22/view-calendar-day.png000066400000000000000000000020361416454732000224330ustar00rootroot00000000000000PNG  IHDRĴl;bKGDC pHYs B(xtIME ᙛIDAT8˵khUɾXAjQ!) BVZE1h&Fi#mBQkM~SJi_E&-mG #*^89;79s!ʅM'О7ZG#&T׻/[CGl;x#K'M-'o/j$=.7{U c#71f42lNq+} c'ߔti\J177LΥkv۶I%ut58~wt5k5ݥ_}=}G7? -_^MMtV^|߮ǰm~l˻ p455a*.p]]݆` c RJ>K"4㠵ĩS[ZZ?.8a޵.[yum[x]$F(TKEh M륕qR~935ͶOB @k~R BȾtuvb$S)fggm v6-4x^aY?B1>7n$ DDH)BJ)„ׅ(ؼϑΤ !`$rPi ״ևKZ㭬zo|WƆ;mĂ9<,oB:^|wXVcLVi{ʕȳ .bG" hc c 1F` R@:,!J]TlDIN@^ P{4@XR@8g`?ODYr)9.9@q.Rc~`/IENDB`Eqonomize-1.5.3/data/standard/22/view-refresh.png000066400000000000000000000025241416454732000215470ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|dtEXtSoftwarewww.inkscape.org<IDAT8iLg;3;K9[kEh&1iOM&415iZ$54iGb53LNUxO&3E,kÓ]zCM/ >5+5nmJ_;$ nB8,!Xd1 CH `"wĴUtyh*K1C!vò)B0cK`e)N,MZ.j\귊Ԥx iNl.HH01HK97rŢ.jHc,ҎGH^V@s>⪦1ǸqFO;Jkdl9ƀnL)@VZPv>,}\Gyd\5Bi^߉ հNITɰHll͜3nӖ)?FU4/],a}@8qܝ01kr08Đȁ-=])nJXb\d"CUzm)c5;_ft/EĴyϋW 3tǾg'NƐ֐8'k+z"0g4C5&8߱im˺,7`"0/M.R]MG e/$"0Ƥ FﺸqQʝ%իOMQ2ScaC0L ]qC=81raa"gu~s=}5)++ZZp:UFLߟ}6uE$ }͛ /PDFn%! !F\GPѢ1&́D a7oEcD0Ț)i\r`IENDB`Eqonomize-1.5.3/data/standard/32/000077500000000000000000000000001416454732000164315ustar00rootroot00000000000000Eqonomize-1.5.3/data/standard/32/application-exit.png000066400000000000000000000032261416454732000224140ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDATXÕWklUfv}Jn[hEP-HLHcbLQG"1&&&J &C£4h $6VMҖvcvfL6sgաւ END~ n3,` (//ǶmPQQQ4e.`_@gVwoޤk)$DĘ4P[^e1~$wہ<ƈ5%X7u5% .Xd 6oތNcK1>~Pr+1Tn޳^+?bl(=)'kjj҂|N 3/a ?v-yI'Onʾ:@TUU455ݥbr_+aE*TgRs}k:ϥtmfیؐN}vtadaYO; ]J}~JYrkз+;֭XfљnlDPĴ;o+J}J&Ljq&EUcq⩓'IX3n"k e۱nMBLbODG 8 !4S wJ Ĭ"Q(@<-b> *! xF& ǎZ4gaBTedHbcPؽ.wDFC9IuQ|s؃ zU%W H<ɩ xzYkd9e ^lrIPo3`Z-0ASZ}O6$W#yB 6$fd=u0<2B֯m;#q !@,#r2{_6aJ.YL..$i3D05'#Fry=ju6;,^zMq^aӕ% X,_zEB .GAq$KOjpa!S 5֧=z sZ$45y;IENDB`Eqonomize-1.5.3/data/standard/32/document-new.png000066400000000000000000000017601416454732000215500ustar00rootroot00000000000000PNG  IHDR szzsBIT|dIDATXŗKO[G3sm .L %Rd n*Tj.*FAjC"5ܙŵøT=hf4s,_l'n`m[g/B;`}}\.1c' Cs}w<^x;LOoWxqζj_s)Q߬D"0 cY7!45)H caNj9GXnӅq"lr>VjD0fTm<еJD[< =$>֜#{/U@K8|1ཏUX#u[^csg zb&F 3yƂ zUFdoKqas/@RhBbj9<1jKԣJpݝ_/n 7AFSWrY?]W8i1iqs^E/Ӷ9&P? 2ŋHarfqL9B$7 œ=,7K/@Z ¬LUi&@ו۞ ig"@Jeh):FH<6660f0q4da^jee%bJR8I A՜3![RC0Ҭ,*H*Qz䁻[Y2F譌,UM(cNU\.Ag

0]Amƍ8HhpM6Nv;=l%TY1<4rdI5EaЛt:Ԁt:VNyzRyfmlzw4h$e7A}^&gw,bNu.su4Zvp7T%M[W((K-N(hn {qP$uڜӋ|!ؐ%Y9' {H"[Zf`'J%Sie $6 FO4uij;U-xUG:;;M @1`ǁy =VT"N$`@dQ 9d⫑#5{ ^;v CCxݓ#}|xoh0aVc Ԭ@ yM+nGLǷ lNY,F,Fy 333 '-T 5(#N{93+ȒgjtZN2YlxjTafzthFlnFf^mlZϚ 1PaaeGCNЯxS e lp69*cʿE^z톉X"h4Zn#IfFH$huqA" VՉ|23O[IPޞ\&E<#K5kQ/xrr%S.Lz7|j0vBvieȣ(g&N}{pu&LvnPt-֖ʪ_95;wR2&NEc1GB;i(urz \#}gu6 OOFAIN2FǮZ,`hΒkh\O"B=W16( Fr1Sx_MCϻ~{N"ȋ4UC*Н`08:bD!=ł+$$ BI-$$2N80H !h3;3Uag{gzfF#}DE|з(.T^ObAͦS3yn_zw;Y}'P.^(Ozq#s1q̷N#y{㵷k}3˾__./d!RBkRJBTU<U@eiV7oޤjcER$I?]#֎o(T8sAR:u c ys]w~g(1Ibiik-ι RJ^{UYyc<À PJaCt:ۍ .ƘdBiZ6V=J)jaͷˁ2A=?,رcIQ cc߇Rs#+eFCnmmO:jW.c EPrv]0??oVWW&>t\}!8 dWF{nuFΏ6_;oFz/_`105c ߒ#>3?&AU5YftYZlngz- w!@ &J*',Iާji. 5ޥh9M?35$g/nB@YKj<5pba71d#Ԓ81kmjGix@"n[K yTE?N3!\cc;&w(%X11H-xQ1P~ pԩO-֖̋jc8Y&NM]\hmkj ؐ1enzL^{1AQjƲӋjj!2unl؍ qf1ZNIFOs`0խ思SnČ$-;GAFߎuZIsnH;0dƍYu gDbl\JNre !iQԔ%QP*BUyK hJ|"5DVT( 5)m 1[~އw;3~ڱy<~鑎tgfsvݴml߾}w.[C|=7nέ68Ϊ 6op}ΝPJ'qL"8>H4:^acF~]7=a}q"r 07`/U+!1x'?כzb̎“2z{pxnF)_/\q0禱|=}`FZ:2t:Iۇݲ,,˺{^ykT37aٶ?ҳӘ`'$eB*%Ls̛[ybޓ7&s ryt&N`B H)QR $UC\2׮]6LӼ74=V(o| #$똦*`Rη:AUtLAѕ/0q=\!n-znYYAGMUaZ%dE"K* ͢i5XM5KxGBW;~åg3@`h#T棫 c0CQ`+5l:^J*ʕ˄B ^ZYٙsݻá>n:;G"ׯ_8OձEz6Ko*˅.]2!ɠBpSę3gNqvھ;v:LG0'Ks=zɵSV!4z::8(EFbhl444dYnR`/^9Lx<M@QyT)u]<ϟ?'0<<` d2"{{{wLNNTe<bP%m=Nyq ۶C1|{WM/`RI|%bDuuttbvŭIh5 E i~o$?zaaAed2cccTզķtuureVWWKR/VVV$}133ӛL&HR.//I$j58nmm}| r%q-82۶ś7/u},J !8=}(C4RBnT @ iܬF@׫Xv5pJ!ǡX o8YaF{q޾۶x60iDJD(jTTUEӂujtzi!M W_cYV(~4CQ^|qC:LLdfBຮuq=|n+cj Ԃf>ZDjUb@߽{ $IrP=k.$IRB~zzҟ !Z\rw@~5Q7H=ſ ,/\@Q@}g`;7TUIENDB`Eqonomize-1.5.3/data/standard/32/document-revert.png000066400000000000000000000036011416454732000222620ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<tEXtTitlePaper SheetstEXtAuthorLapo Calamandreiߑ*'tEXtDescriptionwith a HUGE help from JakubTIDATXŗkl쮯;ؤH! ڨUR#zQrQV?\X.-(j(q \;J l ww3_D2=;gEU$'|=9ZPswDU}9[6lRRl~gKYlە"# Μ93CeK>KT k-ZE-ZZŪEbUu.rɩLɭt?"—UQ>0k'jԿ?NH$Xʚk*޷~@T y B >ESc37Lܵwߞ]W$V:} YL"Q#B:z.]Zoww?qu6G-eH"X Y|e*lɖ]_/%#/IR4uWVK|~|X~Dq01UeppU_mwC[im=k$Wt)_CPYYI]} [[\JuU5+sfuw=p$3,j R h@"ƀB,kxmɃSi{.h sOieޓGӰ/Lj^.^XGɦ#b0b06;GnZ7Y?-x,Ag&OwVܲxVld1) -!RvhY3f2ED$|}2!^_;""4}_ @$g1՘hw6 B ۷Poz1匜xkRI*rS&N6q;SAĀh.IH=ܶTT/$ƙS}X~b2+ lKa|ǡߝ JO%>pFn-VcOD8 g>Alv6xJ($ȼ^AۊM39=KJT#n=b0Oɦ{U1*~ rwD7H6*`?#9zc]L^}6ᑙQPaH,kwAi[v#Ɏ&6~?|ܴ?0֘zIL{Cz}>h4uKnH= mPp7_bXaGʶ `P(>\6^Us|nh=-PBшOh_/ x Zz4Fmv2z%ݭ$dB$eQ_kzؙ0- ~ȼ W0@iz7/U"Ek7{~ԶǷLK(ls $.-ȅƄ.׶Xm;DX,JCCQBf8*.\pDDhwpD­89*:M446`P\zV* ɩ-R"ĥx<>˸t:M:z{{E nLy~oPeJ%}oGK& Xx q (S0= Lv=([Vh9j+ӧIya|_q~dwz{_B.{, ͡x]yb̪!maIDJped7.u/u[0y{nDYO+`MR7f$*1Drl>Ikכu{"RцDMץCSw_>s򁊒ȸdڣ0?B, x]sU-l%3%<{_>YXsr+1({pwrek׮ lw-k2&5/WD-̆U|UڈsO6ƼX5rЋ04A5黖W7B(([|= ƘlRJy8ۗ`hm]֭[܌2CW\_ƐGIa>ҎsN1k׮'^O_] qM^x1~ﵽyKl["Z1,Ri5&yu훀kWV} -ˢ~F ?8WdaWXR`[F#`eH)0޾|3ϧZpϞ=>`X.]J20qT`2dw8H)T :w#۶Td볽ySyr+_,17z~zW:{/)(1t_= O 9caNZ18@ߟvpp2ʶ$~)g I ڈ+~H$IJ ~kndvj,ʢg_|/TWJ)w]={';Z[٦Mvvv" 74Ɛwܶi/hmIv;wb3˖-F"͗Xd-|>mcPJ*D9wfO#+(7w\0(#u]:::l߾]^N,Z6P(RQ,)h7sv#ϞF,­sy^cqpyAmxG2dΜ93>"!V\I. 1&D,Ï6si92ϑ`g3>RJRhq]ŋcY֖ ֭^Ѐ8(H)Rrooohw` Ch(++CA.CkMPή֯_o"Q|'HljF!,[CSlJSDQ8dd2y8)%H .Å: u%222 ¶eY$I`ߜN4PQn#Dkz,_ߑRJ{R!L2dddgϢFʱ,+4ԏb1=g!8ZkL@ @8\ Z%>/oX]xIENDB`Eqonomize-1.5.3/data/standard/32/edit-clear.png000066400000000000000000000032221416454732000211470ustar00rootroot00000000000000PNG  IHDR szzsBIT|dIIDATX}l]u9vm׭vٱ=̈dVS6j1bD F 2@c1D]]DCW>޶❔tv7wrr9s~})d}hf7G0G%![mk\&ov#7=Ef.ҕKf?r(FIEqaV3p`Wx1;ssM|9X39*kVz=-R8 4|[]F 7Ϛ/)>i2 M3|һnֺ#t={㧓sNJCS2TUٜ;0;;϶N|;5n33N:V!b+`Az%2N.cs僖K7ߺ^=@_p8PU}aN4# Njʆ_[ƞ9X` d jCti=|0gt^6}a~ )a޲(pbZ[?0mQ48"}8knV/~8GmaLκ6īx p.SRD|ܶ]XXdsA\#0jYȸ x wcz!>nE1 f'}4F t VZglvӈeǰ9°!OQ }/f@Ѱ<Ѹ@ SJ&Pѳ~-A,^(.1j̥6mLq5\*GR3T5F %nHArvXMW=V.9Ok`W3qCUAdtuAHbh94JV3yylG_5 ӉHV줒 2AJʋ<^1 f&uRrz x+#uCB":ER(*qT#GR(e5k~oZ pZN45EN(Jd8 ۸sl2Ֆ6&}l:B`|(_;0Z):^OZҾﱹy O&F<9T̩hO)ywm)h.B)Qk` Xt!bjS\1k]@!49)IENDB`Eqonomize-1.5.3/data/standard/32/edit-copy.png000066400000000000000000000013231416454732000210330ustar00rootroot00000000000000PNG  IHDR szzsBIT|dIDATX͗MkAxI~dA=-F'KтxWR-ţjU!I٤K^f<,;􁐙<8h1˅MY54fByv3/j(ES|>O=t%ʩDF5ոaPV%{˫ p`iiIy "%" a0Y"*Y!"OXqBT*AeIe tС( Dsev`px(@&,T),+ L]LjH BSU(HR璂~9BxHZ_H"D0n~$?T), DM c'a)iƘia IbJ{"~{b`{ fPi&"<|iLp4D>.k*q`n9We7;{7  I*c@O{a=?\I ڵJXup1 `6}9Y.W& TD"i҇1!}3?NP]zo.'[F񩤰nߵ1v0擕յiט{VT MIENDB`Eqonomize-1.5.3/data/standard/32/edit-delete.png000066400000000000000000000040011416454732000213170ustar00rootroot00000000000000PNG  IHDR szzsBIT|dtEXtSoftwarewww.inkscape.org<IDATXW[]Wuۗ9sfN3$M&Ѧ R-xy*} R+} ->ւh*AHiSۦA3Ld.͙9s}u߇ 3әPeֿBmx(C"Rʙo;;o#PJFU`l?z0"fF3_Ms "h`fcŶ&{{ z\ Q k-fggeٶ"yFFF+O;gxZ<=6&8w=}m ODӹ:Nf_wn?8F[crC6^g]f.v3ϝnx:[ND@s։{vt>'_..1sFM(X9!7=|= 3;rFIENDB`Eqonomize-1.5.3/data/standard/32/edit-find.png000066400000000000000000000031441416454732000210040ustar00rootroot00000000000000PNG  IHDR szzsBIT|dIDATXmh[^]ٖ7َ_j`[RҒMIf4Qؗ 01ePɖt]^x mΛ_f/8NHeɺ{!)v¾큇sAiJß1<4}/ܲf|Vnfx3~V:B21H}{9j'o[KU@)PXBޡu|Z'uouu󝷿Dvr)N S,sQL q;?ā0_}%r|AƁݍwŴž}/'!m{Ť{vos{ÁhNMrQS?4ĶۙGJ%Ⱦ (2/7f "M CZDZ`CT[,3Tϕ\u7e az~ SϰLk E I Kw-r{0t$@y&MsbH`ˢġ9q]L PYI34m'#  N#K* ̭UWW*}}]= /?wPeraFZ1 ~sss՗xloD68+$2** ز`G7CLMMH$n\RѦMܸq(羽w~!#3<꣺B0,F兩n"m5%IϹzcc /Auv2@"6>'m \l{&thNgΜYb!Rz1MVVҌ{*vCs:1I,O?PDQ4Mc|b1,ŋE=j_p(@4Eav6(3wI.'~p8B=LϹ_PQQA0n0??dv>ʵkWL>{Ote5^=A_rUv|8P`]s.8R>EQmx<z\ܿ%]IR,//L&I$$ 8TGbs۳,FZ67 vzzGNS k`)FU¥K;vVw X}Psj W XXWCf*"X VBh {H$JX: "|^X}rNh#!+!)ύtq.@xjOn=Ff1k g?ѸDOo:mA[z6R0*h@'^{ZvwS_'ڷ p+ȤkY=E*&W"r=s~Ӊ t8s5^μbeCęWƻ) 650xsw{̘<_B_xxp~"[l%4=3ko}*2捦:.v]:os :8e35jOpV~cS `(QJTuVG:k䔦#go] U`^0i 6~OOX}}~9vԵPf4x:XXPQf6gZbRз  uO^Ŀ5/vmIENDB`Eqonomize-1.5.3/data/standard/32/go-jump.png000066400000000000000000000027231416454732000205210ustar00rootroot00000000000000PNG  IHDR szzsBIT|dIDATXV[lTU]53iki+TmR@J?L5ĠclJM aL$Ah*3myX>g:<̽0SNv9}{f?7]Hx~1 9QFO5}JC' }jCQe8NtuojU)!5.ٍ*D@.$Kqҩ' /\Xbp>U L`a1<I1Bc~ $ D5esrDg)LŸ QLHEhmkS.^m@ཟ!B^ر2'QZo93`t(m5 ;ŸϋK/x^4GXՁ=kzS*?~h$Ui r͉n0;9r L* <ѣ8k=unkO~GJCZL|aZoQ.G-ߡob? s3 'm\,>HJy#3%'kḻ89Xѯ}64{KC09! 椤%5u RWs% oj%7r"٘</XOҋ\[}Ml_ %*8pg ]aXyљ VaG3!^CC$ɘ{NS# j'>yts@{c{4S}H:dlj Iԁ1g& |@t uodВJX:FDQm _|*a2#mհW$K=[)aӊ+z}$^ICtnq o}; 2ML=P\ Ӝ :U)wK:]U  BXTj&x~r\kAOuQMY2pe`Scy# ToM(Y1N{eT4V`.cc<ޜ|_#,FƜ/B yYO>u2%2,g#ڻK׭C jyS5֝`m\XpS@w\2;Hen;%/Pb )٦,g6[gKo,tP`M5U)HM9}t%2MF-i@CV@dH#miH͵ &! Zh積EOid78D:hfuXb"g"@KF-Q<_m-}mIENDB`Eqonomize-1.5.3/data/standard/32/go-up.png000066400000000000000000000022511416454732000201660ustar00rootroot00000000000000PNG  IHDR szzsBIT|d`IDATX[lU5{OO{jCXD$JZM1T%DLDD1KO $Q  Q iz93{0rz5>==k ܴ봅;)bn4w=)_*6̼}W~[ -+3-rJ= .?_)vMf&Sl_rg>#0 .lU6LLtb&uk8--NCZ`ĚX~[{SnC:Ѹ=1g֝s "8 !-Xs״es쮉+PQk*]ʲ5'0idOGo#K{?t;JM?P^k/:c3U㿶ӝh5<?CقoNV\:<^1bkX,U-=k`^<&_=meunc ]_s_j:~n %+ }GJw4ڵ_VW/*:]N@U#QQcςg1J@E?{3 `(|~`%5ߐ N5!sHnax-]g\Xm[ۛgݶX玍5liY7hލ5;!1ؙ} $=m8 Q@*5PՁ ?\W~x0[f_p*tg TbAJ^7``PP{;#$䋑P+K_Ə$q\?GB;9wNah~ @ $FZaRKIh$Q:Eya&.] c)MalTfπ+PPoԆ1πg$sH>O m UIQ#:c  022i 4AzGj(VW_?T0R qP554Kgde2&l˂CD3CnPh'Ӵfg<9ioご|~IENDB`Eqonomize-1.5.3/data/standard/32/help-about.png000066400000000000000000000032641416454732000212040ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<1IDATXýklUϽ3ovt[(E BE)bA0DD x|1%DA `!b*h?ȫ,K\Nt t{{JT [O^ If׸iZRJ9[}Q/^ܣ `iA:fB`,'~~7_>K<3H_XVȴB M$,[ᯘexAJ96rV_E{r4)pƃh´ @8~e`\9 | Kg<V62x='dL\VH8O\*چ],.u^~/'~9W J6pk֨w0ǻF mGV#9UNo V XA6DmJI5z.USbҡ.7@" {X vAKnP%A2gC UO)p¡ϣ3p?Ͼ_D? `N)uV*KJl(n~}MBa:dv{= +fv.n=N}vUEw^V_ #vaрqcLW T]% s {v|8!ZHm 798ie"Ihƙl wI([ǍĴ,FvcF3Y?w*:Ϻ.4oNǧ'%4BBaG˃5D/[źxXD+:@83H&,a[4fRRܗ*s}P ; dN<|/3ý^> j6$`xE`&uy\Ab*x X^d$1@ڼ/oXm{̀*ϱSC'x [NT'/9t ,l 5nH ,atūbڽb| yfsܥsgvkgK <3^ӊ@_LTB7 Ecۧ\IENDB`Eqonomize-1.5.3/data/standard/32/help-contents.png000066400000000000000000000026551416454732000217320ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<*IDATXWmPTU~~Ҳ&8J9fc6:T~Va2Dưǩ*LL)| &,.}smwVe]̙uyyιd(UUUk,&NWJ97bѮ`Hzkh' LȀYT?nn:iDh&x\{A3Dg*,oJm.j~ Cx}p@*%* 314-Vi]L={Q.e@FU%^'7: `KMiV?yQX(s Gk<#w.9`鏽 { m|t !Lԣ1i`&cڐfH" a\1ь'$sJ= Ͼ)J!ҾHG>6M59SH2Bu tv{QT, q0S*d҄ YJJtW]+{r?f^VScFd)"QN*wA|ZXXzUצEVs_w~a ogxRqȱ-[v!IP7i%LMO^K{AgJvg{ɗ|fP'TGk͵e {ڵ߫5ؘL(^&HRAQiۨѪF9pt#LZ\+4ւcqT18w[Z)iB )\zh^GzгOp*5p DJܾ /@fͯ?VYY#1([KxP(. BSNuˋ`0Cm0WJtÅm۵.b[H}]Ci2wbB܅zwkR!7`,BL+/ 6qÄw^"&u?JG f|ya{k6\v]B"8et؏u/BPT:vVV{ Ȍ ]c055w|^l!NxJ&֭⺌t:}7Т||o᰿U/Y7}Fq|!/Ʂu ,ͬBXStV7&|9BmXary.q :N$7{ bZru CBB:^:P߈+× p߄.HYn?kEHd f?HŤnBH#G_j,Cd2@?OED#ju9?)_zJܸ9Yw*MU|~9vIij0#(Ou3`eؼy5ph4f_SiTc/'"%gG`$āWT:F%} *+;4|+ }6;w=,'w=KR'ޣ,땬W랩ojx\<<~OިkgV3Je*ﮩE4<3s iu`0P $?vZq)=y20sKeJ RX\Z9?9~ (gTطo_USsO4r~<er+\ʒ\2 :s>dY b%Ca1˹&H29[k98CIENDB`Eqonomize-1.5.3/data/standard/32/preferences-desktop-font.png000066400000000000000000000024441416454732000240570ustar00rootroot00000000000000PNG  IHDR szzsBIT|dIDATXMhSY%~i;c;3A\XAM,])f*bW)4tf1* 2b\BjhTPKLIl"佼; }|4u%{ν^Q>|򏭭SiJ rrJ?R>}:SC0⽽z^r=S,I$ӧO? ߙ3gVܖCTx^w&A WRsRJ^[)g&ar6M`B ݻwvb޽DQV G/^Ν;9|p]tuu177LJrS YinnFA<'ޤ\j]בR"ö9@4… !0MqvɦMVu͛7R.,8 ͒JfLOO#D"g|t]'͛贈&&&ԩSx<^zG4yfSNB:ᘂ1Ξ=kovZ`d2ISSCCC{RB.nj˲Lz#LJP!@2NpTi}G*2!'N   {'E޽K,ם"#k/^$ r%SkIիWYZZav [udƍ54MޠhЊD"ݽ˗/Y!Yao߮(CU|ޯi,,,L/uƍߥB;v0 ׯ_=z alh4-?( |e4 `ozmJ:@F ;IENDB`Eqonomize-1.5.3/data/standard/32/preferences-desktop-locale.png000066400000000000000000000024411416454732000243450ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDATXŗˏ16 PF2KKHD#xl!( BR)Q"D2=3xucc{@oSVtNνD)CPfl˨'i-ՉB Q~\*KW8s8NNv/{Qstg;ΑI2!I2Id4acu6ׇ>M ̦|Y3(a ͺW*vGqWS?>sac'eʬĕ&!6uNK1mL`/ïG7&de^KUT^i s(10FKi/ql6U4 tB%$iBMȦq+כ݉J[%Ph8k 7wWTe(%! l=h4{ B%cV;H_yG@"TnhܸI9 &Y pfHІǏ=͏z?ca0OQŔș g IDATXWypb1V Q!lMHCKb tZ?Q D84@sskw\PbTlOpZ㌙5?ñc;NUbyI3{llUu h4FNndgp\d:@eggsݸt㿎s1tfgW11 \,ݤd:GFK K?ԣ"GxCU@ @/^Dsk J!V(JD!R@){@.L<1LNNB ]Xfw".tLݞjAhw)Ptl0Yhko^Eku.   X]qqQ&,4!dDq{ ""BҕNunSb3b58===DBb#@$(CBtT!!J%SkL3 !5ԠPҊ"7֠nlCFVRE7+TyB|FdCH~/]`/.-DF d#'?yY((ʁ$%r P(]|@ ZR9Of00ԇ:c Z9g ICv^r ϡ硨4%(,BUMlX\T:j;H*nXbpQ؛٭4 ..\qUM9,v& k+PYSJuTA]Cn^.9ӄRS!IrWTBILXmR3t4?#^Kx"/ȘFKjU7 Â4jI53+vA̍J9rp Hj7˔$ Fst܉s uX׉B} ztkWTLO!2Ɋ يo%R=/-MP/<W*V }x=!*]G$$݄bEXZDcw/p7FRWO" HR籰Eno1 {P(Sٳh47rͼވbD){;aڊ9J XT3b=MʧhjF=Ђ^5!hHUꛕUZnyhnqUe0WdǟL" /=kkvC`Z;hjB/]7R*OH9#J.>sR݇j4۷gŚAQNRx73w5s/,ԫ;xAbE+vlO?ˎTFV;Kmf_l2[sK})Epz|t4@88/GIOƿSN@m0OGW;Fh˚/'f24ّHJ*eh  XN^VY ݈nCm9^t}A݌Vtri8xl (t!D<-oX)>4̶.,nߙ$ә=:氇9y9|C&JȝcNTWJDaӦº]"ҟ l&Ok7ޛuqc?r5^>A>T Fy՞v^H¥+ +YZ@%>'H'CM˧'IxO%"֭[)a ȿCoom?"ķN$y&yyy1_Ȣ`6xG]ZD˘BaX]#xאq+R/GxxXdu^$}h1YIENDB`Eqonomize-1.5.3/data/standard/32/tools-report-bug.png000066400000000000000000000032551416454732000223700ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<*IDATxW{LWwRmi)S@[t:I L͡Ӆ)Y͑:#nfԍD80+u,nI4:LQ9FYνws?=S<?\.F>iph4Ъ@4 < ."dlVݬT*F?Xqc-`l1Oll$ 1 T*?e ER͖\)͝ ʆHMEVaND8 A|2iĞBI=_`.Qx n.ڰ0> hp'+`%BNjRQz{S-ltDEEE{޵[zӦZ#9IӒ"1VW4ց2)C OT]]zADCA1K=߿׏p6d22L!555TUUEqqq1n؇5ᬄRB^j2XmT&Дa4қH#.:)7NF#7/)?YSa j"Mo'ߘr#^MJc34&^zދ4Sqxqy$DrU| _5:rSjj*eddP&BP /_9rk<r(0nwdb-zhoh{`Mb]*U111k렕 $CCT3(jԦS84?%s'ulBS=430j2glv tZ&dZM*>^(P<%FqdP~_;te8jNiS8zt+.D[.3׾[?;`{RZW Â__yXB7t)q5'$Й~} mp!nIjM_!4\?ݽg#"52qfi0Rf uSi;B~:pBQC&0`H9xFptT M ӁRJzԉe;as*;ƘiꀡeDڵ6!@^!RJDJ ϡ:Fـ ? ݴ\OC@i LÙfD+X 8dV?Ï ΎnC$瀣@#^6>uhB&lSj*nvchu 1c Y?TrFpb`=Xñ%[p"*ܹjkB@yG(9:L_X$yNbE|5C!EUlE8'U0n8@1AfMbwÁPbK`L7E)Ô7b8\m,JQXdkWs Uq@iϹz_F2q&S_^F_BDwsyj縚g4L1 cD'$`H1Z"97P4Wr\͉Qm 2L׀'IENDB`Eqonomize-1.5.3/data/standard/32/view-calendar-day.png000066400000000000000000000030461416454732000224360ustar00rootroot00000000000000PNG  IHDR szzsBIT|dIDATXW[lUΙݶhM-҆M@dx!Ĕ'#Q[D! E4b@HT/$˓FRJ([)Μ9>vvH _r2s|:f 9!K.ٶSҦtzΜ ,YfM"qeA?Ź҆ի~N%@hM':U*J&M=Nj׳)DH} h .}4Dz0 hىÉ4h:nEFGσiFZ[[E4_o$h%+M2^wEǡΐNƬKbtlxpe z*ˍ#T+иW~e=y%S$QqrmDA,6'UhXو2PJ$'Naxwc ;ގDbVRk_K *!ۋ _^vCww7R<388.r PTTfYssL%@ P/_c eJ2DWM\~###gbtt,4MPJA)8sp$M6AӴF[[A@*(y$ ̝;ix(']U|51ߪPZZ J ell a]ieŠbxx}4@eTVVNrN9}с44U2O'O.ޱ. u.t߾PU/؁ښ0 &D&Բ eg"֛o@؜ |Ӷ,'8iPqE|٧S?΋xk#y|Ig TUN ~O/׭B9Gs`jlr(TE|vk,P_W@,=PJA)iS:-^(8B!0_EQ I$I,ːe4=Gl=Ԛ=D$I.wܘH,Fc* gO-P.fgvD]O)rAPJ 0~=TbQUUPĠB, 6 Ȳd243~oy:[]|ٶHANRJypH%pKT2y{^^I`q =%Ƃ|yާM<5Tc||w@Ztݺ8_O3asC$`qL˺yٷg^;!aɳE$,7llmٲe<3FFFߏGfnDtk]7;E4bbn+uWt: y޾`Yrk9̲Lr2象kzH;@HH[6 N͛@!O@?;x . ; pA?6S<%MI@IENDB`Eqonomize-1.5.3/data/standard/32/view-refresh.png000066400000000000000000000037501416454732000215520ustar00rootroot00000000000000PNG  IHDR szzsBIT|dIDATXŗilT޷q ij,\5(%%QBZ〚㦊RRPFE,iIҪ qC Mc xggz7͹;w= 66O7.(;U8[9sX n#u13mǷ[SZ[[Č5~0-ݰXtM#%Lp@`ʽ|s }?EAӢ߷xSt ~]U..eD$IK)s~3@ }Cn#e!XƇE]70-m]=kad^@ q$ %A )$|t}p&_[7U8y^e].jx:0+KrKdaX!P lWr$HlI0m3=6Yͬx)w|e"y`D8S'<&"F: &x\H"خBMb߉)ronmܸ(ۋo2'q>BI˝ vq3kwRgp͖:/177 @M 0f4Iv p*/>, N]YQUmk[cO2idmxmtF.i_pjH$w0XBL }f7{G 9w> kʷ uGkª8eME"9.^%8c_GO, %F,F%Y"/uvj}#_ TGѴPw枹Ա /S֤w?ڌ""/Ep UhP{'dt!qvKA hX~ɚ.q nIoK[6`{Cۉg:9@{@ݘ&n?s퍽ͅ{QZȒEJ)eii cp$`6҆d2&cmf}_y5n̓@r{Q8{s)*[ee5zQٗB 9*׈}8t\?Y 篆L*j~w;8l"1XN~aAX`l#BL ?َ.S!F=HA^UK /x!Nѻ$k >_=ˆm2svIENDB`Eqonomize-1.5.3/data/standard/48/000077500000000000000000000000001416454732000164405ustar00rootroot00000000000000Eqonomize-1.5.3/data/standard/48/application-exit.png000066400000000000000000000051111416454732000224160ustar00rootroot00000000000000PNG  IHDR00WsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org< IDATh޽Y l=3;`OKh 5-jD&Hi6"QQdZUZ%JD* )iK.$` `k{ݷ3>z>;9s߻=A4 &1ye\3&pog`͞,[YR=?-?CQt#n6 vNSpp܂H2hTU,H$cwՁ:K$ 68*~ľ>""!L@]/ "$QFEy%m{Q'q\ZM'co^7IrYMh9 A.INkOEmQkO;]bG >fȀӹMa2?8Ҹ΃#zb9 2cfƹ8U391~/mN$Iv;LŻ"0x7'zlNE@JRL=@&LV01B6 87)*?\a.l6ި0MWBS0@g=̐AF H(i/÷muϷ/ի&K*i| g֮7]Pjݬ?WT̝ṼY. SW pG>n}kو{y U˱d=Rthi0J+LFVˑN?˗US ɓk{Xk5Ϊ*+r<*0YġB!VPB(a~^޴*!:RG7n͛7 ͊CɟHvkoGa͆!>-a \mvPJȐ ~lflڴgd"CQ^uj̆/]BǏ[bM-Րn#jhB IvdFJYAs}x<.ݷm݊BRwEl7ٵ+s[[| M2MJJJuOOo0_ܾ /c0R*"6n@^d6i7Úv5kgNK.?qwAmXebળslmMդPu_x ۢi&[ʰ~zիS;g=c]XZ1vsPS4Q| ]pݙU y^l޼(//0t܉2#׃?ͯZݯ%-AQ{8+GU=ȴt14"#|Igl'PP~nբ!!_S Y-+9J+R#E ,VCQ &a2iyɎ`k)!t+۟jx%– M]V-['qP, .ˢYH{p7rcTw״H\TT7;z{{ XY#eހ$/yLLLD "4m͌@&x:I#O40ƀ>q/FRNGc#!d N:.aL*F#ǗY2`AEυ$DRvz7oYW)Q&.vS࣮Z?\F%43qJN׃.~Ư7{J'pu:k6dĆ.KJ10ps M)3aVfOIoF9 |}=#?aLY`:X-oy5>{}%lqNƌ_7 dݑʒY34DPn D0IENDB`Eqonomize-1.5.3/data/standard/48/document-new.png000066400000000000000000000042301416454732000215520ustar00rootroot00000000000000PNG  IHDR00WgAMA a cHRMz&u0`:pQ<bKGDC pHYs B(xIDATh͚r/T#9-Uyra! r%WRD) JL )oU(΀C$ĎԩP0,Xt,ʜK\MRGp~ x(]?)ӥ^{R/Q`rZ'h1F^e)o^CU13̌4M !`fx !B/{?k:ĝEcmF mDKVZx/!+bq쒗_鷿Ϭ=cY)V|/npR>#܀"L`dZ UZ`KNBYVb}@Dצ2 qz3(Fk'DpFdX gU0kP #]}+_1y=%0.],Df`VA49gŗ؜ z :>CWɈpw6۵9:`jSVE޼Qi<覇x8ߴmq/@:b}n۲Z?9D)E^%~'@dSPfk{wwwOmwO|ROlrx(hۤi󢧄e.kj<bS"+ c}^ٕMxpbJQB-E\ SXaeCh'@Y7bf |Qh?.c; ⷵզ,֠<-o8ahie{aSXzqy_xnI_S`o7j9@hi$t:!T N4MQ4ؐBQ7o޼s ENE潗8!{Cգ EQԎMDRdXY~<`}TyxyROTAKvtEXtAuthorJakub Steiner/XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/%tEXtdate:create2016-05-15T11:28:46+02:00L-%tEXtdate:modify2016-05-15T11:28:46+02:00tEXtSoftwarewww.inkscape.org<!tEXtSourcehttp://jimmac.musichall.czif^tEXtTitleNew DocumentIENDB`Eqonomize-1.5.3/data/standard/48/document-open-recent.png000066400000000000000000000111221416454732000231760ustar00rootroot00000000000000PNG  IHDR00WsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org< tEXtTitleClocks J`tEXtAuthorLapo Calamandreiߑ*IDAThZ{p\u{>V` C)10 Lvf:iIfJmi$ـ$ٲe=>$}yo]$'^}Zؿ??>NĻŎm! 04YQװ5+͊V7boBSSk\7_#8%?{h6of:պOqkMQ k6 ()t󦢢I:zf˅6r'L& rBT<=8s7ncO<ҽu0 *];qnehI3 !\;FQh+(`% 0U`ԣCR"l6; #=G-=w6K ~oo!t1㿀s*ylj CwoBɻ" y A$)Q)2Tr`2PdZN,kP1lzJzˉpF $h,jYL[z}'t0ch[z0YD( VÊ/}2gR oӔ tJ?DMMW?hWqq_YJaX q_A=2QILNN-\ hf_$gͦľ}{k_KJS{IjU,_G/y"!GtXl&=e& JzP: EV`TIlQ56C00&R׊`Q !SHSgƞϞ͇\LreN(4͟&,v8Tb.bQٳ;:G]aW(X XP:sINv*cĆ o:GMu5#/=uRAWsC\)`ĥ}vN =17?OZ,h}}= $bO?|a VWםܕVV1dSejjDܲ ̓S~56u4z446(j27^oQD*Ί#e(ckƖKEs?sS'RED|ѫ0??h_n//zT!fK TQ߇K}=czpj+TjQ(!1cbmtl$91%,[[m$  atttW~+sXrl{ %Əa7oR'}Zv#+wu*/zՖ+n7l‰fIJ'cǎ XiF®w+|AQ 2Rҝ:s#&m z؅)?>@Y{$chpNnccI\c|庹w}a.O~h<_ZT3iLq",s::}05߾λL[nWfC!!r ş$F4[byfPEA \ gy{unO/3g>a 22?7wHPqDZ5>׆Z9 #J ,4ڱiӆu^vñfIG`X`5[IyB3`LѲ/$x8O.OHQuDTI!$$0W5 z5UeKKkFf#I*b) \"ũÊ/p`bbbXjx\ Mh /K[~f4^V*FCFkr +qZ320Y+Y߉5`9#h+<=.[֌Šcr醵 `ºnص~eJ!?\(IENDB`Eqonomize-1.5.3/data/standard/48/document-open.png000066400000000000000000000053411416454732000217260ustar00rootroot00000000000000PNG  IHDR00WgAMA a cHRMz&u0`:pQ<bKGDC pHYs B(x~IDAThYoS{b;! #T.hQ7Ă TP"uMV,YDUUEUh,njD1;6yvg?{O{ā0#U{޽w>xolX .\ !DGc}sAD#bBp{ZGƺe1pΡa௦ikn:=_lXOSoߎٶ "QȞnR`aaAjܹS|K*̻Vû偃\~nj_жuJ)H)5{^y' ^:Ji"Ǐ#ɼ÷ŋCZ DdD "O4躎r߲m{9iBՊ$/h@w xJ/Xu]q1(\sssx)R`ĉ񝞃z}R)),RJgfffT*_.1??˲|Ċ"j1:: ,O#]uUV#k`ee7n܀ac|||ϽsGZVk1h Rz^4lB'|8y$Ĉ #Qn$ͻ:uuIR)T*?~FBMB|$o!KMBzb #Nd#r%"1|,]w-˒RٳBP)|H+13Cot-m<0YԔ@BRJV 0`l6(>R] o;逭^+m:t"\Jɸ(U D He%4WҲ,p!aK$C{7I?_)ۗА+6g՞,..<]aYco(ܟ+xkhRw %lOb<$G$R d=BBCӴw8y]]5+HApkI%bX|'أ+Pb<5JtmgwQvvHhfAi+?CbJ1hF*؟JUdAJ/< Op}lOv%mލG`Bp~DF@JR@4d2Xs16^Bx/#lGe*}=RY7>>ݽ{9]6C>m#qꣁH7M>|\pL[L*hhau0ZH1;#4 "a|8Z|2itH"4l_m]MP('8A1W }K&knnNk$qdq(c(6$I 'InekffFT*ȫ#@|?O쇿x5E= $@-c`s'O58DX}i<ckV MY0~OǾ||-y}# `15|}@H@{k1  16v*nw7EkGA;}x3i.tEXtAuthorJakub Steiner/XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/tEXtCreation Time2005-01-31%tEXtdate:create2016-05-15T11:28:46+02:00L-%tEXtdate:modify2016-05-15T11:28:46+02:00;tEXtDescriptionActive state - when files are being dragged to.gXEtEXtSoftwarewww.inkscape.org<!tEXtSourcehttp://jimmac.musichall.czif^tEXtTitleFolder Icon Accept5IENDB`Eqonomize-1.5.3/data/standard/48/document-print-preview.png000066400000000000000000000066401416454732000236030ustar00rootroot00000000000000PNG  IHDR00WgAMA a cHRMz&u0`:pQ<bKGDC pHYs B(x IDAThkpyvW+iWHH"q BBv( 16=!x qbMblQq0.+^9ՎF1Ğߝ;gy-|%_o[uݟI)}7U!!a;\ץ#3ㆮy ]SHi!!HCJKX, ?+ fVl0FMCyη, IC5'BJ nihRB.u}Ln@,, 46qZmXϓ Mii+ꋓt$p\*S-M@Oooo|hi7ąb=e!DH.o5v!r1p1 ;@ qHHp%xJK8cjA4q?>BL>??H)G;o-+"GK{/ B0t p@̓&hnn&//} k֬oӧYhߟ?Isv")B!A&4\}9yӰm'O2ydΜ93…֬Yr0NR;mv3y䑐e{LػX2vrD+3KBaZPB!P 6)A8b)cYaO}}=gժU(ˣѣG feL& BDhoo'''e˖a﩮F_(<@ %RIg"ӞĞIRkdh/+̊r[8ѣGI&!PR)*.b+4ilܴŋS\\LOO%%%X|9} b|oٲHgԓtuw1ʾRREΟ?ǓmoӴbq)Sm晍(++^&xb>L'C=q!i>B(i;Q褯.o%׺кVY^^l.q!0,>͛GwOKmiil\gepQjaƍ]?WO>SBA|>rssqڽ;󻶶v\׹b]<񓟢k#h^{ ]1 X͛7yM4-}p,Vq\ JQL+ʕd)^~e:ujfemɓK޲(4r+ziYXieykRtR(%5䩱ˤu]Ξm[ZZXs4@7p>x ewuuWȜȷ5*;]nwE" 5FR:}roܸ #FFFCc:r}+rD`VQ޽ee||;D]ݛYEhkbVL'34(@q&@Â`@?%WnhdG?V*2^tEXtAuthorJakub Steiner/XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/%tEXtdate:create2016-05-15T11:28:47+02:00+;%tEXtdate:modify2016-05-15T11:28:47+02:00Zf%tEXtSoftwarewww.inkscape.org<!tEXtSourcehttp://jimmac.musichall.czif^tEXtTitlePrint Document) IENDB`Eqonomize-1.5.3/data/standard/48/document-revert.png000066400000000000000000000057031416454732000222760ustar00rootroot00000000000000PNG  IHDR00WsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<tEXtTitlePaper SheetstEXtAuthorLapo Calamandreiߑ*'tEXtDescriptionwith a HUGE help from JakubT IDAThՙ{T?w޹9s~5_+1 /޽2 )Z0@;,PmeY&cmѢEgGgyz̈y'ceHIi;ّ<ޑI? U=`̈رk{wn]KgRh[;YKj蜕fg e 1 D"#ɎgKn[;b1`vXDm; F{s4]݀xXV}'E˙6yzx)׆ӁW_}y҈i:oUk9wmz͛_~<}u!xGϽ0ISt Q}irVjM?r]/ Z 0 :;Oa` f̨^۸e/F΅w $ fVRN C!*+2ejE7֭[x yb(x 2 Z/. ˲ JԌ1ǎ ʻ^=/<h4 "`2` XŢZm,fN$. "NH$H$(++cYL<9'`P>@/M^F>xT"e%PJDa]]]~s7ä"V^!xR|Kx{A `&HiDU`*ESOS_3ʻ6_m]:/ޕX{Vf  biJЖ/l)\=@cqm.@r2̸'G50]\k!>wePjډS__B#-d.ZɝaIDoreJy6mlLN۹힭\>yzb hzDFWcʭ40g{?+ pҷG:=-7__Z!Au1p6})7߹PL*?`6sP/ ۶ V~Pa2}=7{<|b.ոz{ 5w[ ؙbMsf壜! Y(.*8e\X5&sXZCI!%G9zp5zM9:δcD)DcG džUn=TQ6("Q{Fa({Atǒmfm-ڄ>Bf#Lv ԐI`wDY%Ԭ8!b`۽(3L `L2t ʗu\$7"ٹwnJ5`%9;0g{3(ş MZۤN1h#~t3'8.p ?΂9m||[(p轕L <]{$*t#-@I x4Y{R?0lu[bQjި8J>~ t< Q_ kMyg X9T+/_3#eP0Dyy9IBSK fh,ƸU?HըЍbF9d53m<%`sQ h4Ƹ~g!xft*pfd>g')}Sq+ * oSDwBE~H"H,Wg1cLChҟ y#j#3QyZV*:زxM(x\9V|*miͅ8:E#:[?Jnb$7PXHZo(lnt,v$0\IH HI_g2#g 8KDB =dtT*YdG!u*K_IENDB`Eqonomize-1.5.3/data/standard/48/document-save-as.png000066400000000000000000000064451416454732000223320ustar00rootroot00000000000000PNG  IHDR00WgAMA a cHRMz&u0`:pQ<bKGDC pHYs B(x 8IDAThpTǿH6& $ !4 dТI4&ԊPvv:(CNX9i;2 X 6"V @!d}{lb@0;w=s9]rc. m晌s'cyNpbS7$dhY~[Eozxa%%ֱ9ȭ9G0߳| f9OL%@@)Rk8UrӳwuCWVIw߹`΅|Y'f6!f:q @)C@_;zrv]a/T␅8W!PHy IF[P E#0)PQ+2VwO6A mM**ď*:|#~v?tJC3LlPD Wh1ChڊM^6$?vqG8(^59ښՕ gDtҳw-*qf }*L )wa[VzZ.\w{_.\ݷx{Tӵ\hθkc){T̛)FT$RxS7|Ge?޲hcn8/Bp À(pv>Cg@IߛR_P)Lix?ɟyçƓ;}y%%0g~q&ާ ]PY''@!d ĔϽChll 6&!GpZ8w604 y9~+]^ܾ}{50sEb7ƿPH^()++]Nذ`4`m< Qŀϓ1/ӓǎnܸP(Tm۶k(NjGۛ tټyJ 3BwT 8oa2cA|>455yl4 d גV!d{^ytoo}!9`e ng<σan֭[/SCWB`V~&n+gx~(s 898d !)(EŃ+)c8y ZOE3@)ܹs[[[.4UPE!(b%ih%Ei20$2T Xzˮ˕LML7Afz*!8|x#ǭ^hh0BS {$>Ӊ 7I&tbBM1/R+*@TC_DEߠ CČl~^|b< R EQPPPkhll,ϯȀv IaM 0&y`DIL UO#G$#"'>S  Kf0dQǮՍ`yJ'@KF@T@TC8:{x)H\Aqge.8]ESJ<AqPUUUSq  V!8eӄa0 lz;wEUD:9,cYU}q3&f:LӴsyyiUddd '[JDQf8!a@up`⫯; s3)5 uŶ R J%Eŋ[sǭ^|9b0 iObMjyS q䳯0;/}TKsh;u|tHhR 4MCQQ\.Wʕ+ӯ|R]ԗ*OT6ݘ17L-YHu}_?z+Da(Nqj ðy;KKK!P(jgB,ógƅ 000`B,pرI5%>BANUJ!AlörT @ee磏>jynҥ6477F%܌&o(~ jݻ˗/GfҍJ)v؁T8?sͪ q\N (ʂ,2ԩS1!|>!p:|$cH$ IdYFKK0 9CX' x4 188XPJzt:AAoo/VAu.ohh@QQגߪ~#jֻC{{;TUm;qD 0ֿJTzСeN[Wў1;::~amiRSSSiii>4塁N|=8<azzzz(ɇrkFF"?x\@?8: 2y̿YvCW1`ZF'3̧{jtEXtAuthorJakub Steiner/XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/%tEXtdate:create2016-05-15T11:28:47+02:00+;%tEXtdate:modify2016-05-15T11:28:47+02:00Zf%tEXtSoftwarewww.inkscape.org<!tEXtSourcehttp://jimmac.musichall.czif^ tEXtTitleSave AsdgIENDB`Eqonomize-1.5.3/data/standard/48/document-save.png000066400000000000000000000070541416454732000217260ustar00rootroot00000000000000PNG  IHDR00WgAMA a cHRMz&u0`:pQ<bKGDC pHYs B(x BIDAThkpTǕ1oi$, IXF腅, 8YǠIv!:ʇVr*]*Oݪ$@MmlළB06 Bs}^ Wb|HWݺt>|>6+Oe IQ@rIf7#/?sO}[ UEh4cAU%v*ɏ')m ;ruJhs]O񶪐PbFXF3d[n;g pT$z wA5]Ø]A 6m|,;>ry_?<)[ cTC_Y{.8q[(%lWڹ 6V]ي4mW.+{#WV~stwF8{^LNhiꊈ$e3 `#Yhm+9-iV+>mY]h}eXw[<|//^Ǐm‡TfƫZ$;|/o 6UKSi- \X~ Xqwt5 +Vv7aFM_[g+ѭn_V%Otp9C>|wiT|w/z}KdfSF^~dIG_{gʲ,q&sXB˶ $:srT7'O߹fYַ^wT Լ7@&%pW&\\j6]w.088x;XWOȁuk6wga2C}mL g_|cRYcj_@"8Outta#(Hg4H2mWy29 H%PL۷X{xiτH$EXb&&&PϵaJpN@ ITz @z..&?sx`}38XfM_Ղfm{g"0,6Lg =DHNfaye' r#3KPWkCOCUE1h~>}((]ׯG&+xr[7b#ITlôa2ib6}#: S)SiA~q\ɏ010109õ) ɉ ~!we}2]=wwf"J)$I!\===טeS_lȲeۆeY, 3fFƒ:jb!Let491-Lo!0۶]1(0Mhmmmھ}TVV~#Dc, i}/\Jf)JCq03Ƿr98ϖ$Irذa-{E6X۶AAE {rμ}e>;+J|_mYC0rJ;v쨘`۶mh4庺:sZ1۶oZEahN>XˢrWF85}NBgY]# 9/UuwI9w?urQJ+}X XSxG=_DO]EbDžu@>u{{{fݠ$@NQJ]LXV'_~=wTkE5ִTᗯ}vģ~W\% ۲,q444t vZ+@uwM\Qu6ǐG;n+Ñy _ߴ $ $pKr7 @__<6+!dז-[ܕ*L"@QgYV/@W5>QEQ rA;o@ h4 ˲UUw&U"HᇃRZa&!B|LEjyY][UZQB!RL&0̑9}/^W:eҥPi,8{tņ(y#!TقrsӅ!FPUbRiO5OgYy.TB:Aι\jםY ȟgJ?ʕ+A@s4 F~}z1~ttp###Bp{A$sn`arrǁd'Ow۶mxOK/U_|;WYYB  d1~d6644o:uj餶]L.Ͻr øpsvr@@0EmVg: VBJeYVvbbb M ||P_0?83&@n}ֿY%kvgl tEXtAuthorJakub Steiner/XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/%tEXtdate:create2016-05-15T11:28:47+02:00+;%tEXtdate:modify2016-05-15T11:28:47+02:00Zf%tEXtSoftwarewww.inkscape.org<!tEXtSourcehttp://jimmac.musichall.czif^ tEXtTitleSave^LIENDB`Eqonomize-1.5.3/data/standard/48/edit-clear.png000066400000000000000000000065351416454732000211700ustar00rootroot00000000000000PNG  IHDR00WgAMA a cHRMz&u0`:pQ<bKGDC pHYs B(x iIDATh{y?=g/.]@$@5Uc84N$MLC i#d:Ԩ`m㭶FKIE J@ , Wv^^~̑3{s<8 ISMn\j_][ ٕ}}VoS6ڢ˯ ;P,ɉ#%oן|OrƍO.//TbxrAB 4h7h]*GS.-uy4|;7Iͅ>-~x ZJf( 6-mn~O ebFmdQjc,hQdj_Qd7g/ o9I$b(#bXrS41Cb:0Z.T*pMR|/ۑ;˦N95mfEc(m,h"vSףPdeE ~nŧtxY#(ງ`\6W. 2:<)\ cCR".oݖdBY y?*1QyBRkg?s5m+g_T _ Pv`]+Xcf@ܼ yAvymrG‘Fs*E$$R[{+aΕܸS6zI|ҏ^i#y"tp`5DYQ&a^/#|2`bY%|_`yW%u_ " `"*'/@YJHR ፁ?0eRqldU`8Եa>|p|&tLT,&Oe^R:U-GHjaD2ކgȡGI$7؏j$rő]ǝ}Gz/=;!tZ?6QqȭKU=RKf #荨F ١~B1(GQ =DQBRW3:P_6htjWƓPhB&gRr3'PΎWjUoE$09TX*F{~Fuu_z=6SMƩn 鴱d9XmkگRPxpmHb)5އ'ݽ2xyo>̮lpܟ^U>yD&Uս^%4JGeŒs7B~e5+ő}JtYvSBEU[))D >}Q"7/?7'UgW:.@XF|usW\)d>䡞DS =Cڦeu:n&کV}*Se`LTLNG&EkM;gcNR|tEXtAuthorAndreas Nilsson+XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/%tEXtdate:create2016-05-15T11:28:48+02:00sp%tEXtdate:modify2016-05-15T11:28:48+02:00.otEXtSoftwarewww.inkscape.org<#tEXtSourcehttp://www.tango-project.orgɾtEXtTitleEdit Clear݅IENDB`Eqonomize-1.5.3/data/standard/48/edit-copy.png000066400000000000000000000033701416454732000210460ustar00rootroot00000000000000PNG  IHDR00` gAMA a cHRMz&u0`:pQ<PLTEǚ񐐍Žꩫϸž勎ELm=tRNS]\۷\d#j ubKGDH pHYs B(xtIME 0IDATH͕W`m*B&"DBP@jvO/ sz.,gQi%KMTh6X  @fkX4p3Ya4aÞ2 Tx &J> o){93l1ЧK 8 /P8p8N pT HWoimm3l@c G#*`s[Pt<2 F(##fCwc!hEr|0g>1`%5~bua8%H>LJ%Z.xqGDAbkju4e9lɰNe]z tSfGGEOn\_ 6@cD峹\nl,'|y 6A^ 셨P,ZfcE>+'x<$VT'[G1j#6Si͜3u6y`)'/:(xivnvn}+Wc׮ذLl*U`ss;wߴLR6x'Omj1Ub#LM?7omQ(66һ?~snKB!_L,_~{Zf0QC=fi'$U Av'V<tEXtAuthorAndreas Nilsson+XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/tEXtCreation Time2005-10-15 W%tEXtdate:create2016-05-15T11:28:48+02:00sp%tEXtdate:modify2016-05-15T11:28:48+02:00.otEXtSoftwarewww.inkscape.org<tEXtTitleEdit CopyE IENDB`Eqonomize-1.5.3/data/standard/48/edit-delete.png000066400000000000000000000071651416454732000213440ustar00rootroot00000000000000PNG  IHDR00WgAMA a cHRMz&u0`:pQ<bKGDC pHYs B(x IDATh՚k]Uu=zfvRIIiK)5@Z@U"a$PhDBD) $$P5AiD8qı=<}ܙ̌37K:w߳:w^q>.d+NCkB$!o껕Z_|>oZזoGRaݾb_V.pܹsPJm;9عscȶ[uz{{ןa<{]o˖ǹYc̶ctttSsBĂAr&})#co0@T*t:q n] ޱ=gל.\`W{!̰'nnqEcZaaxx0 !sB(J*vW1;]!t|y/fax;~}T??U\oBFIZB,53?)%響>h JIpAvwgO8->8|ح =#>E{oꊥ28Ihr*G_źz{%GO< i5o`l|oc@CCVW_w :x_} jq}w>x*eWXi sރQ$.䜽mQ|R~< w}$: Qwx0V J<X=땝8#(TxJ]Xh)ۃ5]k_q pW3o>O_7E+vr{cml5׮US-,vz8_Y`ғs %\S"0FWύ+0ǘqw|ꏦEwׇG709c&sq;|Z\paflSw^Tѡoƛ9+nr7tW^9r?W*wwf_'{ǫsZ*<ؿuxǏBnkq3QanM$}!Yΐv:;v(!RJRңRPڣR2()Թe?gMN)YVA$N,c„a:ϕdntvv6}ƙeNem @tRZQJraVGr/_RjqfB@RV%Y`6 c掠ڙXg}P3K)83qC1P- ʸ'XE k,(u0J!˖+~3őʒah$v>!gȺWo 01(7 93Yq*Ͳ  j4 RRąa˗+~JBacVmu߿a a8g1j99jU\*%*$IJ %*KS뗊{׭7J+!DUʕPrD(Qr9ZSJUR[JQ97a1f906Ju%D"B7;W.W B. CJ>cHkݪ kNg>KXתLkݩUkR(yެTj{>TH%+JnEIFpAcRꌑ{LR"89$ I^t{ݙvR!:Mܹ()DV+ RɥzQv: i0x U3dhTzb(O 1B@3f)gV%Md[~E4BBZQb>}XkL7X(fι9U+ Q'uI$I*BIͲ:'I粿KT.WÉ@XPF%9c$:,%iIʈ匙c{F0ֺ։7818R0yZg~an>T !(c !hefs:-db ;!MqaKQ%rYƘe:n`zIzBT0f#%B&'O+=B 84ӈ^?FwB'Ga;\u1P"{(gxq 7ޘKp-Rl/{u( J/=3}>N6vΙv}p\$y9( w~j1N$-6Gwp^orl=wGR*f1m4bkNM9rA@5vʗayutsJrk!Տ1W*ij6nA^j-wWF9s(ݖz=0B9l67u$ L)'.Bv<"zg-Zs܇ R* f.p{{IkG 9Sc, DsYVJ1,oldgϝ? ٱs?(a'PN`]aP(!W29Χq~.  @n$ҩgv;?e8XagA*es2v{ݎ4v-Љfȑ#}:Ll1W~u3}0‡A=f.bœ68,-wkڧ^:ۇ>sf@RQ^~g>OzɓW~P @:kx2c|s{ ޫJs䅉7 p@{m7:Q\mD~pb_srkA",5me%q?4IQHStEXtAuthorJakub Steiner/XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/%tEXtdate:create2016-05-15T11:28:48+02:00sp%tEXtdate:modify2016-05-15T11:28:48+02:00.otEXtSoftwarewww.inkscape.org< tEXtTitleDelete5ZIENDB`Eqonomize-1.5.3/data/standard/48/edit-find.png000066400000000000000000000060431416454732000210140ustar00rootroot00000000000000PNG  IHDR00WgAMA a cHRMz&u0`:pQ<bKGDC pHYs B(x `IDATh[lgfwػZ/뵡}'oΙL:o߾Bx$IBe$I²,,BuLIJ, 4MLL yN,+io8A6\v}ssҲ[U/яvwww^s]WWhR(9i+$1SS(`Ӊ,y#0_9$B"'"Q(#KUWWp8D"zj^alȲL4Ee^/%%%8Ȅ2*Ix<=!CCC\x{uR YI$ܹs?UUillvydz=߽{u7ϓW7 < e4U~!K,aÆ A^AwjjjXv-_vc׸k,,svI E'5vlXԳk.:D?K.}ٙ|>O>$O]᭏?n`qI$thLI. sA.oz|" :mE\ 6m'_x/?7x'k[^ǥ* EE beUe(][a!d$eB%LbE4KX ZRݻ\.vE NzEattnx{k MXeK6. ,@7!a tS3;~1ʕ+WU|^|ts_/`Ws=e^].c lT n Z_Xi\<Td&&&zƢ2T|j,HB0UAD391L8W7`ɜ>}H$͛7YjգȗF~MM GZK˫C[27Ev`(FnS Y|M^|E6n8Br{{ ˗ƍٺ͍+8}m]8wcnRVXSSk6bqP(nݺ#G0229/oF>p8f3T:y$~zQU5, qeN>Mcc#q0tV$QΞ= sαwyǧigB6._ @EE^EQdtt7oRYYc˖-8&''1 q !^8qDA;v{w eppp8L,pvYbEjǞ={زe ,  "I@RǎkB48qb  ߿ߛ jO|8JOK)w^YlcccMx-;bӭ(*t]2oϒEF4X,F4Mmp8DD"_.JJJb,\P(Dyy9w>ڶm/@p@bw7>N'ۍr*`SߓN~uxx<΢EXr% l޼yi[!O %!HGvLd;'=%̢ERǃi @x:*ֹsp89q9Hӿ"-²,a侌t X,BV0+bۜ:uj8XTا'tqRu]/2~ě^eY3MeY>y%SF%A f2"i ߒ^xotEXtAuthorSteven Garrity;QXtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/%tEXtdate:create2016-05-15T11:28:49+02:00{%tEXtdate:modify2016-05-15T11:28:49+02:00 YdxtEXtSoftwarewww.inkscape.org<tEXtTitleEdit Find%QQIENDB`Eqonomize-1.5.3/data/standard/48/go-down.png000066400000000000000000000042551416454732000205260ustar00rootroot00000000000000PNG  IHDR00WgAMA a cHRMz&u0`:pQ<bKGDC pHYs B(xIDATh[lUlږ/X{!F.>`4"ѨŠ *hH $KiP9afvgm[=/ߙ93{|̙x/f>t  vRz}O|/APP@d{E1Lis %@PK @!K-2!$zKc,ąVh<Ȳd#cygZ<7 Fo(щQPcmJDَ(%Z%qJɛ+2$(NDIpE&D; '@YpSu9m/wdP&n-JbF!x mY5[ "=9 Dd!pN30YU5) ;&N綕:̎. te{)0F)0N` xQXrE%Mosb¨=U4x5̚wMڶeŗzO"TnS>' μ'8@@(E MUqDx7F-Wc{@5-Zgy|}2 b`bGeNU8g)+ (b_]-u S.x4J1g ,6$ Ec""5[,Ӓ֑A:ڈK-MֹnObGMM}m+VLr1jA=qFP3$35O5Ic)w| F8FQN0e4!ŒU}jfO}i KpA46uv\ΛEt?DJ[}b7zGkDԚ=?5qg &mrsz[4y  3#{ )j4~d1ئ=uSF-e0 ВO1iwP4fh#饽.O:.._:1߀م$sDs'w8exd>~ l.{yX?ʅ}=+'G3] "TO߀Sfp^"6`/Zh%WAI(x̻tcuO ֣WGMM{͓&ϝY̓ Kcי?l%Td -,Wе͟:Df|nkXqqW Tk(2+PUۤr8JʴJ*71bwc BѨ都s-mO/['Xa)PU`I3vw~!wE0[p׊\h'/uԬZ7`v!j xh~;Ÿ90o4#u,B:O3 ;C}młh,">ܭ~N\NZF3俥*T*kƊ9j==_[ƾc|Vl,;= `(Zz_o?mmi?Ai\egfLM>qUsgu (4W B&XvE,&sx[\Q{E{-ʹGwTs8W>C筻G'L4ϙeQy[tEXtAuthorJakub Steiner/XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/%tEXtdate:create2016-05-15T11:28:52+02:00%tEXtdate:modify2016-05-15T11:28:52+02:000tEXtSoftwarewww.inkscape.org<!tEXtSourcehttp://jimmac.musichall.czif^ tEXtTitleGo DownyIENDB`Eqonomize-1.5.3/data/standard/48/go-jump.png000066400000000000000000000052401416454732000205250ustar00rootroot00000000000000PNG  IHDR00WgAMA a cHRMz&u0`:pQ<bKGDC pHYs B(xIDAThklwޗ^#ĮYcl0؄@P/UPPEx-V JT5JTQhAxm6e׻̽x-5|3s3sg)k#O%BI5D e F_ڃ@L'D(3byySIba5vFFF 1\Ң![=԰*@VD6ٕBʬbi #FH$dIٰyyqMSÑ]?;&/ Ql R Ux}dh#ˊGh~o_+e!%Q]Z'wܸT;k5;p ZZ٫̇VysCOv>;VTyz^#Uu N(nu7LT'Vl7T;<)mg3ɤnS!uiddH `w]nxh؍@ȯt^/͝6v4ԏBLpFVbwj],zrpӐ{@U[_ ϣdV?tI9`HAjΦ+Zdۍ~F?}T,pۼ䘦;-3N0^2JC)] =0ο͘6.a4dl`Sᥪ!II '0duJnUbOEU]F] 9diD ioNHJ|ow#"I#m y;;u;NrerV AdD H !"z}N?U։@PF֨vR.i>)jTr&)lG߆@9z"wXO6tILAc1l>x|#Q:7[L ٟ1{!wS%tàLSp sv?q W2x%uko]>Ilk:uf ]g@¥=~jO;I(b `3bizxFXcWJTUOOK$۵0MzĻTO1,iwjW^`R}f;d:]imTcXTO&'` muUE,fyӖ!f;a.GMK&6y'zt w]sA-F;7kh<{\`/xʓFY4x5DfSG`0Pw!n&*7ʅ{_$^O2¾ug8rQ%jh%Cu1 [?d8;8t/ET 9>+++&O93mWEdž?]qc?,2|Y_?JGfYXN2!}7obUi3Б/Oy&1_PFG;bBt''@(Ya0|'̼^ǐ3^/CՔΛy/%)%cπH,t`b[ (&&e~h'm'q5Mw.5%44lŷyGrQgLz ɳx>H]TU24':H"L&I@|JGfe :޾TBt}rL!Dg:m`R =p=(yRI NlOٔM#4sU\tEXtAuthorJakub Steiner/XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/%tEXtdate:create2016-05-15T11:28:53+02:00ރ%tEXtdate:modify2016-05-15T11:28:53+02:00b;tEXtSoftwarewww.inkscape.org<!tEXtSourcehttp://jimmac.musichall.czif^ tEXtTitleGo JumpHTIENDB`Eqonomize-1.5.3/data/standard/48/go-up.png000066400000000000000000000044101416454732000201740ustar00rootroot00000000000000PNG  IHDR00WgAMA a cHRMz&u0`:pQ<bKGDC pHYs B(xIDAThYklν3z7Ia7)n0)I7RJKBmPVHVT@R[HQ" Iŏ"pJ?qlo={{wwv-w]#;;3wY`QeQj.Y{~zXI,imnY !_(/Y c%Ktw=\NkLt[aUj?;uO8hݵr t܋lijՋg Pc|Ml )L&Gnw7%ý%ΏW5J[CGLgD^=;x:z~cE |P~.T fhV:5qϿ}CЧ/V@~5Ψ$N{#K>*!0 ɧnZaww䫁^<CCVol&qg敛R^7,ep~}WN!7@ YEѾ^w;o{g@~P羱˱c,6Y-O@ 08lntn ӑ=Z9@Ǿ#(FpA@@XS=ΌDLcG;$[U'އz-eC%dA9f,%  6c,m>Ws ~rֵӣ'CB`kL HI! O%)Y/ܹQVwjɧ76G6vl}r/gb*¬6r.ŽH "$C Kk\Q>Ut]/NٱS{WkV꼲)5 <2Dɮz.NTlKs@Slg|+胏!]`(H@!24P(^0~3Lhcwz`@k9ONᥣ&bk_ze&3q~M\ >}ŌR, `fdu !hx(ْ Ok<fl=?QM.}Pi g2* b<>iR,]5{,#1 H'0#~n:PALϖ_'0Y&y(fC,mтmW?L:xz $[}sY@m AU*U#cVAH04Ȅ WZE)[d.0Dj2CQ PDkU.0m&93|wbV[% xC@^⹠ZZ1T]k|p4:(\Cmم{m ru5m#zL,լ" XYA34j x3i m(pڽK2?KYmtk%=Wr;$"8/"mbz8a-̹G+.h;ּ~2OرηK/B"-ǓEL&V}\[ow=D}s`c7M⛕Ks bEnԐ2@}fSbKJ>1%ayPa&&ۅMs`J%wy& (Dk y_ZisP|hڻ:q4 ʳkܾ9g~eKw_" E* ! J@9-kT-Hy: D?%knڿ9@t/r4 "P: S* NCBqرo]~mz Rs Y7.8շuhc?%E~u%w]4RW$JA$NGyx`dwTww\ݗFAcSP:R y.`ww_{z.ϺԶQkL΋vZ)<, =2|-$?=r<PxofIJK?v9Adǀ|@D * &.*`щFQVG7JW Y&mtZ=&σp `Z4BHx1H}$ m2( #o-9Yn,g(n'ދ%w5H%HA \*}Wr>A>Ǝ8;Tn3o'_Azh}zV.{gS@D`W P@}I Nh IN )qf|a.;Rj+:sKZ^p.* eI;> YQ=\m` 0e0^BGL;nXw<`cރû9I*v% ⫪X(Q?Kd(́]4Z~#{,RoK ç 0W պgbHt6(W^3xVUu'Lge%!TKvźغ)I(I8'Rܩ'@94ŏDR$:^q&FG~o\ݱV;kݿ2nܭ䢞ůt"" XWυ 90[L[u>v!!Wʣ'AD!yred 11`d^NvS(_oؼzR{ 2ic?$!HCP:O~y]xޥ})O< "Hȼ~ K_ v{Se95{GQ\W^U駇{-]{MZ)QX@1j02Hu]/W& _p3nRw oO o &GsepTse( \DeWm/ #|ui-"q@OG3u` Q>A:Z$_=4 MPuFxe h"> U(ġ;_`: {l 3ZG ͦq~872Xo1B HhNhZJC if^Bȴm *^j)@i =hc0~䇏OȷB#AVU4rÇ&m20:e& **{ك-nλV:gT!څ`cDžD$zt FaL&SjxdjFx0jEm``~ DY0?|o!MC x',,΢e?j1i'φJul3|OOϐoSuZ }OO;i1J5Lr- =Цd12=vͱn0nsȓ 7|~WE,EؗqERJ3 5BOkaw(*_ cLFg̵9 NcT&Gf V&r她ɛFg9ѦJ4|-_w=}u‹$ۈVtf]9S@QCnQSHN]gYz?0 H\Sr(-cXow_';,ƃ@fIENDB`Eqonomize-1.5.3/data/standard/48/help-contents.png000066400000000000000000000054321416454732000217350ustar00rootroot00000000000000PNG  IHDR00WsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org< IDATh՚{T՝?L 30P0 :(Ht$$1 U1ƅ q-Ą2Pꂲ"!In\ a5$0(Ĭ 0}cpan Tu{Ϲ~ZQnx3`i`ҥkm;IR*'|pKb@kMKU) ߓO>c<lx<>!xLϣ*o*$1X[l%8E+йJ).V\P B)*' !x~ x:ⲤP6&^7@X0Ja1L-YHw寪BMm!+>6ZC|0lpP8uQi> Bbve |/+0JAr=;t Cٳv:Gįg>u3v,JIT!0ib`>yinJ{k JrG6ڊ7Ii'pWUpkO?_*iݻqo>b.#G*%z垂{8+Mnza<{زlkFLIJiد g>wڹǘ#۷8;dOEp BpF_Ts0{ #v :%K:"0!lRⴴ %W]Ļ{I q/} (I o2zI#<Ǯ㭃i}Tz pկ%cK0 .oʾq1ağT$?as7=7s,3 0!':ٲc|:>Q==j6[lݶin\y  4B~q >2Z G0ųiimźr[$2zW0i"?Ԫ&Cu,N2=r)Bϋ׋0\hºV^5Y˖]c35oENךp( @.+9 ;;TcJJhxQi C]z)lf~0jbQ%pB4Pp@Ny';x"( BFHz e)]8&w`+pT:5j6&P84lHPBSGvH$JɧEcL2Ia*CBl8$۩>?#AS|5 /KrLnH6E54`hBkpr  9kj$A6mDwxf߿ux"Hq-f<"kvcT|U ~|-/⋰2jApl+9bﶴP4X RGI0 [͙@ O}(%x\Y"7e琢WS[[K<' #Aۉ$ۨ 䘻g+.u/ y ;q>G)uBիWZ.$}7E]Lyt5c2ҽ)N?{y|TTԏ@j!uh'? [ N) N)k(?!2m_@'Xm"ůܶ!nRc炙垄1P+G<+0]#v8(F,xbK:*P5ÂӘ18NP(h..;sOSQ]m1P=. ąk׮W%Zk-NYtRiiqeY$ɧbfKyWWW&Ht#X3SBg&OmyufD??&4IENDB`Eqonomize-1.5.3/data/standard/48/mail-attachment.png000066400000000000000000000061061416454732000222210ustar00rootroot00000000000000PNG  IHDR00WgAMA a cHRMz&u0`:pQ<bKGDC pHYs B(x -IDAThylǿofo{m6^!H(J(ZId|N{V)mR?ڊ4 s!v|ޝ?NPIOO}ћ7{q/Ž88Nr0]<t;!$@b;a˿qpU2u1c I\e!;ˊ:3Ts}NADfV^gС5 X2YpMOWb}YYBb|YU|Z!ZS [^^>11'??)tw_9r%D6jttlSnui&Ѓy޲TWWkXFRcǣVi(*^3qKiٞפk))[M +a_lw⁴4S 011ѣTOlo<(WH_YSP / _*--?6_^E|\ ,]rVd/ҥFPݻwς/5OsI{ HuPJtw 䭂5~\S-%ۭOhbA jGfhBsS#QS[[:7߀f5/(FF@VVI@j6oڌ&7h2(Jt]HN.ONcc Ԋ@q)ݠPps"l6N"lܰ gϞ ej!-Affe)F1)--XQͦ$7mE})"gX@g~ \HZc͖+d_&b<aĚѱ 4*?ǹsg)X}ꩧvuҾ>LNL.)|6[喈Ȉ'ssP_^_o޸457b~\Tqr!-VxVF6.^b)C~к nsQɞ])IyZm,D, ϳX#6gՏ䔡޲ o6zzv%'&FGGKhj%,pb0(#ҿ"a%>.4 m-,ڷ/K3ZP/(4H职Xۍ{Cy^{n>`0AE7Qv=e뿷N*q7VЃ&cz@57tf{L+'~\lZq\`.p$IX,?Ο/qȱQ  %Yd*W&Ʀ2LmN=p+HБ5996?juX7GTeg ~~X.3#{3sqŧՇ J7n//uF\H\,BVT%S33Y_ݯF  xnJ'ZmƘh ;g)ZJ M,Av8SJjt:r'&&y2 I **n]Er##ChhXJB%+jbMV 9|}9/a^(N>l))wsuMM2 [J*>ݞ0yU{A)r+d~|^rMDK yL7 o/E!RJ}}Я2B*9^^^T&}&1! )v/t`3i떇D*l :#q{?ȖMp^:U`dgFNLހ5v9Kl`cZm:*#&n`pp;eKkJ%ð{Lt!]ݝ&en|~{RSRYFѱLLN(ɘh 0=B__#4qzY[EygVVUTxDF!JA)E0Č{p4}~kMBX-/LaΝ?]T*]*R<Ϗ}?~ < Ⱦo*0a}LX7Wy |[یo&IJ{q/v LtEXtAuthorAndreas Nilsson+XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/tEXtCreation Time2005-11-044a%tEXtdate:create2016-05-15T11:32:14+02:00i%tEXtdate:modify2016-05-15T11:32:14+02:00DtEXtSoftwarewww.inkscape.org<tEXtSourcehttp://tango-project.org tEXtTitleMail Attachment{HuIENDB`Eqonomize-1.5.3/data/standard/48/preferences-desktop-font.png000066400000000000000000000033571416454732000240720ustar00rootroot00000000000000PNG  IHDR00 1 gAMA a cHRMz&u0`:pQ<bKGD#2 pHYs B(xtIME j:#IDATX]lUwfvlMˇ_i5V Di- A4b@D&_FG#4FC#Q&`H* ZP -4tݽ>ݝ3C;s"m&-[+#7H>=sGbcVYs,qi0C.N7Ϛ-I!]NKb>*܌lj!p?k^b`gC#@(c/G\;?XOJޯbVFU l>$] *̦yn~>y^>`#w&KK'E#gDF1uJ1aR]2~ p;-4qy8XA0B7S֟Շ]\=< .mi"^) ,S+Q=s4! b0LЎp8 ԫ;:*d89WŜ;ARd%3沑7r|\|y 'E3顇:L0 8$ъ$ "\PC |1ʭ,sREw)A]gxFyV-POmpmU ɻ,{.D3k=3pBͽd%+U{"Bj@ mh;=maw`?c4SdzUu 6S:^ZU/y&}w83i I>e7ǙU>X7,}BP{{kEvGy)=~< 'A^M!EYR^sPVa[Y}I}88 C֕@߈0}ᶒFi0[`gУK=&:Y$ņ@ NGx_Fl@+qi|A18|N3o>'yZ,ui@')'Z`>YJLrNj3`ig {0đ(#M LO/2EU]I e& AGRCaaak/+ ӧ,~ ۭS3cPu H,BR,c!L!,,LLRaBd8><ֵ $IÇQNtI3V1|b*" 9vy3LgDeDF!*#ɐ&ILa,z\%GI;=@,YG7PUk(#tEXtAuthorJakub Steiner/XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/%tEXtdate:create2016-05-15T11:30:04+02:00L,%tEXtdate:modify2016-05-15T11:30:04+02:00=vtEXtSoftwarewww.inkscape.org<!tEXtSourcehttp://jimmac.musichall.czif^tEXtTitleWi-Fi networkU½4IENDB`Eqonomize-1.5.3/data/standard/48/preferences-desktop-locale.png000066400000000000000000000042341416454732000243560ustar00rootroot00000000000000PNG  IHDR00WgAMA a cHRMz&u0`:pQ<bKGDC pHYs B(xIDAThˏG?a^#  A₄)HA?ޑ8! !,9 ulóϙG8xNQSgW߯j$j_;!;RIp˜s +. U]>y~|i9W<#^P,LM;⦞,UGT(4Ɉ∨Qߪv6j:j n;) /' g^PgGF+'?}861 yf !ICrP\8}Mam֖imV;#9s- u(j,VxyfH ?n?$O}SccS47Z,=|w5i'+"Nc3xKt|jD/Q~YjUAiP`u68p WXZXA"}PG1z8RB+0 !3Parp%5Z)-acs4IɳR(կsM o}ޅ'Ya(^fzF=mpXՈCF^mV "D`_;POsy,#3*p*!CbbM֚7Yۨ}F\å5AP vj #gxa<23ĮNSGCY0e F] (259 NrWY^aJB-j/+)6K򕗾/ZV/rrGph~s/\R7|/r=} E+Oh#&#Ea!3&ݍAX<<4C"utB$ ʥ?4Yhrc ʅ7`8O~@BH ~B##;;0Jn^AR(HPJ,+z.8NjFxOJ9F_~8`,>-1> >ri7Ζa;kBSW;af`ph;(:חh7@~C{k̭+Y ^uчQj7xN;?\߼6; ƫZ',mlKfF&b?@5]9=a^E+G -;8Tt鷄@rYFwA{9hA[J $;6T@~QGF<~i%p cݕ)QRE=D(aDN"b&M"Ѥ0<0/]# e=B;i5uVZi .ƙg  FfD=QViC.$D [o+s46 v]|LJt"tI{GU|g IDAThZPg6 A4Dx .ĒKJ&M9sM.ѻT+jH.&$T ٥ H,4*H9H"ߟab3_yuƌ.{h>p[$Ty<<+[PxɞǼYkݐeKd6Hp^Vnz#[o^fqDžreWKK ꠻ + x oIp5F(ї_*(UUL9/׃XRWVn0՛DR! ;`4Id"ђk*Cì:FfAJj"dd.?5M~\#Gǃ -7HMHz::1= g!>)Sb!I)iH,hniz$s2$j1+!YD lQ|v]aK< !I+$HLl dj@$.6CyeR})\fuD,mmphR`ttR3R&ƌh1RJ4\L]Ȇy s0G$3u KMPM &S-\jiƬ2YOR)-+1Λ/H~nr;Å"CX`SK'` E}16 ZO7fWuOҸc\͓#Paɉ|6E}TˠReʪ9Qb t]a-*&=2PWoW^}>QvH ݄BWCeZۛ'߳9KC.cI[/"AOj|;F3U]R0*Ql7e.9% V(Bqidҙ&ml- )8!Kpz F5!;; q y }sF4aSs,Fi. u>cv9ɾC[ 6`AdT8`D.ϛuDm~$^PP4iEub $&p\jkSaa(PDpHL-<@*UTC^DW@vF]ƛ衪l"5*&Dz2Ř@*mĂO%A!c_ ? @T '0iҩ3Waѕdf‚ݰ~|n8thTT cܼuZ;Kj L731oe ~G/2 K}׮[wۂόTv%7OjMSHYtMXqg&=ѣ,賧'*m:rĬInDM&[pT1DSQU1+|F+@% Lqk0n[Z.ajgl~ϥao+> UKi҂Yɰ,%%Uc%ۋ3bLNxͅ#k%d}h3`8|?qlLq={̸,xl[;Nb1E©8xkpunS`Dj㉤"0_gR*Η8 uu5eA!ǠBO3[ M x.2fjUP5,:( :7/OAPq=8U:O|!'!9l 84+|ZPw33/*.b >*: (P0'im J  [p[IJ?قOX*!j̀PPwǿrͪ-ώ}uT_'+t pE[kX{`_E@y`__"l`hDFy6&:dF E␠ ΀͚!ٽ(Ơ'rZ Qb>i  )H_ǡꀰto؝-rczծN((BWY öo" +[ :::.qqYkmAnD<#rwW>:*[$Thtypq NP<%Y:Z%Q/`:,?xkZ7ł9B΋zMm^[Xxl*MH"OD1zkSc dus8t '%_"6قIJ>/@\Vٺȗ@X~sA8#!rz`X8_e7 ĞںjI$t`c72gDNGv=؜ ,`Q nܶǤ!XqIWn%D <<?' 9lf+KB''sG(ڎ%aÀ-ήl/k]\k79bI_0|Ū?~r?]]}ɹK \eȄ EAVN:D[PL$M">< #  )ZJk_QsH]i=.j{GGo:Q U8΃P*З>{a @xɠ!&B'=@#Y]xr Vc.wt%@R If.\zۮ>pDқKuYDo7u2w^T|( )%Iﵚfu y Rq岀ۭ̀*1pfu-\«mm%Ģ !͊ötx\EӓIZˋhP'Á#U`w*8SnR l 9ċ,5|]g3="-ZGz^FL>@3}JXiVLilߝ4ΙM8\JKaq$wN|/`4IENDB`Eqonomize-1.5.3/data/standard/48/tools-report-bug.png000066400000000000000000000061361416454732000224000ustar00rootroot00000000000000PNG  IHDR00WsBIT|d pHYs11(RtEXtSoftwarewww.inkscape.org< IDATx pUO^eH!Ԅ, b2 ,).X* Kl"[5 $Mw<Yڙޙ{9yQ"? !ڔ߿6 oX3Mpcy???wPPZ__ߴ@PbbJ Wj'DDD  IOҏf$FkA (..nKTT)L2S~#)Sfؖ<{t%<<|f{LOO?ѡCZ 3"/'Rf*Vi|;w&,VΝ;o!46'U:֯HmqӒ.V X,~Ney6UpyyCڜ@hhh jt6zuqc"_EI<bcc@uynI+@̙Xg vq}z${7xc쒒'&Lɓ'KYY\.j+VTt'榡v.hⲰJ=0Wn!555g7ntQt0K`XSjAUW5&I( 7!Ȝ9sZ*++ 7"#/9Pgq9$0oҢp2Ol 2!6ۗt2.kelZq?)I ʒ1r<[ʊ5R'CFߔ!ҟ/,\^J2^CAwՖWS&}}yax^9?H.RRR"sg+LNT08Θ_j)?"@I6&WkUGkpO΄ɺ ?OHҵkWϗr6&2xtK.HW*d%}Ds،DaN`9w< m8NQro>"wB1|sU|||J͉Hpnn&?e)ajt,'ulC幊Ji9SF &whh)dg^|(ac>>Rv(r"wV6LUEpZ?V~Kp?|ͻ/R.> 3#Gd+H tZ5ܔ9]\"SL)(R.1MN6K)ب ȣKIKH=/n_P]e)VSjyXA )¤Ir+,˕DT\$ >PUΧeوH9I*§\yQ㱺/H|+)A0 5{ޥ-Pmg#ɂef8M]~4s3`@cvyjIp:gTٌմC,xʭF`YsC1 r )J =k2Z%0ރ&Bn£ H ,[ qEr}2y@̃h}{>wCfnQRDÍ~u))rUkPx`5$Z\rС˵J5I>M#Fj`'%Bmh=-Ջc mh_ܢAi@xJ/dBˋ-7d@`=z|SC>xE?@ЯdA Sr=n-+GMuagYLV3UmA b#۽R_E=|Jj4.f58LRqv.,Ai^5]Үfg Jp@gDtzx֖xƲB96W~'qpK,d(T-YJ,b,9>'&F, ZL4~Wp\ ;L+XؤC}<tE`> '|ECAMI`oqL( A4Dd,bf4`[7-xL!icᑍޅycI(E&MO6?J?s/xq#& &kAA%Bq:A/cYo`c# [@"4Vإwf3[gU$ۙ^\GAƂe[ B=|k%k+.)?ݗw,cH$ZkzfI;hyF廓.u;Dbm $vc+r'Ql6^?-.CEx= @;y:ӥn }bm&8q/s % h}hZSLF:بnd :&Pt2}I~}cVu{:u7Cw mJ3Vk?"$6kY&3ڞԯu|8?@zB`SXo[/6gAkIENDB`Eqonomize-1.5.3/data/standard/48/view-calendar-day.png000066400000000000000000000054011416454732000224420ustar00rootroot00000000000000PNG  IHDR00WgAMA a cHRMz&u0`:pQ<bKGDC pHYs B(x -IDATh}l]eǿs~nۻv!э ]3(1 (JhH,k2, s8)v[˶==m{;;|'99<|K+HЁ@--?m޼9Y/>m{Dܹ;#&sn߾=Z/_ueò~=6;DYre7ʾbŊ+',z(Řo ܹ5ݶeܝp7ӉqGYj477YN܉{|>_{]%0LSTknWǶm8t]랱۷o_9ẁD<ؙ3mڒXya[n-{LJmU+ݗLSWdppfιft4f&iY @YǾwxnt#161MMDU\.Pz9 ]=VV$[>qKn7诿q߶ ow߇6^L&𯷎+_*l W/WݪBo[B: tiihdd1 TUH$pq$qb1 4s|`v͢"+BBq)Ba`0 TL&d\N6ř3g @Piò,b T0tH)}9|r#ncq;SYMG?cǐL7l($!:qySeמe?B`gp/ʴZ1](P)F)+W_E.L㘞΢cEM7;<9! lRz6n؀͛:}r~j\0O8:k{'N(L RȎm^7oA#ٝWXzZŚՂSðm 뮭4D)E( 10yBi 5te229q9h4 CaF0ԇSy䬞HtEXtAuthorJakub Steiner/XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/%tEXtdate:create2016-05-15T11:31:39+02:00LZ!%tEXtdate:modify2016-05-15T11:31:39+02:00=ktEXtSoftwarewww.inkscape.org<!tEXtSourcehttp://jimmac.musichall.czif^IENDB`Eqonomize-1.5.3/data/standard/48/view-refresh.png000066400000000000000000000075301416454732000215610ustar00rootroot00000000000000PNG  IHDR00WgAMA a cHRMz&u0`:pQ<bKGDC pHYs B(x fIDAThYkpT}sVZ1[0vLK\f8M%vgxXi>43iF'M'uiH zqp  K-$ǽawjWHvs=9$>U2z[(I15ۤA.N]Pg˾~$"-*4K ]ǩ:B 0Q&+mگ6~ÏDev&H$髟_PgiZ\ Qa 0-v>-&L'n_oO6nnݺ=Jչ[E`C_TeCkZ($$ÙO=C hl9TjYgLa;YK;L྽thvm3VPJ"AL & "o$wtFz {Oa_[pqMw{:u5a\޲ok ~[kxa_wVz2R]:M,t=F܆?@GǞGֺNqg^}]=aϑr3_ذWĈt+4J3"I¡=__,.tL&T/2\SBI 8{]>{Ru{mW/.]3 ظlLp04rƎW(ykmB)ĪH}OPD`mpδ0e(2X(>0Nΰ(C5KÇ{ojhX`!]%|U;~MUz7?yjQCYP^l"Mtp&ES8*Ƃ1T900-bDQ&K*j*C#GXbq%C`?{ Sg]]1X4+vd$Q2Tx8z#qj҃+;Qs@--b&8gT55u=KJ1!$ceEgZQ]m'b0Ӡ7{J嗏mYix : {]JE1X6bKMq55نa{[wviK)O)R{Ơ=r{?o (CW}.T'QmE-k @n֘N` Dp`, |j߿p SDM,@r]302-)ʵSq歊h]I*-+qx P-`B$럂!e#" ⡡#׏Ec/̼\%L`|.5՞گyV<(Wq.*%4Ƹ$1&$XJX,S(ѱ[?9}XWhvV/2 J@Nq=Odx醅BtI@ BCm'ѱX g- `A0}5S }vZo5-=T&rrv:3C~I."&5>WϲgY g:A9~>i^d?7đ3@tEXtAuthorJakub Steiner/XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/%tEXtdate:create2016-05-15T11:29:00+02:00%tEXtdate:modify2016-05-15T11:29:00+02:00IDotEXtSoftwarewww.inkscape.org<!tEXtSourcehttp://jimmac.musichall.czif^tEXtTitleView RefreshbIENDB`Eqonomize-1.5.3/data/standard/64/000077500000000000000000000000001416454732000164365ustar00rootroot00000000000000Eqonomize-1.5.3/data/standard/64/application-exit.png000066400000000000000000000271231416454732000224230ustar00rootroot00000000000000PNG  IHDR@@iqzTXtRaw profile type exifxڭisL.9Z~Fz()K{N f emr΄K)= 5TR~'ϟoͯKOM}q=~l~Sކ z2A ywwSҗ)Yi;㖷ߞ<7>[]םtX_~3s9nCJ?nYgmD럯g{ٵ ˕I}L|NKO<Xm2n/:z`mvu> 12 ϵⳫn,15{ =O˓Ҙo?ϷZ_kŸ\ar0Ƴ܏cx0Dӷm@/c=x&d粵c>cMtQS߼yEw//"4(+Vpf!Ƙb%ؒO!ŔRN©}9s.V| %Tr)V]X45\K5:mVƅǞz3ˆ#<ʨM7L32l.\iWZyUW;λ/Vnk5w ոGVpe3,Yld:oQFgZY e]>-v3nO32LrV?R 'x>.eԴg][k>52W-6Aٌ^S7mݫ<#8&k7{A}z=mG CwT3EC59z##d{?WÞb7q^{m0N뽉ps*Rm~/;pM&=Li1Zs9{_qvlaPX 4;ܶ5b&[}0\ZźW.^#_L5z6"b\{.WSfyZ3﹘w4{? |n6 rZ9j-:)f:tuzb_Ü&& H6p5ꝅZ]RJi/+9ƴĹ-G kH-a(O@k>=uEB/D)y}dezC+xy$XE ,; ڦU903%s>̇DMND}7:f7D@(, + jm@gߏV1M/xӶ ,)o\ZyYI~{:–H&l49Qxs9#3mRIIAP2gIԯA +=Ǯ+l9v]Y-ϰYxo06f.VV˕Ԭ,P+!_c4)l$ذF/`,_[-.D\r7e1 #O@F#ɓv$Ōch\էE-)m0Tp$yXu]"evm7X%wD  1k[6~67tK?5c`Z¿5ͱ0P@[a| n_r)ebhf[`On~i7EI+LF|b}Mp,2 ×վA>le2Ά6N/Lx{wڤzVMp kԯ86?FvӼ áNLWl&K\a@=!o?|$"Q{bvъW꓅o"y\/!%CVJ]o-K0 +q80Ug wg"g,d`16RH'p l'JO .%\nȹ?2H ؇zEByijK%ϻMEJYz)HPS4צ!eB˷q}K"곲4 ]|"X qb,1qx3 AGO~ЀRfmV?T4Vl ݱdE4F7 G.7 $ &/B#!m:(δ}H勍]$+S<`x<LX%6p5;TL2rEҗ~`Q15%7U!jXEH-dJ`MtI"'`l IX1x}=/5 GWcR L|h9W$Ç1Gબ'vErA2{{(BNAg02O 4V'&̔xiBE(-TKe[G02ҍp.E5a>,+ˀ;JMcYZn-"MOgDo,Fo`1aV}|AmehipJTL#(U,nRXƍw>3h ̀Zf?dPA$AD -x:TƬm'?\.L.eRJS(nd=YB0]ŤRT &wR !\yjPI ZRVBDv"T Z3[s'}g> E `$"*"yfW}^Cd`]kH~M:m obufqmZ)Q D24_J9 ~u*k!5h <`&btdI 6̝!A[Q^cZ?7[@Qo)6D^^6VB_*r@ W]"X0ɡ%EirRGhS?b!JFqDr>J,H?n"bxCfEAbt%{@,%%/& 2I&^$GVQusIi?4˳Lmc45Lp9ԧhy"; d (CKb {Uۧe/LԪIHχ$cri!!V4rQ˫ .ik?'&,c⩍:4i֡y{ĝ62O~S[؊r9"}Jq%ܵP%"-"PbِzޡJ8b A.tL\U3y__MxTp$1uyP}}RMsIxZ4[VHX$/?9 \w4>tQ0˟r.4k50EΠCoWRXP*:'TEW7=WDþ`@8\ =*l7! Y9u8~PT,ȣp!.o`"?H2 BKK@T%Uw޵i95 BTۀ;p9DQI%j_$q$oGI#Ecva9,Wj?Ik惵"zVӁ)Y;/>7f5T}[G,ݟ$yjKbaj>~PN^u5}iX?AsOc $j :-oLN W$㒻v@đB'#,TbU!e6IjTg6'u4P=&eATuL )$CGUʲ{bk {He&&lL=;d!п7tA5IXsLsH ʣ(rt"A:h]xԑJ6GiL!Ntvt@t@~^'l4UAB 9v眂jѽp]t$~\Ql&ϊ3H젓=_(,hp%/ATԈfv_عf&$-ϗ)5Ā!K0H[u\U轔zS"Vv XUtR2*.vZ6z6NzK,F8hIlX !v$q't: m(b^*7E pَД9vZy9owD#7FHb@HB߂9+\/agioer@U?sGE'>P#%qzcɪtLX(hY+@M̋/<؁XSh6m "&Ah`S)[#sYw9*zDl:ڌxܪ)g& XOz'Ը$T n\'t퇐N:U6@7g9 1w1)Yi WS%KdW"4%䯺$L<%2&EI)MvGH? p}XRY̐W]wN'QR=j YZF"=0f 'B^}UEaN"؜ )aǹXNj{NTjJAI6*+֠m Քm\+Kdh?B{<!p=k7-8_c  &T^j:?r}C=^۩SXN)V*`ծ=N`Bf"R6(PN^3WRUmBW/%}#sWOȏE9VU!uTD#(Sƌ:Ci qVJ>?$BMV宓ͰŬgȒЅ, Ο )UXwH{NAҾsҁ$!m:6R}'1}Npx"TYcx##hZHf&kR{R4"HY;$-.(sxg3lhmep'ⲓBX 8rtqJY$ƩK@~tN/y5OhkrNhzwR:D3L98ڂ4sB" *ћ?sFȤs +}Ie$:bx8pTIyau뢘7Lrb OSd4F"ǢddxŚ =hQ%qSJ +!gGM3= 5L.縚-G_|h|: JWM=3웄;#^{@Xc?3_< UoHs=zfrgd!gH;g> LY7eܥA NÌܸOBBAN䣜 ezLZbBr.O[m=6ӄ}L?yqZ&fD'x6!Y#GSuňoiot<5\QoQ5e (1YUsBq殍&{pC~=7tmn~~z^u :g%O6nM߻4*U9w[>N7-\Poގty0H<[d hu>gB6 KiCCPICC profilex}=H@_S;8dND8jP :\!4iHR\ׂUg]\AIEJ_Rhq?{ܽZf8jLvE }F?3d2u_"<ܟGə 3L7,u覥s'tAG.q.8,̐NB -̊Jz&;.#i <~FߔnU>N4uey4k>r~ QbKGD pHYs B(xtIME gIDATxyY}?ޫ>Yc6K,a9@$dIP!rh Q(DF@`-60Y{>gό>{zz3HQ*1}}>a.z@U_N5i8u6:?#6Vց [`"u/]z>*\塔BJ J_4<@89JI<Lu=Wdd2<ϓJ*GJVkm(2QR »Ak`7xwώә/'Ƀa(0ւb-~gVW,3B u]|mmirR"DՖc"M@_~?{ϻ;D3{@*rgff?|o:t[71z (˔2:DQDEhZS*V BR(|7A:o'v&WX@@e *@a濝xWFFol twwٹiu]t c 5+#!QQ5&}k-b-df[©x+>`tI)rd26~(0Ơ^ֺ1fY׏q8 HG~o)K p]IRnzZBZ!~x.@#K8RFvf*!{3^l$4ŰBm4V2u%m4qR(EBP!#QJ5Niy@7i&G0vbiT8@I)G6E3OcCP/ppD3WkB/x>7X!I\E}/Pd˽Ϧ./5\RpK'cf9`דޚSWIEPʝ\g}fb%[CdNѠ1 an>=~J`JR{ Z)qicc ~ȝ;X|;7~S/~z`NPw` 8}7.|&?=GH>Q.2iZ8P9lf)xtC;I|PXkeyb['8S_i̽ro~LPGnkTm#`9fŴ O07ϙ?"gؽ e"3< lG*%+"2k倵u~bgŹvD־7kW"P| jHu{n `vvP\&jU*!B ˧vgs;v!D=vfztEWY72~*f9>(رc=^0'0zZ% `嗹W_1z޼o^lQcg$4#cvhNnX7YJL`Zufx"Quj88W}{x'FV-5WMɩi{*W#f8 (bdd~Ξ=Kttt}v|?4+Qp>=;]۰n~|RTv@ab.З._{y 5bWkv왙N:ő#GصkLKY\g3l)u5}(#IKD&sN+?/pxخPuZl~cvDKy@X a|ttt.b[7oѶx%7<̫4-[w6 /mf˲y_ԌV+FQ2£t'{Urrr۷sA0ܹs,k" |_g,Ƀ?M?02Foq8];ݺZeYPz'zØ;::xGQJq5Xr.zyfwl?uPfXx[ߊ݅$/PYDq֐S[,t] 2b`Ic^Z3=Çʕ+W8{,)(b3 L:YoeXīvDhM 3g2o"h;dݻwo>.\ӧZյ4~})AT( Np}eL<-1V>EHIޝwnG)A*).&mmmEhIbpÞ_ A@~4&pw ߏ F XN#Ď.]P(P*p]'Oc1'u4:r)E8"ѭ[dvwILr} \Ewc"._+JLOO痬-w?KC-Afg Y(B:i}~R)Pª/;H;sMN׽ִBdJb D}j}[vR71s`bK&՝@O1s.zQmO1v&ESBYX0qIIy]3E<۶q~ӝ9gPlOهe9͈7?D_ЫO?mW(mL$4BP]F q]ҽc\Wۺ|]XhxR*IjAHKϟprǎ'5 ŝz+MƑZߒw]v=t1f \Iڞ&-W_teBjO9:VO\V 4*)Z.تέ  Z>1 . 2 3Qq=-־vz:NЇGlz9|H,'XƩkB5ˢʐ޵={0p-{(zt1({zI;{sWXVP2EEH _ c,+Ҡxh!#yl ok[[hͺy4Kb*UAJBr9 bMkdRt>L/a՝ #39B&S]S/6^k]0(<<bp]UґUI/?bߏ.AM0^ahJ[<81J)\<|}Ē<4M(AX]!SwvN7WfF88i3ɥ9=8|-]¡RjIS~UUP<\OUU/r1"Ʒ2`}^}S0gN<cNOKcCɝNg&",7Œ!!܊7$+H*Ӡ RҺsS\6h'&Nfy. =rzMS5 bJT a"$Hff3d2Y24Hc-VߞǤXn6#'>4PJ Cpݻ@}&7MRZk}󈢐\.G\<2 L֖,lT*'=$PY?KjX]_0Unr Ube|S4X%I1y*C* Ft:USa{ck\X c0iSeҍD@ UDQHX$ Cr $mҒ%H>JU(g 6- 1h+hJRl|ΑQ BT.ZZId*!uq]wMd돘WTZkrohیZ]%N8S L[{ȴIgH%%J$"˭ԓ0 ķwaX]RNZ[[iim!L* kdFnXk ZT(2WR !bR4AL%"Rjr#^YRnv,ܨ7L4R7xcC*q36~khd"WK)kg 1mVCK6t:EX`ttJIH$Z~/YT7*^fl5Mr(W1P# zDtp&q, :z _xAa8/_dlj jAP1Z,n|' 2FG=^DZVRjfZ>} x~%^8.6$jn\G7t{{;v싿OoajS뎞_+`~dpI{G0Z[[s'6C |b`]?p3yDZ ;|?}8??_.IENDB`Eqonomize-1.5.3/data/standard/64/document-new.png000066400000000000000000000070001416454732000215460ustar00rootroot00000000000000PNG  IHDR@@iqgAMA a cHRMz&u0`:pQ<bKGDC pHYs B(xtIME -o IDATx͛$Ir?3#:zky KT  \ )DAqyR1g @a0*3 vv+++ˍGTGeU=8[YB )b$d8DT ( }΀ #G#4F  c*pC2At ^>S !IDAU`f*uC}Kſj!0M1(f xȯ6 SHHh JD"9l`n!S6dloց Y!b-/A_ \ ,\&I&NDG`#!,E̝4ڊIEF75y$'$s  dQK1!"2dNJA0MQMhGsm.}Z)JD ; ^7^yfu"hh & f1cĬH:]@RAa,w(aAү Hx0% qaW'Pw5 D )#[i"DKִzᯚ] w hgmnO Azۀ ( ]cz[?R`V!^*B{T}>iOC`@c0@"b<"9l05k`BV`krm0:,x_08 Ϳ)Nqw? D N.k1+p^H7yb1f-06V`lS sz (u0ä_;>Fc6/Clef fSDjAQ|%x[X$UPt"` 0` C5(QVqYn,\ bj%" _`_d^9Ǯ#` 0F+5r+Dy%s$"/̗ꦴ{P`M9Ek%F%8į) dX+bl6w`lAL^%V+("M'/;OFa$){ ! )e5 0F (W=ө;|g٘PV6zgH8:%B\`xF8@C+)pMi\-1fSf\7tPUF^UUv5$I; cK<²W"Ch `)&dy$-SwK}DSOp\^H@[`-Oǭ@OXJcD&_h,`8-]ߢe0w~OF&HjFa!0 f୏0Yalh`ߗ?_ds>!(%6L0aL1M@^1~c'Y+mDrjg)`>e)l6]^l:m,+1]/M_&TUnI臰-Ͷs;R=s >m%{|vv͗@r].Х}~"@hkDtzNOK~ m O"}aߦ>O l݉}^TUuz. ]wh{l6#"8~ps\:7,WUd2aXtOWk,`W$\__3 H Ի9? *(*x.)8C.NS`W:q8rS3§gݎ Pg٥\ֻmځPs2,Has;#>Uٮsy!>+mh}^&IeyW_}Ga JS뼪o0*5>G _|<矧_|şHխCefZ7| ףyR}&~Eh2I+UT> %Z=@˲.%ˣAܥ$fΩ+QY$9Haf6}4َywl[ʏ%IhtihW5Ћtc~-^tEXtAuthorJakub Steiner/XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/%tEXtdate:create2016-05-15T11:29:01+02:00#cg%tEXtdate:modify2016-05-15T11:29:01+02:00R>OtEXtSoftwarewww.inkscape.org<!tEXtSourcehttp://jimmac.musichall.czif^tEXtTitleNew DocumentIENDB`Eqonomize-1.5.3/data/standard/64/document-open-recent.png000066400000000000000000000412121416454732000231770ustar00rootroot00000000000000PNG  IHDR@@iq!WzTXtRaw profile type exifxڭi+9p)t`d[2ilYgsR~b*5_-6h?xV5?\y?|np2?ϩ}>>0he/σO;=b/ X\xϻR`k ~~K~~>{>3)#VNw]~gs=]QsQ7.3mWN8xyd}\tuwܶ&[~«{⛟򠇅F|h.ًucqw6"NSP bL1oO )r*z9s.Y8K(K)kkڛoKO˭ZE{O+*ՖHAiNLD:<5ځɻr*c ~c"=g0WgöhB%h1Xm`j3O{ۃ.AJt-}lU7r{}$vra8mo=u3r-,1Fm)=nduk l ƌ>6˙C)/KF2ut^N`XVckn`,Q?^W1޷$Y4666V2qHeBM.\YVǝ>s.`ފ_M=x@hZY؝%ZKGX{=!:l nA7 `-s"q`K;~֖QlP@7KjrUY*H.{1g̨>ۘmn!SNYUMudD'$$D;.2mUyO 9e: :ZQlz\m YхIFb$ָ[V"u8=z6Z.1$jĔ oۏ߇ YP2. 'y";~|\8-N"}nDԁL:h"lK8 m#3'BDY7`F5cN/ۉ|&7%%3:['vpP XГnjMF:}x'rOn_*!&\0)4^WHKFhDe?N(y %Lp"z<ACbt~9C@! \(fuݝv&&P ɹ9dtoeG˰-ae8w3xѳ3A3Dq , Q53*yjQ42k t`Q:ńP0C ?U0,x12AvG "z/WJSݠJ5]/Msm֍l<ũctH/xBHR F  /`Nt7N9غ:f n@PCAu WM#;P L<:RA7 պ4⬩@m„;MT$vypWmZO$ou}O8?WA$"r<_|CCi8#; xN08BumASx;ϋ # *bz?ʌ|=ᩞ8WӚ $E[7s=C_ #Tw\5gƊ;cR䨑LŽ6 Zu#vԬMY >_ⵛqvP=i/X[Ts#ڦ3[AAJ`a8 Lyxjt. Ma,X=(q4Ģ" Fv~d@2nf&0[e? mYd$t$[=ik]۵OcO줛vD7qF&O$՘@`}cM!E=|G9ef<dQ"cUfĥx#LoW0!|4>pqJDP~m)fW1QM^$uCY k%h 9BG\>QJ2ip]T^TASȎX?Ӱh+)>*%&R٥Q UFy>4\<`FOJl]`cG|B ckB %$nԛr hl AܦZTc{#~A\1C-[`l\EJ@fQAڕT~16V$usTʼNEy75zPt%є8؎һ#Rii1d<^K@Y,+NpJ %&VFׯ$b@V!V & Mbe)҉muIl0o]3H ԎU7g&BfK+(S$oVw.7ַ,$5_g~]ZA8  |ÒBi-;R3N7ntG0`Ѽ{''#ي<6t$*-xl=l*r;|Teן%q{&D\^u_{{H'8 I O%} uIj16B0D-VI#%) ̽lX/ֿXB邕vy:DWs`8!7P|m}s ֐}rBV'Ag?ŷrHLyU $SC3%OK]R6DE$AiH%&[1"I%b9"P5x< Σ `0 4Ug [{KGB`G5J%l̋Pv8?iǥ<z8J*C;;PFL)WSkX&+5r6}*iD&%"L۫mPtފl66~9Cok t 1.zQt>-P.]jdy Qi,BU h@ @y< ֪D5(4Y8tKX% <6[5:YOR!7D6Z6xxw{0h@ұ! Ys."S.Djۯ8IwS H,, upѩC99x@tUL){biAE@lx,>2cԨXE8n҅o* 3MT(AK`& ey]N(DSw6R\U%}LɞE#:C ssiIN #ȁΧU""*Twx2f14 DeZqu[x4GqU*wacߎlp@@' ͍D :˟NEj&m6-,IAEJײne\ V"M$#ˁT&>Xfp'`\sQ׆" Vܱ֌n !q3z-7QX~,[*fh)O/S8">O#;zeG*k}TZ˫p@˸[lc؎d@Vįhn6VMK}-wA6K,[վKF1*oPU~_pR,* KھQbp6'C#arWmXeK-+q>TsjFk:2Rފ)ϭlxe 7[6:hkCZSΪlA I3kʖe"vrPZX:Z?Š2 4bZݩx!44ߩ)  ca6g财fYeU]M &Ц иYz.K\E`o!|VJu )Pՠ}o Ѝ#>)d!N֣W?> eSyK71 [xȼhSB bY8eF㔲 g^|4}FhE.p?wٽ}0)lojLiVh@c@'mjQ}`ܷ"ueV0u;ES&x5"cc0\3.:lV]t'w+Bۗ3\IpVM9"qD%ŮDX%fk @k6 ]x?!YYe[Dj@XpwţQ|pI'Iy%bL**{4IkaDf 1IW+&2N Y1+hͥmem`꼱O vK<2sVt)AMRn6b' uŕp5Y$˟IV-v&H{ X%Vk!-dv6b^꽩wt(<1$4UA՚ 8蹕cH|Tx_aXB4z9,+aDo9JE볻D&U1D&d27kO> 4De"\IY6{Im +$ˑHP=BđѶnzjHP-iZyZ-bz3j cUVSognB4+\t®KЬ/㎦]fT1B¯5q ޔbmhsH+oe!dk"Dey%WQ#hdkQT>{:,AJ6 yZ+Bl+HY#J9~础+!oҰt\csѨJwy;TYȴ,Wgdy&#gmFiͼh͎srG*QJ. )kV{Lm~&@v< xݱja7>'"\f d6m0)p7Iʻǹ#دFv5Z)aB櫎n -OGJ4pU0A[Sh5 IwUk.Q[0}>6dshy<]whj̫4S#52tn3;(V3:sQ6ye?S%x6ͤVljrSy&"D z-2w#:`&,4`Vd05\J:I9pomJC75(^6-=֞V29"5.A>|.@L7^5aQϵ(VMP ܂bz;85wS9%[%}JT6k>34e~NbܓVXH 5n"uk@I&̋ϱh雿Džܽg*zT*fg} دyqNj *s{ʟג^2k θ8p"te*+Q\7; 3܆>ņnhli8'I0ϷTDlRCiAb} Ov-i#LpXKܗX-O\5ZfikEKOԡX"wwb{~;E]7:ĿB,D4#FKRu2!Z#N_ Q 7*MNhqkՐåǒ1Q&8tOo e+XO+eF/!vޡN|~ Ǵjh~>L)s3%/G 6t&;,[T)A9Ec*HPg+[␍w8?},s&`s٩+](>YA5 _e͒ y\vUWT-0GOLt"6niCCPICC profilex}=H@߶jE* vqP,q*BZu04$).kŪ "%~Zxq}w^fT2Rɮ Wtf 39QLs|(s*9>xEA7e[g[@ze{o4rE+bKGD pHYs B(xtIME1WMC#IDATxidu^{Cr$."ef$Xv8)6 Fȇ_ $c'1dٲDZ܇!93=[uwUo7jꞡL%Rb =sQu_z=|։?я,~?LG4N*q̥iZ)!"d]F4du=iXuǷ6~~)ԧ~()~/~:NLibm{m{㺾˹+3`WN8`tVAe27rNn}iygo_+_Y*`m4-C4M1Mrq]qp|hN`0 z.nO q}9 \[[z|f?Ֆ>.T[cf'VC@k}= yh[[[W~`{ ~3_;}ׁ|s>;gkNpEӲl i`4Z)Qf)Y$ ime7" Czavtx[/9i1?ooX,Opij {.i0 oAD?MVnRVX\g~n+wS͠\*ÏrN_~ M?sw5Ձ`w޿=xCria )%ik3~52-8qfsrn'Odiy9| XXX _S(䘝0?lmM4IiH) %Skxksin FS+bX}޿t 3 `0sy.qer w+QA)8 3`YZ:R!~.2mRT*TkU* a vQ04 \EHvmpwnh{#е7^O9'OxR*& g { @wr$<Ž.aUlk\Bi\a|>m;yJB ,ƶ\`;6jmqksFE0!<qAWNnn?qAsO.4|䅗_ άģ#;sT9ńr@2Cr|y/B^vM\\.#Đvpl$ҠR.sIz{f$sð)v\,=QΗgVΟ뮯kyaٲ}?>/}%<}Y*G35fN\`f$j/_rj Ү"d !I`aJe5۲PJ# 89Bv٭~CBqUwK;{?cWߺ]/w_YF[gy5{н*yF^2sŊc,Q&M PBE >Ґ(Fh`mc[6>NNmӲR:)aW^z?so=\-⬉Ll}vUoiwr 9'0兇::Ċnk~I*@"@'BF)5Lѣt!S:90& XaZ!0Mޠat*;λtZOrុQ:̩%#N79Ԙ-އ K=fO`mT5q-].P>80E&4tv@Y1x"-gh!ZQ*=p&e#XN^Zfgon ^T,qcG*K!H]̴Nma{J/wo|OSŔ-H{l_`sok)rJ $Zk$j! bRH)'~T,`95^-Y8$.DU6bgٽfq~˟EFPj44 (^BM(@+Kl!077CO$4 qyVkk;OJiw)04rxaHfJˊ$Nc8PJFǀiuhJk~B}Π?\ ˜V8PZ \.^o x S KEvNN6 ڠZ@TfЬظM_zLkȩ'14Dq:ndjLzPp=JKI\&y|) 4M 4̖$uG(j3sKRS\NH!Het @H t:,LX1V_5q^^N&#WCԴ0 (=q )$.m/\סiG!qc|RJT yCH`. =2E\v.Dp{tXc4i>I= d?%q $ID&!1MKXP(i6:f2cbLSEŤIHv(,?ad~~ U|sl/Gw|',cwwzN&#sԏ-ӂKr"s) ,ˢX,zIeQebdYj03sK\A$iJeDA!v(@0,B 6Ԁ_o`3G ӠZ)t`(_Bʼn#mW^}I^{I{mJ#3%Ҁ4=4*N&mEan| i怊c;b&9`ڞpNӋkK >9a1FiaYeÊlҎ3K_o%B}'x|_>u@L4?CLRӴnC\r&æe4MlA+qLiOo^RF)Y /콏M}ڽ&iL,ՙ{K#!':Gvbi췞%I>q½\6{u_}Ӝ9sC)& 00MR#>2e%z&~\.Ox]s}Y <5VL)Druo\2!d2+؎c:kl~H\m*meh0W^z4S(N>{/R(Oƴ0MNi,|!?HC"@j8@)LM03mHkeM:9Ŷ-}|%|tHCa?[Wߦqp@cAdgϞ0 \=G2!+<#SyO|Sc)Ͳ$t;dia [li!A:SYr~eGki:L0aݶܼu0B)A#cK1Jg8_L1(R 'MvwiLCplV0=[1n/ 7!%" ) vvY[[%B@cQ #b{ IO NR azE:mHlv{4Hii YivAʲ)A'HFS,olrc Oy1@ a]"M3|ò,,$|6s@Fjw{`2F毕¶L4-ZIL C؜H)CS7DLNBa&tA A.G)y>itbelm$ȺRo./u)^x%܄R 8+|]OZ3EnY`q|HZa%5}dNF=w4VkZ˸I@X""67oFe?SUwlz"͵ PTp]Aqz.Ri592w2Iq5H1 IƔuaP:.~FÐCؖMVQfӾ}=\ BxҚh4 LqDg"89S$&'? 9~6b$Rdoo7E1GkH3E!GnKۻ0^, #RZW{=\*'1ʀuK\f~nvq[24v9_YqDdm&=N\"סZrcܸ,Vѭ-jamoꫯllu[9ߣVAӴ €[޸AyRκ-B )י L397xeZ6Ra9gksC jf]ǯF |?NDzhQc[7qj@eX-iJ HC-Mm[aN}/ƭ- }v ~k_F0ŸbB)EdiiixW1՝hjޛ\r \*م gΜCIݦh6SR.){%Vέ0rgdiFG}6q^EN8^[[ۨJ v㚾~munշ~{q觞zJciXe >@X,]w++/͋rJ'4M$qFwjaiZL4H4EJuy0Hl8JbT)a" rfζZ~;o}AߺV{JljGp ǂ[ 8uZIQ4(E ]xmYY IӌL)T&I r8@MlT 8I`m"@7[ z7{۟ݸxJqV}k s ض8|ϙgu'K{QDQDզ3ReX8$qYV+8_{[+i}o\y [Y@4Zdul_c VNQ,|r“gϝ}ZNXE8I$MIbZaw\q€f&յonm<[߽$IMh#+I7Y2b;93a ?Z9)eq'VϞ=Wslۑc{#1M q1McT1'qLGAwµ{;;NZ$ZHH` k Rq@k-Zk-03snűjQ!"7RJo~a~yfvyU4 aieVAd4MY4zcFƓ;0?&_*?~燦(buu WGXSn2GH𤔞BXBSW@Je*ZgZX,"T_k5b>y$Νq;wŋûFM:MSq6͝JTgs[A'/LchM=}"׻~j7 >VԈ;±Wqީ'vO>l q ~]l_IENDB`Eqonomize-1.5.3/data/standard/64/document-open.png000066400000000000000000000110471416454732000217240ustar00rootroot00000000000000PNG  IHDR@@iqgAMA a cHRMz&u0`:pQ<bKGDC pHYs B(xtIME -oIDATxZ]$y~sNuuO̎vgVM !J +ۀU~Bbtgr 1"9ƱJZLOwWUWEw|V!zfO:~s .t/2@D$ Z/vH$"DVJA)՜[w~4˿ZC)Ռ^kcGD%"w<(FkX "!"U7ZoDDf{}FZ.q _޹scYHD MDIsiZJD4vˇs !&3߯`W_M_keIc$I$"8::[k#pTW33F,(JַC #٫,vƘ`fF#ܿ?'ιO7X Z[Xk,(vah4jXN'"akk!Zh`0޿[q$k7Q^UUe9( c h4¼_%I%;]ꢧpp8pp/`O?AIH(pvv<|4Bw_TKIlfW_?x@?1biz ct"u45b[k( F#@#X ^]/`z-w&pvzTz<-Y)}J)`RUUWu- "L&boo ,*iVZGdBg:q3ߵP^ݙPf"Du( !Z-5_̜`gg7Q*S yݏoDK [ZvZq$QeϴZ-eLz>wao\G݂&V*W4@7 ^ptI?<i*bclNv{p, yv UdxXp7sZ"a0.'bH,Ce8<,=!oz!H spr9[ c<c BFxOc<>UPxAOraˆ ,1ƹUHi,+x]$hZZ7S߽=}@*((e`=M+cr@/d |("(**hG͘E2*W@fs!MS03R(=B&pXV{ /`E>0Zp:*y>M~EQ׳,6꘠NEaӂcA\ڥ-k~dY̚}FSF)$p2ʅXn`::|1s:PJYP84AKpVK*aE$IqQ}(_c !&eIӊgE݆sn:;$2\iP @ftPDeYBUUEk׮tۚ*/ Ad9/%L#} ??&N ߿q8.L- MSl淜yt=cAkfB E=]!X^mq@8҆UA%fw9 EQ,+B`AVhcVfJjDjvO3+d%F!xD aD7yfkfQ)5~!4a Œ$N Hia\&XeSpG:!"M( @w?.ofJܾ:@+ e |y$ECFkЊ LJhRy=5"b,6C@k0Ri+]j% uI+#D(Jc)6")l1FdcA2Qf"lhӶRLy!5'1 ,WKEQ3EC ,03("'ڲniph%.a1 * ◈[}/@SȊ ~$P@;tV `HD'fݻ8==I8vJkRp. edRTΖ/-7kv_oߦgy߼ySyKsq쀅f<i28.:pccǾzK+;x!>rJBiv{[ӫ1|>?d٩42R NͦwBA |=j :tf&ǰl:k; TNCat?~T:Rv5TBNg]i)P rC)%% 6¶,X c$ ,;֪I33S^#dzzB_JB,YkpgX37H$v\ka"çe")н8@f=fnKhІlN* feG`arrD, ;^^7muݸXRFH0)R(B! "#-M BZ|psjC)M,#]Q(t% qұX,& _!e :A;۶m;J2qHq de,@(I^aeEtضoaI)RJa0T&C1( rPGitA ,RD}f_[8 'y|+_ 79$0*t]zJi-h! "*CA c}6VcaBt1Sq6fh>A`K1Fi4a]/+| 5h#Aivj],$HP0h:?*d!D[)> w~*%`+l4HbK V*$|?$eJ2D@xfkIڕM&Rh4PJa6Vk$ϸmۃи_BK.q> FNqw{/nh .D!A 25|>%B|?dccRD!!loosGU&&&Ĺse{mɶCFD[sa~~~aqqqD8qF]]噟Jp{!ǍR&O4mIsSIg(66ݣX,RT<,/Z]XXXq#A荝0 G3gPVO\xSƘb9 @/SmYVO˳>˕+WBZɓLOOBgNMF ?ThcH,B UH^gmm˗/˫R uRl6m)o6nc b1 jYQ8m/ʄaqZ(bІ{T*(oBsY \|ׯ嘞&ؖT*ܽ{۷o!FvqRdYZnD"SO=2wW^qbGZ+<#܀0 Ű=*Z n"h34Ѩ7hw:r֭NJA8KnbT*>`Xd~~T*E%L>ǙR)皜={g+F5 lRo abbbn0MQ}La 7ٳgS7T*TU&cd2>v8Z7(d2*ӽ*GGVLORjuVmz-677qbHY5q)I|ӟ_yJt=CVRp_ 8nmm.KKKd3yb=vkZGwyfO#ʭb~˲.n5Z ;W.S(FAQ'LbV>uHA,^,jܸqkz}{1˶i4,//Od2IP 8}4?uk 0ȞJW@W۶YZ:~?ޏ~oL?ri^oŋYZZ'Q&c Ź"L{>l_x89s:j}գO "ZƇ~RJ_Xb,XCJﱃ#U^B8ў~;g 9"b1;t>O* "~t?8H: X,FgELi?roTA$N @F8 G}`#7`zL͔1} oh4b2`tȾ 71J)B<TC'~F3l4bUBXzP(.2Ɍx +9}>x~m&\W7h4ZQo41! h{ ĀxOOvwwmgq34:9Juc{Pjf9xmT hܬT*c}}=Rh2l;wee9J 3J%m H#>sG"BsĽLƘ=gRvc Z|o WoN^=55|u]WXmYXv1llBXV{3&[e6Mo'Y/3w/Y #Ԍc0y=]4Y_/ի;:rϷCbдŜ$LV?.F$zz3-DTڰ,Hjsؖ0"!yH5#աNӹK.Vk@ T*Ng˲ 1cC4;ȃ_q~-4ƘrT^ǧ 8Cb_d}S7!=IW@ 0%Pi#1o!#EF%_ K:VQ1taO'cpUutEXtAuthorJakub Steiner/XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/%tEXtdate:create2016-05-15T11:29:02+02:00%tEXtdate:modify2016-05-15T11:29:02+02:00cUFtEXtSoftwarewww.inkscape.org<!tEXtSourcehttp://jimmac.musichall.czif^tEXtTitlePrint Preview$IENDB`Eqonomize-1.5.3/data/standard/64/document-print.png000066400000000000000000000071211416454732000221150ustar00rootroot00000000000000PNG  IHDR@@iqgAMA a cHRMz&u0`:pQ<bKGDC pHYs B(xtIME W$ JIDATxZoGvU4j!){HKZ+ ,$#6l $oX>8# #bF9;9搬 `I^,J" 31^!gԇ?1]]~ޫ^ =}OIG ADOwB@J 0@DRwߝ9`zf'@,yCf@f%ԟ'I*I/Z,i?g毅m_f$I~v4+va$Iʏx H):坝W ;zRDJӜ;fFt:pja9T"~t]A>jآ8Z痗a&9&U*,--iN<$aXXXRˣz.eY٘'q[fBa"TafDQIi tQ*O* Cx7!.8.!Z$A^8 8ϔ ϣRL)[|"tQPՠnBߟgϞEq|"@H1(mc"}ݻwqi;wJ`NL脥c@DGwDuT;6 >R`5>$ 2 ȻG&wO^~J)ض 41z|EED;)#]}_.[ifp!ݸqqGQJò,|'; =$J'IJ)Eٶm( b6!,*J/R4a6RPJmJ!"#H)o&VWW駟Ѻ |4Ϳ?2 @DI IT>{y~`RJA0Ol!4Mi @ !0'I7L :vww'K@?Wx^_۷ogzAA2GyVaFf[Ν;WvZMqv_yXV| g}6oU /_ob^MLiꦩl6q{Zz7tc{>`z-|E;;;X[[slfsk&Ctl?*N'<6af6h˗//(E׺CgόKF"xZK/ȴm{LuRbTOvn e R e+Ο<|yX"KHdض8kmիr{~~~BҥKh6`I7ZX077'\yّR/,jNzl6/fFktX__D> /Y#61KqDHF2MS<f';1,嘘A>菑cIOʟ:hAz_!R "#I1777@^rJ%J)T*Hۆq<4͡~d: x}q`.2H{ )Ba&a4xTy]}?RP9ŋFL˒^GDvIX&*ݤ裤n! F!\_Օ\t_OCnvN-²L 4O߃iX0- {{{/Eqv >S$>:}j\3ń#8 .~X]]=JI}Zmx]HMg0h4q&ܹ"i{wg,S)=gT&c9BB#9˲l6v۷s>:) lfNx& p4M\pgΞEEC$ӳx88w}~!qmY?k!07`nFZo#}A*i?ֿv|̜ @hp; pb7VH}Ta sbIH)T?Q:|i@z2&(/}@ZErs>րmX0 c30?6̽ !u#e/ Yh_?Vz)%$\~ԪcB?_T{nץ=yԩ±%Jcx }Bcc'Ѻ^υy$蹮k !Gd *>VoZv>8lA٧b2E&9&eq~{ixp\gZ_7^7ywπ^3;w@Twߴm;|_~;d1#yg?ɳ _}5tş3_bg_}~{?X}_u=oϲk!̕M}rŎ952E<xmnm6:rWZU7S|5Z=Vd2̯~ ڧ|يu9,ːo_c_k`d\;Xu<`nJ<]q{=u $M5$ !DBc1c5SH1peC9K_B%\JUW=0MM5RkmI[h~BwcO=koađFeѦ~fgueŠ+ʪmbmvi]vkWzW5w忼?CXI gyvSlNϞ>:Vi1<uq/广ܟO C;uLfh)=aaذr4B  wnGQ*LNp^ ^+ArBuw߄>CdUBƨ%SxCi5dtL N0zM+ LS6T>U^ bn_` dk.hȯ@. } `oOln*+dE2%{,eM] K$ L1"5,m!_aM Q_+=p]5^O?y$FMd\ džBC-u]~mQ>g![*T'kp%$H 6^gDNmLa?rTb %:lwn&/ жH L"T ͊<7h: )7ܳ(RPQRMs˒6'$!.fWE:lC#eMn~HpްShzp"a>IID+޲NXUt 2+DU;mLO=U'P WmDg9yYo=|qUa|s*@.oh1.p V}-#ߊGxڷ(7‡y,T5Df0^g|}b^j:i<^%(Y"܁AR6$ǩk~ڻyPLk#oP߂8$|@0Q6gn82flZUgf*Z zWz,*o@*]\=5c&'Ij UqbI@Ph'!C((pT51'"́0B!R6S`mPX[cRTS쒝Cb"V>&>,ɋ%gO&sYe oa0h" DVR1VnFVs!ΖK`%!O::7Z?W Tz=.8^ huD<*lfGE^nUW qP:Ȣ06rV&wO!@ck7,d$8_ 3`) #3뤻A(;y)D s`_8͏}tucbOSRL\=@WA3rO' ru>pv,(1@\rp(\!6G>G {YUg@(䁲҉_0- {Nyco a@H GxQ(c*+@"|L6]2ԺaXsE 8b~!+Vc166~l]"-n3m í:)K!h> 7F9-Sʩ{|"Y p$-8B#xi4geF> bہ #(ގO ru*GRxGDfQ̄Ae_C\C-ۺY0AX!,>өnm{lcX@Sa{u@$#M̤r*اx.SvיWo+S2J k+B:qKmx޽ [-n*K&1[/dnp T 8)SAvEI"止l Izљ1Xz=XE[sA$7qDP0Cfw3F (޾~Z fb6C7x5Z&phg0u <^n)d)Bjo!{+gzLJ*ZW-ZN7 Òp~n2bW K61>)O}GcB^ޙޙ|:E{b&~z| Ŏk+x sC=u=&RHE(P;ICOS h5&z67Xk2WoC^2EӨ/{u$~ڷRv'd+-&@>Ӻ&$EIgD'cȨ QW'DY-Yxpnz'#LZ{{QWDJ>IK=g!^}uZ[  [L ]X~:ID3p:4+ ȃB.))NאRaIX$E(IJR&K_d< T 8KGI5R]^&Xs:ڻQ/ݏjI7]VPרp7 @' QOlAI{FrfC~Dj 7ńZi!$GTOG_sy.3v>34(tWJ g{c q}Ю8VjE{H|ѴDbk~oR*ӧO!:1G09y~`dvNWGP9{Ct;aHd*hK HxP@uP@@it|~:$t<(]ʅ8W;DzFm$rn9P'0֩VNQUKpMʳrgS- Tgj&hIfAOV CD Z`N"F^^@kj=QxtZޞ㹦&ﰤH%&V ?ѵbE=VO.6/G.!Vw+4^[QGjv=[ .:cK\br~@vK07Lm[j{AJ`~? a-\tBgp\~*6*JWpdpAoKHm̤F!p̄@sVһ;\Eb5wrCsuVO^q0_n+[CԤ@"܇빷3:CΣٍpAlB !Xrw&!zP"82R2ßwBraNv#v)YH!=T1|FcZ#d`j ;'Hi\s, iیS;iFHsl%0k yAcuR2˔4b0L\+ATα vszhfӉ!B\8=*%0aP@σt/ 3̦N?syəK Smeljȩ[Fd 9oKRvw@|^8-*=hB֓ESoWP:FyNv {ĉ~kl/HP bzņCCGGP(:KmSƂ(xM| Qĥke`@_z9g Mu'<PtGN !/\+p{C0''sGl\g8Hyv:lPɺ-vφ0ʡ"TM C&#/BK> JS.0rCWO 3^'.)L}Ni+a E+CCg [l:>,5]r4 D"Gmbbcbzo UzCzk4eR] !={n9} ثr 'C'jJFyV N-&ZA+E{zM1$roaO}y\{qv=07:jŇ7E*>#;nj^i>7h2b6 WJ 8eGΩVR^t"흫/w ޻tno.GϷ*@ ma{FqFLzdۑ}u.2oωMJ $tQ1QJѿ6代Ov4HϾήw_N:ͯ]ݓk77{:HH>cWP˳Q泧S<5J2y# eg~*W]}wx,)g^&t47Sc ӳGR0:Vߓ+ȢB\ T4oCe8jޜk:U2L'$'X sa&d dq1A$Ű-ԗ~{ \O#'괠؜8e1z*}LQld?@1Pziq/bԾ[9EfD &at@يu`2l.U"0'3[/` f^iCCPICC profilex}=H@_S;8dND8jP :\!4iHR\ׂUg]\AIEJ_Rhq?{ܽZf8jLvE }F?3d2u_"<ܟGə 3L7,u覥s'tAG.q.8,̐NB -̊Jz&;.#i <~FߔnU>N4uey4k>r~ QbKGD pHYs B(xtIME ";$IDATx[yWy}kV;@%Y%Y ; 1؀!WLQTA\T\UT(T)%c]}1=3=3%Akzws-F'yŰ SX &f^c+o `R٦V$2I&' q㎫zx4"צeHDfe& '\Ǔ' fvhX<| јпiJ{_d dk7;)tUPk(Tf3s sۧogMK~R:SϽeKysWW`fh143++F0& Y7`-,w0ٙ \~fs|<2 ˭BK`gY0B⊹Ty>xJR!bE+IewuaK$=I!Oݟ^5+D '~aЄ""ZkKK@]z"}}wn߼~٫0WЬ2}'I=ݻ TL69!T1n--!O9}媙뚔f4@=F͌R1h!+EKK=Im'~yޛrW^-T窙fZkA#4"H!.`J0 A[lٱc/'?Ů hd!ST̄B,BBRq H0LDmXn`sϚ޿j'nW!:>>~EAF?}HP1$TSO%Huhf(Ä D8:]Ro:/aqH_+`#p(@,M̈́?yeA71k! Ix:T)RJ(^¹sC8q8N:ѱQ,/FKKXi;%y&C~=l+n(>5~0Aa;6<<,H$ذi#i-ltСONNLX}jV9G5#HTX E~e2aQd3DͨjݲeO?]8~ۚ&VR…: )0`&,B$,٬ho|y ~o!O$K!AJHĂ2$ǁp%F."8zSM.o`#"$]-XA,pR 0=&@%u.Ccn1 O倠j⃕a+դc꾨 f,!! H3ucwEG8oH©љ[ pH2ƬfU1%, 2ḠyO[콷8G'F?柍~]O۶T8g+-V &+4wKy2XAI a^&Me֡X^2gua엿gOϕo> h`H%ub@(lvKZ,!/]L PBiu!0ݸO~'?TvCPL%Wʞ?m<-^`lQAKpKps~ l;Coѱǔhn5f+bA9 E8 ^PUFAT N hwTxI :Dt#*cww>G u^0#.C~ ٥qPV ^NDLз+b`!U'S!pniцç>/ze@Tz ?'؉}=T:Q1bqix׭XwG)8ɪCA!m$=~- GPJ]:fUҰ`4JFxC]Eh7f G<tݍ{vG2"W^ Х??X`wH:L_G:Z(<[4)%,Ϝo \u0 r>=rehy0-b JCvE\8yzlV7=6XvAyG yؙa#5ɛ> 2jv #~N}?;?躪ysӘhCmνC"݈% E9P\HX IHs v?3904C=_hI^/@!*R*) .m];@]: dddW9hL0N]D8Ϗ>9P}|q`}%s`'0Պv=ȎƐ%G$ 5>$(QˊA&K24;l v.3_X*.2u?n?{wyį>gKFLƻjYQ$A<ęa ,@>U G!}X:fAr \ );5!3(V gQQ>pXVϧZ#t'ygܰe0 D[7$m?\WP@,ށXkkwBCVMW~G3՚?6f@4b2ify2gGsBy~4o`&MuBF_fV2s^v,f}߿_yz ( ~%Ŭn?\!+$ Ok0|13 ()J /h}́_5dА#ǡR__y䑦 (,9j %זNmѕm u M mkYg e.kvǜ<##uirr^{: '* pӧf7nش&k8Fy2;]14t B!kvSQ?E54^|Tiu޷u붸,==r/ߨJqĉÃϝ8zl"qa$8244v>pvu( p uc&q" tzĉcobjfnbɆF `OUJT,7Nzvdzz4+^=]W}: r޾f!~Hw|(Vp_th01 m۶3g8q0ѿspgE0RrOO۷/̌{bppizAc?bBxboίz p2D%7`SM6لOS;lGfF_"ǼIENDB`Eqonomize-1.5.3/data/standard/64/document-save-as.png000066400000000000000000000137451416454732000223310ustar00rootroot00000000000000PNG  IHDR@@iqgAMA a cHRMz&u0`:pQ<bKGDC pHYs B(xtIME  #CIDATx[Yl\yι箳o\3UhIbKeñfs;1P(} (>Z14}KA_~Fq6KIh. gY0sGCd.x.9 Bw|}" R)riXT`Cuocƥ(`6MfjI댬$-J[[JB?R(Å>Ż(P4e 3M68(!؄@K5ņ/J\ʚ A=b@(}}]& !Ä3F;ϥc4s"H)yv=(W/cH V

7uЈ y3 |f`㙸}8H:R.nVJսX^m<AۈƣNq8IFTL T: |JbI ۫V׵,\1 :GIZqh(ZRm O+YcjӔ NMe)C#!T P(<1 *us[Tj}!Pf.ۭExH>W KՆO닟r.+VoΞ}C@#Rr9M'ꘌ1 ^ . u0C1Ū PA WϾ7 }agor(b}5/Yk|gG\iܲt?I QO*WrGm\cK2t-3]^ۖ"|cPT ~'H?5t:JY#?U~LIYvh挅_O~?|퓱YЙy>aq ߐLϦc\R??@{ۊ=o;@%wsN.9kl޲Z^puF "F B)!DSl#ьCa38iy\H(um/ 64lZZ#I6~R=")LJ)BҠ ,9^z1mƤ\QLU&WO|u}2m0P>4$d]ˉ$%*L'(*@*Yˀ~- c^^+Sv`NY6=_@up.nԟ 0p7brrr:FI_ݩK '"M{#)!$|*M;DcFl\?>J:\.,,?CZD"qMyt,?-8Tu(A_?ڏ]`===}ԩSF(9RK+hy> ,@PR"RPM@N~Bu|jmkkkꏷBҙ3gٳg 7%(%X>qNGGGaZVVQo`+]C W5R=[*K .(֛x%0v A `A6GPɓ'c?]SJK.\؃_ "imB =#!]?~d2خ6xMnڻF݂a(泠:zv62?J~ݭBB5 q0&iERz18,,,\pӟ>sU!4"18cÄl۶hpLTʀPHAXPB(Dr(굁BPFM>t7ɣXu,Dl+H:PB8m0 *[X v$Im6,S&bB sY$"&8`ajjlZ7,--yGw}c]`6==~H Lh+'N81>0t 7L9~*66+`: ].:4WVH\G :f{B.bbbo1؉{dJ+2^eY*SiH$rljjH)9R B 'phApbD DmBH\"4;0x@ Pk6|ԛ>RHEL, /B p P<9\Hd2Z^^f&&&j(!$dfcH* @ȚmD?(8u@ $c& IyߥTBnjvCrxb0419~YL3c},1Y|>QJ!NR)bNL3Д@\ z^9ZG娵|[>V^ p R E6ah7c_*@ i"J)Abb8]JPJ/1 Er9(MOO&''ylPpb?0]Em`K)DQP@6xR^  FMXbm} :8NT1dB^|@6E:[u@z``R a N$C\A)M@)Ɓ- EkuPw}4\/p! IllAD i{Gab/9H&zX,&#ΝK1m칑9v}nlv.BK"F[TC,bhx W+PƁ>Jm̏'qr6dĄdDӴ0juuaǏ<]{|iF4͛T A@Jٵ|pyY)\#vF K1rpJ Y)@鄅|&l^,РcI%-w-Z=4Ho<}X cccs=w1cKhtW4"cSSSv,MKW:(D71Q@$`A2bҝ :`0h3ȧmx>^ B0 d23%Iι.\׽2!/x<>8 d ԾϴDmN0?E>E"㎁с& ӧGWt]䤙I)9s~e>999=>>~tvv6n Gz$r &Ҙaye:#5AX:3Qdb&^[X@ 4JnxP0v*CD>:A)UJ)bpvST vZġO%P:q&LDmԡA`l0\H GC cf8 Jpze!k|&QTu硔2#ȼmۇ zK0FPJQ pQ]* e~|<% :<[p&q0m0VlF6'4rFGFF2LƲ.ջOga& Ài|k>d#_]FѰVBZř}J j.pR ˲`f7 ! Jqz>}sBRjBŇv ^ v2t]G]C¥h$ܗ/7/-1G?A"V^)RJ: \8jRzi'4M@>Dž @)u!gPXDQ{-/!b`16hoθy/ spλFT(BDQRH6V+++d`yy>(|>˲NضG)r7F7Jl+;5҈;:\` tߝve!lD_1x R zk_<L^x?k+xd{kJ*)&ؼB]]>Ya:L&1ܹsQJ$F/šecGZVanzVٯM+٥ƺx c"Zri˲၁/#LMM!`;B*z)LOOcjjjG?(QJZ"PJ)c,mfW_%ӊ!eY47qAm(Jx/~GN?(li4rՍ9כ&nq݈BZaJS ,jZhL%TBa"펯F[0 @B;߭0{s]/-ro0Bza{P ; AtrYtU [`@4c[܄ -]^+jQ!mB ^vz=W{L]S҂z' ?Hz^OOz7e @oGaddLB: \=[jPJ! yMJI;7!y, LLN`nn.\ԁ!NVV* y衇p-J)*$mCEC(WBt^TB,+#M8ah !$\eY'7Bw ~oe 6rmmx38yjvvsssT*ݯv/fu;]8MRI_<溮1DkFZ}sJ>`Gj-*{-φR.ʍFzVGo0<2c,缸4 1g%"{71f[˥R_wnPAF9˲Һ5Maπ*U~ ,BDGӔR R=+JR< Kfa#xA{ 5:?v;R*r7iZ@Ȁ{`$eRcZtEXtAuthorJakub Steiner/XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/%tEXtdate:create2016-05-15T11:29:03+02:00N%tEXtdate:modify2016-05-15T11:29:03+02:00š^tEXtSoftwarewww.inkscape.org<!tEXtSourcehttp://jimmac.musichall.czif^ tEXtTitleSave AsdgIENDB`Eqonomize-1.5.3/data/standard/64/document-save.png000066400000000000000000000143421416454732000217220ustar00rootroot00000000000000PNG  IHDR@@iqgAMA a cHRMz&u0`:pQ<bKGDC pHYs B(xtIME W$IDATx{Ydyw־RUM/ӳ4G3g( -ɢ)R8 y1$<b&dyȋ F^|2)k YLdE2!9lN7{ꪮUvMuOrus̓9Q, M5;Dip)o;O(`8VXVC»#kH[bk>GZA$c P&DTh@h)⣆f@$!!Bi@wE(V[ %ѭB3 D?ɻ^L!䓄3c)N RJR^ k{-?PK{ڔƻ[3C 0BQt=N' |=[.N糉tf ׄipPJ;i! D <Z{֍;U~amgjx@᤯`:AMF(%O泉_)dˣC\ehsIǶ8Ѵ$C5\SJةwjdfu~[{Gl@ vԍJv $)Y&*XptkqvL$hKJ͔BjB#A9&H%R Z K;u!T{[-OA1ID3d+MW/T4!ZۄGtRZC)@k 4TZ#H8)f, ̷VRᝲP]u{Cނ 24:GКsF)QJK!y^ Fdh9gZtvVF3 oݮUZhi} BI Lne:U&3\1H.C@kr0 Dclz. 8 :OIQD)cϯm?|s}NuCA^qkaijW)!]<;7^r&#tԨgSɍ+o6깄ݚ ͿC ;I%ɱl8~6hyo{^(? x UQo[^WkN8t-9ʻ (LΑrMӰvp6eJ{'@$O8敉RvnWj/wo&&=ΘmCjH 0qꉅS ^p>r3餃@Nrp71ڦkZ!Gk{7Ҏ sT s)+z4褆w[;{ׄ&wj?6,{ :A[Ck,V}" THZ(S%!b%.0l؋/ = {$N-5v{I{s'Ry)eNJPA֖to5 Y0[e$wZwRAICPr c?#[H&I[k_4]}ar\)HPd%3gSgHwRJoeee{^Y{LDuNֿG$w3J7O$yuYXXXr $%} ZӚ|?x~A =4R%-ʕ('to[H!Ǚܴ666YkRk9O'9oBk郒-PjHen {yqqqljj m4!>l4&TPꁸTV BiPJh^ggldxg|r/_NOA)~Xy Ђ@I-|-!e0-//BF oGu7zze2V5Ýj  U~5?-5bwm0Lqmys<*K)9uLMMVVVN@ku1>>8Aٔ2^ `E)% Lµ-SR*hD |0ƇҀ(8?^:lp'Ό"0JNxr[hY(d2;'1w"TIBJB x Ju|A4PbFpnya[ +H9))" V~hmm7?z (l ;EJݍw4TQoh8P)L̍pyqcz,ӝ 2>>Nfgg9m??81fBJDѡF.e(.Z ɠ4~(ھ'lhC!|/CP(0J1>kw)44c ^BJ '/Up0v5 eĽ1^tvwv!UpgX,:RiƘ_җk_`jrrrP(lQ'x˲`&cp`Iʙa7YGeܬØ 阝t¶mXKq'ar !nBQlGsX˲`Fg9#z߸\g! Cxf|4r'xdž3N>=-{Rp]sH):B%-˂8=)*ќ1L`Nr񘧔q <σt333o8ۄw])+rϻdHdX"E0 a3F| j9JbǟEq0::jyβ4tT*qqzwr?ē` àzf?Hwm#NS4ifo޼I4y,Fg-! F ~e?N;-qgDt0Ƭ![BRv d2cI8 bqұ}J)RCa"AV! {DŠϓighG1h4z6E9@'5M4{I!?|s*8tĈAaӿJt>7Hur{qnf/MDx{;2Qj6jQB~8 ^_㜣X,Ν;b5d2hR[n!0A` ^Iޯ" \iRֽs9w8 #C~1dxxw{3/՟L{'0 $"pi9?q╀% !m|Vx\>g4y/>QjBHgW_eZkzTFmDgR'wj6h DXUU/ /}QS)ERddauޤK-HZS (Bmbw Z|{{K8:a@0J)%Ѓ 25hGп,vopα5 n/F'⢱bN677GgW !Հ|vӶT Rʃ ެVkmmFD@L&###Cm H3A}#B? R~Vm5|?F%谁w0NEP{sA)**yFc@@Ā8'I/B3@ž tEXtAuthorJakub Steiner/XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/%tEXtdate:create2016-05-15T11:29:02+02:00%tEXtdate:modify2016-05-15T11:29:02+02:00cUFtEXtSoftwarewww.inkscape.org<!tEXtSourcehttp://jimmac.musichall.czif^ tEXtTitleSave^LIENDB`Eqonomize-1.5.3/data/standard/64/edit-clear.png000066400000000000000000000135471416454732000211670ustar00rootroot00000000000000PNG  IHDR@@iqgAMA a cHRMz&u0`:pQ<bKGDC pHYs B(xtIME  #C`IDATxyl}?3\͛K].v+vbK*Ҥ)Ď?F"E?:E FѢZ*;AHr`[BtYiKki%쒻\/yk喦IZK gy̐M}&ާX\tD d7 !Κ ON-r#%{l*R߿ws ̾c4_ai!ʳy{.T|͙%ٝh1 Bڃʏ>etJm^Pq{KLO\7+^)Qu1ֽ 42;sT({V{Vokrxh;-静\P|uATy8ʑ_}J{sH=?-"@TwZ@hn+KJyR9|3[R+[Q1R:/|ae], X}Dg8Q0uj/+و^!6vZX+'tEI;/234`ߧjfoj%I100FQA)BF?hﴮ 8@ SfnT[uv @1:^ }E *]-S"7κTHfijcx\{آAT'/кȲֽW9N{W /c^?(e@Cm#W3'lWϝzf~ͭ 28p֐(a *=`g]6ܟ[˯CѢܤj.gNU*J(g $Je(;1RWewwZmJP?RG383hqdILF\ !nuppGuxkh8[hpӢכw^;RK.1ח ,W}/EX6{8nXk^"3YmJ뽠ϥoVk}[n[ t+9t+n._`V_6h9F8JzʻRR{ #bwagM(־N~%[~WFێs65N8BhcQ|`xbĵW _rDu`_蜱yCRx?f6m碕Vt=$#B0.RHs*ԇkoX~/?.t)CsPP۹{|F^[$l͘PTAX6*9`d0k91ƫ'4Av-v] +-~[=TQ-o=W\#wP@C|^{Pҩ0|]<> "!ŚF{( +*7'1||d6r$PSXN,#3L>&T=YT8% Iؖ@pˊ:Qmp1tH"͙闖~a't` ̺n("+.O̗hRkC=Rʳ d41?|z qsɾ t?WpӁ|S@ꏺJA$U MI5\ʋgQ,WGݔHz.ZJfa94\u'ˤnaN| .xئx17 jmoK՚\Lab<31:0RJ.-ӼqnVQ7~m9.?'L,q*?*8*wHU]2* T<8L9b=ϥ70tiNizcigN'DYNAO| ^?p<#Q<瞖^KxcV_ꔪUTB%-~Ko~C1JCTZt͹W=JQn L(}N Egq+>7A8jDJBb0>|9{bc άL gX&a yxt'n:KYeꚥnx{¶B5<1*~edU]L~?~>8N}D l91:obL6BJ&l4v o^ `O _p h 0VHȉ|:vϯitC!,iI/3@]l/ NH:k_ y<%&g󰾅 _ FVK@St #+P?q?oagWw4YAJR`M.2E#$"]&x/er A`?P$l2?o.7v)O+bNJDyD>EFwҡ|& AC: tRqD~00lu֠n(,[ e>{7|[kE MsypE 3PXUJinU[tH!GX"s"Yk_R_Gm~!fi,iO՛TgJnw5{Ap/.JI )9F(%Uu)&tJ*Ja¹t1=+W@/D~IQ]ЗF1E)A `QYcO9GiΕH+ Bj,^0HX@E]H8"Az!Q@gK~/BYFdgy AqI΋Eޝy F^]84T(rG0 /+(U!$ ~ɧܿ3&|?]:M{~"N3i{͇cLƕn1=@OykɯR)ɃaT`.E#GEBUytW"!(UQE` " Ay7AyҥŹox{Ë=Ba BoíN߸Ar5}#j`op6&OV&%ʯr'Gz5W'n-lxR!@y} S$+cs ˏ{%ѹ嵥 \ah:k.Ĩ&z{uQ9Ն|ISR"~Qq?C2Kv&"(V4 YN쏺K/^Zξc|}7 8ג|'z[ ywTR䏅`."/9 T !_&(&^`R?B"~ʍkQ(kG3'k7}}XĸMDOvo|&tO18PT+/;Xh!ʘ"Ⱥ rT"dE8cyɻ~8HP/'.:Zsfi??"Ki~ݰ5Ϸ7Kk ,ULcl^Z Vr֑v"Fy%_Czez& BYEzFdqGX9c*řم'ވpߣ<,Ӈ&x\=jP+Vϥ3iT=w|isghkoVp.`i95nCA?A%:=g5&+ewrr&|M=tɹ%ENb!l[][Ο[#y)wL3ܟ ,"yN:1I矵~8m/-lv{Gm-8Z! u?1;rgl6ll맲-zC݅ͦ­Ʒ9jfn3!Ym}عՔ)6y֚7 da֝[mٛtVv|w[oa[ i./f _tEXtAuthorAndreas Nilsson+XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/%tEXtdate:create2016-05-15T11:29:03+02:00N%tEXtdate:modify2016-05-15T11:29:03+02:00š^tEXtSoftwarewww.inkscape.org<#tEXtSourcehttp://www.tango-project.orgɾtEXtTitleEdit Clear݅IENDB`Eqonomize-1.5.3/data/standard/64/edit-copy.png000066400000000000000000000063261416454732000210500ustar00rootroot00000000000000PNG  IHDR@@iqgAMA a cHRMz&u0`:pQ<bKGDC pHYs B(xtIME  #C IDATx[Ml$G^Uuxل BHB"npDB $."A.8 ,M7$^x~q=kJS󪾯z6!I:YmR ~ɕU@D5<Eѹ{ :ro0UVXZ?rG.^59 x  J 8:yO'̧&?Z l,QA=m}}gF+o9sXk;$JQ 3N7qzmudqtkgTwƷ Gp]R03'L28Vv50[Be%3@tq*hF߇Qao_ܿVblIE* I8l?j q|EBukD 6&`<C1vwownol:cqnΩ NObhq _J5%pVV"'~ObssƘS_mRg={hhHZ<oNc0 LFhڙ.L\>,Z ֞3Z[!q{0 BS(`<k0*MWǣ t]t:kWx7w#7>P=F9uZs%eQ:1HgQZ$9%r=3g5 C Ü,JJ)quEY*@# \*701 "~W`ft:lll,n# x w*GqTuzN 8~3f ko,k nw<kW_֒ty23{|(Wffع>k 2I^|y!(N /zz@>N(hRpg%\^٪g}Jk503z R:ӳ@Ֆ#"q Y[,:Bv @ Gj.9bBw<a{{.fJ){.\&}BV?yAvVӋ@I#L6N\034@)94?l \ncggXjs'C3gz@0uey{nׄAŤЯ(`<^\ȪD@/&ceNW&RKqa<,uV]￿4(qkND\0Z0 W"r_Z0Ϲ`';R5t1t+*ZK8v b2@;BRbS̏am|UhZޞ;|~E@TJ'd 辶[`;dܙT<4Y_7ۗnWHgʕM;Od`r[M'>e-CRA<]7|I= U^}͙=HU'?X]#DZrTysy)@1P6Ƭ>AT(StqvzUR R)I\Sg^W&( 'DIN%?:  ٝpA^>!1?$gkcz| ȖNN;MIA5L&(BF.]n> 淾q'WW|ʽ''X$5!1a1"F֚gT?أוǷ>4[xπXs+N fXGH[0 a?>0( b tÜVfiLă&>aʻOcu~ٳH$`fX#20DE}AuZ[z1S^cRJ[y:WRIo$0 I q!#hmu?N6o!=별w%(D//3?8=9E›e gfQ? žN,_1KtU ?t;[:kI_o_/_=T[V^DD+BgwXv.f"߳,CR./=/B߬wqt|d^1/| ƈ[k}#x>onwz: _Hfo޼pb|>S߬(]bU&t]x ~ʽyc4AU߹< %@BR]MQBuiT= zo_=_L&O~tO^>ē?+aUDa`TcV5@ZRM6o~C;yꃗ`SeYj<s;U{jOK?iDt@MҟG`?u>"3 /c4xd]޳6zB8<vqsP Fڽ1&F7+Ng~swt{Me6V(b fGI'^^:1ӟi̟J. yQ VVGb|>l6}Qb4!@cж B"YP*%M'|7~i:Z=)jt :#UhJ.M9k[𭖇0ϔ n1lNT"+kt<1&O/߲p׊CEh4+e:^n~X<._0͠IxdU=λjbz: )q:^zȇ!S|6]#Wc_կpGq«χMzOY+eUAh\6ƍ17R5|*I aAY8>u| fk7޷/ .~z…(ΨZD>X&hӻSw($NdYern[{1`!b=F\__EAlyPН&k7_ŗd _-as? >g~7F莏G(/g{di0msj2Sw ,vK6-&Ki;pQ/>յGt}ne [`PeeIiA))ϵpO`&HSkj'صѐ"_]/CUC,#l^D1j<"BHhA>~j _.bHP5t~~fTTӓʏ,6"}+w4FlUGpu{K_iVAܬ6}bii(* I)%]bBY8ƼЄ[xGip>\:6 o@= tBL 6RBch> !KxGw-렖Q 4QV2ĬD:1Yq,uhm1xC}i1Aդ !M`oMo\lhe"yٝTz]z>Lڣm:Z[Lt0LGoN<]0љdvbV0z')X 2ԧN1IAܙa/zB9D[cVw1M6_]}lįo< J~0s*#S곑Jֈ Sϑ0SC4,"4iׅ31F BL`phR4o;LaD1X+/&}%Lv~-x22G{jZxY緶1jcRyӗW։ AUN9SUU[vWWKa4wSJ\Eݺu U9| ;c~atꕽ_~N_~r*˷a `P9#_o~kc_ξ_2Πkfo_ӿi#m~vy}nĘ̑'ƒL7<ϝ6䭵*+.. pXLVm[?,Kj>v%ח6ju#C]%H8?9T67ڎ]腪@vJxWl\(0VY#YC=Xk/˭ 6'P\ ?wh, J$]bYLvǤb}HQ5$nZo]|!Dզ:cb QcJ1iA5;BT1)*IcH 1]^AlU٨@ɐ.jUa+e?8=<<뺾Ie‰## GbRE M"H eb̔HSSb101iR)% H@sw|JNp`DDJH$\fQEʲ,dyu)RLC*&_<ѱg̉ %8X  Aѝ M)%1=vJ J R"(~ tq&Rwc\(rf.9]R9Jsع}??}"oXzͳDaF$HȬ1F(ZXDՈ1F )LYff;YkI7bU[x u`Sc1Ihԥ#*_Q1~CU"&Y",%s(qX8Zka;aV% 8uU8Y$g9ȈIy5F򌌘\2cRke,F6THΪI,¢)6(.?g r3BJI#UUy.yQzADX<υE1E^cYWwM㇣afjUBJ'(Te弰8,-UIcZ ¢̬)NU;f o^vwwﷀ~b ]7)XqjMƘT+cZK-EL~. dL9VURLm&s1΋r9TU4iLsRjȃ|YVUbjmF DX)%TWEt! uE:fyj0(RJ,)23@DeN'ZkmAp4(KRyu,˘Ѫ,jjq`4̜bf֚`Dk{~)ŤAO}||ۈfch:rYfreY|XR:Xx|BHQY"3<ϭvYm;a(,jkJI b֞k1R ogMS(K]"RfN̜@B>*<<NeC1bn@DL]aM|^b^ 󽭭[^z3cԩ3b뺶m[a6Ng}cF"r1F%P2F1 ^v1&kĆue"jt1ԲKgbץBDeak1D|t|EpnE9۽:o!DD*,z^|>;88:ʜs 6lGo\{a`7%k]v4Zk3grwogWf͔R7l9UUm&zvgN`-c0`U%"JIx{gebRˬLu]露늛7Rd0,w|;n0'[[vʪTcaPyOo'ݪ,eY>&ijeduu]GE8͌1Hd %6m:v p(":Hbf]Z^FTu:OfENeU,3=4ML_O<h4h4"r5esUvH\TET>3󤪋3 ?F@n6uB`#?Hĝ*::xH"Ō1un2ie94poP?J97c&"1|i_gS@]P䪧`mwbѯz ^>ocӴZ׍vgl"ϗ_ wQqrWja<ڇV b!{wNL&gڝ _M7)JPa䔉 f)ܺ/}KȲ߇`ko8H#񤈪rѨM1&B5s3>޹[ow.*~”4Yc3C#*YgLgAWG66? )q!%u'?9XD >-:?VU>Z hǓ@ 'z ں]uH+y`3R/}7pjz$'D,{DI32䘹!d6 t-x/dusuww.] @ o3\SSJ|HTBf<>u=mX('z`Oido__zĥfiiy{jJQUa>NJSAЭaU1Z}צ{VM <@x2{{W^ԛ ˲o?'?` ׯ_۷wYԮ[OB@ƊCDaq \/t8;vMtEXtAuthorJakub Steiner/XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/%tEXtdate:create2016-05-15T11:29:04+02:00q[%tEXtdate:modify2016-05-15T11:29:04+02:00`|tEXtSoftwarewww.inkscape.org< tEXtTitleDelete5ZIENDB`Eqonomize-1.5.3/data/standard/64/edit-find.png000066400000000000000000000115621416454732000210140ustar00rootroot00000000000000PNG  IHDR@@iqgAMA a cHRMz&u0`:pQ<bKGDC pHYs B(xtIME GiIDATxr\yg} $&H[J"]\*Uy< M*QYŔR8Jʎ,hA$@; gA_%]5g{ou'? Zkض!R~B(PJJ8?x>O&v}ӟt((1@vEE!DZR 0(3J) Ѓ'.\@s$'-0VJ!!D,P$| 9 л0i*wW^Z68U!|RjqaƹfsÞE~g} iajpUbHx/b<\{:}}gڀ2MDkM @&u{=wVK2Y.BE$9o<$,dv pQcB_t_d_TZ`_z' e22HE7A=Hpl ĿaRq(BLZ< qpp@eO6}q"'0 #n0H?88l\&mY,zN"Fp!$eT3>jvIE=2sTh|Qmgy^%J).i8H&Z)8˪@&\DQtf71 cd"$5EqJcKRJrT 0h(VN3''{Gu] R0 R8tt:gXkij0.@L&/7;l iaIYJRX;;;8CX$Ɍ8 ~Y$ B rPnKCDJ$BaXB)ÐHnϞ²>KY|/>GGGsB0)nܸq\?h|`[-;arfv"TW^ᕅ_5+++puR)c=8/Wt SqV6e133MZcQGH4R)Gؖdq^t7nC677jj~Qd/]I¨!a3 UVwǝ5~B#2LV)ÖNn̓-vmss_-ݿӧO1 z>(rVT.0,!Bl6i6}֚)Wpۿ~fU޹VgiD>c T˓pC\/[3ܺu>M2 |LLLPVh4HR\]z}>'#WyRmH&TahabZlz!wD웳ܺuǏSn޼l@8vt:n'Zgs ZR/ȤL(xIZcO`RjBqwe/wXʕ)66h4h}d_&/A}d2E?wϚԫyzNB#E4JCUǏ: ZZ%nn0.Q](<(:bj<!HS4]WȤl^2_/"HHi"Qh40T `~8{-&&&looN/ U0u]l4$G=nvrKY8fXc#: #D=PaA9M;{M`a8gK!1((<G!OMt⟤]JIk0 c26A7PH!9v#vyaݛSLU2뺤 ?4M4Mk,--o/zݕMY&) ۔Ʊ7PZyಾ2 <1Mӧz=Ldee%l۾<$`߉ *J4ܻt&í)*4'|vw.W*Yj9ʹ) RVg{#RZ(ị,M0䱝0 =z|c#@y_}׮u^eivC:n׶woyekef)AoKXDk_|8}O?0NVI*ˤiX[[155{+\d~NW +4W'T 6no>ow]V8C^gmmezQEض͇~gI0َVVZB޽{>f{{E* P[j'Ps^g묮L&arrl6_ < vqO>9_f}*dulllp= ɜ,v,"v<ϣX,o__o`Y֩ozJq( /`ϥ#}ƍ7Z zkrnn 8d69xwW6X,R(ɕt]\E)iuX\\d~~l6KÇ3^OMӤP(LJ;;;4U Bp5L2S5aP.T*Oݦj~Km8CT"$o޼R?5&'')JR)0Kn:sssUԟK)3Ϟ=3Z,w]U?яJ_VM ~ϟ/Bҳf? VL`E}f-"Q,)JJ%APTjܿ_wf({<öm&&&,q;uFr]d@2BaR;SEa -w#3aMOJcwwubC8J2 kkk\ i0w'N u m}cf@ P:l00QmvGmR[Ə?~p@=v/#¢ba PvK!@60(Ь1լ#1y Jxf|,>=p6F\_Gr c4tT (oX ѾIp$$ HX` p8 5N 010( MڕdR[#N|N M~iB8ʃ=]sMcߵaT4™ "x7FD',Ì9p35.Sfny0-O%=v !0pG9ڡ % @ڨOSՀ}!>9ˬO!C :S"N ljb 2>4wz? kֱ(qnδ&npSw;VjC""phPɀ[fmxsc% ;TlEQsW KZ@+L m ?ҧ4a Z AR4nY(nɬ _Br( v zijOSKzHv6 ŖljH0 왡 4 ~'J>-j-0h4k8Zs6z#@ ctMJm!H.^!e<4*4z F p!ބ(E`b4D00a "PvN9$ ̻#7 BҲ0~U۲rW2*|  HC EPAsptv b,%އXikhLu) dtEu/SO[ZkոAο,T;Jg 斡L>"Q@a31@x*uh@AD dT)BQw*F%E 2j{ PY~xMiZSPDI7dL`Brí^NYP/BZ* h=4 \]]2op,jFP Ɠftz}5IMD> e#LM;!|埳=>>4)Hq" <8juUkP@ O##"]#&ԈStϠ˳V?{_us0vTM@l2` ͔ab./L ð04|8jU>;!PI o'$E+-38?y3-ޙݫ|3[ۗfh2B=@$r1) ~k nOxVmkcپuN7<1}333@k@(<(L997ӵpg:D 콙yvnl[i$p=0 t X,/ -cZ|npX2 \ D\2!k s?sי7we?i,PQo{tޫ\?{ӷV(/` i 0B|4rعJi Po"8S4_\y*Z)StAcX}-,lo|5xAoae'MH6 [9˟嚖x/[$r1>!y Mܙ7 ]3n*H=' < 8YTg#q08U~~m? }*I9vmTlpƹ#l13UBN噙z6zfkn~Q݌w{~+t4ٱUX'ِեk7WmX; dؑp\zQ,w[pQXY*yPuȭ 8i qI86@s+9~-W}ܼ-nbR-~Ce(8:*耺$ASG&\o[Ac /WDeb0DAkp\OS"w ~ֽщ$Aǎ qp}8{}P'yJm鐱^} 8%Ğ{bOg觪˕tEXtAuthorJakub Steiner/XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/%tEXtdate:create2016-05-15T11:29:08+02:00%tEXtdate:modify2016-05-15T11:29:08+02:00Ǧ tEXtSoftwarewww.inkscape.org<!tEXtSourcehttp://jimmac.musichall.czif^ tEXtTitleGo DownyIENDB`Eqonomize-1.5.3/data/standard/64/go-jump.png000066400000000000000000000122401416454732000205210ustar00rootroot00000000000000PNG  IHDR@@iqgAMA a cHRMz&u0`:pQ<bKGDC pHYs B(xtIME %IDATxZk\GuNsJ$ܺݷoӧ\KrI ^/>_  ` D 0p^JDKJA2H 4݃8U`f+4a~)_ ;, -Q \A@A [RE)dQJ#k:FdԫT2H>_=ki/nO0{R!7AD7X|NI2(Paь+UfԈ`<ӻǽpS2<4'l0sK]BDC [J;z dζ a@j0ik %Th奕sqG(N{nYn]`2Sf2gsɛ{r=#żۗC&"!2b@@$aIHQ_Tz1VV\ bIL~֨~I x*p&Fl B7&G[w##{ OW͠L;$)ki@ ojr׾ipO_E"R݃L]#0a[N61 ҈a O+sBƱCFĆ|/^-#7{G_gQ@1Ќ IBƲw`7_qeV7q& MI$2Np[3`0jݥ ZQFP612n}AZ_̧nC}mG"E\LJm}G?d2zUgUyja~ &*ÀDbLصg=GfR}4Nc9rhUiIޟ~;wNAG>wư.pVB޳=>vfsT֘1ufDHEЛgod`` ӛ"le5u%Zw[&O\g[oFk21 '8Բ+R}身8NҞ>}=-/ZRض\JآjTr/~aM+g}ꍚ4dRv6KRxAZ6kZҹY"6 H9rE,ڼ63_9+  x', 2aow<2c;3<4zz8/^wi&<G nP~z '<Ǭ4|(Ii DMpVu5>rC sK3Y⪷{*Ou5.=7I$$II444{w N㓣,MޥUM]NJO(" LlڟwY1{Ƙa~u}T AGg_h u#ae%DX|!_%NSg羱Ҽ7EaÜ3 ~͜&8:8G7ЈZ?n)@Dυa<-T^7 !e2SiVbu@j6t\hv"uBvQd}B͚``5pD> S10Njm$HBs!JNJ~lxڒ⃅|@p2+miZVlO ͱXlVOLbIwZs֧p6YUi5:J-Ri|jecQm'[E[t f1i~aaa dvq5jH 렫/ HVpzgbmrq1v㓣jlb2ˆq.MWE"i;L,!gkf ~G,VcJkA:db.#>"#T"Ch[{9ACD6T>B#R"A16~f/TkϥTBIl< ]n2A]ń~\N4< 'c#\.gjs) ( $ϱSp!AqRo#km2Rf.pdca~>{fIcR:6W&~ςdYi&@/!b(P9P1Dx,eTV 2sOMdZ\|[DN75ܕ'6Μ=u"0gGh%^97ll}#)0 16pϊi$gZYb gュT,%lNS՟7.#D;sىxrz"XQ6@kw}on`&O@+O+Z3  )rH3\;|j'J!_baqzvjX%'^f+e;  z~8\ڤ)[Etˡ/ؑOg å֑wӎ@$zSKE<:jufnYa?`#6YT-Hlȉ'xw7 ?.RvIZF˕^Zi !){xaa'ΆFWl&4EZ]vjzsaW`%ZhZoNw{vIQZCoV윚89)l+ΒDYnPܼ^TZ_臭ը">7۝B~@PQS n23/ĢqR*#f)[&rnep4RVؼ0؜9T6wwrU!pG]S p9UCay @E0jrfJ Ts̷w"Blȹv:Ę[ԍW/U'S?0/5 o:/}-kZ߼2k:)Z5[%Ӧv)7F?`![0Mm-o3Fw7r:4MTNB5[Yfns΅ت@tf{-/6ۚ&qq!ukp'ގtSejt|jE7 f[z<5m~n=R ':pv9ߎf Im;JvѦz.NZ]OƷNuE4*}ÔC9pQ53qpЯ9QK/A_ ::!"kGkP""U;Õ8<4r m[C$-Jb'ٻo|8:xZgױZs 16/as:q CgP%?Zt%5-ˏw[.OZf4UL23ψJ_# 6+"@FK|V]tW'|ϱڼStuM?m Fd<Akݥ(/#ccP)ǿ(Ib~~{'F',ϧ·}ZSV)P. x|宽XZ4{ƷL=uY>].rED6$Ljޙ[.8mtQyzl;8w 0}Aqҹ}_?zÇW,&ͶGpQjB1WYwԖr "Tn3c_AHlL{`xܶE<˥B[^׵h];38bs K+:oM3L6 r]|xbd;=NX?O-\ZRQTDA>+- x:"Hy7h6'61ֹ!Vv΃=W^D }oQ+ sjg\,,7 6dfVLx5i_[},ũ͞#X P3T/W/TGO%6rS~ޙC;srJZm P0 B3kpX$‹""D@$ŠԢ?Ԗ9°- ɡμơ;M^&X'|O$J2S*??936_m.^"qaG=¶7-; Ո55đdAT>$."q"F&I 5Z⅕[IO(5nbč O N|C{+X X}5Sۮbj t=I*6]#zš Eq I҈roRjFeO$>f>fytSaU'*^!ԁvGZr9?Okn.DL mXtU"[OF1"FUtD_P38p uszc/78QW?ryimlXE AWf&<|!qӟZSk58,HA ͸BVH4@5{?d ¾l؏ `y{^x_?FBV4D̐Wb?2p|iIE.18Z[>9EN=Y&r `ZմeR\f J~ j󲡳Ya+Iu*eHy ͅ+t4QQƉ51:~C@]Bd2MWqVNZIU1X\]0/3*xƈ ;p6yK`4Ws}il-_N(IUDԨEBWˠd[wG[VЊ.3s#(oy^WGn)[8Irm=S~H`x W*[ֵK *ebm ^j-YT:.A0PpQI_W4:;9 ۊ8SnPx-_2u$ݢ(֩&WH,AvdjSN@.'ơv}*g>&ƇE X߄׀GT5hؕM@%ueTܵg|lTT-uBݮHgacZn.L}`߮6@b5$r FcRM*X B-* d67YAg HMt=6Adtwihi5*`چ'2|<W-tZMI-x]ԥ!݃Gu9M[4+ Woy֛>Zľƺvsj k*\&x;wn@xׂbY`[`iSUmV~ D֌4 W(y ]0̍ hz6&hs;_;˖tLvH$ 2uWp߾MՎ*wJzDKh-@[Cؔ"I\@\@nWV 00S>hqGv$u:~zH=VFv$'\m[zMh $]m]Dqd^{U#x=Ȧvv_Y䧜yM@ET hk\kK컲:7 @YKP7y+Z^xpk^Ҟ;ێ,]"QzsP+U1a˜˘sSQAӫjVj"d%=Bp"818gۭeUO}=徂凲ɦ▏]loLxdsl~GFBg W6`7ຏdji/8][?uxoՃ&;{݋^y*Įy?鯾 CJQ[ .һ8u?o+x;Nw\scTzE.;=K'5xpVHe7\}$ꅢܽ~.zR_f}![SVd*pmP#\D$WѾoj~_$_Jw^pc:J$A'Z;rd7g+:)=}k^h!4R00LWRdžRǣ_byPx+=BHY,&נ{卮عauByS>+\QZqeuUN*BUF^>Vl [?rsl+wn»35i%,L P^JɯA!pP߃c`H#, ֌S]r=^V'7RE%\?2Jl[WvX  IxJf։Gy< / GR߻5˷8Ah2@* 5&:FP^_Zۥ[G~.ֹ1x8>.PڄMGR#d!#BY@ 3$Ai վ"E34Y  +W5RiDCP!de_N0(~ n7c~!z~Cϯ:!ػΎkWAxdKH#U }Jj;nLoLZǛݿG\=o+>L:B(aAf^ ]b8^zJ&l'< pC>2|0W{(aq[^"PN*/ F,Ԑʲҏbƻ>@^/=-?< V)ϕvѲu 5pH,"TlÙS=H#Ǝ!%b #C|cMfpݳįxZ$\WP|AеfW߆MNcmݞI/E \:\16A6n|p? xt_8qDi4i¡[?2po}?xNѩ<ӥ;qtбһ,^*b!k#9OH%1.9c8g3]18 _zI1&Nng()U\ֽjKsoK]>%%MOC!崦>:yPJgSDYuI":BzP9գ/n?ag ]yz2 ǿf)Qj)V;V{/XxyPBe%^U2Ems r{S 3@"d:@.ź4q6¹c" q.#ds4 Iqky4nM;Xy@q91m~~g]?%3 k>qRX+ܤMj*RXƙ6`2WT2Rv 693gB8ٷ ΅8frDԝ( DS;LDi\{.n?[ëI̡G}4 ݛS; `[ >,trZչJ*DֶqsnY`Xd`(8 e3N&k# q GnׇE{i>h`dG֚[OS۶A&ˎoQq?A;\ڻB2rh(l*'9Y}r^vgXam`.>gp<슜P8b!!uҹJDRcWwN s@4x5A|Ws=%\ިr_&XL[\ K[9 _gb?oΤBl+S%&]?C!ʞmٲ:nclgìU.#0%nѪNAX&qNj@PA?xgZL'}Rr_,+\P]گ ("hbm-sK3!3U)rPե ,8.<c;[g\#`Cp!jdS|>ΕI6Ik, qYŖS7/?{|y$7J=B+;:l.w tP64L  RޙϲdUhZqN})udL2uqKqQ1iDX?l[cD栔wgvx"zI)%thSAjWyit4:PA>thc j$q@+NQ?כ'/Sׁnn#9jW(ҷ~-3,v+[yp5B~Ru0>ۄ$ߊΝ ߃x&~ތ86qٿ~秜Z&t/id=d8Ƅ46w Bzh gʨ^+߸DGiAXalI_ Th݅34nDvWW(k@_s″)ӏ sAg^#Q]Hݑd!5R(UD2JW +Hˆ=1l-0mJ4Ogz\,BiC8n&mm߇u!T )5R(~f~9/\$- B5^h5'NtDMURH]EnpFMڍȗs/\ PzL p  C=<7>V5v! ((@h݁]Dq=lrpƌE^yHP4x]LE&1RQ^Gj<@"@*]u"pB \=bG8֊IA(T+H]'i'oLsX9I4NbS(=GƇDi.*fu⬤]I(89̑A94Cn7F`Rw3rI˵G,(]Źwab`8:a{y1μnzU-? tPnڹ8d DKhxYh+sY$[ n=O?djbg!Yϝ-<7S3kyӨ˞&}~/?|U.?6ӎqAM)nf)lf2WE*DbF_,0;TĿ>kWo8uоtts!McvN0.^QZsMnx7Vj~Dݥsijvc=≠&OL ~F/#%QIsy{3+@`Er%)e!" i-dL󏅖U1`Qcp_D㠝w`nYtN@HEIGGq{# y+d?/# %ۺIliWs?h#z;8G~?Z/>.\@]q%VD0CB;AYo2r a8|u("8zh%J<@)%8u u,ىwul|wDjˮ3BkPk6j >P30̑};5mDơ1:Zc'3gN d3P @.\@ut=GhdzjxL:jGP I5$›L܉**OEȾc'R>'Q}}hÈF( iC,;~qUU"8F&vK3wW/1xcbd=Khd%¨MB:Lފ2cs^CoasΜF=aۨdl8.} ڽD2E>;{K3Oz}}A;f4ºod`ǚxn'ׄOupu[a]@(:t*|è.M@U2BcׇU]Mގ۶kyw܎(l!{n|?zmk;t=6[mm4#{ c/V~ίFIl~0aF-o MO!jנmCɓ _GwDch+eB k}S||'NP6;;w"6lDl{D>6N.Bl k3$R ¦iy=TU31ۻ={?E v}!zúFtu -m)(s0Ues4p6ҐҀ @Q}};me>JR~_L{!J~6p=v<YeMa8!H<+1UŀLLL`xT(W֨ `rl]0;, v Fk+B-v32vH$LLLP,k +>Kdh!oZɤ,h4RԦfL!H.;@(/{۱I$LNfp]w+zB /7gS0snJ0|Vr@YfZ+O{>l4Wr1DX$NP^ LFBd( md2IsLf@5F2"VQA08@.P&( uX! &RX/01>N2qiyj_`2h4 4|@+KL5I.:ũG ^0=~+74`>iHM B!ҊH8i\bK?M3K>F9<](BT]kt}$[[۵p*.{Di#dxy^Kŋfr*E$IJl4x3zz } <4p~W/''6ፏf7HX;()V(dw7Ǟ'Zpu0= f| *b!\v'W5pY:(|k=k7`8^9Rclƍ,w9qwF)'Oyea6}34z~}8q׿Efʇn:|=B$к~\Bz/4vsY.|s )RF2fQ]]`Bغ<@](D.xBl} fS3UqF=Kp t²Ls]5Ml}*y<~d e5u 6"8,>Jtm]t-NWw'uQLN::0 (>8\۶'1D^xN*@GVWtnjn\TZ"#_ݝ .bk?Ʃ?g$~8q A!CRYQIc:L/ŝ'p|ggIX }TpN>$|wMjAiApnj7!*ӗܸYY F111lT@L-BbX!̺: ÀlH`_g oh'~#ԂaY+ LoI^DЁ2OaحǮ pOsr-8 -UBݴϼD"P 6(w9![WT_e_DF+cEAWZB(يvr/Nx^ϺݷzHW[@(T\mћ%4;{*$kh zl˟$3v deOf'X՛ 2 ,ۄcq>E;#::٢C]p=Tcb+4L Y ЪT g2cp [GZB=(7oٟFFޅnDP@j<`8;Ki@1?_W^ g(>xJ*++I&D\%066#4!E&(I>-ƌޅ%dS(`BذV ~Tw=ћ&*QgdxQŌS@h&o:Kb㏉?~HA/dyqرȪZZZrA047wR6.u`p;q's9r,BX蹘mۄ0HH$E@஘J) նmfŀ3DT޸skSـ7Dapbbuc5B{fD]odi7mۡEKk ysgh:;^|?y[0<<N{{{ٳo3 fZ JsN%oJ)2G kڵpRJ, K[s9\}Zk- BX,z\.=8887y^lf(0S'^1lmw_MM?44V3X;5CΠBZkߍqQe3 IENDB`Eqonomize-1.5.3/data/standard/64/mail-attachment.png000066400000000000000000000137211416454732000222200ustar00rootroot00000000000000PNG  IHDR@@iqgAMA a cHRMz&u0`:pQ<bKGDC pHYs B(xtIME 'PIDATx{k\u}yߺ< 2 Hpl'cGf&S8Ė' S33ԌmM(A "z\Ow{! a_dfXUsZZgxOޓ=XJ _-رMn0 AAk 6 .E_+@poC\HX`zEnڰo $˲϶خu~L18 )T@.a5AxLJWZK/9 ;+c詵mp]@K`Þ{u]뭖e]D#ey!pzZ:ٗoe+k'֩yDQ~LRp_|-6n[f~u>XJ)&I&aTeNxem{LZ!vHkkLNVkԎ3#2kU1xvvEN"8 wyb $duk'֖~݆UBnEs.d<_KoTC"iRl\>624|AEӉ^{O{^l<zw;v1#1 ]e_ՃC~rcp^d|yA8hn'jEY'V .OjAz<׍;=corz}R SS4MQٳOJxYU( :$H\'lRNXn,ؐ-py֪u,7_0&c1Fƍ~ ,%Ǖ?00q\I g)TJ][VOslJD/;ȝ%o[fNpp"K?j``]ЏS2I:ϲ쳂 D0 s9{7,k[ ,syV|M_D*>>66^X\\8[cA;4/38رka|}ݳ]ks{?"Dǽl.Z*)ȲL'I2+MJA[`O@ ᑡ(E4Mvy1jcK ,uc}餭ix9T\S KgڶN$yZ8"61ֻW!zzq& Ц }Ͽ6~t;4/3w '+=RU{u=R8p|(`b bPJqD奦H JyI$: Kvk뵺uÝn<7qxwX\ZLvn7z(׽+@*}GJJB(^{DⱯPf5HH H%ƅuRy̶,,̥qܽSJ}!jGiۓf703\|JdEpEmp3 6Ÿ~l 3lh]d̀e9l2d---&~Y ,JZ1"|ȳox:K)_jxz Z%(tpDѩj"`$-qmҶ,|B)%zl5vE~) ZuryB&iv;//txuS Hб6C B2}zP#yHyaͥ~E<*'K~VIݎ^3! 80qı8PHG+@sju n;犏aI)eAk%VQk=ሒJ͢m$I;VO2LalA&Ǎ7w$!wyuoBV٘8b A@GjζRv$Ivyeӯ--9?m>HJ1ID (emuqs6n~exRg4M@L^2i/<z,xӎ4yDRipNQ+z ӖR\ťRJdg-!" C /-xU#I h=NV0͒4j7_̲ΏWR?XQ?`횵, Z63?E׳,@}dYG(?ݘoVg`'ube-aJ!h,_e}_,p󡵎|}ۍ<CõJ;J?74}zgZdl5R8uF' ۶)`C;ӭ0P6!? jVZ׋~̳ >Xjav᛼ ]uaۍ;hGsn {qp) OcOg+<Ƶ֥ RXcFBRʊ "qlf.5JYZk՚6fc.jOSOv펓&+~eY?݇o}S?iR3J^{J8icBض~˕P)ez=h,uq?v7ٷ0tt? [9N?!{uYzfX \j]3fi&'|'~ua~!{MA|}CqVoڵkJ? n=0,<RVI+IyIt:F>l^ܻwg6c}7;n&]gAyWゖo։H03]tK\=_J9! VƘ(FQ+z#޽H +Ma+>pbhx RQZs$IiwFv:8ޜ'Jq<| {'򶕙|8yWRN9/ ;DvOw>_{'{GxioVtEXtAuthorAndreas Nilsson+XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/tEXtCreation Time2005-11-044a%tEXtdate:create2016-05-15T11:32:22+02:00iΰ%tEXtdate:modify2016-05-15T11:32:22+02:00v tEXtSoftwarewww.inkscape.org<tEXtSourcehttp://tango-project.org tEXtTitleMail Attachment{HuIENDB`Eqonomize-1.5.3/data/standard/64/preferences-desktop-font.png000066400000000000000000000055471416454732000240730ustar00rootroot00000000000000PNG  IHDR@@`UgAMA a cHRMz&u0`:pQ<bKGD#2 pHYs B(xtIME  ' eIDATh[l\G3眽{N|c;i6iڦI)RD\C@< RU/ -U UjӨ!iر]DZ^_9g={vک,̃g}3"?^@UD&'y "I -_LZzj\^V-*fpǬH'Qبcu-ϾfQxfmft] @܅'GrC.%f'vVL$5&DTTX3sS{VϾƩ t:~8LV @E1WFG*Lp!Mզ  I);+\BsiO=k]:2F"Aaa 3C 8 V(^S"uw <MQvӾJ03VfyߺIW6 8EP88MJG}AEY7uƹ|-+E(Ѯ=ڷ7'bB/ɫ'ߜá@<6n%0%",i!Fgŧ6~o0~ LbP5+ĤTҩz<9cŘR$  Rͻn޳gso|vFGl6& tĀ1{\*N1EX(1İ ̘l'Inc'&wƉ 2%. -g]rX9Lv=o^nnmo]:UUv(w*d3K1bH15Mt6'd4x0Ӧ1l(]1n7LtPY52 c.bbjĤ&Y(MdRfÂק`6WZYt[뾷o׹_뺵5[[Kץӭ _x #H&6"MhhBr=kd6uS7Ms76Vbo6u080a 2281DD`h_gHyGWG>ˇǕR1)86fLRu*8f&",zk^.yjkgC _BR{)"),,cd T|(;E @S  ֌86M3nES63;2f0b[lGfDM <9_Ho/~!bٖy+zbyw+B!@Lq{' T~Ylomx)˒,(0ٜ#gg8*P^ΙPr-`XE15 #f9{zdsՖw1`Uh_ _zq =yܫ^BYyiCS$;=3 9H }.19u.g šfLc1F4yJkb[1b"L *\,TUH {Dā΁YtQ^(错1 -&>}i$$FHT,(y&q KlTb +C f%˦2,淼 ;O>[a^P1$6M=dI1zN4;a{[lm&rn٧p`rԡfRN810Mbh Y?٠oRN( fM=Lk&jb).ﲚ[p d.oxNUQTJQ%nm! gȥ! MmP)لxl<%ԓLgB&OUؤ(M9''9|(,+ً$a^vgޜ< w;8գ NI@ 3 LI ,MS7ʂeEoJH8/ eRt~3R7Ml6#DxKF%6kdg~zgJ` Te7tif InnrXQ8x8-px7D"YH)>ĜPvݾGI$&֤Ԑ]B7f&ieɰuq`eQpR唿Z'kQuAN`S_ߊf6"iD)%H)ZIU(J֡QTEE򅣙y;7REss-ݵ!h5ñϢʇg H&["[j5Ų( 4us/;/Yլ,?Z1W9u9UqfY0gy6`"q/-}X*s `~2wl Zm{}0w.yYz_mdwq Z38Bt鷰 'xt%hf?<ˣN);U(J)k@twֺT݊zPud˨W@jh4a8C"FWZ!s x 4ٴ&4!M'Cd{f.=_(_~)}}}/9L>FOwwpG"Ovo5-ؓP)zьx4no NƷ o D=Zp8ާr`f_ɍ3*ɪV1\^7[dSn_I|X2ϲP#؋}awXG(Zw\mtz~)7oBLT1A/\]SGa: =Ļ>(,o }ĺʢ HhkKݖGuyrU (ˢK[ew}zR$꼠NYciS,tҘe ǘ:qZ~hpx6gL*vqƏn٤zÕ}e_ .e7m_olrM]u%K}U9S*+shӳ= 91%6|yZwFEE{.?QeFX-zJ#\#]ݑ~gS֊9OWt\AחS/]uZ"r2ҽ8 ?|BYq!os:S׻DsjL~`Gj"qW > яB1gگ"2UJi,LAHr^$|3pkL@t fW 0֐6_+@nVNwtEXtAuthorJakub Steiner/XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/%tEXtdate:create2016-05-15T11:30:11+02:00R%tEXtdate:modify2016-05-15T11:30:11+02:00OtEXtSoftwarewww.inkscape.org<!tEXtSourcehttp://jimmac.musichall.czif^tEXtTitleLocale Preferences⑰uIENDB`Eqonomize-1.5.3/data/standard/64/system-run.png000066400000000000000000000172611416454732000213010ustar00rootroot00000000000000PNG  IHDR@@iqbKGD pHYs B(xtIME  0)X>IDATxzyp}^sf0A  EQxH,ɒȉkd+^U9jSU&ěq'Qb:E}18fs_w -+zLw{4v8|&c>,FGGA~A߿]]]f^O< Bs-b-x?E|Ѐ͈4v :^ t41/?0a.Lqd;2s}u$Y.Un\|rT۩kWf .41"XOtvE ҧu6~7[?b(O) nLN<fLd$[_y=rP޶K~O&Iqx%th?ZN%I=<޾$⡣G8?H4L>wv$#aB!@isp8wcn<P5eq% I"ShjSNѭ[\EQ`Z: @Ъ =DjkL:5FIۿ?.\p!;VJpWخ]իD۶n=\(K1AUUK-ܺu8] eG uiMuy==t*~I>o[_O/Vb%"V+(֪8m6+ʑ8s]>:~3==ǗR+#qf-i|>`Sn/NAgG'<<& S xr " k>'R-r\;wGKGCaw][tԛV<~zz{Q.rq( 14u l< oG{{<4F[[  *NL|-U?o̧*K"BzMmSO?vj'²,H J)(HR B(׋"jz $In #=@~ǭ;׷uWe:wm S37yx<Cu-h 2PJQW0DQ4*dYƙg/d6IƢO><>GJQש, t GRASoȲ/˶p4ҙ5PJ#DDRvlx` /]X\*9-KGɒwl>4e۲a6(Š55%PBA)Q@@p%re%^Hy𰯳# DZ: :9sqd %ME"0:CYx*7n@%8Jزc*-mCG46I-`#<DžjaO~I( PV@kZ(bK?j`(x sP(WMkEP@:3gC~(|cޘ3rui\ې*kN0 cwVAUU!4u `Y&*(!$Kp]R0 Pkj9s4LSH$$Enm-wMS Hèڷwg6'gϟz5w @Mp8z^]nHg =ގ\8 \K9uIS^ ]1=59w^m6%DPFp lQM{(xO|#ɇE,۲_~ٹ^z&)#IG8/_h,H(CQB"x^W''OVCO} ٩+6|z˧& )0M0_,O:-.c;ۓv*Hx^ǭz`:0t n ͢T*ñpE($be`|`$IcPz{.q^;CmΞ(rĄ~x_o}榤, dRpէÇz:AxsRDԆFlFǖ-Vk7&B*YaY&(?CpӲih:$Q;]j^umyV]yܝ4t\w4-ϐDimfgfk¥+XVwAXSUշsd8c'd2p4lبM>~ sXY]FQ8y)>D#mh;F>gQ:(G{^xeZ*V['… ?xpcW ř7_O C@2@\qXMgٹʥp`M'I'sӟiXƍI65=M+P5ö-0[ i0,>ŏX[(㩥@{` KW>K>mìI͉3oGd0REp8MaVAVR/cҙiN2덆Аr!(>+KX\Z!Vd10´aJa&**๯`n~-Qts{y ᮬ]i %I:488бs,$XrW'IVhkxG8c@&U*۷Csp=8~3s8ڛks _Vk'EQCĥd$|G@0C7~Uy5lۆ(hFq\R A Ň+Wj6/؎۳wnCahM W|PU}+j'L:AD1t@\ ?$DqzCk7<33gtut  ɖ@}%(W-C%eKL$̯?kl](m B(p8Or1Qn]$FH;vH߉NIċ~y~Bq}ŋ :  *KGo9N۶mcG+vl@R>h6iF[=+gbpd8[z0tGj?B4ĢqC[90mObm1 QEQ~l-{д S׉~hM G.c8x2=='pKBCSi>/y,ǭoqacGH0DR[o혚:=ooPek٢ٙ,T*ôLe6DA ؑCRV/_(rm!9l܎{t&{3UeDBQX , o _v8ʫH$ޡ￟ŰirA"J2'#AQ$ k0, VρTu4 bm1hMٖ}2-tlr"=yV8aee HZ.^5ueW}[y 3{v vCTH4"IT^f#W+[ b<ʭj<C7a J2[]IRt:I-Lޜ,b10٘m={ 0 þNw={ݨ֪E$C%6=3#՚ x3s?LJ$I`, CIZ Wӥ||[{bжHTeZ9}toWOQ~+׮s[h[Dۢ0- a6JjY 6LVa6&sJoeO%+mM]ֺB0lB$Qx }rx;L15=ٹ9TeW{7@s wyo*us,ˢz hzbmt.߻(fVd8.8Gv-CWI[|4D.zh+lT]>yLv ssj-k-|f3m Gw+/<myPBezd"aPJijj [*MiW%xX*}l5=7=m:-H/^GW[.S77Imfߝ l<8 ݳ{=vx,EPBQ*>Ap80 ZSG>WKW/-,}0  !/RggB~Ve`QlܨV<ϳ7^1ijCFPm"Ļ'HZE2.;ch.1D 0=;U=Ѧ˲, UERG:Ao.ϝoٰrkeZkʆmNm㜅>sf)Z-PkZHoDž5+<1qnfSff2 AX--/YjmY @蹮ۊ#EZȷ󏀻ӱDž)MlӺV5\n _(o2oN^N=_)o2Z,"=ݠ#Mkbrjƫj߱ C}o+}ݚ tsMǽ{>`u?N i4j#8NT*7ճM\ײMSdy8L$9UKHggZ酭;Lsj?I ssStM7hQ2sf-ʴcYfKk<DZWF1h 奥mY)uRu=u`o!üAG`ܰKO+~ D=+1\&Bdwc8ϷJ-)o6x s=0\ulǶ Ƕ;7܋?l6k@~Br[(]eMn͎G:\4,c8`?%Ae(IENDB`Eqonomize-1.5.3/data/standard/64/tools-report-bug.png000066400000000000000000000114221416454732000223700ustar00rootroot00000000000000PNG  IHDR@@iqsBIT|d pHYsu85tEXtSoftwarewww.inkscape.org<IDATx[ p]yݷ?M6"; 1@)M`4 @ȸB)&&e7[2@c[Ȗ,K%=}N޼LZE 93{w9߿s4qyn:>ͅ4M3Y!5_aM Bgy X ^c;»Ll%l Xr4 øM`PeyGH.r|>oUVV$7'D<C4;"j9(@pMt@K:j&#|g~eD:Ɓ^J_8sp3 ^ ~&Jw>m,1 &uuu#ӦM;u9@ ?kuuN`#gH.j0Ar PO>}aH+_ֶB!|igժwl>NR&揣؎j%(zVZuݺuncL~;*c8DQ_Lz7<4\gzu~4= ne700@!gwWˬ&D,v2:po AbSMFB۶HXEv6oi-ƆNs҅J3ki }>ڵ3iQEVmu}5l&jcE8ږH$"^r"Qt ןM-'|߾$T?7PODc}i8SN=Ov&O,&$x-sW8 CKqhE"Nr6ќG4u+W|hѢE ڌj{{{HT_uKGfA0>O(\Z 0c;A t /zx1@aBN%2S3f_fXb`eLv#-:8ps\ Y\~E[7Vnܲ58od'?(n5`cssmCCCWmZgx |Xx1VXHQW^ywMT<Ea!>=%=N,0N=y "g͚U$ARƀ vXi,{Рीl۶ gtttdZgTH9lIc&1R۱cXϗb@8t,o,L5AU섈J V;#ZLBž={ M +J$E0=_xݝ\VU&@TZ.[dJں9ϱ^-zk8iEC ᨆCwPIjB66<_bn2)XH@ Z)R,) .b@*$@3.<Ђl!o*| OE*Ua$trN"u.ఱ}$EٱF(=0P"`Y4*¢0s' #/]*͏ ! Q"?ŭiC򝕾X-RߩSQ9wDYm)06>\\s41i _N$J EߝL"3gT;( KY@] AC +rQTV[iUr ho/Bbl(TwVZF c瓬.V "lESS 8>ApQjnim|Co`e2 w1:۳4jԕIS=X"e`%8Mym!i6 :\&٨h{ CVôTj?|- j~} }aHN/;yb4" `I|x>?$/,"4k\Q1ߎqҶY 3-D7ju#=2E45~KY ɨ1RH{%5n (h)p|<[* KW,# s|>F*w$niyj))QeADuk !FcIȩ*H r.뎗dr(iFYI{,Yso0˙߁,Z$.b^I R,@ "δ—p]%UW#{S$=\q<iuS+iu2Ah]ix)Rd,>Mt'r$k_%uiR8vOSLr4EQ$"u:~ Usz@Y[0{Ǵw%zDc 'y"xQ]Tsy^8FS F"e0 `k$Jz"|?#1` L1kz僄 \+;&2q e=Ic%`L7QI=\ _] 4_H>a_UO>YQ bhЇ(%-" Rȫ{:H콦$hsd5j-eM@z}}1_(TCYQ f梒΀be"2$QIj:V0(V9L%Wd*۹HDKkHDIQ1$וL`"Lwu]zi$ Ae6[d~8c_ *BpZfM+ uI, Y@>;/8ixY1Vٽ4UKwϷ+ffPq) u"$Q~R:o)")C?'{\Ӡm|JIpEnM GRsvj.e)T iF"^DiKv=4Pzl<P <\)^LPs=*܌ܕ' $Y*Uylghs<}O#}zT?]w?;3cڨW9e2G6AFq,hiiY7˲ z4tѰ0̟/mbp[ϭ;l?H atNNP BA݀󓼽 ka |-8; _/'/@B 8ahaEZHbeEBQK9[[[H˘}˵A@wn](ODd೸I~0Zc3;NㅝkQ/Χ8"]ΡOTDI7}wڵIƀeY/,CF#|mj i]>vMJ'p~|ZKtjV Oh=R(ʷǎdln!ACNdeiO|OIENDB`Eqonomize-1.5.3/data/standard/64/view-calendar-day.png000066400000000000000000000125671416454732000224530ustar00rootroot00000000000000PNG  IHDR@@iqgAMA a cHRMz&u0`:pQ<bKGDC pHYs B(xtIME ,ģIDATx[{\Wy}׾'f$Nbq *%*!⟶}PB(iHrm Ѡ )(acؘm݆~qnő#G裏?W_}y05lff}W+p ḲƳl)?k|K_B5xF; 5_NJ w_OahRj(7yywm|Pom3JDR"!L- 'Ir8:A$&H7| armuݸ1`nAOPR ۱BHzlZsg2cغuL&MIr|=/j5컆8PJDfxxDx| _xד!JŢZ.ٓ&LީI<#oʲf0-VsZ*P( ,--lwRykk<υyu]~}8t RiO% =)%ǹ"6emA)9WJŲyߙ9%+Vd췆hFX,0A @ѿNI?lkZkw[候3JQ˲\[Y^^VBq !w n`0eA{ƶը:-6l[Zc_S7!y?|33|;wƘ49^a‚A>I$bbg{n܋⡯>?V˕f07=?FUO-[Ǭ$I( '뵘tb쿺3[\k%ޞhoԌ8mccɸe!۱OyCQ5^Q?|ɝ#I_||L=*\-X'ewˡt8GH,<%-: I~OǥTLDVfk  !@DHBXz-FCFO c5l$7 CS5c03^WV H@_ ۶ ]{ssgcW_C\Bd2H!h# 6rr Re4::v:Զ #F(Jxa΃(@J8H'^yi_\w{3P@v@9qj +\ׇc;R"XAD$ :J<8FVa}@h!DXY) 4ʲ,800R6 ,Z QTG\1mò,!! @KǦ@|]5y@ZI%ZZdYil߾A)022w}C:Af뺸188 pUWoV|wj=;y:`L3{8ADTB5wucccpgS̰, ;v@*BEmtY) [y`ܼ(L[.0y11,}!@DHd2Z7)hIt7֯rmc֭$IcҩtxqM3v42!l5ZQajyffj%̟JbttSs1B@JbsP($ \vlq{ki·cf~T*0D_4ѣ( 0@1 joԺibe FZX @ 3ڳacEO+3gP($ RF^3'O! r1qrʒ} XP%,֪/{B`_xϿ"* Rpe#J 0D% z CX]]ũӧq xg0<4;︣ii@3,ڬ ض "xɳ,&Vu|1::(̳bzzu]:xpڱ!/|qŹ9?֜~ڨnF&0}4}WC8%`?2` o,Lc̞>r'CC~#ٜm٘juTk /uV)%c0FKm<{?hO8㸼ttRzmzK]yhmm^D6``æg+ 'A0lFIn3 4N<ǵ]UOo!Ķm!@3hVBB ){rlʳ9r0g0{ ;5=wwʲ,):'O6wR8@0ܿR{gfQO/(kN\{5oFh܀xD]:В]˲q~PթX*ox:˫`TVޱSzD^?.W6z!=rn%ZqV "@,K!LӮm$!.>sؿnj-12?]{j~9(Q kϕK.|_ c"PJbfvl~U j6N eIH4E[nhNDPخL:ے:Íͷ:Tֽv}'3 T= TS^?EUURQg.Rn2m6X]4=%^wh6jDkDB$jژJAm?M|zc)Ƙ̼ȌZSuKR)?l{|f79_^YlѦ" #̼jjy9I @}{?3$񺜅&&/̚7GNDUfI %gKp$Mf"&.5̞Bֽglށ{H9_:ZH9\ƅlF:]S`(Z+.jr309To^nFH68_?rn< ^Gq߆aNnlfM0!nQ0kb#}ٜs5;j)S'f Qi@:@08&,*,>?ͫ.mqsYHj݌V<(`Z`v'gR@` -~őr2A:p.uƀC bH)u$62VL&vbnB&զiYD%A;Tݻyd s`b*n"CC׳L޷60J-I޴{7:RȎ]sd^s^Q:eQ$92741?vvpnqt?(_7Ar$}v{vm2Ycޗ_3Ij370woa-eA0}*~ ].OܑzJA1fRYżGueB= !ewnܺ}|Z?>S!GH%@.ky{ [FVI4c.B3oW\ k=c*_=1&y/m$sC##%xCG<+cX 9*^m(3ZΑk[3' Bh($ؖXpm $c266}g}~ ;|b}J'<2vsx(2-l^y\8D`0Paji&XF6l 6i$A-8,z(3,dPȻJ$@ Q50ĠiF \KP7]i@!Ñ5T[2#8g8Y-]-B]V@R49⩹&Z!6Іi5',02X[B` es@fT̹(\d2?"y,)Ӽ>Q-c!f|xi,`Y01e3:9FiAJuy@p1}IضYVlDjnkHLƅ%mBXFtK*$7ēL!T=Wr3BB=0CR9N("EqR 2'1^Gq):oO1CF28){ǧj?7S{ ]s[%?PJc$ =Vfk@H1֤1dր.06"96NM.a9H"EZAt$,֓I:t2Qؖ-ã05>q~m v][r+A!K~"l;1 EB)k y['7{ ~ , ۼ--'` Bʘ b}AJh 5j. @ A6-q֣R!{@#HcB 4ql+j>?R>6"^v󙱡 vlU /@IaClZk[-!HA!E)k=qsg?MaD/2UROso1>8i$gj!ڑE((y}kYa dh)u^-:-HB @DBYBIri8)[l;as7&IC"Z_&!aT !l n2guta@ +رmwꊂDEKZNA7@7.XƉj Y"JBbC AJ1ζAy'#C"U } |wzjg[XN\V?5ʵ0q顀x*>+Ci#.lm9RftpqO5"e ɲ[ߐd 6hkI(ØPKiȹ S|?8nc-9d*bΞo33GmÂpI){p)@pTc+^c4Fbec XB$xsZÞ%n5ůlL]zq16X1S*vѶ큽Ff8Nm;C CDPRB k6G7@'%THtqpR8qfBW$DԎ Xů|dCɥ Hd1$^A|9(  0Z,"_$!#A`%/6yԣIG 5~sYH͜,9 FcR\2V!`%h\q]:ZŌgfjmiew} nN:6øɘ6f!" *)xl`2Y1F^̗Yuf.&FjSbK @._qb'Js1y@Uf3D0UKPws B&D†LZ\)K'žD#@^-]uh_P'joA"ݿ_`9 3??28p 0$ ;-!LCD2P#7,e=I ! WSO.uX'(=qQ7,;rۓ׳amO~?}E|܂YOQ!"Qmc7Zt].u >%E2І _Dܗ2e j~sۮ[Щ3I=0=b񷣿ġ~SGXGe1Η?|ֵsV)X,I"V=9>[y9Jb 9X.  }*j'^jfFb]ۆsR2/wnȍ_z)aG# 0Tou7wsoj,ɸrPHs~񥉹ܡ~l2qE L j!Th@ CC D SڑBkR _uYwo Fi˗N$Iڍv~9{8*l!|}|.{P}ƲRVM6~L]n Zq9L&!cQqyo5ObNwzg}LH+Cթ򤋛#122@CͰ2xqZJ@U (pR[nv֭ĶUF'3gjtK 캞m~X<ω^ @γ F1ciVf%Wb2PKl7UANMGGUa $ ! kd=$D,%Y#ò-I0l4T 7W*A+gjϟtzϼįq{h[%R8 f;%J[g!q`KJȠw cu_I}FX̱'&_||"n/_+0xlycW[ Nc/<:{;g Og_Z섍VЎ&@֒B:_N`j)_{5 #mt6Tcc38/ r|ztW  stտ}oOŭ1d{/&TIF,.5R%kK!;g' 4M y;9ux*QH7kuޘ O.Cp"X>b|u:CZ٘0w '5.b6,|~='#u~~Fˌ泞rv.gs,F8=^j \%=k9©cEFϹ7VV/n4N,Kg_pa:[,ǫ!I "`Ѭfe 6B)oˇDԘ9|CKkV Fnd#>=/F&զjs +S lmSadV8Yg۶xk9CBHLh$IґQIuǢ 1Xk6tEXtAuthorJakub Steiner/XtEXtCopyrightCC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/%tEXtdate:create2016-05-15T11:29:15+02:00%tEXtdate:modify2016-05-15T11:29:15+02:00jkVtEXtSoftwarewww.inkscape.org<!tEXtSourcehttp://jimmac.musichall.czif^tEXtTitleView RefreshbIENDB`Eqonomize-1.5.3/data/standard/application-exit.svg000066400000000000000000000404761416454732000222130ustar00rootroot00000000000000 image/svg+xml Eqonomize-1.5.3/data/standard/document-new.svg000066400000000000000000000417761416454732000213520ustar00rootroot00000000000000 image/svg+xml New Document Jakub Steiner http://jimmac.musichall.cz Eqonomize-1.5.3/data/standard/document-open.svg000066400000000000000000000741251416454732000215140ustar00rootroot00000000000000 image/svg+xml Folder Icon Accept 2005-01-31 Jakub Steiner http://jimmac.musichall.cz Active state - when files are being dragged to. Novell, Inc. Eqonomize-1.5.3/data/standard/document-print-preview.svg000066400000000000000000001020251416454732000233550ustar00rootroot00000000000000 image/svg+xml Print Preview Jakub Steiner http://jimmac.musichall.cz printer local laser bubblejet inkjet print output cups lpd preview Corey Woodworth Eqonomize-1.5.3/data/standard/document-print.svg000066400000000000000000000554451416454732000217130ustar00rootroot00000000000000 image/svg+xml Print Document Jakub Steiner http://jimmac.musichall.cz document lpr print local laser bubblejet inkjet print output cups lpd Eqonomize-1.5.3/data/standard/document-save-as.svg000066400000000000000000000762511416454732000221140ustar00rootroot00000000000000 image/svg+xml Save As Jakub Steiner hdd hard drive save as io store http://jimmac.musichall.cz Eqonomize-1.5.3/data/standard/document-save.svg000066400000000000000000000723061416454732000215100ustar00rootroot00000000000000 image/svg+xml Save Jakub Steiner hdd hard drive save io store http://jimmac.musichall.cz Eqonomize-1.5.3/data/standard/edit-clear.svg000066400000000000000000000460531416454732000207470ustar00rootroot00000000000000 image/svg+xml Edit Clear Andreas Nilsson http://www.tango-project.org clear reset blank edit Jakub Steiner (although minimally ;) Eqonomize-1.5.3/data/standard/edit-copy.svg000066400000000000000000000363531416454732000206350ustar00rootroot00000000000000 image/svg+xml Edit Copy 2005-10-15 Andreas Nilsson edit copy Jakub Steiner Eqonomize-1.5.3/data/standard/edit-delete.svg000066400000000000000000001532161416454732000211230ustar00rootroot00000000000000 image/svg+xml Delete Jakub Steiner edit delete shredder Novell, Inc. Eqonomize-1.5.3/data/standard/edit-find.svg000066400000000000000000001051241416454732000205740ustar00rootroot00000000000000 image/svg+xml Edit Find edit find locate search Steven Garrity Jakub Steiner Eqonomize-1.5.3/data/standard/go-down.svg000066400000000000000000000202141416454732000202770ustar00rootroot00000000000000 image/svg+xml Jakub Steiner http://jimmac.musichall.cz Go Down go lower down arrow pointer > Andreas Nilsson Eqonomize-1.5.3/data/standard/go-jump.svg000066400000000000000000000176621416454732000203200ustar00rootroot00000000000000 image/svg+xml Jakub Steiner http://jimmac.musichall.cz Go Jump go jump seek arrow pointer Eqonomize-1.5.3/data/standard/go-up.svg000066400000000000000000000200321416454732000177520ustar00rootroot00000000000000 image/svg+xml Jakub Steiner http://jimmac.musichall.cz Go Up go higher up arrow pointer > Andreas Nilsson Eqonomize-1.5.3/data/standard/mail-attachment.svg000066400000000000000000000161021416454732000217760ustar00rootroot00000000000000 image/svg+xml Mail Attachment 2005-11-04 Andreas Nilsson http://tango-project.org attachment file Garrett LeSage Eqonomize-1.5.3/data/standard/preferences-desktop-font.svg000066400000000000000000000355721416454732000236560ustar00rootroot00000000000000 image/svg+xml Jakub Steiner http://jimmac.musichall.cz Wi-Fi network Eqonomize-1.5.3/data/standard/preferences-desktop-locale.svg000066400000000000000000000745041416454732000241450ustar00rootroot00000000000000 image/svg+xml Jakub Steiner http://jimmac.musichall.cz Locale Preferences locale preferences Eqonomize-1.5.3/data/standard/view-calendar-day.svg000066400000000000000000001230051416454732000222230ustar00rootroot00000000000000 image/svg+xml Jakub Steiner http://jimmac.musichall.cz Eqonomize-1.5.3/data/standard/view-refresh.svg000066400000000000000000000407441416454732000213450ustar00rootroot00000000000000 image/svg+xml Jakub Steiner http://jimmac.musichall.cz View Refresh reload refresh view Eqonomize-1.5.3/doc.qrc000066400000000000000000000047211416454732000147540ustar00rootroot00000000000000 doc/html/C/accounting.html doc/html/C/accounts.html doc/html/C/commands.html doc/html/C/credits.html doc/html/C/currencies.html doc/html/C/import_export.html doc/html/C/index.html doc/html/C/introduction.html doc/html/C/securities.html doc/html/C/statistics.html doc/html/C/transactions.html doc/html/C/using-eqonomize.html doc/html/C/figures/accounts.png doc/html/C/figures/asksave.png doc/html/C/figures/categoriescomparisonchart.png doc/html/C/figures/categoriescomparisonreport.png doc/html/C/figures/confirmschedule.png doc/html/C/figures/csvcolumns.png doc/html/C/figures/currencyconverter.png doc/html/C/figures/debtpayment.png doc/html/C/figures/editbudget.png doc/html/C/figures/editquotes.png doc/html/C/figures/editsecurity.png doc/html/C/figures/edittransaction2.png doc/html/C/figures/edittransaction.png doc/html/C/figures/eqonomize-accountsview.png doc/html/C/figures/expenses.png doc/html/C/figures/exportqif.png doc/html/C/figures/filter.png doc/html/C/figures/importcsv.png doc/html/C/figures/importeqz.png doc/html/C/figures/incomes.png doc/html/C/figures/inputfield.png doc/html/C/figures/ledger.png doc/html/C/figures/multiplepayments.png doc/html/C/figures/newaccount.png doc/html/C/figures/newcategory.png doc/html/C/figures/overtimechart.png doc/html/C/figures/overtimereport.png doc/html/C/figures/payedwithloan.png doc/html/C/figures/recurrence.png doc/html/C/figures/refund.png doc/html/C/figures/reinvesteddividend.png doc/html/C/figures/schedule.png doc/html/C/figures/securities.png doc/html/C/figures/setbudgetperiod.png doc/html/C/figures/setmaincurrency.png doc/html/C/figures/setquote.png doc/html/C/figures/sharesbought.png doc/html/C/figures/splittransaction.png doc/html/C/figures/transfers.png doc/html/C/figures/unpayedinterest.png Eqonomize-1.5.3/doc/000077500000000000000000000000001416454732000142415ustar00rootroot00000000000000Eqonomize-1.5.3/doc/C/000077500000000000000000000000001416454732000144235ustar00rootroot00000000000000Eqonomize-1.5.3/doc/C/index.docbook000066400000000000000000002054721416454732000171060ustar00rootroot00000000000000 ]> &app; Manual v&manrevision; 2008, 2017 Hanna Knutsson Hanna Knutsson Hanna Knutsson This manual describes version &appversion; of &app;. Feedback To report a bug or make a suggestion regarding the &app; application or this manual create a new issue at . &app; is a personal accounting software, with focus on efficiency and ease of use for the small household economy. &app; provides a complete solution, with bookkeeping by double entry and support for scheduled recurring transactions, security investments, and budgeting. It gives a clear overview of past and present transactions, and development of incomes and expenses, with descriptive tables and charts, as well as an approximation of future account values. Qt Eqonomize Money Finances Bookkeeping Budget Introduction &app; is a tool for keeping track of and monitoring personal finances. This means entering of everyday expenses and incomes – when you buy something, receive salary, pay bills, transfer money between bank accounts, invest in stock, etc. &app; provides tools for making this process as easy and efficient as possible. You can then effortlessly retrieve information and statistics about your financial situation. You will for example be able to easily identify major leaks, and direct saving efforts to the right areas. You can also monitor performance in relation to a budget and check what your choices might mean for your future wealth. The purpose of this manual is to describe how to practically use &app; for those who do not find the graphical user interface self-explanatory, as well as document some less obvious efficiency-enhancing features and explain how &app; interprets the data you provide. When using &app; for the first time you should read . Accounting with &app; The basics principle behind accounting in &app; is the idea of money flowing through transactions between accounts as reservoirs. A transaction represents a gain (you receive money), loss (you buy something), or transformation (you withdraw from or deposit in a bank account) of money. A transaction always means that money is moved from one account to another. An expense (something is bought) can for example mean that you pay with cash from your cash account. The money is then put in an expense account. This account represents the products and services you pay for. It represents the money that you do not have as a result of expenses, and is therefor useful for record keeping. Incomes is usually put in a bank account and withdrawn from an income account. This means that income accounts will have a negative value, but to avoid confusion, the value of income accounts are shown as positive values. Different income and expense accounts are used for categorisation, and are therefor more naturally referred to as categories. Other accounts, which represents the money you actually have and often represents real world bank accounts, are simply referred to as accounts. Getting Started The main window consists of six different views. When &app; is started, the accounts view is shown. To change view click on the corresponding icon in the horizontal list above. Create Accounts The first time you start &app; a predefined set of accounts and categories are already present. These can be considered an example or a starting point for a setup matching your own conditions. You can either begin by modifying the suggested accounts and categories or start from scratch with FileNew (CtrlN). Accounts should be created to match your real world bank accounts plus at least one account for cash. Categories are used to keep incomes and expenses better organised. Each transaction must be connected to an account and a category, or two accounts for transfers between accounts. To create accounts and categories use the Accounts menu or the context menu of accounts view. Accounts and categories can also be added as needed when entering new transactions. A monthly budget can be set for each separate category. Enter Transactions Now it is time to start recording transactions each time money have been deposited or withdrawn from one of you accounts. If you have kept book before, either on paper, or in another program, you can either import a file from another program (see ), enter each transaction manually by hand, or start from scratch (remember to enter the correct opening balance for each account). Transactions can be entered in two ways, either using the new expense/income/transfer dialogs (where you have the option to create a recurring transaction), or from the transaction views. The latter option is usually preferred. The first time you record an expense you should follow these steps: Switch to the expenses view, using the top icons. The input focus is now in the description entry. Type in a description for the expense. You are free to use the description property as you want, but I suggest you keep short and consistent without any inflections, as a final level of categorisation, for optimum efficiency and good statistics. For example, if you buy a delicious red Ingrid Marie apple and have an expense category for fruit, the description will be Apple, and if you want to record additional information put Delicious red Ingrid Marie apple as comment (others might find it more appropriate to use Groceries as category and Fruit as description). Press Enter or Tab and focus will move to the cost entry. Enter what you paid. Note that the value should not be negative (except for refunds) and you do not need to type any currency. Press Enter or Tab. Optionally enter a quantity (if you bought multiple apples). Note that the previously entered value is the total cost and independent of the quantity. This and the payee field can be hidden from the settings menu, if not used. Press Enter or Tab. Select the date when the transaction occurred. To change the date, either write a valid date, select one from the pop-up calendar, or increment/decrement the current value with up/down keys. If you now press Enter, the new expense record will be created, but we do not want do that this time since the current account and category probably are not correct. Select the correct account (where the money for the expense is taken from) and expense category from the drop-down lists on the right. (If you have not yet added the category and/or account, select New expense category or New account from the top list.) Optionally enter a payee (the store where you bought the apple). Optionally enter a comment (memo) for the expense. Click Add or press Enter. Enter adds a transaction if pressed with input focus in the date or comment entry. Otherwise it moves input focus to the next entry. Repeat the process to record another expense. When you enter the next (and all subsequent expenses) expense you can however usually do it more efficiently. Date, account and category will not be reset each time, so often you need at least not change account. More importantly &app; remembers the last expense entered for each unique description. When you enter a description, all values, except date, will be filled in with the properties of the last expense with the same description. Even more so, as you type the description a list will pop up with all previous descriptions with matching opening letters. This means that you often will follow this much shorter process: Type the first letter of a description and select the correct one from the list. Check if the cost is the same this time and press enter. Press enter to move past the quantity field, if enabled. Check the date and press enter. The same process as for recording expenses is repeated for incomes, except that the quantity field is absent. Click the incomes icon on the left and enter an income instead of a cost (still positive, but instead means amount deposited, added, to the account). To record a transfer from one account to another (for example an ATM withdrawal from a bank account to cash) follow the same process as for expenses and incomes. Click the transfer icon on the left. Enter the amount transferred (positive) and select the from account (withdrawn from) and the to account (deposited to). Saving When you have made some changes you need to save your work. Save the file using FileSave (CtrlS) or the corresponding toolbar button. The first time your work is saved &app; will ask for a location and name for the file. &app; will then automatically open that file each time the program is started. If when closing &app; there are some changes that have been made after the last save, you will be asked if the file should be saved before closing. Before the file is saved, a backup copy is made with the name prefixed by ~. Also the current data is continuously (at most once per minute) saved to prevent data loss in case &app; exits unexpectedly. Accounts and Categories Assets & Liabilities &app; does not differentiate between accounts for assets and liabilities, except that they are grouped differently in the account view and that liabilities support some special transactions for convenience. Account Creation and Editing To create an account use Add Account in the context menu, AccountsNew Account, or the corresponding button in the toolbar. You can also create a new account by selecting the top item in the accounts list when editing a transaction. A window will open where you can enter the details of the account. Select the type of account, associated currency, enter a name, and specify the opening balance. The account types debt and credit card are used for liabilities, the rest for assets. The securities type represents special accounts that are the only ones that can be associated with securities and only supports security transactions. The opening balance represents the amount of money present in the account before any recorded transactions. This value should be negative for liabilities. You may optionally also enter a bank (or lender for loan) name and description. You can also create a debt account using Add Loan. Here you will have the option to create the associated loan transaction at the same time. Notice that a positive debt value here represents a negative opening balance. You may edit the properties of an account after it has been created by double-clicking the account name, or using Edit in the context menu or the Accounts menu. The Ledger The ledger shows all transactions to and from an account in chronological order. The ledger is accessed by double-clicking the change or balance column of an account in the account view, Show Transactions in the context menu, AccountsShow Ledger, or by clicking the corresponding button in the toolbar. All transactions are shown in falling date order. The balance column shows the accumulated account value ⸺ the amount of money in the account after the transaction occurred. This may not be the exact same value as on the corresponding bank statement if the transaction order does not match exactly. You can edit or create transactions using the buttons to the right or by double-clicking a transaction. Multiple accounts can not be shown simultaneously in the ledger. Switch between accounts using the drop-down list in the upper left corner of the window. To the right of this menu are buttons for saving the transaction list to a HTML file or a CSV file (can be opened in spreadsheet programs), or print it on paper. Adjust Balance If the account balance shown in &app; differs from the actual balance (in your wallet), and you are unable to find out what is wrong or missing (e.g. by comparing transactions with receipts or bank statements with the ledger), you will have the possibility the adjust the account balance (using Adjust balance in the Accounts menu or in the context menu of an account. When you enter the real value of the account in the dialog, an account balance adjustment transfer to a hidden balancing account is created to match the book value with the real value. This should be avoided, but may sometimes be necessary (usually for cash accounts). Marking an Account as Closed An account can be mark as closed using Close Account in the Accounts or context menu, or at the bottom of the dialog for account editing. The account will then be hidden from the account view when the change and balance values for the select period is zero. The closed account will be moved to the bottom section of account lists when editing transactions. Categories Incomes and expenses are organised in categories with associated budgets. Category Creation and Editing To create an account use Add Category in the context menu, AccountsNew Income/Expense Category, or the corresponding button in the toolbar. You can also create a new category by selecting the top item in the category list when editing an income or expense. Enter a name, and optionally a description, a parent category and/or monthly budget, in the window that appears and click OK. &app; supports one level of subcategories (subcategories of subcategories are not supported). Subcategories can be created using Add Category in the context menu of a category or by selecting a parent category in the category edit dialog. Subcategories can also be moved to and from parent categories using drag and drop. You may edit the properties of a category after it has been created by double-clicking the category name, or using Edit in the context menu or the Accounts menu. Budget A monthly budget can be associated with each category. This way you can continuously compare actual and planned expenses, and see how your current budget will affect your future wealth. A budget is initially asked for when creating a category. Later you can update it from the budget tab at the bottom of the accounts view (affects the category currently selected in accounts list). If the budget has not been set for a month, the budget of the previous month is used. You can choose to set budgets for only some categories. In the accounts list, budget and remaining budget (budget minus past and planned expenses/incomes) is displayed in the second column. If not all categories have a budget, the total remaining budget only summarises the categories with budget and thus does not include actual expenses or incomes from other categories. A budget can also be set for each subcategory. If no budget is set for the parent category the sum of the value for subcategories with budgets will be displayed (the transactions of subcategories without a budget are excluded). It is possible to specify a budget for both each subcategory and the parent budget. This can be useful if you want to use a single budget for only some subcategories or if some transactions does not belong to a subcategory, but will be confusing if you set the parent budget to a value that is lower than the sum of the specified budgets of subcategories. The Budget Month The budget month by default starts on the first and ends on the last day of the calendar month. This can be changed using SettingsSet Budget Month. Only the first day of the budget month can be selected (the budget month will always be as long as the calendar month of the start date). This will also affect how statistics are calculated and displayed. Months (and years) in charts and tables refers to the budget month. If the budget day is set to a value greater than 15, the budget month uses the name, and year, of the calendar month of the last the day of the budget month (if the first budget day is set to 25, the budget month that begins on December 25 2017, is referred to as January 2018), otherwise the calendar month of the start day is used. The Accounts View The accounts view displays a list of all accounts and categories, sorted alphabetically under assets, liabilities, incomes, and expenses. The rows for the main account/category types displays the sum of all accounts/categories below. The list has four columns. The first simply displays the name of the account or category. The second does for categories display the budget for the selected period and what is left of the budget. Unless the Show partial budget option is checked, the budget (and remaining budget) is displayed for whole months, thus you can in the default mode see whats left to spend of the current monthly budget. The third column displays the change in value, while the last column displays the total value. In the bottom of the accounts view, there is a box for period selection. The period controls within which dates statistics will be shown in the list. If the button for the from (start) date is unchecked, all transactions up til and including the to (end) date will be included. The third, Change, column displays the value of all transactions that occurred between the two dates – the change in total value from start to end date. The last column (Total) displays the total value of all transaction up til and including the end date, plus the initial balance for accounts. If from date is unset, change and total will be equal for all categories. For accounts the total represents the actual money present at the end date, and change, the profit (or loss in the case of liabilities) during the period. By default, the period is set to run from the beginning of the current month to (including) current date. Thus, the current state of accounts and transactions so far during the month are shown. The four buttons to the right of the dates moves the entire period backwards or forwards a month or a year. Values for future dates are based on budgets and scheduled transactions (whichever is greatest). An account can be designated as budget account (default for current accounts), meaning that budgeted incomes and expenses will be included in the statistics displayed for that account. Otherwise the budgeted amount will only be included in the values of the total assets item (thus it will not necessarily equal the sum of the values of each assets account). Double-clicking an account or category in the list will result in a different action depending on type and column. The different actions are listed in the table below. Double-click actions for the account view Column Action for accounts Action for categories Account / Category Edit Account (or expand/collapse list) Edit Category (or expand/collapse list) Remaining Budget Open ledger Edit budget Change Open ledger Open expenses or incomes view with a filter for selected category Total Open ledger Open expenses or incomes view with a filter for selected category and period
If you press Enter on the keyboard when a row is selected, it will result in the same action as if the last column was double-clicked.
Transactions Expenses, incomes and transfers &app; has three different basic transactions types – expenses, incomes, and transfers. Expenses represent a loss of money, a transaction where you give away money, mostly in return for something else. This can be a payment for products and services, or a gift. Incomes represent a gain of money; when you are given money. This is when your at the other end of an expense, when you receive payment for products and services you provide (often as salary for your regular job), or when someone gives you money as a gift. The third transaction type, transfer, represents neither a loss nor gain, but a transfer of money from one account to another. This can for example be when you withdraw money from your bank account as cash, or when you transfer money to a savings account. Loans, and loan payments reducing the debt, are also transfers (from a liability account to an assets account, and vice versa), even though &app; provides alternative methods for recording these. Each transaction has a number of mandatory or optional properties. All the basic transactions have four mandatory properties – value, date, and from and to accounts/categories. Value represents the amount of money that is affected by the transaction, date when the transaction occurred, from account where the money was taken from and to account where money was put. These are the generic property names, which shows that all transaction types basically are the same. For expenses the value is a cost, a positive value representing a loss of money, from the account that the expense is paid from, to an expense category. For incomes the value is an income, a positive value representing a gain of money, from an income category, to the account that the income is deposited in. For transfers the value is referred to as amount, or withdrawal (from an account) and deposit (to an account). Mandatory Properties Generic Expense Income Transfer Value Cost Income Amount (withdrawal and deposit) Date Date Date Date From Account/Category Account (account) Category (income category) From (account) To Account/Category Category (expense category) Account (account) To (account)
All transactions do in addition have three optional properties. The description property provides information about the nature of the transaction. This can be considered a final level of categorisation (you get enhanced statistics and increased efficiency if you keep the description consise and without inflections, and reuse it for similar transactions). The comment property is used for any additional information, not used for categorisation, about the transaction. If you for example buy a pair of shoes, you might create an expense in a clothing category, with the description Shoes and comments Shiny red Pradas. The third property, associated file, allows you to specify a link to a file on the computer which will be connected to the transaction. This will typically be receipt, invoice or payslip, but any file can be selected. The file will not be moved, copied or modified. If the file is moved or renamed outside of &app;, the file will not be accessible from within the program. Expenses have two additional properties which can be shown or hidden using SettingsUse Additional Transaction Properties (deactivating this option will not permanently remove any data from already entered transactions). The quantity property denotes how many entities was involved in the transaction. This can be a whole number, as in two CD's, or a fraction, as in 0.56 kg apples (units are not included). This property is by default set to 1 and does not affect the value (the value per entity equals value divided by quantity). The payee property represents the person or entity, for example the store where goods where bought, which receives the money. Incomes have a similar payer property, representing the one who gave you the money, for example your employer.
The Transactions Views The transactions views show a list of expenses, incomes or transfers. By default all transactions (including scheduled transactions, shown in italics) up till and including the current date are shown, sorted in falling date order. The sort order can be changed by clicking the appropriate column header. Transactions with the same date are shown in the order they were entered. Statistics are shown immediately below the list. These numbers summarises all transactions currently in the list, unless two or more transactions are selected (in which case the numbers only refers to selected transactions). Filter Transactions Below the list of transactions is a section for filtering transactions. By default the tab for editing transactions is shown instead. To show the filter tab, click on Filter above the input fields. This enables you to select which transactions are shown in the list above. You can filter transactions based on date, value, account, category, description and/or payee/payer. Unless the exact match box is marked, text in the description and payee/payer fields will be matched against any part of the of the corresponding transaction properties, including comments in the case of the description field. You can opt to show all transactions that do not match (all) the filter criteria, by activating Exclude instead of Include. Create/Edit Transactions New transactions can be entered in two ways, either with the new expense/income/transfer dialogs (accessed from context menus, the Transactions menu or the toolbar), or from the transactions views, below the transaction list. The edit a previous transaction either double-click the transaction (there are further options in different menus) or select (single-click) the transaction in the transactions view and change the values in the fields below the list. Notice that you have to press Apply or the changes are lost. Both the Enter key and the Tabulator key, on the keyboard, can be used to move to the next field. When in the last field of column (in the transaction edit dialog this is the last input field; in the transaction view this refers to both the date field and the comments field), the Enter key will however instead confirm the entered values (equivalent to pressing OK in the transaction edit dialog, or the Add button in the transaction view). When entering a previously used description in the description field, all are other fields (except date) will be automatically filled with the values of the last transaction with the same description. This requires that the current value in the value/cost/income field is zero. If the description field is empty, the category and payee/payer fields exhibit a similar behaviour. The Value Input Field The input field for transaction values support basic arithmetic calculation. Addition, subtraction, multiplication, division and exponentiation are supported and uses standard order of operations (1+2*3 equals 7, not 9). Currency conversion is also supported. Currencies will be converted to the currency of the currently selected account of the transaction. Note that the currency symbols used for conversion must be unambiguous. Symbols used for multiple currencies are not allowed (e.g. $ is used by many currencies, and you should therefor type USD instead for conversion from U.S. dollars), except for the main currency. By default the value field uses the current currency as prefix or suffix. This can be omitted when entering a new value and is ignored when using currency conversion (expressions similar to £5 € are allowed). If arithmetic or conversion have been used, the calculated expression is copied to the comments field, if empty. Edit Multiple Transaction Simultaneously It is possible to change the value of one or more properties of multiple transactions at the same time (e.g. if you want to move some transactions to a new subcategory). Select the transactions you want to edit in the transaction list and select Edit transactions (Occurrence) from the context menu or the Transactions menu. A window will open with a list of properties that can be changed. The fields are prefilled with the values of the first transaction. Next to each property is a box for marking each property that will be changed. Properties with equal value for all selected transaction are marked for change by default. Enter new values for appropriate properties and click OK to make the change. Refunds and Repayments You should enter a refund instead of an income when you receive money as a refund for a previous expense. This can for example be if you return a product and get your money back, or if you buy a present that you and your friend will give to a mutual friend, and you receive your friends share of the cost later. The create a new refund use TransactionsNew Refund/Repayment or the context menu with the refunded expense selected in the expense list. You will have to enter the amount of money refunded (initially set to full refund) and the date of the refund. In addition you should specify the product quantity returned by you. In the first expample above this is clearly 1, but in the second case this is less clear. It can either be 0.5 if you count it as a half product, or 0 if considered a whole gift (none returned). The use is more obvious if the quantity property is activated for all expenses and incomes. The refund is recorded as an expense with negative cost and quantity. Repayments are similar tto refunds, but is used for incomes that you have been forced to repay. Split Transactions Split transactions are used when a single transfer to/from an account is used for multiple transactions. This is not when money is withdrawn from a bank account through an ATM and you go shopping (that is first a transfer from a bank account to cash, then multiple regular expenses). A split transaction will for example be appropriate when you make a single payment for multiple products (especially if they are categorised differently), or when you pay with your credit card in a store and tell them to withdraw some extra money, which you get as cash in your hand. It is up to you how and when you want to use split transactions. Multiple ordinary transactions can be used with the same end result, even though one way might represent reality better. A split transaction can be created from scratch using TransactionsNew Split Transaction or from the context menu. It is however often more efficient to use the join action. This way you can enter transactions the usual way and later join them in a split transaction. Select the transactions to join and activate Join Transactions from the Transactions menu or the context menu, and enter a description. All transactions in a split transaction share a common date, account and payee/payer. To reverse the action and transform transactions in a split transaction to ordinary transactions, select a split transaction and use Split Up. In the transaction list (ledger) for the account associated with the split, the split will be shown as only one transaction, but everywhere else the parts of the split will appear as ordinary transactions. You cannot edit a transaction that is part of a split transaction directly from the fields below the transaction lists. Instead you should press Edit to edit the whole split transaction, or double click the transaction in the list to edit the separate transaction (excluding the common date, account and payee/payer properties of the split transaction). Expenses with Multiple Payments Expenses with multiple payments are similar to split transactions, but instead of using a common date and account, they share description, category, quantity and comments. The intended usage is for when multiple payments, primarily from different accounts, are made for a single product/service. They should not be used for payment plans/loans (although an expenses with multiple payments is created for expenses with downpayment). Expenses with multiple payments can be created using the TransactionsNew Expense with Multiple Payments or by selecting Multiple accounts/payments in the account menu for an expense. Expenses with multiple payments will show up as a single transaction in the expenses view, but as multiple transactions in the ledger. Similarly to split transactions they cannot be edited directly from the fields under the expenses list. Note that even if you create a recurring expense with multiple payments where each payment has a different date, all recurrences after the first occurrence will use the same date for each separate payment. If a future date is set for the first, or only, occurrence, the program will only ask for confirmation of the expense on the first date. Expense Paid with Loan An expense paid with loan is not actually recorded as a specific kind of transaction, but is a shortcut for creating a debt account and an expense with multiple payments (or a regular expense if downpayment is zero). Expenses with multiple payments can be created using the LoansExpense Paid with Loan or by selecting Paid with loan in the account menu for an expense. Enter the usual expense properties (account excluded), an optional lender and optional value and account for downpayment (represents the amount of money you pay immediately). Debt Payments Debt payments are a third kind of combined transaction. These group together repayment, interest and fees. Ordinary transactions can also be used for these purposes. Interest and fee are expenses and loan reductions are transfers. Debt reduction represents the amount you (re)pay that actually reduces the value of the debt. Interest represents the amount the debt has increased (before debt reduction) and may or may not be paid directly. Fee usually represents an administration fee added to each bill. You only need the enter one of the three values (the other can be zero). LoansNew Unpaid Interest also creates loan payment transactions but provides a simplified dialog when the debt has increased because of added interest. Transactions in a loan payment cannot be edited separately. Scheduled Transactions A scheduled transaction is a transaction that is planned to occur, and thus it has not occurred yet. It is basically just a transaction, of any type, that has a date set in the future. When a scheduled transaction has occurred, it becomes a regular transaction. Scheduled transactions makes it possible to keep track of and be reminded of future transactions. &app; will ask for confirmation when the transaction is expected to have occurred. A scheduled transaction can be recurring, thus it will regularly occur on a certain date or with a certain interval. This is useful mostly for bills and salaries, which then need not be entered manually each time, and you can check &app; for upcoming payments. When a recurring scheduled recurring transaction has occurred, a regular transaction is created, the occurrence date is removed from the recurrence, and the scheduled transaction date is moved forward to the next occurrence. If you modify the properties of a recurring transaction, the previous occurrences will not be affected and vice versa. A scheduled transaction with no occurrences left is removed. Single occurrence scheduled transactions are create just like ordinary transactions, except with a future date. Recurring transactions can only be created from the transaction dialogs (opened from the schedule view, toolbar buttons or menu items, or when double clicking a transaction), with recurrences specified in the second tab. The next occurrence of each scheduled transaction is displayed in the schedule view. You can edit or delete either the single occurrence or all future recurrences. If a single occurrence is edited, it will be created as a separate transaction, and any changes made to recurring transaction will not affect this occurrence. If the date is changed to the current or a past date, the scheduled transaction becomes an ordinary transaction. When a scheduled transaction is due, when the current date has gone past the date of the occurrence (or same date after 6 pm), &app; will ask you to confirm that the transaction really has occurred. You are then given the option to accept the transaction as it is, make some changes (for example the cost of your telephone bill might vary slightly), or postpone it. If the scheduled transaction is not postponed, it will become an ordinary transaction.
Securities Securities represents money invested in stock, bonds and mutual funds. &app; does not differentiate between different kinds of securities, even though the terminology used is better suited for some. Securities and associated statistics are displayed in the securities view. The create a new security in &app; use SecuritiesNew Security or the New Security button. First select an account. Securities are associated with an account of securities type, which cannot be associated with ordinary transactions. Enter name of the security and select type. Specify initial shares if you do not want to back-track all transactions (it is always preferred to use transactions instead, for better statistics), and enter a quotation with associated date. Automatic updates of stock quotes are not supported. You will have to update the value per share manually (using Set Quote or Edit Quotes in Securities or context menu) for the security value to be up to date. Security Transactions The following transactions are supported for securities: Shares boughtWhen additional shares of a security have been bought or received (as an income). Specify two of number of shares bought, price per share and total cost (including fees/commission), and select an account (if bought) or income category (if received). Shares soldWhen some shares of a security have been sold or given away (or used as payment). Specify two of number of shares sold, price per share and total income, and select an account (if sold) or expense category (if given away). Shares tradedWhen shares of one security are sold and shares of another security are bought for the same amount of money, without transfer of income to an account in between. DividendWhen money is received for each share of a security. Specify income and income category. Reinvested dividendWhen dividend is received as additional shares. All shares bought and sold are listed as transfers (listed in the transfers view), unless recieved/given away (in which case the transaction are listed as an income or expense), and dividends as incomes (in the incomes view). You can list all transactions associated with a single security using SecuritiesTransactions (or the context menu). The Securities View Statistics displayed for each security: ValueValue at period end date date (quotation * shares). QuotationPrice per share at period end date. SharesShares at period end date. CostTotal price paid for all buys minus sells, at end date. ProfitProfit during the period (value + dividends - cost). Yearly RatePercent increase of value per share (for a share bought at the beginning of the period), during the period on a yearly basis. Includes dividends. In the total statistics displayed below the security list, quotation and yearly rate are weighted based on the value of each security. Predictions are simplistic and based on previous development, with respect to dividends and quotations, only. Future quotations are calculated using quotations during the nearest past time. The quotation one month from current date is assumed to have increased at the same rate as during the past month (or the date before with a specified quotation). Dividends are always predicted using full past years (they are assumed to occur on a yearly basis). Using Multiple Currencies &app; support per account currencies. A different currency can be selected for each account (for assets and liabilities). The main currency determines the default currency for new accounts and the currency used for statistics. The sum of values from accounts in different currencies and the total value and change of categories (for example in the accounts view, or in the statistical reports and diagrams) are be shown in the main currency. By default the main currency is set to the system wide local currency. Use SettingsSet Main Currency to change the main currency. A dialog is then shown, where you can select a new main currency, with the option to change the currency of all accounts using the previous main currency. The currency of an account is selected in the dialog for account creation/editing. It is generally not advisable to change the currency of an account with associated transactions. This will leave the numerical value of associated transactions unchanged, but the actual monetary value might be radically different. For transfers between accounts with different currencies both withdrawn and deposited amount must be specified. The same is true for loan payments (reductions) where the loan is in a different currency from the account used for the payment. Conversion losses are not treated as expenses and are thus not included in statistics for expenses and profits. Included currencies support automatic exchange rate updates If multiple currencies are in use, the exchange rates are automatically updated once every week, but they can also be updated using FileUpdate Exchange Rates. If a currency is not available, you can add it manually using the top item in currency menu when creating a new or editing a present account (it can also be done from main currency selection dialog). You must specify the three letter code of the currency and you should enter an exchange rate in European euros. The currently selected currency of the account can be edited using the button directly under the currency menu. The exchange rate will not be updated automatically. Which Exchange Rate is used When? &app; saves, but does not download, historical exchange rates. It is not obvious which exchange rate should and is used when converting the value of transaction to a different currency, for display. In the account view, the exchange rate nearest the current end date (of the displayed period) is always used for the sum of assets and liabilities. For expense and income categories, however, their are two options (selectable from the Settings menu) available. The first option is to use the appropriate exchange rate for the date of each separate transaction. The second default option is to simply use to current exchange rate, regardless of the transaction date (or the current end date). The same logic is used in the transaction lists for transactions using multiple currencies, as well as in different statistics (with the exception of historical account values). None of the options are optimal and which one is more appropriate depends on the typical flow between accounts in different currencies. This is however of minor importance for stable currencies. Currency Conversion You can quickly convert between different currencies by using the currency converter (FileCurrency Converter). Select currencies for conversion in the drop-down menus on the right and enter a value in one of the fields to the left. The value is converted as you type. It is also possible to do currency conversion in every value field elsewhere in &app; (see ). Statistics You can get an overview of your economical situation by using the charts and reports accessible from the Statistics menu. Categories Comparison The categories comparison report allows comparison between or within expense and/or income categories. The initial view shows all categories with subcategories hidden, with values for the past year. The display settings can be changed at the bottom of the window. The source can changed to also display every separate subcategory, or only show a single category. If a specific category is selected, you will have the option to compare the values for subcategories, different transaction descriptions or payees/payers. The data can be broken even further down by only comparing descriptions for a specific payee/payer, payees/payers for a specific description. Below, the period shown can be selected. For dates extending into the future, scheduled transactions are included in the value, but not budgeted incomes/expenses. Finally you can select which columns shall be displayed. Displayable columns include total value, averages based on different time periods (e.g. the daily average equals the total value divided by the number of days in the selected time period), total quantity, and average value of each item (total value divided by total quantity). The buttons in the upper right corner allows you to save the view as a HTML file or print it on paper. The categories comparison chart displays the same total values as the report, but in a pie or bar chart. The chart type and style is selected in the upper right corner of the window. For the chart you can select (in the lower right corner) to display all expense or income categories (with subcategories shown or hidden), or a specific category. If a single category is selected, the data is divided into subcategories, or (if there are no subcategory) into different transaction descriptions. Here you will also have the option to compare the value of different accounts (assets). As in the report you can select the time period values are shown for (for accounts the from date is ignored). In the upper right there also here buttons for saving (to an image file), or printing the chart. Click on a sector, or the corresponding title in the legend, to show it exploded (separated). Development Over Time The development over time report shows values for each separate month and year. Initially total profits (incomes minus expenses) are shown. Below the table you will have the option to show expenses or incomes separately instead. These can be further broken down into separate categories and transaction descriptions. Note that payments that reduces a debt are not counted as expenses. At the bottom of the window displayed columns can be selected. The columns include total value, averages based on different time periods (e.g. the daily average equals the total value divided by the number of days in the selected time period), total quantity, and average value of each item (total value divided by total quantity). The buttons in the upper right corner allows you to save the view as a HTML file or print it on paper. The development over time chart shows how expenses and incomes change over time, with values grouped by month, in line or bar chart. The chart type and style is selected in the upper right corner of the window. Initially incomes and expenses are shown from the month and year of the first transaction to the the end of the last budget month (unless the first and last month are the same). The time span displayed can be changed below the chart. Bar chart can at most display one whole year at the same time. For future dates scheduled transactions are included, but budgeted incomes/expenses are only included when all categories are combined (including the profits source). Below the table you will have the option to show profits(expenses minus incomes) or specific categories. Categories can be shown combined or separately ⸺ all with separate lines/bars or only one. Categories can be further broken down into transaction descriptions and separate payees/payers. There is also an option to display total accumulated assets and liabilities (the Assets and Liabilities source). The char can show the total values for each month, the daily average (within each month), the total quantity, or average value per quantity each month. Daily averages compensates for the different number of days in month, but this is offset by the fact that large expenses and incomes often occur monthly. Click on a label in the chart legend to hide a data series from the chart. Move the mouse over a line or a bar to show details above single values. Click, hold and move the pointer (drag) to zoom in the chart. In the upper right there also here buttons for saving (to an image file), or printing the chart. Import & Export of Transactions QIF Files Files using the Quicken Interchange Format can be read by most personal money management software. The format is however old and has limitations, which means that data might be lost during import and export. QIF Import Select FileImportImport QIF File and follow the instructions. QIF is a file format that might differ much depending on the software that saved the file. How much details you will need to provide about the file depends on ambiguity of the date format, how localised the file is, and how well accounts are defined. Securities, investment transactions, memorised transactions, budgets, and classes are not imported. QIF Export Activate FileExport QIF File and select account to export, format for dates and numbers, and filename. It is possible to export transactions from all accounts, but multi-account QIF files are not always supported by other software. Not all transaction properties are exported. CSV Import This function imports data files with clear text values in columns separated by a character (comma, space, tab, etc.), with a new transaction on each row. Select FileImportImport CSV File and enter details about the structure of the file you want to import. Transaction parameters can either be imported from a column in the file or a set to a specified value. CSV or HTML Export Every account and transaction list in &app; can be saved to a HTML or CSV file. HTML files are suitable for display in a web browser and CSV (comma separated values) files can be opened in most spreadsheet programs. Use FileExport View or the corresponding toolbar button to save a list of accounts, expenses, incomes, transfers, securities or scheduled transactions. The displayed values will be exported (for accounts and securities the current time period is used and for transactions the current filter and sort order is adhered to). The ledger can be exported using the Export button in the upper left corner of the ledger window. Merge &app; File Accounts and transactions from another &app; file can be imported to the current file using FileImportImport &app; File. All accounts and transactions from the file will be copied. When the file has been selected you will be presented with alternatives for handling of duplicate transactions, accounts, categories and securities. If you select the rename options ("imported") will be appended to the name, otherwise the transactions will be added to the already present accounts with the same name. This makes it easier to distinguish and manipulate imported transactions. (For information on how to modify/move mmultiple transactions at the same time see .) Credits and License Program copyright 2017 Hanna Knutsson hanna.knutsson@protonmail.com Contributors: Hanna Knutsson hanna.knutsson@protonmail.com Documentation copyright 2017 Hanna Knutsson hanna.knutsson@protonmail.com
Eqonomize-1.5.3/doc/generatehtml000077500000000000000000000000701416454732000166430ustar00rootroot00000000000000mkdir html ./generatehtml_lang C #./generatehtml_lang frEqonomize-1.5.3/doc/generatehtml_lang000077500000000000000000000005131416454732000176460ustar00rootroot00000000000000#!/bin/sh xsltproc -o html/$1/ --stringparam chunker.output.encoding UTF-8 --stringparam use.id.as.filename 1 --stringparam chunk.section.depth 0 "http://docbook.sourceforge.net/release/xsl/current/html/chunk.xsl" $1/index.docbook cd html/$1/ for f in *.html; do sed -i 's/Chapter 3. Accounting with Eqonomize!

Chapter 3. Accounting with Eqonomize!

Overview

The basics principle behind accounting in Eqonomize! is the idea of money flowing through transactions between accounts as reservoirs. A transaction represents a gain (you receive money), loss (you buy something), or transformation (you withdraw from or deposit in a bank account) of money.

A transaction always means that money is moved from one account to another. An expense (something is bought) can for example mean that you pay with cash from your cash account. The money is then put in an expense account. This account represents the products and services you pay for. It represents the money that you do not have as a result of expenses, and is therefor useful for record keeping.

Incomes is usually put in a bank account and withdrawn from an income account. This means that income accounts will have a negative value, but to avoid confusion, the value of income accounts are shown as positive values.

Different income and expense accounts are used for categorisation, and are therefor more naturally referred to as categories. Other accounts, which represents the money you actually have and often are real world bank accounts, are simply referred to as accounts.

Accounts and Categories

Eqonomize! does not differentiate between accounts for assets and liabilities, except that they are group differently in the account view and that liabilities support some special transactions for convenience.

Transactions

Eqonomize! has three different basic transactions types – expenses, incomes, and transfers. Securities uses some special transactions which are described in the section called “Securities”. The account types debt and credit card are used for lialibilities, the rest for assets. The securities type represents special accounts that are the only ones that can be associated with securities and only supports security transactions.

Expenses represents a loss of money, a transaction where you give away money, mostly in return for something else. This can be a payment for products and services, or a gift (or you lend someone money).

Incomes represents a gain of money; when you are given money. This is when your at the other end of an expense, when you receive payment for products and services you provide (often as salary for your regular job), or when someone gives you money as a gift or loan.

The third transaction type, the transfer, represents neither a loss nor gain, but a transfer of money from one account to another. This can for example be when you withdraw money from your bank account as cash, or you transfer money to a savings account.

Each transaction has a number of mandatory or optional properties. All the basic transactions have four mandatory properties – value, date, and from and to accounts/categories. Value represents the amount of money that is affected by the transaction, date when the transaction occurred, from account where the money was taken from and to account where money was put. These are the generic property names, which shows that all transaction types basically are the same.

For expenses the value is a cost, a positive value representing a loss of money and the to account/category is called category and the from account/category is the account that the expense is paid from. The category is always an expense category and the from account/category an account.

For incomes the value is an income, a positive value representing a gain of money and the from account/category is called category and the the to account/category is the account that the income is deposited in. The category is always an income category and the to/from account an account.

For transfers the value is called amount, and the to and from accounts/categories are both accounts.

Table 3.1. Mandatory Properties

Generic

Expense

Income

Transfer

Value

Cost

Income

Amount

Date

Date

Date

Date

From Account/Category

Account (account)

Category (income category)

From (account)

To Account/Category

Category (expense category)

Account (account)

To (account)


All transactions do in addition have three optional properties. The description property provides information about the nature of the transaction. For expenses and incomes this can be considered a flexible subcategory. The comment property is used for any additional information, not used for categorisation, about the transaction. If you for example buy a pair of shoes, you might create an expense in a clothing category, with the description Shoes and comments Shiny red Pradas. The third property, Associated File, allows you to specify a link to file on the computer which will be connected to the transaction. This will typically be receipt, invoice or payslip, but any file can be selected. The file will not be moved, copied or modified. If the file is moved or renamed outside of Eqonomize!, the file will not be accessible from within the program.

Expenses have two additional properties which can be show or hidden using SettingsUse Additional Transaction Properties (deactivating this option will not permanently remove any properties from already entered transactions). The quantity property denotes how many entities was involved in the transaction. This can be a whole number, as in two CD's, or a fraction, as in 0.56 kg apples (units are not included). This property is by default set to 1 and does not affect the value (the value per entity equals the value divided by the quantity). Expenses also have a payee property for the person or entity, for example the store where goods where bought, which receives the money. Incomes also have the payer property for the one who gives you the money, for example your employer.

The input field for transaction values support basic arithmetics. Addition, subtraction, multiplication, division and exponentiation are supported and uses standard order of operations (1+2*3 equals 7, not 9). Parentheses can not be used.

Currency conversion are also supported. Currencies will be converted to the currency of the currently selected account of the transaction. Note that the currency symbols used for conversion must be unambiguous. Symbols used for multiple currencies are not allowed (e.g. $ is used by many currencies, and you should therefor type USD instead for conversion from U.S. dollars), except for the main currency.

By default the value field uses the current currency as prefix or suffix. This can be omitted when entering a new value and are ignored when using currency conversion (expressions similar to £5 € are allowed).

If arithmetics or conversion have been used the calculated expression is copied to the comments field, if empty.

Split Transactions

Split transactions are used when a single transfer to/from an account is used for multiple transactions. This is not when money is withdrawn from a bank account through an ATM and you go shopping (that is first a transfer from a bank account to cash, then multiple regular expenses). A split transaction will for example be appropriate when you make a single payment for multiple products (especially if they are categorised differently), or when you pay with your credit card in a store and tell them to withdraw some extra money, which you get as cash in your hand.

It is up to you how and when you want to use split transactions, as multiple ordinary transactions can be used with the same end result, even though one way might represent what happened in reality better.

You can create a split from scratch with TransactionsNew Split Transaction... or from the context menu. It is however often more efficient to use the join action. This way you can enter transactions the usual way and later join them in a split transactions. Select the transactions to join and activate Join Transactions... from the Transactions menu or the context menu, and enter a description. All transactions in a split transaction have a common date and account.

To reverse the action and transform transactions in a split transaction to ordinary transactions, select a transaction and use Split Up.

In transaction list (ledger) for the account associated with the split, the split will be shown as only one transaction, but everywhere else the parts of the split will appear as ordinary transactions. You cannot edit a transaction that is part of a split transaction directly from the fields below the transaction lists. Instead you should press Edit... to edit the whole split transaction, or double click the transaction in the list to edit the separate transaction (excluding the common date and account of the split transaction).

Expenses with Multiple Payments

Expenses with multiple payments are similar to split transactions, but instead of using a common date and account, they share description, category, quantity and comments. The intended usage is for when multiple payments, primarily from different accounts, are made for a single product/service. They should not be used for payment plans/loans, although an expenses with multiple payments is created for expenses with a downpayment.

Expenses with multiple payments will show up single transaction in the expenses, but as multiple transactions in the account ledgers. Similarily to split transactions they cannot be edited directly from the fields under the expenses list.

Loan Payments

Loan payments are a third kind of combined transaction. These group together payments on loans (reductions), interest and fees. Ordinary transactions can also be used for these purposes. Interest and fee are expenses and loan reductions are transfers.

LoansNew Unpaid Interest... also creates loan payment transactions but provides a simplified dialog when the debt has increased because of added interest.

Transactions in a loan payment can not be edited separately.

Scheduled Transactions

A scheduled transaction is a transaction that is planned to occur, thus it has not occurred yet. It is basically just a transaction, of any type, that has a date set in the future. When a scheduled transaction has occurred, it becomes a regular transaction. Scheduled transactions makes it possible to keep track of and be reminded of future transactions. Eqonomize! will request for a confirmation when the transaction is expected to have occurred.

A scheduled transaction can be recurring, thus it will regularly occur on a certain date or with a certain interval. This is useful mostly for bills and salaries, which then need not be entered manually each time and you can check Eqonomize! for upcoming payments. When a scheduled recurring transaction has occurred, a regular transaction is created, the occurrence date is removed from the recurrence, and the scheduled transaction date is moved forward to the next occurrence. A scheduled transaction with no occurrences left is removed.

Single occurrence scheduled transactions are create just like ordinary transactions, except with a future date. Recurring transactions can only be created from the dialogs, with recurrences specified in the second tab.

The next occurrence of each scheduled transaction is displayed in the schedule view. You can edit or delete either the single occurrence or all future recurrences. If a single occurrence is edited, it will be created as a separate transaction, and any changes made to all recurrences will not affect this occurrence. If the date is changed to the current or a past date, the scheduled transaction becomes an ordinary transaction.

When a scheduled transaction is due, when the current date has gone past the date of the occurrence (or same date after 6 pm), Eqonomize! will ask you to confirm that the transaction really has occurred. You are then given the option to accept the transaction as it is, make some changes (for example the cost of your telephone bill might vary slightly), or postpone it. If the scheduled transaction is not postponed, it will become an ordinary transaction.

Securities

Securities represents money invested in stock, bonds and mutual funds. Eqonomize! does not differentiate between different kinds of securities, even though the terminology used is better suited for some. Securities and associated statistics are displayed in the securities view (accessed using the icons on the left).

The create a new security in Eqonomize! use SecuritiesNew Security... or the New Security... button. First select account. Securities are associated with an account of securities type, which cannot be associated with ordinary transactions. Enter name of the security and select type. Specify initial shares if you do not want to back-track all transactions (it is always preferred to use transactions instead, for better statistics). Specify then also date and quotation.

Security Transactions

The following transactions are supported for securities:

Shares bought

When more shares of a security have been bought. Specify new shares, price per share (quotation given) and total cost, including fees/commission.

Shares sold

When some shares of a security have been sold. Specify new shares, price per share and total cost, including fees/commission.

Shares traded

When shares of one security are sold and shares of another security are bought for the same amount of money, without transfer of sell income to an account in between.

Dividend

When money is received for each share of a security. Specify income and income category.

Reinvested dividend

When dividend is received as additional shares.

All security transactions are listed listed as transfers (in the transfers view), except dividends, and shares bought if associated with an income category, which are displayed as incomes. You can list all transactions for a single security using SecuritiesTransactions... (or the context menu).

The Securities View

Statistics displayed for each security:

Value

Value at period end date date (quotation * shares).

Quotation

Price per share at period end date.

Shares

Shares at period end date.

Cost

Total price paid for all buys minus sells, at end date.

Profit

Profit during the period (value + dividends - cost).

Yearly Rate

Percent increase of value per share (for a share bought at the beginning of the period), during the period on a yearly basis. Includes dividends.

In the total statistics displayed below the security list, quotation and yearly rate are weighted based on the value of each security.

Predictions are simplistic and base on previous development, with respect to dividends and quotations, only. Future quotations are calculated using quotations during the nearest past time. The quotation one month from current date is assumed to have increased at the same rate as during the past month (or the date before with a specified quotation). Dividends are always predicted using full past years (they are assumed to occur on a yearly basis).

Using Multiple Currencies

Eqonomize! support per account currencies. A different currency can be selected for each account (for assets and liabilities).

The sum of values from accounts in different currencies and the total value and change of categories (for example in the accounts view, or in the statistical reports and diagrams) will be shown in the main currency. By default the main currency is set to the currency of the system default location, but this can be changed from the settings menu, or in the edit dialog of each currency.

For transfers between accounts with different currencies both withdrawn and deposited amount must be specified. The same is true for loan payments (reductions) where the loan is in a different currency from the account used for the payment.

Included exchange rates support automatic exchange rate updates using data from the European Central Bank. If multiple currencies are in use, the exchange rates are automatically updated once every week, but they can also be updated using the FileUpdate Exchange Rates.

If a currency you use is not available you can add it manually using the top item in currency menu when creating a new or editing a present account (it can also be done from main currency selection window). You must specify the three letter code of the currency and you should enter an exchange rate in European euros. The currently selected currency of the account can be edited using the button directly under the currency menu.

Which Exchange Rate is used When?

Eqonomize! saves, but does not download, historical exchange rates. It is not obvious which exchange rate should and is used when converting the value of transaction to a different currency, for display. In the account view, the exchange rate nearest the current end date (of the displayed period) is always for the sum of assets and liabilities.

For expense and income categories, however, their are two options (selectable from the Settings menu) available. The first option is to use the appropriate exchange rate for the date of each separate transaction. The second default option is to simply use to current exchange rate, regardless of the transaction date (or the current end date). The same logic is used for in the transaction lists for transactions using multiple currencies, as well as in different statistics (with the exception of historical account values). None of the options are optimal and which one is more appropriate depends on the typical flow between accounts in different currencies. This is however of minor importance for stable currencies.

Eqonomize-1.5.3/doc/html/C/accounts.html000066400000000000000000000401701416454732000200760ustar00rootroot00000000000000Chapter 3. Accounts and Categories

Chapter 3. Accounts and Categories

Assets & Liabilities

Eqonomize! does not differentiate between accounts for assets and liabilities, except that they are grouped differently in the account view and that liabilities support some special transactions for convenience.

Account Creation and Editing

To create an account use Add Account in the context menu, AccountsNew Account, or the corresponding button in the toolbar. You can also create a new account by selecting the top item in the accounts list when editing a transaction.

A window will open where you can enter the details of the account. Select the type of account, associated currency, enter a name, and specify the opening balance. The account types debt and credit card are used for liabilities, the rest for assets. The securities type represents special accounts that are the only ones that can be associated with securities and only supports security transactions. The opening balance represents the amount of money present in the account before any recorded transactions. This value should be negative for liabilities. You may optionally also enter a bank (or lender for loan) name and description.

You can also create a debt account using Add Loan. Here you will have the option to create the associated loan transaction at the same time. Notice that a positive debt value here represents a negative opening balance.

You may edit the properties of an account after it has been created by double-clicking the account name, or using Edit in the context menu or the Accounts menu.

The Ledger

The ledger shows all transactions to and from an account in chronological order. The ledger is accessed by double-clicking the change or balance column of an account in the account view, Show Transactions in the context menu, AccountsShow Ledger, or by clicking the corresponding button in the toolbar.

All transactions are shown in falling date order. The balance column shows the accumulated account value ⸺ the amount of money in the account after the transaction occurred. This may not be the exact same value as on the corresponding bank statement if the transaction order does not match exactly. You can edit or create transactions using the buttons to the right or by double-clicking a transaction.

Multiple accounts can not be shown simultaneously in the ledger. Switch between accounts using the drop-down list in the upper left corner of the window. To the right of this menu are buttons for saving the transaction list to a HTML file or a CSV file (can be opened in spreadsheet programs), or print it on paper.

Adjust Balance

If the account balance shown in Eqonomize! differs from the actual balance (in your wallet), and you are unable to find out what is wrong or missing (e.g. by comparing transactions with receipts or bank statements with the ledger), you will have the possibility the adjust the account balance (using Adjust balance in the Accounts menu or in the context menu of an account. When you enter the real value of the account in the dialog, an account balance adjustment transfer to a hidden balancing account is created to match the book value with the real value. This should be avoided, but may sometimes be necessary (usually for cash accounts).

Marking an Account as Closed

An account can be mark as closed using Close Account in the Accounts or context menu, or at the bottom of the dialog for account editing. The account will then be hidden from the account view when the change and balance values for the select period is zero. The closed account will be moved to the bottom section of account lists when editing transactions.

Categories

Incomes and expenses are organised in categories with associated budgets.

Category Creation and Editing

To create an account use Add Category in the context menu, AccountsNew Income/Expense Category, or the corresponding button in the toolbar. You can also create a new category by selecting the top item in the category list when editing an income or expense. Enter a name, and optionally a description, a parent category and/or monthly budget, in the window that appears and click OK.

Eqonomize! supports one level of subcategories (subcategories of subcategories are not supported). Subcategories can be created using Add Category in the context menu of a category or by selecting a parent category in the category edit dialog. Subcategories can also be moved to and from parent categories using drag and drop.

You may edit the properties of a category after it has been created by double-clicking the category name, or using Edit in the context menu or the Accounts menu.

Budget

A monthly budget can be associated with each category. This way you can continuously compare actual and planned expenses, and see how your current budget will affect your future wealth.

A budget is initially asked for when creating a category. Later you can update it from the budget tab at the bottom of the accounts view (affects the category currently selected in accounts list). If the budget has not been set for a month, the budget of the previous month is used.

You can choose to set budgets for only some categories. In the accounts list, budget and remaining budget (budget minus past and planned expenses/incomes) is displayed in the second column. If not all categories have a budget, the total remaining budget only summarises the categories with budget and thus does not include actual expenses or incomes from other categories.

A budget can also be set for each subcategory. If no budget is set for the parent category the sum of the value for subcategories with budgets will be displayed (the transactions of subcategories without a budget are excluded). It is possible to specify a budget for both each subcategory and the parent budget. This can be useful if you want to use a single budget for only some subcategories or if some transactions does not belong to a subcategory, but will be confusing if you set the parent budget to a value that is lower than the sum of the specified budgets of subcategories.

The Budget Month

The budget month by default starts on the first and ends on the last day of the calendar month. This can be changed using SettingsSet Budget Month. Only the first day of the budget month can be selected (the budget month will always be as long as the calendar month of the start date).

This will also affect how statistics are calculated and displayed. Months (and years) in charts and tables refers to the budget month. If the budget day is set to a value greater than 15, the budget month uses the name, and year, of the calendar month of the last the day of the budget month (if the first budget day is set to 25, the budget month that begins on December 25 2017, is referred to as January 2018), otherwise the calendar month of the start day is used.

The Accounts View

The accounts view displays a list of all accounts and categories, sorted alphabetically under assets, liabilities, incomes, and expenses. The rows for the main account/category types displays the sum of all accounts/categories below.

The list has four columns. The first simply displays the name of the account or category. The second does for categories display the budget for the selected period and what is left of the budget. Unless the Show partial budget option is checked, the budget (and remaining budget) is displayed for whole months, thus you can in the default mode see whats left to spend of the current monthly budget. The third column displays the change in value, while the last column displays the total value.

In the bottom of the accounts view, there is a box for period selection. The period controls within which dates statistics will be shown in the list. If the button for the from (start) date is unchecked, all transactions up til and including the to (end) date will be included. The third, Change, column displays the value of all transactions that occurred between the two dates – the change in total value from start to end date. The last column (Total) displays the total value of all transaction up til and including the end date, plus the initial balance for accounts. If from date is unset, change and total will be equal for all categories. For accounts the total represents the actual money present at the end date, and change, the profit (or loss in the case of liabilities) during the period.

By default, the period is set to run from the beginning of the current month to (including) current date. Thus, the current state of accounts and transactions so far during the month are shown. The four buttons to the right of the dates moves the entire period backwards or forwards a month or a year.

Values for future dates are based on budgets and scheduled transactions (whichever is greatest). An account can be designated as budget account (default for current accounts), meaning that budgeted incomes and expenses will be included in the statistics displayed for that account. Otherwise the budgeted amount will only be included in the values of the total assets item (thus it will not necessarily equal the sum of the values of each assets account).

Double-clicking an account or category in the list will result in a different action depending on type and column. The different actions are listed in the table below.

Table 3.1. Double-click actions for the account view

Column

Action for accounts

Action for categories

Account / Category

Edit Account (or expand/collapse list)

Edit Category (or expand/collapse list)

Remaining Budget

Open ledger

Edit budget

Change

Open ledger

Open expenses or incomes view with a filter for selected category

Total

Open ledger

Open expenses or incomes view with a filter for selected category and period


If you press Enter on the keyboard when a row is selected, it will result in the same action as if the last column was double-clicked.

Eqonomize-1.5.3/doc/html/C/commands.html000066400000000000000000000064431416454732000200650ustar00rootroot00000000000000Chapter 9. Command Reference

Chapter 9. Command Reference

The main Eqonomize! window

The File Menu

FileNew (N)

Creates a new document

FileSave (S)

Saves the document

FileQuit (Q)

Quits Eqonomize!

Eqonomize-1.5.3/doc/html/C/credits.html000066400000000000000000000043511416454732000177150ustar00rootroot00000000000000Chapter 9. Credits and License

Chapter 9. Credits and License

Program copyright 2017 Hanna Knutsson

Contributors:

Documentation copyright 2017 Hanna Knutsson

Eqonomize-1.5.3/doc/html/C/currencies.html000066400000000000000000000147051416454732000204260ustar00rootroot00000000000000Chapter 6. Using Multiple Currencies

Chapter 6. Using Multiple Currencies

Eqonomize! support per account currencies. A different currency can be selected for each account (for assets and liabilities).

The main currency determines the default currency for new accounts and the currency used for statistics. The sum of values from accounts in different currencies and the total value and change of categories (for example in the accounts view, or in the statistical reports and diagrams) are be shown in the main currency. By default the main currency is set to the system wide local currency. Use SettingsSet Main Currency to change the main currency. A dialog is then shown, where you can select a new main currency, with the option to change the currency of all accounts using the previous main currency.

The currency of an account is selected in the dialog for account creation/editing. It is generally not advisable to change the currency of an account with associated transactions. This will leave the numerical value of associated transactions unchanged, but the actual monetary value might be radically different.

For transfers between accounts with different currencies both withdrawn and deposited amount must be specified. The same is true for loan payments (reductions) where the loan is in a different currency from the account used for the payment. Conversion losses are not treated as expenses and are thus not included in statistics for expenses and profits.

Included currencies support automatic exchange rate updates If multiple currencies are in use, the exchange rates are automatically updated once every week, but they can also be updated using FileUpdate Exchange Rates.

If a currency is not available, you can add it manually using the top item in currency menu when creating a new or editing a present account (it can also be done from main currency selection dialog). You must specify the three letter code of the currency and you should enter an exchange rate in European euros. The currently selected currency of the account can be edited using the button directly under the currency menu. The exchange rate will not be updated automatically.

Which Exchange Rate is used When?

Eqonomize! saves, but does not download, historical exchange rates. It is not obvious which exchange rate should and is used when converting the value of transaction to a different currency, for display. In the account view, the exchange rate nearest the current end date (of the displayed period) is always used for the sum of assets and liabilities.

For expense and income categories, however, their are two options (selectable from the Settings menu) available. The first option is to use the appropriate exchange rate for the date of each separate transaction. The second default option is to simply use to current exchange rate, regardless of the transaction date (or the current end date). The same logic is used in the transaction lists for transactions using multiple currencies, as well as in different statistics (with the exception of historical account values). None of the options are optimal and which one is more appropriate depends on the typical flow between accounts in different currencies. This is however of minor importance for stable currencies.

Currency Conversion

You can quickly convert between different currencies by using the currency converter (FileCurrency Converter). Select currencies for conversion in the drop-down menus on the right and enter a value in one of the fields to the left. The value is converted as you type.

It is also possible to do currency conversion in every value field elsewhere in Eqonomize! (see the section called “The Value Input Field”).

Eqonomize-1.5.3/doc/html/C/figures/000077500000000000000000000000001416454732000170335ustar00rootroot00000000000000Eqonomize-1.5.3/doc/html/C/figures/accounts.png000066400000000000000000005754741416454732000214060ustar00rootroot00000000000000PNG  IHDR]QݐgAMA a cHRMz&u0`:pQ<bKGDIDATxwxIv"3[ I56țݕv[s޷Y4#iv7{Ѐ}UfA=*+#N ("O?S,?rYXXXXXXXXXXX|$l<3ߟ3bÀA# R~"xٛ%?1B|Jo(t,,,,,,,,,,,,~FEQn<{Ňe6. 8LA!ŚY̳((?3ћhOcttHۦ!n蒔 yr||>O.#N% }% ;y_񥯽Mdޖ MĻiR,rrybqsѓ9w5^CpN4) 3@QS#zB@Pp}/3z^~dHs͗q| !NXW#M`3;;/872Brf"sC.ln. ᓼ{JJ#DqB7^JcHɸlzR֢=GzZ*Txti'Op~.V y&oC\I|4osO~5!Gψ}8_HCIjjCqVvS$v>seqLENYb˦.P5c kySuhy:8;Ӫy{h 1Ϛ~Y =ySս˭S{*kĆm"8v " dQ Na|+^X}/ ЎȎouI IN\4nDcnd#yvow_k @ ;$m|?#[[_q `PWig`|( 5ot ͫ~<ۑБD"Jh%/5Ǐ&5x[|\(FCȷ9[z(?\MjPmܻq5AW^=ݿ|vS-H?OwHmx]}6vvvY\[ͦMӷߧr*k&>X(`g~V!?'VWJIU"cb] ͋S6#7k?!6yNd }E% 5_P?[*տGjwZiJM y$<$%R\b\{͔Kxe1p)jaӺzt?$[h58/ Nҫgaaa RU ÉZkj*E;XFpc֖~."l{q"LOb빣3+ EAU54M]v!j.!:Sfu>U Qͦ-"B*-!鉳<ʼ熐&.EeG=TU[vzD3+ˬ. 2SYjlTU]0BU@"}'vrh n$\V+v̴彠 B_݁Gut]5+W0X^%(tI(:sfȤ&]Syyi gf xFf_u!zie}Nkvp%+PU znV_ K@6:x:4UuS"<6m^9. ==oӛmZ%cc 27žMcZ9 C%QKˤjec­ӥy}CОLlm*P~hPvua*8iscaisPY&;\h;mင9pm8 eIX<7^XF @$X(Y2 f>0{U3IN0:#/l*a7P.Ybrj%tO8~1T]``hldAUUKpUxP000dH*ZUbA&N*lE/DoYYbdӌE*ć{J`Mg#. #'?}ݩgh⾍-d`4y\pr.F@K*b2q jEsf\۴Vbrsͬ]ՊG+M˫TC}LgEo>8t`]++[C |K 1z:L;YS$2:@BwTCH$6xݐ8մ4 R6Κ0zd CWti A6:[kXeAOG4Fu4Rp…,=OD.V6Q,eU(F` {5H(9}XFWؖ\!IiϿOE߁.{(cbrB wU alJ9+5=DD_u1ӓOKjc'ϓUTQ0>< TaL_/"Xi4S m%}2}鮶1:0NUJcH*KAרok0 wS5.s7_zD; ,wt>LMuUd`lWKs؃:ycHg7 ,>McMTdžMҲ FSwQ.WtZ@2ֲze~܀. &/bU57?:m(N[m5]+3&wOR-p'RW@ЭaL Qp4zI㡳rw72:$b"fs`ݺ N(75L2\JP_ޗɥF&GH7~-C!tG]+yl( 2P$ bIΞ8Ʊӣ~7O^1DNsGudAo}"or(Nƨjeź{`rsr4ẃ8^zk79bwxVq zR k|IJnK(B2xE/36+">oPUJQ^Η~Ƨ;.W:94^.7?|= 3v8( 0ͻ/>Ɉ[3xf5B;}NLp]dF|b AvDS;__~DE ___?zL]o÷ Dqw{S.$ di(4{T_Wyyl $g>2%\l|k}jd^waxշ9=9U=!0-Du fE/ޗ"F6P_D#o?2TГy=N(JL? &򌟼.QbWe+>qɣ/'|IJ Ϥ fzyoqN10BKNPT UP '17}q4wbJrirkB) d;pv$z~/ǥ2{ьqm]$GN֎%Lw6?ydu T"LT EU1Sc/'|*LOw^&x_' ' T"gwoĤnG+Lҷ͞N=v cEZ1Ņ2쟒TH$J$ɕɕ]0.)`ػ%9vn/}eF2'ѕ276)8oH7uǸKsTQLQ4|g+/3YMJD.K XzA!ڝHps=drG]/ʈinM{=7_pז8I=ş~|?| l!_^ԜԶwc BhZj$OeX[:H/qdy>vGMV1SO=K3y=a#Ou*YoUHKss-`'y!t]A\?;:WMR\g^[٫ŋ0 <ʱsAzj[;Țdv=Q~U?3}uG[ ^^ź9f[+ 0MJV)r&9"G{6w '<n_~b5MM5G}li~Fw_xd0vvrY&Jq{?V<6Go}EZ_Deݫ%WI+o[ ܫg+Oމ0+?IUAP؏Q*W3gcG\͚-il 1g'TO{C5椾aLu5g㉒B?//h.Z.ӗw"CVUɓxmI):J6/;|S8v.0Ow,]bl>o 7wO9r3_jPUq=W"g!p]khTwa8cegm *sO0ԑK(b0{1`},QhƘ$%zS7PaW^DIYLwӶv]iJXz. qNt *!~):&}=4 N\'֓YS 74cl>*lwO;1+4..'AVh"99?w#c3o61@)95;B[)zY+gMJ+ʅRƐhԴ5Ixx=ƪ? o<غ}Kƍ. .ghdbQb!N_)d/3 jt&尷B1<$!n^8aC+dHٷRahN**H٧qh0I߉ӜpmhD7 Դj/w"}#KR Նi ?LCh>{%mM]ϿS,O݅-O T\n/|^g%j4!IFB΅v~wяDSMյTk6J"byU7׿ϟE|<V#} xvH7A1:y E?_4 6v 9+",{4P1lG41Lu9N}x~NjR[Uc@4X_+b OOҢ:'zPs[?F]uռ>Ύgi<|e Qpx|x=.|n M 5u K:ZU=;|Mr|hie*yu7o}|럨onAyElo=JRPIca/T B,S#9n5ۋm7gy^$5Ryˣ(*Rϑ+tXuO0M)n.M+'0+!,<K?i M`KSQ?#瞠fʺT'ϰ7?+s4|>㲣bPYSGOd 0fO4E` ·Ϙ釷) )̴YB0#ˡѡk%w7۽>.7%ӆfj~뾷shǃNcaaaaG+XI}C\D8t(J< P0ͩI>I>OO}_qwcb,/QTѡ !bLjļ]4JL`#T fCgW'rn3q슟7!غǶP;gї9d]:*3~0[ 5V"Rb M߿Fc|Krb Gzx8tzQ.@'ː%3•W_3Id`藄R6v(͵_L(˯<ƉΗWIʲ\,>8\B10LQHsh'<`4 yr3NRw Oo󛏭+<㹥FlI_yVk NR(.08]OBdLeJcKb . غD@JE.(3Be;~G_d9LY6|W;4.]!K|wޮCDsW$ ;KD@1T"KS^W_ NE KӥRD*7ƅrnLpjq̌r^§>Daǟb]xOqy S!Ij>9RM/t&% zS3>*RJpoD F906ꦭJOw^?OֻXVCS϶M3]O(ɫ|H b"-dC!($&8@Q@J;PIeU 5T5rfxwMēF\9^|u?\(ecDRyPTLyL0u"*A/:ihnB+{4ɥdinԒ H=;HY$h kaSSoXwǝt #1c#MSi+N2%J3QkSL$&DP3Cͷ&};qJU[w/):c[r.lGJCkBLkچOGy^2~z] ^#O<ũ/ſbTUo3??:{: ;xj?BPټ!^xy.LDgJT:HT*E$¬S$R$&.p ;jY32O6UՎc-z6tD1dJ\A<!0>6NjF)& );MPhHұ(t _$F.Ⱥ-BU&Z:kA?N$' G)z΍v}N8Oa]zDx2+Dh4F2 Or`0ǚP!Vnn,Ɉ]SE5EGP<?~/ݗLpזJkѽrO?|b,[%[2\˺JzwŨu994ۘ$ 61A2[e,Fs}̨~B5TL {4J*-;ODݬoSRl^٣1kEP#{^1y➵*L݅O5{AAUL*K 5>NsWY]ɱ67PYӄ#%N)^;@޺` ?\36;w톮Fjb$2 EZ'95i *hyk֬ŮXj++k=K:lխ?qMfu-]{Y:D,#Md0jQ4XLi+FIRDItCk/^u f.Ts葍ll]̚ T:~V^29>I.&>5M*߆WY5uұi"XXpmU䲞;4Th$A,=9~6ٽǨ0E~4 k1w xprdh4Q'0~wgGN*ijAIsv"7"\O]U+Y5n .i$:x`uuA $}c(udr8*[ضu5~V6mEL^Rrp;ԵwcӘ}AB.857% tZSMCk- b im4=pAj ofUj痢‰QL~ӏ"Dc}-"5NXGJ2c Q4ЃwPV&l!гqΟj}viG9Å [Q&llQC*FD 7[`US᧹QÅ"@}C#n31l/մVg `8*hikQݺjjjnR([MsLC_A}sA[K*pJb4ΊZ+5G0n**hh" ; ]lߴJbt u/w?|?f.yTY݊ȓ3l4ZڎZ9J\OF*T`MagIp 5^}L5|Yz"W)wwwyWy}1z; 182n-޵mi "=7ꠇ:*@ KY.Q}Cx!꫃T^I.+J z/ }T*il)zcӮ5~It:~ ߳C . ޟɟ\"Oڷ),9{-35oORVH//,?oly_),k}c M1saW(\}(0x/n=,y.L|"rfdOVb[]~s{fsGy̓</6W/=WGfƦ\.2꼘/ŌlwNwYtif|ыKq{%b/ׅCӥH3inŮ@1[ϱ??v/嬍2>_P7Ӆr'Hd/GQ=W,,,,,>[ \ -uKibx41^P@w,e҂K)/ܲs,^^TH%u\^ 0&Ngv7~3Fe&/f5\)\QUޫ3hg]V8meE?Eᄉf]b#v'$dlZbl@.%_2tae4 Uo*3/ũ"]wϖ[@F] SYA_j` %qC{,,,,,,~VL0EAU[}YLYwbX=]?+HYN)ʼ>zˀ^haaaaaaaaaaaq . [etYXXXXXXXXXXXB,b]貰XF-:!E(KzӢC"KOmK+HX,,,,> XF2#`/)O\0W0dm' GJB4%R `~=4[nCQnm"iJ!P)-wK))tLsi7i*6miGP*-nv}( :rNgȏ/=dt)rI\ɕߥIOriޖؼaL&)W-iWU4xtǏi κuشy-(\.Goo/LUW 0!BgϐLtn]400Ll򛺡S[S{SFPf]@e9-1sQU)[@hqRL CRuZ;Bx!!@uedY ݸe.&N30d P,H 莳5HG<(LIEEÃUܞ2D4` Ι8I-N,3C z<4Gcs εiLMNp= y+ xnX:|NwWײ" W"e FG"v'>?ZXXXrFsα;!*ǎ6d'|V//EQ&&&xWjDnRO>nj!" RSS3g :;;1MEQ8<`cM7e!d2[LLN)ZÏҲd+… hhl`eJENUΞ;˅ زu]`&:yfQU_5kײqF}YJbsaVƳ_P6E5 A)"O#kOTmތr-eJ) $?P,d|1M]_˃02eWOh8p4\QH(XSA!0tܞJܞмgmƳ<XÎ]S%9%.3,e`U#)qU$M(N?Ҕ @` U c&ԉ&s7DPYӈD kd]bR,TkP]ВM;~]B GG1-Ç0&&4JsCU(rx>yĶ;ʞ0 [Β mvMMMW\WUq 'c2>>>7'OܲzJ%Μ9êU+ %wyH$BK[Qimk0B*td2ySeY__t^ロm۶v9vw~睬^ ̭/YyE)9;Y)P]Ŷ/=5Юkt~czPLeKuҷ8uyX~мWtCgbɠƉ x4 }l6w)&i[Bt W~-e-,΢tc}1aDM NBUvR`kgKwؖfK@IP”4)t(AE@PB3V(+]SKMUudAGJCd͗0(e߫IX"[б+%$Eb-"R^%V?B q|g7^,$f6!ӅqjhaaaqXZ" y1 lx\.7y׵o}{/| ]nIu}vҕzu===MMM7RUܼ͛(?~|d-h/aA'Ns1\.wq8N;6Ʒzj{_zw޹Y 74 h]ZWh"APXo ,)}W(|TT32:Nm=?LxmmƋ %H#LfJhV63Es-U7\R1?&eUg$R:OEFi*6\GcCL159ڟ"Q2%.DyhC5%A2eMA<Aq{ 3[NB0 d9S+P<>J(biENOj38!0u4T&0_Cu%,  Y-d/0gxeY~H>'p`⽮`]sX0 1oEJ~VsI.'յ7a⍟KbLټy\ٳg/㬱zj:::#ܱ}MeP(O/Mn9LitjjkXrJ%2itE(%ٽ_s5fI }r zZ.ҕ7o P,^!*5^::@!T8:hBQճ۱OMֱjԻRW4][5u4V&f5n J;oB6JDÓBW#俉1 ^mUD( =F0@p@'+u׾T*6pؖ0>K :]~JA.z-4TTk3Tm>O! G@,l Q6p8S.g\.0:LZB\M)橞a Ǐۇ_YXXXX\e7l@`^f9xYٹ6,*Lm1!ظi}5Eap,[JIP ̅9chG,ɤ3PO0!k֬%J7+_ -msJ2#ˡjڂIRbBl6m>TaK%%ALO3y e3ijr%PiJJl^nwr4UXΩ4ˎnAja*T]^6LCR,f0Mͅf[}/i%R Fz^ 9AUMc4lic (F΄C ˢQD@.q+î  gC9oR/J<4lEaGJ"~Yd?UOSQYR D`#hUznjV6gwgYѹy)Dj)Ke+9cqj7l@k9k#wn3!ώ$?Q4d(Id&QÃ]]BvYgd˿K/eO_*3cz&!O컀L&4ht]o2D}nFK ŰFatw?xU孷"ܔaGQm_uz9szYzKY盛8Me\Y/|.5TU}eRJ.>wbH.^-\.6l8S&.NvB}yJgŢ:l5;םDkv;6xt'#;P`W@RJ?S(BL(>H_wQawcSd1v35v @ -FQn,r>CD+ȅr[9SVpEH ĩJZx]%$U!8P-#d2ԶI-mF32j}g!&z84j*@h {M!)&*(&+KҵKDPUu&kb&D"E( ^:8yENPnH=l׽H]偖?ckSP0'&{e^4~wMl6X׎uj<۶8Sd&CHpKZW{5#A(o[^hoinn0wCn f^Cuu5_ZUJ sykiR]]Muuu?'?MH) BLOOM__\2]יFUU0RJ&&&p:<㋾i:|{Quv }޳(OۂIdg '!QKFJO础4ɤM՝CJӵlEayf6:@˗uiN7w qwQWPɦOq1tשm A2>J:~P^4g{NfCSivL( abiT_υMjbwiYF/|l69F&O0rluCosGTVCD8qMw+ 3v Ɔ𫄂Y?[8vt4}=Sː5TzHqAs؉ˮ޴^JI4pѣG1 }cccLLLNYjBu0L)J۱1&''g<]3ijIܫqzglu@0Ij &y#!JrnRZEOꚲ}{?g?p:py~'[ۃh<]-!N`&>5A'$JtUQ$R:$5[qkHD`W=r5 )l|2 Mc*Z[SG 4W?ZW<{ Dr!eVM 0(2.f*Y@K@ &m5^6&=Or (vX,FTb``H$B{{;ׯqHĨ N9~T*aEnD3FWoo&PGI&J'&峅q0o4@(mxm(MMFB]w_ t? G%V3wĢng B/ -g PK#D<@tX[ft-;LDznyQ~ B)%dݨJI/afҙ,>PI͆iTVVέ !hllDul64po55$oX^=޳st7i%m}Im*Fϐ孁Eyy}rE&r44n-LMO-wel@xou6\({LLq5o+8C;Hf]*S4=,C  k1>$$ fzoY9Dv=KWWCC47ʊeg_hM6ieާOJI8c?ƩSZ5{n ]ԗ')ٵk'k׮駟;y֠mllGرceP'z9{V1MD"ԁAHh+$gZPs=^3{MӜ !0 N'7ofppi֮];-,dӦMp9R^ʂ}B֟o1_s\1^&_7v-L$Mݜwv*nNN'2qnʺ&aA;68^lBp*n*& 7XF ٹs'W7h C-zҰ&p:l޼.<(=0\޶Ѣp^;Cax TUy{{"nk~8YnW30U]y0>zA)&"pAۊ-Q̕L'On)93^*!Οݍ"r?ngllPսh0s r"QUk 26l>7p/M S YN~z\h?uDsǃ7ٛMs3CZl`t|q1 4M&ja|tvZ4[ _~_#G*n}׉xE2&Dn 黯BW%qǙ7|G}x4&r'?obJ{z⭭SSÙ; b&6_eBJQq#烪*Bu5~l`aaaax~:g̷=WvdRRU]ux種ajjq\rQFFgB+p,cP/n?Z&ϳf͚l߾g};3>8御^\*`d E(4Wr4Ԛ|A" B|6HOt-ἢː(at(j#(*YFv( \Wn?ñ{+빒$6HZl?Um֭Dѹp$4ط/F{GUUUA-$Oٽ{7LLL~&&&R)ϱr9C3>~ )}lvñ hD?E9 LOE(v;U+ѼE{N~@NK͖+hLv)qBU7.w!̧pO.0$*ܘJyoʣ BL zp2,,,,nK3D9bh*7'%AQ%ziEAUչ ڪzU^sO| Bޤtw n{.'"ʹ`aw^vO<$p-/{?H￟D"A6eH)9~8ap}!ĉH)yD"aÆe+t:TQ17萢0<2+|[ti0w4ё8p>L"7n .d4 6ϱww9w,4#WSW߉vjlJz=o`܆qY7g+k}݄uDƎ/0=oXz++>9y亓znYQ$Klt: mP Jq8 111A]]~sxix>NuU ]73g̅E"x $@%L&ٵkREKu::th8xPE9suSy/FM ;^~GyknX4q_ mm{lS4@4Z1Z;?&lXP Es3Q)%O=4x&+hjjn+axK}h/dŊ$ɹךk544}4sEeZƚ5k%J_|p>646obJeoΞ={L&)ٳ6vI.1<O9G) Eņ{qsvPY=< . "OEs7y,K*LͰ_/abޙR.&t6K*Q p8}8c!2J466~trvRi\3RQQ&NihhdʕYi⺆R:gaԩlHTzӦE7і2V<TQs"gV$biH)b ~?"[,#"AG !ĜL&f2x|>`ŲD_RRx5f~:ڨlʙzYXXXXjtY -,n#BBТV YoO)%>?wlۡ4CZŇ貰XƔ26<:vqs,,,,,,,,,,,,,etYXXXXXXXXXXXB,b]貰XF-2,,,,,,,,,,,,n!:k1ZXXXXXXXXX|T̴\2Mx"ATjaq(J4v.<PKH)XiEN] ) 8bч h6nkv [5.!x]7ptY-,nRIf}HBf1MkaR)] ʫD`]`чUU UV>Xp]OWPA! ΐΤB,Y~ BP)\[XmjaP( a-Ykt RZS # 8P.< X51̶ify,Se.$jĒmdQ4,,,,>J0>0Thq}/`M?ӄn)`f't~6fs9rHK)x>ہC7cJ% àX, aG .  AbRKQMӐRZ2?],fێ@a׻맧ɤ8B>?H)bdH$9OePx[zߖK'oh X54RRG%fƍtt `5h[,EU41o> kNQvex&PP*lH8T$ؔM 781Rм8N$PM α xN,DduW?x*x-4TmޣYEAUUb]%!嬛WW1?OaDH&di dBccc I%S76RSSsJ(g $t C8.HrEB->:,5;Hyzzz8xCCRQQ/j]͛7S]]}%?;`b!> GI;Qu!!( 3k>tF{ors B,giJ!TTJy+ 39Ba$q(!IUbS<8ЋqѻaQF7%gNj$J4C'WHcpUElD9gl֐"bbIedv f.sD1Ν:l/|lA5M]Q)%BiFFFp\`]v}r8!BHc蝐t]YHpuUy>ۧD"Bw}7~&&x~pGajjRi/^69?~ $[{pOnDR[! zi(LHS{ysa>Óo߳&Y0qǧNbϞ$S)-q:LLLpq}{]֮]]wCC}=v(xg/buYt#ܙL&򘊃4WHfI!Ξchtd\N kZ7&[#;η_$m{ E!yQ,\#pЙ֍ѵ;xIGMa=O,AcMPG'̀"xC/v:/pJMQ&i_]HIzk}Qwkt~6׃.Hm5PPA@4]`l:l286a[MDR%욂ߥ]3!{^y Q09E ;)T/as7"K?z| ]L^%>2Mi}]'HյO|?HDFh39z6n^_Cs'xpЊ6|z@OOo[h~ SSDQ:;;y衇DAX ( 0oB8B5h/ S')Y\$6D?Ŝ=t%]gzY^le&QXgapF Bl޼\.o͛o99_y?ίꯡi/ĩON#ݨ,o1E)qz oo?a{m@yxg_?JŚy ]$'/K/ѓ_KڿFz*Qnc\b X0iteJ:bf+yiniB#ki_T(g9B I=`bZ,cE @ m4eDWP YXƠ>с]+xRptɋb/:92aSq*ud)OS=[WR[$ڻޏ&xj)ɞ cv8'Μù Î s[u3gΐfqݴt:Rp8n<ƋcÃC!>fGijly/tA@O~ ފBǙ$wߍE̤3t^\Lo(ѧz'b1FGGlkO2|ropH]1f3!N"jpSXF*cEK"\GeuFgY<]BQln^v-sb  F l_y={VR|$r].ey/ټ2N=AKyr00N`F9ffP&W@=aw9c) ^c-^nHʱۚW YdbpL؜}^RܔddBQVQLF?3<>z1ݶOőCJT.ÌfꝟX5c^(_'쵚 PK36ǚ ꅢ w+vu ާ!.ya/|AX|6wMIɠ 炞R'.\.ۍĩIp6S^i 3aD$妜&\xĂ ּ י 3:7yվs]on/@`6PtX5m+8 ˵ `5!c%,e~i0|ÅOTpMf6o@$R^O6paq8+ en1EZPٳ{xŌn aoo>4 T]3<+ɂ[gLdrrd" 3SSSizٵRJBs/DX4J5wII;&ǁN;)T.ٝmrKJ3o{B`>⾨3dĘ-Õ=7w,,>,,U__GG x N碯K&8̆A(pʍ<]o|l)! `t|dN QdzlHSDmUcSJ&K}C>4t1bu< z'-lhA`LNİW㓌NQմ6ᵫI}`|Zŧn."2>6E^X^rI<.LdH*PAI>e|2Fۉ 1a9ƞ\M4V8Hǧ'W\$LTT.%e*Njk/&oOBl6ccc 144ϥrQhmm[dqqWǙ;c8d;5)M"gصֵ9߷y±^׊>~g_xi݉KtG5MU]B$R񊡯6НwRT]q74Q,d*wpkyӇ) 8(u /!0 )NI̳- (zKmR}Y~I*Q/&x]&=yÉ}aRZ% aIdCQg߾UMy6HMsn?|oc' N}9E~iEmu%^0 2q?@QKāww3Z(FK47Vad[ATBJyyAAFW̓}L.Ei76?n7)]5܀8fx[GHǎQ,İjѴa2sSc9M_< =gQE~4+Ww(R3ǎ1/b9̘NK{8 ѳGwfP]d^~kςa$[h`b|wAOsDF1#tvDujLJ׵X,^qMd[tAcSɱ+;\tHH4`@W~cBb#XqZèB;K=ώs1C6F1F`i^e')G -U$_{w!c9w^FsC)>;;Ɓd0뢥GcS[F.p?/)5qz9v'OrUئٻ\N"):}T|k&p:W\BNUV΅ :n7ht:M,ݎnfp8$ rOw4ig8k*;Hs99Hespt)"ͮq'W"]f:/dhuxh;<aqNibZk6oLyy9cllիWd8vj*dYfq}_$HL0&k:[;jrҸN`&K$>DZVDE45 ^~}+hqMs>br*|6Ԍ 8`؃SNiU/aIJϟg q5kngo@N^3.jB*9/ž/yXlg?kiFamnDVD,!|&52Q$e8]~7l%~R3>{-)Ę X\m00;Yݼ da u[RҐ$*\W_Ϛix^JJJxweKH$HsY?R MgY#_{a-~ gڸ{\6=.cFMp0>M;h*wbwI:md.2ޒ*ʼr'B-9Affno^Faf&drRUWϚ`Ͷ[YY@SUD"ӤhQ>OE}  B26C8>l[T0]{@!¨2!lV,h"N'>,%%%z뭔3 %%%yDyv9dxNʚE,iYce3>SX,y).BSad4J4{! -C:=44aDa0gakdQ$3Ee`ER4d *=>A !U,`27sC3[)sL^YIF<~n_͂L&Hϳ;vfOU(y+|iS f\?Q|EsOY!RWN֏J/2Z]x|C2Y<招e㗾aE!$\x93-[fNѕ(<@-YJzz"ryx&L&K6]dJnDfZ595-u:),"vyqyLJ,'`U|\zjk : {XVĝ3} &CIXncT^p u 2[J6DFnu369Kpfk% y~K1i*qx6^vR ٻ-ǧ)w=۩tIy}Yu` .,& x,g|<$7~+kHOt1fWĞ de o?7s%S\M(u-?TO*Q[HhV"b͍(A V5pÝ8 Z&.v.^ EX dtj%] Ðl!>~c"TW ٬B~}mK)xp[m=^v ḃu0jݟIDAT)XHēj.(]-7‚&r~ڿǟJq[XTx!s6lhm`.G9'6\PvlTȒ,2(]HFÎRBIaNf[0M  !xnl6׃,XJ$jb>~io UsY> u1(3I9ߊ$))*Lݱ_*ow]YRfV^HhӧOn: ?R &H wks*xҙn&2~fJmY>q * [Y$g}zn 8.l7E%|~4EESv"_؝.fCnbmZ[n]1΍IK~ŹM~:dEU1 DazhXԄAUU***(--hkkl^hA"0Օ $lV3t)_oVԲd{A~ws%_nÊQ2R\RiECMN9Ţf"_BF<)*TE`;pykYBNMa[o[Em§p@\!bY.J$Is+gNERCz[|-~ۿ-T?d4;2M0Z^33ʭ% J:IBQ|G6d:CZDtCZf=w ID4 M{lpvn@Ɇ;=@Z2U+nq 3}S6Tc%6w9ͫP^J*@2jr#{?dϑvBIGA:b,7̮Gz j?.{.j!Al-hj YfW|RRY"M(\ĂBc"s;+i`rxs=2dِ51{}6ZfWY=|/sHV9-kHME%#1js2h.4J063CFXaz6o=qr(i}~9+cd\%+8F06!f-HM}qLSx/nsc-y|M!5C#=C(=K#'9b(ޯEI^}q^MV;΄F:#a&a78SjxmO˟?ŁɋS?wbnvzAFGG)//1000}}ueД %ew{֢L7 I1Me rGfHƹcp^ ͵vq+PIEɨ$!$ o_̙x/:X8t>g΅ureYhɺɠ,b韈/ %LX@a8+eY"MIe gmv>R)Y)7$)&D5^%BcEmuN1}YN^MI26{d bq# ltCm V%3(r&fzeg#W"!$4Rēx&E Y1'JjsS f~oo/ɓbQ2PNMS܁)ty$NG0jp6`! ^")o: ζJxbeX^I*\T$HYDEq;1+C# MIJ"GRS ' fB83^\ma0RXTL1u#{)$,Z'(I14764M[GwGǡه#w(KV/1S8í1=q͵9FClpW{3q7- Mhws|6N#]? \2wH&UIOe/q,Xw~zm}d@A0Dy揶%>w]F%p vh'l}ɐJ+xHqt~,JOsk"ΒKf..Y|F.1d3G93+d 7>z~zGct9eEz=sĒ$1::kFuu5> ---,Z6ni,BZmlZGr]bnn;K*@ؼT:4'{G%c .?^MTG01|l$4 TnJȪ s !SX^TIM'Hem.b^i#ܡ*hE),+VVߍ~-/4ֱ/(w nǯdױElY\HwVLA9>Fs|'L4k!ljdU0*)"D4Fqy Ɏtq)dN!uI!zZ%xyąŚna_.Ȧ E;~#CSx1E] k?RyyΛ/a1H"|ƫ 1Wameq&DtX/bH;NRS蠰67q..!OQٲ*:y/-͙ʨ))beMYy-K1%8xrbytrH4N$$KcM#&ijVƖxJ}DBJ>NцU|ԷTS\SQ>EIE'((wۃlM[ bFʪb >{#,k1`Z$b,QF3s/x7;lng y)D;]QrLn|8(gNSn=K:֭^{^&25PS%I&5,ՄJK&IF2ƻ2a_²3:"lX_'C*Wr  +((,QmX~ r0y=&.GI3L ar*JWG$D$)"8fDK%$c1RY,LH%b ǒU7%^ziFVPld'-ls xcU,rl?[6 R3 b$jJ~ >'0GME9ZpchHAqe^<4c3X J,v2qAn޶"|\C*ei}jd6[AME9bpTA&N.xpV|R*\0ΩnGF]Mkz}TS :,ǖNb/؋_qQSHL`ljeAc <$x7yo[ڻSZ]CEE- af>F4m-Kq2 um$f[%d5I_  CUU9b7-kH26:ӲRth ]u3kqxW^xޚ&;@!re %395E 0h;H ݎ溌)L#2.L m ci6 !!MdqVP`sdiRN;r&TGe-&:*FB1DE]=%nҡQ:H8Eؙo*d1Cg7, [Zd[VMMx0@8QXYǂ",RсzFHJXn>v.'jLH$ek#)28`)W F5چV'&b&Bf ZT:ꤴ_a) 1s`Ҹd!^Oq5 JFc:eyfZjjn"Iee3tuČg#0CLقBu dj:lpB ]f NPմB $$cs..hGGD&X,.6NPZRa w jҐXn"X1-x Gz "@(9x,Bdw) 0X|%t,X>* G#Y( t?2_Ȇa::5 SrRZSG@h*@\3SY'Sd%3_aVL&0EVUǕF"|>1Ҭa0jbXzLLL)..&O$P6;X 14:tkiV/cd e5 (uXZJI$e' Pc8)*t3WUQVzKI )*OH<0B8I+fw`$ET7ꢴoA!u *1a"R`7g`XR齢H$"0Xn񤮮nN@n߾ b q# ^$nZ~F& կ`]K-V$a* Lv0"mPCwGIoa9ui jՖb5WS教f& b6E^<7V"/$ * x}.<^\Vc=팆4db >jLN.^i➽P L0< zY,]-x~__qF/>}Glft]6<&M>܄slOx{,oϿŮ{c/]Y/=,D dd+`^RK|3 3gt\M9SN}ez7ϒ|߽{)FM= Rrz?0H4bhTU!0ފ(si+D&kgPVjk\O8?L+?RoqJPK">x5ƕQUqP!Ny@UeW `(BDҵ/|_劺d_P\/W56EQDs;(cm u>hnZ5$b(Ox&owy5uN_|cj> =TFYT3yzzT*5sɓ'\(=CMM Lx<+?˕Eed6 ţfWșza]0Kt;\U^dn4ͳ._{E4 5MG:o3#0zQ|u.τv;(1hHH%$Ab3Ů]Um] d`ALu I/ Wϭ; _Ëx|/4 _a-VG'(;P536g%^ZلCwYx?a+W)șO~6)dVP?~o)f !Ri YK}uNu B`X0 ss)))Ux~qD܈/w%Ǘ F0T/g*dMa& u7}3opqUW"q" ;(oweRY2܏}p/4Mb-eHB0<#2 a;P)&ƺSԄpA4t F}ӽ.:v EQ2Q&'nb~8wb.IpTUUa6X,(ܫs]$Zҩ vbff+Vz$ Ӆ5oީ( ݻ^\n7%}̒|R|lKUUΜ9M,#> ]UǏ曱lϕtnL _ѷ8?\Hee9lݼB9)vQXҀYDW`ppY++.DQV'OҦ2}*/eO7jVoz;w.#cجfll6K{pz+\&ƻ;I`HqvJ*}J7Y3Y%k.S5icpL&CpfӧO… s;X&x!zzzr)-+#S4.>]cccLNN^`7!_&FZ )}sM͒JȪ &Fy?q4,Xxuޕf=gBUwc\>p.rVQA \"uEP2&FO09vl:W2O]>|\ MY$!#Hp]-W58ЏÓp~g(*>ѹR2dxh($#H(9Oݎf¢"]>]:OWii)|tv .O>h ،`Ta0/WXyg!0Mi+)._deӼ::PI[#HHM\{q/(*='i jjk ΐL$D"$ $ap:]X,|~?&IWtt>\& 6ɺeuE$ />șZ}LMp8+4Qu>Yftfd2腹t FYQUUo Y }SGGGGGs}bi\E>_GG皸 K\M /$O>ǎ,nL{Q(+*]lUodt|j*T.o,! t:YE\{Ȓ F7&HDOsMhh^9U4MHw D4 )z GVeg7bE&7&zxqC%q;]6MFbZZu1tttttttttn@ya&o|hy&:7[?h}~,UqYKT lt[:::)S#O!Dd2-^t>SadIQ3EccTW_BwTUnattt>c јSttt>1dYYEB`0eY:9h$L~NG:::5ȥG@w'}n}>G9k:$IzMLSd50 xAH-rS!d Ij =D$JZqW=&cDS*',&$dlh~Ҕ$g8qr%me s!D' i؉D-ܹ. !a//(5MEQs?%puMӼj= TU\AhCC+*qg1|$#eu8w !P3q"J 2Ҳ2n;8sQa:Ow|E6c4OQu5,gx Lw)Ǎkߺ UY(t|0 `# ɊjB6٩D3!PS3y)~}ɟmDc|  % F bJ qa}?}jᮕB_Թ~A2nfMɢ`0Д ij,@K8s蔑иF:s:|L I Ii?|7S,DnT^bJ!4}yg?㵽llLuy#A+*ʢsB2{xhV+">ODļI,6bmcUnٲYb$ag&0M;Ό^ 4Lbh+_2 ]ްplNj/6E2XLLCo>/_LJ}R0ձ ؖˣliAr j{H(2WWsMN- qz2 1jC >U MѴ~9Qpugi Vpςٿ{01aq oh$Oy_p2av=sa˒r,&h¢r'%%zn=OMo/PYǠy)#+VEq Ó/#* ~eI6`]sǒBƧ0Vمt{yrN[C.ܘQ5~IY2"USc>wo]"iުZ ܨ "L!'Y$E Tv| }YN HRg牗zLOkteLM`Z:v<,)Z<#Fdr֎^' bZ}kL3IW0c##LEal]QcŲHjjy5# /Й[<1M 9^LQd); %-Mp|G?bf_f{KნNssc dbtˮaة.To}8hFa>ia67{`h4t0Nլk(CS HǦ8y(C$*a%+*0xxj+RB_W'@M>ky1vTQ '%iٻDއBRݼnArz6 ;y5+׾+j0k*Dw otfYtmԙFy?`WWĔPk/I$-b!Idt~Kߴ•[F?|k#%VQ[VJқWɻ/%l}ޣIWGo_4<(`>:q#/$^[︋͋Xty_<7qwr2?{ Os*HNoSd,ona*/'ݘ-Vjae}pMa$?F>k9Cfzso2`4gw0O_Sq)Ig?}c*Wo5Uxy^?60Bxø㖕{CHB7`0?Wxek5Z7RZ*̉.Rjn*8[ӃqQ-zyf$?"Oy7q]R̐)Y]1k1wgۯOad _yNlutr} M&dX!$(o<]J)n%%.&J黭T-=LQ_=7Ė3€IDW6EQM5j͍uGD2JTU඙/i͋$%8@/o,œx (Vny DϾyXPt+|HTesr&s;OR%46;TnecS<H& Ӽʛ􅲺V23~}8-qwO lE47V,o.C4~%OYٸm%V~~B)>z y\NĆZ}'0 р>m^$)CǞhOV%e 2Y F;1m:U>;*Kߌ$i~wc6.B3tfJv/^x8nj"Iy[[krмW$KDF)7t MDk`50Zx(MdoKV`5s4р͒ D䶳k(]XK68+Urz^ƴbn^MR)//y~F&51lT/!qpHJE ;HU|edM~-[_G;a&V-Hy=lƄioFΧhbCu3pePuC!|99~NVq߃QUHD9s7j*/AhellX,sy,haFּaj뗲X&Ģ׏1:8F":<g& (pļٲ @6`٘:~\|[uCع%dHzj$gä vLBIf֭C<Γ \MG#k*Z.yi_L8219Q+Y"]$ta~kGWdb>W*`1gNnHlckK{>`*V#77qɴssICM ƦBd Oe! $Lf+bdP!|AB*$n{K|%lwd(;yйhhXii;4 s dw11dUZ:嵽NNƕ|/f]SnesbTί|N2NyMCQE'&2j ̤0{3ky-@dyY^ۃ혛_HpMJ, Ӓ_$K6`6kSƟ]'kdDzr@$F$%3oy7/*y40xd[%{^yWvb&AddY"ek;h;[o$fQ0J%Ń TIW(P˩4u_#Czdüu(ocurm+DT$O_BsHLtgYj#VTUCT2zj2 +XVc=.\T4Mɢer;F,/=3vA1jR=c rXVEI4f{>dߍ G>#øEX,D TEFo:iYhyxU Ӛ2䶻"MhWqϗnfu3UV.Ҕ"L0!#IN0e" (`:$JRe*Zh ʫ;蛊G&NLQ gv̀Vw[MT-hDQ] +kWO.Flmg8E Ff&& E#" F|FhΊ|aA_="d5,HBao9HH6jpoz'"L*A*d:#TEePwgqZ6ok$̒5[OƙQFhk&݋/Y"[k[}vT,TPcqRSl̞:[NJ)9Ѷ~",΢ * ;4{hhZ99wPo_bm?;zǎ;bL0Jңx69;3EUŤxgYd1m˩ QUl^1{! qd{;3Z?#8xI,B|N˼x`;@dDhS9;MݦxfF tw+1H#$n_NPst?G;I(p@ghx'qa=~ ,;ރ Ve8&4e8`Pw!O !D>Hv޷2ZZԐ MWW'}v?uE7w#%Xy}L]̂26vx064r{@څ,*$2pwIE (`o'GD5ESRh;rícY2*KB$$a6/rx)Gcxʨ.+aSQS4=@#tP&ڴA %&OrsfW\ԙN^D``cA9enf JjX\W3F! N)zߙo ϛe&O ^,KSdd@d+k7R2Rh:, XՅ" Pqffӂ4$&̄dU0Xx=N B͕Df;^l$J`jaRLOe4./;X0dSPfB&Ide<8ƹIF m@H`8BZAF6qݹđB<d:*eVbrzppAYLBDžIP⣼K㶙Qq*?TmCͦ IdT$وfPUx8@ Gŀͽ${]ɪڢO Cε1>1{vД4d$.#hF%5?Nd5MxfHRtuّ,4S8ъЏ2BTt`d ~?vJ(0E,k"„S3Ta[nT If0;=zh0 iE0f v \fiCqي*2&,~7c<_3q0 i7LOs95 Pm%ljb2"i& Y"Laذ۬D_”baHF^B]S1L&3bJ%S=lwct:l[XBy\4 [R~ "Aq"+n|J $3ET/3cR5YdՋ)B;+GGGGC]s>j>-g[2⢮i9 /g]e:_(,W}T4U7Mѹjb:%9:+G|֏4T$77jtPhZ.ɷΧG׉Jfd2]f,B*J.B**B:9>\r]RQzm_WC::VŌO.tt7NsNQ糦!Nst ra|dY&S霫o۹:::::::::::|DJv#lokBS(g] -L?q].!,kBg'ѹ& 3tu,_~n6e?|!IYBHW IB/mZY"qx#)dȵtvB I2,!]!RKuq<]MR qL&Wјr5 也Kw,[>AsFk:::::::_ G9#"A% γR3q0N1;d,nD&N"GD.4σA(D;k%0USڼxQ+5a>O`(kfj hBh#LttO/WVg&:Ş {ckXҲ I %S"f32h^\$)PR84 $NYFLd~VC`41sK&9o5 ۡ˦LOGPu Lmm݄U+ ԖI5+]333 F<EQx7z,^*!`cϿ௺yʹL8eE RI9&cv⮪2vJIӅةyDZev,ޥF=4؃:!BH8ar~:UuY:~݇tJK1udm#D0LL17=r+CH):|!du,g H)!Hqrsy*_ʢu$&p_)gx79(Ik%x` jS>OgC_a7|뛰ӓ ^ӳ H\Ch?muNT%?[~qRj)uBD>?'o ,Z,T: uIkwor{1*.!gΜ:;fΝdÆ <#_Fi?5ŦnF}5>qVR ϫ2!@Usɀ$ 8Aij&ѷ䗽>ΗueLGGGGGGD*ĈՎaB;gISUcؗDt,t1{08ZTͭwM["4ѓL„b5YXL߾W?G(OZf2C'p)C Q`\i #tRP a㩨Eմ ׊/e[)v!@ uq')oF~EEXLɷHI%,ҌA# ${w "BSp; 'Œ I")NMqg^{PwtW.`r4?I tf m(E<6U$.\Y!ýxmF'x,worlʒX,JFfj?6dXPPiA0hp8L$!033C0bt:/k^( }ڱ oKP&ع$Yl]/p׿~Jd_= 7bi)D 3'O2l{fr`8G|Gk0yPƗ4B2G ޖW$yc0YG {ivMUє8M`9 >$gY&d#t{-|FМT}~ʫwGL-l/hfqבMK0H|_{%Gɚ(ԌӨ{u}ZhYĺ-t~s/|=Is 474Q09W5[w5q'sN!$#2es N@h)-($T>vܼ ,@Mpz!-ܷmK(rRğؖZ".sLPڵZZZxַE6|;8q .ys!3[ h;~3DB(k^j,cT~E z\Xc}u^y^̢Z'^}nyz^RG }ʹTi CU|ycY`XHdžxxPra ~:::::::+$r6TXO1?nBIj2h=/xf‚"Jˋ Mw6ccUE/S'X{#|c[ ? 6L7:Lo7@#4txu:O0f,AfKUU2 T MHRd2TU%Lf/jxU{_|Wv fTE!"]h9=Ytq (ZV?z;#rn0!Unx.L"[%EuֿEC3Izgn1_Ќ2# 'Pzw$mvy5R{R]WSo r递jo$ce6E**wڌ?z Y9=ΰm%Rq|dCWn_;<{GD,-6ѱ-NJݍK0 HMuvjWmdIΣG:V`dUxKrB ]Ȳ*8P7FVRMZ:d ` B=<N~)n/f!/`dd2v0vJcc#p 蠨X nc 2bq*aAӈL30 QA6QRQ%dt* &;t!&IL/,2)cL㘜b5FI+ťFg (/fLx2* }S@sG?"Y^<߮PIaOvP`"׀)Ka B))#(\.WJ~< )[\$%Hs\<#%.=A򧄦gt?twcY)&YMEb:وZz(+hYPS&tǓ/q?ڢI-~EgDz E2+).,np~_fҤ3Y2FQd_P 錂l4aρ3#TLX]^`(]P`0xE;YTXWfX"<5lc=!*SU^~>;ص(]xzWuD1ѹ\ɲ>z-`1癪t2^GGGGGGGGGGG|d9 7T|J' 5 L!$钻Hg2qA6<=6rrVu}-U%ô6nU#>ans`Ό&[mbuE!ZӇ1May5K*m\l@ILs^S[g?x~2{]nXtgPAx?ഛn;oζ۸;XU)32)N l4b4}Os##PZi oFRP/př>Cģ3_ ]ĝC@j_'ᬣbJ4tkۻw?`h:N2IdG,ne 7-P4HLshaf!J2HgkYgO' /v³;کh^˦5K)r?Hjގ+41Ӄ&BS;yPؼy3\A}u™ft fk?WԆ(ٜ=cͭ0WAh*Ϲc~rS0MCUՋ󛍚bs2@)X h$_ـ,i~ JϹfYB%$QU Y2 j> Q[EeY ?dTE]S' 4J[PEJL7~~} Kl+n'Vg &g>x'?GeB?B9˨ia34 CfomB Kb}YE*]u{W7 v4M`Sn4ħm?áG2r߽P뷢#>LHHFp6.)_D!<99މλSWh͊3x+6Q .44M!$GB%ąۊ)t(2 /fYB!yӘE?Χ&)*1K<5ar\.3=3=99gH)R,Ye^k^wVVDI$r`&癞α R Ja?tU:u/RB~yt}g> c3ՄaFKw.TI|(uc-򣢣kT,WTlv"vmh,h~+?noKcU%7YsK  ]AƤ\%REK X7dԾ;,J1mzal%شCOΐ H[ (^&= /`* "?ꤧH[WPTWK>Oee_8ReGaQ.IQ.2G8WO۱N4iiHtmp/^h H9-C=bl2H݆TzL{R|6Sj#lD8yh&NkN20fr==|+_a?~ YD9;"5S㌇ꏾO^D A*2AkK3"{ǿ?%B !ɹ}O13E73$j0Iqӌ.!d &&'DuX3d<}`ٜ,S^7Ɉ{")_y'w3tL$ffT%nBjgox @pTQ!?:?L8?g?PT"t"'Wx:BJ@Fhɏ ;ְk??D3ʟ0j/~k ]WX>l峟4M_{ɸ5@Os9Jˆ:/7] -K |uL2TղbooAL +L 6v;|f{ǎl_͉e"iZg(wޤi9]RJv;Epؾk5=̫v DB1.IaG-KJmf ƳX;hl```````A@dG=(B;;N2þ~3+~g%R[ m u'o7V:zx-nccj8\cgCʆg^At 7?I$)hRqen$Bz,qF޴E5SNemdP@1cwXQNQE~2F(* E̎tSU\ƹ!"NI%4Ukrs;qK0{ßm%ُyD'єDUMT=y?d!xbZ&I4#|L>;n)MlC4)\ ~M"O0typ]ju**ę@r"jÉK"\~\|<4N;$CQPȤ<+3fsxkJQ UW!HNq &D6.i0!31ZhF]}4mf"d ol)++jE0 ,(@x$@Lcd!t&TV.D3yX~5`R%ýъW9knysd)%z>?z^b<\v $=tw!.C~[4uL}-ji_d'Q7/ǚp`Kk1O;T'X[Wb >HiQ0xN m Bf3lGNҎDfR芓?R&N'XSH֕Xo=ddUP` k) #]Ne0xA2+zWc[R\:_S;<I2 VǫotRd%~ͧt4nn^>SV1qNfxgN*jH]\˻#%r{B5aϪ끔:+ phiM9cƗא9㔁~ݱndh.[aL yz򶌮wb,o+b6aX0]Q*iM.74`1Z-b !4 UU@:K9on% ~6f^(9 JiWV-!71YDxn;03IpfR'i```````! $?TCP>?_ȋcW+zrWO&hZ溥4 #Pp%zj#OkoG;EbŒn('${#~Jpnbfx/EwPR]9}8t/:s !P15u @ND2|H w:vx=iZ{FD" v ]Plޱ:*YD*vj!0rtDLd ] LWY{LJ5B n=dygOt*_CFkښ@*P d:ą6Si5* ~,..|1w|y`sdžLE67yB,%1%`vpy0lB2̑7Or+$jvݾBK 0pTQ]FR,df8,+a"A*:IOw*|y$RKpP*~3`+vMkĢIlcCS&f* 4Bcm8ot.!"ü-cE-.!3LӏsrbWc7y y>f,#_/HxOz _gN)^ui,5^P'˩,-tp)}J C^\я*C 8`K;N2ձ깍hQ͗ ,_ }G{4Bui#Cq+5 .E!&gi~q%h)Fz蝠lFj ̌șKፍI"A%={|AN$NqSP =VSs^R! ,H]nZu{m\ mV;Z瞵d,4{IDAT:PYmR4qWbLjErWIܾ<3R"RLPA&2WŢjl*Hinl>P(ް^8q MMJ6W+1NI;vRTW2\:K粁XJ(BgᗽuK i$.Ԗc3),?)BLD^:?7< ^m,}˷e A W銘((C[gdxR #i 5:ϯ RQ 5[_)MO 26({/b൛bJ TTh&VUSBh;*.pk'cxU&sW#Kƚ=ÐGyy1c׾ d"{G}.&Bq5L//Xx|5Z馴7&#]G*e^b﹟}AL ZxgG6nBTt^! v=DuCA6_KxVD\KcćőH2$x" ѐZt* FMRq-㾭i}s/|C"Oz/?Q҆R]G_?~ڈ%wDžd#$4IEqU=nE*t]{M.լ˿*PJ3f59fb!4B(9]Z2AD$3lxAF)QEڰn6(AYȫod*zL[H-q*W_תD,-xa2b(3#a1IR\ 486\Ć-ۨ/0qi]m. siSzݿ%rmeWU 2Gg)b:4(iϽuKŃ/&uQLv3xj M lKA(޲|۸pPqLeoP+. Yآ$K6cC%mkP|D 7QRTEm~sލO>= S?3,3?`h/Eꖗ Z,b2Hyбx8 +PNb2Oы$CXyԯÄ́;_VTѧӡAL͎QlXTdo`ߛ')n>uZL l%d[;asҵB:ơ3v&qWWJT2>}`ډ%RߣR7BDabE~3b*m7B<.8 (`pmB,'g4Z۱# iFYY653[qžЧx~ MBda*Lw#PLN'݊>.A&FTL2$ZFClX\#!3 7Ievf~rN^bSdn?ͥ‡@؝y8OfVZSwuVMxTM\USGZ$)i[h]BpUlv<6 uIK Rk 200000xXjAbSuO|g('ǐmwSb gQy)%Mk)[kOq:fO -9駼/"JA.<#cĞx, ӴAk71x2f >>Eᝋ(f o8= N(-SH¦ri䆿_j/d׸p?Ws{t:OxRɿnnf{Y~#{'Xm5j&2ѓ}?+J9^3!\<~Xa#K*GM*.h E*BiꦝEJoIU%x˗pŇW]21AB'f'Niob*"K ")"$4S>vNAIBQE0>2%_0k-Gx$WOŞ8] ?q?K] RՒa&PfCJqbGy>vJM$aǦ Dhp;Xp)#!#@ii%L/0[mVbͮȖ4 nRON5OEb`ݽTW~ah'@8ʫP΂Ō_I~sSˌ o_AIRy&0g ]&? R0nXq BleÆ$ҜGoSI'uRY7??֡k$R)T Ԯ3K3ⶆly^?c+p3F8ɷsέ9n|Tm@զUb/!_Fe󾤞&I-d#dR୨v(b6mz&*V-nwxE2r =-h2WMY K۩ MzB{.F"uLy猋:V~6l< @IGhk=Ow IUew-(/>ce,D!"6&V:TKIUNE&h=ux;75a:h "~vJs?ޏyz .v;WC 39fx<"3F&GĠiw57 n߶{ m74[OCsa39s/pv]%xXU)o7>ÿ#` Wb5Xm'kw6 O~< 3qFPYWHeYW &O 6ošW̪5+-rilݸ|Z,!35XcRG糨H.d٢:(ത+R?":FT!ERJ).&e%5{]D6j~RGKpZHivwIE]!Z֟̓$"ABÓNJԅ/ &\yVɊ%+((@2pA;gѺ:ԙ:Nf"( Ō_99NWG1n{,e(YmKyEʊqa0eUzg' 36:Z;o_۬"\u-/\h!knي|7_Jt]s ]z~U-6+af"Prşr\n|d <ԕi9KykސR^=yu]B5pBBخF0000000x]8+(ZW-TJ%U9#L^Z_N UsrxfSE)B5~&wz6{$SղWDFh tRTh#8X.΢g,'_ 7kPq:+KKTU&|ҍ%4 ~Q ~~ߤRBLd{v-=4B`kAarRt%ysֈG"?@ ]Aacw=9qt}>jh\]ET/Յ[lM4rH0r|O%/D0ʨ|53ޡ.M4횆\Ay>ZIMq . $IP[0LdF%o;ztU_ĕ% >(1IE$M%B UX10000000xpE?*)s!nkAk9>i9 [,a{L`"Ĥ̾?_dF\r`{s=_yg.?!Log<wk.Dov2b*˼S8wK! R%ؼeX|?$.;z%EUXXMA \SPZAK%$Os[ӼMƓT{n[Eqgl>C'vczI3e%XdGӊ,cɾ[+LV/y5+Um;wp׽}ܚB?gz~f w R#6FOy MBG'w_$ղ<{.\ -.WxQ)#@0soF.cqwj?OFzo=~ztK׾?N-&/)c^֬n`ij|R(`Ij?d1+jx;h'+UT_Xkr|ٽJ8"L Dߢ%C%TSi/35)F%WR w** 2v$,6^f7΢"E8enby.Qm(yy=s\%~\u^y'Iu61>1b_U+kq^%:H,BA @&8p/z%kTQZM2! X$z-X7?;xF^g*BgaJV\BII-n[qk UF8kYPNE*64Zjvw/SX_RƊwp{c!0ݸn|yA,B(^RIۉ(^|.7ng)eeT.{wS()BMt9]2w1")I&].BeB$|glt( t:Iۂ/ςxPy R|ew?UHJuc2nWi9S!i)s۳M_W+tw T@AE]Ցf%7-7rKGu] s\UTۜ`=w[x? \Et|JG^;Fㇿ7p|>Rx?1;ECsDM1*^ _+^8'ڰˌJIkXO~Hj;:Vw`ta6?~@/aS)w޳ 7 6{of};3ݥ~c#\<Onj*I:Z.p;|o_sZuod;+qYauJׇ]n@D1ݘ 1qR+9WŠ89"Sifo1bSd^&%*N761AA4ƛ@$Ϗ% 5Y~j =o߀szu]SLcވ1SQ&%lZEMXmhCt#@K9$;H~.-ĵ wam ocEOҗHS@4$OFc|4@F yLW']2:Z%'&k>&NIwڲPqv 2<CRB$]$.ɺpZR]S-)Z`=qsTK󈮬h'z/䋟iDA`{09},]skl#lT_hXGxYV >zo֓*;P`+E C]x6F $LTUy![ gqoz+QR!.wvt#s]G9ܓ*OpUn3?GSN3؉NA`~ k}t'ȅ%Y2b] kxÞou]ZV-.t'~4%a200000xOeZUZj\􏵀do':77a&M&@u T X gd1p)LU3r"B2D5( sJ' PC_"yDw^M.[(d~gt \d|Ƣ*=|v5g|8ԹwW eDMQ36p/}Y1&+7BLqRre>%K70iQz&(+R4c٬D^!e<|f? u:tR~ޕ@4lEUlZȑp#R6%H {FE^⬀DB&3}4CKG9m˟EݒoIuMӰ痳D8N>J&2W2.o3e&9~ZH9BQy9EN7%;xtTZC56f\-2b̓L'w:J7Td|muNfEXdRsPL,U:P-VxrNl|a(hܑ:,Pb%vQ܏"<D͕svW%uԢJvI21JrT#i!?S/ 4[f cOr|D,t3# ھnob DrY찠KJ~ 淐ϸE!e%BX2 2s,xłjꈓHgdGlEղ7:&5&7]fLd J6DIpy~]L9ZGٺ̏&ߦ[& ӁYY5]Y_d݆R:tЄjdl)BŕU"[2Ls)O~ ^$ X9{#(wJcQb 9(A&D Rx<}2$V<>3Lh"Ϳ'dPEd ̈{ߙAJLݫ0Y $ɔDAc >n\St]N%Ȥ(:$V 6Ӊ^Ϛ"9F,y/$x/S}h CALU)(0#3 "DqtߒZL)h) AL J$E, ׏ffе9 P`VV39!H2Mdx"\N7CQ*ix#屧o_y-UyԵlw;>1~3o~|S>=[(*,gݢ<&{: d"<66%vQP,A`2B1hXBdbcNJYZ.wtt2xVT^8PBF洓RL,J(AVK1E!P}a=ӡĒ_ ɿ*%1]_Y7/LƙjmErI BuRk;j!Ds}xnzuZd ВIґIFD_[*jw1:_$ M2zb?=P57IfdiE[YȖq#n:d  e4zR>ƿ˷ye2„:h\hXk;@ ZH%&9wEkB:'BA]P-KJT ʏ_DJYykuDhؼ؏xټu+3#}ۨ-_#XTdXhcx(j՜|)^>D0B$89(`ŒL^- LHG'3躠l>^;@0qov^@ L׏D4d*m# ԡ#tǐZ~:Z/r:ۅv_P39Js[ 5J?NDAY1EZ8zɤݞGIY16U[Ròj/#;+wpϖ%8ԌCoi%<dB\:wh,:Z@墥,-`IC9Z:HY},]zlMHmٹMQV&)8 )+.&ߚ\ `uB9z,AAIe HM =*0 n%h;GN Gqz~9!vu(ܴ|ge 6eN8mzu-&Ep-ʇ%x_ݽDnvmRbU񙘼to uWc*WN@NzpP7cN1p0im!,N“0yg#(߾R7 Z ]F`FuWǤqUVaJOhn#7㮭j}~(]G_቗΀Nbr nIS ZyWi9ظr ΙDl(hbuSEUP3q%z}Ksj-p<Jbìq'\ Z2D$ō+Y\(@w ^ns5篤:[TݷcH-:J$8\8{}Ҷ"ܾ^ԓtyӝCHS]bRR]=1ȅN) 5ոuh)%H}7x__uf Lo3``p|l6uo|2$S\T%ZFq3O*u@5sNɖ#D1>BhqBjqƚAen EȫH]CӲc*:TNkYlDڊ"DvN 9=tP蚆p?d &"vZ2r:$'eYWͨ&r뒽\.W @\%JT|6beZIT Y͕[ϦX~¤O֧H- Sy5\޼VSs傓F$b6;'Hd&{iJ;wVOYYmZ]PFϮb\8X eQͩ)u`OG '5$T$L(鳗M˫hg79OpV5s^\W"3˜~M9~~4-KQլ.>F7SIɟi4!*˯4>\u !M[]PdָRr*.0@QMWbNW$D̝ `NdbsUb]_/us n2"޵ptU2s5\jq3ys̍^suTU7 #% *ش*W:l:ã\Ki =zEIV'kN*c= W W|عBu+Z\u\5Մ&20000000000xH.knNg$eM+(lv# ǭpm]׫S?] י_ax6+dW"Ʉav0MWrE\kB*;,o``````````ޒ-oQw캉4~ћ&PŗR2x[L2םoO_bD9m;3>fRsD{zGҼ iK]C(b۝w&sZ]z};_$RWB/W9^uW/:^cpvr}x! a$%%~,fLEe,]TAui>X`QҪj \Z2xa,BjJqĵH!@K2>0@O&7%e Hhina`*MI ,*4GK8#S o"C 6o W/ǟgAv6sk Gq-V4*iTeb85XRox}t^&# *\+ " 1QUSE4cԠep"㧦ҏ]?B4#T,N7eeH{9{pE+YXizD!N@H_@}F8Yf)N3RsZzp7fY./ }2??󝟝%1"ql5'ВyH0wrF#2Ћqy=9+gt-5 S<^:mc2%Mۑyp3)=Ņ}O0Y8bJvã/e,F1T'6"Tn~78r90w^(&#Π"kLsjxǞ=dZ|@D'zc}7"Lf|wDbF9zCy1 S7$A(<3Yf-7M|XTQp \ã22LOd:I]hWbnZz㌟:q-2WK%15E E5H.LJXi+Ζ?U]ej}Ͻ@m[ֱ}fDa~YRB!6̓/Ʒx=7lbν4ϏpDAx{xw0 h%>̎ť):-Y?z+@8"RŎ5sG?jOg=$Nӯֳ}]=>pWIF3|'?џx=8ۗi J-oH Bj\L\$pI4=. RhJFp}t z9ђ{A+q) :O7駱ڍeM+)G8x #Rc/䡇Љ ;vuU &zy0Qr:0),6f "ȧX㩟`,M[XqǺjvtYיZޖ>qߒmm<}??x";O{ +ktK!&'ׯeFd`$#eTk<80!4pEV2xgc4a )\rH'Or|P$ FDP`(`mT4.>烬XUK'ϵ#}xcTb?xqΆ yCwSh"P(.Mv|=K}0t;[ʭ9GdK=3д^X -t28g-U.b=:Z4;ͅcwcJp浧ᳯh woA ` 6}ev&RN39@he|W.BYmc ՂCY7$4ÄD'o@/ RX<`rzo71ZXn l RQYlOz>?OOb嶇ەl0)J ǥ9VOm@D&BsXʖ2۴ =mhZ&o:/&E % JpiCnQ4&;(ȳ6/0 0>n]FU .a@K7A} Źp>(/tHS ]ׯX'ٕGA5)Dw?yoxOmk!Tlzt| 󗏾cx)J&X.-7 ֭t] }_ q=[;?>De֭Q&㵙{(-*epy?`bGNuOe4}Oݏ|{.ŪxJkXT[I?w|-d3RYy7WqoϢ]/hJGhqNyh&tycGp۸j?Ώ%)xʗN16@r/(<[RVR"JT'ܽN#',l!>N:<˷CzLu}{1/[rQz1Y#ncdB2s^&fzG&#tw\f4D1 E e6-PEU0ED&g*fŤ"0!4 V0Yc]9b2HH;)%]> F[:fo-[Ur)/-.TiO$DAi܀PP̈́-:ț[hAW!uȄ@q.\g2_ࠀH7c *Gp_@&.yytpOUeH-Mύ:gR(8<⭄ir!li(ě"!D3B2$b`uꈺZ* \H}k31=i]Sb}hHOJSHEEU`GhH$ʥoMj*.J1hZdEU5ٔyʫSw?3W ('Њ%d(u{">ew|\Z@~k0tsΡ XTiLlaEtCs?S6o}+ʨ\eh[X@]i%S]}lQD4H2dYx]FCJJJ e}2M`2W>5KK MdKE,ãukbsSYb E!=OkGW6|PHs!8JVZ{7~̙4,wսtmyͮVnMC4dRh29CBG;o[3 |[EvS4v})v3®U^T*V }|Pp0B*{\h2RS͏a%%8رg342V:'CjWMNR,LMF E"/ZSp 9&΢JV-mW9ƖWK)~7͝X7~284Hs\ꍳ|ם'J&ɣ :<`SLG9iA"+p$ѩN8™KT76bI0o<ɖ ŕVUPW]Hy^?tqtz+j+Td`xm\WGsoryhJG&L*= Nw)ΓǞIzYXa!h᭓y" =ae[MV)T4t169LguwɪJ/"9Кau9Zg{ ^Ǣ`rx)+/[]f ,EhXBV;EOw7mYnUNj/dJة0j|yEԕJ|j٨E^~u/gzưXUA($37|eNu`iOTp -Zd'W|4n|C(ĩ)Vnl!aj|h| Zv2IFƧHK+>1^BplPŞGIq!  2:6< }͆e````` Bdr|XN7^ ߄R*>S6@dt@ T.i6bp`XŁЋE\'Jh)iɄj@&P꠰mmg31`3SHuv7E8,*TSc#NŲ)7r6'^PBeQ^֓s z{gA <"&˄-$:2 MI)(p_"`"CY}i ]& %2V'>!HVwMddNlfd&h~P.K qY˟"8<M3UHFMjwQ/nK4;:)++zh׳=q.cΆL(J֨2#E˞B(|#>m݋l)٥N\Β?3e;f>>Gn\a]^yMz~sI!8b{u[x-&3lzݧ5kyϞk1000000w\μV~g\@:|{s,ӿ 1kݟN b [Y2!u82΢Mk;-WkX=?2q9z;w~5͵)kȝ󗑿_z_mZW |BDnU M>.xMԑڂ[>&m=?•\h7:\ .S^Âm%t`XaJV!]co hk7Zw.t _. `2lhDU2000000000u"e\nb|mOKTՔnoT:i$)qV~t&C*> JΐVu3 F)>hmee ˞t- @O38DBWift9eНn-ZN̴zdz.;׻pnB dp0c_ʲ$S< xog$/?{ .9CDzV?Y=' 0u_!D$H\,ۏ* 21 R ~q gb8hmYq4I&B4y]c]A:arrP4s\p\v}PP S=vnUN 0e+;vw; $ӈN #dn_T8ʳ9bO=D[=vHsRv޾"@KNqz&T^JPD!`f"4۰k*$]OdJ3>bVTyZ!B⓽>yQ&3zQcmoA?%^L u5@⡮|PⰣEZٲy-Ehב @Op)ƒ lߵ<%=8vq&.¶՘=A׹#\Ja%dVlrM[R3xH?K6n;Ck#OUEHS'n#_]ͅCy\W鉍@JL] ~ Z;,b ܱk~J2AIϩ=<revr5/Ə^9MgewJ8B(`}ś-<F} "ػ֠ku$ID83' EΜ;NK8x`o4F pٟњ,b۹}]o>A\O&$&㭗w!mULxvTˌPȄyWr7rw,~SNQM*S](]w?xrcqbKI.ұL2nۼRy; *UU1Tic&du[N( "}efdBǩ \:Ý~#>sxfEUrs1W(sέӜȺ(:A gLd`````` ё.ZFqy0زq=~->1UcRP敕G{ 5O`I]Y0S|=yC*h)@1xKOy0!ɂ%װdA6c K8qE+6EQc@bszђ=<&嚆bE ƧXp]X)@Z?bX7l>^ihu/;gj8qpg*64$j*):H./·0jcG6/"y蚎"sy,[Ʉ#+.t>"%UDkSQѸt e&EJ#@e7^dgC!u>"Y\ /&;)1vG&NIU-mi(.T|nd>BYNeGz{Mr_M؅@JA^q9=ܺત]rOĔ6-+ۯvwK!vAsyyn[7/;372atxpOH~~͝d4A6>Λo}6A8f2nXf?^ Yb )Ct} D86S'xk gׯ"1)%D ZRt%^ĭ_ u_;YsgYQC&L.&fBL B.ׂ#3j(Hin` iVy!b){.`wx9 OZ1t+E,Zȗ'_./ 3d𳨱572{>n56{&I"#Xx=KQ4FV"+aA9NױfZ>{YV`~2@*2ʮWSYQuk5COg[h;o""dޣu/OP0<@ n<M\b*REQ kMދzɀif1 sNtkd:sf MaFHcwH$6HҐS3F&l SRj-\S+s3W4IIvn5܇((ibkDx-{Hü`)iiZXJfauIϬG $IcYsLhN:!b9mYVtd*}\K4R4c㌍]k||q=>/7fy'9w&_ ni(YȺRzKTqMǪhb6W:6 ͅaAEˍbH-$12&d LׁKWQ>7<<3R1Ƈ/]Hq @QU#^T^ t3>ʁd!@X)oۮ8֋iMavBtp(đ2!~ :b%W E@M8~\~7dD")r zg$ dy y^O(%!0MIs]jR^VFaA*((t*t(1T-~NJScGwnͭ{-`yXr*xwd0]2%zY=6'ލ6|qk7 Y(Z?,z`DCx7S_G&fػM-eH8O0/샇Ncafl{__l:u3"N eF#@& G{)[s ڪc#:63@,%(wr yv $6æW7ӟde^o}Ǩ^ynRS=fz^Vh䉟<̰<hI-]96A&fYz !CA*y%8- 0]nR̟Ewf 2:OD/`~< t;;?2p2 ('8މauo^5|6V w88&0͉~\,*Ax獗9/`Yb ]&'kҼ `xN@@sؕWEQEhdA$D(Puk*{8h҆-13 ?HO|?x'e͒E Ab89Δ[/k0F:86eMst;X\q:XU~rTCl}s1bI(X- $6=F]lvkE\NFd?}cC]e o7ށkj2G_}7Gt.ÞpM2pbi ۅDSNa`~ x+e^RG'qhϊ2'stCL8V<0pYj`u*SdLyװ8TWq(kbfWVp@xJXʒLb33jRR\ǒ&PRTDIT8HڑG]U)E%%Т]ξlۅ~ MY+2W4C#HO1yqnq6&`q#e>ʫLmIϼ%,_\]Σn_y^fJPX*K%ܰ<@Oa9up[hikfт:UV13-TWVPRRB[03UQIeyx^**9-=TW㱩_{(q bz~gKr#TB"BT&Nuq2~D ]λ@r1~r{Ͼk3{ |0ȁ-j=]<19߻D}oN[ϓ#9WO933ѣG4F*mLg?/&ӯ|u+& !|G큅4 ?J d[ο>Sp#hgPgӫqܶm^yovl}hqʪj]'+'M:/0R b:,p^z$dcSl~-dAz; /GmBMqib?]q䕲~~BuAae-uUصW]?/+ffߌ yl~6err[}v$ v8^Ӊ]3MWX΋XK!~@---Ϯs!Rp|uܸa~Ǔy,Yynl/^9ʦ)j M%a,-Ů Hgqfu +h[Flꗃ((!ye OM1FX[;3"2}?sԵEEX4w䝉 y<Ѵ 2<ͨ!"Gxv[=u,#!;Ottsi?"XXM'湭;heW@W&r*a2x-}s?(voӽUX4ăc~~8dVTefSL 'lR %.F>?=r)Dy=:&^xd>Mu@';_ގ9eQv(O&8 ӕB&>ľ)9ΫOH?4ԖI)ݛ<~}xx_2۷oxnZv'Z~z/?,,gv|h徽qU^''8 ı'yw%q{^y[G×5lQ O2ᨡu!׬l%0F:8̮{b#D yF8xC9rlC/&cpCΠ ˉw=,6=\_03nh:%8 6IDAT 03$C]Nv+Vg>eQFFAp Ă ?QW)BB҉]@hfWwAxpt-[ٽ{7YTŅtopdy#nX(ndNndx ^k;<m=Z[8_!:%:%48x< CUM~EKa}6Y3F:L7<48"fv>faסtqqӂZeЊ(||RP^?9ŏ}Go_冚JiAdá4bL(A"e"TdحMIK2yj Dnc ` #C0 %\h҄no"i(SF)NVɓh6'-K<"mXU%%ž͟}2<ϞO|_mYNsmLkg^5PHƙ2 tN0% 6!;xDp,quJ"~@.8fPk.ɤSdS4 ݉E Ru >!s/ rc(YuF zj"lvvM?-OywrBHƏnc8^LK0$q .̶'m8^ >R$өꗹ7nTr; WGIg=tۉ#"#O ^'vWc%//%Rny87inn˿t> RS_u9߶n;&ci oVdBvF$O)t'^+iYWr֛>{Lhjk=KiJn^iok+TeEQEy 3A,p7)sp@jTSZ)2rsͅs3}Zw;\YpGq^)rtl ldɔRJ|&Dh A"DjX4rh QBi v|Js8"J#Vt,UrU{X "aˇbd~#twwMM Aj>sy"#A&b;)4mHĘ,,\RM145C֐ $x"?&13&h ӑ$&~L3A,ŔPTT18F0#ɷKy5%د+*!C8Xnl^/ՊA¡BhHi"M$r.J9}dh:gxizZ!dt&E&KL3K"'mIMr5WRo=wɮFm6Cbvܰ8YCt I,'͒dg}2/G}U ۟/" 380S}@eEQEQޯtr]0MhhB0rü5#``zoʋH{x714o)v88EJ@"6x<ΒE(sjA+'f&A&1E׈ Sut}S 44!pc)sCrNnAni憼,^OѾ?#3V?E~Kwsٰ~ uVt9+/U[pbpM vcbe#e%u,_9Ce@xI-%;Ŀ?6ӆKc6C@:4HTkRR^%&rt0L pc[%\+^ynadYd23nE#0 O rtz9xudlwdStw 0O׏Hg^5@stO4\_^JzW_y ށm'{2 0 } v Fe<otIf"QZ*RWQן$XPg(BhrZV3E(?᭦&p#lڴkp%MKsSS{.4((#6&7a:' mڪOД4\"Ax|1\,l6^xD۹kh8PO'K>n[:6+{_$Zba]km%>[Ƿ2rw:T\ox`[JgۡK3ƺϲ"$T1pbD-|43Lsx/S4:k_V]#868A${k1WwYu-L)ogvjj n,;l{etcmejr뽿B}/ sM"; X:w6;q_/;񯾝m"lnn켟={ccYYwպYxqd!hW^yX, `)%]]]Z&QB|VbqEhP8B4U״#TAjJ )fQ}=u5V԰|:V-juyfbboi-M pLNeobae1%eňxƦŔR^+dTSXRIJDtzJ(+ɧ˚jVmA9.n21>[odQSEQ嗀)/C%H w,UVbgC4-5u+i-gqU% S븳q)ְ͞K6LȰ6W vXy,`uJu5,: ŃѶjcn@>Z(SL&TVP\(2Bp|AJZw_GU}60=2LB]RZ*8|y,3go%mTp(99y$&z1IS[ U+&DI)_Ƶ]Dž.5= J*((ߩ`]2iv/MmyQ%|OIJEQEQE\6O>!Sҥ(((rXbU7Bud+((K ӞKtI Π[R\0=fI&Sxi((( @W\t6\tT*E(>((at>gO\uՂe\*\=˭>cU<((ʇL'&F *T1(E"fb]Sj;ߙNJbK:)!Q"8Y3hnvYUhDƒ,>~EQEe 2>yCc׸Z[ukes0m= 3D1R`׵ !ȤcD)4 ݁<$ sYTO݇@ sv!Dh"nwu;l;W<&8\>IiMh3m8Tpۨ+e9|>[_kZ)pk((YC{a|nlXq3c`HE8gkA쟈`Yf)_O[aA.Y9Խn`m:\sU; X@ .{9:"L&%- Ӓ*Bg:ڃaFn@`'n+4qA gt|[~5r|KpO?/w 0Rt@e2,iY<vcHR ЈN.]έ-(=bhp?Ͽ5z/3XD_a nژOlZV/+gmM%sbsMͮQ M k-Y˼1>F*c{h,9,[Ffpŵ/CMDx, 䒭9i԰ҟ{FcFFqKp$ҔʪJ$g:4DwWT`)S3K1:ё<=͖dp"z壀 >{3-қ~'tF#5ol%(]X'x/&L;6?|Up xo}1E((2)5*VqCuO;8:1qW>b)Rld)‰q\Vhi3 INpYG#SgT'fDʼnuғa&Y4lYZDA҆ >R"pʼncvD,sF}[LyC3)uaũg0ˢXf{c4BwhhH(Ĵi d 'H4M`ZGӬx  E GB"Svy;=؜nBn.&]R^q3&)M4yLlb`GcS 6LKe)W+1OϹyJn@8{_|V]JMy9:x82%Awк[o^C7avn Xx'_k-LZ]((g{)׶gkվMOʼn!c} j\|36 CFS hE̦ 3{F:n4FI40Tح:R$d 2ۊj1SjƔKo?bUa'M ejǁlgwU$d6M""1ȘҐh&$kȦdLR 4 3M*mq.)%LsΚcBXmvҩ l6Oej][$SVU/4T:%|!/(j/-%rB?V 7YC&abbHRrt,V ~Ӂ՚dw8 1ɡ#)j65.|if97UeǦ![l8l6N6]yq2dW+WVEQE9`wFҒ(3dZt$SZAץ#'t,< ǩ..ȣ$qMIdR\uU^xR| %?%NʓOs` NC }68Ǐhcy<\t6atuË>|i"qRr5 cJYQpOZ|,{(U+h-F$u S].a)(\L ЅH4E|+iXH׏UH&ktE( C3cD ;-Gq<G0A=))#8h,Z!4(odk/IBuE+%8##7-^o%7Etb3L;YZQ劦($8t=B΂U8ITgԪU6%Rfhzff|h榢v,nl<"jk,^Jr\YӾr4WѺ Lti0?gq3~db}[6}PհE0Gz'05Lbx}47`kcGᆚyX5+^/رG32Cˢi$x5U 3aw22Δ^- Z4<"3'q[k_~*Nϕ [7'.S `l: ܼa)~Lb;RĂN f^ny]TԷP^n4laiVqSàp%@'q׎:7W[< gZ:ڏvӭ,.??)',_|9#6dm׷uEbCtLx]7g9>NRF|g/i<~}>Ib,ead$L$A&F:Yf=m5J+/rQZ( QZU=&.*'률0bi浲niMH μ2F2ꗭm^!BJ,6%4,_H(*]"N𳠡#PTƚ8,|/Iשf!ԋB04H~xl̓ Jh!yg s )o˸ .^'4,+N452tG7CDSeD_ a>c?>Olmo~5O((ʇL1uo#ΰy8,u:;{ gT̫$BfiՐy!&Buu1J(aAM)Tr>vnL$l2d I'ueS#ׄxp!B)yU%8 t)F !mnʫk( 9H9!::N/j}97:y,A6>Cwgy̯,Ʈ]*ɿ|_05{Hϋf'_eW &v(7gb/E<<kn>O_LCQEQC>p $QRUGJx>4#ҋ8ʳn&STG}W$_7w[i%8faltz]^&yN峸 d[&/?SuO S~΄ʓO1ᨡm!׬[6PB#b׮ݜdߎD 9[WO d<!^{^=K`q|:sfl,tCS6qukFw񳷏zducS! TӁau㋫+8g3#Ecn& CCitvݬIpJ\BF*$=G %ɠ  Zȍ4M4]'$.2dj|H(]zÝPq–"Ve~!$:gh܅4/_WB#=1km'4dm;v,6hli#x`UMW3{4)V_}/T&j ;Y'KxG8,wޭd2qC_o^`a&Gx3 F2hdf~j4, tb&k8Cÿ=Ƅ%ydq㝧*xsQ&&x?|uڻGbRxG7wQ:ogL|#[i[2XoEQEQ iB~BܼAF\Bb"š.%Ee~s`$}CČ~)%w<#'H=-ὯD܈xdDH, !}+hiX;<&{i%7a&Bcb52('^B>W²% 1Oo5t:p$Ge"[]Β?~V/.h +ih\'>u3WJ9hnmmU w|/7?D6&jltlxZ=cB :蝌aCOѾ$5K*VEQ&~{ C'5IMc4n;a Ȝ$ !L4Ajo"i"3Q,RH4%0Ry?Ds}z<37ʿK&R_{/>A =E4x\vέ!]|?1*O+0n@ERB`r~VP_uߛ<q]`SdĎ*[S!Nn/=7-ab]R14!-nl:6f6E& ?'wl&M6bJ[3@ <]RA:Sݕs驞ӓ8Il2ZXl)+/cQu No)__XK gE&)(GI6g|bI&CQRNYbN ʟ)urwAQ+3&575X]HJ,. 31L`:" lcS㹞 #cFsQTRێ#"a8(o?d]ID.:SCxG7`-w|a]5{7rx8'Dđom;<G<}o&<||5:w#dJꢨҲr3m>+##DSf>&Vo7׹wU%CSTTDvp`&| 2I5%خүFpzɱ <.33L8qtև] ˌ5F'"Q|0q*H| YRЛOvB$]poaqhzʱAAsSՅsYߘͶT5E@UKy'1B,'498S} ?9?=x8(Q'%k_wWO^3! bm̠knŗ PPCe_".${)H0;xk ȷ}-&v\BGrDpp%VQ/cDFG818B09؍_ĊUP$ƶg /@j<6R )1 0$03bY4 ,|Y8u2)8@HS@64xN@<7 &x+W^%ABV%2!-,l՜g_Iljw78Ki]Tлxek;V6C/nGm,Nly{3;3ŋ-q -b;k_4 t׶[(c:៿ JHvo4\JJo` Wi- }ii <1E ܼaWEQ~1H)O})wrlV7@*<đ>&&b/mpQZ줫 "<#cnQ@džkRUQ'9ʾcdu 2ai@N^q1 a%ʞG(Yz;Zi੗wHG:H p}# Rfq`6n;Jhue\N,67';IJѡcl?M͟k3Yw2,_JUi!CXG7^ί|njlaw^`~ rwZa&`5~%_S];x8cf;0n)9Ot֣^Inh)"po waJ]뱉s'uW`feWTQY9/WBR`Ϡ&BHSL%4-[A]E۳ST-n2,)BY7-KPZXHYI XB}M%5,_554ElǞ09[]R/H111Eᷦ üE+-td)i>ŅERQȲTRQ]NJ5kh)rc74pmQP}ኢ(blד u3ܵU % kX\LY6oªI,:T6wy' Xo?3^|S O஻׷ڗ[Lkk#~-T(C}bl' ;:K/R9C+/r9j ~/I?)%Sp yCQ"^QEQE̞ cA\$[{oj σv}=*i*IG )((bS b=W5REQEQE9K ⺪j(((0dO %},d :UEQEQ嗓ҐWe /LgEIRaXr<*/((r Q& ø|㲆^n}1.!n'ݝe|SO\|o < &Ʌ%BwsaKQEQ}FhWߎQPEˊxZd!$}^,^{_Bk<~9Lgq㭷՟=̞B܋]nYOQ0?{e.^|D] 41ȯj3p}ޟǗ `w]UMk>sCs]Ŝͦ繂iVEQEXB#6ő n[F2`bЬ}癗g"汦&'nZJKԐ3 Əfg>_MX߲c^[PfZ';g_q8x1%hD?͍_,C3Mt|~D!1[ 4_>~=t47T@fjluЭ>LDshY57:i+.ßX;O /0Q&%WyV?[6̖ms̋fxo:n[T(t n~s,,rCe&fnYQE߁wqx'?Oo mΦ$>5Ȼ^ᇟ'ħ8m[6;;JM>:OLL ߍ((/ A$yM 2Mjbh96>IIq!JYu`dN@h)uSӑg~ L9~pM"MD~Gąۄ>;7J)zrt.Hds2 d Þ^tFg"g!3()SwC|p(d,c5"wh(HPG4Lby4ssZ]8:BpFGqͻ[nqtƂb0?Պn((B_?jԽ\SPǚ-e˹5fyz Y[DSf.sŊmSBd`\1A`G"A6maUnPޗ >-{~ [lbφU\+9>H$,_lgGLaE9[Q R<4?kw7pg4+E5M3o1k;6zK*=W _2wF"g`8ޅ%0/3|hE>4 -6; hB"43b#6M/.\?%~7Vyn/5%yXD.4 %f6IJS52dַx rjs>_~^糴agXt$gy}U+⢟˗ _kH$bHD0HӸ+wA%3ztGF4#}xww+o7ALzOs¦647obwO˗S8ċoK3U5!':ֻ`jl}yͷv\[ijY((/Kd!2I:F 7ږj"/G2HDKLy;e͒Eia=~ k%^ ](&3ti< Gt-׷TVumd'93.RǨ,m5bC{_#Ft.5>ndx;By-zHCc($k֯o#2OG nLҹ]Nd-$':G?D+0u|{iyEĆ1n:I~z-.r~V)%hwvoZ;ʎӆSussD H`(%Y%g{W0@/gE4ffGUKnajJ6OR\VA f8Ꮫ)"oB K -i* qX4bi#nSYL9Ք撓Kljj]R0WTSDdȗb;uU1Ŝrd4H(!_ŨH2-ZLUU1Q\DW! R2!%V q(pelZՈHivîBp_~Y|ss4֯*׆!TJ$͋PqR^HcGl&߁W837l0M,ChޠwlGH e8((*y"L"of6gn6fTaΎUzZ@$Iar6-æ\=1ί `tl\l6[ވD"A0+^|8d ˌPqB((ȆJ@QU@54]"UQM:܋R/lt4B@UMgz81yr!!@8jsӬ\ Ov+U(r)Hy> D@㴜+$YVlf"󓔙ȹn |%16>NEyF9+a7koLJ-}JZ:v:FZ.]ӮS h[*/(B"OJC̘j%M[ 旐SYOJy$g%Cӛ=W;_aɌ. !n|aW7R^[e\zhXjzz4.Y߁e{atJQvB475qN.͇B\ .Eq].`2]fN(B`2 Nx[K6ƔDL&vۯ/lzX|ab_i-7$/F!@O$ UQ@c#ÃԈܣcpun1qWR "S=<?x@1z C( \O .g0~-[.x.=?`BD*Bǩ]tΦb|- m@7zi9=L, -u+Zt'Jx&2 >H&9}[FuHi;i%ɯnf: A::GGg._N}DN L$5իS4}~Lhc$z4ƫ Yvy}҉()XE dY a%//E*߻dNFfVcSӴ34BX=,^gv_9N 'qUr" ﹩"Lu+ٶm7f6)%Vo)Xo @gԳt,4Xe̍0Nt~~}ְiQ.&}?R?({Uݲp+#tQL7?illݸC?ۏ2<^>LҾ^;5Eys37DEd#8g|3ȋP::}kOWq>(:o3'(Xnx92FH/𤙍l;w}Iz(Bl~4lӇo\{."c;DGCSU1.euf=!TUEU '/nrM|~((zi^BQeߙ9jj:mW/[6RtCb6o)+k )nXΦ7vJ(Nq_Aqn6n6wKchX:oYHW9>Dy]@rp : 8sX,)K LI/e&$LOK&.smMzY}>1F$}c| )mXͦF_XH$$R0{X|)Eyu+C:ޏ.ҴxD9UWZ-}B6{}XJfN͓DsĴ"Dhn?G0~Aa#39:C8,]}Cup1NwMk$S9qSCD0 >H]#NBI\v3s+]qQ}CS\i&Tu"ga65GNLE ( 8u0&]H ZbN02\s,\'Yr!nS’E RU]EI^Npw'ZZ q,D6- Ay%cʜCY=aN%07͉vx :&JkW:89~z{ltItac ,r;雎 7d1NĞg|W[/3;ƙc?3?y #C^:?w> 7GtD%x?ag0)|R*[چ^}q^?L0vg ǂx\_n /~gf2@aʐ[z]hSC~ƦX.,-w& i~-He՚U|xKU+3nEH5BSh7g1ߎ/3e昊q:( BcsL"<09#h2+.bdO r @Jprqx LݰR 7 j%o9uAa;|_#/$Jznm\'? :OY cJ}4 h#F\}v1UA08VWmcw&NJQCbp߾w9㇞ݿf(i xt2:'bu /t$$U墁 GE'4DT$bcqӝ|r@b3F^[\BO3s'^Bo ĕ!zOAb(aȤ ebذ9ÄɌJXM(.XD<2Z$dd 8 !FcLLNʇXXz /sHg]Y\nThUWCRGlX]nTmMEhD5(,'ǭSWWEe9cJodpv+cVQcCF/6B@t_D*tm,.qqn$8K?EHQǛK#Ĝ?DFEGI(y8PD  F,,ϋדST}:@K*̹aTUCN?^oƅ'$^BDV*(+0Epo1jc wh.ӯ3Y'Bꗸ/Gܪl\^cH |<}ۨ˷^5 s\Q*j`-a}e!]̥AQlY^AדL 28#[[s~?BQ `ȟa ,y,RG`$B$g'lEV) Gׯ!utLdzEYXECM9y9X.3~ԯꁔYMQMlJ 0eEZ:KTxIsc(4"R1)fj?J߄](A>V,ZDNA+z;fA&r5ܠwC/|2wWA,:F Gc&hm{YX@tfc"fratp(F4&H10} 7I" h }RGYv9Df n)&:ϰg_+sU-ئZ8tv0ǻ,m5^3 OOȭ[90#mثcC#&ҸNZ8p@8@3º+D ~5EM} 'wa.o9oiƪK$t*A($H2i?ZBQu?k^>50000000P"⣧b[)iD )ٱ5GQ"cec. !e ~1'e'XU^+282(qpq*6œt˭Y2KE)N~i=}]nt= qi_si!OwK{z빿4EJ20000000@"~O7BιW-*^^ ]PŇ/}ȓ8{(]D00000000i\B V4;(sݰW7>ܞ._:VCWP^%%J*6){~26]㜯f```````````!Ew\@:=]3]!00000x7|I1 qPćܜzB(=yH.FZޱ׋3s= 0.-^m_hF rg/y$/ߝctNY5,EzIm*¼rc&9}Я"uoՖ͋݃CDҼu[51 {LZ3B!PLDj:m3kc)m%,>քI3 n6t}8[UlǬ@I2'K&U\4&h$ 4b5[QŕbFB(h0c3}tN ,XšW(P Gf0~. B21zW))'QiQQfiI njrWy $DLlrEHbY' T7Bǂ4i6sk!T`G ~v`zE.lVQB@2&%,8k'8chzL %%6tvŒ,>[Ct;ifJ\r캍.!PC kdb! l%%uU <=_ST CfB9{#lĤJY]YQ>-玅[:@ Ǻvr`fAv4,'ߪ^0?w7?aC&]B ֿ]p,Z5v@'.+ [걼xA:6 G'XIZm I *=JQ;ù)b>d5.U_OAƣrrwy^ h&6tݜ NY.\muf1|y+ozmf)4:DmQ׈p4|0=6ѣƟ =قp 7605'It:zJ9a2It m%ܽ`Ll҉JղJ+F':NkCsYV"@&LfrM=fc x!H3yCG?D8)ۨW_BOOdxxBԫ<9ZtLe&<%Y^Uz{qy n7493VsCؽ#g|Vl.e4 rغy '3(o`֥xw %O)F]!_55uJfnENn>9-9TX0x"c ٿEd u/9 RE38ol|뗜PK;۶]0+.ĺ^?9ZmO?RɊ,VFe΄))':}orSLԕTs?x3>p!&tLOG!{+_X;ky2H<7ɖ՟Zl ?vQF"5ZUP%Bia. DfV!8sU5 XTp}3$4 j zr-OP/$%B8 ?lkcOɅq2^~9$t~8,xS ]ɗ(XE ܾf g{Ic>?GӲYx([<@G^[{Y]A ?^^C2$tx? _?g1$0Xco^?>*wֽ×XS|rr\£x<{X 'u~sQxJ %K)IR$l=\m^ ;;Mǔ3DŽ?juRVY9>ШKN 5XeI?Ĕ11@qPVZ#k !HD昜M)sck ~4) difGG8TVVf,X`? BXQ|Q2ʊr1%{Z:Dh sr0SSRۋsȱ WU_Z'N3B,uP4Vz+?xlZ$͵}?߱XwUv5|Lpg|4no|C)h\]YlF0=q{gHl, Ǚ Hb&YD;%f\ 2:s!=5Tx: }f\uܽU0z'+iν7v8 z1j^ʊ|ںN(B29}]4m- 5,9/w:f{wFV'˫W6va]-81 w$~H|b)i2фNۂˋIc_BQH %~QRbbq#Ai.u)6D6~a Dմܵ9Xl*eM9Dufjr7Bz"gڋmKR( BhLtc"Qz-% ÷&Vw6$ґҵEl*~^نjF QNƚ|/f4"ͷvz;WcGBcGvS{ߗgHԯE!2r'_dk7&]JW,\@53O5ub9a&Ad㝳,[S] 87[6|rrm*Rf"ʄP1)N;NkHL'y5(,qa]($fzxg]o_) 0fo)`22kZ)\U^7F_⺍. Y'N_z2" Gg9{,F[H%)-MqgZRҺ0XuC4_}}ܳ5ЙLg?ncֵ]c:O=Uuq+~V{:{i(_ϒ qUсݬ6jkg>[fF c?cp3RWiboԮSl|O2&'&$P200x#f7}sX+8QI 3D h-JSE(Y3=GнO.a}ݼEI8پ^Wܛ9HAge`<^vL2}Ij˒L??Gɒ[b_RWP<ꦏ Qty|vMe[>OX _ECcd8,YUhq|rǨ%L8B1Q3wɁͤ Kk>uM`Q@ⶸA| ()Q(f;9&)"IbX]w[>IS_=<]Liڱˌ@GLQz/u1왱!$ 9zJ6DV~eOg(ؼ5<!ҥbQt-/x>4V#61B':#L^ o\RJ[B8U]u\*x\;QLkWP*RRȝ?YU8[?}Dq45, !@ngJ/!p40t}rs)IN5JVz9U1 5,&EEńIQ'f fs~=Q~zt&Q54Rol?e^t]~U.d. /=ə\xsيɉ lB'9Ђc4@{w>̟XUm?G2N#lͬ_Pve㥄M_n(KLDBRl wK?䟿4 n @`=qn!V:*ӌ 3.C^*ngw13]Pdbol3 m7TI_|JC= SӔ.@QTJ,VT. 0lvLV r ο@t)zJYbEǕ/a]$1+ dLBCk[JͰc#1?{Iuv_h+V΃4=$k #?gß>./400xߣBQ:h*[C%;8yQN 枦TXA4CNڻ)exIDAT!]0-îd%$:*w5ǨhCyP$Cx]IB)lr4xp{6)*˛ٮյvtPܷ(dZHŠ.,"YjWyv`_4I݆yxM\>]I;cjD2`vfPD)D̯ԁ$t*D( gtMD_vN̓o"]l5bI&Hx˩(%7+_ Z0BZO]8:R8QΧ?|̶mwI ww&-' ([u'?n,^x 3XX*_ŊBf%SWel8ǧܱ,"$3Yb0g3eiRl5NTQhD~Z&NCM"278>9'%'bgPg9.s&;`g0Pf6*qg Β!$_Ncq%.E,1Fqk; )0g2 y^"GNDѥ\t_2MAn.I (BНGE(."I4±9Z%ʫPelR*at4˩񖰸}sHE%4j+Sh[}PHM2181QX.L =X::c$w_G|%(,ueBqw5<;%.jD:2gbNN#e7œlߒ`">p7HEΐ֌{=gIkVRi@ Oq!  IIxv?;K(*uuk`IIRJtMG]8,\vS4G$Uq s5^B*y.X,A*bz>GZ h^GyWh8t*ȹ~&gpi^c0g&?/?{ϰ#xh,UU0?g},.7ⰺctt'/sl^YY-kE$qĪ'#bq8{ҸNbQe>jضo<g&lRyysG首KiZHnrT2000x h1^DYH2iD5o"ϔd` {i|*BN" XYGkᙓ.``(LJF(x/.^<=q4F81geݽw2:2#4.pGXҼE#sr &n UANv"Zɦ(ڪR_xnSgOp(Vl\ICR QMqd'{20єp:0CC=,.$ܕ&>u{};*s 6s[q zOMrJk^O3o)vP]VƒbfW￳` V^M4Qwr(0[ɭvNO_H+Ҷ?-+HoߎM ty9nH}66 H 7Wh BZ1agaْ9R5 [FXMpNaZoD*d_};1̓iEǾN*A1N=5[Y6̗1)m8< G83ųv.!o!eUI'3ClS|%̴~wmÖX]D@X`R*rdi_O^v ƆKri. Oړ?Ƀ5 sZ\5~~_%T}/Oݲ[mI+dCd |d L|qUDD[ ._۲ cPB!v;&30cTPRGIiE4-$JB!4&zZ82[5,ZZh9JŠ̴xTxa|bxZ#T56bwv^7z([OܱBImy3P^K걥>q؜VʪF8qazi('9ѣXy]l[Zli! nsӄ,eYS%FNs{SWho)7 FNqb{Vˆ2G_+ L &bTc-ʾC+Z*L $*+ocAn% (USQ-YKE#vUaq~.W9K*H:ދO/eCi1fx[V}E[̖<V,D;~Q,E|l,u qdɂ"Ә-TzܗxɎK;"*+E7"#%S $+cb-`AYg:ٰl*WΜubw%[v eLtr IeQ%J# uV5ϭXD䱠e(8c>}@P.֓LMPy=Ԯo,{G1K2wQ{ߝ@(h^{ƏQKe F3N3}n{F|VPB#:c-^E4ǩ(/> "#3R7DHS?A(_!Z\G Rz:HFfp]d:A(A3{{ 3 q!Z@R1^};Wa0D$矿o630000000@ LlUe3Xv>m'5֟[^MP^jW"-I?_j}-ۺ8rd_f~㺑< e+&֯_NۂDA O ],d1Lw>zޭ_ 000000000 !0s:x G#PUHٚMzU SH%jj:mT/-(gD [b>s諾LG/h2\hP eцz&lyh?౗K)ZE ~8; 9~ qKU䇼61s'y5K(+d["M79/g*e]=u^7I7EA1fUEZ0g/SgƘǸ8_@'8=BgYtM>0 zb'3W%ePrkkpb~F{FpVW`F" sG ]/$N-!uB3{I1sn5v@jX=<ĩs Aiv$AX(i˄Y<,YHiI5Քⴙ.%ILF ,Ga9M=lїTAkVcf_ e-l^e+7O$}YS=Ɣ9\H{^- *Cj;K`nmgqU1+(m$_iHU<7O/]HSh4K-H=͹xey=iy-ُҘoGꗙ]2ō#{ӥIY mr@H,/>co<|-3OfW^xb,rJ2~D9GV^|US0F⢯eOX6[UkݱmBcS)&8?CtsKK,"KtXqXmND)$2nYo輁XVV~Uj3( ق]f}I=v2x RBo_8o'_ #b5i,f;NŎE5 eRb-o`.eSI 57'L`c8LϗJ'(3ߓ T"Š fɐSLL[d̊ bx^o D״zv>g9t!Jk~GٰΉaUQJ~51/5dhHÒS &W)w<[ٟq{#}=mb}C5sHp; T`-"&[^R"DJݍÌB]DҠIx|%we5^$4܄]|V$3|( 'ݴ%͵fz &@ jϧpE&/D2B.ƣ2',WPUi;?>&lv Z:KR|^$]|0X!MKW3UI~e;x{(+}t3'p-͋qDp< ch:^ (}~tNYp9ljDd,) F9kPnc vHh(H<Ϙ?L88=rb͝wMW!Gc5SQbx )uh4{iÒSƢeU7bE7fK >E&{i?s!D`by˨Ҍ)$ ֳ'Su3n@yܵe1a:ݺ<-8{FoWq'[? wohF-*Q8KJJm?NL řC}m([ZpVmn|Ӄ 0vh,o^4_Iqf;JVӼu)V53 ג[lbI,hڸY N|nK"J0Y57 6Sc^UHA}1сnfGH9jhk3n |3x7(*+߱/R" rl%_RבE0:2cNL DE%2 ONmeW 2(%B3Lsdrs͇PbW_koȮ4 QPOi7Q(h]<ͷJM%DD @LrN%T9.+Lh 22vŶRfkiFOoeee]Ox榘>p⒢ϗ_˶J-+Ben .E<ށ)@l/YG(JCUqvy{Y9cvs"%&6{tVO"e}F7CŔ:GP.qaB2T\Յ}]ޟ ot*MatG;Qf&Zr$kpɪ^ ]P[,avch?|00.;B;B.cvQy7;F!_1h _+@kdJx{ػ%&UeKn 2# i8 lUz?#4R ^}!D`6<.:7YNWF_50LTUU.H7"#Ͻɰ/qwqvo!5TN4{}Q AjS(z/Wz2u٬a} д兕q4_]g8_#ӗOQIOao)LxqܯEk3e@bdd;RGK.gw4Jgjv]h,5 Ť1I_lzW/L߰RI.}UEAUUJN(nB!Z"#D  +rJ ?OYq/Y4OAjgΫT> zh'=bK>ܽ40006BC̵2eœjYQKnmS pzëc2qۘ:K1٨dh'{כ0óW<τP'g@j F{8goő}S[=1g$ƚL8oϞ;?%oXH{nt !97#KGd^eVe}ܳH$D(*;,#3[vDXڸu o?cc```!F tcl% qUSiy圣uch̄ wu)Yy,k !OcpQD&4I3h75RlVç+P'#:=(jfvUBCb,]]GŖm֖H?_*];[IeIcĻ`%%KQa!/16 &x(_k(%. D'5E/[Bӵ,ikͳxWtJV,C}LŇ!5'05hqTv;4Ftq⟿`0:U  ?0;TrgbFJXuȵL=PJ8sHX|xSL057ޗN5SSmŽ?g\j$G_ gd,d=Z :=ͣotP`Okiv@ εbܛP,^Lc/*^zfܨ]BEU)r[31Úuw6t2A,#OI{R)>($ MdݐROE&@ScE5k$18i]^rct2A<#DGb4p300"ILϑGRX,t$'zHu%;uQ+ω`9Sm,ffnq>|N&cC3oM1<.qRD )B|Dh@t"}yƉG uSP<q֢j6 4S%9X+fD3j\v)lx,8X%H@t9c)CDQ|'OKSD%q&wa8>H >3H7I2BJ. $Ge.+fLj'j ̛ 28luTiɥ`Q ZA&bć;U)\R}{@ IГIj;1x!d)cCӄit]b/* 1ҲX<),3\d꼬$|%ԕWeEٹsN !7dq}9V!G8#~a&g"H$TTƅ[9]B@pCG'(f Q-nڕqϞ̹)L:Fzذ~%^]KmTTW"?]Χ>]N6y!LM)X HpQd9LP0;NGۛ} 폲jxTo~!1}aع%Cii ;@V%˨݁>e=TFu%$b$.VvR]1m{[3y nf&RYˢm_zLB"Nw%*SM!t?wfȗ ِ-GN|m;וq'5TS著4q}}E%B4; `^͒߸[tDcZ6>H6Ǚm;,*/;s J%1 bFdPBb($"aBh:)[X*olT=T}aroތ7r{4v2)Zp6ﻗ>]vu*ZBnUԮ`pHKj<|6=/C -u~e5UܦhT$jΗJP-6T/xKj#afS&Q(v/J2GZRXxZjT?g>91?{;ɋo3c;PCwr%n9@EQThD rY0}t eGBd{s^- EE7' ;Z;)15 w{6"'ND5 Bay!efd*D j$cuѴx)ENS)6g>ŕ =ιY W -<³m]8RW~=c-\YmNrf s\/7Mӈ$Fj`: i]xC//X*jd&NKˠ͎dbsr93^JNyKSQuX AP^Hi#]PIs]9*-nk7TcAJAlvNnEye0sQ6000x dۧX>UNs3GHuC݌<N;#1us#3tV]K^|/i# >F+IZ% 8$Pdo4Bd䊶R^݃i9y%*(s3N bE10X]NL櫌>Ś/}};>B-h0tSF]Q -\sj_ۗ6.ќP뚔Dg4~6& Iq )<>%V>{zj%$| :c Rcj#`{M@Q1 rYhd Ctɓ-F}qfu"Zw7u~3O'fTy#Q io̡;Khq+M ΒWמ/c-F{iw []̌,$u =A7fd`S sl?Z@Xc;ke9Ə?J0unXxRpmpBrrrPTZ8Dh g24A-nV ).5l8{两 ut!PLfEdW"Ϝ٨쌡D%BQ1Yzv]gi3[O0?Bd5T ׸)A`+{^avRęC @NJw*lro7'hDFH$#.؁H2+["YvdHfH"O^M)G@[}B/8wdyF͆ ZtȈkBI gA>4r/(VE?JON+s-EkP%S2!DKư帰{t;G1v9 M^t#Z(V8Q^wW7P*3[XL~q6͍20f:xW@2ThZ)-uo%}}n*ώzfТ>̅0f|pX{[h+!޳ǞxSg^bElܐftI)l\Rga̙G[,&"B!ڇ,-8)r LNB@EHz]8PdlC즗;;ξTs]~>;TnsfB sT%^z+)߰^$6JvG͒B ĩD1J޲-6DA{H Ճ0Et.l^,`s*եȈPTYX%uh-|&\͘wuDAjqbsqr+)`xZeRH. kd]W0)6e8J_?\&>Gm Gx&En 8aSnX{IB҉77Sn-m» {͖`ʭaoRSBf>>7'R4`Q FWΈ%HaFR1u(8?=*sۉ܅Mt|X0xiB G͔[%5nBzy'PxrHQ ˆ<ͧ~&+| ׿dGݛ[$X$9NzZ޾Y"uI*GW-Xlyo]D>{xSvLV'lbERH,U\5&G(8pUQHF|L,l\\(Ó~9\+[ɷ((&+N Ӊt`6Vy @4'c>ņY[)HxN\NgL6Zp8l(),Ùe*DA#8VLMAP/2L|wl>ɞ3t'VӊL Ulh.!>7™/E~ R~'T^¬ 緶lRȦ5xb>ʆu(zw=>g϶b1Lϥuu0P=S|v؜`W>}uuqN7bo cl\ހdDk|Аs.9E)| %2\8,ز #Å-_VX+i:E&}YzTGt:IZoKGXXr 0xh|.Ϟdԏ{ԬFEL^Zٝ}$Dp+0C!F66rە:~w~)S4^ax 25ڱ #39NʗX0t#*!AVUi:6ih(-w:$_P8>tͫڥ$=3^-WWr?+<})t0Ys.!V.Iɽg[>Kܽ1=9N̕fd~`pҏĶ՛3p7 9Lė>Cs]6  QXP2 XҒs"?AY6 ?Q1~+bf&B7@8EM2%t >>ٹ331LI0@%&A 4Qb&"DYp VH ChH"p5î>rIHy`m1Rץ( HZYU8$V*N6-pO/Hl,\^\h+ gwA"K1a_BH(8t vL$+Rw 0hl*#u.q.rd w1c[p/'X 3EܸtbQip 9&!@DX?.k~ \>b;'H#5g0*3X$nAB=ع4h#/0ɪuyMsi:ǻo iF5MK si2NcvM.<8?JdLN_XY28 Ӄ+YAX4G=Y]wExYQƵ{u HX4:F9z(cY-6XB[XIdWK': &/8bv|^1珠:7r6h+`)::Ok.&gw 'n'Io~>K PE~ !0ļUiL1:,sroK~+[~v|p!/zB0fK . dλ]Οasss\gXIG5kE^\|@\ya둋Nw\n1? RZϏRJ) B^דf<㦲炇[~7*?Hw/_u]uw{$hi$E96(+o2UEQ 9ƌ)GL]Ghɱ7E^e"r^pee݆겡(((7+ &\ :*υ(((A\N'*I[TEQEQdY 4.Zh0% 34 CuSEQoLhBMfc/a] &\B)QbM;?|_Ä@Ӵ#ɟ )QED&:΀% 0ӓk{'):I_qidc]4qG)S>ZJ3sh"_r^#zhXo/CQk-\ya&Bgf&g;\A^KB0t%~gO|h.Q(Bd޾t8jjP1tR;).mYVկ}mjB Җwn>*@ 3x8y5McU-5ι)ѣ7]K<K6($%iM7m|nESs !0q1lC/S;WW@*9L&C |B`'9^koNNeќ^<ɺgѴTL%0S1R$NP~EiV7&Uw3aC_b !E`2o}> %p9$:5Mtuo?Ս,̧l£S$ c !/hɲ'hvgw3 ƭ5$vSLX l׬4g6R! Av>;x >|OMB])%Í{ް&Q>v<Ǝtͯz9v޾u(Tx;|lپ9w>ȧ7+[?4#0Ew+6U1 H)$&i?~\QS=<ΪVNN`&QS7M gNTm[j&]t 6oYK[P UtCg_o.Eh6*|iLtqoX4bӦ5{S>t܈$H/y"n]XjRC*M01xQQ#55H䒃~+}3ySJA9av^ A.ǻYZêPNK7\T.,Fr|jLְhZ1>$+&13~xhkȗAaq w'8hV,W4O>ŋ:HΏIO6C8{'FGy 1?fbḛR;j kȶw0bdSk&?@44 "7RG߳D$Í;hs򩟒s%MӑDJpWq3Χzp0–`:X%ZxH^bS) ξSWQlw 7bcM[&f5Ix*>*LjN…~~Mc֣1v6=&!ߚf3~IVׄ@(\MOG.IV DJ(_m+~ 21M[_u͖%U85ϕ2f/zBJc}OHjˊpOF35y{$S2I7md-q78Ehft7l~'jtZ}^=DJ{m<=R+4>]_9$c31!^?T4,So#+\<}O}'^o%6ǏxJڶ;#?~ɸEQ+J{osblS拾$J $(񖬥 _e̋\1dzo9HԔKgæloF>?<3&@[yd=/)Z|#Bsmy s^/烴L;/Mu=T#>J$9)$R| rq9",.-Q͍[˧ LXι^:MD 9~=zvt:TܶpTl`W~O H ҖA7gd(67yW -+;yB;uՁCib|_r TWKb.|\|E}NNcW\4&3é7O_ׄ&7?m,y/?۱Lh4nH'JNOX֠Kf߂k[&6L[..3QΜ>Mɓ_!aF6ԴP I9Kx? ~!s bt#4z>ȫٿ~L-=Bt@dy|&H˶ta8е,9”6mq]Bаb(7) sǟ[Vԛ/y`|"jNBr]{ ;~>0 1xb9v>YP 4A6[:u/BO$lYMhTr9WPtϚxNp7x_fEP/hU1mGQk<~t!$R D?\ZpH4$qkhBH r#-.6+=;[xR:m(r#˧븥L_-{O:*DCCKv_ȑu9}i''6!JU}N+0_gT(é%;̪^;F_¤9Wz-}w [78etΓ=- 3-tqxOyݱt2R&@Zy,/tn?l7 Ӝ}QbZ"~"1&,reuMA_GvlI˜iH/nV~%|+7B>K";!]@f'tcgЏS+vg= [6'_gfzs:lGwvwod}(r_[w̳{ϲ3pgn>hB 3}[bGsHp:a Vۢ༲CX.)%~*j/W]Ul;>6ﴍBVTbqbJ.濞R7 t#M";o4tÍK\N&g:iN"+OZ]r+CB7&9?-W~}5?=E)\lX&DbKwu`όENf" J9y?xwݻ~߿l S[v/q; l \-˿mJO2 ! #G"Y@8H3I4`IIq6^2#Le>wN\[D%cME5LM Os38ٜΪلMs#)TRe '*&t =TC;LuQX<+t֦rÓi29 05}Il$1*DƣȹV]1;HGhZ:CxZ5i\{H[#v;I}m"Ie@_cpHƘKePRB5;xAi"?4|T ҒUFgO[qe %l]w8i4 gzȸְ Mhk{Ng2#).na}ycm\ΉWn饩BE1l_F'Nsz 4-_LDa1-u8͙2mp()WEbvR4(h X@hS׎i0:Xr0=A| %.YVKh$0t lyʾW_7m0';gdl gAT7/j%g%Qݼmp'E .8@ DgP=>+ƞ2W6x;c=>U܈ێޑSXx>f.;2u h9:ә0(IFUl- q~1, /Յ$O!Nm]Cqgķlcdo}֩"vhfxS~#߷ŋ=Gk멪*%7Ήٲ5gGK9()%SSSYpxϿ%ɬ6 Q]UtB$STW} عcC2\zӜ$.`ժU9]t􎒕f6·VrbXSτ=>^b&N{4AUHGGi=rM/ǩDGi#چ&Bة)t2phn%ZIEQ>l:hO4OroGZQ]uCKL0/@?EQ XLMvM 3c`AY&9{Wԗ5PձEy!Ȧ&'n膏zJ|ngVX>ˈ${h5 ϛF;2FR:(ղb!Nb.&2&0r Ύ@%%eDr>Z*]g'KUIi%`,ctPVGСVc![D˶:!Lt*n=}da8AW%\f4YOeh\. !XW?FF9P@Q]%.P*JAH ]}w Q>1_NGF9#@eC3-u8<JB~?U h.Bɳ󝟼r+*xô[CyR@.NGYVՆ:#]3݂ysrF$g;zIQ%e[-lG']O+.&۝V3i4})QJ{фyBhOOm7\S^0nkg׻p[}:ۦ(ʍj<9ĔɊ9EO*,(Ow3YXZfX*F]7L'!Ă_x~aNdJRQEo{Xp],_m{MGh:L0zzX d_Dl2pzp8& t j $ܬ9dL<8A\n&E&]yin.B.HN> ϹMƉ^`߂kBxx*{ ?1;) M_X"A(,奇k+rĹqRn%-|}|kR+(ǏTݹZ\G.p@z Η5{(((2]*Ց(((7 }{iZr&\"iضM4Q}9EQEQEue. dYvFL&iYS5PYQ妑OTq_# xaFCܼsCq]]_e].(υe&$f0o. cSݜjc [~n+;T:B.:'HkS ̌ϐ5o cHCbY&-$ǻx= Fjh(ωi$#>BĺxhqyłTы?-cmkr`cvmaEi9‰S}|cϫEB#9u=}SX=d~%7D´=72K nyn4n Z|% :bm[V~i[AnBCG5Muŕ]eyն]as>ڔ{_|Gyӟ5t 2t7?޸KuPEx#=72D_2NuA#ФI"Dwp. LH:7SoI21 )zX&]C蜚 cلKVjNJK⢡v >B6{96.xhl[CWLŹɈ@q\PZ۪p@LN1N|AAZMuhH6S 𔳩~e]]}[|+pΞdb3LXZM4\X M0|(#GImv܎)2\:7i8wн7+Vt'GCMT%FtIgR*m$t%0S3t<ȑtZqN=RLMNtBE#,t{d;3)lMh._Psmx*#XΦ-( 8ۣ>'`b1<q̲,2,>v@s 3[j+܌ORJnBz,(rM +s_',MuLL(h&]0ϼm׬ 6#N$w3T5StwxEbe.a2?u'aȪ05[1Gފ6=BY*<Ϋ=pwy +DY8L&Ӈw R\ڧU,Gx:*̹i=S^sp{(ᾗ ְ"GFyivmuLOtPǠ#g/tkzm<_r?]tݯN{ЪQRFUI܆ͩ_9vOnVldӞd]#q%do>I'JnwVO?VY9A(zW_{y#]*) בqyrW'5͍zKlH S\ɣl&&{5k(;A{m G_y7zu6ý'$ o1;<_KU!nǃ;chXVCtt]G[\.?%xob~9]OZ@u Ph=4 9VEhpd:AMq%^ݠWmȰNX^ bt4?>1*j{|g;:1H-_oV-C`fy!%k() ﴿x'xou-1v%+/rMG״EO-;8.8#87XQ\SwPRV!3V=¯l%y9<G3em*B k$9{}ݘd9.geKY~55fs3EGA6ÛgYOOm-y &o"lm;̮!fpmӄ+q8 \hرO#ٰMlŭ Pak* sSܲ/H-N} [ZL|t!kjp+c-co3Ez H`g8 o .n{v|H+CG7ʵ|K_WCW? btWuMDQiϲv*B kwIpYN?[6/[W3.Zb,W?׏{!-BHT_MIbjB d2n2$UC#Xr* :DǺͫ(`̌2Stƨln"$15Dt& U(rB#9e+,́FJ-Md'sh\#!`ppg(W:CLZI᥺M(UR]Hh#9vqac +8A3t0HŮ0?o#fxBKO?5J2 ?UՄ]6:g&{yYh%+/"ݝ!\H)᳣Vwl0>+N$'w4.y(Vf~׿}49ʋzft{DƇyga1|]?c&&`{_<ݧ85c{333s?.oE'/܄l ygh<͹J;8Ks$\t! 2qtri,;+Y*J''^9W/`:e25IiDN EIbxuB>=ű,+;r*lX$1&-Z[\oc< 4.m [~u}Hi1pYtI8PH2B4!&3?>h<"&*) { `J ){k7IkcC}؁ Gz6+T:.=KhpA.n}_qKqW^}C10h*EI]v-}_^{lx TVBᅃ?9h6l~;,O~G951r$YeeIe3r)8nÅ#$%V 27GtV`kír;F]XT8 XS?xZQ+N_δ}oq`|8!X1:Ɔ{~Igc< K<&K5 :Ht݁9fR&K^.pk1 I3hxӎ1?LI Yte;93n&.4ֶ0l!1RD1cr[rX/G8%3Kd+-L t3W=kgpEۑ6yepēiR4LrA|" $Oa/S#u/BNrS4 !BGF ɉNNW;Ԑ]CA8OSK/?=[r/aVUhR._Eyy9x ɶ85|,]`nEQnJ/?C2c8bCE3KIV~.wǩp(]M W~<;AJEGmRfvG.%g[厒R"\^ N& xhmt&l(mN7^L.* := Ӄ';LfApXǍ_w"I9>ǂG!)a`#ml"'Wve1KPnpbAӂANg9Rp GBl}tf9{ξVyIDATOT|~Kl%:t6jgV뼲rI/([l\ۖKaz^iyBf MF|~Msz͏}|w$Xx~us}-ːe,Dm+܌V6HuUk>;$ շʯn=ƘY-ȧx ( Ts66Jv3]._ UfH26?:I()NL2!"Ka ϲ3dr,Lj:^ ].$eܽd~?W5>6܉=~df&$8?Ė5&EJЄNah2N,.&-R$0AO9)rf˲ {?7>vHRHW)~9rIrW8mr6iϛ[_ .f;2Iyh.<%ADnTb}UM2< lt\ +E6SRCSx$ib[ w*~_fCyC@Z3]l% }5m>9Naq8t!:I* CABbFfV!2X9҂epJax<]^gAkȗ춅b ?AB\.Vhƻ LfDm%Q |" apxP݈_7V7f(.ņ\Ԗ$hO5ǔe{NV\ؖ5z&l]UVbXq:O1ĩx]%| H=Mqr$] Mp&<`zGzAƌʼnf5l]G奮_n2ȝA"qKYYRAl1ܷraCC" ֗65Q3HfMN#he #tM%ܽj|S>b)gƻ7qMRumA;4lWRtM9T\{R )j&7[Ue$.@KNp)NݰB/'8S6ň$pӼi+-Ad*Bt G =8n…ń4!堬i5jp877ˌ=@rPAJ_ʦ bC=([}wl"Z:Y 旚)go ݗ.3 XҒN(g-+f燹rKrvdn- (rsʏmNul-w:Ηsco% dޡ6iKW"\!2d73Gʂ*!lœy{ 2[s/^l=1؛&bEbS/Xj~xcԹ@Rnnk=AOwM;:MaDJ.zm+iuB9;Ϟi*C\s`υ׌+*ϋ/䗊g,bhxꪪ󃮧C|cHJyE~.غIL$/jr+d~Bp-U8/['%+7=e%-Tj/Xf1b. _~Ļ]D&m!u ayo˼yܶ[Z  J ӜKwYn'/rsO78W ,}\+EХ(\4́Gsr* K>=XWH=x(ǖı,?V8TGYEQCƾ.<ΛHEQ>=t)((\SWԽ0?v(tne@LQEQEQFe.x.|^ϥ. J^r9EQEQEQeYWx]qKץZRKs&BJLDjlSEQE'mv-+Isy:o<]_Y[5 &>l#ظༀJC/Oڱ L,%u*Wob}} ;pNJeNJ аĖb mӗ6aQQEQ랐d|ʵQ @JǨރ}Mpӆ|Yh{ J_XGx;{u(aMura4UB}RQHg$BO Yy<3]hʵ$DN,b]c=yݬo !m2;Iyq/21:N⍧g8; y 2GZڅx4K*&;t7v^ݎ63 ėAIΞ _ņx?fpl)$mc6R~CU'y?P_ +9?6?xy/C#LD OI<2K IcLO3M`ɹ4`edM\:t((r} "6$| SmշJY]XւO8 )[ӄ+ dr#}Vm$ח YL|V[Vvy(ް$g8N֌«D=-e8<ܹ dž*CuI(}R),ATlشv ba/df\! *B`8MK6hXtNk&Ұv8{NJW-haS]1@)nHEO")t/LLNrǎ0t℀PKy إ;W_б.jxŷc G7"dSSGk)iQs+cE؉4Sv7#3<4Vs ;8Vn%8kgo[EQEQ>Fe3O"VmXјբB׳]/*?ڴosVcG  ѹNdbv=r93H\Ek Y%C$zg"Cw z 5Z:#ƵM^!W~H P}'߻n#m>*js">zt:N".Rgh?3fQLn),942L,12O 9C4eC7)%%mK$L =Gг9^kE0޾EΎ̐6%٩~"29჻szw>D}ة.EQ&!Є6n Apk㌏ɑʞKragIb}|J&3'HԌC{];ELN Ah :pmӻ&IImN_<1"Y9eJGhOOҝ6$)Tf3vt1# qA@MwI^s~Nu23@4 _U{ww20Ùa2C_,-]RJjx&b8}a0m[_b쥦prq8prq@ 8 tS30f2jN ϱ/F?%΋B:'v7m`佷H 3y#^JWͮ@ZaX?n 53w{=OF$z=o,+`>ውNí?巟{K1Vl(}xߥkZGj%B`&=} @:ƴ%x<'0,c,q^e31܇ P[[IX4K˧4E>\c9Hn#\R߶0 7бmJs((7 ! 0CP\ZKUuRSV}3/G F5Ŕ@7 #]TV^+McO# $i?u41LJpߦi4 -d5l?!61eZY^ϤDNү7so|uT@ -KYi=% i**x@i3=>NNu`K!vi,L熯i4]DfoVZ4 hkw^,AW6qO}1JKK/H Fn^;u3 4hp'wlBfC?椰ɣij?Hef7(d_/ 9Yf.tGm,wgfA6iəa(rBip9]8 *Y܍@ ^{T>[to'Ұ-|vxdV*AZi̜9nva]8\. !ÉaXeO%ͷ M`qO_Cֽ&:p⹃<ˬ^7EQ+:ƾoI14۷Q5G c7`ulL6G._ ۍ۝~v Nn?}\rAfg~  uhfn| mE[ KJIqQ!c ۟rPsh?'8]Op ;i.m#q׽?sL㮻`9񳓤S4lL+xDIΎ5ҸnᩗOҲv[mHrqFnR'spM [jp XQEyH"%ZA^)١$iZt'0hؾSfs9"Oҽ$g{;h )М>|ոkBl mx]Nķ[pȑߎ\Hq^=r\ճz%_TNyA+zײmclٸWnW}!Gn_5H_[7 {rTP<::5+@Ce9|h#4ٞqm2=˻/LmwQ0;~{Go_W[X`YLO?S]b@۹>|OL:I*C x^^0MR$9[``Hlpx]L~=h<>NCGHL:E:ka8xgSgR))|rL9(\#J1uiƃvs5vu/݇:&Dis#gA#3rlK qA=I&f*sceH0,"]hýb-UWqu #Ǐ21hKхT rd2y\x%w݌a`:q=:=E74zeA/͐Ng#ۍyar$9n7N6֝ 81FQ6} Lv m7le?˲8Iee=| 3t-9/@,f3;k>ٹm!reEQEQkB%e ut5˴.U4)`1^dzt_I NPcn0Bv)*O}}>K;$R^%LL),+m\Ay] =?}D/vҖz]EQE!IMsũدRH `E`/QߒO/>vÑFayY|W])梬ן7D/tͯgХ((,/5T=ntu0} RbvCg/TEQEQEQ.N](((א EQEQEQ!t)((\C*REQEQETХ(((r KQEQEQRA(((5.EQEQEQkH](((א EQEQEQōˮO$N OQEQEQ!dâK]RJ `rr>DEQEQEQ ʛ.t:(MQEQEQcj.냬TQEQEQES4EQEQEQ!t)((\CWؽ:/Hw((.tY \ 힋*e&xԸ@EQEQuɠK S.uYٶx=H&nuEQEQe[\p10B @J)Ҿg5M#LDFrAXj#?K41->lEQEQE|DMq885CUti2>o?|hfhW  .z|C$dhcy͟s>lp(M&ٽUΌ>ܺEQEQE"WHbd6V:z1 AFQe= \W۸ 7ZǾhΰ}j'tU{!fN:&15 fX< i+L_j\ԾWxWAJeE`#tvu7ÉBJ*j* c|K;H\L&C6;u.߹4Hn2%zI@h:]CJ{(*'HfM۲0Mkv#ΐ͙]̞]x^`(NJgM.%ɐuugw3JeTOEEQEQEjP>ȤM?+KBlNǣ$bL&5on[p3U:U`;|h,`eb:z(S#Oiᶭk)piH!Ir36LqlpqiIvX"?+I_Gc1cQ#\rSGp:U§ތ#[ɾAQj; K_Bhhah$5{1~ d4<:ɲ|sR&&i?DD`2d|AH;@G+mCI<"ɱCG"LSc ;vng1tT"F$Ѵ~ 5i{u?a\NR·̗((\疱,"994m.}<{4u -Wq[[BU4B}A4r~kίsK=_3]_߆+ ?yk(ΰOU.4p{}==8-W#0o͛m?H!N?2 d&9cw?XʆNha>OQttlh3>ɡ} F:ZTM5$n>*ZaPRE~,o 4c{u>nDwS{ìo*Dڒ5 -yV^¶m4lZZ𜍀А^x}ϳ6&mJoe_;Pеwf u8`IϑRPU[ORvhNLp >Ce(, $xeWrd,>Mwr9 ^[Fĉ (vמ~cd{S)ӅS˧Є@hpNLp/?FȣNJ+ fF IbziRYUL ѴNLpko6%5 Ct`׋ש-[rEQEQE,O%A.JZ00t c?XN}CX$iK4M0-kvB|KL.6I4 $T231!m'\gC-'P@umzrRdiJ]RjE+Ll2t઩Kɳ/wsO $3 s6ȏ@)ֲCdkLLD()""1=6JxGUU7I@d"EQEQEQ.b9 G膁a:hx:E,s.ಬ˹ux9dƧH-҉A߃Eg`: 6Ar3ضmض:]`,89'0l77\<" .S_J߮mKܾTl`4|N75x:QR(c$2̹>8˲dL]4 3>í$֮Z6@2&:3M,"͐3|x)1 rܤQ"Qbcl Ӳ% ѾzDz"v0:5P?CIrfL&\.C3IfHL2,DO(om6qێXYF n*FƋe`tN':NeM11'}Μ((r㙟PO?b^qG2=̤lEEw󓚋jtYTc{Nb9 *%s7_HGFʩ[AHu!:;+6oģ QU~4JFXRQ\K?$INc%>y}'L$I%" wsqϸ(dUTU%8~H MLpx ./Fط 6uuph6g6̎oJNz G;d3uw¦<|zB.mOp4 I eeQQR@ 'g,0SL'2*( aEٽk7Ctws NJ(+/cpx+#SpQR^Nσ0ll$qa8NJ((rC9<_oG"3?lM!sdv, X!s)f"12 8f4p*u:s)IeQ vh$B:g#t'P&,D7%drN7nb.O?8[,T.h󊙖 xXXσmfq]+M45<~!-(w;Vx,F2kMCC á1?mfE0vt9]=dq4Ãcfۅf/ql8BiƇ*[kB4x-xݎqi6xDl:-++[+((ʍ)so|DR g#)k)%PX۽Z*B\ILwEQÓp:(*,0@J d>rEQez KVc8S`K夨udIl^uEEx< K3c]z=\gYəoW4 |ة H)$ UzyEQS^M A$l**P+rLNMF Ë\dllBw0<2BMu5Ͽn6#cC!\.nW@,ehxښESI)%x<{@sdt E`ٷNj@j r9¡剰(σLM\z=~5VQd*E2=۶$ .{70m/4-Bvm6LMMc6BEe ]z϶l6GiIɒ~ddt 4/:e,(rۜUp-ʻs ;WK){.݅{-5J)/Yym\ÏEu7yq:C϶(71~Ap߳Er]ip|#Ӈ .Ԗ^%L7--_7s9,ᤠ0|sU9#2&` UvsMuuz]53oּ7g3==]ӱ]vp1`0`rH oǽQ`%pO';{vھ&Y@iY5paӲ@p{44![u!f$?ANnbK ^riYSkHtM'0܌9[o&op-,2OQM3H4t'|mvGQ m$2o‡GoYC#oSw-ƭMOLї,Bñ/Qk90@_~o 9n2{Ew=|4y L"<Éc,C_`/6xeŐ"~;Jf£(ʯtir9u^'bIަ|C<5tMP+|R1%i?lݴ`/UExM8!۞=LE2_)M, t}e|N76rD-ь}sшQ#?FYb[Y  ~8ѓwh9k;V> X|KA؍EF2 !||688n.I"ƒR=m"k|(t:pܳ]40dxx&+bBð:إ Pə IfGKvD_J :Rx77!x Mƴ1#Ltw}3v4-eδ̫vZ85SO4x7ܻ 4Rbx2X{ \^)Ǚn'3r_76&ݭk;ʦ![=shJYK[AvC ;%R{|$+nDݽԜŠwA2ۿǽEx^vqsۢtiqsM*2%i{˹{\Jp/ضWsL"?sהC(?~:9:Ft()᮪qu+=%HaiIο'O?co;IJ|şHZRBl}_Ŭ=;D !JWɚ-^z~ -`Yx.v~'(Iw`ٸ,$ ZrƓ/v ~ 3=hB k)ƵgRƒLi===l{ypwi5M_{mzDr|W=zi֟~KO<=1Bϳ? ׬a}VW[;xGs-l?)Ht]ð'14}  G}ɗ@HtCCfeFV>Ǩvaj:²)yTᴁL:o 掠sm򪗰2ZNgЖK)\Uˌ9ͣG|ȡl**)-SX}_GX7v "^AHR`1ŞA^i I+V鱍naTMcض,T|v;l>=Y`h5ٮ^M>̬eb?MJ …:|%GNwbZA2/7>#OppC|~ 4~} :/;o`Wk^xCN pg߯N_Hr(qٕÜ?{pV6YIK΄oA% jΟc0L~)22Z!ѐlWURUG6\Ǔ+@`7[J ˉC0H󥢵23G* G qƨ?%Bnr !#D"VH$CG캦yc-+=lܾξV4~ ig0E#P@%EStXsbF)=T"8| a9C]RNQ4Z!;م̭(!縤0UJXp9ex^yq=Gr:}C^ 5MO<i૓T-ZD2*ʍv3gG-& :/>e3ϐv1યgΜjn}5I`2M#g 'N_ٴiӴs{]L>] ੧& 1<<|GSjBjjAym3<ȢKً/RW[;f7˘Y#69D姡Yh$*ʱp/GZQ.~wv|$y?}U+*%T Wfa4C.FC$;;c$P3b$sI$Iin ?}s7sȲ-c\ IIJrɭlXeSqH:Nѩ qFZI$łG2L͗{^ʂR! >thE ϻ##=ŋ`m9iB!}}b3|Ɇx(/[q8L3qpq~ˬ߰M6#-mSnZ\/MC ?ǓO>z=ߓ,j*,B4Vz+eayb۶xɧ(+/dݽ.%9sOl%0Ha1N1DYђ:U9Dfr8q\B$R<]. ]C)ix1;=!+?J{p}&xcGj}8m`͎9&WX"%t4M~ ClV|Arx=X Kx7LR>SY\* rRCss }}-=^Ix<iK.LpQy:gytvIt*~]6,*ߎtX0'}\eC'=/5%>m?FIQv 'bG&N &.v,}C+4Ve(7=>\]b1";d.Mc8aJגDQYSUYص{__ԔT6ݱ~?ً~RRR, Mhkkٟr~q:I4UkVeQ_5kf-'%x/+ tV{uO$z Ux8~ ܎X>7*Xt~iYvASN j?]=2 H͡RM( dh}, ǗZLꝭ(7r޳kDa%Ҟ8[~?>]/S_k3>ڽP^fq3UNNXbzI$0 4]reւ.SJLɤ?rvPO+#&xp6/sU'#t ]67LNeB8 "q !Fv}q gFD& ,il& u;XBCut] uǻkxz)//D3aŒi"j#,.ᄦkd'UaaX4L_g] QőH!0\p$9xAbA%pnh >ۏ1g.UYPeYdffcc1;%N/)Z!?(GcDMjhp>'O<̷:[` bigF߬婇Hq?g!4ooMW e/5hh$]:0CMm,5K[Q![:IŬYNci^m ,`aQb]Sx7I:x+rәSUM8+ *I'w{=Kooo|WӤ> 㣏>"ŷ3a玚Y&?eQQQO<];OGZg/5rNeEiHsMˡz^aK+[do} z߭'FIlYY!M,$ý_wz:H╋8Сs]pjj,܌x=ѿ_!d b,2*Y!_?@ rloLC+7Kwoa{Ֆӿ s'EJ[WbN>nNp t$97Ԗم#,*eOb $2')W|@\JIq i#L?G>}'%ٹiS)~cv|qulDK`II,8@{c=-}thh#8l= us撓I^nn駭/DVaYd`Ls :!É@Fhlj%jKa^Y4<ɛlm󗰠$v:zI-Yk(Nw6 Yt!>l6'Esp <6\ r=DB 2Zh(('=5dS(^rP"%ᶍk)H1Fgh"7tҒtb,dYu6,(גi 4¢?HϣE^i1u-uqL-V-lki񯰄 vĢ,{v1Ŗe~o, KIˑʊXY=Un-fAU.]ǗU+(Luas&SRMؓ2()kF qB\HIN&9%BXNq WJ?+nceUN<D{ijiCJ|?4t4 pl0ٙ(7h4'rkit*\.RZdfe$R\\k뛖%%%9eFǐCZz۷'Z'=b(d_2rww/IIh = #p|;Bg_?ii`鉠*ü}=[w1BAxuWb^Kz Eoo))8'R288HRR`? &)P-dfvOpWmQb4ImqgA9n1Zeų. Ĥ1_c'=drd!x˛eƳ #蚎Kvњ(/wsq#]e.3Q~9IVK&I!7uM;qci({~!~}FοeH9U(x‚)hk$8|)d'7~z$6 ܆Kم"3##]"`G4Lͥ(rmt8Rɟc㗹l݉1ge̳pgq"5"yKE|n3EQvtuw Ü?HIIK?g'O7ۏۧ}wVcbE\*)%)))<ē*e1o3. 2f23򊂮I`1q{_n)rmI)xygsTS\\2W隃.>1eQLQIJ*p" ].(4 ,xIg͞dbMĜnJ*REQEQYiv:5z>_0~m{5TХ((({QEQEQEQkn:Dx7*((:+ A4ǡ̐|>i60PQEQEQ]u[AgW^} EQ RSSotqEQEQ:Lt^_y|ٟAQEQEQI][25|Mk(((27iB`&4>BCӮ>a4-`BZi4%-iN_߇ka~󯅢((ʍtMALˉ44MCIgϞȊ rz' j\\{B6l66fVYX 9y@_3;>9D :auDz4_<1yqbJVx^{O'|ȶgߢ~06+ަӼe=5 PEQEQwhWI/!0} qP]]ECL^+A}[ w9MyTgЮ"@1}-Jú}B}|˷~9La,˺l i!ZΝkH$esR>o1v[޻Pr|SS ͿgޅϘ>sbG֔˺;@-lj~,yY*@ x=*=n9SEQE~9Ån>$es 1WҊXYƜ @J _6 T(k BÓAp:j|{ q+ x4;s<@&8j@ZɣoK}}:|p82|^IrRK,v?2~$֭K=FSP$"W{\ȹ2"B\,~2ơOw H _K2%gEJI9߇Y:kR)Yʌhi=oVwXEQEQp#3y+&,ZjS}] (q"+0ue6 殠0qn xm}NǎKII1BOg8q\>h9 K`Z =m _\clr~FB 9M\g48s.ed妣[RS2o9\z_]:S;kןx|Bqe&K8а 1i51=MVJKL((暳NٽPJBa.Pld˒!0#!(%1n\CDvDBCb&xN4a c&ٺe3).^lcIB"б i^JK>@`9nprƏ$1P ;h @#Q!6#!LKxW=҇daor Ԗ((r}L,422>/b葇ټ C@&a,}# |{Y ilO88H{G/ի2l!pޞn:_v7ˏGd9Kyd{ \]8{¸r._)}',Xw/ga{;JF"</3lmX R<5+dN74BiA,Y5z=A@0H,]n!y\`&H-f/Ͼ[6RM=ϒICԴYQSpm\N~Xjzi\~Ϻ2_ o~ܻƃ?O8ţw{iY\94۷u-9C]͜k88*ﱧٴ `;>m,\aݸZ:( >IkTr$+sm(( 2^NkDz$I yaY?ǿOL;1D|,01͗#D1LZN~ko}NSQK8Î/s:M <ȷz*2Y87q:]b4X7ҪfYDC~N@m-M/žߺ{'_K{8U[Ù!D~"򍛹{}$5_'[ロ{70͞Z(GqNvs "O9WWs]mUY9|1cr\50JF"Y1om(2| wq{ٴ"?W>=h1w޶gx#) OR6Vb !>\ oZ&+ټf㩄9sx7N(έ*''|tXA܁s|$!-'\>,(l"*}Y.=mM`E{ػ};zݿB_=I06m0az K##p#htm?h:YYPF JG];>-o-r[HqBtp|6mGؖª; ܗ{`Z Gپ(w>K_Xw~o=JE EQEQF\SKJSt?,w?Yeokǂ,KWac;UW#b-F3d}۲'O#csR?ކaH=S`G'sS*`Ot]vFܒnǒM4͉xB-> >W"k;;> s8NiOiI)uTKN'cǎ!(/+Ow q^ʰR'XS~7xw7TRUEYdP"]ۻk]*2XEVJTɳ;wyXEGGU=%0!*_[k4^"m" IYTf" */"nз9}y4_òwQWx(LsCeii BOò$>laq91IJv ɜ 4'ի"TKvVGaN%%؝YT)#/ /.<5m#>׈ BC6äm!v,KO($.:M*Rh̼q@&i6:viUK961\,]5,4K:虴D;6->,h1!?Ѝ?'+1KkcL7}CtbdW?ޘDӵT !(-)FlO?{7zFwm)%;ew|  {Bx&4CJ@(IlRϣE!氮:nYo^c KZ4Bsd|&@Z˲pz)(00T`0.$hŽ.,b1p%@tt)WzfDN )l^A(Fd!*Gs$nelIgL[kYT$nLKvNXl7u7HaEQEQe,N;y*XZD I-+Nbd.Á1zM:HJ'ۦo"8 ?8DVZ ).;RxXn9UVƢ+) g搛eň-*sf?)B~q1Ɏ$ӻIq4k},WTDf'~/tgeR B|g&τiZ"0gszq A]mA:G)qO|^o=;?.B~%>}@ M! t)(| B5g>wc!V% Y2V,e;/{;ǎPڏXeF1MpxXj/p3'9z's: R , ieYWA 3SpWna26QǘBFP!LZOjpED_oh~:ƴ,9zGΒ;qy5Co1 ,36]Gh2Ѐzeæ5eu)-V[Bnc߱fv sdR9z(.XWCmS7p@ Zox:~¦üoqdžu-HEBrظGGϜ#=BG(υ6zz{}C((N  q1X!}8. øriVckoh.;`II o5=9Ғ|P;{>>9%gGaAéck&R}dr!m"j$SZ^Nv.h?}3ͽhT2S۴DW;le]u :))d]ӤD؜8}\iduAGQ>uNNaY9) PwF5PvX^C$e s{v'p˞JQ^.ǚdc>̙S'=OF. 66%j)̩*'9sJ (. R_[KÅ ;F ܽv>D~hoD]k?6#'SKvFyEMA._L rq:ѻ8pC#t_\BClDړ(.+!#ɉ墻5 D 񝎢(( "dppj?K]O0dպsNݢb9L&4 6nR[+& cxݦa""fwq9ݙI($rmbA"1 ˍۑE('˅n׎cFAL $N Ø~r X?>nv HtqzbxcDvn'cB$ff`f{\=dee^ّ M}!&55N$``$׈b#ANύe?~ֵ|R QS6s5zh =qňF%Ƅ7v!ħmg 0 '13gAh|>6É?_ÁĖ̊Eoi6n"ci6\{n ]uOÅ 2-p p]s0 b \n76bc2~:Z>ph )6=o!Lυ4ôtk`,MN7Nm4M$ a8\]v5KQEQo$4ijj&??b&pjJ%\s"MbLx9F''9Dpyq7*x鸼}mNO gwV' '-'hobɋm)Nɑ2zc|L'-iz][ϫlm]]X5eOÌ *&$<8M|6rn4)s=ŦZ@h6쎙pKJ"0]l|\;ϗ[f')qgqnw츸]vu|ɩnwt؝qb\^͆Ǘgt:cǔf#$ƙ;9wT{DkgȘ߳߳ szTEQEz6ܴۙl)M<]:Ӯwe: F,+Qɞ|BL60񳫽nWAgL$\kJ{mN[mC"(uG9XȦͫIpewXY~qk((Mpm-]4fn?N=g9{VyXz_}'Ǜ>知܌ MST-X((WiVʘ ZC#m'OXk̒[+h!,mxIdffqw\QEQ{'E-wJi9@< d  OJ6Ui9tRۊ((tŧV^~RJLӼ }CIiN((캦KǍ]^((+rMAWJrPfȒ~(((:Rp׻׈ۅ)((rYҥii7EQEQEQnZj"EQEQEQH](((ב EQEQEQ]*(((ոl" ۍ]VEQEQEQ* WapڠKJIjj*=.EQEQEQ~i:ke[ ;+F(((MJ.<]WQEQEQEQ%Ne/TEQEQETХ(((rM^X)((|M؀}S}8n֏~G HFZQEQEQk0 |Mz]EQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE~h1%tEXtdate:create2017-10-09T15:10:06+02:00/$%tEXtdate:modify2017-10-09T15:07:27+02:00TtEXtSoftwaregnome-screenshot>IENDB`Eqonomize-1.5.3/doc/html/C/figures/accountview.dia000066400000000000000000000031551416454732000220450ustar00rootroot00000000000000\oF~篰WwٟtTRO}3Z168^wlKp` fkyt$'IhM$o{B4Us>g`^h)(2K?*۞A1MO;Y;l-KJO@U>~@ qC<8hq@TDD#ը4#H4>f:s s<0U8IlK @kl(n=DzC&(m#^@?L\;Ҕw>A%' LR7@$—yȓ$G:XNj$Eau&|E]%?*K 4dMC 8jD@\NG(mXS1D>Q_,v/#?0̃!9¬.Ë[K+ϔ}elC킺TK@ՇB"ߋBϼ6g"lmw6>ÒGvHm6$;wjn KY&A,?VښzGPF~3%x0n"3R>KQj7OĪzz) .qz4-NQ?胡rhlQ"~P<. Ah&[NNMvղ@խNQ%*(Vܰ'-PU7yt*s]B`Q_*Vddר* kO1\J8-"^}A)w޶UV_BרB!6om>QP(|2' O:4/é]Ԯ<-NQD: VJ%"/ 8:jW_CרC^J VJ9$+%JP)}~нFT]4T/}mok[2KEqonomize-1.5.3/doc/html/C/figures/asksave.png000066400000000000000000000370551416454732000212100ustar00rootroot00000000000000PNG  IHDRhdPgAMA a cHRMz&u0`:pQ<bKGD=IDATxypy;}w/ ;%Qb-bٲc+vKfd*SS35UcOTԫ$%yy8vlE-,lH bwb3܋ {O G,;9I3GjJk|XXXXX|<4}__]0gAA"_']Z  PFp:eU$;AO!р+ N,e=6@gRJ2=7]yo^\EU5xw"HAY iFFR|H}464 [Qϖ"\-*j`r %s)%ya!0zꦧ޾>룧nGgnwӆ$$ĕg!@ vM]6Mԋ{>6mG92 NO.UeX ۍӥ1) OgUO'cyNT cwNSQD:-+Fas`b垐 l*痿`v! M_O?BNݣoSA $j.")jz>Ii$S'40 ݍpٱi aSkܲZPBğ*bև'Jvb&RƿWď1<|B,87^q4by=_ ɺ"yM3>%nCSTP篳Pkɛ+1[>P\y-Ɗmr^K[W.X}=.es2 %~_-iĆ4c'6 UQm!rqOz|!DQUxp94LSLd_AN<˟}i vfgeEg)&{칙U( bחi=6^L_\ j OY{'mؘ.YՈ.,vWT E]J`j^}$HSWSIP]k(̌F-]R¹ Kw{-Lg};16' Τ!5ΉӽTOMzK$d2z&o:?y?i"@w[C39PBﴓ R>-¡Dh>:+fPSW$J_%Z;(?A{U^.663I`-N~$0Ocs? 9(S\jFgVA.^lk4Hٖܳ{ M q*`T*<WFlj0`f[4L2ٴgd˗.KG<* I[?Cu9)C3t1 Vl8QW!MCDEM=QJSaKp7T%kgFinjfx*)!%B6QN(mFm׿`O߆rJ3t %n(%ѡ|#q6ap\ pO%}*i(nOK#p/W:qgc6Ө >CAp6ǿ=F& {BHN֑F\5ܻs3`/{Pm#p\')'lrz"(}os13S4~*cptpp#o| v9~  ]?%9+1~g!Ii6ngO]TD2߿@:NRY"ī0QptoH.3#0u/W/73$G_!??HT16m~7i _xOw+*W›WȭAmI*iB76!iV]&Ё7h pǯ~Ip34¡o08s?%MC ^9oͣtMd3~=ӯ( ?W>mgOqw!(x}>.d+?/h `KHvj1BSY L΢h׊#qU`(`Ǯ]TٿxA/ţ'A("ɫI=&Y pcȭ_,aJK0P ? qB9IMM#aBz&6dkpdGMP5>I+W/i2tmNqg1PWf9HdVP@CMcCɥx}-K!%# j(TRSIty+>:r< hڲn ŘdoF PT{/<4LXF+-gK.J])c]y%#R #Gfp̋a*Ltq yv;R"yKiLflPټ?/*q5\3B Ov4ps] Ӫٗ ᠨmd};i?9G7JY%PYRR{vDku1 4j NhgOƹpZr퐙goD N_'gSI. mfJZƎJVY-Y>3d:ϱ7Jp bgǩYL(Uv:-шoD 5I}eW9 +% N͆0 z8揾l'2+v_/5x.ΐ{ؿ.1V=?4_&sO/sn#_ݑ@S=Q4i\Ucܾ  >Z6MSH4O")BA&Fh.<}Q.0=\j RKPXrqKbENUuNTQE DjEU(=xR1Mɨjn_WP5e}vOW:tg^R/)^om&깟$-fCe C)4_u:LvB!!zFxpSμ51ѫiCZgIV .\@O, +)TK)qsUx`*\q z80f`&;f^~._ic24M @_N3^,(Ģ_Jeo( W͕ЍEK7-M<4r;ӑ(i`uPyf&9w7:T]H\5|sŜ{'KtvD7nEzZ ףa e{-knWqLb˵Vm`4?HD8Ua@JS>>ݺČVz%{YMחxŁe%F01Ik8<݁fD }A:r۴%JLibv<#;~*rPh6;ND7yEŹ /^]9ٷgn#@&o ,&j2UO[FJ!bƭE.bljFcq'SSYwxx04c" n b5 Gy"é16>ʴ?L4bjrn̍EeQ2;Hv * ^7?$ 26<¤?̜c<>s/  ( B (H!`~o[œJmE);" %ֳ@W-Gx_C^++:HKUS|eW6)NBpPiC 4 T UD&)mx2KMr)#HL a^4g&,j7!EC*v*H\7?d`rVa|t ! Fl8wa2d.zބPR3?`odNN6S9aP5Ta2Tn%1٢7qfUqlN^w ).eI֏hxFoGNbb* 399I$3V\;߹*BA cXť%ro ޾F(D#mɬ 1*(/'!M&+ wBf1j(Bs10>2BP$}QyMfi?v!g'N=I$AQ>DWEiY )n#@:rWNi^n OJ:v?n&F"{8Mڨ߾ `I>r3mUxl̩+Cab<'t]:omQZFMEѱ>x״S#au7sG}؝Id./QC;Acs?ɥedi[Tƭ{9o8 +\U6olBsIUb x1AZs\7qsgJ>uդm]DFjn!Y)Y7dN{FP)Mfrp%%4"\IĕJMm H+dƎIyn&cGFu3<+5"R]Rt8-m!#AF^)}-l,ƭͯ5Ls*#Q a󐕛Oqa: C z$gPz"`fr$]`a`l)4s).QH=@wK]car)NWInv.ۊW.p fqk$#" =u;ͨ1\jLI __&֭RTE4|oa}EQQUr})cn\/6}~<"41%2IBQbXPsTEg ̱5y̺J] #3U5PÜzN_p]3v,7 U™uXvPfl1 m&so1Ww2(X(aXȃx,'"JiBm5)Y[t./v,]Yp%fgUU0휿sqMϺφEE-^tglr]\/@Q{Ǯawuۘy%enQеy]]yq^,ٙN\.fHل0Bhܙz&u]jo<- "l̸rXZOqsf\N80yf)M YrٲJi/~y,Lh7UWs+ Ir3q3+ kI`qQuqM}.x;( +gv6t-r6qۍ+*KS}4MFkU4Wʅ*sAtZ e ID"oțSށAB !v,Fܶ-޺0pe!/i̍K#V$ PonC"YsNHfS"o~YvPE J1xfgp{J! ]=IZXX|h_9+n)N XG|<wRqL% :`iÞJLMFDz08o&WihokЋn_-,f! |]Y`]|F0e\Ɇ'P#cRʉ #Eݐh[:_O(\u',}9Yfdw'RȝbaJ,Tu~9YKʩfLdp(K0ӐDXۧ! J T-_ xs_6RLʡ0 WFկwnqx ջ4ypw6^x=(cN$jL^idEy_q;@qu A$&;9EkҳsIp:HH+*\ܣqR[][dٙ4@_s̎|Ol4YniqQ 2(0wOS]6 *o ݦaEQc:*ʂc+Bm^zp$ٴs7  a=?~q7U%i iFuQT嚗f䂿o48]@sЩa$z\x,-{_u2&P@gf ^z}`wR[lbȬb4ZԹAjṕ:FC QC·5Y̊nF]R(il*s~d# dl'9w\ؕ[%R!Q@bI)ii؞Džw.'á>N:LS^^DD`/&Į@<(M9Ô/D$ZC A0I[ؗ|#ވ &G:u΍xkL ruDR ,2Hy$#a~?P<CN9)HD[ΆJ;2Ǜa)%oY_|$f'  Ä|46\sȷv,,n/䕢"ZvH4'-DlS*s{*ߋA~?3O$YX5P֪˅2j+籽p8 ?|t7.dz3H&{{6<0q7%gkMvchc?Oǩl?ͥ/!IH 5D( 22CɳN1R6 #47؄6/05N18~;uDt>Mkqp!~4Qg0z#otɀAzn*B.lXCAV鳴yх >/~&*gy%Q̉K+:sEUÄ.cڌ("ʤf[k0^ENZ"B3Q2ұ)zjg)K#0K$+ҲB}]DIʧ,? el1 XŌf4 ''=M8#DMÓLnN&Z }"GBy85#u HaG3@jL|cQ|x$EQ!|f7̝ d|؟aqJ{8" Eabnd 4#1\r \4"L7fշG-laaa"w܂6a3n9>i)g *hn?G~RS@CV}aY̝SB/"T5 haaaqA*wb]],maaaN:RKA[XXXS>͒,,nwE=d~ q{6-m.Dcƭ: %]NRRRPUuQZ$addH4])<4TuʉDܽ{U$Q4 u@ֆ(BaRbJ34`SO>7+Ys[EUi\vqX_, ib,hEQi~QWs9KA[VHervFPl4\JIK@|Zô_8<edؿUu|N]fRIcQWUT2J?wIήwS[ԗ\1i.! [/ry ;yxo=I63a0Hν[WSt8Ԭ*Ȃ^ {ϽLaSnccy.W㙟Lq>ĖI}}5 2'ɵ} /!^޳6FFAnFde$ -BHU@6ί_{Mqf+v]e8DiA_Ͳ- ׻D&8ETf*>4E!1~K 17ve&&sK.o/>b %n![ي\5B%1-M;zKő|VRNϣp>In fe^kAngRݼv Ofoi2Sx=U?ሎh$%%aWbg D,|z-9MK|yC)Lk\Q?]]vq15|T΋x6IgK#$Hs  2=1Lw(|[+WHAz ?yk$F%tLJ4ܙ'zW{}O2Ҕh <; OlT9gyBbR(y 9yGc G~uh|nB=rBM`#_3̻'zܾTLt_~q|Q(ΞkOӇopaþ/<ŗ \2˂X,$RtaFF4M\YxzMgbwhCQ$ i9dg+8MQ!E:QG] K&ۭ0 'ؘ`J'nXbe f,{2~?YSܸ]"o\jr LSfuyαs< XOL*wZ 5)$;х:-Oo~Ä]xLQq4'9<&?yWWeA[PJ>._lfژܙ챦ĝIΝ8&B[W@HL4MPT &cffDi`JIpzA(@ZZ*i3k.\W|M9/ֳHȫ{T3/pe"; 9=щ)BQcMʶr=5Mt:VN2‘#GiR((!f]UKqET9($EFGW7}a6{5ؔ<>qvxB053*kBt^:-ÐA~n)fꤱ 餰 7-9D{0vqߖr\ 31rxwH_/#M_y jBOZJ }P#0"U MK 5p:]l`DDu$ 6pݔEǷ;5cyZliLNp8lXRJJZZ"z{p7_2(Ht,vmq7Yi1WLp$!AQ 7x hoEz줥CG#D1EӰl(B ll8춘;ĈH`;H9FffyjjJ5 ,uʛ%N#lv4}I U l?QZrľ& 9\wPp8s}\`/_^Նe22) ew8殍-`@9ЮX{.]ZoJB O77ny]Uk%]Avs{z,+Ԛ\Ոg)huỏ)Q9V܈n~uY bpK?`.|VvaqW0]6 ,ŧ!h"Dz q٣z u]dE],ag RDFFGrHibk/%9)A&'J;ZJp\HS3w2 đR@(+)!.˽Yrs t1Ns*Y=y!Ӭ쎕V-BILLb1˞HBgO,bb)h u-,,,)X)h=-,,,>Khq{m/*O| >ZXXX|W_]6a 5},,,,,RJRS>bXXXXXXXXXXXXXXXXXXXXXXXXXXX|,%tEXtdate:create2017-10-10T16:53:53+02:00d%tEXtdate:modify2017-10-10T16:53:53+02:00ܮtEXtSoftwaregnome-screenshot>IENDB`Eqonomize-1.5.3/doc/html/C/figures/categoriescomparisonchart.png000066400000000000000000002656371416454732000250260ustar00rootroot00000000000000PNG  IHDRGDbgAMA a cHRMz&u0`:pQ<bKGDIDATxw|]asEoHT$vRUݝ[;d&m6dfgw^yM2KvI6q'&YeIeu{OqKE}'s {9>4Y̅򈈈m fྉ.Lc솱X2O$bTWMS&s xɛl``3D"DC"L#yyyL.C0l"7ٳ'''G!qp @ cK26u,Phl@6d2׋KA&<˾IS۟s;<H;5Oe,"VWey+0 7R$1,N|}1xٱ71qݑ7Jng sq\o'^ny NDD [2ܞn~1˘~7uIc,,`yh=}w|ك< fIXщO{A/飴uϑbޣQu}cC#Tަ*pcYq~=#5qr8<̌Ip\R>c,,}U:WH v7ygc=l~ _&+W~~7lEu[iz]4).~@ ]} KJ  ~]> ist,C`i3 qb'O#eKxfSPy`yTF073'7q<1NΜ\G/@'*b2+Y#c]qejɾ&+tYKwG$;E2y6D\hZǦ,/Z$qm>Şi)ʕ+,xv6c\N}~t8.x΀cϳYƺ2/~j>D;ޥuQ 4-124sh [k<֦&ꪋ0UH}7Vص!h~Xf_Ȭ̕2S|ⷾ=nn[`\Qwg?gER[SMI8u/E˖P2lff9yQ3jUYH Q>>zR` ^fSHSVYZ =./qv Et+T}>̾媌ul5]WM{?DK:gS]P=N,ZRߚz¹$[OA&/zRg\>wGd&+ W9fȭw qƉx@'E3^й}9wk!ֲo'fOTѻpN>m_fϮtol_M_'> Jlsa[$1K_8KsY9T8MUj<c`xd<ϐʭbZE ^KnTTR>h RJpO_Hy\Eq||g~:5|5Q0v:E0!Iƈ'mrA<;e\X"~kk 8bDA+ s>䍄b a\۱(," 됲 9iFM1 5G?zM}+Ys="e:H|WVkt hP9 d"F2<-i\v=SīG<'_ 27\6].p^}c=#\sl\,_at/@:kgYel(FljC"vDX#gmgpIO"7'$ RG(%]){ܥ Ҷ&@$oœpd;炱 ?e]&E23fO_0B~tK"_9c%ϟ}JBk=#L4 X߂17eXsɽ<+Da^Iy$zس -"̯rςiX`g;gٷ{zCN'ybU &ڋ851"lXƑbkyrU -_[?=O|l:MPw[,qgA ' tI ћdΪͬWF-}.U30aEXCƛ4&yӏ3=k9b)MGYy3sʢ.?/k'?rԸcHsn4b3į~!*8gr!8Hp&):nTMQ^>#l`֎(}C]^̓}QO`dL&s"C}>[*ynƐ>s)\t/dz4ndb~Jaz;˗078kGYq8Uq7_4il'Ij_D(O.r+V0WlH 8=\cyʈG4{';xy9/gydݬ6rmW?slNz^߉&EBw9_Z8M2tLo5E}@Q!.o00wVݯl<|R/Ìi9s`+Nvݟ?+O3~[l;D;M2w`#A߻mYW(LJXГ|9|e=ޅh?.>Jxíq{7`׉v3wKgRp5_/}.{y9s?y:r:::yW!|H&q#elx|bL2[OAx槯s7]'[;vp Q6{Xh}|Vxp9vī䙧ΉҮlf[oؗ~+/jv>3j 'fh<}':qrc|y~z8ɪMyc2+bS1-Y7vT2,fO8˼sQ.XDEe)%s'.A}w+tc }vً""r.<N%O~k<4G^~a4Ƕ{V}Q;,Zs?wUr (kݧ;Id\T/a.fGc4u  arYd.ɦ]iՆh_el9'ٴ7{c.=\tb[Qg m'x{;iN0w}I*g/ r,Ɍ3~ϳ,xÿ׵ b0?% ffUO Y{|VmiU:PˉX)`nM%E,^Hw6YC!0s쑖@0g GCjĒrx1>x6sf.$7}󪋈2gv-EKɧ?ͱ{9غ u`ixw  YxTMdٙz`CV|c"0sj8 2 ;ƶ$?y%AcṺ́s y!E( w27y+e-.g(*j9L0)_C ,+"Z]'`򩪛MIi!E3sתsӜ[|B0稌뺔P]]ūC=W_g:ʧMk`9ȃ5}1<{kayK.9T_7yu`Yt{ZTϛKUA *EsW?N`R>zJBx1pY7ED0ξn +}~s7$~*ҼQFxG?I#PXͫyLJ8y-tEsO] {^T/>|<ŋXEn&1􁝜H6p'v]rϼȵ< bϞ&Wذd& ی vvƠ& k+ΞMivf-Xƪx ̚]GήF3=" 1wf>el#4ִ\>`8B8=n~VV|4LNUTYW0 h gOxXV`?.5P&`A?OZ*e+ v x1̞dkbXlֳDBTLq\ϣvfj ^˻sAY,bˇYOr\dziL*,bz=/O{l%sR;±S ;+ۑ+Ac͎!s], Z gn kv<-C sy -p3>V}x𳟽 x,^u.ym]|G$,LyE9]0e25< |~ ߂2xgH̡xt ppGf@\o|>#>uK5vzcy pHCOL+}v5"sS+{|W_!Yee;h σPn>Io 9:0u־ {ڼ<[^m&[Y?%ңw ]oy.ܕ6{^[?~tec f䮟z+Yv5V͚,#z_Se ( qh'1V6Dڶsڻ),Rr' -:I<&6#mzWb8w~2cp S=p 0sZͲ8]va|VTb9.jř68nn(..d<]ۍ&>um&bI7{1} VT yIGŽd<8^7~R|5w cG:c8@<\;HauIƇ%W.֋Y>WG|/ /x{3&U%<70yns-tg]rBQ\'vzeWϳ#>waT~Oܝ/~}^u3:۴TJlFvqqGng>XN0H4N:#qU,bܵrZ"Ƕxi؎8V^KaϳΜ`wQRV3%Nƛ{N` `c8;P\1hdښ2ڎneziҊ J rC(#j-g_Iu륨`0xƸ;omLkj)Y``o.s]ԾNfQU]KeI#8xbFM~N;O1E,XPG(ƻmh[?E5sUOѭ01;yfRYU鹴fӪ)/ ֝'(cKd_app# S=g[[9=Mڷ-oŖIVYAnA`is+sb{N9Ďm[yi%|&y]NuVfviysqҁ|fϫ(?3Ⴧ錹SA4/vq@<‚+Dcd yyy8r M;wsԮ{^9E*Ȍ2%̮ Ǚp][Oq ʪ*!8ҡCj<>~ptfe[:);QSԞ];@SgEֳt4Nb q'yo_3U3{zvZ75; ԰vi Xcu\ Ǿc1i8#`Cw1~sgp%FV=vh#I.(̋`ݷ8tTxpGcD|M4[RͼiF6qhIUL'cdg|A Aa\{9l2ʢ\==G ,cY]1h}D#rrrv(?ˏ_/|ЁiYݹɌ,,"kņI@(I1< %'Nƈ%m~X,<\&H /n@OqqX ;邞` h;PT55zDt3?ۃGv;C]&Xg?Ο> 7b8},:c --Kmm52C"`􊋿=d"N2mc,  ]}$dNp$7'D:ǶD!UrL2 $5!rFC\fh(F"DЙdX" $3?DNyة$iG8kT d@8rH8&@4la6uuɡ!h8KΔoE^|`4wdq  '}}~FƐ>ū;YoݵuȰſSøEcܗ?cH CmqcXDD*";_` _b. # {R= [}A .G>>'b P%0Ȃ!N2P:_>b,?т±4z-(itɖ:R"r/7f,3fɹN .%f  ywɍOq/vѼ{:|AHF&{  iw^uq꽖绬lWxuSnWxι+Os|W;ZV3:u~sYF~,ppar˲"Gjxo|9+S:> '"!O;z%*Y݈:Gk}+ߘMw u++>ʟ}>;} y3XƦq#rAkIN6=Cذx:u)N꺐?c?ȶ_>KߩYTO/#?Wsߐ+AGDDYF2gHRt0/qI 0OL/_!RP'~I?Q>H$9\`O˙ KeFRRs"""a\wg)NɮYv1,.^>73=ʥr<%HM˻"ȇsuouԵy{՞" >ln9w[3EDnߩ? 9Q1! 萔[ϐL% BwDB/7mP2il?Bxɛ,P[[;+r{3`YևI3i&(r)ǯȍyprTp8D^^ea12b:vdf!s]WT1|.Ȅ2ƐG^\h4J4bܶpDDDDDDd\$EDDDDDd\$EDDDDDd\$EDDDDDd\$EDDDDDd\$EDDDDDd\$EDDDDDd\>:,cF\l&<< `p81 """"""'@&Jݐ0y][}>`()"""""2 |> yXXXL|>DԈHܠ&EIIIIIIIIIIy<DZq\:.DWDDD ""SXێ4c18M&ʟGY>=<ѥ )""7O6ޏ=C?Lb{Yp:ax:t> )""2 (Hc)VK cc 6=+|y#+<[/wQrI| o"^ +ēPw'"""")""703:Z$u!0e )""#O`! }ø58=\G^QVmۄ (+ओ 5D45{`~)3g͢(z.=?Z*fK*^'ud:8s$jg͢8zYtF{H[a** rAt[9D@hA 3,/&軠Ԟ@WMMO)K'""r(H-hx_؉<o)/} .X?E6mΑSg8 }V#}Y~$ X!勿6/8ϽN%Qzx]/ tPρG(\͊|^|u-py|o2(aziFu{Fp`(Hȭc ൧ũ7sq)]4&<>z']˗b }8&̞UA^Fj^z+Iwsv~lPN^gnrH);說cݯ+ W V?W_k?b_Xri BVlλ4tsz+|o,!䕧gi㡯g"L-?q\,/ן/L{7o0.VK+_i>{ێ`v:|eie>|׾ я/'{>%XVqܷ_||3㟰1%Q:{ 8nn¹'2|S44~U._2sʢxNsC-yG?aQ};9Al gƪUs`0C[xFQh5 ]* }X>OZ>uDARDD&/@q۬P}:s8{f/Sƻp.WOᐠDڥ^ʦq~O()= noN?;ѻFKXy ~C]zCz)ZNmE//G DNO`zkZ={=vů|*kL,f,Exsh36]8tg\"e4Y&;mgV'wO~~>9 S_k* Br[Y8vs>'HqyϐN5e{>3l_yY-G{8Qs^&&\!H4t%I*zBٽ7|duܞ_򃟼KJqԐq]X~1aRSS魿?} ڻH3;߻ջO{t<>{,1~p ꖬ,ij}*rxv?m;ͥYCl?F|=_8/R [6 vW-_}^y~o/i!36H3m8v-4&3=<;Ų-"3CP6C@4O/o;ͷxyOgk?{d 3ȴ2̛DDE7y1]DGf@5,]3c%.~7$t>9y z8烤)+_:# % NcܹTW]6iO2g{(?O݂[x[Ǘo}%ː]Vb>%#e/Էtq B[t3 P8w#oVs:UDDno /@ON4z-w2C'yšџ57õӤ2?H(c?Nq< v¡JgE0R~kLHRzO\vZ$EDdJr]N`Dn7?/#AWDDd<4َL U4{M )""S`1EDDnI2A1qؿ{7uv6)""riLr.]x#/^F3>>ǨNDDF7Lrӗl7os ٖȍ )""ޅm"""rshLnK2#qnSݨr<qAE]yhi`0ac,e-,|Zf8Z&OAϛhةN/0! {Nt2oZJ#0NҢЅs J7|.6f.\<ƅ[́m4[KX8rxn}nB6<0w.&}{??k)w\ڎǮ 3>`N#Ql=UmėfcTܳȍJ"""""I][e-)l|{6gÆl~a>G9袎1i<яr7` 4p)Ȳ3 D1cL2'4D^sw{, H)s*;N<ܱQXA,YȹDrIиU~< 6-A袖/ xaVF{ @uqǹZʎmcuXϻx̡tUsqlq2У **C5l|/|O<?.s$G[--o2-p/ȭ,/Ʃӭx@$;XTCmV"s=7'um0wC;o.ʁa- pRC:=Ax-eͧ8!A:m_9U+QP7l N5T}# p%(w7kWcċfR<[ƂpvW, uR_D)*ŪEUxmٹDuϼiD/NYye. /816l'v;K5K8vG$'riJ9|,bNƁ0ʥ_VK1-{:HUMxERt´b "|}!b^٧_hGʋ?}xp:/2Rc)NfHv>юp^ 30r>?}cPWSE^У~7?KJo?Ƴ? 'B9x=^t 4yccZ|NV0~pc.];xZ!zNcXFN  E]) I"!\zK{d6떔z+k`Em] jEDDDDE-1/N*T=}Cd\CAE gUt,x,xs ·f._[^C8h,uUK/瞻Y9[ϰS*yJ/1Usfƣ l QxRՆ1<@d$yn"䮝{< {dHN WhJ!b CN!';9lEDDDD&aS?BGیE*rCIIEpc$/ ~\1v:E  7 r M'yHpgR9|.D:ts=>G~r;Yë[l:`h"L]raYe̬+23#\u=p1oG;[[UNł}5w=6![ٹd,+!{d2.x6NR;g#!׵$eŌe^Û|7i` ;M"$θd=\k$MKXn:Dwv3̑CggWs3tts{[ֽG?MxX oF 1o;OL}[7휪?Cwo' ST k_6[,g2b$w738""""2Ʀ ?F~>>`@M#SLUytcgĉ87Rl+#8t7^ VW1H0@Ie-'w'q6Q}ӢTU1p oSgۉ{~f͡4GvncStcEJ.n^}]TWΠ8bt-bz%xŸ[JuE ~=7gӚ_6s}.s* X.'Ddٷm;5%7@[9e~\ʶlgo<@U.I&S$Sks .AAR2.-d[[<d/_}g)""""FI*rykX36#矨gQ>% """"r[P_8ʺ.F?Lẻ.("""""" )""""""㢮±cٱc' ڵk?DCDDDDP ´iXnsum={D∈HAR())x!ضm;%D b(2 ͝;84E;$ذa=Nc#""""wII+e˻ض=;$p.!$E&@ 8|}]C(HLrӦMclݺ q&8""""rPV\A&](HLPUc*""""7Q]]̙3ٶm&JARd0ưj] p䩉.La "SH(b޽.LQ "SLMM ٳu'8""""2)HL1֯_GkkMMg'8""""2)HLAhuֲ}v'8""""2(HLQuug^*""""7Yv 47ܲ*"""2)HLa}ݼl۾+q<@Co|_d "Sܹs(,,`׮7e״㲻ez=x֭[ɓazp+ ӣ@)>N`r_D "w,Y;d2\l^#n9ZS23 ^8։URDDDdOtDX|-۷5kV:g'xP;'cخ9N_ܒD)<2X".dxA$M*!ΐd..`v3#dߌȾȏ 3-"{<=f>^DDDI;Dvռ2mڴk~lW,˧Nv q<ɆK,É88Ŭu5W8 $Si2 LX~:{!bqtx"0Lf$(fâ= C*E(EÐ f,1 ~77r\- !B>CnYcGARR^^ܹsؾ}'O<>}]򏻛yL/uI خOvRL˾9gmi즻wx20M4klkI\vlv\q\vm3Y9<#ۅY;o(p׌d-Co,rQ!0Ң aEؗܞ$E V\ϿѣXtz-)t62[-cS*)r\X<  sTNa:{hꥻ8|7\WiUvq|L1p70C>Co-B>C^PY7PAg#wa޼BnHڼ~oiPzHO/cV;V2i좫8`0cx;z_ˌ(Nqc*SGH1 AE~߂[j$E@ӧO#E][3A"mgG^oCCo6c%34Iζv͉3M>JGw/yXP|%q 1#3zdAf0{[g(Z]dE!&KKGAR lKPpj穃mOfǵ}JҮ/NvؼRM˝|St70ę6Ϟ#'h즳!lZ-kt>T N)ǣ#wƺFavmHARv\^8upk3]1^avIor/].ۦ#461=IOv B>ByAk"""r}TC5V>NQW=;Lαt!N9˫ę4qHZp}<,Off a{mC2,҈Ȍ+""2> "wdݳ}{MonX2c/3;Mu'A=cۜjl䙳l?p׶Xt:1`Y>Kq2=2Goҡ7 6+M^Т<8 f "w4h72%&㸼ZX\~G}}$!""2$E)eG-΍ A|Vv/Ou34J6?Hùj7xC#ݽ  >uKL C6X\.m a~CVvK """c$E0g-`I1zFz\PƼҜ 'tƖ6ܱ-} .]ïu8Hc,mcθ4 gdg- (n "Syl?7?j捆[ y)clvhnF{-v:ē)|5/^ClGAڥ/ E!չ~>"ZVDDDP "S@'G;giLex j'xbAo򺒞'y;oo$SiŲ(ftKz\e( j;ԟw5C ۪r38??Ҝ2k"lko[; εwb]%:z^q}8] /ye,3:x7C"e:f=2.Ci֘C^P,0h =""2E)HLËǻmMMЄ:YW'!gpu\;ݓ|*cθ CQ8;9OeMARdzL/tL$3%n_opx-v44aYjr3dtI:% f6O~"cXDD&!II*a &288łBy %uwXs'_Zd['5L6r 2N4aF?Q?~""2(HLR.7T[H9\]|rq9KϏLr={x.xp:Enj8=5fS3 @QȺ)∈h)2I_>.,cNi HvҎ7}0_Owo8e9wC]ۅǙ &ە#x:ED )2 u,v'gv=^?m3yx\"7@[cc8ӗ'Z%-cxp\]yxHqy@l\Gn$7^u0diOL3EoҙEDdSb*B:VN ǻ8VSV'.!' ~M#w!&8ܓʎd终Ln "Sв\~wC%\I^8yQo10O^}+]En4VILGzlmKrzP]EDQ|%o$M0z8y|񾕄m~ŻG/d̚I7ȍԛrוbGGADDn:I)g UIg&M2sI;r~W2ܿt6Vuc5@"a>},}ɝːͶ$'$r֋d ]<0d2.j}ZSZ,"'jYw5Q^Y͒4VRʸN=IgB͡ )2U{f"g(-chONH Y̲'c&"1m etEDDn,I;². Ou=nNu+Ys ?=csTϜ͜ڪ M#!G "wuU:#I1^hLԡvR#>sX5=߽1XZ%E.wّpZ'EDPC, |n P`l1ʁz/[JEi2DZ4:St%I5~$E y!?N.c%_:Evlpʱ`\W ۼ^AR*ړH$ED )rfCMѤ+9 i9Pplzz4+-Lc%E]ivH^$E@Ua~C-sK}ˤ:pXI2l:>s{I<ى.mQϧ7,%/:ߪyw9ш&Fږyѹ#""CARլ)+FVU7y,7dk`+hvq̸Lr/CZ'ED*$E.֭p肱y9|@@<6]ܨZ%E pO])v??m;ee0ųG:H\0=faAưY +YvXIc $[yM.Ȥd΄î$gӷu$E0IO cC ۓc1̒r>1]+ xh'3U Y9rX LQŒZ+Ed| 0vەho&EDI;J[Gy!Fe<{c) 360Rؿ s|aʱ+7!S.GzIиI;q0:- Ү!;jS'hc6+ߖFgpѡ65$]< jqF NzlVi]INە?IDN )2ŹI9؝#ۺ0S<[?LDTn0yoeoӋExevq;}Ʋ'ay!]I·~>TRǻ j?  {7y~HY|sM59AmƤe -)^8IcxqqV\.ȔNvAos(HLQˋ 1}d֘s ٙo7'F}/񾏟0~q#c|ck`|M8ZPDn$MC6mvIDDn.I)(n{O7^S4PÜ;?N2j\0m_CmFו4KfzN&֑FV,]Be4A t&9٧]ED$ "SpGYc1DcCV pwem<>Ǯ恱me|~JrA<1n-egr^cq7͉Xx$EXGyl׻3p7wћ< tAY.aLc-}ZSxX:[^c`Y_ ml9Ƶ(*y"24M%""S1rCz62= 1bwl=uEfS V3880_ٸ0,5l{9mE]}ikI)MARd K9|o5'nؤ8 -9֝+"nV=$2p;鑱xpU9VNqظhDaR@=)I)LARd;|$07p10vIm||q Wv[4=?X˴m1^Nѻzn})hɇ6cY~k] YR>ѻg ?D[d!C=i ""$1qlkuY/e \=5̙Dg;}h\>n #c%`f1J"4 e8қ&ADD&5II qÃ7|awlqBZM˝w,)~z=X7zS1ܰO";4ȱ4)GaRDdRI67<Fs|Z"/eӕ{LJwW6Q 2ѫXSV V _?˘QV@Dnۃ4'&ED&+IX!^?6ɐc 5/cAGk&~򝁤G®ɮ+aAag1ۼAAR1d 3z""r$EnSS'.%v=^lfWGr,4Z~utL 6lض(߼huyP˗.bJȸҜ'm(a{p&M1Үw۵F2R.=>ĩܠ]ɽ3'v:Rx= ش(1^Zᮥpmg4LI?ȭ )r]m ^:#}C(@ͷrn|E ̟lŒ\ LexT7ۆBmq^_ݴxiclX₼ mE xLw>ȭ )r9ڛ橓 ZYy0}e9Ϧ 51Xbi=XI̭est[q{^cUDd"mhI۞m?SIM9I'ו y!?n]-+ŝnexcc%Ks%EDJ;O<袎mHARdloKc Oe>{ ~xrx&[ S[n%?kL/Z2Vͩsq\9r,?դ"%xMѫ\EDn; "D_d NqWc87Z\}3Kj|0e 5lض(Z(OlZKWkr;M֙("r;QIgi'ZONs'=2]ɯ,)ww1Oܑ3 slNsJѽ- w6Bɶ6kVy,D&Ǿ})""MARN8MC\Z8策E3?o"ݲ?kd :Of[8 ~~-q=\#,_2\POI_z "@vyL}ݩ;6DBx|;;ca2|rQ-P[W{686 '7$/ ;z9w}"2eئqP%ED&-=ūgA+5vAZ #~c,ƹxZI;ߜM ظqxY6]CQA-_RD.'Ӵm_ "7M ;bka ygŲ[:^rǹ~ipYO^nTaR6`΄֗ "7zgW eȫ{\6*>cV1__]E$`ݒ0 oeO+ʍK)+NR6\>"4ڴUDVS <`OgWхgB0o$GF_/%-L|@ R)uK1-Hwz疛~ۄh $eI!A$;6Έ\\!];>t2HlDmE?QCq;jJ~oNn2(oo%E52WRYİq4@4u;B$ xL,i(`o_“%j :? 6Q FcI8htvgC ;׀h={- 1[(K4%t!*HkĴ'F2/*$ _Ex7:me8mutPo޺LozIݔTְBB" hW!$1^`H\qU`秂Onur !zBkkJm"54NP[&YI!fӂ$tqBI#OIkFS''4''3E~'uBA85On|fxДŏNj*J d)!f`25.%BqH )U/4'yLhZl7iW-9)#$52IϕTEܲ Bܳkuo$2 tB\/H qN%y+* ^^ogZ$ϙ4?VEqwxe'Ev!?G0xX +(.ĔB*IӢq4X\Bq=H )U$L~f(j kO|kW:"MSܵ(o)LF&8C䜹-}#D-[bvQxܤi,!w:@ROɴ@1!aXS} BCw7"W$25We͛בuOxD;[6'737B\ h %z_B!@ROi ٖ0%L)<-0uAs۪Ys]8`4Ss%)uKAB8ٶn%-B|* HI"))qBkII!>ijG@R7Rpf,'.NpKץ鍮)ieodw;ܖ ?jmzUYFQ`Jz@ROq4]d`SYnG5&Jxp/cleUlA)ũA"VbBB:MI ~ !ĵ"W(0?br3JGqJ=K-l5:({:&FcÎM<bQ@0a<;BqH )Cq$! &-n qp >mWV׼e,:b[ M)jǛWLC] 1 $ڒBq-H )x5L$%LR Fc&585ܞe̾YAM)>m>nn8;P,t}"!yI$$-)WMI!.SҴXB3g't2 Ynk|G)S_Ʒo^GX8{-ܹs+vMJ\鱤T!U@Rː4-NI6r17`s]}uM [J0xd$'/%BBg䴮B!>B\±8HܣP3!NL55o-edp@w^dt- Tgq[%RB+!L2Nsz#?9#8|'c7UY7r^Q@$eA&F]JYU?HS\7,*֕u1m枛wfB\B(iJɀB\ $8GOޘtj4c1785zlƼy}trޥn㛻Rc-rI̕b2L $ DI!&G1z):O)^|~'qg jKu%]Sݶ.޴lUWQ\+SqREk IJw !%I )pr$Ήtj]@Dτ83irXx#3W-a8x8ݲӐV!f#tVr8&Q! $łJZIJ6rQ )~r"Pt[*XQT\p?K'Q(ZYYBL+)ĬsvɠpJBK@R,xG27rIF&D)k37Ps^q0)k'ܾ7.MV#-")IB@R,h'M#b!vN'כkr۫9lW|Ǧ)wxmt2rܖ9 VB: $LFbgB@R,h#1cqdyaS@ܰx5贋,/7֖iW|1KH/KgR0l_z_L ڃ)i#!XN$hOJ _ rt81Z{řCxךG&c6/m[I~7kF^d%,`4f0F!8b, e1IS6ىqZ dI|s W4_RS M|vs':x-W1+Ωi}4zɵ~<zaA=f#D~d{>d(1NLJtR27R\gBO.|oc9/%A O}W- Nna1+\I!f!G ƥŷBLd24O>wn93<<ՖkO_TFEq˞QgܖUL:N`ʠ4 ?g?<ƩqN{ M=3|DFiG_N2Yl8ч4Lߗ7,G2WNIP)k#C36*nξW8S̕dzyTچfW!fa;Bq$Sa=~F?5ٶ232)bͮqZ?Di4qQp@DN ˫(r_Et$>HVM|^O[#]O;M8{t>3h_Tβ/00\``&+j}hDz"O3>G*\C)_ӣ ~~2HlDYo&,1HStO͕\YUsJVW`JVRYǴ`(fȚB1a_K:Zw+_)K6}=m477Glg6+I=?WgctG&PDô>ɉmE4E`hن<0#D:OqdciV2@Om-M9tCpH㎏w=RȒRVmfVs}aǪ28;˗ǢUkY$>:da061"k%`L]O++Q!"3qDJJI6R\6Á8Lj 6goW_V'W])t:29WikPJq?-[7`ׯ[R GeG!l3}WǢ~ZVWD`엌c-Dh7MmIoI)+:'F.ԯPXu68C)2<~+9N/39cxMkIrà 6 X14% YQx_p8Y2r<\BdN^s*9/\tRPUo1pwqڴn 4Q 4MLL3I׉-7Mdwuse ܹTjB,)0 bHq,{84,+//j%nX0,9u,)きyQZ&WQ/IY ̱B,xs<#iǰ,4ە8<6~.m]'tu~[v ʽEl|;g]].鎰3%k6sWw[46t1ӗ3p_;_8؇ī]mqm {Xy#9 ^Axll/%fnzc~ne5ioue#++3"i@4@wg6qbN((믿X^dPBIS+j"L]D>T_YY̗VaO)89ϡn㳛i'ܳk۬. Y@$E*B`:90##\${ 9( g.Ϥ4u.<Q)|EfdRQ]I#B$nr Υ Ca"*&p H$ p:B"F,KH&"8m/0G>۹iYe!vg8H[z#9Ci/."ItݡH W6MV D3cSY.XOnHStG',xh+ ˨(.B2 {B@RQlu)=Le$H`(XܒQ;,'!O/rs֪T 9ҚnY dn559xA:zƩe59>#k6;};o_2 3ٛ>vQRV:+"H͆R`;JHZ$b&.mVge8 fqMWy Ug{Oj`|B3]S utQæ- h Z)[LbIe5BlQ/}q;{xvQ.}jlzs6tePTPLv“24'#lE ׮n;rBwgpq E"Q)2EDcQ"8e2-Th8L4%4dF_`13 % Ѣ4w SGN"#VRSo럒sb),Ǫ3}>3nRPQ>z }82Iah`C9v#(ofQTǖQƒ꼉 "gVpqem+HO+h u-nXIOYR-( E:hS,Mt.WV9?vѤ3'6ʉ|e|xo{s+,qVĠ;t!47:6_\v^l\<7=9k%ZSkteYn4&nRW4̳e MSSynJ]xT7wŰ-|3G VwT&govV2L0u>;g_EssoGyP;V?kO#1w`j,kWf"9$7/6i袿)g5Ӯl;zgu {|_-2 wͽ_́Pyʲgcc M*B%/Oʼy.]&u nצ]<JS wv+‡/>I=aڶC8([JqAde\_yEo>6:8]KfmfR$R<"ϥS2*c?TH$ɇQ@ /~{E%RTXŽ۫q]:93w6'wfdZ4eJaXvOB/.U;M=DE+F:+yע<2ߨtצ.y62$.l1(ٰI71>ܽ6a .C k`ʣϾU84x/GTBג>Qا;x6o8/o&lĩ6\+XVfNKxrKX,V3|%4,c:Ddᰛ|qZ o]_ d$g EF e׶nX.2x w-Σ:;=WK+6m6щӤLSE7-F3|J)͆/#ߎL7ykKzVA-<օצ|S24HGoyNjFyG90gp;'oYvk959x,eGZIfEU,-xCܼlͤ(V)7UN*yXQVspKV_>])//#>:(**"??|Wo},?gu8y ɯ\WVGW\b/ю *dܝIanDYFѢJbϴ1MI|> qea&cccwEGGibYYTTSQQG֍r$f85 )hO~!!>lg |#Q>IⱣ}JaQ'ܼe='ۦ1B(ӂIҴhaI8uA>k.`F*XW#;bQ,Gk=kq\<6 /YRD*06`q>]$+W?C<,4I0׉߲m2ʖMx(iN6,LEi>~fCzh9[ccM:;0S"RNnn.]D"(c ry=v;eeeCFF~IoX֎7>S+':o.Ow^9X45mC)8=~gc9R8l6>?K|arsϴR07FB hO\9Ng]29ymz)3' X}~?e +ۼ}d~,'ȺĖE40@nm)A2b?Q05]krhdnoyǹft ?8N_%qp|wݻٽ 7Q?ƨtobHSPP@AAK,&JL&Gq8.r)---m2-N&H\vB\i0^*>w,ʥe Xק.tIB-xnqt].Zi 'M $KKd$S%F5qj[o[?;|20p×YX#:W?_z-e}t*i?'1ôh&p .-pk/n-'}}Ƹ7u^⩇o޳%VkC Y-ϡy%+q_æ(.g6qJԈ'36bFl6n7eeeرo|k|_f۶mTVV~~syFFF'~2 RGH/?!>M%|su w/ɿ`}I]Sz0č6]M Rl)ŅUY&2f)fu~d5Ӊ7ʊ*t6E֢wJW<~ N/TҲ 1 +S[Rx۶v wr2NKٵi-?~iB#1aM 17XX&ēɠRPJC9iGJ.|إv"UkߗW|qZEU Of!,楨"`XyA3#]CWC38֑;ŒO,6.f5¡6_6>ıAFsȓWL2bVRJvfy|_躍6^{ ~Ӈx'8p VX)fRL8b$65.[swհ,7R2S+iӹoR:GlX ,i#ĬL.b6 PNa>zk'v{;nHĢQ"(IJ?.!%0-d~{3u~@ f]Sη_9 @(`IUyNYX hOL^L*&A69Y.JӦM,s2UJCs4uXOrz#~ӪieN^SǠ4rӏ;1Pu*"/Oʼ żqp̠;$~'iZ<У؅No+'硃ݘLt3,:1]Iϕ\ZV@uaI3uxwBӂ@B` /څ.c@]}.Nmr^o=8ծkܻn)oZG's%)pRI1sm?, }c;eYxvܾYӑ@RK1bsxz29wN~sKMvs'Z Y4,F>B0X\I!ĦLH۝8}ZΉy'aX4%x#!n$M8 07&+OwPsbNm ɁɮN˫&s6 LR@̰$B,Hy'aZs{1vwDgm*X4L^85HhtqN KhX\a3m\B, Hy0a bHFRzg4?U|vyX]æY/7 aL\}:ۤx$&* b L*EC'ILn;mRnŲ eZVlS: 1#,sgDFɫ؋E,8Lgq$pd8j qadsC̆Ǯ{ypim1990ytVTemJ|Vz 94ĢQ"(hx"59bFya?swWw$;/@ kFG _aT2IRM 1zz1Kdk1 `B:M}a_֨ہt'pgq>KfRM>F%FS8J~f"D۩jad,@J9p9t,,gö53)ɵ7@R}7'w"`4%;""c>?7z3Cw?fϣcPnEyEdt OlJ1rӽ#DU+VS[1 SQZ;TԕTgľ}mE"oHyeI Ouu?ZI/T[;4NuNL$>Hyð,%#)DO qd(1]_/ihqSQώM$+) Hϓ4d qY;"{#B[`zFG_j꒙C36kyq$xēo"a*xA9p:әN"āN?ρÜ=/yz 1S?Ko{`79ޛ./5/y6>'_APs_X]F{ig#i*2SMoUfCieJo2=}1IM"6Y/릨GsvZbް,K )`0jc㴞s1up{].݁T4rYf jd!n4єEܐoq, >ctlC'0I3i>ogdŎXlxzeynjl{ngumN_6o㖻?˷t+8d8#'-{f>n:KFl'NԞ#E,[-o1\GīK upzLc};ȳRYNf~$0HFDx)vseʺחpwhe05%h 5WtpN=&C}9-2z '҉Ӎ̄*݁`uܾ| DPSH&X ;vaٴ4cC۸yeEsb裯oeKwGhcWr'.R1w HyCIӒ?ļ<#@互Q͚Yt)#,B(RT|,QKs9}dy`AHaZLtH_ s @)j74-79>8>FMe]EEpy0‰ᘢaZ#e{V2<mU<{6cdcQtp&VMCgz{"$혳׮Hy7"%#b3,x#+S(+]vrp;)),[qslF(eZK'f1{Ujm/ɱ.F]KܝȘhhoe<;|j?ocT! B6Y3|32~_%7Jc}6CZ<U VkζOj(wk QQvMp:|;x魽R*ufa4 '!ݝ;>[ LAiͻ$#)XʒVbAtRqz6q\R kdޖי"LHd!nMױ:7b^H SHMS4䡓VZFY|[y$2-YKR1I )慄a!B}uMqU=;֯Đ;B\W>7 !|%L 2+.Kϵy+:6M) ryd}:ҹU1I )演eLR*EçM׸mFU\I!#bَBOH9/aXǥLOsi h 4̊hJQ]w qXIBWH9/&%#)$7O5߱:6e:L+)uaY`KkNeH9/nZ,%E(O hTs-۱$+)bZH#81DKoo/CcY7w~O?ho72ɩANO0e.~1m{"g>s?~3m,dǬ*Ω·~_s9~Nչ[R6Hc'Տ_r'Ȍ˼8qKC'y#,ZÒ~-0#>xvicImL}ғ,zseYL-RPB(n0_: qX -1+1<^jrr`EE.sҎbnzkܿ fSqh*Ej9qj²*_xo~Q6X&Gdf>4>z($s$`2rrYN̡azG"3,)ms"%S$D$sTw7=:Ӈ'ļ#9" J_z1s+#x&o.J}c ' 8'{Q7+n%^F:Osxg&SY.:[Np Nne=/g vX0aϦ~M>;^6O '¹uF^N5Pbv"4IS[@ÕCêDG8|΂:6'1j oƨ)*8'f×1QRHX\hF9aѪU}~/0Mac< %e:ᤃE+VP@yuI8 <W2b^V!.POOx.ٹ"*5fZaR{ZGo?ޜ/jeoش4vRSY ~_/.z{Di;"WQu\@f?V`&9gdzVTi=|XAymF ;n7'%q'#mt  ?yz`1|f?Ͼ.c)nox,f1N47r ws.[[_꽏p) :uN9fw` "CKz(1c.=rG}@T8 H9O)i#ĕxm4! YD{; rRdllȚfXVD2~A<:OP }m)(fJ,>q}'?ydJ w{& s$O'|{(iP\D6=kznm90Q4nE5 <|Ekypga.Ľ_}Agb%Qkňh?z"YZˆ9O`2p9oOEF8s[[9|$|Q9/g8tjܔ$0RLd4N1K 5ʤk}an- WU?HM)Hn_ÝTX| $ŜCH qWnQ⵱Wg_G'B\+*=?Ҝ՗bO[F~9=DsJ>uo|ehne5vfm+5_KJxCt?@{` ݎX(®_@ױdfid h$ NP-X<}f-f/8 Gi,Ų59??|+VqϽFWá7_Liz1~n]ɦ3455C2ȲuX P>\6pgd2KD R4^J[Ŝ JX99dmvm\3Ӈ%ļb"][XͫJi޿ZGQ]YÖO69xtp$2mIBNl ?BJ)R(7ܨihaZO7=?\7w2ycw?x מ;(8Zj6/)LB Jۿ||_\jg.//|j[x4lYYT2Mx mZXxcΏ $<`HEOES5Ecrn&Af6,)ί}uC=dsVa\~Db]kҝdӻyXb YlI&E e80i7@LK jKsq"[~}Te3upjm5w|Kk.bˮmlzK Orj** |,^]m r5g1A:zly7\ gEoUդ-6m¢ \u}CX(3IWQFRb{h7kե^oQRPײ@)LmnƇ9|)pQPM?r 763Y2X53NO `ĿO~/B\WQ׻rSk$PhJ1+/ !>CWlxR&/ xc=4k*bV[KMD8D$Hd,eGC9v"46-bcS ON+jq"D Yl߹\w)lnai5yYVԱaj vV̬V,*'سټmxRSUCp7/qaKVpӆx'&2]Z _Ģ%fO-a&(e9P?U5%h(j֯\ob-ᦣ4ǝlí_P22d$<lρ=65aB\ |0 $Ter?Ek 5Ӈ%Ĝf>Ʀ"')חi1> \pR<%3}bs{pMu9c ۗAV4"Cʛ8d뒼뒑˽糳2/A~Ĝ7kDž4(XWby]!)mP#u)R5mqy#V4lN3,KRS[w}kII1]EzcSll)vQi'fX F BIt,ĵ`ZF!YE3}iΌ"Vm% $sY?b#L;t滨Lڂ)5яOqhJSBKI1IFRK3t߮ѐ`s,N a<$nZUR !%t9K q\ x}$IBID*ob~@RyR:$DEM"Oz,6 cN2"PhJ: !' $ŜgYyX ܺ""uYD( 6QVɨb@R 69OЉKjSIi#_!nꢦa9~GzG Gzk()?obs*=$5DbH/RwWfZ>5-"qN)4M*줹YްeJyϲ"k?籡.چ,[VC>dK)mZ5R=ʲUkFo+6\x9:{: ;k)N6`'~F]wee+eӺb^m/gcUϿ_"ǫfi:tgNcAnYCdXyfSA.נ3H )<~bXРgc}9P03 d`D9Nt7N,"L]6Æ6r>f*N[mÌƉɚ-̶3zwSm e$=|#zG5/vA}7^{^O=_m#h/o<!}M;Ğr[}i&'gz&*r]ӏL1<Ўzd ib ܑ㟼o~Y5gMхs:{]BLnY[{b¨4tpgF2y vpgjtlrs(-J4'eyR<†F۹}"Y%,)aXUna3I>b >a!|UbqJNbƙVYaZ/* NBI3 9 !7%s$Ŭgb,FF"F|{Um}~9=t b"CbC'ZQ5<"af1N8}IRdyBaN 6eXc֮t /̢o|r_해6l4-e69@t3l)>v)\+AXa=!֭Z' Mp@"Z1Oё6k`d >O4.^JmU7^ޥf#SZ.L7\ tvgnjr,:Ygڈ_HdƏ>`0X}8;DY`O#'j$h9Ոxynlbv-~Mml͝ einO1:6_\v^g_ǒFd=qCwhfZc#4DB,Pи܃Ce `&7Ǘq~4s;ޝ'Y=]݌X(ݎMD8#k(6r (*M/$c9/ǻx| ESI";ˈ3<8D̴K;5cjfXX<~w|vV7H )_HBlXdM|H`(f:Bȣ-!,dgz/M)XVV@]qާ\790Ý{, HbX`;_jfCDwZP #] )b^tj Kj[ubZ` ӡ<'nHh4BL549D)B+~Mi:׵ r*P]Y6kII1/ؔ., t 2w"7]50؅|5y:/JH9Y\=ӇXR5GqI )òvOږ"UɰE߆aAO8E8eM2v!}'iHyASPaSDSHf@k#4$rq(8 pJ:R1I )]):6 O,, ƚ|'+z tΌ'IV>A !.]WA\1I )B $c$.iɪ<'.b$f8B\ p銫m(b5f]\t\A(lbJ!Up.)mBsHy"۩35fP,tKWml/qS1@?bL@Gq8$BsHyá+ <:fHlsl; \TmM:C)5BkrTBOI1ouB|^U\ Jg3\N hW.׊cf;bL&< b5uHzia;@{uV:X®p̤yL9<Ƣ{hF8q6laT )_^2M,λ`0 J| 6bA– N; XuaL`&|so30X(z^I<&KZY$Qps"e8PDʼX$n |/wbݟaӢK5cXj~kX]={7=Ç(,rAu`JT2:4K*3!̑9b^Q r:]Iy}?3BI1ltE8eI`1YiP⵱Ţ,A{pjdPȄ|vA7i<<+94M_}AzC݌'uN_8AaY#PKiXR{tqa #$jxذvK>XͿh#O<6lnv݆M9p{8mOݕ҆e!s uU/6¢/;ᶀzi62XDmH~-֯se28}L9sU8hyG_1oMFȪ7c{^㟇زu m}T&75K(a,`Q U+ػ%lpz.yd 5qb JI1d46 6搳=MѐdMrPҤ5$nX'A !f 5HM.h8k q*8LK+KE9yOЧ6* nOGpwD.Eհp8l^\)JgG+(bd:5˽Ƈ':ٺ8sڻaA=^qnZ2\.vAۧ8Tz rPlk# F1Hmf;bєȫKaZGScG]Ž^`|tP Ds$c AOafzM>E߃D<ʆ1=M"D&=}[*Kb,2bqbIY I1/u2l E l Jg]bENJ6")$s?bR*F;bhwʎ.reEh lx39n9ӏ#`m?'8bɆ%yR*3&͆/#뢯X&rѰV =sp8`w2!Ă#P) $?-Jw$sl*t<ׁǦ13hILv(!BcYt,֍BII1yety:Wƴ#~Qp ӔU!f ]I!#ײKNHsfbQu.j$ DGy? ]KgPI )5H'$/ɲAdC.b7n`Ң-$&~P!ҿ]QK)!$~b[gi,4ջiAKcU5Nr\:#1@Dj/5vB,LHyȣSqf,9Ӈ2kVzyl"N\6M`L,!GBqq (tؤU@I )=])rM.QPmSacusN 61&eB|B,l+(JL;jYvVX()B)S!5e~ba@R,. AyeHMQ巳EF҄A(9uV!vte>tkB,xHCѩHVJ/βEHܠ#"fXU?{gyyo\@! `3)fI,˲nn%K%Rs@99xV @!P dIs"2",9+"<I* Qwn8ϢmUaV)t0< tJ""7 VZ쳤2̜S}yr->,#"ŰZuAARn9uq!VL]WZ -q0)sWmG*g9՗7{::l[) iVP[PqanYSc B7+s[UGW&pOLbQ룈ȵḦ́-"R )!jb{s,@gqee;c;8qx k}DDnq1ߡ"ZED(H-iBcjωo; '&=XR!s4ڏ*\,01խUDdܒ\,TF]ÚUDd$IeG]WG8;Cmq:ݙ]Y2 ""/ρGH͑""gP[V)ӑ %LMSvXXQ5rLۙ ""; D=K""gӓQnisB) dꊂǒ0*„]C@REDnDTZ9rK;jljNΏmҝr 1L+.L:K興|Pp9Ҍŕ!*Xy%>KL+ї 8՟c g5 NS֒""Q[^w.ʁ/u *, SʞBȍu:$EDF )<1̯S8ޛ9+|XuSΚ ߡ#`Wtޞ7""r@QaBB$RR䱨"̉'<WYP"948՟#o ?W8GL"" )BaBk":5@G*OsOx^afO`-HwE=ÄB P4, -'r&QBDf {ED亦 )2(=3Iw6?p0q(;*C,z\"\Sӗ 8ړ#3"Dȭ2RUk(H 5q_w-w S>jED.JeLLF\oJDDn2Oej$ "g )E=ED.Y1Z%EDnF)"r$EF&URDໆE>q dzbqUMeaVD I{ IOwM3i%>auAE1P(XI1QOD=TX QOyRhͪ"RHˡ )rqabBc%EDn&c^;j*\+)"r@uԥ"jleRaPs""76 D׍."r$E.c>Q*)"r3f䞠""WDARE\"k&EDnP10GC#EDT\&&ޘȍӊ}J>f X QIEj* Q20X$}}DDƃ"cj9c. IM#"2^$E.Cs^"fI^5(7 "j*)"r}kHzT)"2$E.S5L+.QX ڧp)"2$E@ieju304DiX'p L))h*"r5(H\kUSuIafI\ "WLJ""rzա )2BaNYUWkQ)Iǀ\`aF;)HÜ0au&,fDivEgg>s7|(Mc<ǿ}_>Y~m|Oxlrv@*"@yRi?;de>h8L.әQ7W/L-:sHeY6fΜ\zll ;uNj)+xq&ϞǬU+㏾lᒇx Uqj#qێ2}]TTt09Ӫqn:cM.Z_^h?uM=$kh)adl_7Nd44giٷ4VέW˅MH8 %>UQ*"E@YeJqKuY|ܳ͛kqUŏSD+/?kw5o.1~/GvTKDLͨw 0/Cqnjzf9}#~5eQ[NaJ}9kteO^o~ez_?e^dӑb͜lqeuUCzEPg avf X Hm1L׾ _\.wUNj$PGiISf0sT|1[rx f޶YK d̈H1cgX` #/IO~ _zfN  φޡzfMcEL+igi^L3̢<ʪvyNI[̄3!V>uCQR )251iŚUDVS,P;='Nꫯru<\)?z33,f)ҙ(?ȥhoLnՄ5>SR0fmxyj&U&rm}l>Ԃ_Q|d8ɦT~{,)j?Kތ ř9k:=I Й 3>cm4̚HCDE4G90=\=Dƒ\"r(H\E)E>qO""lJĄ%h=/;w<R׿a޽W:i%TTV3yBcw~o7X,03kiw?bL\Фܶp︗o?0>k\Kx37>+s׃,Iqv)UcZCo@("0}}}䆖 <]~듂U BIq`ˬ^HQQ<߾7yyh ~cE$T_>9?3&\} eqjyIDAT{ěںΈj"iR7MR n>("KP ٷ:"L^̝s}ݤOGf̪1`Z<'B"K4dh GS$EeBǻjs[a^Ydh10}4 <:;w"1m'0`;hio'XL/;7`O-\Hϓ/O.#˒]>!˓eǦ5tKΡ8>Jfi] Od効[2Gf w,DŽʘ1Yr-4d%=dhXCL=̜>G-1czʊ"_CDHU Rӓ ӑQˤe ,RW*#sQ֬YXnJ/ٰi(72 ᩿o4\=i$;wdqv;Ed;ھ;'ä/-@ ~yBģaeHgpGίT5@<"D3y>&Ɂ)lsiy朿K|??GSGԭ|5*rHҤKH|Ü=ـt%ED.jb.w\~ &Lg:t+簾zw\X¿FC(#4 \xoa%27 x6<@]b0h?"w0y.v)9ي̪V)H| PqYTf]SU 旅nzz*++ٹs'.3fLgѢD+3 P9cĊ&N| P;X"";e!*~ P(ŋyhjjW_WTUMBf )r 8>S|Z""7󲢢~sGwKD j"k$fUDd I%W8eʔɬZw30}P^CA`eHDnEﰰDn "XqaaE Mirc[ZDfd)T- S1F8Ә>}ڵ>/čt:1;"r/ SuL#""SfZkŽaAy:M\$Ee EDnE%>rr9MAR: *BLL&^Dn= IY5vED )r *46HDn {,_3Hu(0I4-k}H"r&2LeԽև#""Ÿ0 ϊ kNk}P"r]B"HI[TQaIE簿+K&иI9a00NXꈈ "0,D2䰵-@NaRD !80,Ĥ"_9-.}4Z\cuqye!*BJc$Eja۪"ʨ-Z%!4RDD.BARD sBvudDM/Sup\I9c.QrݑHONd,veY5EDD.ɐŠ0e3Gf`pa O""2f "rAa0ȧ4찳=E"7 &&.PGDD.\1PqYZeog\ ZH L- 9ED)H%yJCDvgh+L\Z!+.CTE=!EDJ)HȘ8dﰯ3ˁ,UT: &q )"cf04JS|>1ORDDIBSuAyڸў,zsdZ.D|zG]"E>)""IBy&Rq8Е?O*BDF@3TE]TE]\uc넂\cyG\q/K6PH1%<&%=*뎂\SQI)YZVP-RO\uVSD:""rRB5=.ԟ'˫,ژˤ"Z ED )" C@=1Qsiq+Gk*O6o1*[Mbh1TD\{T<®""rcP뎡Bِy48@)7 ®!"I>Z{Cdqz#+rؽr\11/ {+ *]k\?V h`ή.PXn0U_*SARn8\RB9?须k-xslOOmm][k)J&)--='ZWaxr<̢H*|.UDB׻t:Mss \nܯ\.̿ ]L#,7c MtPQ^~߿TWUQTԽ"7c ttuQ]Uu7@$cÑ#GF#D"3AMu5x2R>rX,J,`C[{;eel!p!(EEEgD"1+c \CCYY8^1.(UR*DQ˥ y)%ju1BWW}(1B>A>?/Xvo¡|@>c 9 BA@>`̙95Ws}-t=|_y` \7vu =gPtTk ?ⶽh i/s}/{Uz5\l߷_Bط# fp;17u7=u];FN_#<} b.OmIdDŽ?cpkG+`cNw>v07PV39޻g;v'[{ U036έts~m2fDƵUrŶk&zSTPWEGÙlGOũ8{G9?#Gy^$iɫt>֞wvp_t ԃ@` fj)֭ Wr-."i6Kʊb1l/}zߟyL#`vp>ㅣDCT=)>ySGCux?|=n?䁙%NX_9{._mF1l Oy;EKPi}xrl?xõ33r\Q4OIsynӵPC[pr}y@-C>}T6\cݺO7!cR ZjZNZqGN슥 bo ??\?sqgعiTL{bzM,]6p5k哺cHAX=߳w fUGM5Ko P wΩ¨` -?upѐKo'Oqi2)z{ oO_yڏffz sgN 0=lYk:m"qRFbze>l.e@~û6f6ڂfqF~M!{bo~\׿$ >I[ks{ۏw K LYp7;\r 38kVλHc-XVqY|m*Ǻ|ą 3vps1#*E/\k;OkRY+&d|J#,=C/ǿio?Dz^YH)/"C̞5 {l#?/=ÓwO Oct{LNeu~y RSGVL>i9tfv>Żَ-I,Y8w7&|-Zc(?NԻbE]QL y&FGoTѩ Q'`YUt 7&3PTN^z\{c|~9n??ey]!ˉ[[c-l=}nxT5aތbu̟7C* aߩ~ 70$D&|pע"5&Jl_5Q,x& ;!NWh+ZjUt5h@?g;.r;vaDΚ͵۷x:1ŏ^T<ʪ{8>q&7 m-wësKw*2Yq]ܑcg ~ӧRoaꜥg^> ũNL•HpӰO8}{$ q\exQ7~kS^_aj%)#>\GCܿ /pXZQq 8sONp4vB imD< a-i ^ O` ;8v/ȓ@a!g1#jk ,|rw<|9C~L,lID+g$'vf-zl,qvx9[ܡ;t۝ 14`q\<6樜b~l8,phg˔ `rm O7yɥԔv(<h=&TWe{͒ ugqRj T~GHø%xP(Kӕv{et2\)[إgzb|¿[m+&Ć+MLW)Ϭ#OarGɋxY?_2Gt ψ #s]c<{xŸȱdJo$vxha=o Ϊ./M$b,Nc?ܰ=}Jk{z ",5G}оc^ݐe 7ן37u{C#G 2w3a~_o~I yc,]LgU[|ʳ2Ѻ=C{{;/gXb%碿wd;Z6n)++l5i>C8_:hۿ{1yl[SS*JܟPQsB PK~Ok=> O| ~_}p:fX3XRf{VG-asyTŀ<\~ Ag |݈Cc C ~0nІ籃eߚk Rր,By99B 6Byq\#˨r+6 ,g:sPAVέs{?O.Y-&sp=3x=C1F7 'bM;_#E\w`Yqkzƶq_ Sr칯`ESSx=s| ,='wꫫﳴ P=]>}Y{\mCpqp0؎ C.z> NKru7َc qyd;f ,+wpLQξ|&Nt3af݇w~.f̥o*47(;-΂ͦ1/]LCY|[ױn_yh;-OPv0rQJB8էh`rqٳ:K4gc8r(?2e O=  7l=K/)Ba> !r5_}f̘y m ._~ ~\{|g~Oc~Dii)APQQw]/׿MLZK.}.6>BDjÉ1ҽwxe%ExyzzM[?#rjJ(+㒣~'DIic Cwo?%(4Y_q A!dԚC0'u<~J]ӨO"u<'ض݄΢ym$w,'ټS,vص}+O1}̴`~eo/@ѣ+_~{Xݛװun{ Z2cr޵]GZl) X6w2 /DZ]yg&5UBӡ۴FcsR4q!}!&x,vn`&{)ϡm'<]qϧi(,KNŞrw}Q  =:qSdµbUE%}Sj颻_14@16lA?.vgNcɝm8u-vӑOCn[D}y Áغ7ÌEI6줇&qpjx`]T فN8HS{7ݝdcqRbYoĎӔN/rц\.wR۸f3!/9`u~φl>#~_P/<'vW‡[*o`:? ȗz?9ҝl[>z!3LYt'w/d߼)znw_ɞ͠d cKGIBl^=C$c9^/O_xw{}]񨞺?B47^|[(G_B7 ;U42j'9~OJstw4Is%,T6?T7\zƇga# S4aʣ.޳T*5\Soy}/H4i޿_MoŮy_U2l^4o‘n:N(AÇ$$Q߿nuEwpݼ׿WXD8 ΝNr6})fTXۛGHR|=6mcͼ/ś[z[i64]tm {}cEahiܿ]%5̟=X5 n[i3Xq}̯MfY̜{W.%-lF>p;y5Z"?o/gk[KC8#꺘P~;FKp%]x`nOsc ?]_~E u 퇷)SY&swt:x"±BC9CG)>⇼k-W\w|SǏ[WJMy \߅28G8xf2V=P +O<CJʩ,-"|qa˦-{; ;dry Y3L16l:ʌ( ud>xm9qe$KW u1~0qD GBo嗿%w<Sh>c8W>gڵk|+_e1uQmu,G5lxg~^CSSY Q&Z̺gGu`CP:xiX͇%O<r׼ xV%>r.R4m'y_#l;==opuk9?ώ0ĺ [rz3rƃ).xSWbiOo)=9ŃK'2/^).+eּ̜>{:ϬgUl趍+fTV3[{%!3cR EYhSg{!zS6 P7 2£yvI3cL*ʙ8s9aɄT;mⓍIL8A0{/.sprvmEOΒuNN53*%̘356.x/*H-ơ|.Ŵ %4֗#7p_^S5S+u3s!G:21<^8?L" G)--(139Ws2_9s) ĸ!Z.c9L6-vW]ˑ4=G? X=@Gvh=TlaEAPTTD<wޥ^y=r#;暯#9U̝O~at:HBg<N0{Uኰ Td4j"e0ZҜG~~`+46}J{r!3bxDOq~Syh13J+@q088fh&ᐿ~o=|idQTZCglLͤ.MNz  ªO6SsW46*O?Ϟqrn[䊷fԜYw0 3xck"USiK'3,=S y0c̈cApj:jx) c_$z;ƚ$Zr4$ű0E'*^E<5Xk]E<ƛd2,?u/qϡ9=^-J/I*d/pd#?gٲe< ο]{^1SN?Ǟ;,o>2p]+0i$***/r]ϳTZKyy9~}6m4z)/'MuDI0!&_ɟ,{w7G#lAEIĐC͜%,.}U{g{sz ˙-?Vĺ2JO̜99etoW?&rɪ),1\ź<2{!\/O?CmPEu;y,M|%$LC?7YRWpfC Ga'Lg⹸< eSW73~avI*p̚?Զ=w l͘ME0FaLBWsuBx![qחžzoGr#0NRwp`K.vWɎ]_{h6r|gl;~;%GXhk}9B9`F\ӡ<\)s";8/y{Zߒ2B,fDi`h3j Fm9`-|w_ynosϢ)#Yq !`9 c{h󆆈 UL͜@W3v93퍴4siH`3Zk'tr"ݭLs9qk) ]XM'Ig`-nOaΆkWx㴵P3es+C uvm |NVW_{u)--';+B/u"949aC(>}p#:x g}l6Cw&G<칻_W~VvvSҟg)eS?یZСs.ߘ<Ƕo;/?~;CD:.f66SϥH1xw8Ƕ@~w̩S(x(J&,]7l؀n [p"q1] 5.ɲj&7Tѱ6cP=s(5.Ӗ<=s ){gMGww?Ȍa&Q94)Es!چp4O?pMNf&mh$O0Nrb=5E#Z}c;OsĮ-ZK2Epם_zmz+HRlܸq,D2ܹs9rGƈm_h_,^];wt$-:x3mNo>.]Jt9BOo~av«(B>FfhCg.vCВ8Cs4d7En d:hk?"LHI&03W<#w#=vR+ZlAr1Zj'xtneF| ʌhob \ab'Ò&ɦ{ "YΞgE&o)%(KF GC޳ V-v=]7T̸!__^ۯڃqe&A,/{lWnY{z3κux9uOyCE2(Sk ȍ21|MGFlbO (tɝnt$N"읾ChF}Q^_f#Wdw524Έ[`prӏsmWYIY<c 1W4s[C{ơ(y0syEcvL.ڀ +1tG9G~},滬] yDIl1eHQ8 F\g>ς8̆'68} +控?ߤs^Ǵ.Y.wy;3Oh4B0|C[&o Y_yppm>K34'"01XIJ^wuL;v`'s)C fh[5#acg4[+o|)ϖO׳n7mK6iS&Q\j]ĂIRtsx>;ik<ƱS=d2`ETPLqC£L5&MƺCUxwnffvn+jfbm9T +oG #m Tݳ2Gx1fXFuլW2}+ܶd%:ϖƥJc=b0S}tf3ͬ'iƶc,[;Ywyd~9XkLKm/ȉtaF3סo'WG>Ͽ4<i ;i졯Lc9߼\Q=V<6@ɺ9ܵ-?3A=;-rO0R vD5f'7,a"i a2ɗ~CK9e{̬ngxWO Q`IJG?ر糷sC+Ho}R~qp1c{&o~H$rk{9?|Ǽ֛|_gm n{}s[#Kgc+p#L3)$ +)JqD'֓%Y9`L&G>?X>1 7I=r0n6rgq̥q ɪt(LfӅnOGm7ڋhbTWC]*'dƔk[鵰rдAaQ})-KWo}?6oLO ,8Ğ|q'ka-ܳ(ɧ ;fpbFM1UeQY>pEx^џqt9 Pa=MFz-1qb >92)I-~(L&G[G=eSX2^~7s Κ>&!c)+V>ȣ/,bmYwMUw59NN,_4 |ZOO`fY% XXhh}k辽m3o<|K*7=v~ҐI.I6+*\b.vaY_Y4#HstF`GWP]QF2Zq(c͇|a7^% u#ki(pl^;8ud{OX>l >}6kv,&Ѽ{=|fSͼ(}>~ʩ3>UOOee-MǷݟ=ܺ{tyl[ņijkڭM̹A'F4:z*yT N(N(}5qLq.ISQI壷x"usX8L~z]v63y&'Ym!?>?Ďkyyw|wärKvmMkG'lāw|ǘR&j5~՛vqxi-S'u5 |ʫ*1C}?_{>? {^E)m.5sc3ye AkWbպtb&VR^RLPuPL>3gMiY9&N@,75x K(3gϚի1}:ɢ$#k hoo.:l8f̙<֮eib1NbGc8q?e„ |"xhko'HF^Ww7~(D$9XW^͛o"{zzx{}F #g49p%?'~G ;kؗR>rJ84\[ٯ.I|D[XfY,?pt{|vawRw fH'ol<¾TLII~w -Ypl>L~?W[ۙ5wc ==x7d[xV_As|w~SFC}}ª-j1kR57r2[œYөHNWjHwbd~Siҽܻ p'6nWw0aӴg5oF6VǬidNmOїu9pToehQe?_Ǻiō2cx0 y?Ads&پv-؉6&%(NPW]LͬYƶNr^*v}]8uIܹ|1>%9c sn3G?-8޽C8ÂgZya\-ȚmGdj⾡y;?k>>\KK*ɂS)zч~LXOÔ$mܷ |njN8FMpK7 G_k )e*m?Gm`.򄨨*'껃!՟x$',μID"Qmt=ںtu#EkoFzn#dK) X IoeM;[]̘ɤj&N(>]͝ BO#85r^+ffUaX% -x3Cw̿] 7k]WL?ߟfvC];oot6e˰6yzZin"@(VLUe9Hj 퍍0U uޓ"ET/rT@Qy :ij&ǩ&fill?GꪒIk-'Odg3m9LƞbLXʑDkP_ǔәR_gF+?S~ٴx@`!T6DEe|iX"Iܷ67K etO43ʪ*M0cGNuf;h눺Lg_/pBUV L_'- SR^AEI߁޶l3n  =^ G1mڔ ųYkYf ~yYBEcg3ZZ[?C~:fLjh8yL;'`z{{/?RQQqPٷ&RTT4{uժOxxٯq۲e@y=k;F)-)jL`|/' N0}|&U&0@׳)E$\cќCbû歍':%s'ӼZw *r'yn2csش?^OS*KcRՖ9ŧ˧ۏʢE Y<&%>>zlO~9c ǎ &! ;@St Q_UFhpyS-d7T{+}iBRjM΍PUSCIl>GKs39kq=L:C(ހZʣH{OP |3_l)Kj|pÔ CFG^ʊRwA055:iSWUB4 S^YI" 6Z:i?Nye9@wGQY%0Y[NztU˷L}y%xb,=]=e -)*kj/VBUy1VZ;1jI]q95e=ͥhkk?x!JˉNȧ{ijj%m}J+ eX"h'<ɲ *gLdhmi?0r'GbO>OO}X#޶vZڻɻQ**IFT/sNPYcQx>kF>/ek%>Sq9Aw"Cw*{ރ10aEuY58 '3Zi=s9)/0l^5Nabÿc N~q 1gp\.K>t~/\,GDP_5{|aLaS>3X˳qfI|zM #mE+tIAC c=Ox gys𜉟F/g^39]|19k?cZ^#G2}¢nO>N1|?4>^|W̜9;k 9ʂоzzzxWYpsνphAx,:j8|Z;ΓO=5$34/sam DCy衇/99H9lg41NOg&ؠ<)̒i'q \ܘϝpsg^.[XN/n|aQ*ɡuh"3FϹe.3l]c΃sl#7=6O_6`p <k ' K; >y{ne1lG|Pgȿ;cᅷy t6saS0*:ڲl0sgg\C>ӟr;}OOQww_홟:qz]m0p8潼v =L7쿰6w=DGF0?6Fww.89 ]qB*H`>_T[.rsK r,sz`a11BK&3|vvìҙEX n U!a6kگ^i,* Sy (SX+u,"Z=f6;""{-O/p.swWll/b?^ފFt!ί`9JubC6.Xq-9ë`Y|֟#Is_Qk{ӎouVs+<,A>""i1WB'{?ߛv1/Vʼ`p Z>="07^Zǒ' r 9F.H68cɫ]u_uw:Ρ"} Ujf=Є17 9o|D._aH7qIgx=cC~aM],G "P8DgW%L r!:Z.TC`/5ȯ~ujm1 ÔscC8qt:M4=ԄfYbHaR$qZ[xsr9BЙKj8߶v}|q]kyRVZB*ĉpD .ecZB$/yዪwʊk}"m{CEymmm >=ץlԙV+++iii!N~=s Z Ƒ\ǡY|c<;Z 'Zވ|?Ą:5ZjEnZw9$@YK{EnFHZ$C5ٯy\1u]z{<] <][x$EDD.-7y5Na?ε>(HȘ(HȘ(HȘ(HȘ(HȘhQA@0 c \rK """"""gIg2477ٚWF)//1:;;F"4LևsUr9>L8t )"""""r 8Zθ+Bre(_Y[EDDDDD0c  q'Q9QL!<|?{>{ןh7\é|AT][EDDDDDF3c,V<#'!p:y ybWoWU )"""""rp D.K(q~l'oy>߾}Sgͤh7kXIXNǬ cNn}oyI_!^d__.ܾ1ZoǞn%-t5fOob2)H^J(3O~B$}CHaۨ`(>c(U/#Q\B"⁵,ڻzQ\ZF?{=)Nl[{[Xt#|ˏ1&v/}ttJi; N .vW>Z$EDDDDDFsIYGcD֓"6i-ؠ}H&Y*n/zJR7~KȜX=,øx%YR-""""""g ele4T70eF]{6ycF /{D ~:3^ϵc#.ڻRTϽΣo{v6OQQd2I2 /5J[$$EDDDDDFs _:~j9=8lXcC*tL ::RL2I(Y1ᆵglo E2]^,8tvl'x$EDDDDDFw>y6Ous潷^gkCK.%I᧨˝u;dٲy/IENDB`Eqonomize-1.5.3/doc/html/C/figures/categoriescomparisonreport.png000066400000000000000000005226461416454732000252340ustar00rootroot00000000000000PNG  IHDRsuVgAMA a cHRMz&u0`:pQ<bKGDIDATxuxj{$[ Prq.)BKPwoTFi63c6+yНٙgH$I$I$I$I$I$I$IOJXé1е@ml,I$I$I"<\1GbB ,Ve")*m|k|2ku^Oo|쁟@|?Rwiɘ2my6b:0iXqdj |%I$I$IR5Uv[F[R;0xt9)F" A [Sባ,lBIrR?fY.@7j4޷!r,'FI$I$Iײi+ Χ BTz'h4aT|d/3Vđհ/@ߞ)[5D$`UuBðdMf17Sx)ݑChz!l6lt7|VoƩ)͇-'W|לʪyشEˁɅrۚ&y0QM49=l"}M[ %U!eVAH5/{޻n4ǰ!4\Mvno4ptzؠk躆קޏt4Eh}u Mo^XiM.C]m M>B&W=d-_UEAQUwob[$J$I$I @tamd ~y.>zghYyB̝wXݺS#Z%v`՞ E:$ξ2F,?J09@״E3g:w7eQOyԖRb̅ w3w?nApGw[k8}zSIƗ͆TzP.@Ѩ)=v6Zr} >W 3oRپvۋP4Vug>g9rw6Q};U9+ٶ#ȎmԹ<``d6͝hh̓j9p}*MÅ֢XNc_-xsa +}ѵu^$I$IEQhhh䤤 Mh +ہG7hrɊɠڧFf1h{7qk:Fs@U>{\'N`"Ii>O% ݶӃbżw<.'>Xͭj|EAZj*ᠬmSZ㢩ɉOP `1p<b1Ad1Zu:<@ 77Kck>&^&-ЊNty5W` {. xpmnnDT8;<,rp+I$I$IW`a;l4={;E5͟Ҳߪpބ`$&B#r%pkPa hU9i4`޾  ,hfpJQ tr[h8-~%poۻJPh8Vy`{T,A2``3'lb`cȋ}$I$I$IM7@HPk#omuwC_QYpPcICH9sld_I$I$ITyr;`g3o2$I$I$I&~]+:K$I$Ipئɞw95$I$I$%!Iǧ'#Y+I$I$IߖoU_Ww4?Ձu]MstѴvnW$I$IJbFQ PTyt <҅Ns !0LLF OʼS&!_I$I$IN8L|\ ~d 9Vh4K]}d!E!00/_I$I$I :[ $ D'/l.I$I$I$Id+I$I$I$Ԏ*X$I$I$IdBi+ ~ &I$I$I$EYTʯ ~9@Nn0l6O"Y$I$I$I:1>^*~Ec|4F$`%I$I$I?.`AQ=]`o+VVy%I$I$I?AY$I~ Aav B4Nj':5oKEN NtJ$IΒ$u9s2j4(@0aݒۮy+p.| &(?Bu ak$ ?щGȜG^岁'$ Zc)?_LiAE{4f԰oN-cu߸8:V[ mӻouH%"Eg2G;ˉN$I48F|,)C#S8i7D$'|ٵŋ5;Zo0zgtl^8,4㭷>eg@DjWvkEѰWg ٙm8 W9? z${W!+wA 7p({x8Okbdf1{Κbf2˶5]zW$47,_]3hz#y#|3ױxJv6J#=#lٵJ>d,=BZ.Y_GۇdN9D9E5W9jعyW%wOXĐ=itExټ[|SdӾ#w!cxz\!tIӽdbJ6gޖ>3o'B-xF-^Avq5d{bź;AiF((b0ɰF_1mn^$IS[WXm]8_um[#>]HWV%>q.vFD"gb7_Mto#AYTL\=*q%uN jE-g ^Otv^wxsq~ϽbR"d(0DLrq3Dyv9 O-Ebb/!^$t"_wԸŊ+қyubuى΢o-fA((d= O Y)f}>U9 3{I/C! .>q''ϷT^Y(^xH۟%$ rw2K+Ɗޣ.O>EBhtbNv4GջD an#~+_$4]BׅFe1SPUHt;+%ڱtWX8)1KBAFED$=(xʣbht1K/O;L$xsQpJDi:#uK1iW{w/bDk|Ho=xwL#xF7$,(Uup1km]wuwe$tD1Mh 'P6C鵻W^973/01 r.A:` $0dlD'j%+N曋y52}IG׳tLD@LpW3{;|S\լSQz6zzZl^º (jyd@;G%AFCm{7` 6\j[/_kMLtUn,˥`$gvn.hlzuD' puO/@P}-˷Ȳp @5moU rؽgf#y=/D#쳳lN.νQzf,jJrңĦŃNOygY ̹?DH\f&¬f3Yv.NHorކ26o_#׸dQͿ 2Yum$\$@tQ1UR#]:v;ڕza0Ā`Dʾ:*6G*NQT}wlFI!mܽ{H 1ݹqtN A>]7ʴ5%8l_VrŸ.|5]sf -uAxBo%E pAFƿI9jh EeSeܕ;B.?3&Vo7?bGNo )ma3adzYqma_ŗZ?uPUTu^Tl\;u',LְS]$.:_ϒ仟ӡA ֶ7?n4r/sBXMR^V &M %TkU\4a|ɞ3y>t ;"7y3~\8BS*4*w÷÷˸A$Y>{o2+ tw_wOLY?38{\_FG~ISx:\~ ((8 T9iۡ;k]q> y lD:Lf/k8YXRNZ2𕤓rcëlSYYëMdH NS}5U5u}*AaDG/@ey./` 0>U>uMD`ԱVQYۈ! { B^WMUMj@( IrCf=8 BP_SEu]Fdt!G1@ 'C11"{Hq.NH ?~e먰{@x| ]{a)I8ڥ$7.t@i&(] xZ֞Z4sa 5TT",6bbb4.qWS^Yn <*CoֽN]b6 5UTQ62X :*jpj*!QDs`'t T1yyΎb$*:明w5(կc5-eI3FfoA(u>S]Xfs}5ocA#W N;5lё\vkGE !,FZ+k"b :z!$I5(&⻍_/.jC|8lO[ 7kd:%a]+lscO>MH? __/0;^*Djͺ9Syc%;3Wa 0'1|4=|5f%qJN׏ãc ':*sQ'yթ1^o9o4=h߶ƞq.+; ۩prh$Yn[ɢUб6a #kWik")=0Edp}d F/g^c= puS]DЭ>چqs[`Z?wh7ƨdul_S|d^I$ʋ!kR~XW̸`eK\z-\zF[Bj_} 7ppfzv%wx1]b6b7|L V!mKI 79In2\c{Jv{wCq%//&Xάguco¥~tnp3Ӧ|^k0ukg.7o>bl<œԇɁGV[BN>_Π.o5v SbI'|5;5p ~7,g==bY~2=ÆcexSf(Xm\|nŗPXׄ94A] 4윝lZY\zS$㵷Ԏb 30(#UA]Ŵq QCD1p 2ma?1l8/_?W(sc4#伃9!zr 5@b:my&._GUlv.aZ'ճgx6@e Ͽ0Cmn[Œ <_y6t]eݲy,ƝO_G@ϼWdԂBB\{-L쟁HiV7LtBjs nCI-4T{PptN"i1̛VꐋuLabϟ37uo^I~p8q6[l6k (҉:K$Yʚy+o()-m"Hj.OncM\==A?G̛>f-QHwy-t~z!}f2;kt9t8BM@l;nzGa끙m"M"+sb$VRm9> c1YINhOCL݃pc͗ BB-ٱx:.rp+W= !t葈irrJdd$IW2O- So|BNo@$ v 4F6l+»e3۳1|5C4YP'~fq5qZD*/_㋏ߧtM[G<ȓoLǓ<'_xݣ(X:{噇nWb0M؃|3wUQ=ykh(AoͦmbHFVvHԻٔF%:;[]_IeN*KvёT3Qqq ic/<$֕dr  3v2޼FPL'N?L,6FzL>d#f{NUʌwwfQbw`Ea~ w95^{n زe=٥5|S7w/\3\4=u߫PT.2wz^n[:Sr^oʢ Bc*ܰF_z+IA*aoq]:^z_DQÜɯ2cGn?F,{ngnc7zF%kk\{qԼ!7!7grcOq4fȁ"껟JX#{x53!e[\=-{^z;T<OM_;$Eld]ܣ-e"p/;tR dnb;S_eH:u1F jkbjd,b2^ Kqj`>ҌJH\!4g`v3 K}dEi /l[-kHxqzxtk::|udhl^@p`[Gspd1wQ ⥇惥&^. o>M}2NO&r v#Q@t\QVb4Ϡƚ=<a ;smUМRHI~̧-0\.!خe[8MtҒ$Xc9;)[FPdwn_Y_œw]G ꥹ\: Sw|W_kKG _^f\xo[Pkn Rswf{ L~[l?xiøד fzQqخXz}8?2Rg5Vs^{;crRfE5OxW _8/w0t޻?ٶn_}-g8w5Πtҍ!-Q45[*'r*gs?wx=pOݦp#7WMڼoњ)˦"c F^SUPzì+u;Ik[AN};/C |9&|>0㱫jpeyB]A$%IJcjޟgyBi ]1#Rx,-AG9&^5ńx,Ys@gsFFS$=OM k>6jchWl.fcsPNC*/s&L}X":ri|< өyP"PnaeWQq*;*و&̀3nn*\N\0--P B}.KǼy UGOiЧW"ה`6x 0;*jil^3)v`Rw=T FT_AM^{Gx囵 }z2b 0~}z1bi!G#4&|˷1}KA#y1Ueu1v3KNJdݗWآlao&.yykg^7ᇾBabw7O2J?%,6jÀatOCz܉㘺q4,v.GdƄXH8l_O&:p ! =4R>ZMˆMjK\ ;tBR47@9SeV qMO`fوLTnYhR E]pn;]9?Uy[xuG?K>oM9SKޔϧ&xDPdaqKٯ0yТFDp Yٵ^~nO+ǶTisBI"1k^(h Y|>m6nkW B^@0G(i(S2 1t@#-@'OO~ *FhjagONǤ.L(*TXgV:ZVDЩ IKT[B ^z!Q=}(u!>#c?jw"\5e }=h=`㬻_:/5 TZsEPG8o~PehjM F3 ~)F!!C @Sn_*{)QBܠUf.`Ƣ\s779o+!<-F MEDZèɚ-өwsF}{]TUT֏Z[$qFrC[.dӜx뮽y{NaR" ,D11@P- *{6̇_,ápA?; ƎbAW &UPs-/݀;+W}'C;[{z k>*&y_j=ߵ?WrLPi{ے$5WqD`eF1b 'p"bocZ]E}@%S|-${: clQ֋HlGjh$kiQ9CAT{S k mDp2]t!¬6Ap NmO!(d o>tH`ӚR62W1⫹k6ydׯ翠~/cf_ /~Iq]#K~97j;|yӈMͨXla%C8_Rx&pNܲiR[8}b_q`>c d? J mlgW~u=yNT*SmB؃gmۦSGo>Qq=RS7[SzBɮ5l;0[pOrJ}<0j '5闖Ȏlsnݼ_ݷ^GYQS>`mc:W?xJH\{.؞{x[+/XMe=;9oEE(1p#ƋkǵWo?-\\2(1h l 0W~.]9b0~|pDzL:e {'RȽdWN{fư:Y!@^@Cм.;.y+Bnض~> .T%Cnw8YcIX{>^LYMWtܴFsI>~$Iy2$Px씕:) !|VuEo2>GXuZEmoXՈJknޚ:{~{Ǣ]4W#3xil/f{!dМH ;Fkӟīo+(Aq^H !k4q&-T9)/qc jѼp6VC:w刍ő>P2{oA/6{eS;^ u:cS-ihӟyb2o<Д75 Qhw!߼kjx1ቫ;:ssmOEl̮ģ#'+NbxfgT--eMx(AGqv/>~3}'^B*oMqnwTx>c~{=~o9x>6R`k5l+Ĺxpz')1KO_^ȴ>`7\>V-1T2_Wkײvoռxh,0!_LaL+/G|A 7Ҧ-,YFޖl鿞!1`$ ԌjSÒEk_5O>=ͳ\Brχiiþwlt.'M8R2zPS8]{YJҋEJO{}FmX1@#JIGk"!4BA!i>ijf}.6e]8;\$wCi/ K؝_j{Mեr47^ܿG.#|*I1{oyS^Fzo=}"(ɩ8l!_CO-ֽ'NI]_|Mn@~^ŧMfM^sG΢fYS7^xMn W&Ϣ0q&V:c8 <#)ɩ9_hhU.Dq)8p:Laɜu̓|0-.\yTm29 _rڥǃ^*wI'({-~6:[SKuI#|ݔCQk<_y3x^<7MU|,Uw[; 6` 8rUW.49[ժUC#L'#)صk~3'c7GE4獇"fv5gc#A٦<*͑DqA=v€^ruu%"Z ެ\} \L&f Q \X|:gKnӻ]ާr55Lk6:pVd\v9@%q50C8`mAxY9]->(|nvo1"u|XGxuC^Brl()_1m%mzSw;vR|wսWPRR2 Bܭ9Boutu!g 85$(ݵ ;IQ%I$t|5y :4_shE+pPjhk穗2`X;Vޛ9ضq9SxfFοu6#4lԱw2W,~EOa\Xui:}tMCk.5oeB5/je]qXsy؞WHQM3v7S8cy%ltN<|][g=(۵Fw~GE)θ=QB&4WŀKW.]bBiv`Dڳ٣8{Ţj!<TEX"3m|#6o)VzO'NX#ĩ7 6څBxbWň$տAVF&tOXbh1TZф?/EY/X#j^!%gtE/]z CθJLYK_+sV[7߼_I Ͽ_l.w1&`?IJݺw w(-0N| H>5Ed嗈_(QS&V~o['+xX< {N<=⢳ljfEAUZ𙸠sjmЅ.6oG)SlNMoݔ||US\qǣ+5 '*fo.iVWExʱ"d0XCDjbࠁ߰ÓZGX{Y7V;osiB:EOqFkx%-N)n} vV~ ]DX-ۜͳFul{#^&&.4a?uB"sf{^iѢykz9  F׾|߾dWbLzPWŎj8 ٬բ޳?7} yK&X|]l?3}-~V/~x2mm>"ۊL2q=>)8Yӥys߈S;c9-t+*w-w. 0Ĥ9pEI#/8~ΟKm{!H r6wNQ6{Vp5T]6i! kN֗vZbɻw`Ǣ+o;"&58O0Ű +t8[pTfϞAn#l!1bԅf.d+wI ̈iĭ/|)_i"wgީܜ&[حճtƵbB|5;(R[gr>G\3Qr\یD(lx"hϻO,޴],I9.TtwXT#rvd9)mNJ\!j~OP|eVOq=9NYĕN.fPBw?濃)hf=tsINƂHNM']mٓ b;1O>zEidd$at҆aY\_LBtelhH] o׋a;Mb K`yН;% 0X>p8&sJ.ǢF>7O(-_p&AzL0{ʈ2Кռ5evkH4.CZ[HzvFQ]G@jo:LJΐ} q A6:9{$ٱq5˗-bl*3肻yt<7DkHvаh#Pna;o!tg2Kiװi f.F39glo͇p5k&Wx22 9:G]%Ż)]Dq>:r9=oFBb:_$} VHH ##@ #$aZ(]p)cK Hշ7_NԈVMA< 8= v{`ox%BIK 5LqU5{7FZzcϠK(* Xf9.`ъMI#yG`Dg,$[l'&ܚLȝ̈́4;6f%,\u SOg9'Ϋ M dĹg *ؓp^}2x!6y{tL>BPUŴwzl_4{-=aS`$]ԱHP+,Z>Ly& "v I67af/n,ڰE y5_ThpVݖ^Ȅ] 9DgjGy>" yΧ6`dn XYL÷1(#U>U\ ʭńD'ϕDm'@RCq{g#? #ۅs4+\~MJ}|%鯮ṀGw_=-1CmAFcdJf |%/Ih>}{C*܈d|inb(UiW4QUYEG!8˧KlZ)qX<,&A1'Hg ûO_B_}nj*ipj£  k /{<bBUg@ yNTT8|G$ľџ[ncoPC]Gy {xsb0cZ*<6yg.sh 0Z 'f=~k:5É d8qکk "" ˯H1Wt/uU6:0qюh%= eQyI ~n$5>H=pvxSA L(_Vb 8*wݤψ3;ѿNXVXtI2蕤J$ISaq{'cy.X6lǞt$Isb:rWXD#[9!HHw[Mgu={rגf*cIfw=(HJұPLĤ?ѩ$O$$IW>3XSvϣt'm8r Smn5^~.FR*I$I$$I(S[0#)k:[,hAC]5d &׌+I$I3rp+I$71ZBHL 9ɐDUν"I$IJ6u$I$I$INj2$I$I$INj2$I$I$INj2$I$I$INj2$I$I$INj2$I$I$INj2$I$I$INj2$I$I$INj2$I$I$INj2$I$I$INj2$I$I$INj2$I$I$INj2$I$I$INj2$I$I$INj2$I$I$INj2$I$I$INj2$I$I$INj2$I$I$INj2$I$I$INj2$I$I$INj2$I$I$INj2$I$I$INj2$I$I$INj2$I$I$INj2$I$I$INj2$I$I$INj2$I$I$INj2$I$I$INj2$I$I$INj2$I$I$INj?bnݎʸZB ׅt!PD'Et]qO!5B4L&~Wup%I-\.4MfHPN!AAA':)i.K^Cҟ ÉN$4MC?|?H(ʾ?Ij$ϲ@tTUb0*7餧ҺA? 2$IN~.I43S@ '?6Su{a{[Mu|/,EQQF4k\м{G?U]wQ'ˇoBFuE{Tu߉)@7Fg}/kP4桱<-bl?QKaQ N((BOf1{()*A⒓ :"Q& wne L:,+2tLF}U !0G&ڲ{.M}@LB"l?(Q h.seF64qYI.()f˖-dn&n:0}UExTy(IPTtꫩɣ` %*:s'8Bżw?KJA%&Ug}.?'ӽTQ^Exb#mFCU +4A@xS;g| : b1k򬞨!v X]wz1+촞~ a$( Bו?ǟ*t-=8Ӷzt\1?!XfC{e\~ɿ}'`h_Q5aֻǛ4E72Xπj`Kߡ߼Nmm[k:rȾPŠu(6gʲ4Aa-`0PS(8GSA%@`L*\@9UYM3Yb0Z}sEUQ V}EP_x Tks-k[WP1XNJo ow}196KU.ҭ4$medUAlgC\{i-[VzҟMAl"M3hB10-7|V+j㶿lX2lwZK*aǢ`}5Xa{8tNaN׮#FϨ+CS3y_fum"\>kc[֯ggA1v%ЯcLYWڕ+ٞSԸ}-҇L3G6+sP#,6%5l(?݂ٲx!$CjXpv>17oe W^t* 6l9$cNK}J6TӶG,Y$w9[ٰn==]`VYdm+!M`EVi6I!]x'oKT[BFllO"t9agI_elmł.(ٹAZo@RNv:6mEEKh4UPM^Y ){PY&#haf ^|a>^G 2wTKmNf/Z]u)zTUT{V 0's916M/?ai; N뛆E*o#Y\yU%׮dl*aʲ)ϯi^Tٟʊ\1\ńº))֦C#1DCV%!_c6G@uVu6QM4#O@ϴH]2׮`ö< wʹiߟ.@;6)s{jd`ؐ>DgΟEQU\9{J`N>@\}:ѝqjd|f.f| gp[Ǝ SE\ 韂Qxd61)](1t3~[?Cf}ї<, Go( 6_|Z5;vQ%0xWl(dGqnչըa>"Nmo`7SXey3q@;~.|d΢yÐ)X`9gFiLdEMmsEgɧ}KƥW]Jpֲ=JǾ%pQU^̶|L6nczO8cWi=6`Lim Gu!kV`[^K;5P8.OM)ec 앎j8! Ie;d3HfuwvGMi6)9}bk˞];غmEN4< gΘ )aˆ d0DkPzǠݟRzϧ DrCɤ_ExJc]قQo&&/'ʠ(uټ%>~ ys{ ,ɭ'qGؙ4r FUaGO۞ڎ1#zSK:>`qr/G1y8o83Qh#&.%dtm&-_ŜUp h,I~:+Ͼϙex 'Wɬpc8 VP׸g aP'?c{{[~'_, Gtaɯ7(:^Jjq2̙:a; #44bOp=PlmؑY]uS~ىGse|5 |fv<~m<dIX6x NK?i4_-aG:wz/.FkIX8c*_-! 4XB UvF>-A!E4b5 }:ҫFg!s%emhkbŷ_MC# #UKF.:V7+w?Ϧts{WsoG}c F_s?>2ZPFu c43p "-nϾ7!hEѩ+aǺRT(L(8mɠ}&TdCÔYKqFS}Eb/Y?5GUE4;sՕkÜɬr\b6p"R:4& M)+Q,&#MN캙nFs)cѱ;0c EMtHO(;TGVVEӫkOFJy]JdRG"(fSY#(G O=0TqM1}m5ypw;SlL+ضsyKJngWXC1oɷW~it `tL=|S|>cֽn)K ,t0$2r8qbX"iaՌy{<\r߆O1mT7.-P-?ֻctŀjo=?Zu(ԬVN|MpvE"XBS1n aC{Re3~$. '(:oCR׍*)N]icTp{}`08'Ò|-bՔۍZ>-E  y|BrHjd颹l+sд{ wNBUTt4F(o9OXo&6= NC)[o~Df#ƑbMzo6=ZEK%< 1:ƘȈ501DrWp뽏qw][kNƠ3.cRDl A ϤCTSU|Y%l^3l^gjU¸gy!8 3+.&%@atu̚3HvA#eA%2% C&^}S6fX6̥^? Pѫ@Hd[TZm4.HTJG: *:5%E;33dhk!Na)= GD{ιZqnp0M[ؖWOJɈ̀=i9;MuUШ6Dt;1#1)~_9}S s((E|k,L$:"G ዋ$&Hl!kAݖ]Ll"o#u>zl!Ԯ@YV8uxvo[ J˘~x ăϿ{>1.%H<"x(aT{g!N]:wԉz0bڨv* RR(0?9̛ ˩c/h誕.CFЫk8kX|68Ы+VO e:>Ϲ i%%h 31I9]xUQ MC$w^nZBnf͜Kny57<4yc: OI"eU{((o|h#4l7oKC])9]h7ټzξz-ħ3j8$(n"$&o)!,o!EDuǦxٺ3MOhCUA"҉MfY6[Eh%666I$ tuz~ˌy?. 7ȳ*ɹa}(¬,t6AnDA2]4&s.0pf}}4(Rgn6|ƎL d".%X(:G3톜)]>gz#v]I t䕹AMAm:!$om#m,-yP Q 4ׯM\>lVؤ6^spK旬|#fYÄ(S!/U؝mۗr93, U[`KL&6i˿b쥜JucgI^=Y;w7" 1ga0(U5ITT)躎7,,B: 9_ Pr+np[}x|F$f1Qm#}t:{ uǠgĄƦȖFHS|U^ k=V9c2Dj3P%<:9'(Z}}M& f  @bAq.eb+F3{wa! 8Lx 6% E)tpr6[;WŚ^ΜʉH2t㉟6pE1;0 gS7W¹0(=1p6X *@HDXQq$ŴA|Ğ{NG;\Edx(5=4:4t9XLM+c d1 &^f$8, Kh8mP/潻K3X5+=+i#g{&yuytV*SAn_[mE `50`0.4 MB }|y) ?Woe朥|aFeT0%'gNkZʘv:c1=6tE`ĈOsiXMMqwp"z姩|>inEGwk7@4mUT*-k"]:]W7]BTZ՝a0'#:ж\~-dSVKKsH2Pa0x4ֻhөIѵ|BthϏ~5/~ \4;d|?g˫BinB/F11}c 4cuwE˔VşPt1}a_yH{ҟKQh+XzvęAӸևٶv& \CQ9|8#q`4Z9uӽo{_yW}aiŎ,'= QA( tAxnJ~>]y;9c f#F :EEk]'5 ;},)_.a™|EFm*ZS| 0tV[pi:z\IU1[ 46ypDӫ_JxBޟW:);u:ͅwݛ6 dG=*lAZ^0[^˨ia˘D=|r:JKٕE5xPhW0qpON!Hj Cd1EYбO G(J9!A'+̜)BjM$C`<Mśގͪ˓iDv*䤡N*bA5ST=uVVPCSc#jx #=K6PZP99"iTyA1k o*|to5V75б1pS\E F,73p=S" fH(Pa0i`x(n\|?'({jK!_(]'$Ng!_.)&SW *M{XWNHK'!>?zmL.6-Tp=Ž.LA!أU?WvG!dnA[kXC!Tx߻ LEǤp tRS׈YOέ$Ky8g@*֏]X?^zk[vSRl꽲ŸE),I_J[DfQ# VdݘpđDZU&+fҒ2 ʩʉpx] ,.ϼ9 gLWzeĢ ꩩiģrt44Z*khlt/Cc[B7Μ0sR.̣m،|߯VVÀ$'߆CG@:]qU^~2gLcSBVG8;4R UX gjvɓb:Mb7MM]8jKiˮe\.:f^yz'0Z|RK)Ra G1{4[p!}30+ uKxǙN~} TAumvԽtl2a WgWQuTVW#8pl?m q$нs*Fyw?(olǟȎ:hWU;HΚyL' E'й{gR>9;),2%Kw\Cxa)j4Ѯ05gJ~iM3)(" ѷ@R,cfJ߾=0/Y]Cd.ё0 baܵD W7 Z1\5x%>\XD.}Šu;(޾_VZOzt&>,@ 6pNQa&,fr0F!̖/H,ؓS\YWUP*(cK&=^zUQdT_BJ1@pxl,ZǮ2BvCry !5:sb :)f"tAx W]3>zo<\zϣ\6VU`4lƍ[+lp; wl&uk7.OTb 'M8du8m6jg|ʼXc;3wb̦[)unhl3˳P?qٲ~ 8}$)6`%: y6W{٪v1}sx7)Rѿ3(lXTہN7b7AI$do\?dmyIҝO1s-XchFl Uwk26eQU@Q TQ!25KywilGLB]eET}FR oQT&Gwڄ64YlY1WsY -ֱ%: 4bJ]U ;>ݕ A{)h ť[@! q⮛dun6&P|'Kg{gs﨑>}K/V npK!f9;JmE"蓒 Zٹy rrZ4dv~>UU$  3h6=vݟhjngogtܨ25)OO{{: π2iKIOb4֓[݂b ߮YB쟁=EMDd7B|KW ϒ Cr57,PYLn^m70Dѣi܀)IvvY;kkvG~qC9lNcvZ ّFjF*RF""n`ΝԺHЏ@O O#9@Ύ 䔷 ?fXlڰҺ6Optg={wfQެJzxΉǞ*{௴O[f 1ڊ?l@R]dgî${C2$%T-{kqן bh."+ԡ7uMIyAyuHMK%:JkU>݉/?T%ÓKCnZ׏P^V^.M.-erэN'PwPYG~q5GFl(TώrS24%7HW)KV^qK|.R3@m6EMeDhdwn?R 3S &:Pl&TW+%9W6ca1(x<ȲLXXOt?C?sBzvmkM|A&2j*.a0]8MOK)߾;C<8&o6nf_|5M랃,wmN|=:ruWOM B |ҙ,0A}sqt`*J&l@6t I}>ޝv7sn&ZOT βm_dkBg'˝CvuTU鞓%rg)u!ss^ҸZg*}ǩ}廪9 ]PMI6om -{d YBTE^8НΝ2߫߹|:}6I݋gͼz}tڪ;k>tcᐁ/+%W5|޳< f\|!ɒA6 u" ];ӎ3G/e/K=򈆢҃ԙ}鯫Ne@^Ӷ,gW}Kx9+ 51/\I6`ٿ]s{gK7߱$yu,UYtM&{R #D"k*v/筷!d썼A}i~F}KnU˝MWyj4mwKIDATcEU:=թ$ M- D:V1Xܪ"}UQz(TʻEBed7AtMD65_|]hvh('gp)qȈ_3r/Awx{IJpO/XN^m/Y;VԟyrI^UwSs.*sY|ghAi3~?竮{^auw P;ׇLy=.9(ttodou.fuo /:#Ħ`33r.d] |骋[ظum $I_zmiR ]XӦf{ ΂pjFsղ%8bF0c\&V7:GRS P$82䔾dfds͎u>$I)[i ʠc}!6aj~:p󯗄i`V6nM@tB2)dM$յ߉=8:Hjy?tQ>Tp<,o׼5t7?U$V}c'6"uks&?O[ |}||bdss|]P^G܂ Ce&]<op'sQb ^&$AAAAD+   D+؉;R5DAdsxsQA8IEuFpI," /$I( ,w'A8ZdY`0`0DZNX]eHG-u8 %׮+U;c+ jliP~MhooG4,GQxzb1U?9W$L&|}d2ʒpI`@eRUY1-`h4pL&ăA:麎xߊp4 MD_HQN'~~~X};  '<=Zh-n#LEU*^נ O4EA#sN2Wq |uڪKWh)B_հ b_At W#fŋFyAN2Z[_ً# ؏CּԕgoumN@Tro9G |g=L2J ,Zف1 IDzݭ:R/'Զ铑IluO$u]Fфh m_VjR?t 1>}U~fB* ّUHp0D!i/u]G hz$dk~j-&+V y>/A|///pB'EtQ)J1<-SϑOWdjJ)G5IL$1r{DdiQ5M6b6F脞pבMMLrFWsֲX_)dhbʏĹiqS;8 =z~%Ȅ"͍,\h*o_yU%h:D•C?`3SњgDtM e1?W^w)bQl[9_.Ln匑I)5/PLzٍj7|ѧ߿7{Kz߈ |h'%89Ahf˲ugڔ~X~✚͋b}1'7>GF^x) #K_neٷN7c4Ⱦ l e9vD[ϳEkxu;L"[w֣r]M[ {MŪɿك1ՉVOV93e 231hx.&Fs`gMtZ(svB@6A_1w-YTʀQCOfę\8*oH<&< 6s^J{gM} S2f8,]}YEx@vo-՞Ε7\Ok-1yO+%{PUMolc6WE3y`ƴF{#;P)Hsnl32=̘s&1Ue9[YxsO6TU,|0f@2f|[GDADD(z[@buJ qDFFNDeX =0j,U ә8C' Vo}KU8H  HE+Aܝ,}X+*w0NB|"FO㒉z .P !j{)_|-qѣ]כ ѼMdezQ^4? v߈5gc9Z_sJxWɮW}](ZcW|LEڐd7${\~c۰w)/~.}1}ν*>(n $%I#X0iG ?_?B{4Y,Ys 71lh9qvD{i.ɧM3aXSI>@NCI6~ |WmcGw5b:S/܍,j.9DWGlem|$ |e5{X2I)KU~ c 8_g>YLؔ3jAX2p$Vl@hbWyiEx1蒕Gh51a`2K5YZJݞBZv ch.a:Ɣ($a6T~noIIo&g7Ɲ~v#E~i(gca-` z $y,gLKdݷQT>╏OǞܺιq*5El>xIxͼjZ;"vl X{z=VASÇqmURŷ=MM<7we0ZҺx#/l|*^|qvoF;̃,8qyxrPݙzՃiC`#¡Qa' / 3xƙV,6":Ԇu}Lm@F2gy߯. ڔϢMU 4^:6!qjmdc=I}s1GwNb*u3[[lqFc^ȭ7=njýCs3h{W6Jz`9= ]]`+o?%4؆:Z2vls?>.E-vjNl}dxl_@ݎYoc$e̘f &ٌе¢~O'2&S'ch@S>_->e<'O|^:1p(L</FC26bϒjWgn dE71ưxCD2]w MoqC/i$i<0ʛ A#J"v<#y:leW[op^RO>,۫8F}e)J<.a6Wv2sop%i{QnypyM 2Qaxu!xkd79^^rn`4c 4zh`?>ctM;n^z]㤺u˩/|%=K%#O;P Mt#/?)Csl'|h{c KVvd8I3;nk+6v?ߍYb - CI Դt9.:̈́W8*d1V_ij3wƎfsl*aeYΰ ;QG{k mG݌ZkL4'W#A tz2?ؽѲV9eI&4e,wu;-kqWe63?o3~گa M?Ӓ:ah`'1sO9g&fŚ8SL6kQD:vLp|XS_cV'J?f dﳡ6r/c^|?قcOK_z,^Ew z e]Ka쨑)nT d&a{6'o%cb.`Z*JllDGB!$u0OFoBq'N?A~U"KADF$tOc73dx"XY8himG!0:1ɧklDSE-RX%vzuLz{KǷ.< j+@u$c C&NOZ5*c#b=^Ogoa+)1HȤɔ8[m `?B0*ڝރS9Qc'{QTxveQF3iP1 | }G9/k/|5Z*v狉:|$lիW@Cc=4]Eq+ھʣziQ5<!̙y:ş>ǣ/}ɎP(,O|:&!x=g 2GhcBoCy1Rhm[oo6AQ}'zG! ™vѹ(ؘ8ؾ1eT؆E8\v/Rj1\t8z(4ŃSzU47;ӯAa R:/!gvBGLczh,aeӦ%#P+r"8QFG]WƠY2sD"M§4(}詜5 ]#њY6^Ĕ1ok+/s<#t>z v5Y2Rs-yfΞLW%Ύ{(+.ЗL#Au1H8,f*ve6]G'a3qX R_ pN9!3oRj '̦wjj-8o&yHᑘ\5q+#0kB_Lhz.Y;zFWXVn6w#[-̘s: $R`]PsNouaEQz?`_&~[ ;O453h:lnT'6u\477ASp8:pyT$Ihgr'm0𳢹9 Ft8F; t͋ÁG 蚗6^dQv^/!!!Ʉ_FWqv8h(Z{1Y|@{,^MLlb*'&⡶hs?',pQ4dWEqDzfa7JF}6/]Ob#9-Qw.lâw}R6Gjz?dl7|垢Kmvl޶64M#((x%0ʶ/@3]@p:^$لnFFle7y6MJOp8Q0Y,F_DsSUU-(`{5w .#1R/7NfmMDe,v?XꚇrɄXd(B}}=IT ÉۣvlVAD#IAp^7y)D=wc/E'2.IYJKv>~e3`3v:pyTdqyؼOzF2 0Bm{Y J $Ghp;] VBڒM dxTM꘬vlANAXO//m%Oxxt0'$ |$$_QK~~V8ػ}MTK."_i*)B #·hgFLooo|cI'HNJ~Z[)D3at:`ޱ |ENcG_Mp:]'=>7 ‘%xq*2#' zA6JfӁ1/A$_A$C@A풌"6pA8rl s2AA8FD+ "AAANh"AAANh"AAANh"AAANh"AAANhGu;#]uxGA8$iLE5I+E_F#XL8uO:N0NʂvQUsoE8I\.t]v[$MhooGQf:mmm* `XuZkZ h<ʂ Ix^BBBDpIDkk+,Ҡ j=޷#BCCE]Z89N\.QQI$!2, Dpu" /#˲njHkXFNUZj(iD9"¯ꤢG;w"'( b ‘{[)iB՗vp9T۩˝{~(A~CU,\ҺvT>=4ŋ«vr2X4&18OqVǕlX2c0)봷6xGS,dKt+4fin^n#'ʐP_9y(ٱm8]n$[,ND\oAuk(htp2ozVc.lvс?&LepBZ]ʫq0}8ż0mn[i*u3f14!wꢺ4BIK[3V,w?u@pd,Ⱥ *ZGE-(X B喛* 4}Ce;QqX 2ZvmJUu#aBѢS>Xr!쓙NKM!dz,yqᩣ 0sOF/'qᅦp5ﭫ!m8l&Au}oԂ0k _z[ojz?}6{.sǜskĂ5u轷|^dSjM690frɥs٥rSQ=LNO_N`-śxgY[֎ۘ|(%ZG߿UM>sgL7RɆ y[/q^A=l]&V>ZAR.ì.lp`7I{ ~[Mr>mv>JcZtIB2h3!LtBbB".qC{ԛr.b֌S4q",1sh?&=)q\r&J6IAa蚛5e2nD&M,2H;k}65Eyb141Y8oEȔPdtDUf0pl˹q(H1uaDՏ2Fe^!}3ip$đ:|*1[I!u=&7#Ǡѓ4y2 &V't6҆E].L5 ߰k[X,ڸrV7Έ36u(V;|_k,"kǫΣѝMe,_.? *{=nb Y@Wo?6 /O沾M_rŀQΚWҢE3 pɜ)~.~[*k@$&[^'EWN'A]i#&C151$ -47Xgw0"+ng 2!1Hhu9(lm`u@Rl\OC#(*͢2%avƜy 1 y浹,_C{^]pVjFg\%z |% s-,*v$ȌXCqˊW!)21@%0Lsv1Ozs! = ÙyͤƳod2gtJ hQ*zr3Y֋f>7URoԠ'czܵfFu>Nn[-a ȧးLuSXoUV[$.0R6pln^|NV+OypǏ|||YDYہ8XV2b rj+[ FL?Zm:xkI:mo nJϳM&CJAn wS KpVr5lt嬙~c<˛oǓno-͞m_cP"e8b983ږϿJzYebqmrS <]T?%c͌g _β~؂p Ku݋, #!~t;quo:rl A~-4;b1`̱w_ ˁf INeʚto;{ SՌ~P+`[P$ zq)86/fÖ[H %?S2Z "20Ź?X$?bSbin/k}'iDoOj¥DMXT"~ 4wҀўAlq2"ð])*}c bYbV?Î_E8(nέ ο/\?/{\\HxD8}Gr3:rht,]^S&KKM[.6u鹤t$+g_-3g3f0 9ȔLƏHajT{gZFί}ƽ|WecȠQ9-BE@ ]32p~}̚yCS"ǔOJA„=ǭ[*ic0Axx#83Sc(Sv4s7UE43/ⱡlʥ'$Aqumwjo@5p瓣c-+PV=Ի\!88AvaC xD$l 0$7ٻ),7q_FHpc[F4]?`2&Fh^p`dokuь=eAQ7=;\=| DgcDykVCAɞ& =܈jdǺd78u4A;\XPNq1&3mz25;6SYC.Ǜ2)Q"`ZKv I͟#UG#(n4IQ A[GsiRbT>a\Ɵɰ`@)QSO㬳f1o(1i2e A&抽ٸF^(/9CZD!V1jB8bd{8'`vg=3ET`N=e(!VNJz+;QA$t Fw&#Y?ho*twfs-ΘNZ4- BIBPBfӟIu BEv1(1v7cgA-fMC϶:VM-ɧęzߨpSϊՕ{8k<\ue$ 8ڪ)(kؖUJN֎m6\G}m+ *u4RVuVi^P(޲&m TTBUc)bOHEl|XQN(fl}{ *h`Ƕ] =Ǧ5MBiy9TNaeXc+xUۿ f| e"+پn-9{d`ao)fTaw9#\(ؒ 0e-Ŕw w*Ah/Ϋ_C2gJ0[FqU9WψYL XpդYXbU٬Gz(#b໅Y3z m2vp"6R{.?۞fE1w%|q^{k* hr)N{uu`PcS.,ڐCeN6WKy9[g|?4z!t.=75  60sǧN M|pUE^UY3'Y'kv)'i)\|4b|]׼To#{PFdtg<jZ7TPlg/ҷIl0/m2C- ֒W\އFZDMFM̩C3*a)`faf\f4HKjL9AÆbwTP\RޏfO!w-[X#%RV@YM QæqL,]ױZEU^ewdmtD cPB_~y p:,)ENGg@h/'w:153=tgؔTgo`UV6Ӊ%qhN9Aq##I6`ɄQq,WËϘݝ40RV&5 iͤ4 ÁjhЍdHZ=uttK '.Qڱ 6s$,Qw!ϼ1v͵x=,F$ Aia.W9uHVŀtI:Qn|E֔u6S\XIL׽M@L2".*AY2<ɂ@0?)NƐD 3I M2G3bh&"J+OӇo?M+nU&̾`g?Aot~AasԤ`̆.f]Ŏ%Ҟ> ގ%$$xʉQ>7Dq4QOmBPD,I 1m9Ʉ{iAAAɄ3l CbB_k.#DB1*S93ơ*̀|tG'6ʋjtb$1)`?LQ  HQWSSCXXد.-UZCPsQROeh ߿2on .=äK}y1E H@ ?ƫtp8 IT{7|p]I[8-? ^XΚ+F{G~MieɠW,in2ZPt2#{*5~|L,$e &xl !s$kC@Ja3:vo`$OH#XE d#agHmN!M= HX"7? FTA#l ,*(?Ip5<|Hh AAA8$xAAANVbԯ   pB   pB   pB   5j9j[Iiz *hv$I(" /Up麎(roEv_ш<_@~ $It( "9Ip\hhiP~`z'8MGGxߊ 5]c1H']בeYP$YFU\.L:E7bEk i]^ f3FY4i ѠzI$5  p*.bFT_cJ=*oIF6H&:3qG2<9JhoX_seP}7I6S5?nFZ9 NJ$cIq :˙zo$YFZ+ĒYq]th]>$I7:Iz}ǽv}$2k ?lkiszJ}C$4Tm,K>y%I]fFHD$v#_G$'rۍ(ߗ%_40E_zg^sJ<'R>|Y?5dWM|,b|f MyմR8sc8/ gn9ka/'~Ə&Ix[J!397WP\mdKfXQ~$ ޭX[V3jFMMrz( Gk, IV vnfBZ=bS2j`'R](,Gfа JU*5Էy?CTh7[wneDž"io_(1!Ш/f9d3rp*~&gӂߐtY,[&!}xFBL*[Q5=̇Z@ѝ5,[Ɛa̞EßTqݷ1&ןG*A$ZK6KY,|tVWq<5m)\[$L 闹tork9yČ}#n $do3 zcn.t˿yӨ-sg\H\ ՓuQaIR[!"É nc(CS"1dGp?ЪT S/+{%FgF/0sj?'y.lWoϬqȪB{c%{c_O {JP^l=󧐙YB5JQ]Ȝx%O?72,F$ሑ዇x4 ]}ս<uN:j{"{Adx XIvZ&Q!Vdٻx & 欁B$Qnu۴V$'{ycHB ď=G~CgגҾ/n= 1kȲF,ww.JL`P~M7/#m|399:X3f:V4Ud @ hluЄ` j:$c0tS}[rf@F%PAWw^e "ztK=:v}(_ޣj*.u= sh=A.ߐY9KBt47뼾HH{]Dpdmexo2:C M8۶7"NO9U7o}ƞ 1z##Z|EM¬ /')^29u8" ^ɀT{v1d(!@Cj^ycvW841А_z'9mΈ:>yn^y#H`k1[lfxӥD.q7w1לAUF5t$pֱS.aRE544d1U8$rv̺R2fa蔑tDZ;HLMB]ٷݍ߈% _]﹞,gmN9g y&Ae~#&ItDoaŴ˰˿6qhE$TG5?˜YSSKy78͚NrG$+~מyi#3c;(w{yL IHZ;D> ɗʣwn G_{劑ǼE1 zoGAGـ`eۑGc -#2vvUsfU o[ε7\8yl߼5[rL嗜MPϸ=|vʢŤ/!#H0;2hl V1ӸYXWK%o$Қfql'QWWb:v2#20㦪 vAn\ͺ9T+$5Sι3gb3H芃ܝٶ;ZD>!I!ulZM ir;nMط1%I(Z[jsSǐ' P?%2qf3oq PMx׳`"Ho,Izau@V,dݴ L{sg%t'{-E?믙CR ]SQ:%>3 %Ƞ 2~ȺvW5*n!y##tM=0o].`GdXf -LYS8#AMGs;v c/0E3bȲNe.OLΈ(i2_^6|&#Sk% IS޼m\Y1%3,Q%k]~ "eOy;՟=}U$IaҷO :gg(jgы<"&^ꈽ #>y5x;{p~d:e kx&v9l|M\{8F]_Ojq:2&^ȵRCnx I5:MKww8} 隆}AeY14!Y]P/|믹nEukroold]oǨ6QS\S_8Rt$[4Λ_V>?kiɚ,y5Mj;Ó1t5;q~ح~HȖ@MkmLXH0&tؑM,˧}LN={5~ {ѐѨ+eG_qkUS#IB\ϟo/Ã&ޓDO\5~8-(Fz:Yh.Y18_=:H~ "Ȃ(x;jOiNјdݠU*?>l/Qlf"=*0#6#^~'eV_Dms-FS8ꊊisK|Tc :*voϙ3ƒ/`JyYn $*pLrz?'oTQIWmmUd7KV4s'XMNUw?ȿx r>~p,[ zkёLL>nh`󆍬Vnå_NPLO1;7a+ȯt03k8sD8=u-S3ls?'g*^B)``˹o{w>]*Ix]*@gnd3"\8ݭ(ʱ'*?^|'O=t7X?%| n"uYSqe/摿ͻve JiM⴩3^dv4v?$Ʉ.8ߎOχdlZDXh&.Fn 6&[.$-u7p9^n,I:*2xeH.^KyI0$$c$ $7jAt B"dt| xJYSNps L̀ɗ3;7/U7H? u2 Cƛ|LLyy*:}7W᳂ }Cj ēϱJU#2.>|a{Y3bZTȈ3/Mg$w<>|%/?Ee0r`~O>}V:F}OĿn9o9~e*A-4U4@W5tݟ&PpHc9Yyͼ̇5 ȟz' ]6I)I:+xeĄX:hU[ք%($4:Mp\g{ Ft16Nfc˲OxM6 ;k~3>{-6 Z#I@tgy o:o4p#1p19LώoeQt2KRS{u+1Cm/Ool&@1F%"ΙMbM $ʼnGבqk@lhz2Js_|)s/݂ۀۣffnfя=f#C|[Y=ђ0ѵ<~ܸv/ V@}MP`o3kzϷŏpZ#*<A"j,~vLx)n_ 8$PT0&qӝ2&Ap -nJF5tHXr q VM FĠ{[ANI-JV\xٵd.kc8Q$]Czx2s43U8j(/$sLMrߞagAr+3/dH/5ai̙3 sk5r {Λ51^ {+oS;D*:V ?ѓ( ^Y?mt\Ȓ/>bݸqL~H.$<[x#a0Q rvdQ\݌[D- 7fZ[jhU ָ QڗKŬ6//筤e ip2Ml5FJQ pa}.-#3 i,`ڒɈqHM_+[XNlɩ wYp_Gf${ CP2F[O?9R3x@ Okf5l= m fP r/ǜ/d\zcLINUUt]l6[9IHgq+dONlڍ2d\~(L2kW0.G":*H#IJ 4.P7DƆ-p͍nVGl|4J]qf> Ww31/3Gd`"Ը$[KC.v瓟KE7[)ovd:07r/]ʮ\6YGqN \Jy)B P}71>(/q;}8QQDEEB}] / Ps+=M熫!!؄9)ޱE}ut̄GM^`ԌY1XJ+,(w%FνO?2JH x;as~S2躎i _3 ') @B\ʝn] SbnfwмcVob-QYdҹgԾT!$.[[?3!%sϳ|K1#O?`?}/"+H 1TQ[ xghH[.M7T27"vΦ8w r:wH |Ko>N@ɒwb$)i9ٓ|r%θ&HRTUUTO'7af0:>{~AasԤ`̆g@EGGF%I)-EGAߴtm^UFue%5MB%$;u4SVRNn&<:? Tb&.ҏRZU1hJX"ILu>*?ҚfLpt }c-ȧ h$2!P#%9yԵ0ĦdAX[EU]XO's,i7QQYMB"f=PVߊ,HH'>T(7&l Oz_UVl1M!jhVGJJ˫qa!*.؈@5pݨا(QP~,᲋ǩb1vNKJoQd!4,8FhJ*kv ĀFGc;7/f'8癘hlf'(cڹg^%"4r4 avV}CH 1$$g0a2bQ\-W` K T-僗_cW$FG"p!DuvH/j-f;s 8\8m Jc.o*t%1.׋Q]Ͳ|t^ ;0bWЛz{(L:H(4VP\Vf %%%?Sg *huEED]&ؤ$&$t͵WѦ'62o?x6ԗR1rxBlk(S$Զ">|eW+$Eb`FLn8ڊAI‰Fh]Ky~߯e7C9Db0rdFf`DVޝy g.<`4f}0gIi)X/-bsƀv$p6R\RFf%>9?$]GtPVRb$)6w~~Kl6$CM<,VtGsBz]A6[+BQ;z_n !孫5 Mבd7/s`Iл ]CeAY6 wtN|ۤ:ݷvmK"!]C}-~ s}t߽t}wMK=L Z:ׅOǀ$򐣊;+e{eeY}%懕vDZ%Hc;wPGA2XmR4Uhݩb[D;vs*^n eYWY#Ay_‘{d7y+עAzgzQ^n*fŴ/J zk===zq(lV A ÉW訊y"=yHd040)2CtM젭Íjώd@+Io?ߕ2$p<`0c1蚂ӥ`Y0b4슧}zmt ˅d:>+bc9tUUy[GU_4z|_Qq4U?} .u]Cqu}o! ')]GSD2}toX{iHoyHlb{gO [w^r$c0YԳ F!ػAs.=NZ&#7?^ь0JLf}AawZ$G=V5t J8hq*ьZis;C`ga1RJ8 $ F3v^pRu]"0{h=J_ V}kFBpkw1$ѱX'>Zln7: {yg!*Xl?1 =ӝHIDA8ڪκc4BUe5v8±'I^]E_H4E`0 ˢ@8dYd2&$IBӴ* A-p\*`qt:u]4H /immmx^fr0.-<&_& FYNz$!2 pIݪ*Ҡ $IBQ<~~~XVvp“$ Ӊ(GZG-5 X,ƣv AMzHb9޷"<4(`h4bXD>&‰NӴ)Gob̥u{䷮hã/A~*D!džk::PDA8bT=Q_ok7m 4nGwV5,9q d5? ?XK? m%"_A#Cdn87uN4OeZSl q3o_ɃO~wU\isոw"ݷvnn}+[wwk @]GEH}sL&3gssι?dcEԌH-EXȹwd絵'w KgWLFR*Æ(sx]ۑ5F|Q>5XE3x "Fq:츽39Qr`Pk:q(\zvlAMmhC'wD25EQHS&$)a0$VBϓfJֳtR:Td&2|ݏ2ue*(C4wFUn pzUD$Wzp]1GNXmUcvz1'?+c)UV5V4%e"NE9|qX:h0o<:sc9VbI/>Mgbxrh+2. KFk0j8TZs䱼|mo(Ry멧X]~ٳsW= k\kT BLdjį'suR@xB=XS={}Ϧ}2Sb c@D,_Gp5pDDyY&qLSS+G3f(FCVl`7U7K`%̔(0Mh+g7N@"ӳIǢ{#$_Fb7k׮E׶NڭUd5~V.8_}C'9ҀGU dHרGDUl=v5395cYwE@%]y),Y W(h;x|z2GFA|lNDLh_PٛzSS[OxFAz@pKv6lHcm&iP,S67Lf~JҴe%1=UGmAi%@BmnfϺJDD߸H /#a aJӂ(hMUIIRIVt_7pRq;[ٶE!xCFnkHcB`j[MkukС2ӯ0JObz)?~Πka AFؑ`qzf.D஠\Q|p?ӳY׃߹k) +!B<ſ*ܡkVc_-XIy '!lFgڝ^TH %s_.!MX)D %6Jc^;̴4tE=Ե#i M~G{䱜64_0)TROEYMso ?]@cF;k:V:1g1;G-W>}vD}A;~%bE\eyxُ(m9C3. +~7|-#|"r<7?~v5\>9/pʑ䏏O7I zNv)13h M<|(*>zKpr%$IH* uLVfdu~`o 4oekABӸ~r?w<2߭.cy7p֠n*/{ُVlLn`^{C H>& r39yq)/$$p4WoWY_ʥg#Ww&|c|WQS|yu X{(v ^Pjɗi"6544#6?ߣgtYaes㿿4WA19r.lz~m,Q^sgS@K\o?^>@g~_ӛD@`n^n>o /Scqz^<3|0)Mv8\u+g8ynv,x 5c f_1)k,XkKJ#+[YW%e@~КZBl7EE7AiB3qrec04EEmXvK/'Peq69/^>e/<#o"^K$??[xw> ^{Zjƛ7:y Xo۟y,|lsTD+G}ax[/peI/",{ZD3p *cq}dL6rw>-.yK=3ϿJ(wb\FGsc} i7T(߸|)1dJqPy%i~vi꾕A1D|oW(nq! ˝mD7)]5=,V+VYNH&3{8xCM6m*IDXf{9#+d6D Z0E㚻= ٱ>330n֮. yM x\h2IDAT %MRQrwW۱ sB̡ґo. Y׉jjaw@q7fqf;msBX;J>|m*M9<{ao~Pچ˰rônH V~+q,n\?&> R{s@f;{>n btS#蓚 pU3(Ʈ1p(?);̞5_Seu6.|a}3^Drٰj#bIb9Ws$v[Z¢2N5 [U/c)yu<[  ɮS903ڭ9znΉգ9"x?] $tPpx])(٘w=KV~`2"A<|3cDAQi;A!3w2Ϛtw9OD@ ބt^J$i;|uյQOmc0/J@W$Шl6+ҕ";]UHIC x=v^F1d\_ΣITo{E@ D|&X"}Kd_g(نO6" OpL&2:$$Š$8F1j0)(#ROYY+}ω@f3rx ߹\=@Hvlء>Ppo T~q2O\)`DtpNHd)RP_IAQE>p" 4  [5;|N *a25Fչuk ;y6CSˉңTtF[5KhfsAa⢩! #b*55D%>k8GvB2(%=*->azWYۡX<U,kjpь݂uˍÆ+nsrYpYRctb}˙ p$ |bf BI~S0-+kKauƍ%fbޘVĿw$+nb#'q\^9l;[Y Z*+v oх|wp=b-v uܹJXNn݆Xf ɟ.D߾U۪8ټgΥ^.A$Ƈ?buv;عݰi;"sgNP5u;xM0x\AĈTb/Δ (جASqC\Y] `6K 5_5>}>$⼽^:*K(E3k@D8"Rqٰٰ;u"Yqzg),*gs+kh$7;%u8,v 윕^xQ}%}) |=uVO`%qL";VE6k,Auwn׾ `O)}{q eLԸ1[lxZ*= 5/5(;`b׿#(@]!1PZu9ǃh4Ru.IZ Qnak;s-701;oG5,dGLDXomêڿ?aV~Nu۶:#gȴ(4"O8ɸ\.dY`蝵pTjyٴq#[K˜y 1 FwxuHz#޶r6ayM EtT!ϗ$BVlYPBy勄 X W^! RlkWQGmlemT8s8B$ eD0&R"=yGd2Aqi9D 3G;tBQz}ouӒϗl޴[w"%`Ɉ&S",1wQXy^0o F MKCj.eǮBJʛHw6'CoןcU ľ[IejU*? 'OODjRwSRZ6y4GA?RCUw1u.gLA{PGel6zFL)t^ÖKXvI01񱘔&?85ٽRwΟNjTTjFU 9ذi;=2'tD wxWWm+[n%gk!>Qˇy]v F=[ǼC1%՟S4c9bbrAeIC/)}h*'o12ϾqUoߦʡǀQ'Qi=n kw吲0?Fk[;}AV`K ]#pFhh"{x( ((32#h~ ǃRѨQ<^*I"+OT*4&, n߾3gS/ElXOQγ5a}fNL%+3`A κL»Ƽ^^%խ>A~ Jl}"pʒj  >,UTuiz'UW9;ز|5MXlN~ {]t6Ҏ#yl]4 ǣ)aZ:pOÃ:j|&>F>ҁ6,9 O1N~uϷDlV`Wj tdG 6m`4DȀ39{pt+;ՕԵXQsd{l瞦UܗX[jnĩJ'a":9pYؙKsr :?YCck '^bS(7lobӒT5(R$g9m. sٰ}l6% V ' wk̗E݄Xصu#k岫o͹Sr鸔n ^|;M̠oj<Xؾy=n҇aPj$ pٕ j iU2xıٲCm׈R EEHtpF>bM+xo`KuCfL0qP} -XIiFYxeG- ǮeL&5{RpQ(]=6X1f[M;^9|~z򯾤RO`xVK"BPI|jd_ ]wk7?\.ϸ g\r1Qjb^ykI?g}by# lQz+b{ hzְόؼ6 G^wgua_P{V`[Z$$l+Y2;Jرq|\5)#דk|՟q#|罼'djrX}7WqSh{ )ƽkyw)1qp,nOhU&gYo>Ⱥ߱>[דW-q?Vꬿlݴ{J]#o~4cL8զ& Z5م4^}IɖlڵkX\s\?E{G_7\}+dguݲͪYr%thFO324^)V-]&cS}~xI* FhbA~ ,NV6Ok?vqc1$H ][yܵ}=?Ty1yvP/b8YO\MQ$sn6M k_PQM n00Z(jSBqvԋ`F1hٸnx-urbwL;7/|cIhTd;K!h"}#5n%~, Qx%/}9ӇMc)}| glN3KhJ^?0gNEGꡈOx]_rH{JGLbVX4W%o>./jc0Ybg+{;XKnWipJ6nރ”i Ԃ⥽JG'½1㉖kټuM0Ɲ11⦾l{5Q-*16h ©GCps6) uWus4٥Iͫwb/`+$E GQ:+7ͥXXǕIq=SPWRv9!Gk[%a <в'wKRt{1s*,zZ珟xtHZmZQa4 8wPb$22'Ku lIdAhѐb┡,ف|;WjeRTdWC ^ݕfUɘBz@q}NoG*b^T^)G;w)>QB Ǚㇲt8:tFBuu9I!e0)6@Rvq&yFz3H/8#[XFʔdFc[(Y@ck^J}-dS Ac _OƏ8v:IBr+g3m2z_?s/3 Y}vcz7E>gzw>{m3޷wK;rGhOnIԢNNM> v>3R=|+|-GVB+͎nk-bgˆe'9X|PFA4ˋٌdݹ9X#'I9 a9uVvd76ksd;8tt;8nE׆kmdԠn+.m)'rӺm=x^Z||Pit؝ݛײzvVϼ#1k{Rh(šB7iv+vہBQD=]H~%Dv}8]{+_oDNVŊ9$ ve{ 93Iyh.flٸ^}/7ꄳ%[9~(~Ljm5l]M6y뫵\q5q'{=,IL&Pcf{q؟qK yv\yZ H[\F$(Zh(MΖIOpx(r GC%Ԫj1aaq@M`X!~Nlv-PaA8IEg0+iȎO?zގWWS䩗ټ }l(4rݸLEx7(͛&Ty! r]oSur i.%j$[l.7_aQ߽ ^{s+WPʗG~㣜uxz614FRN+^Vo>I\&Дl+}&νlπSlu,]!=¤X(W1>5Sa jl#a">goox!FEz V^⣍-c$\o˧ȿ&-wR@!$I^R&'aygUn?Ͻ9~Vq:tCb'RČnf cA 8iokŭvBu㲻#Шh.) ruYF4#04 >n,xKW hpGO"X Se1oy- y|[?ﯤtDŠFMdP G ݱ8sp4:-=˫ n㑂fg]#6(13b= !9?? ܛcƇO4.BŲ42 ͺݼ_(z??Pi\1{Uko#xeA$t;[XA]$(Su)Dtkg՘aޔh N G%vͩlF*Y\v$T&ti83 X@WV˪2/ӯ8ZgOiSyeZ]>㲽 y͡^{r?ooKoCKL5b22=KB-u辌cc&.LK3{*{,|ոjdEq%ˈ?G/E<]cdNȬ8 &:0B'2{G9JL * hF#(?ݮ8݇j_H^}B~jt7 3'* mM/ѷs56aLɰ(ҲC~:5&ʈFvEl4E(h|\E[ufR)j QaqEcCgYr-rX%q9cGKdxJk?ykVqQe)[ZcκKK?~CEqa\=(FIDTR"7b_:Lۗt 8/[/W:?, ε6oo~(&ia\y?flz(ͅMfGd >`HR+e_k%S0X)WNCCe$5TBqE-h*C>Z к()Z&DkZzpL*++ ODMwENE>-93_"[;rL?*n ~79;zKht4Φ5n7!r\6wتpdtXJG2b%p) #Ö=v]{5Ya"z$!l|wXST^JA2wȑFK?v|WLe|mI璿=e&6,Ƙ\yX$}[rȊDĿ-aZ2~~ˮ'~FF9f K!R"/)>Q`%')^Èߟ ¯#h"eP8:{g|m%YBYC#ZOv.÷R wJ GpfQZP֗EpW:֖qEGLn)9Ff\F[<id`o*&$+֚<3= B;`b׿#(@]!1P88y<F+rKB2ah%i8pܘ2Yhkš d@BLc,$[3-mTL?L2":5~J¤߰xRhmjEOzb< ѨʹX%gOIFdB_H𧭩CP,}HH$hh8xb" 5ls^uְx|ьA5n\.dY`0 ;.ؤ05ѮK V/_3.iG@Rk M,bȎvvoZy3Sc OF6CG#6xhz70CI A-14~i ؚi´љ+]Sz}o_n$OEMUŕO ƿ\OI$b" #,~ 47) 8eYfhDZ[0ݟ#RVuiG}eTxb MCR>$YF&3tTEwXdN: ^ ÒB^Qv;|tum47621tVL&N9Pn7F'&$D ڣǣ?ؑrdx8K8 =^ Klb4 lw//8Dp$ł&((L8<nܛW+y($%%ϼݔ7yKM!*įǦ7ȲL@@oߙ u8(_;K++H`n[?8\{y<455(ӯ.-J [A2mXbnmIg"$,WzQTC":8̭446DK`p!CkE鸝vFHHdz4Is}~ <#_Z[oOՏsы^A8i:cL'i6Ik/jӏdgTԤ10`h+K ?1}W 'DXfrQR_p16Q̺/xυ I*'QUGJHʏ?i1A:vipTb "ENutVBJr&\%I*D'_Hm?I겕l+ HKbؔل~E   p"28OEAAA8.$   D+   D+   D+   D+  '!I]#6l6V{w^'I6 ǃFAQ>%F$V+R=(,8, n[>>l~1W0 uA8qNSS߄_3%cR6jASxW5{ZzDQQDnn.}_qVxq?x{R >d+y9쬲8^z+6ɄNEfd0sL|zWqٺ3XM֐QFEըTY[o0Ϸ3o`D_p~J2F1BN{]~=uv A4尻SҎ ]b IadyNV~7kːPPp%gms~%JQI!}qE6Pncv6LCogl*bLEO%=9E^88Y6; Bj+e.Cرg_OvW_x5錝:8'P-=gן |=5m.|4j$$@ןK޾riCR]{k"H0@)jfy>ױg:5((ߐ԰m389`_eŎ:>jT $ !yCbۏݬXk?ygO%!GkQTd޹N=V}w<r쩌>3l8ξj.<Ob1g3sl?4Ӝm?~G^CIJgɨ(&Cz]Ԕ`WK͏9-Gn{#[6l"TMP]DnV)*.^QЪߋڢ<֬ߍOx")Įt?bMqgi,畗?TXג>`)zG>fƱLMA. Fu3⵰}Jnٍ#:V?,d_;sLG{ɡՇ Co_64hga9 'dݾ>5T%ohVǒIjpΚ:@M)ŲLٞ-q|ճlt4T'?63f;:h*Ŗ"B-^/vf|kZ݇mhbՏٰ/^kֽy (MGwXJ̄3~Oz@tENE%)x.. >z=Zao9Ett{PitZ]$^ۋVg TxA%8.T>:t>jًWVPk4]߇NGӕOx\.dI^o8sAN}l-0b}@YG\QT22~MAQ_LؤGk쿼ȰTcjhߏ _#qԞ{+rSWWǍLNaYWt { *wQ7b0!1c~V_Ķ ˲JyڙK3"Y{{m lޱ=<%u8G& Ef/_广'χc%|4e vjKN#>.E"(*l( >4Q(uP27Qh; C'ϛx aYdTqߚ^{.C"6l܂7{_W ʍpʞYq(_)=CWƪ 84:pz1yى[*jQey4uXim猳g¯`fFsn!~Qù ,e**BS]%TfΜB\ejᰚIw>ň4CA8UH:ҳұN?g{staxcZLAmt5_DoGfі!P7J ';d ]CWywcn䏶v#npLE䔵3lGTuGt$P@Gn~͒^ z*YqRY]O;#?Vdƒ"{޹W{M%2GMgʈ~ÏS@^p!͛CP"niv߰ps%p7sjUx̕|+,-ҏ>b:V6| #(&8I!u,-VnkBRlǧƒdPyZX;l,i`ߺ/ymY9Ͽ/N r*']wΝxGxiMWKx{n|IGӭg@} ̝20=8,m{\jjQTzu*O,u }j7Vlͥ-hCRBQѹ5] MM9%DGbUkPabԈ4 ]I4OZJذA{4$ٕÏvROai9mMHD ґԬ}:^yud WF<׸ۨncƤ$wIMel.wB * zWRaiQy[iB~LvSoyP%,&c=x7x42[++J=< jԹgƌ >/>HCBG\6\̹e&Ybx5AaRUCM NqkeBTo_270=(Y ,Ds3b bԦHt/=w eMͳSޝKy E'6%h<>NH=8}_`jδfI$)?w?Ӈ7Xx#䆙(m΃FʧBTg\S:#??reum"$L;-daz vUĶ$OJYYa`_h"n-e>X MմI=7'%̈ ZAKU g\|#)+ "e\"J41$k 9w/Ey;Ƞ'%+7oAi 9}9sXK1#%Xkw(1F*Z ld7=]WRz(HZta=ئ$qn{B"V0=x\63ǑJMumVJSԇUdj(hbI :E d%@Md.c 2'vZQ8hc B57gDt^ ` g!>? O9ɿ .K $E;鳇iJٷ<,"juhH`P& jcLԤ̀jd)JS۸vmO2ovIv^k7?J^BIBpt:- gw$Up_q)'mg݂u&)frNFGPHΆ|Z&g @2=+̱LCh&02 L%lgS[ Sa21赺ׄdh4`4hQk4&4&__LM&tZ5Q?<ϭ͕ze0b2Ш5 F|uoT3q\6bDs{ќv6wtDQU$kKXp5ТIeҔ`h4a4q=t2w[)V cK}ҽ1{;ZX;,Sٝ+fV,OQdDQ0zg(V-g5͢ٺ+Ѣ7MCSa$qز~;.^Di/ipzU K00pUY&LcQH@t|#_{_~3hPFi+̺J˜zsGedTٓ*9*Ȅм!; $RR 3M3!j©Mi-_ 5{iЦqyAQp9-^S8LUZ£Rk8nk[;}^#x8: E xtaBR5gG-!{56ns6 N{zMC.qڊ~t>w:hk@ \ S@0ii @e Z463nE?)MPPoߙpBx\6-Mlٲ~` #)V۱؝|o^oPЪHJj:iԀBSf.@O\d233I GUcWd7v *Zhi\|E\EAEpd~emm # ٌ,I{ޡx];)@^)K䶷fFEތC2oB%a.같?vZZ0(^5%dn1rh_G .-(,\>S9gX1qX̴wt`uћϤEBvc exw՚7hhovhD&"Wݴ>@ӡ)vFHSWTtfRsN+@"=U45T*i Q$U7(Jg$ꡩE+,4Z\D&ĝRi"~ k}da~ǟJ/8Am!&T*Y{.O !T'#R#WN6\>Jm .5OC8]I:cz,Nj=6       5   5   5   5   5   5   BQ9DnЀZ_DNf$p8z{a?I( ,cXxOv$w|rA:سq=Vgoa;aq$c7ЄK'$<?ݑfqG: ElMيƐQI 7u~((Ύ]؜.L=`HN1^{sYn-۫)ˉI J 좶t7;PEf2zxx7vP#}uX^B1zx_]{[hjs` %4ȋNCK]%U" @- 8l_+qԗŬ6VO475as$@R@$ 9*ش9V3.%;.Ұ/-KHA3h?UwzHbhpvV5h,~Q ``#_A~KXI:' wPֶB=}^rn-[`i,מ?}I͠޶{-ui9{ TX47Ƨq%_vb^~L9sC=T49F/ wỼe҈ѬPS^bIsưHo- ;)Y[ȿ'./,~o9|ه<}m\{,.hNg[Mdi#4l>i.]Ɣg0sLf͚ŬY8ҿpWK#g$¼yCU,[y/p&3Su~c1޹=ז)1!1!$ DV1Az?lLX4ӧ8#61~'׏ů?Ǜڦe6oXEut|8< oSűso^u~_ gWM~';̧'Zf3Q Sk p YZ&%*BRN@ר\4Zzs ͱ8m6ESS } 47DIWL!QؽT׶U_@Ksn_-ekn筷<|$aXqyVG{ _OAl@xzBj,HmW !& 31pH౷e})}FiLS3YEֶqy5>ڟ^z&vsdGIys^_D(} j!t ʦp= |[ VUZEeU-KKhB;کi!I`m͏_|+S:yGKk+ ~A1 ^'u| acxzjK))׀iۗE3OFRu< Zǟf>??/opPTO/>PkbQ*- 98mdgT,y)t=sCPhv}˰~5&[m8r{ݎ,PiTY_q3pzsVxOXv59ybv>}# Ať^@cO{)?l,a5W00WitMX:SEH_~% փ&F!Ɠ|H>[nt9 ?xx㺁,6CcʥW"m/n$.:s 7pǝpH oy": VO} E%0R$wAbDpBhd; GſAO3$B4'_4g_q#V?~|MRm*L19Ě4S73Bߩڇ? v^U/F~M;?EQjta޳=l͒qlp#ԨU*T"M@\?!?5-C*(׃N2 jю-YVA0? Ӓؼc^ 2pC[^ [mŐ6F=ZY3Sۺ4{'EF_ ^޾py=^/ }[&T 2u{!$4R8q&ӳc(+zX")0P3 M"N[3*0۵b.]Drh6N _0Q$˕Eksō>-txaPvuP} f:y0 yLtP2}T$L~{.u]^CU !LȌ% *kMpw}H'3! _0FM;BccZ:ӊ,HKäKC p*2_;ZFK]Q~N |M]IحmX~pAT>I;#X)ص7@QTE6@BrEWpqaԠٺr M >doƾyV#k0܅,SD17Q`2i`|M1` Z;k˨`^=֜)475 P%ʡAn\Vr.Ǖ>s3w᩽!X> 3Df{G+ ׾,.edB1gd&5:)a*.yɫnĭnJh sk#V&`>jF xɻpU]،6-&ŤǦPʪ-hggcnohW+7q^۾'[K\PJEݴV7w\8! Ehoځ@Sp# s_z/4đs>|?,\MKSa;Q1m@4byc_dh`Z=Qv KѠ6wP7ZM]<#ne g3eœXԙسL=-n˽O?͜y<63!JNs/$ޤ^ןkCRUJIinåLJ=nښ?@^{#UL="2{K8IZE9lʫe?mmk!qLWڊ7dtX6q6\#{"TΝ?,c\ ; cf\ /pY.Scٰ24ts?N]5v@=jձ=шJٔbE-4V7o XV&AacH 󡾶1#au6V2IH$!@͞S/ϞJIBM4X3O8"":߰`D bQdHW7_4C!1Hw~. Y1 }gB FekNa%EZ,eg{9Oq[k`ŒI$ٶ~#ч1WAYё:d4qAu }}sT:GȘ’Amn*Ț9c>,'Qwۈ>3FeSyطGߋ:j L˔dYfhDÒȮ&(_ԣ(nj8f!$LzP]Z~ Aa8KؒRM9뮱Ci>(ሲWRG1 %/kboa -13IiDUƹ3G;v1Ͼv'!Z=@+>}ǎ7Zn[ZLL~q8 /AbXpq4g=_'2#Ol6#2}gp(.OK0Fp2={<  H/xiˮ}KJ!16Q'$$DԥGG!oob} ݊GsKvl6!!!vEEi&xn| <#$A_BG ‰!4n>*LRń>7y1L2TO /!1TA~=[A*U AAANk"AAANk"AAANk"AAANk"AAANk"AAANk"AAANk'l_׋(N$n7n˅(}J$I=q ¯zx<\.T*xj&ɉv_MGGjp$ Á%WHn?p{P~9Yq8T*р$pٌJ%4ӗ$I8NZ ? |z=h4'pJX,nzT?(ٌ,)( >4'2I8vl6 ?hBAA*)zY-E9  ᥮z/y= 5V_EQQ>ASB{c9-=|XiW_ggn*p{wAejv7݋[3粰g:lNEukaJ{8^!S[U+W;ݕ⥣Ғj:8nUBTqo&JYE5m6?pVv5=;WqSe˷WJiX]'(Eb(_V4C(b]Ղ <VX=4U\ ML.F^*NIZ:yaHN#6~jr+H8ʹ9([D]]P i}4/JFbZ1,L86vYκ|j-^|,f)N%UvQW^LieĴ,BMt})#+ `OAfs 5N*lc}N>NS4#Ǎ%5ҟ7kXy;M.@Eh|6Ç$q j|$=1AqqJrwhwie1nc"Ne,^W@p8Κ>0aQ%2Ĉۋ3'sVʋRЎ/Դ4~QOqa)~Id$bHp{<hG1s;<.RΟ={^dwoX?M0e ?/f{#G1ltfOOE IxޑCE6>^_~c"O{],nj.'gw"V'*/qԬ'k5Y˯L*P5_oy:4 ҵ"a=gM!5Έ^+vZċ>ͪ+sxϴgS])EͲc↿?C'Sݳמ'z'{ԉ:RXZjذMzյ|YdqTm]H>r֬idݔʡދ^~ǁuR[o>ʵ>Țݖs^s>}~"j>Xl{oc/^/ѾlU{w9^Z_{u<-39kB?K,̜ 7e߂yE Y ,t~D=NBqQX:tH: .ֿJ;(M`BҔ1,Y5۫Ec:N\R&El)kBN&aVċQ,#B:PGnBx'D~WM-M/JpWʜ.(P?6,b;ӘHо}U! ǧ&,:zV?A^.{ƘA;)G7)S.2scHd|u;ٻc_;c]`4a>,+^-ExC Fd\Ng kʕ왧MQz?n6lYֆ&<}0bx⁌/|UY{`b;L0 ?_s-}Ep=ꊷCt&~]l/0l@89.K,*]حWlv+vlw893?v^=13gv>i<ޓCQ8]Z:Z(z3^2 ;PhICc3vŅvjzOZ3i(v1~B Ix\2IIݓ54@D ƞ6#'pUiRlrf-x8k9oX F7?s=S 2.9(;go;}a1g{%* mM5TUUQU]Kkh:}/}w[e3wNQ5T7`wZiq$/\v"J? FDbI;/F{z/of_A6>BN-xӼ4kwPLuUUUU4vo\ļw'`YFH ͈آasvR/Iӈ[p_}y:O_ן%o>s# GG_/q7wm|"-u],]Slmja{s ZKYt-ΐ( j9m47b?1HIpPo7&HOZLpx)G{ow* ~;3@y _HG_`썧N6:UMS1y],c-jd4UF$<glwfsn!g}Mzh>{S E>+pJތ^|f`q>C8O_g9qΠPcsf͡Ut rkJh~/þ;G^ #ͧ:ÈDkx?~G|F3w𩹇'4:z9Ȧ9wz ر\Ap7[%ʲIʲ΄ԙƝy\:$_AekItB=1Ceso.qm/0ƮIz|Ʈ70d`<6mǡKMOygeh(Y%[}%! ղm$[%D$!r%ĸ=Cq:hoTƋ,*qڈK0{uý":RAzSaH1ƳV%y^Ho T{8=_^̦)__[TG+&|MhDPx/+=s9߅&xb$7i4$hʚ]w;=|I?`yLd 8`)Zż~K!'m{zAbZ7錥w.wY36Sxs׃7MvTʼnBCBS%44H.01RX=~^OkG͵Wu/{A8uKTt2ˎU$ez $::p|=\U>gryd=>DCTd,Mcco.cBXtֳp&sd}j}q՘$QXlڶC:: OjnADGGM'7@sn6lup]w3 {YD ؐY @keX%[gV&n?n.)$$!qx5DP]vM c4vdIut#nDbxwO" 6U7740>^j*C'(]"q7A}w氰n׬nw\I "f!'('zθ7Cj&fl!>,7[s%I{I2 '9*>CGn6la L(e iN5u{)uU=M-K6cHH@ZwCLungΚ,К_i.g\?dGMEt<|1vD*J9?nlX-s{1: ?BWԌ[ZU 7)=fB`` zхb-vtzƄi:*ydTc Wr$J} ;w@CwwQvb{3O,n: kK5Ŵ)& AR+}խx/5ZEDioot'chom] |t9YgvDtx Ɓ=U;uSd% <Bnp6LlT  J0dx7kFbĨQTu/sT2qCe9gkkkCUU||_pv6SVR¾k9ʫglZ6H~:N ipb&.6eK(uwRgBI44MigjCw8* OKh. wSY$_pMi elj1?촷wT%nOHDutP/'@G 7@W$A舊Oo}hW|=Bro "H<$~G=շE8$06&}MAR!|I'M    WAAAK   &_AAA/M   _|AAA4   i"AA? IN%_Dn܌N;տQl6. MNSVUUQT_ ))Bgg'FT_с,ˢ.-vpΠ0" ]-"2nnn"N:IPM3(!EQZL&fHG e0D]Z?AU~zNJ.t:qss;՗"M\.TUϠ \.a6OqmmmW[?D46;Nķ ˎD _Dt‰8mŹ !QѺ'x6mVê?䥷&zj/FsPc?"?+ZnTdq{? QX"‰]Du/EQò4u !kX[jGek2W)}{H%?N:[}=NkX3o.+66hM%j\} vIh+3fowQs33ILOO!tR܌lj #950_ c|ޅ@LFc,i*&!.J!8`sUurH^GP\.UC" PJSE>{ظ$a#v7 N M G1{[-y4ԟޱA.5 ÆCɄ^S:PՃ=)$uFӺ7NoPTu2A1Qx nGAlD>F>i*&;V">Qz>r)h?~* .EE鏑'7m]ʬ{I{$Ӝlw3`M\8"E-uT Ǭ>A ZZ΢Vrͷ2|`08,ֱ5TzCDQSUAZR"y4#~b 69_ɕD}iu|{LAΈ:f\ςȩ̕a>$OWTfG_T*3ޗ\}a+ӪܟA$@uPH$x!45YfqcO`g_R=j.tTl$k,6;zH KڶWa- H_>1GXsRɪKX93KH v?,Ry\FS}ۄM͛7?v .rW /ǧ_zsⲾG!=[Xh - | 7]4CbdUS_ 3x.R{>1ērkmg50ADGÀs~c{ ;}/{~{  H<g1FTdiC윳I ^ea &߿ꝼ̫/8OLwPafh 2s SJGKWQLpnf,؆3;Zj(ot>Jj4?7`?3Jk pi2$f6&-4}vb·<+!iuV1HQ}I3'&sB9%C|l#b?HڈqʲEpTe6勫 ٗAԛhvjji:Fu947P[H:44TU&ZmLғZv]xyޕ5ؓБ}N+-56cw<3Ow G\t`l <&A$ݓkk`7HB@s&+30{uCǤe IK-bɦ,lvY1(l$O5{Ǔm^Ċ=LLBzn#@eql%ۈ46-۷ޟPf{n9pkر+?zOhbopKh-b4znmp6bkdǶtxVfm@כa؛Kٰa;7+/0w[Yl_ 惏agI k%ޕIQy){ݹxl^J3㏬ݶՂ+6j褡p'_(O{N@:{~{a+ݬZ?.Fu,7,͙9$?cdli@,H(4VRn{o gZ=(#"m/.1Z4ѩ1*.WV40 (.l ֞|`W[p掛JWk#.݁҉Eq{rH_ p-͘Qv)މɘ'GkoRdGNIg&0؛ZtMA4+qCY7FM=$YR_mAzF<ًo#E5ĥtqjm ҰTکlꮽh*T62ap8-X:NM{Nr3so^!=~FcȲg1a~D m\gaaR})+=7m-@q4s6T<|>r E--4T7RtWRLN/xwȮWQPN矏Dzr+fy]7`( :ձ̨}jhju9X99xkHXd>LVbA:I{{%41.|]r8&N:)Sjl5`w4РVSBEI{w :KKp=1^6:~[/j+_,,ay7q;D)͙pfe~߽#JaGeչHO>l>[vo0A: WlOk+ewQLeeFaHǥPM{hjm @[P3zNi`ސðS蛦q* inȠ(<6)396j읨qx䱚}XNC8Py>7+?群U*@fv;XKw5ŮM[>|=-MkcFFPH(>f}[)LJ݂ƃԳk1,fM;Mj[hC@TE"7SGl8:;2vzIh^?6♳pF3$)7_BBl]{[]0~\~"=49q4d,fΜɯWQۮd$~Yt*3-JJ\=I=𪫭mKƀ?JrB yMxfdLvn@0&\\ʎؾ{koB ¨fr |sJꟙ9s&3g/&‚17w?#|Xh-ٻ79ύGZm!24cwj%^)xvcoM9zFtn | ovu_LN,4Bi)q{蒩 l{e5^03g˯(k饢#hBoyuXRGSB4̫fvmZOGh_FQR{^?u|A|jhvl[G5~ÓwNElع kwOzY0:#>Z8v/X>>qcpVckJ߁i-*{(WMIO'MXM~hqz$p5;IM C%(2g'o#ok~+@O`xR؁!չ(C;]%0wWƨ\yZuX l'gG6$u޲jeϾSNgݲ x803"o6TThm5ۘ$IA)|u7l_ WE A)Z HE}|o< GؚiPPVZ?sU,ϪEl"?w/9 OPSy\2"94:9j#w^nhsYX|+w=rwR\{'ϼ~q}]LQ&(ξj6T ,Dq:46]F&Y(6FUQ.99d+ȄMw?=OejڒӒ6,[84 kغ%3~`dy>B]tN_i.ɣT W)YV49T-$w2k1Bq^.9aw!^͐qpAn΢Ц<}Y¢H "v Ͻ}wO9|LJ,Σ/N64}anxй2y9-5{9v;5OIƍޣ,ud`nW~+"/ʝ& ~>w;|2S!R/_޸+VZz#5ckv9oNhTVm {{-lns@B5qshmlϋN#[Gg])63MMFֆ=9팺(`4r#ح̽Č}{- '$5P^?9/@icbM Pi3\鄘;;W쉧3"Vd&κޚ]h^{.k}qAϱeg#D+mVbQ}"Rjf8OÈ[=6yj(zrIr^U8;Аp6ew6_s%gaiC2{n<ٛX *æec9ܰf}4yo ZMƏTEx >,”`2$Q)lwQcmCt8طs7n3WӊŪ偾`ZvncQRpqXֻLt^P7{H ɡb?8{^pP3mШG?)qtECq"ŭPػk/%MU HmwEEB,ˍ~?/~&YP nxQtqlU.K)?|+ޣo3{xeQ֫zy ,(ةZw371ꇸ~8)ܷ y4t8-dsI)ZSh2v줸N(ݱrW't`1wY6Bu;Z__l&UEQ\N+{wv[1ZiJyEedlˤÎ8;())(?}t: db/b_aNxZԾLd!W0nFhV6.Oi\=uz:ٶn%nCcBPh,d[gFJ[n+pstx r9,KVj,b놵,GVm/j܊{VO!1%_Pu\Tvoho(oaM4y-2cO$ \4gS9u&.<"sW{>gg˒L|(&uOE˅_}pk+×9;8Wsc,~1ry"2ΜI7d@UWm#@Rý\ICe[6o3F"䅞=?=}P`{¸_NFKK @MSqT I wM.'NUh#I).. ɀrpl9-ݕ#Hz,.vc2 S.U`!ahӮ 8hhOO:vl\OV^ۛC\. b6@ *8v.Ia40{S[[K@@QuiESA;T¨Xۛ+غqjl$'`æwJWĥt& }rT$cMr" d G{ Y1ph0TO^y;Ix?NjI@@oޏUe=4<<?ߣ:'=+ h6k+,_ᏠG0KE+L"rR_ׂoގ '+)Ia?LX ‰aZa (8T_ğ*   WAAAK   &_AAA/M   _|AAA4   i"A4 MNe Az'z=VIN?\.T_7ى',4˅prNaىdygPU焥$IN? IeEQNSiL&4MH8zxքMt'N+9)H#|* ekQ9:M? 1Q5ͭAp4 ^^n=C$$AuAwbQ7t$i~iHJ~N&*qxOB$pu6y5vbsX Jj,= ¬%SVZJ}0c"uӟ$JB7VSy2řX RIҰXЙ=p7U@ eۭݭ Hjcۢ,UHeC; fff21W-Pq&=7^kW$e[bDz"ͅ?IKN>$IXJa=^ֿaG7{ØK+vd,ak*cO_3oS91aĆxuGp+{ u:Ғs7uł$~i!eXؽf1[d\tGTml_%U^ze$ꉕ$ {k9  QeQ4Gh662f0%|a=+OR>bcCӲo٭tߝ;JBdxGtFNˮ漱Cp:9C%ZK[.NY>WKB%<,1#򺛸rR6~F֕~%IVʬ_uIŻ޽چ&hjjh{  Ìv0!=y= .FƦi#d\q#,.{kΥOL _Tϗ7l4#FOk.aH5yg#WGUhƳw-$W`Ii)'zJ_} W_=y;-7?^sݍs).zOf:,P[÷\MW_Ng%Z_ Oރ9wl4Y_ڪST&}|ZlAlbϺܣs|RbذI\q6J֦|SL{I>Yfv0dM,]" ),oC2ׁ9Y5?8[#t$|9l$5PbqfQB'xwQ&[cB߿;ʑN(i8;OTIvv6eAq o{) ]Bq gc&Pɲm%1}18,TҦy73Փ>uMdɡ &ˈB]e Uv"$ ߘ ua!+cM3t`"|Lh\J8ĥ OR8&-ٙI~E NѤ(HJkeyrs1ǹPu 6c~^_P^!u=KKJKmDi $<}ݺeIkt Iz$́bNg$ :dJmSD"^/W>ډPPIh)ȿ?pzj^*"l(/ hʑHq:0 frTݱ$AO6`tbϪɯ"IҰ6S]܎իX xyaйh(jZa_!I;Ţ_R@6#\zx1''(Uy9IDz~Ig$~8&Im0.4;w"f,جCrGS]TdRP$'o >a8U|Xu₋&2sI4*ۘ}9%T$t::w/~s;ㅢ(GME cȰp #^r~Auz_f*Jh͎n&9y:+Qk]oʒ⭿k_K? GSyCνn{GE{OfIY@/'LKn?3/Kh)GJਲ਼o.i0X/i G1DUbw.js>"-GphƞIRHؐ yCC ._h'_? ,rf_,+3Κ9eQ喧^Kch+a/ћNKh#ÒN`/sSNǺK3. .'-c)ܔA^TC@> X44MCUtD#JңFldcYG]O~@̸:**$~HJ +\5@uu ~xK 9 Io&6a0n_|Ç3|N &pٶu/Hu|CVmŝ|ˇƢưid,͓;'6q^'y[fmIUn:kpi?qÆ2c!zA OOY?W^O* FZ EwR\ fZ,6jڭHc"Nhc-yϰOTU7 L&^7H!'3,qE)G|XB>桓#b0 L̟_D=םKr'&˧YSn{.'FUO__F]N:N "<^~iFYY݇& ̾xȒDGU&72|AGs?.Ľ'F%\|qn 2+a΂ Q 1k?&C +lfwˈ64r-ÆiH=o/挣-Kfﱡ؅TNim ڇ{_xE{L>rO/7$"G\/?Π ˋxnY;#T0p=Y}A~:/Ic:>;֌7^H$IRϒY__Pb7\QDM@ٟϋJ=4IO߉7ʆ_eYXy`>ɩkGoN`n3(fyIxc&%-N*sOp9Tfw&\|/zzly|ǬjAǩ|$ZJ|{)R8B#h4NŀX-7w q0QnD%DaH>WyE``$i˛~ф,YoCC{0y9_s1AToW̒B~|aW]u%_q ] K2L6&̫PhC(>yg?:;p#v!^myGxNmVwePRgy^\4,= >|6|מ 5RS .4z OJI6;npv^zQ^fm$cߦ&.R4ՉՎgьx%cy/`6 N%͌5E$[Fav&º1t< s5;[~y>esϫٰv)\6~wəwaq@抯x×yf=n gϐHOT'<|q̀zG!׏SW5N$ Nd,p;5 _N?7!ҙrh|EȫnUNł32v/xTA}tF  Eĺղnw x7Co sϲj oeJdw s#ogLn>w~vZm޾8*w+ϰp-?pz3 b{חDlYzt\"% Wp,CɃqkf˶ٽ~ 7C;,y@X-Bf݋495<+ibi%K81C#2{&VԣhZZQx0܏YBB}|{ r߿3-q/ LYNjI|%I>iK }{/oa@':j ޑHrFV:v՝-<l7ղӅ҉tad)|"ޙ>Go</ ![Y`<#3yEKUp8 YAY>Ts8 ',$>}?'y Dx4ֶpX *H:J}Y W$w{Ox__D~F|.<$:4}]z?̣<'.laǒeOp@g&W0!D'&2K{]iKNEed}S99VBzL[U6k:~t6`ssg(}pw3DPR0S&]Yî “IOOC'!6-%gIP,J3rn,zbZܲ:Z*#W*F "QQ1x+bP?!IUdK?׎OM#4^wŒ׏oWT$YGWɫu~u-h:۹O HZL<ݣ4`kkI??/FwbSg2S끧*8e|<0y+ Qϼ_\|Üb ]J&#Q${!aJbg{5 |V.i.\fA8R ɬ#<OcWWj BI"k1Kϕi`&O(1zErqɡ|n. w?k'PFPhŨᗐBRZZrmrzsCh] -vu-F4UҐe3>nr0!4;͵mxIXtx?y~{`\?Gр*F-szrp:GvJl!gYZUN{o."} bR)( a4ƅʞ3{[#];)oi&pp8ŐDψ#>b$aٳE Ï+3tG Ⱦ݅Ȟnd\8A<9_+Jxw N'QG4ewRAA~^oe[}w dcmFAޭR2$}JE",~S/KU$IvP W?HԒTCty6bM4w8 %Ws˳\r۸.#i JOϭk3 c&37[es~ O'LeDظ* ^ 4p_$ 4GY;ٹ{(w\b֭DI]'~ 21(ѫ 'Fse.;3sݵ9VλnIw쿁$w51Gy]\ҧpQ*e̙l~1z+ ؾ#6BH8ҙ$Kd}ޗ C~6ҋC9r:jsY| đ9$N2)CIAҺ*[UYdΥ]#<>Ai<;%Iji~N~f9yy۴ȳyI$Ezxٲ-z<Ψ#Iq1g^Ez"W;u 8+f%kvIID(*Ul߶N|Cc7p ~4!aǓfk%Nvf)ҟpԲez1"- \.р)@BVtK!IEg]$T+{wurK@FL`FJBa{X,<==H^T+YٛǶ-+SMwL0,IsQ;-ơ҇cN#y?9/gc-3a(cvfsO-.#1}Я~nz%X[Ƥ|lv1bP/Fj!\pE @4МTaGf5maq Џvp8ȲL@@oގUe=4<njGI |صOzijwO%aQt2^UK,uVf*H2:]#ue<]I2:}\ $ug> [!'XVPuaځ%d@*(|QƁuwYC$;wO'$2Y^^Do-n.i.*K($$6@Ott'cﺎD]W鬳܂b h(Cr\ J|< 2$uҎe<{!_?#2I%c|vjaD.E=u躟E<*e]K>e2[FFPGYwb A}v%d]&,{hzDPr}uifʪ<  co E,."# U$YN#ª5\~,% v.`Ik2KD=n>3沷SYVJMc:7oB# FwİG) PQ6ʋ+,7"cۤ;F}k<d'q+MCqP(: (CTp>qϫarr,鐡N\tJ㻎|+==ݟ{e]A8; 8zk^ĂhB]I;3I:L3hv/<#0:`apt>uU[E,\'iH8dt z>s:,J^g"酇}зHՎn*'; Y78kzw?{to33&͐sxtBSU\bQߠ*Ns&71ILu7wGϵ1 Dh\ }RQuS󟑦Xint^CCs'& H;,!C|d=e;n?;8LiPnTc ? wMߘoKUTň!Iky VNOw@5 dq 2j/ d?i O R"b=AҎ)¿G |+=wAAAB uAAAD+   WAAAK;as|5M = B7IGNC= F DNQoN3~_UU1 A;$ ˅if4pIϠ \.c0NqɄN-\$*N:~ HnraZE!t(2].ש/nA_: Ii,K8dY $I=I0g/oؓ1Jo3Y$Y?) 'ߴG q=ItǏUŅKQd'VЛq7':UMCuu:;k?*$YFshim恏7F'$D,i vnfM TN Nƿ1 Y UepI$߃ֆC2n#Q~PZIHپ% Y$ UU4t&QP޻EW1u#q)G@2Fw ͻ 9*GxD4 I gah)ÒEkhmb_6ξ[/H;4wt?'IFe$}&$!'tUz5x IݻihG׹3:Α=:u-ǻ.IDJ8$Yp^y@SzLKG2iji\K2Ri@$I(Njkq| G/$~Ti1ʚiPW{K$dm_0 G#|54U;,>r%#σz;Ԏ_>=ӚƩQO|+IH.MM1gXE5+]Iz½m `hJ(nfHYhf/3֗ċ:n V˪_~Kl%`N<+ų"lay}V,%IָO_x-3yk3eL|:ކwfILVo熛&D+H-kY|> қg&) 4zp4KCMV!ᡘlmdJL3uT<:qgc;nS`F'.4 ,6oC]BHb:#!Mו.% JEY6 &¢ ^@P_-;(` !up;5k-G.271J@Q7e+ֲ}5tS‘<P}1K2{8<IH]lKMGt@F J(U28mVՠ"]Y߰rL|ߡ4v5;,ͦճM$73]-Y|dM@hŸ ؋Ā#|He5W} Vn#v'N T_g iNv|ZVҰw FszXt2(fr3co9FFLhj`즪7HA0LrWd߮dVcDx|oOMGUؼ}M}#2b8a>b$IsQ_QNMS;:|" uv^'e "iH{qq;_|6n:$\s#'{9nx'IരkwU-ߜç#W:C.A{> UXoq4N ʵ7υYˇQw09dՠJ2bps~i˟S;|Jlao+o4#'Ha=W~yiFfv,䩻fgG _=<|l x)L2)Sirx" {w3#Cj?͌k2v-^"cd{sq2|8}Y3!Q$KmORhqcoP*GQ;ɫ_]aԑno=s?]$Kۑ$ISw#3YsG/qM7hqJG!{6*럫ko sp"!K-;y 5W^Ƞ0+n|*[f[~=ϥ=+yy}uW]<>?IR);Z͞ 3vVȡө:سW#Fzjm*:YdlV52islw=ɝON#(xz{pݍ/DRg/?ʛHҷޗVbA%tm%LvL9L˯-AGFd`3I 0r) Ȳ< Ypݎӥ9c=O:|u=u&2N離*FDnLIP)پNٳyuģ\06_ģ&6 Ȫf]GjpB#65?qO6$]+PӮ+~b՞f{'5CPAFV9_hq>n"scGIc[>/lHȲJmA!_=='Aw )dణt ;GC뚓sr6fau ̈́$ baDH]O?.Zܑ:?[a*9ڱ՛4`~|$[C vqI1% uI*vT#1ٶj%[sG:mp޴߇+X;g# 2krp̙9}@X]N?xL_ϗ>%W Ŏ}'Ӯ>eR`Ar`e3(Ur',_.*ANT|IBq97ۯhLEy*xTM+4[Ϗ wJXvvC)11ˋ8bؤcN3k ffiJ yNIGg!.m ~al Gk-'sF> 'Cpu7dz>ބ?r7ΜB1L쟀N GS>+m'0:ߍehbUkNUadOй1:[ }z)(u=v]^%((V{x%-(!ddݍȞ! H b=ߐϘk45Srrs0xjh2v<߱Îu"΍":>NF땨j~~Eps$ EQE*[$и^ȒLG/>~~OO$aW_fE}~gUA/*UuMrv(Ȟ7q$?}R|PT"6Y'_@( [j`{E{ H>!hٷʚ &G`x"l)ːlͬ߼@t"19)tR=NW]K0_$MAqPNA{w $pWͷʘ8÷MI;Ϲ'gr|S/>xB ܵl70oKdlQ\TWUmbo#t zw$Bi:YA8y4++zWDL{{&kee$dkiƄ!II::|X^t(JԮ ufN4ؿj=nF@{1q9~[J[-]wA\wuIgu[nfSێ,)m_^K N{IYF'ˢ.Oi1xg8+9 ౻_v`G~ tt?ےގuW4F7=lf+Ž(l^W(]wa2=>ԵXb)bO?EyN (3>ѻnWME IdIh'4de,^aW{-ڡ_E7sKiqiŸIx o"`L{}v9)ڹg/d}l_5Ͽ1k:ѐI7]È@srfZJQx8k/2wS@}I!zS"CSpvK3`0`HFo&\yMCݼ^ɶV ?kmz/@blر~I~ ɓ8>3/q2&)r?Jo1AkCm"^>UGLxo,~f9> ?;r>Mld1=LڌOi+*9e^,yUD h7Nyx/oLgC)Eiyg-1(;J:w&z:{`u)l7BUٵq O(R tO 6g:uAYC4+ckogmt=R4u#1\eYwoZ318K>#K+qs' j5ABeV{V.Z[Ij2e_,Masb F>ۈ?*~x#lz˯qu+PntdϮ}9|~WxPgQ.uhƀY;ILZFcc*u2fbN)MRIA0x|WBvE~KӃ;x=sl`05J 1ڎIk>ၟ >?UQR1@,M>Io**]qŰU 鋔|j Ek'4_V!nupyg;7̽_s/]#cr|Y*d<̳L+z}Ī랻VSLoVq7u*h̍HoG맿*6ŶBv|O|͑ͪRV~`':x'?7/s?Ͽ]q/gfBRrz :ZTy^~t7ͯ˗r//7t}ƓH}f*AC<,[pyV1u65??bO؎W9 ˟/?ptO? _f:>֫q[݃mqz*c׸ڷqf3>!΁ }¹4M@iLαΤM?)z77CO2R2{'Fgh4!K6_c]e~ ~zUl,5A>I* Wُ̏_ Hwa&3oNW=8oϿ-7`;Q=͡8:'Iq?F13Zy+o{{=Vik[׮'umR|1uV`^z/;8>NW$+WoVa8-?4XU]Y7Κ-K7ؿovPi{g9#ݗ`XhG7۶g凸~|5kپud *)rO~kI81͋??sG cq;]G[6M6#ўx <p[ﺛ-kWa;سer_y\kIX_G _sߓşw[>ノ 3Hor3[%޹/<ώc3lg}=2,\\ݏ=OUV hw]R0dc<#< W]6~Wbe.E2#ˑ˵wΰƧɧX rc?!mk֮'Q:̋/b{lSܰ2"dN|G0g%F/'wͷ￟|!&'޻p]ƍL?OKuUע#ޱ+r =ع?M]d˜T!-Cȉ)TXѯoi.ǟoMއY_Ú8{^vΗOyxg{n!JQO@ouְ+Ȯgya~f?'G>@ΩOs֧?آ fkx3i;}</ff_K-Axf:UY\(8IMmYg_TBYQarb|7TŴ2cTCTZa2t;]u,aiPXK[|Rċ_現7?f}ʢ05Kf 8FxdHc4I&1=9l +L":89)|)P f1DS pj *J[Gajl*^.PTϾ}noMYyJ}aH"8( Lz?!~M]X L2/QB]ҙvzz;k ;, y:Ix}­+"AƦD]vY9RVNXp^uVzfn+qYnIuҕK`)E(3>2L9 mk-:l_A~| 'j1x<.xU(N39}g7sԢsJY6g?mn_c<x x3wAB_3<%_. $S*N 3L q]7lt8}y:Vvj^n}Ue AjH6\SۿU]i,sb #nOc+2>3#Nҝ v{_:8+Vglz6d8s,Ϻ+1aH8G| ͜ |R ^j==5>oHa tgJY42h hGHn^rN> ?ۿd>-8sͩXNY(32Z4ҭ2B9~Q_I*r"OeGif; F052bZiFk5=cx篼OaZ׸5w-ꓮ%b~f9e9xӜ| NkV0SXBѺuO3ZkkEVxkkQ,,c,$8c4~Jx(V|t~.8,,;PȆ|+C mF<lnfBP uYm.>ZBAQe:Zr*^яA,W{c4 Z|4VZr?h91g1_2K|O^gjr 6+{;mIZKgB,oMuF 9kX\Y2w>K-n {j>S7ڜ~yz'2lY*<[8hGHj޿VVKw)Ja;>s7OǝX?gILXwʧ @8WJYx|KN8 / q.фOQY6DO[4l. ,ZpR;Gm1li/p ws^!B!Wc^}WhB!B:": !B!X$B!BI+B!bYW!B!IJ&B!BeM_!B!+H٫NY!xdfB!W |ϳkx _&<Bq)޷&J.IB!. |Czw#a-B!.+pfkx&/olR'I!($=mm(zB\e`RF!8$ ̫@[?[1iB&eبW߷̝*inn{UkW%|B\aO₿1W-fp/`DdY.RP6l+ :m'J-\J/s>$"` ̫ϙlJ)&g gv e<ؚR kg:_~3r !W)hT uBT:CY~sb }³Rv5_X3`} B5DCkn_9V^6wi^~ulGq W쫘ӞWۻmޞ _5BZB!0)U&/^5oo14r؀3|}|ju}`4N d;s96kG'' Ԃ,-u?/6̢8Cn:jrҲu+ *mg 7Vi6дj[iBhι}] 08[㓎ߢVc nQ-ޥɟ/5@m)n,71J-y-Z΂sb1̓?F}0,ggZ>ñe! _VZʦUffhq WhK!e5M *:04LC~2RT9惱*(D2ro?ca}. 7x a]͇z-f OMDc[,8V凚ތ{zmzlCjV5[:lO+tk{Xxv: jizC{z:w[xuvk Ѩŧ7xl5O8Q;rpp:`17mI|]׸OND6 1Ls is[-20`+g-:Us{~iwXB [:m>e1xz*$TlB&jU6hB[qϚwd 5&+GIDAT40QxypEӕU9e(.Yaֵ;|fCX xa (xJYHd~o˵QM+\~c=yuzbX~vU9_M%4\~Έ➵._L\ *X!'-0C`͗C SUM_mXq;XЄ( FCNLv;jSy'C vW ɐlI;jNl+s4`uW}s+NC?bBCHγUM-͚[z6 <QjD7T,s8pƳyAst6@Ik!!ijhYS a]M! jLP-ź6yӆJ؊BMMȑ*? k"/~wy MqkAM@eC68FVaxaAŪ]}U }%ygxx'*޻£ !Qe`m|f5>s7c 6tAʍr_NJlP'}z qp=lDzQn=4mit\#;2Dۛ޲Uk7ymT.d) űIz'Fwv @~<͚ͧez2Z5Zq Ke QL{۬ hhOZt+4d6cP?s$kaisMA3 hź! $뢊uMVV׹Z=uaնj I^e8|\d{6o[z^E7k")4G5_kڐrFaj}Nj%ɉ_]$|vc{ArcZ {P аcglUEQCeh."*V kx9!>j}aT3ԳnF5mCR kxbhRlKYfAlMh o))] ip__'-;X籼.TF!>RUK[DQ 4=֠}B!82u&4/y?oOilr`㺚_' MRR.myhZ]hO6c &݇(5t~4k;^9MkpD#l͏dOG@kA_W Us>0eϽm^82͇2 f-c4tlN?B3>#;=!y@=V U|?M{f [νӦj5Ph=x64oyo_nNf-|b}"e7C38u 5(wxs]ϴ>1]:͹M9Zۯz.pؘSĬip0h_ Nw-KwE~) o*(֨'sBqxB{gQe)'btz&ƏDvǎkԛB.QSkz|J̍#S@20&Ӟ2x AxJkeh*ŚEmN{!/Á&5/O5v@w&86k (<mm޽cS ;X9Hޔ&i6GEa~۟qjܪVP9S9m+"ܚVmC6:+LՁ"jEASm֚τxKMjլɞw0X6 ^t75wm@٘ŀcxj`5#U:Sֺou+t%"ǏTC |Kq^CC6H-pV'Zض"a]iB!`0XSܹ&IE6[}6`kS! \i_WP{&du;;lR!"iC_)<:0Qj}U̇f0XM6)c,ngi(ֱk'>C?[r ې`]L1SlJ=Zoթڊ2>.K͞ Q -zp6 !W{:;˦p~0)9g'v?M$t@gH =y=U9,#O?hFifc0\Xi+=)ї~O؁ݱumlHᦔbPГvxkvL@"WV{*޸EB,icL)EoT|!n2a&e3SLCysC <7Tklc{asJ1] )ttvWћtbq\ZmDy)ɥ]:m)m BW 7K98Zԕ"Y@3^ `KKm]ۺ=Ui0⺮v9#MчdM6EȌfnz=e)mc!=+\b(6ɀ,.# inr: i eۯlB!m??8ϙ<׹.59v05Hx2U+Ĝf-RZ#0U5 tZ#C8ήw3GXvmL14=@WmFzS͚_{9x| 'MLGQj1=dzWe͊bǏX՛љ{;Y)8Vg]6-p`goEZ\iYY,gmm8<3*pis`L@M>=f!j&ʬ攢X9Z59j9`W!ĸ6u8d-)-Ԕbua]҆Psl6`Uc;7&."*t#;|k"@]^sꌙJȾbH(6+!4ɹlL5]S>Gj۶XqX~ȡـ#5CGak ]Rljx qʰeELQ (7d( )H9lLxF>T6g!Ś_t$l"Zs20XŖ6\ CG¢\ 9R1d%,†fO޶KΌÖO58fl~c{;`)EQ]e.l;1bK[}Yۙl;;0U 9ErRsGevID)`_YρR8O8plgY6;-u:g3h l1Y SQϷE7QexyΔQ&'-le}ِɠ暎u3t99yR7΄͖MLXy]f[C}(R;7vK"!|\6s)E),Z״.^eYEMz˰-ٷR=lR6k5?zOZnU*^d.?:Nq.04U4T`46kmBs35֦9@@; |Oϥ\~dSu^xc[5F |J: ܰ͠xU=kv-H?/[<;>};H+b |_Өó} 3.# E_m,r>eν9kr_>sg w>O6,쓾wKÖ( `9ɔj i`[ߙ[R4qQe[B' ~fw}{NMu-ކӥ}u`璦uMhܾ2j>Zq`1\E[KSj g>sN{K'mϽT4=<~bi={Uեe-49C!.{2B+k |Ỉr-S,Hl L&)x`̧Q9iZspN90,-6v*ãea u6|7q 4kbU]f3k#1֚ew!^<!|3˻@#c\p}G9>[^\y1iY( e ,RDٔrճY>BϽ/幵cEG{J3YyH2X!.e|B!NGlnڡ\0^c{ K]|_%Yޢqx|c_}{rX!;ub8! "d+N*eKJ; &̷W5g\3B!0G0dW!KxV!XLDl~mkBaE孫s`Z!W |#˲xNnOgI!,eFm)!r]5>?!(`=4VkDc1bk^,xBy͹ A,jYe TMw_\_fygjr03} jLMf&^+OU LLW\)yN9չQReۤڄTul/zރ JAP-199MVarr& . υ<]kSߋH)EA6K)l>As 3EB@Evsv([Q-@/Ì^AX/3|0)2qAj `Y`ӬUAU{CvɴuqAf !0^$bbH*u=& 5/\.{jkB .qG$ DZl1V`~ ֿp%~K UC+k zA\΂ =/ƹ?7,D~ Ӱp9{LL!m9<Ųm Jm,D+ u\X,NsA5;ٽ8Yߛcu}xf-8vRdj>?o8`%lnI99mszNޖi^jeh+׶Q ~u>s@||4 } j"ւs{މu-_ҽ<i8u:m;^8<>\hc^ŀX qٙ+^@^`J)b*C##4 "v::mK  w7g+(FtST C2>BZ`$rFHR'B2[0>rZ#!L6kZTaTRK3ܻ68SHZCyVڤ)_Th"I"rRE3Pdz>cb$Z>uVL:~nCBœgPKI5ӤSITA@^T*Hĉbb>J)l J Sjh"Qn> *߷c qMHal]at$]_c|lJa:3=:Hfx+QnhtPcrd|#43dJqzGP dFicGG+ˊ̎6elN: +=tƱ{̇$ 6ˑ)F*IPdCL!И>1vr ԙۖc#LCAMqlC!? șoZBHgGic{GޠQNzJK=80,Fin2(}85tt6Ecvyl[Q"IEl F&h^ahd 'îLwjiNe*ٳ##(Os`^@kJ;zO2&BF3<[<"c7 T=vgaI'R 0vN!QڴfK0 jض=aC)5z|vgg>jX,e-'(EPxd[7]8L2{\ُ(0>\LQqرYߣ+𡽌T:҄iƦh ,cXTԢ85dFSO24:6f9rt}L:BfFFtl&b!A G&nL*~)*2Ǐ08U!AT8z`7{M Ό0n]gl|FhÃLez {fǎ34Q!;>D]}iǏ1^Ξ6?CMVu]$?bQ4 | n֨ժ(]c Fx<޺N_=W} p }&G)Ez"f$ɖ=xLMfFVvep=ׂ04(2DOIIEoOmuGYř:Tetw4M 3M4%Vtfg#Qjnoӆ1Nf6Q(plmoٴuW>gBsR4v{qnD\%vѽ~E|V%l1)ep-@PP LQX; W)ERuBLę}"9#JY <5ѡI,G *uFqbZPacGN:*5İ2;Śu5k) *~k/|*~lGHA^uC[M[6;c]1bͥQP c94\0A<ףQ_ yUXFm),'J׊8vs/ 2SҗKڳ=4`y1ϣJdj4$/0:^$0?<ӔPJ[4ŏ!OD rnR-}cc!Akp\`ZX=b}V@Y}3Ε!=K ۶n3&h[apA8p~G  UttPW Q8 k5l5}yXdUۉ~FÀM5mt,f f IR &Hdh069xUj+.4*|FzHEUuaYi+keb1|Db4 +,Iը-Р$ivL2OR#t=_'hTj>( 2fj?bÁطelX4abAYP|z sd{,F*ٌYDZmnbL\ku4돁a޶ \ǡ&A=h=`?nXYohj6K̂4BE-H:a+~çVg= < N%P+1028JrU22^ Ow6 40Pj!Al&>;6H#HepS u1a:bXFFZm+kO~Lkc/t,8RYX4WcLpT]ըj$LhM>Zz. OXF(k tH$&⸴$"YxUYvfݖ>\7n9|t%Q?$Nmlj-ٚ :=&,tL'0>YmHL)g*F4t71fisٗ(Jo]ٵk7=x5Aߨj4dKV~4RhD{/yGH"&G&PNz&$}^Q{q38q%?Rh~Tᯌ|D"d\.KG{;t ,J)R)e{x0'_,Q*Wp\Mm*\l EcQq=lJ2r"{M&c*ZݙkMVljg̥1~@$"4*h"E*&Kj $".J0CC;~Ct\ңR̓/4 kKbFerc$F7*l%H'eXaJ$h#ff)UC(D"y~>q bDT"L&䙘*}J3 *;3f|rcdlӠZd!X Hwۖ\ҹqPThhLG'4jHDLHafR 9Lu ?5D)$j*u30@[Y)U*h#w)P5>dh,N.A%fEJ*n]\E\`r mG+NRضC<"LO͐/U2] tpOjW L̔Xe%Edrlbju ϢQ)05]BӜ7Y}^'Bǖrll^rTghbHVñ.EAм' "G*Z\ ̣-2<| eyD#ZbtvI'r@[_?i(d&G*jSVdt vIgݜl[dV&_঻Sd;ۈn"JA(228 nT)z6_(d#T:(eCKݙix\:FXR4Y\LOLQ64F\TXgff|og>kE& e1DI(lh2fժ1Vbr*O`YE4#❽eX6\rrd7H$dTgf6u7z9ҭi*|?^1H%bK *9>4&̥ͦqOljrWObLMOjr&qK^XWr8]2"/P.|uq24>SSaxJH&W2űAyaCe]Zag>NW3+IɱH'mWU`jzfٗx ÐrDWg'X>fN@y]$eN^Z}&DN;P#Tb+پ58RmQÀDRzG4!%^̂B} qY0xKwWjZNKlսڴYV&wNW&AJY^.3sA/m]vsƈF'QguEs!.7 AJBq&52 ק8w͂D+Q\.!R+g:aP*:)B%cE#:u,lKQ.%B\~1xeY$W!NC,%ISV@ːc$IRN8dYJ2ZK!I,eHp],__!8,RTR'E!kňŮi%xT!B!IJ&B!BeM_!B!˚B!B!5 |B!B,k !B!X$B!B>y]/1K):::uB C_)Vض͚ի,y&HRh=R 0d5.ĕVsQRB>OWgL}GR!,Zo>'N~T*YYP$u׫ ERR;5pQfy |xW*l²,֗:9B,m_VƠ²,1zӅXV>ueq g͇XKݛ6ح,PK6FZZB5Fc[YR KYٸBXo9q2B!N pyl4z \)En=!ąt ˶@k̤J@EID]Te\ ;hMLU5'^9qs"eu,t/͵r"hoבVmE|+lsk |g],ugJקy$Voe}w(:C Qo{rbq4y9bGSSZ|tyF\ޔj62(P\<ԳNvqM׳ ӭJ-NRPfA*KHE >jf*93f>TtaM{âe+Log8z y~jg`6M3ijᲕ"9xլ_EZ\8VgٞG\Z,t,n>k>b/Ptڼϰ M!^^uTȾwαuiBb~7n[CS,oU =ּu)Tr,e8VcUP ͛fз ){-֥E^H8p1>kpu b "`N}qv)۸o79Q4>&46m%z;ғXT3cyqqyy tQV9yٓl}ymWZ8"\s+m|o~$Ar#X||g:6\Pl'?|G,B'yV#XXlZ@{?}k#(wc"_!ٰ:|a|S|GϑYwWt{/~@r9‚+43C}cVG(Lu&3۸7s޲j:y ۯ9`~C5Ӫ1VJnß ;bZ73R iק̕ +yXjϥYR|.=FIڹ{`%YzOcVm/93{l|wsmwٟ_-m73ԫ4Iyt^@b?5Jz__w]Oxn9KҿrD6K玲\}\{o~ۻ=7c$8_؏ӱd42KAIvj:;[O{뼇 O#b Y?t'{Y˭7mnc5}?c60(2=|_(C,džg0K[hfZ'5SVsau fP J'6/8%KV%[P=Sֈ{ύ1`ca 4mHu7@le('BsP&V`X5R!ejuc9bQl4ZFqU<NL.Ey-&|-`)fpZMܫZVbcB? 4j ?H,X(СOh,,Bj:h,k\,|Dlܡ͔_"C-I4&ɵ7Ʈwr{Q.ݫ7ak(׾r19sӭ>kx|,U1W:S[A"A$rd h[NV_JjP9OylG?Vr@~vF57ɎNݝדq91ʩe❏>*7l۶ ]FF\teU^Ww_Cċ-Hzm T92.zEd::O=0Jy7`Oqd(j2mvfQ᧨%װ;` /r`p[5=vKGڜ*cZzhtizVbxV󦦨'ާP1nڏgj/׿/Nz'w_e/=￾>~1Y$_~N+ﺙ;BWw7`СKu3Лd2DZ49xU4MW #cEn褽omUxdCg`Mym| kr s jB"3W)|X$3\2lךF[x[Ư0zZG{wm9GF),7o{vdprA&*Q6Ox r7mKHu6Coe6 QϢ,'zhw=jb.e5#ODXu ܀X/!mhGiU45 DrQwrRκKKVJ166?F| O`,vz~ޱ3xk_|'7 lj$_}_0[esN-ku/[&я~{wԯ r^E-hT9~ƭ莇{9^q=S2T 9,_>|'/<۲Pƞ'~3L {?K4* ?|LOo)t}'}y"dQsfYXA/<Ʒ}?__HW<Ӧ7y'WL'_9Ȇy7oK.0>1}y=e{jvLl-29 9'1 dɲc= ޝs>3{f?ܹwv;l[V"E ̤@9|~8$Iٰ%OwWu8vUEgw7-5ØSFYFzƒ>CW;)4|)yԴt9[~8u%gdQ[|wjȱU~Yb-I6(Ql);H@#5H0`^z^a2 z!Cü446Nd;6Y&T9?B@Oo> VG}Hi"4WxgXǿ lv۴Ϗgs}qgϜWdLnɹ s~>//\r7^H$2g&~nrwb͚\\5ѯ1x^|y:;g,dyAQw,5#t4q&Ϟx}\m餳`4`7A|x~.)5%$촶u1jA_ ~>/kBI,X*B&NB0}lz1})Sj$/]ju9[j"9NYY圩Ś&z q|M$b).o"g$p8ݪe>NQ.G&[+_%BJiO$-5-XP7TyRĈFI\M}$ wX|o4{x֤ qiyddi%{¤٘>8֖@go7 L3ʊ09GFndSmYsI;쉵03},VPCGXT.=vTqfJ;`A;onoÇJbbDP0;v;O<Nc7h]ek֭=1ܨ> e>>\EP'38 '.Ȏ\.%B,sBb}NhI,f^bÙHEAFK-A&~ 2Ա؋VQRZ)3Bj 6oKرޙh+Ww}jjyf8yD8׸гniN;wӧ'?yţ;u8wrA֮]KnN.as7bgΜ[N 򇇇ٻ}rssXruORWΊrWJ a42[ 5Ԭ\.:"Xĭ~oHNVN6qf B ,ddO#GRYY*c|tCsrAZki_͙Fqce6ͶBh3&bk`Q ĔgJirKc}XGzX]92@˱)Hi^8 ,027Mn^Rٳ;t.0hiGFhӕʅhsXit ^dN^iW 55I3:u7kFgAY?Iti39Oփ;_y˝!D )ްkl`h4X7g&ҧ|JoJV'i%N\ܭF$8)ɉc!c,Y2ӉJN&=!Vm7m!z<;~sW>yw]f$26Gfh p-(Ow[ʦL+^z( \9M򭛉مvUWgdӢio ᨁ1NbG8eP*4˗eFh0=YJINv?>{A`opa Ӽ4쑔[عA^UN/{1Cd{"@}Uad} eنTՂυ5T$Ws!.SӶ8ļ+J A />@G 1 ` <%*JIs`Ӣ9 <$E;evEyZW`q.{g!/Rk*[Xqea^:Ol]b" :=\#Hp`lo6޷i {u4Ĺ:Pظxhkj#lW{Dcb ??(Wα쌒Sl47,; wqx!GI/Xʕ(LoN2ؾk;kʋq=%s|I vrYZXuxӨXLfHgN|y(Q{"%XZF"]yc/FPCܝaJ8,)]IpoZp;3aF :v8cbPhhv'^Kofa?Dӭxb/"i34JχM2<8D0"<{D~pY`ppdeM> (Cѱ/D /S?hEAQYxlڌB|o`_*-ń$82H(  ÆaphAa,6'>_)CkK#`LKJcZ#F1py얉/d#bg4E ӅgD4deaJeZZMow\ ye\:*9ygN)+N1M]`lp݂n(ˆDd:ubha"XNhLF 3ёa,@kQE%V8c"fёaFGDjzqXt0Fin%.%xERnaT֒9-m_ASS3iixA_,tb#?#8po&O=k׭~)%/_!))v|7 (G2>x`?|!?bҥs~RRR&~ Ak[;8<===7}5y|]dddL}Ww7pi>;oc=κ1Mslz:;;&33k֠WASs3]'''D܊ pˁ/06*!oMe,xOr~'nci7S_h YJbohbxl:,ypNki_pߔ?LuRӷ1erY9~S?Ʊ9B;μ?,Oǿeek}g-\嘵^na}Eq]߱smr?!S9/8G7s^=0۽dr\g7u2 Up7%x9}4[n#>>~, !}wax衇UW|gLC8NVZ55XS[KRb,FRRҌ4zΟ?;x<co=H$LZZڴ#!!UVMɺ q/[N FV|ifFu5"r_f c3des~у K,I0M gos?>_&pozߧ}bC4*ʢ{k)JvM;3MM0W9ngύiP;iv73<`7cu[滜V/xvs\9zĆD"hW[73 RJqiX]0!77!9Fnnۆ2=e|߇~$6F|A.rG3R34֛%;*y|-ܹx(QnbD"f]f~,L>3U52Tmq̿;u:ǧ,7;:(*_*_J~I,dsVEQ!Zό+K.nW=(=EʗnPPBb-O7TGQEQ1rTX/7皹l*]y(ʽD-iNpBQ*3u)]2gw~sg-], ޢ_l6鉍&rchc=R.IWW7EWױ)6}ֿQ#w00@Ԉ9ae /0f+|Wyw+4,(Zyc5rRrӤ8Ldpp(wtM#>>]YVU_5Et]'1!aƀvM_߮aجCz_a.Kpe1ۛH֚B>"uE^r+duTEQ;쎌iFx~a^q' C֟?{'B\¼gDG0so\[Di0N@iIIâHF{"bZHLM#c& 4W\~^s(x@~#i^7z4w00Đ&)Xt4݊GB|6){FsŁVn>/ +?"#yGfǎl)a}M)iĹ,3d.W\IqXB Wwt.6Kb0 "=sEyҸm'P3OҌAH[%u p=q{7!A~ql1 sami>珔0{+ F $}nt!)y5Mr#:<k7Ϛ23$!?8]8,_Dρ t~NYW*(ʗm!ô^>uH ih<صq9nݜGJH.8jIoR=\AZ~9)q 'z ZG圍j>+KqP`~ Uh$ 04436&c)5t4I INjP'(/A_^y.N~I,$b=PEQe.<-svEmo @?UWX;p]t.jH[:^m厑({Zy`8jC`YK`+~/&i ӣd9L/`4jr#ɂx -P$Μ#+eK{pp!EQح?@Qy~E[yrRv&aAъmݚ9sB@{@ᱰ*F *J̲6*Ab`|&L?Iox,mZHzۚL#L9mߧǴ 3Y{̯##hBc%/(gAQ!ˉF LOD absb1MU|&;T3ϽFuVvja̲ӎ1Plδr|=+m\aiDQVHa^laB}T5xqX]O\^JDXcEv^E'a_{NݸEYY) f9gPN)oqD.V&;{\hMTI/VOLW\@L)ҍ  ~d+ |Ff8F$`K(eJ~nVrV0 SX*wXEݧoS>u3:^)?:px2Aӭ86 bnp-4"l@Ovر2hHV'[HtZhU@`,!*;3g;^S90wӴkjn=^' y90gX׍ΝI(er-MrAjC6~f)qsz X4rP+YEXTm[}Gް?nT䟫"׍DwH0b]hZso,!"lKbJAf6Hfney3|i yꛫ eNjjj.8;gxk<}'k<\=}gX.Hbg4heͶg}[`PSͤVddIu L#LGs-m}#XXV^DCje+([kjSn=I_g~2LVZwW^ !y}kfo8?dY]d{4@o~ɯ_z}ħga³?^}Q'YN.~y$ fhcŋ|r W C>HD WxKY$#$%m>W*19ԟM[H uFxf?%K ІZ}F|$H {η3S>nY)oHtLNP9 BӷL[ۅ{yK]> IA^I1͍ ޏh7Ɏg{`2p k))IC'Z\Xv|.$#ty;WIh4Y[z8B#Dks 2t"aކjy7rҕXR鷞W0yg~&'tJ$At/}:BǓF#LF2vǫGY ŤAwfs^} GG'dҸu^sjg߫ygkb`0@t'ٹt?ɕQ\N;v}{j&n iL?~_@hnn?l%#)nڜI0RCS_{{ߧ'qT=1|¡+}duc~aͱ{;+O^%:^y8yu{ק\6^KBq i7x3Xf-+Wo䛏oaL,fl5ZM+F$Vw eeĻ+ٰ(+W[HW/S؉'w1kWD ݜpD#`)|v ](͕xXl# `wQZ^J=88xfOk1Ѡ$85B(ެRvl]EMޘfGCbQNolذD CH)H,87iYiPd Mq&zx=Smn/ qn6=`GBL'e,^Me[;c"]Xͽ!IINHe2dKͤ0hhEJJ"ʋrHLdکAHEmJAi-`#pdn^z]j)5tcm;@S!L3L$C[+>ل" }&2<:qE.`TK`4 N Rj=j`}={3LIh* a_e& Kٱi If],v aJXk9nA+[̒kX_Qc iKa`uIHjFTc:1a-[(BQEQdn-YJKQz"ں1 @5M#2:@]e|%XtLD vE^/Bb`8ZHew`YѐF\]5Վm)]Xm\nQRM/gC!~GYG8J-.իVrwG9Y+-^ST-iiwuN9Mh@V-%4`M{ډZ$^HZb64u0M״9aI7$Q;䠤"8iDemB~yU%*ZN1i.aREd5-D鱩FzQ vYVbbc5`;q EcSHHS"y`]n\N͖-+yKԴu;DFz& . R~~sJjkPW:Yz&eXڰiv&BAZ #c5 rډs9фD4lfmrHsKt\ ciuo.M3p?lsG%XؼШVGb@[W9X${I #}}}H)1e,-;eAK ? ͂@dzzB#~ڛ: LԵfsAQ=8¨IVkdF زy3-VBwO.2MAJAKJ\?zGJ ,]v Mr{lAl:&ZC|kFV\kXNQEQ[lH-)sô z(m Xm6FFrzYqfzCN/pmۣ;yɿm>zIbR"nP\b% >ze7I83 #Cw@eOƺapEzc M^=!==W+}! wp8p>D8Yf ֆS>]tzIMwH8 g;tsӰ U#b4EGGMiHX4ym5 &)ѥZ _7$%'M9s4H  ӌh'?a4u3 4)H_̊b?+HZj..Ĕ6ZNJB/UGO ֚DVKebKz-V 1ַ\CMFAQ#6И?_'_3VczHSHaB.@)/ Q 0JIUbMfYvgV0#=uo/v{ⱚ!"h3-&F?b&FvfN|̬1} ss'jBD32qGu|2*ȈGYwYO][M0!8VnXFd&!$TPi⭷R5L(Bcוb#>xh0RYd!>   a?Yo;O k,X[Q^?m GKi!& :DxׯQLf|v #"NVK9y5݆᧳`ਟ&q:ݜ!3IGREQa׉w3$>A}s==vHr@O_ H颾޾![zʵXJ@7 m,K)v;msľ>t u+o< ${8IxNjRٜKNh`q5} /="a aqw7OҢM|Mo7z\rX.u^ASSZ 9tƓ p~eg!==?U+W`g|B9qHX̌PYE}g?aVVDÛJ^nI>DJ%-~ S+jnɉ7zMsPVKOw8)5|PʼnXKxA(*tYƗ5hRe=A2}$ᵘ t5QUU@PKͦl>hns tRKO@G+ J ;\n%H|"2Qu=8\cDQDJjdPQHK5j!.s_h=Á~v=$G4MsH)YTp褺cۯ{ttFwSXRF~ _;uM  N""t5pBr%umx2 pxĴ,Jshpr#k6j$瑟l{e3*k&>̑>.WXD3LUe&9,Kj\{ 4"T~)uG6"AJH4Wp؄wۃk0̅W7ldQDp.†Fr*rqGo|򝭍4y),'ccKU ?դx3 (HP_ۄ-L/WLYx?BxZZ{xS(kfXLOAoiVCU]| Rm46bK'/B{eyI. rAINA>qf4RX@g5턭^ bOº(d7dB?ܑ7Mbozc-))_̱e&ZrLSSF&6`5]HibiKt 0LӔhk,el!i`H5M Bb&Lݶ7iccsʱ}4i6 ضb]`:iSi簶7yAΝ;OOoo,=zƼ^p:,./#--u挂&6njNό/oRLRKL9~L/[4q/+b eĜs0x`W:$fϦ Rv?/Ͷ<-n qc׻i]BƮ2ߏ5mX^iꚎr޴{MܧFNvqMVG-B :s~Eeq-6۔,y`L!UMi^,u$4ơpU(ۇ"]}Nydpm~wX=֓y{B M9[FNEQ *L) BDgrba;GH) ÄY4 ÁB';fޚٸvqKs@0C`Zqmi8@ GNאx=ia&`06O,, c~sIe8~ݷ!q))^;#=-$Wku:ݚ(ܯT{}jh$dN777"=VֻGbf*ŭ/%~ֵc(>ߌl9 N]J՝@DcχDjٕBi*^;S^ΟͩT=Cbj:El\"TЫ((wJuVR&)hO$0Ք-i>_eB:![{>WEQ/nT 0)ب@NM]tR"((GVREQEQEQ9WQEQEQEWQEQEQEWQEQEQEWQEQEQEWQEQEQEWQEQEQEy|EQEQEQibw@5i*((]]a~I$NdVM^(((0!CCCXVrݹ+( m$&&U(((r3MŊiH)ݹV+B øϫWQEQEQ> ㄀/8ͫQEQEQEQYh0@8z_EQEQEQ{$6ԭB 4 mGX '̿>ñ>-ESΊ(((<SBHý4QPv+6< rZ%C59tߊmJyWQEQEQ+F-֞chKشbn'azoK[6Qpg]-*UEQEQE:"+tVM?Ͽ]X$==žQb-rc۔FٱߋMBRDulӂ,D*((bq*YQEQEQE1!`sĭ}, sR,8\3i[~o?DOr*1+6o{jCGH{jUEQEQȨWJ&eS( Y. ̟1 cZ -%H3@gĢM~ǧ? y{_#r~Ƈ =HԊq٭fݨvҡU(((rϛLj΀4M,lv> hSZ}t7qh!4J2 u7,%t2]D΢MOwW,qvE' Wϑ' K4!P(2V\)m:WQEQEQw3A:/ Oy{G(05w93vL0pp$l:yZ7g8d*RmcUOraļ,[XLQf<<˜>~-K>(((ɹtoK]?MCA+9Fׅ.̥<jU#QUt.L!=o'N^gv?YdΠԞcZ7וbxi~𱿏 N}EQEQEQB@Jr<߉O"44D" 3.iX,tM Mh$!% Պ&b˙ՊEc}r (ުX`+L)X֑@jjlL]((($X@kcRXlG)%B`ӯYB:m,b]yS(((=lIENDB`Eqonomize-1.5.3/doc/html/C/figures/confirmschedule.png000066400000000000000000001254011416454732000227160ustar00rootroot00000000000000PNG  IHDR/v)gAMA a cHRMz&u0`:pQ<bKGDIDATxwW؉nDzS{ !'xi{ڳO{蜧޾i$ͨgzf$lHޛY*TAvx ʈ7wD>r<f3ox~a`?(}7000000000x@(@ԔuMww 0o!^yP ~1bh 7OE!BAQ'O4UUŤJZEYsPx2<>Nz4o*B"岜|t&U9 !_]L~@)"̎3vPQZM::z$)t| =c l!360JĞAiI˴.W)?V뉅N*2ӋžOA.ce5H`ёADZev>(Z~Desm/3z4>%ʒLI?OʲQ>!c̎ՏϔŦMuAN?ǚkf&F:8O/B,">&Fc|bI&&&`llq_ᕓ-O/dgnc QB>iЋw\b"Bٷ/CN" 潗at ?l/ͲЧô|B'lν3_c^~.z1XEBg ޽K  zοá[|RxtEo_v#헸jra.wOE茵~b_100xKPT:OnR H Zp}vc̎Lo{߫4SzD䫀BA s%r'S[¬`IL,*sw!@ +u$\#WZ4B(D0KdO*djJ-%šDUe ?^UROQi7]X)%OҾ``I-'Aϱ#-4?f[Fѿ :&Jt G4C60 r>:Ҕc_oĻW9fc_cW0}s @l!Pw:&BHJ/8ngN'nSyPK)1syjFә"ӗdZEc TUA:*~矔Z,_f>PqTȨ`wZ")҇%S$tT>)8ݤX-HwHrb7lB(17قDz)}|Dc1|6Lv')vc_N100xӓI:U4H $ÊYMqdѼWn(nܓp|S#1BY԰Yͨr_ܹAg ӿKBQQUUo.;??`۱Ui !V L>]R6eX=n5enkMo籜^NAY'+uTe@}=>hDUMdcNyX+CVu]k]Fgo!$,ˬ}\)O+\d er]Zkr]Zk, (ج5mrzd~cyO5>8vwۨfxEs$+=6m`ESBٓp.a(!PM&D$qefmhֽ3m44T~=t2<2+?y,w)O}g?i.$5Ӹh!/}zhĝSJ}u n%@c9NFy#يlDyٿgp}'UNMQ"g+}- y7bkmD1t,3DP]{Ȱ'50; _~`{c6(+gKC%%}\V[/gNa=.zF<,ørh.Ī* #L3=x_'S7#+֏=!^:?NSIo*@-|MR꫊qY tu0$yI&n]lO 72͒ϏΦTҰ4S.LXiG%f|)"Hlc!CF"sJH=PWov3d+8r[#aʛvCh9z dOiywr`fy),t+g¨`~ o%݌*h?*?y*AMIK8NLngjr/wny("/3?nY Spuz2KGYrw(7F}X-V2RY8ũ(&58͜p}~yP&:xG{g%O\g\G ~\[pP[[i֒6QTk6 ;ƭ;غ$mSo<{E?s!F'gY僣XaƸ!`4?=&)ԍC`p!ayCzRLK,ň9qR_!G;f5o"]y f#5ALInVvo%y (=0{)-PZSO]YG^/g6$8^ؕ$\)^svi~f*Ru<^4jmOb.qXS#-5LIf1.tϓn5:zxׇW\ExqvHF9\JfsS%jl paT7o2Z[RʸORvg[@p0bǦ/("JxL%54W,jZb #JrN&V\%;(BC]X6f[1,_ȣ ŹB%)Ʌ*d7kv*sz' PZ@mim߿rOX[aG_ywRT]G]y6'0ELv^N\yUli":GRDz-ST4zg'|+%K`gn K_~'u#Ma+pRپs'ue)gn[|KǙ ( ]䕷NXKA}>r%5gpW~\as$9y XLX-* s$c^ /~9klc{?r,Mvss/^GFl)CKvvYqE>x˟b2 QsG يE{׆jepҼc;6c ?@zjOkgF!0[/W9uA&o'ofV#ivd,`ˎ4UTô5?{2*+y%hW1oˡ4;ހ-R-^.I/Ow#lIdb\8tjVmgDZe`7a/$1$嗳kv?~qF=DlsG0)Ă~AYvk*$FZZ .g5Mli*wWOMиc;VԳO#cg_[c13r$NӼg9T6Ğ*:O[VmG+e)cYqgaj!"Bx|ڻtzr]ф&Iέ؉)]v}~IG[ `SNyzm8?^BۑW8VD}M> Q {-3 O36&*.߉\"IN<6m1ů8l j+fI?+ǮtRv7UCUS3yYT4ǧX(m`׾}lJbrxAlR@ʄŊjƬƷL$RiH Vw)6 KK~t$`%#YYU,%Ru=q@UM\NRNL(ā'ATłjIز)IL1Pزo'Ja}>9J ;v` 395K0"'Rpt]f3%RD&ʬqW/)5v:IMMC*Fi ,+V8IO2C,JT)N{wʵ3Rؼ}V.̱89QRf9s} c2j`IbOR"b_qfײ9/Go3<QZ3ٵo3g_qzvńu*sHVKoLӍ-CC4@؁}<|_cwu6.zcd -ĝ(e< 9-d< .RMtLn~&Ӈ"o-@O?2 8."5}S@0"Ig) 035J qST3f̍;%mj`RDkmʵ6V1t¬0]H=Hu9]PNk)BscOKPRSerC$&gn%Jx1_IqyI8Is[u/!uy0a2Ypq;M(iͼj8*6%QoM3>>(CfcG&;k1#69!`ɔ\rVKeXK\@ HN"ad2S}?Gk`WZ1g~ƺi 3IݝKyEWf66EEQ&s8~rLA&'#qQcNef sAT1D kӑ;qJ EhJ)P|wNBqeqYI8IfH&j L\8~ZJٳ\!-Z!:ҝ|-]>ū- Ukd"Vf;M] -$h7|sS2'^{~y\+R4fn=w9sc<.st" %DEud?/򃗏0^KFS_ Id-b`h`䣏$\S$xFAz|h.u`E?wol >:@@/(:Z <~<W}pXS׍ ^u6]yUŤz8skMf(z\@6=l"f|KF[iN 8c8{_C˲-ѕ$قin0ͧ:C$DCVVPEτYUV-?|n.َ+َiCU=sĴP'zn1d'[s{~*jL#>>NlRQdTɹb5uNv c~:/ L/(.lJ2ًW]J*'5wc8|?X( ֔X- i,̢؛n#xY vDŽ`$()j*:Lk$P1J框"L Oa Pn\ة!6̍i{zF9hj.i(l.c1zCV2rrhԄe"gJ}M ID[v>˅B1hgCSķ5YBT qD&&D81MO8vR@5;(c1_ !"ҩjN%ǼqXp8X}0R׈`7g@QQ N\VR%RP\VKcٳ +32:!X,8s+ 7oi&gդ3=!ӈx}>ºx9pJ;ubDQ$p8J(I {~Y+pRD3ͅsW$L(3qm~xHp$W$l+[5q (RwG%,M;6PeEuۯ B[PO$ TEH<#2*h) =x /XEPR 5& iEŤL<=1O\T98A.L'"׽M$Õ_ǎ],D&U!at,Ž*2.ciZ jh4R(`q J64 bQMG::vW&s,df9͸7fm`ce?w?0gOzoҰ(,Mq e k wZˋ)If*']cxz 43S,p\>y-S6TDZV.V7ZPfc\ކ1P5Kx4U5 T:šCfX_Jvn)ֶ!Z qJ͏쮊gPq9btQ4庰9-twa 2s>8O4BXi[t@ &nq2'[T;.΀so1QPUіS:AAI)LH;/Ef^O8cZ2\jk8vf5NB(҂Mdk&,KÜ?}E-*2䒉"Jʱ.qn091Μ J K1!4af:NQlR3Pg5jV͍qZ+[ZT%u[tѓij*e ׆Z`jBmd978Jnt~'auڙlVQ%h/mg9Op ?>;,l~.:GINuΐ]RJiaNŎ.㙙%%2Rᖳ>ׂ-Ʋg:9~<=LM)('7+sk%IܼB]LuY1)Vvw1VW# YƝ'";Pu ƸvL~i YntZLfǸ~OԎrl'z1AÒV@ME~.o!B sPVR@ӊjapm3O٤t_Q"Rd;ȫ*׉߻D0"ɭ#kq TEVJ pRPQGyP궳wkU9#* IAA5Ue|eÑSBa~9Y(E¦ "ݩ((0?lS бttq;QuLkj|r3ͤ&5=LJv19vn 2@ x1%QKNv&.Sob#îC3y.8r,Nv36UNn^)iT5RSOINI5۷ԓbS))fG^7LjQ99dga("ێ#VѠoBAQ9Y; -.%eRZCvN>yD}*囶\Ɇ dK(.a:--t )A&S\]DEF~;wl4?< 1}xaRؽvŁC rٹg+Y.aI|R\dWmsVJ s3խ瓕EFjY45T&9#MgJ (lNV7edҨm"2RSpuWANft,JRK}C-]WRIC} 奥d&ᰮ>QAQq!n fg%Ey. )˲[ w ])s.Bv6meBJn)L!)%M[+@fJi ;MRzn,ۅPS榰jjJJi,xCdLJj:ɎLb"3T;MAAi)IVQ"ߏlđWf e$[Iay5uUT䓚BNA1i8iT6ncG})gᴪ!D47cbuSYWO ^?Qif#lÌN`q%|]dd$9bEnkk)H6DѱPҸM٨H$ yel$;-\ꛚ(vYǫ8)) ٕBfz2vzJLq9Jv a>Nuq!i)nҰgZ>MufJN o¤dPd_DVԜR /`Gf9$7)~ʏ-9j2\fP,TPWUK]U!)ɤPZOMniv4N^^>inB&5X[wVa J+ki(n2 >EJmOxM[#qP@$(5.T/\N_HH+obN[+QTD~Ad#X<"rmmaEQQTtM|༦mV:cn&gZnŘs??Ů?;uR'|s'ꕨ`v#ۇK]C䚭|JbkT` aO*6R߳e'Zk&d@2 VF4 觻(+^e\]x[RUnĝo]JI7X!zkh:-םDޫ˼%ʜ0"`@eyo\qZ2 t#:Ν)q[նUzOp}:m!]i5ee No_!.+V%bϦQJ\8GVzg=Wښck[7l}Ys\_Yj1bX/c;rmS}Y.\ݭ=VvX?lel2dzVW'򝲰w>b4ݥ=?/_[ۯk[<6l{i-p1-ugA][H,\\Xxy:~>KvkIym}c<$%DWiܟH)~T~ƑR#s*Lr{aSsݪj_D,Tc,L ?奠l $a2ts+Ct$YQFbRKUᅪѣ!F9hj( C"|ijm$e|d>g.6Ahc\o͠(S›~-Bxa7~}{#Q+\7 !O?ѯ RAՋ(B #^ξ *s ˟=Ǚvy[^!BojIP q/O+^i#`,?.AsK~y}$znFHb/5oXdd3@QTl639?ŁT( Epif]8y3VYKnn <̟IJ-L^ŷa^|TWnZR?󱎦H{z\\~L"QL&6/%- \'r&,77\ IK09ln b~2@덫Q (ن:RDY% TtiXydutYgbwݽBH'hU6b.х}ߠ*(X6eWU 6K{p8bcM Ŋf꯺4SXK>a```䞧Sۭ? VEMGtk͕E|-siq=8| "EfQM&Dܱ.!i5Bu׎"cc%ѕm5!Ђs5.y6Np>BUUXc'ˮlXY~ۛ>((LbU*bu97(߆BMw޽?jM_}oz*^ +ַ庾*Jهy]:Rg)ct⬮!,VÝ}n2V,XM|# {}nn,+~^:MJײRwQpRĖx? 3tuW7$Q7OǕ^&*b=f8Aclz/3-U鴟9đˣdWmgۇtg2[uũ~N\Agz#i̵21۸rpR%O= 1ϱoqk-{x-v}Z.VR i%(FXSN< >B,4cK$HrZz+/c.c#-B2~x9^=|"='bAWJ NB|kO'pk#DP. /qbA~k1$b+GᷤQ a)QHImwVg}G$Vh tO.&TU7EYfyWsy؏jrۡҰ>ٮUMnV™ϞG2#%H-JO$SVF.\;o"lNK?pҲ<[18a`s'c /\XL}L90;,e_=C1)xG[8x JZ19$E/ܭIlN;& EZ(0qA^Ǒ_WGѕ+!09^9~ "K8kǿY8q<%|RA!ZO;W(mʮd;`\EM86F. b11|oIXvH:NL*md׮TeX ml@,`i=se&w_{.~7')hξ6a32Gqlyh/;벘b1fBΑycLvI!b {~ΑKx|!K!':ygO_;čY p[xuŠi˼|:!!8OnvJQ \cNW n6lZv$2?/W:GBݻ2ɲrH!7DKxɄBt~Kz}~̡u[wcs%3&K C1Ⱦ(v&&#t]SʚwoWbnхfS o8yokr2o^*^?y, 3u?Mdb匛Bta6))Q46a4LqnѐIT=D}>o&I4)[ ]uiS8 pM'ƣU54Q= u*qED8qx9fd&u/RKh(/Ҍ}OQR>,Qi|xG/@۠GʒY̤dAg8}5D|\JRʢ,[Tgy$H}9?-3p8ǩǬyХBxd+2!U1 Y@LV;IETl65RƑ_cӚBYsNřJFW4*l:ü~-AG8-Sz8̐y3S_KUHP]HGr>5udT:"RRҰ;rupptJ#B݄j2c5Nj ġƈi2r$; a M&,3&W6NY!Q3GKv LIlRbsb14]QhQƧ[-׼c{+oe$K59DchX/_۱dt ]G"i0qZGg1EI.'aA$bVStAV2!G%Jaf*Os|'33po }^xNX2@0(VUfs'alAGxƇQٗf_i;dBQ{zCo6e蚎3ci[(@JIp>MłNL F ̪'j^Q=D [\D  ! v qZDz%BQX$ȸgˁbFQbOps6Z=@g0sinԄY0?|Xc]odu.e07EtsP0'%㲨q{;ǂ&I.c[Y:g]fb[2 ) <%(?@HӈFUg\N#M(doJ)rk1Q]GQT$|0#sV*"$F톉zG]ꩳsͷi' ♙`)QZc7<'V'm qě Mg:c1B(Psɳ79ұDIn έ1kw|[sCA(BiRMp{Bg[Hs]>b&DXR rvSc3}妓\P2;ǔKCKmb^Yci瀎Һ '2I㵺ٺ${6u[3q]^[axds^Y6-#sSc Õjf253/!27pUs W7BTB( DɨJMzT0 ~XCRj*ue,^;YbD 4 )u;Owo^VPGmi&u,~ݚYŞ.:Ƃ3$ۊ. , Is2BLs' M; Q,NJk)ru&#Sx<2>Õ+Xri0űNgCa/}7|OPL\cgKR[Si=Hk2NskI)D{9~IU}_:WGɧ87U%0ϱcGitdy<N;̍qZS8TUOqj+ 1XpX<4Sacv?ϞCSc /bACGlPnF4=4\"Iߥ ·1p$ٙe\c\ R|N&gyd~+#b:qPVRzۼC 9cπfba?;&[S0ْϴ.`pl ʨ(/#9:ų4sey$l,uNg"H1_™UAqn*d?Oۼb2\X,62٫ O0YKa~6Yif. Xũ!ڻH.) 7n ZtT+Q *HW@>OGQ]3õ9{k sqn ()#+ٍ.gs-~U<قUo£#t\MCY;tX-RH&-j&o 8,bMh'989TTQ},/bx|YiEe$9y:?9&dž[)++'/D5BؙFQqiN:eR ʜ/ 5f)_F #M,qRBTpH/7]aad6FaI)NTŌf=IyeZ pRJQcK;*ovCUcB'ٟ2/,G?|xZ!t3E0[R2LW"~CCcb (3=tO9&Y15E"\j*P0#,+*pύه7椼 3cݝypdQW]90I[G7a+%U5奬[.,MՏeu2TQWx}(tISuu3/ݔ 3PVQLM07:@4<**T ͆/$7فNz1XS#ꡥO@t2#H[*%dm$6x|q<tu1R+6?>&093&Y+(//$63dNYEIV!5f&[3p>QF,ďŬURfb%oζb& +jKCXCA9<w8, !,xb0}3(>i# 7 ӣRTIhz#L6Ӻ"I) /Ͳ Q .Ou=g|i/<* IpfGCRR6;V2p" tt22đMee)n KS#ttV )+æϳ{ŧY+* + QfLJFMʢ0'iDRٙ8,kGѫ~^R.z!&BE%)3TdŢ RYۺ$xg&YO$%a9%D7;L{W?>Eym i*#O.b,}~a$*kj)Jwlgr%te`U_ 0M0$tLB271$QK2$By_TLet>FzFIffFzA'SPZAiv҆ZK_g3!2 R1 #b(X]ibWo98MO>JAq,-ddlNFrtJJT;'NLoOrS3xHAF*E8M7臘$p qBY (Wٟ.+ EM*/4 )J O%BQPNZ:Bk::q,5Z*b>5 ]&>\ߏ*۝ieS )׵*32GV.%B _=΀Gj2V%4b&Oی]]5-7B|߱mѴ .7I]c Dbklv͢ԉaw{w˶ii1² -[iSHR_qKʺʱvgRN29w{"'r96Fh5r'oM:a&L4=XH=ti~}k```E Ah-̤ц +| B =Sl2ݶ')6ʫk(ʰ5X^!6 %&GCm9્aCl````````Z!j)i```````pOl5gXSAc:1c `_u|tdeqRJ w1!p:\N$9QV(t / RxHKK5b"~].1 >s%!._A okdֹɰ*`iip$BVV~DQpK  Rqx_Ht]g:|;ʖ:`QH@ǥ|E$c~%EDN|7`U7GQv;)Hy/Qy >BC/%_LDcץ60<mK4WnS2o<!Oن!@$V>|r?XW5:R6W(jA!%5BAQDžvT2)g51rh1-&ÏKPdywv@(\OzR躾~d (m}do*ێ.%Z4٬| M+ZdQ|A4]"YE5HM 3=*Ѝ 5fGz &T%!0 b1$N*H(  ScN%.1-ÕLfV&N R DzNxwN_Q5zϽο%.u/93 yA"y 2cddy?,,*H@ DjaYbu=8_n{9vċ?ͼ?ý$/'+'SZћG˟^7n3  ,Sto/r  ptUTdugPst]OˮtÐ7I3;x[M$fR}?V4vfc7B-3# ^|u2]/zG>bhLu "OԢ̌v3=qRpՑ-f`Cى*}*>Q3~2XřICS5wPI{;:H[?)Bai5̛:*uav _ )ǟ~ e`i±o"L^E-U%~ ;ſ0͵o?|cbCAJGʽ- p H]%i/kUQn/B0O੭%}i6Bt6"!\ǫg"躕w;vpl Vn + |9EŤ*wkʹ! y=.pcķn͆s6-ξ8\MFv׎^r=rHIbXpSU^ݢ&]+VJ\JRR1p?xhE$|˰]$oᱭYS( Or˷pnkm'Ys+nLq=3]~ҙop%/AD͔d:EYg<}ŝy+%BAp6I|X{yXwNxk#~ʋrI" ٿdHS 2n,飯2RQlݽcx1dez%"j ۷Pb3>Ay<{)fI`anFb`rS\:NVm.3ӾT~gx-3o>@ewf-DK'|"Dž %nRLNn~k_Cmxb;V2bI"D u-,$~(otuc]vvv>۪r0 >Uf$".ۅj 0FG<:n?Cvnl-3LEx'\?>U 1FQM" u㲯o…Ij<< CxK󇿻ef[mݸKPgCUO=JUK'5xErwI˲pیr`RULDkyt@ .HLc:HCNzyػ_~\e0e,|q&PUU ӌNym/fWS $3[|\T)^y ȕX߈x4D"ѕ%?'.[+x qmR0 U5$kN+{,URM?k~qT +o3tnᅟBXM KAZvI j :뇯NJ˥um^:xow^}oF3O?aM8aqrP4HOKMv,V32ȵ^oEm9͏~so'l˦JP^u5")9/I^~潛chL^wN\g7cO~*pૃ@ }^ʫIΪ]Y_l8 &[/+iZ C/-?z< XE4?zs(g_Go\"z½/~}޿5nc q9&|1PVT0Ew4X򓟿(il+d$$ z;]u8̆21Uw$Sm?#c˸]DoM=wQ"B,і)4!H#'=[]"MS=hD5TWVe38ˬ7Pq'%ᰚIʥ |p&2$;Bo&boȒܸyq=D[k;/]N q<0Gz&c~SU=MY찹WF4nj1Amy>w47Ғ0+:M$ͪHJHBLj~"JHɞkr"eb` hښBN2+"܊{cTHjRll 6kvm蚎(46f@|eKS@VE+T L|-I$ؔT p%jK3 4ži,Ǝz^Ϝwΰ{54P8HOK߷‚OX.5F&/. ա&&5nG$%#z^#c]غm+V74͘J!/H)'%:MD'ٱ)M3=੯乗~?G* 1tʤGʼnaYs9焉q-@  .33!*+e D#ctNI6cQ%2&1w@ x>RB aV >=EcMW`FBNJH32@*:&Նb6%Vb6-iwi5A C=%EQQvRJb尠Jm%FԻ!ML|BSoG1~?bBG2;l@!5C ŴjWw'$av M&;E!05mO#*n~D1)~zb~O85~OXmS]Ko`W6\"?@|Mn6q:K x,LCu94nfZm1t;9q)I␀;7qbٗ вÔ`!uwQqܞn>nhZh,F4c:#`h BYH^S6zڲj{ zL_ك'?B,##Lf&G~kzb|RNC0Тi(DťpݒBCC-}Gs-X`xlP70)%iwRQ^D14 42XRٹ gRna^Atb ЃtRs 9iT7b=/:ȬߢQ+Hǐ/d2cRk'x=n*`gs ׏/u1?3tM( ]DU'qWg;?M_jbu!n?wX`=;%*TLBgXN;rR&^pP(|byhw*7D0U"Yzfh|d3y.k|3 @ڌp77;9Ha$ 'O'r);tr_1ߖh\f:-mD08PDc1=zI,BE\$ưI5[ GeP/ y<-AQ0&LB;ճ79v40z,wK4%!7 G|آ_(B8F#]x^yJb!"8ëSh˫W3cbOV6[™S\ncjzlie|ۑfvXg~0g,:? 580<a:l8RPA;7nǹ9lS=Yc`ƋaޮvU|هɶu]#:o(ǡ-rnQXMmI&C16O ՚Ba>xeݜ' -xgN_kpGzIa=ƕ (I3sw_bIes] VǸ5IvM#yb\;XgTQ6C]|i1J+IDxcWPhR@A4/`6FSld` z&!\i̲d^{- AjzxNqt S^al[7qaRh )ʵ h$N1"Ҽ$| ӺMդmܼt1m7xU[wPbA"/M,-UdɎͤZ,y$~aޢ,2[E bLWN#{ob\Z9-<~LXiŘ+)tK5hλue'cld#GI$kahtޮN2?(BqޙSw8e6 !a}0m;/!o),{|"4%v (.. L){>N(FVĥdK9W<4Svp$ YBuzzYX;j{V=w;"K N]Rn% !.,r[!8yW)/LĹ"XKB.nsԅ. T'5osg /z[ gܒpvԻSoY?xvriý IM3|P<@Sçk^>.6d*m.W)÷ .(lbQ'69G|~2hY7<}}=,? vWhܢϑ%`~R;֔g69L A!m[ӆuB2KSv_vdn<%aΥl@0m*z|~rt'&`yw0TW t%RpIfwb_G>ϥ-~ТRpuڔSx,i2Q1aRdK"tOQ߆m:own(ovb;rm QB=Kڃ_\SpuƔ#lj@{fgͤm)R\)IDAT84+)K #Ѱh.{} X[j5w-hS<~ԣ|qu5ҖV/8iF-찳߰'??墶BssÆed4h^2lsߏ!hnH),>_969Y )MIÞ"l@Ǩ`_)GqMC{A; Cs' ]p݌τؚTB=ӆ8Ţo%Manڐ.WT) εx! =ཧӖ5 ]+k0V~҆a.MiR>'B!\>{㖩QG y_a%BRc >tIZqOChlIhK( eٿ_ R+t2(({<+XbQEnby{>x̵4˓>Zs,z=>c+4%;ntىS> C.[CW fg8χ=^@"QC+m1CgRq͎o[ŭ.u,dawJ=m)[k4ZB֤xhG}zJ )R.uοQο[ )nj8pUb Nj /uut~0a" ak΁& *jÊꐢJ-h3V$4/O1" ~}Zo ttajjjY;]c>?̓5)vC0i1m7dx>[>l9鳫jxg’!J }Rdz x4LXōṵ a`K} qC؀5tT)V[$͡Jхytg,rPX`]YGRte, BX}6ջ|qÕ=YKa`9>󝁹N)B1CcA>'7\F4;gB]8" 6/a`ɸe[>{4T*\ՊC5hUo 9h X-ZE\)lr8n G}YN3>#>i5w9b䛞igG}_l\]y!0mʂ᯻m-=z2V01s07Q3=Lh>7te 9 @"ڜ~yTb)3Ca~Eޡpk-V4KNs"9fbGYd'&rpجʘj˽>odQ4̬+l0hl{ W%47T* %8 [^Lrޞ4b["yڷ` VD -`\Pvf^Uv%[,ȠaG緸l룊9#yg<[Qr6TQvQwF6h)-xJͦExKJ+b!sx޲?m;ACEDQV RU*ffo,%5@h.XF x\ㄶ-Al ,+ +J7yˡiU2Wa@{UPa*3m,*ګE 6}>ƨ%Ѵă747V$'s5 \6W.DzR&|޲orS1LD=dS*֡"mry%? ځ.Bux@3>;o]^5L gxt2QXJsWh /mDX@{*`D>s-vyuRao'T}~2fgGAi(N7d,lJivG-?<~UPVCMIEkT1 6;4f|Њ6k:糫.G]/t=b+ciXd,&^뷻|jKa ݠD2蠇oE(rJxr0K[^筺l Ra,!cQ(R ) =vn:|: /knOf,I {}ZIb*} 9 LxA-C`7mOIqRAzs&I`oϑuX1fN*uW&y-8N3>nٕRt Sۋ>mGהQÝLE5AKBϾz9jiËJi0e2ܱ?hXJо*t=qWIRVz2;^eKxgTDY8\ťuQyrĒ@ycUl hOhL7 6tLC4 )Ƨ ύFS:̣JŴc"t-bKZY5%Kg((Xz ]Q Mlj+SlU֤b[jMk愥9i rRUCӰ8Lyӽ>oe9ˡ)v50dhVFSwӖ\Hqu&C ʳU&5;4M>9-&-VTG^ʰGlQ(.4`K_.?;aE {  EǷ1 mqŴY=PyC`)OQSTh蝶~B3T^FnizG}^bޏpU|rk;RA)7oi :SyKg6;)ɖNb.Lf &-9'-9GRW}Lp}KGڒ1M·קZXZ]UJ1= (ίc~D7K#!6.ܸ4J1j#H$d?_~+'n?'Ŗ`,|ioͼQ+Z,O]-v疚W-1{RtQ*(4K۲bXǷ3neC_E_dɖ)Ό3NjYdZ^{ἲO^p-y>LHl+L[ΔE[|N&\"4lR!466`.9ׯ?3?}+?+Ƥ o3ys-J)ҥA:JdAbc X4xBaVu/Xܧת]zm29ewPUUIC}R=|:Uu +cN?7>{NpztYbbTũ^S8;,t!yB1aN<M˦+c-0tL̽^>2Nwks{~I({"XRh4J;8uط \z4)RA7ri,Lǿ~뻌NqwlOMO]N1L(ISs\jR4C>*xXn|''(cpp4ã *RAc}5Ud렶 +/FAŐ:3JҒBCӻ|iλ{ Ap\L?8D;hN: wʓ'Ѻ(4^u v~ : &nFF+Ay Jo?Db7_^˱wx?}fjh7<,FSar^ƭ\C} u?gƄ85k0 j%չ\nj8 \i CViniԺ !8.F(;)GcүOA*#?L;n[oۯlय़}G_"3r'GJ>rU[:!6lZ.#>w0y/>Y~Fվ>??wx\wmv}5Lx&H0wB-_χ>)>ͼoy Gxop48:)`nֺ8=/?Ǿwۈk+w\e_3peNks-^)x.Xo*WHSmQ{>Ou0WGT|vz\QDcm]LS}5lڶG ^zw<jZ>քBgbƙNy8a{gR|W@!8XtVj VJ(GZv%sЬGv*C>"쪹(K17ѧMġG|f-L65&c.u3Ơ5 s(2LM(*BZvH&L9|e`/cbxP$2A}ß*1֥uͼvSe,ש_:!5B!ރVOdjuNuZ,>1jj&C%(6f0cNܟ"*>u}h+sl)UxR@ Ā&7ɸInsDv)CW`t|v+MUn)Pԡm.|*iol抄aw`pU=5#ýLzQRFuv4MTD[r+NX+h !BVqnyx3#e8, + O\Rҗ\ϽtʯܶvpSwnwަc[HZ~tfSrս7׬'SyWyy&}דƏ}ΓsxPs9h3vrT)l3=|o(S_n|߱)Aic=?<eijg֞܌NS444,KL !B!VGܾD`QMXTk̛l_+{O8heOXVЂN2g|;Ϭr[,.1RJI@,BlŇ5JF5>`U8de`!BnmCOex#i_7g8okB!b5]Plqo/hB!k`S&B85Rꬖ]B!+c΁5_>3fsJ@,Bqi) Nx5vU($ B!8**LLNpsg!Ŗ5B!gh4ʺ6R!b旀X!b D1h%uB!EMb!BqQ !B5܊biǖX!,2>1A&YU9YPZQLH$u!B!Yb2&NSUY)-ūXK2YqK@,Bqyb555Rvm$ B!8Xk1ƬjR+YL!B=[Bku(B!Di8uPZ.^~nZ^]H,)B!g VddbZ7uDE%5DC cNJ) 7_i۷P -+X7 B!LXѿeÑFjZ{d&ǘ\w˭jo.٢j%jbǶ%[|||ߔ3+ 8Ig8c|vzS>-h%;OxP?\A@Yl.~_җn/=N`,:j)BX_řB!VJ)xi$TUi$U}O9+< ^=<$TPؾxv;326Ees)y7wXk'joj7Ͻ XTg9Kxmf:3/I0#P=aOht?_~+' 9B!k,ebi}V>?^p4HWsKQb4mWu|[Aƍ4bx9vգ!Cf繦e=q%ټHgTS#dx?oӺ~#5Ūo嗲X!bM ]lءP Z53pZ87Xc0&jQNv1X d-\QR`̔p´lu[U c(*۸q LU B!lU -gOw.焹3im.=cQJB: !Bkv@eX!;C7")B!k̤L\zʄ\B!X[ëcZMiG-B!ޓH6Ӹhb,++_w ǻ%- !B\Д[⮚.lH8$##R>4 80,ѰB!(hԄՂz rc6 VTH&7)+X,B!5cB@]]ZC),/N=ve xtB!QJ1\ {A!B\$ B!5C!"` 7qeW쐀X!W(P(r!VyF#  !B\RL' !֭[9#<:tI9eH@,Bq3.Z A`˛?B!8TihZ "U&B!.`jb!B h^Xagu[y])RŘY1[z,B!UKP eus&)}5ldk i 2|4;g]Kϛ/'6qw1Y%eB!B"-L?,^&nFnm/W0Q"QJ繗_&_JcE$8ݴDYq0BB,BqYv Rhg?|_igljSS# _#"|ˉ+"F]] ^=uU JB,Bq`YY੔";=NZnR*~goz?7z'tБORe^~j7;[+ƬJ kL!Ba3r o}zHkVvPSax=o+7T(]()B!J;2c ] h8X k}W &/vyX!ggk0VSݲKwl5oy`n&6mh$ S:>Q;*_?E e$X!BJ;YcI6nN mFx2yL.\q )]IXҩN!b`5Zt?ixï n^0#j*} 6WVSōt<˃u񹡝n5F=6>B!kD)EW/*H"cB)M(Bk|A @\ [@sR':::Nа$NU !Bcrq ;ᤝPC8,:rBDc$B! df!BqRvUäB!X L!B\L !B\A I@,BqVW`[=ZQ$eB!H219ɡ|sDF˚_b!B x4FkK3Ll%VJDH$˚_b!B R :!B!5 B!EMb!BqQX!B\$ B!U&^1!B!VTɹy?O( kB!BP(ďyO}꡵^!B!B!B!B!B!B!bmEK{%tEXtdate:create2017-10-09T15:10:06+02:00/$%tEXtdate:modify2017-10-09T15:08:30+02:00a1RtEXtSoftwaregnome-screenshot>IENDB`Eqonomize-1.5.3/doc/html/C/figures/csvcolumns.png000066400000000000000000002327731416454732000217530ustar00rootroot00000000000000PNG  IHDR!|k3gAMA a cHRMz&u0`:pQ<bKGDIDATxwG~~}{ 4<-3kvtާ=++33͌zAޣVuy&U Kʌ\+r|eccccccsp8xg~u暈D2p7p`^\)5i_jn^|lxF\_(Wf6666666&bccccccsE+-\ /"@(iYHykcsEA(H)ewǞFR4IOrh%6Ҳ@Qf'"8zKH}#]2I,K"Pw !BTv89uK)BZ2{7ǡ!&#kQ=(id#[^7P}{Vj\SR@H[x/q|L&ɕ%.7=+*9f.F],!>uZ6666w."@Z:XQIrEG0Z|.8)iK@shWO0'kƧ^8raBH=/ß<ǁ2o~o~akq;TeOkweܷvj WծBdwl|ܱ zn/S6WĺµW=?bQܵmt4+ ! cALU`YHt] aݨN7%4!(~,Aw2jj~RuqH`s'!˖Bllll.:$iplwHT/%U.S.ѯ˼R3J%EH%爎! *B39'Iy})P1S~.u;~1g ͜aS,㻷־\t/Y@$p+=Y iU2l[*/RjI0}՗gfjy'xM,4#XU09|D>ۉ)ӊ|ge.NB%|_'#-KӠjXiYBڜ:g=}P{VȲ}n]y͕!(NOȱyDbF)G,rPWHOKd ܳ"yBzhlR[WG3CZYj2{XtA$n(RTW1ˤQr:8G]}Asvtieb2I'H u\K@H\*J4 _paBʔ,&td \[Qf % (2s$Xִ"kkӋPF!xldpzD"!ܪ 9 HTtd uLþC'8q}='$*m[L kG)9(Jnn_Mĭb2;>pqƜ}ۼwf"ci?Zb "666)dBŁ;,%x;OAn- kHlwp/~3tg,y YWk{i[^{]1ׯ{,ƋwT 5_>_YĞ=z#Yt>K׀,掣*e-̢yߤ+`2lr}Yq8V7%ibɿ5.~퟿{?-V(t)@d)毼[Q p`{<'yh80  c)ԌtuX*9ku;~|l_=^ӂ==L; aҷ;?c,|#XTd6c)[??VX~6"Jk7߼e CƹůCm'63YRXr*DO GO:"?;{;m~wAsxtw/9gAb9l޴329GkJ\^cKR(>7Nqnѡ ϼ`ýmn iIBo}Cw#=OO>ʶؖ1i긁/}2wyi};׳~]]SϽɄIjp/=IDqvb]Oތ踟/~a9$qYu h|u/M hi ).Z7,P3KJi(M{CNR¼[1<5 ;߹ۗ֓t}-2yb%\ԷQuUR0]tP;}bcU7Tze~c 'x ,;}e3`Ѣ<~S?>#_k#_?Tj8l\ݜNJՉDČ%ɚKJ}ғ4P^%tT$ ;{E% N@J˹n8*P(S ttx^PhmoDJnYyVtq(*`V-], Q$ȜnIxCj'x;8M9sj?֧nY__n$VBpq#Bsi\^8̉"޳p҉ObQ(xAAyT6A`@9G8PTE䅘yEN^(T̛4MP]`?plb#o>e!#*BLy}۬q=3ݼLs;iX9Kh4v#jdub4M2H0Z~&r+A&0 %ӟrr,&Ge%_4NǪ"4ZE16x{>NoVV*#z9Gb2Ӂ>D Ȗ&t ߙNGbe\&DJ5=[$/tֆ@G90SvBt2JآiDrp:SQ-β\dg┿JpXwy<3/X֘9"`0e!kw,jDX3"/&*E p _0r9:CWiHUpy3=JP|/VP1!BbV !Pdv~şs0O4{/NR`Ep8+XeUhˍT|?SJ/|QEƽX%PA<]v|hKL/ҙxtvuSdάyOYdż"sfe1T@3B@ϨX9f_# &F-8^?~ѵTHIӞQw+ɘ3΋$v45,M4E-0)ተfenAsW75nL+PUUUR'ɂ3@Gb|$sӟ(jd)xfTJJfexT59p2ĢqRndx]gg#6666]?X$ӿ?$ 2K ď;ס{xNf;boo0ɮm%T*%F%JZ *;OχǫȰ7xkAصm+Gb%22dZ Z_1Dj1aS&$4*ĬDVFP1 ִ?,˪`c"@3R0W T'K:k*/o;Fax1 c{Yi?HBP榝Ko~{7#Q\y+nG'_;ͳ?>@VsmwsӼZ3~z TFQn"(2*Z00MYu@T a|Ix|xdgWw o&]58</@br\:Ʈͯ,Y7uXҀt}{Yf 0-Amg.0C1&LJ8zFP5cn܎2)ŝqn|wQ2S? Z%lw'ձ[gXrc?ł:H ZCzlX2P!vρ8Z[iis3>4L*fAv;Ak}7S,1xx/.BqӾl1-aٱü&?>FIۘLeг{7ma0P}̛Ikc-nVdjx>-zGX~Hq17O`f?Fs!  Cwg~gxy& e4Υ i ֶ||=^#,a~ُU3tx'lxdŴՅrl۸wvM\5,l't]خa??;W"o~+;'66LF&H8}B u t렩&G @/;zG ({Mi,%ڳחv~k|;ԃQ}o׬ei[c;63ha~{+5anɡo^ {XZb3(U-Jcj|㯽&w~x09ƢA"Ӛ5νC+;?:yinU4*Y=҉ qXq2yqEKVDf 3?[Y;)A.fEDYΤI.1¾{9;J`n֬\L9"0Ig>z'Q ,^ʥ]hoc;7;&NQW,^{/W3錣pw?IW\HEŬ^ \ln7)i+;)Y͒&>20o/shϨslgz<ݦgsf#lcccs gB.N }C~֞(Xs}Bl,R+M||EL"x+666666l!OӿMdcccccse!RVޱ(c\l!` !6666666W["BBlllllllv5T*E.U9o^Pz]L;6撣E+BlIdYqU#(Lp(t͟[()W66{n7ne !6,at8x!66WZ|f666UUGoEG]m.B -,|oc*ʴJfjRڇ](үR"GcYҟ v܉~lEO*QEUH,œaZy9^8=y5xWfyE:/ 8d!py<8UovZ8{G|.7 t&G!7q85. ͭ47DpkgW ,Ǝlg?{__ͽ+?LktlRgEW,\x4>KN^{ U^,kmegKRP.)KI|6Ch8>4[m1)p84m,u4K'1v_mxgM|i iBi]KGE $MJ:F} ~|m=Dz>t p9rüċ>sbTĩ8t5]ͯVjtU !$lCsCw34ABP*9KcC5-yc>ƦFp8+\>7SPp:zX}q%Դ.bŒ6+J!-l*IPBgY1:BA#Yd?~yGqf>-MM|R__ =F(E:appheKxOKq|S7LP4*Z/@dn{^09S+>[:t] B}ɴ̧>U3Us dQ WuAƑ*,]ЊOg.i=9'Q 6#oˡXֽ[E$IQ` a82DO[ċ4dSib %uDm$2ELUCU*4"EТ9P.h93ؓU5%. iP]t/&y_n>.MiQ.)t7Rgp&x%zc9"fz)JK%LkZG(22^}& W$Ӱ]-.vL'KJ{6<=~7Q~4hV-ȪETX,RҍiHia:aVK,rHP¬!DŏȒXAXX֑UQ.Q(g-v5eZ*KBp3oA*rwR 71:6Ʒ봵/3h4J_+wzJZ[[e.nYwCP,OXBu1(a2?3J~)3h - :*T$_(aW!4ʔJE2IBP%K㯭v P㓌D)RWI*:hDMs#~Ro!@z|hsF,Ĩ@$'F8>0AQ15M#],Xm)BXS rW n_[g|2SϒT'EYh>.cZ+jWM6.Y)_y3[_f;-"K߉{'%yW#:1}FF9r|T&G2>IHW29Z78�#ekZ;}G /}^}yCǢ% p3:6l[#|prcY`rȪx"!-\0[j&(G}Z'_,Y+ϲ_>u$عy~M(Ijds9&'㸛n|ڇ IXB*˅9hYx82$e%@4P}-! ĩ\?N 8#-Z% [!)$lߏV}Q~'1Xfu=+*lAWf9-yc^f|njgc %SYwvO!|Ӆy\JI( ˡ:m)7mٷ3@XA_Bv:'͝:](*n{pV1 Ţoup uwԸ>/DJjj” _-Yd@?o .`@JBuMaPUEQq:uf2cچ!-!yW,!Rq 8]N|>/tp8pz/7BNy+rI(5 )ࣾf!#O30X}ヤR9"͝ PK% __*(B 8[tVX %j"o}FfՁMb:qq)p*R-bEuu*iJ1XQp0L:vG麟 /I Iv9 nh,5]N>'"/@sp:$1tw--ATq8U44pD&)2քdqƺJE$i؞{JΔ37E&ik6XBdV~Ӥ\6hYc  yCsz¡ -͗T L̖@9`/Wsg~O0%3īߢ'QP)f2$)J&=rToZkx'?12:̑JωAR2R :KӪ 0>e9CHKNAZ)OO$/``!2)&V5rbәid`pL&sN%EQcsSa#44r.LZ8kq-MLR8WA`1~=}(?[5)狤q"R L˜VC5Op 8'1Y*Q.) nXG6O~$12ρ} kPb<1K=M+ %xÍ,jAfQ.Qc:i9F(D#ɒN&%TE*ɗʔJҳS5a0P)dRqFdJ&p-AAl2 Y򦛦@5T#x߷Jbӌ z#m.3Bjiii,AN]s58~76EXt&`/{vf D,Q>}u\=6ā}I a/a,#; zpᣩ}!49¶0ϣzjقLe&Z3ׯ\WEKa"[b(š;UmV(JF:7 > eRuՐر9z~N0,]y͍tUxcC=6L{߱RηRZ=w{L{ |H;x}N&,!dzQ<%]&71nXd \?o# UdV^{{B,O뜳ETE!!M&i&vG8LO BrlCdiomF:뽌{{ϕqGjHb}ɞ,a4mIC}捋P=ld2M:!J-jikxϋhx*n)A'4$repQgԭR5 JGt#EK*]AShJ&Xט4=(vRE` eEUQT /㘶WKH*lU; P*g R8\D"a<I>"qz=*\tq;iY,岉М!BW`Ec   iooC3B01%_(P[[;OI<& 4>- ,>F$N)I0nY$hfx2!5AE1&)y.J}uAQxQOצi gJKKb ]ۅzM̡?5 i5N)?){8Rθg}kB+לO{³ !L8;YFJITp=!dR(8R`0@ScPyܧErڔ&3ffynBϡ '>H1Uh#sEthsBȅsMg̺߮vEbD \KJGCGЪFBhydvk>3?;횪9f+x]4sa\.:;%+ʇq }r3Lh=\ K=}0%^s^1jcs!z%8$Zk ;棌-ؐ%sP85Q棊-\($,vǭ];<#-\XnkPR*^s5\L9\d*.*b\sɳ9*}%$*@T%hcs-c&]9BlIx<R}W:.eeB|KX,_`vU3( > b !6,Np8L\*5Ap88 .〪+] =sc !64W"~k@Nn [.+eccccccsE5!6\^.NR٘e1|\@ٰj>%mB("A^~Ήmhoã T _eV\Nrj]{bvȊf?BHAl;BӍ7rW9WE@V,)$.u+ȳJS!ˌ8#}ē)r:xܕO;nfIKq$:JQuU.(e&Y65X@BR*4" ^3iiv\}(2=^⧿P_ >s2.,͏x Ru(3ʑ:KBhZeN~[:-Ge&G{x [_,\e\Zx?xΆUq,SдN~܊/ཪ$LvO`Yh%0M| 5u~`ٿE~q|>xuA7ül[pPF}WSΌΆ8t4-X\Y@ 򫯳by7|~(T*qx!bZļy]475Q,~:}W[$( P>7e*TCYm$MXS&%eAu!TDϦ~Bb& ETv5clTǒrpr:#' ,7/|WKYG$g!}z |Ӈ҈e=V\ETJT>LàAD3Mwӛ~Ⱦydu#~!A@:68H* RZwWRSƁeUYUPQ}Vy#\~.M  )I;27 cz9X}C7AodgBZLHll$ajǎP4{!u~D?tTttquQ2/ J(}&Bs6!MaO%DŽQbbl[XɲW2!0= !.fEГ7a$䄻UkwF L`' G;7/ãXqihN$BTUh(wR;sDo9W#+'ٷ'&4v5^,0EWrx?%Ȳ+hp8~c)BX XIz7#==&4-fYWyb/_KgVs/əaeyYfnQ^xeshʲeKQezy<^/>{rhll=6-Ik5, Ծ81nJ[Fkĉ4pjMk8X='zI݋R>Ce^KB Ayr,tr666gy 2?XD:WM>zc+cYiٷW;_w nKe;o8P5;f<_W/ΖmoKOK {;?G<³hD iuq?/w_d8(A_ bDwd|o8K"1)NLR{'\Loײ :*y?5ؗH%Nl5Y-L']f$ uuD|3 IgFw/2Zr<&S(L9.cK?goh 3,s(M_ o/!ݟʖ M:6O&Bv(?36&#uwތ:pa` XWqnHDn~`9FKধK*9P ^/q"^ {6ޡʏ~KzS xqIC47YNS(Ƌ#`"[DX(ڶ:Z}C[ٴ77zjz|+w<>(<oy K9,@ -흸5 + nS_&<jb~W=w hAO䱄3Ö_=q?n˖o?ጤBpc㛟]GjtF$5έ987EK2Qh H,-4na.h(")0M,,?$ Kc*.[=݆}'{yzx&Ehl㨚T:P#hܸ̗ 8por~/e_N{ ˊo[)|QE^%O07{R `E2nnEJIgG;wv+niB$NOՒJ)JJқ-{H,ңc+Z}d#&>C4Qhn?F갬8}vvsV Azt"$3LsrjK6 z@>\FX̓#,m,Vv~cyID5Ԇ @YEx4Q,šUTpy|^^Np3 _#CoiǕe xp$ 0ü;Jd݃a#,[0}m>n@ہ"jq:в~ 6^TGK.ɒq.ƴR"tlL̝\QR944̢ۻ iZ8kvOb4X+Čpm)%r#ۏ5T)mh){q kiK(@s*oM=.7fŅzYc(G24mN\yt8jRv(K16nn;^y#w?D`-O,F(:X(agq4!BH Yvu /;DѪ,~RJ|?ڝd_9+PLKʙ3vוlʙYiD%9Du{p9sjiY覅 pp)Nr.o .qO=xLYi", -JYRp*3ZD۹厥Xyg_e9-u,nTEg>ˣ ,r#+63JsU"7{WVIrds9J,eYdي9v(9'l.9"T?ow/0:*l?77mp$<`\1'FA'}15Gزǖ BiADɴ*Q,lo*;½XWKLL2C>'QҸ_~S8 'L:-b{lz Hl:N"W OkÔ"f R)*qϪ8tìIjՋ %2QT,aiq2jUw5a *4?'yYWqdO)xUŐP Z}* u~Vz381VKYEg}=}1g cM!ǬEC@5,T#R6MR9#*Pκfk3Čk+ӽ,kNj `xo_K F@|2FѼ</<6R,=M"&BPP(z!ccD"\ciIVn~7ah H&n/:jjnZ5K~So@S5<b4JE fe3"m͇șE1$W|sN061Ii"޽iUZ(MLg7V4Brc^ߏ{NѴRleyw7xٍ,j ˆ}+7~xx*sldWCe12,eӏxv:&gYR4ٴe++h 3$1k닏NԵѣ<@GP#3I*dL:C,lE;% .zYSj56CG-z5N*w&LLB3Wh)%%|g'~J[Yрǩal{-<ʏ^|7rǶ1Y§ HfbdK! =6O<dmW#=Dd4F~A fzDt"F`֊LNHSDi67LX"C"%+VRDciRI"-u.r8 JtL$}89[2=_3u 9~]4I'r4-oZ=:.ϑ#GymLNLFI;hYsp~/dnb [wq666pw"I|IRXtaEAu<,h Ly-\:h(4fN7FrQ2錸p/ݭA0KaB0--=njiuub:[ijm  ׆ini#@ 5 Ɍ 2Qׅiln]1- SLsEthtRL;w; !(B ~ #=I /STp#Z`zttAnNwK, \0zsȤ3UtSwϢmԜ=Wڛ;Yl> $ H#m!hYu+:inP&uBajZ ׵'5b2Zih& h 4x)t<YMcb|؜DRynyOi_LHZTªܳ,Gd"1]N̚$HDU'Oi8rf$< }_|DmvN'J((%sB:Gdf=g&Jp(ɺXV$)wqPĞ7Bfk0sd~'erFMS5}pZ#PGciߞMiƳ˝4R$l…YpiOLD ֞!0 F) n~&jjja?B fҦIk*\m7G32'}N+4_RLbcs $L>̻ x$: }fބ%Oi|'- skg|*iLs'<:>8_Y3:y/FAS(. ˃[wW.:s[oNq>5ӯ9Is0>RJ"0>%4hnjP(N׋?>{~8eި66)C/ Yۡ~ XCӨk3_lV苑ex#Ls~Xezqj OgaֵsTxG&Dht} | o!Cmllllll>Z|166U*µb:{M͙4RD>*t)%bkEP.먚z̉a(rL{&R0L+].JՌG.G( [fBB^G4B͇ "BBlllllllbccccccsESmYR)r\)Lx B(u|>YO:Ph+5-\!dHi12>%0])%|Sr6ͥCr9B)BlYLpv,JWC( n|p@ZC*J / (õJ5ײpg[!H{ZbEB(ih(r vM#:՗T_kGJSl7uU9{D(X廹7}ǰ$ecMS9}8#}E ,c3ȣ8h5 M6782"ْS>!f}$ &NJKc nrb6|iV~}-/TXDQ+BI:#.` o Bm8@%$dpm=!w,%b~= %|$ahU!2d3YJβ~J,\8hid 4@{/Lr$h Gp?ɛ|3qZ9 ,{'hєIRxIW]qd_}+#R)&x<~bTĩ8t ]ͯVjtU X7g WzzYe!Rc{hjlM\J)H)QUC@U8uV(h $~zhE|lچS6%_6h#&O吊C1EQmgtp$4?A:ir cB5aL$ 8CuA'zHP4M>%f\RN癃o[5ʺ#-4ٸo|Ѥ)c-`RS.,gB)]qn†Σ3$'/ ^o2/|B ?|57>:?j{[2°-U0%>eZC&WoBE#X*ƛx455C "\x"$94J2\\@]M-.42=QJeT429qz#4v8X 4 FQZ2®,"Re<+YZOea  ,&RfQ`th" }?X8CYPpyQǴLD—Ԕsޫ0w=Ol<IJ%8XiX$زnZDRoBB ;XN!'_,aJ*qbk|7L1egAQ{r".ykLWeG$-.vNZ%KUdφx|6Pվ,V-TlBZE ŲQKV;uhKD˔ b&LJ|qW@LLKVA!OT^.('VҢ\,/MyAһм,vn6[d:7"x(ho^f|bCIPO hmi(˧+ P@KEɕ%Hr48}.@"-00Ϧ˲0-2F4 <-U-0ͫOfc3'2|R\YxB!|)LFSn@JP$,HS&5=g((X(5^Lb|$$xJbF=^*161A]]-$)% 28OM@XIv>I,_6z)C=}}IB+7;,I+nlrRL츎.8ќջᾨ썛 UEU&:hx.0rlٸo,jEH딉_6\\;w07pjٜNÂܴz>u+'yg ȷ>q8o+ޘ+sqa6bM',Cτō=&{|sM15Ǝosd\{m+ŧ&өH(խ(XmAܻI>#RW[Mowx쑇x<XiY$IB^gΉ$S*HR՝( -AvNx,Ngq;pb>C2'Q~.^@ݦTĭ Ktp',[JWC!-Jt0(Zښk?PlcF"TAU0I *͛h~'+/ˠP(ar'(sc:s碔)R*9o::xTFsLtvũ!!'].|>%i{@ HE<\JdpzwY~ <([ȱ7iѳE61SS@vww#?he kcetsݭt3Mag{ ,,E m3i< < ƒIkK3ǹMa94Գ+#Q1}/R ܾ Rcdt\2p⢡@ ۩gh(i*B̈bz"'#5ijǪUKx6Z-]HcE&:'H&m ҚqUBlO)GJ%jn2#Wk,Q@OKUUܳ .)96@I`^!P$Ko FE7ww~<άͲ_~Vj TƗ*BG%TN]HSVVϏw,s !lH؏ 19}N'&lN#vn䵷QVĬP*έS*Rũ@H-nWqLj ӤޫX($[{y^Xɒ5{ YppN^V5睥z<۳#+8lXiH ﷱ(aЧJ8RCnbݨ'rR" $.eR(+$ŢvQ U!ŲLJeI(EC y2,bcߺo78_DAQPػWIߋw[c)*fn&h]Zy{/ #uw>]5P qF'SiJ ;_9'9|;ӏ2U0p0iqcg5=MCpwʧ5s7FadIйa~[Dz z'2j3o۲{[{94GUUrc;5 0t ?vC#DF83H\T,bT5*aU`"-RNXUgjpDʙ)e(TB#xo<]?,B /ǎ N˯?zRV|A3^g&luf(0͵^%?K쬊 cEXIXUXt˅MOr$iJiXBR1F'd2)b8y;`f&BIjT,"5/BQiG)IdE.FG z(3CLJɛ1LP0$#|:Ž",Pʧ(!Gr LN "Dh{^pwϹ6+.V.9rzO;k9AKؠHc#?K9-^JЊl?iKĎ7cr1b<~6c Ud`^ 2exsy(TJ30\rQdGJ}}BQؼ]4;n: !膁{PD~RNG}>\.Yj):9Ask3>gEY('Id'|?RN34:A$CNdb2EQP4Q<>n[#1KR(8~B~7h9l66 :xd:M*EW44QTK]܊N"ϑ-+447h`$c$K*u\릜Ke(ZZCh[!L y QdbDT&L؈{2ORynyOi_LHiY&ΐ+A{iK)&(@CAJ 'c o ]U[LlQ  xb+l)2TRh ES23Q,jL޳$Jrt:CAPUExݎ4SYtKh.E"-|&I:WE8li2y׏ߣRN'n=!) 5PjJ&)%NpЋYȐH`(2d] Ab.M*[D(N3D!H$84榓ڕRw|]q_% Qp]RJv˯βeKxB01%_(P[{l\dӁBUt _(t8xP41t u}ZbK&hN'*&eBs8QAIבR9USutDNY6@QP5ZU$)"-|A22͍:EN8)6x[NYb9Sf8YB@Tfxd ]immwǒd2M803pߜ˅!'`Sf^3PsB2lB8].^y T?0E`~G{gly(1RIM+dM S'^ Ζ'|aF0Ȏ39_ߺks)t.D%:GU^6666666W["BhcccsN\ fճ~!L[9؜eYUk)%T*ʼn޾RHL" ^NnB\.'LK)%.K h !6,Np8L\®3\.&<G7⢆B5t^xAW{=ll2l!^mlll ք\TNgF[cccs5c !64a`&WaD^s>ؑ166g/k0ӧ^mH [ )JLXubcEQ¡bsM"@uE!_7lt:iӌ%%Q~Nl|P,}EB5j\+UX$D쓂ml.!>h4JYx<H)+E]4u⣽ IJE& 4Qj9((8)f!ei;Rr3Y[iQ̗HKk%,yoR344IJe-AN'eJ>é3ghk]56!$}G;Ͻˊo!ĆP@yO|[R^CMܗz7hEGUKJ]D*iB[TZe!@ӵ®UY`v[bY0q&&Sh8&S)FzDcq,,<xƉU8AFaet8lپcNuaDYnƋƚ5jMUB;&,k0B_Ϋ`bezT ]w`88"~BSZu+yo>T7Xv7?gvz`.5Pf3;#cF!D r7?&߽RȩD9¬Xy+N4Zfz]/~Ɖꃵl}x3A'Jуմ.ԑ=d*+qy|ԯRT.IwW'C JiDjXR[Cx?A8s,2\1y9tgJ_W} BFFFcu0 BWĉ9s5kVZp27ΞW_c?ܲsRI =@Ai%Pz"mItw%K)-|m>1Fg9*,GόqQ: yp^d>>2 ~-ٳIiAV]C;˹vjJL22eQZU-X2pJ''/ D"aJ"ҙ C(eW'`[S8yQ M~3:ָx'Rh\+<l?]#X_\wԆ(3PO';Kٸf ^ dUk ^ɣep@Ir*XA`jfDrZjиt7 :zII'MWT}' B-rmbB :;0Ԗ.k#&}'gS f&R|8 ü8ϐr{E~$@&No1bz #^?4/\J@O'.~ݿ/c>.{M=?y#Y$G>=ŤeGy7޺Y1M޾>}E,!B)t]h<Ԭ+ϑ(}K: Q0 u-e%wN -b~?8Nh*+{#I4]2p|w;O ϟ/_GG2xcw9 f<w>:q,bJ[fޤ$!q&` %MY,ky"S|d"Xvr2*͋RQh0ߋsgz10ӓӸf)8?C b?5[Ԯ?!p`q878k'Gc({?u9St8'GoJ2pb?O^;p~_B;_ه/%hXccs qi*)i?/,}̓I aIp No:J5У<=Q>xk㌍2SZ]ߩNk{dqcj*j|-^5?ڶe ;ڼ|9,M[/; [l 2ȼb-l_gvcGs;7b\RPJzp:LNNiLsT 5ᕟ زy1W5y4rV(tNyRʌ8Fl{ RNu[[&+1"FKg=У__dwfuM H&LA$G(Y*ɛ" h<e%WKiIQShD2&`$`XjjCm SYi2VzIL0)4z}Nt]cS N`Jb+/9f %Itsp}Ȏ04B fB ɜU\z!6=wCݨ@5[{T\^8y]dRl̩IDATr>cTqe|;k3(r ȝl *ԆRX~ߣ,G`$y  ғ>7mXY>+VÅ2HY\CG9u 4VW<#+u(zGj߀5H]J%bH۽6lvN[jNvM0Lp/ؖt?}:f6aOlBh4HӋs t%()IyqJ,16sX4݅5'RFˍ(ς@f2sLL4ųdWk/enZd,бM JdNu@Ӵ楣c=kGAD?5w@3rF, BG#iZɔK_|wp/<Й?שrq$ŅteRV *ZR#Oz5cQJxyٵk7P'OC;s}1kԄ(b}Pc@,Sh~zd`Y(sh>~q,f-$Z/|xzD;gQX[fYR"5KPPh'n܋NW)`ӌ3T5a( Ee4Wo+6p8H/c[Z x _Ƕ+Q'9rj4T헎ӣymTg=p@Ҫzj+)/+4ש{8c7Mk٥pɼb<]AC[q܋g]|C& M[0%X*=ʆYQ_^g+ùxoGǺ #1ybg;JMʫ4 Hg69:UmضSIlݳwfwUI~ey#cc$OQkl!~ϖǞr'&%Q)4o)7RZ V#NcN&S饪7%[L/?bm5qX1G-+_y^;ĻԲ{gvq09'9:J"ҥm8~gCSȋ,cc$s%X1&&ƈM\zQQFƣunұ F'LG&s#Q1ƧRԔO3XGjz>8#TVO$|BN[W98Mƣ:<ijk# y26߻Wz{XּPR!->݋^"3&ѱOIb1i.ꖬͷ鋯rjgH'>1J4@ͺyzK;x$zzI RyF+y2Q&Orz=SpdS_ %:q&bOq21dd4JK|b8(l32U:z6.÷jj [R>{3ٟx\~eF8==}NF&׮dǶTETUy[eiYOr"eTHFxJj.u7Rhj[ʖjN9^yM>cvśoɞ/gYm Vʙf`phUxޕxnOB% *DֶыkÉqjԄo[Ǥ) SUSG@$8?F(PJii9uA}坔$T^HjޅW.!|[R |i1U賜' o|O/d\1l祼ʊ <U4 6Ӗqۛiך ʦMrBɂɭ30%-LB[g4}VгbA͒CA*BJIWrGG>g|bϏ?W5ᒀ߷p$3Ôt@bePQpa+gJ7]iLjmzQ0/Q4^ +_`ejeESc̜NwV-MU =m%*דm66eY蠡P(tU>jW"мoS.?XgxR.o)kIZz!&uDϜ:4䢤Z8#sҜFA>:J_,Mݒj9wj,72BT\6in<ϜrL9֕d{&k~S:yeMTRb.r[] !8*+=CXWai(O"k7M\Ner:@\j6]լq./r`.>qT yuϤue_,fS!͹_YsR3ml*n# %ٳwvyo'!Q'7-E3W3/Q F;*QR[ru9gW7Z666sQ)+OS]SGsR{y3Bh#u[ۊ[t|~%B8|,()g&\䠔der|vfLY,0!d>f޻ՙYnH!f1\;DNY\.5*-ܕ(5l>O.JiY8vIDA(ﮯ `abӉD2uǮ[Nu1 !(/+vcΎixB]sUln l|nu\66666666s[-l!`;ܵ(Hds[kpz=НR\._ɮø Q-ܕlӴw"$S)2,^W>11A<@hw^[)HK)+-0_]-M/)%XƆz;b $ՅpAl!ss/kS ]HNAuTH)/|EpD*\2hs!%MоEƢZu !Mѵ!$Ҟ HдEDʫiO@'ۏj>Mt K^0MG״aY \lr2[ͯ?F "⊽BTaGHдbTiI\kBdy9p nѬ՛qU ͍`zGxNBct~&S&NGeM-5ex(F:>兟ĚooϏffeZF>vCi.ꗯc]k^:ʧ:I k6ofYM1+1! ;/ _᫏sK !2adbYi~HY?dFPѴ+(v\~,]Q;wɅO֦2X @|r9"Jp:)-PWWKw!9ŻoCW:ڕK(2~ zrt.9in[GSq:^HO72)AiTҦEJIK6G"p8 (,Dl)Ahn MBZ&ef4tdq{0)Zf% rds&NTUUM@f8OyGGYZ/XV=phjR݁휱_G%-:N"`J  }B PLtn I&!o*NNǴ#@Y3Q.Ŕۍ׮1`2(Oֆrڴ_:d]KJFFFr477 U "YxARj|2&IƓg4v dyVwʧnVG XNݽ8,gL4S_83Jϛqp frYaYDr0M|1*~žG۩ ڜ4{@J+hA݉UBXDCQRY7GL Vct1",537N,S !fX.ڕ}bllDP|s&\0/)g4IMMq+ɞ?;b,YgN{,C|qR8 Iu[YRn8s`7;к1qCGϐcq&8~(''XЗ&(8=8vStFo̦F %h?C#LY^xY31p3cxxl5~q,OH($ZnH]h ^z'O=/cwXV]\r5bcGr>gƓ!1ۿxO2>9L} j8CqAmmłk==Βyvqed$ Zf?8nKkJaZZ4T0t?S COd)__bW^7pyqg'zO)idI:|aM ,kT2`$YeP[q`E1r5UN\N'#cS]UU_ _nНBKi11ǹ3߷aQ7,/ˏ^h(Sz~R7K6&S!J1>:Q!pEֹN)٩s|,eNSyp~- __+A::8^NxxζM8,i k3,ln.n8n}rL8]tn̋&t=p*-'ɱn.:Ox85_Bĭ-.#ϓT*v6E/^G~c/韟ݓ ^v~]G{6eǃ[(1yHxgyzs.L;[{*޳/>G^凯!o䡧Fūx#i9 @';OT_eR;go~VvY|ˏRC3ǟhO/bc0B װnM+h N6 \Γ~51~8<(Y!F?~7? iH3EIgoC9Ssinz(RVZk$^,+QF%+#:)t6@BN T7>KYH;oj7lG61u}v  "˩Q,z*B8@;ˋ?Gz0ѐav+;X8(AgFc9U8J2| ;ycGIZ2{S6?5MeH~uٿSxds/d6SOԣ[1O/OZ$O[㬿wcN>898?#琁ZxY^_@Oal-\Fe.Byw ɩ)|m.Ycm1X piZ5k׳-Bi9 UNVe]0O/D(4 k\BaP~6W$ &_h.k""4 ]׊%5Ra+5Qߴm[VCC2kix/* &GH6RAIY-+WQ_S{$ftl kC.)VXo7)nfT0ˉ1WQiZxw6`2':5&t'< /䔤-A.oί 66oԞӌjZM_W %U7y2 I+f BqpIHuY+[?~奮+MfVÅOSbd(B*\l~{WQQ@Ct6i)ܡZږV,-aMx1CWrFm1J^]|gZ6ǁu>95ik@M,AFZU7m l|QF2暑R ig$o6^9'#駺% d`)Jr()Q2"@)+TJMo0bSA t }BJ``"ZF8g<M)ctgy\\,Tgb 1(+Pw OmWQ%F[*6ߡ@1w)B4'˷=C붢Y}4Qp[Ȧ7є.ڜ|ֵpy N4RCb!?G 55LJJ]`ǪP] EbV3f8q.()QJ(d BtB_@姮T$cQK}wP5](MCc^ . L W)4_7[v1ʆ`O!9M,2 =ewt:϶*M^9ExJ%BL+phnv}Sy_0t A1.ʂ?: ք)_.IX˽S! _^M$alh ǖԊ1O"9M"f@h%%R('ֶ6t]gÆuͷ>pCBnM*8)eñ` qb\jJqϤE+U@BrQ>|9^y5% B8r<:&K;9y΁Q e!hbdVgd2JtDR/PP\/a=nKd2Y," ΩWU<ɒ9^}c2rKhv !<./ãș)/O2Kz2ΦU4MTx|"Yf!|tC8@X7y"$Jͩ|>O44RHEkZ0 $nUp^(-Ӹf#.>8-<y8=)uۅLK@hЏPEkG{b3FY&U sU_5ۿSyeAbyUwgS;Czמ]IJʫ( 9lEd#\Z]|v:P̳`ĥf*f$ipYd!TUU8iXwj~ٯk{[-[6r |~NF>!V>JXJ"Y<'Al^p3 ]tF8T>G6)̠,jkČ#fEH BYW( ,hԵ$&@J,%71eI'@T208L**M*hכ >7 ZSQ2y Ũ8JЦ'TT5j$#ǏdiLj&ӅWJ@ KInFhb<%NlFsh}]=zєy}7%~~&P8*㤆Nk>|D2K,6d P*n.! #ƙL@ Lp89mTp9Tm v{h2K6ajlh*R SIrœ*RB4֬^Ŷ{r:ooF*&g{CYy%AWa g?]{O2R]UAI؏aIS١.:zܘņOmy%Fd;ӏeUw?/yY+U4>z.uiYoM8|YGeёAT%ʹ,n}8,YLuuMۏ Fb&Ս47TPR@s\tuup/XѱQBP1M>(MM}jrVTꦽSgrή.֬Fr rsjY~"ѶTa>=Cp9 "Xv~p 6Br@%M,o0v0)#EKk+y{C:&TTǼ12YֶW U|~$ƉN!vBcll !4'&0 ʊrb 2R]XJUa:TiTY 3CPՐ4M1~3"j)ST77aLu%K. Ȟ?cDsrd'j$RVEsUc?r˞PRJ119E8 $(+h2vNwpήse[2/=<݃) PUOQ>ܹCYkaU<g LĈǣ vq~v}>{{ܷm u4z>Az:U<#,a2zgx"DT,5͍02sly ~OvN//Y<IJ)',۟ټfTjK'SXN^nJLjr(M8({d wTXy#"I0EIf-./"M>d"~ Mx@(ǡdD* 1KR8 5E"%Wx|AܺI&g;\DD:7Pɚ7@AL2N<4)Sy.P)s&&()vM&hiYB$YS!I29 Mt׏eR,x$ch-V:%ʃ$ vhHqz:T,h1 b J7¸5x,F:px|Lh?PqkME   D:NRBZ|0Ȳs,h|:.MKz<"~+ #1qy197Ex[B=l*Ag޺kV9u9]z9vᷧ ri ,%||> 1c˾RJ'&!r9)//}U'+zQ.K=?MgNg^JP@>0ymw5B4\< I*gQX{-g_RcB}=t{yKMb|_!d[.{[k{Nst9iGUt:/Qf?B\47bVLȷpllKEBt|_`ẚ.tⷮX~[Oy\W<&x3?Uwzi\p?s]\"?V|Gk,g`u3 U9p?l?{W[1sAA@]85{- w>C~.8^UF/e[𰹩,ܖqWVܰjS sw\'քܵ|n˟\mlln9f̾>\..Bp, |@6t|BlJR8<} 4Ma'hcc τ|XyBlZt]bY;Ӧ!u2.~?]/h-n/#춴Ol!`clz%\䶴SXyBljL4[k0 PqRBE4MRԝ{ώRds9VW"0lTE.! %=[+B4`s$Irr,3G2&oݹ&@/+jTLxGޔK׬gMK-.Mݢvwqfm 9wBd"a:@@ p庒Y;OsLx D8?î淿=-hSPY%>GDqW66@;Cd:xI."dӊG!S'w:^ͲM8eZRB_0ǔ颦MR  )+-̂d&0tiWpOs~͊7 piH@3ki0K<5O P L;Y(1~6/|8_M\W*X)s>Io NGju/!oXY*BJywK>MYi uܿv]$~|V|`5!WmO:O?}wO 7~NwB1 "5!4ttM5}w}{t^($*,B2x#,40g:=  ںMÖ͛شi#׭EN&,Д#oyO7Sk!4ex5Ɍ$8#4Wٶ1RԺjE_qe[b(@29ɉS]lذ2&ѱ!F38KX敬kå+F~?1rFdװWS,8e') }gt׸x'RhXëاtlc}d~emԆH3Nv,uK]\dzkږQN8sYVmŠ0(P${&ɘ5-ԗ)6k+e=vIL;FW,@к9Jȣ %XMׅR \R `\XքR)|{'L/Y<7>_ziJKJnHM"";ũA}T  46E>yd|_r>ji諿}ݘ@XiN}C'0s,-!?x" ;O!0IJ)7Dyy)aX1{o|x; 9 Ͽ1^LO7'X^WH3͛{´LJKJD.**&`0%K ~kr`Z)LHd,h89Wh0o{{10SӴf)?S{ 8E^b9 'Nxp{4 qw8 &Sr,&Bh~U}=:>pY 8o))\RPJ̈́ݒ\e/pBÊʋ0XWu%;}g~.Lmrzx9ਪ8 jxSJ#>ȓ_:|=VGƷ*kcϑVE#e:`ͦSo}PvOۇP8hc$f1é9T1 Cs㡬]wRC5I0hF]ÒFPV#KGS| siVVxIL1:aҲfO N/.AA֔Ku]e>'3{sbN"=4U|6sW_K.o(tyH/QJQ (UȺ\Nv/ u7L|mPn )cP[:_bf3m5`vR$_S_">#mIĴmYsq}.t!Ba*<^y,1KR )%pq:2bWgRJ(m&vObtC[s ҄6KyM1܁R)%Ng5QdsR p a  ӺPXnb}te(X+Ĭc|& y]:HY9^O׃ 'BEA+8.|>7nw׉.p).72Cr-GMR * 9u%74s]Fc)Hɜk@ӚV)Mcql`ԮA@YO3sTմO!]/>$f*)Ȩ6677XBNHgs ܠL|'!\D"i?-28}B4MH^Q3QPzM7SAÇN.> Azp=nc}EükG:ɡ"|3NIիy-9E*@*pX܉i$L]vESm;V"H9@*x ӲR]`8tb_OsY{PtL^M `(ݕ1MkVJ)E4j2P@Pnu~dVri $5k7Cgw~:sVԗLy|?}X׬扟`0i6;R̋7mln'"+" hi(RDl` %*$ɁH+G*C\X<>o~I&RVk6(%Y(zlv})."' okn8Ȧ3ĒV6C2o!U>{_mJJ=:R-A'̿f'9Ӝq̄ ;@1EaGYwVr>W{GXpP(|ѧ 'R!t:^V&%5:Ϯ/I(c e4}UT~P״1G+4Dq"ɐLst1-taџݎE1tܳnt|R-ML4<>MYc8C#QFFƮ'D^]DQDC:QIGv.lQRjZ˶0Gۃ UQr#P |N ٲCôM?WR%.acI9"IPhX@vS^8 S$$%u1C!s=;HYP:s&44|KWmK˪4D8=0UЀ'Fز c`?>ƛt2>19ɫA `e0}qGo4Us92UX]G)Eb7zW 2"2xE.7{iqK16tcddxhDf#(S##LrTԕWrkvR[QEcY)QiJBN**~poamm% {Tl`m[j Q(4cϛ[]||iUis>L;ߜ+_mˁelxORgyGx60qv?|DyFdž!]Jaҕ~cCSюs<$sQF'GL\FQS E1ܤLĘ MdqiS D26M||X }xh$e5Og|l7 7B]Ehx7G<`hx bTVT\ORq @R-5hT9uqD ,exexufn>*g1xg72<>A41X,M}j*| [UCb )GJ6PaK/ͬi)E%l޶dcskQIa བྷ[??`=O|=VIyNʳ-| O?p}տ3Gq=ʃ(D,ijWo|`0ȫ|Rjo9ff6?_WԶ%Lȧ_b_cEU ]*\Ӻz5u4,$ 0% ml۲CemA VRZ^EuP?qᦪ$Beu5P*Z墮gf,W), RQIYD'(,.R-+R+qt~%UMY Cvq]=A"Bttpj``ή.JKJZ(_uYPBzbށab1hX׵qY#SlaW1K($RBuM%Az*dyYƒjjj+=ć᧴"BUuwhHrj$ܔVFdpJ*~R'j y^뢨"#Yҙ,R]]u꺎%K06>N:9SDdCAWc*ยƧRJ*F{Lϳ9*Ap#PM5\ބ/REcS.5jc%Ҫj>Be54ׇɧ#5^%56T z\Ͳ RYn%K J)%=c 5݁~JVTe ,4&fyز!V :|,i[A 1!clҫ/袠i55(;NP_c<}bbr@ YigP LNE+_@ S^ugTGX(RY(UTjU i*).IYKV ߟe3+Dp,: 4]CpQ5ى^d. i͔ x"A60TQYQ13]-FU]4,ZQsf mkbN\hm-,(iaIUh]Cs]O\T )%oA)UN~E+>%hZ0aj%PXPTU(E(]TfG@Lj7f8b_Q3 rH)bҖG:;7ϝ{VXY& ϫ֨kKG'Ou˦y,lg'55EyJ$u3R R8<ߥu~/cشi-eլذƊjV^k !666+n s666WjccccccsK\acllnse !6w-J)R4\Vg k;cL 6667]׉D"\EIBlJL6eZ;2N@""zj ɩ)jjq/hcc3t:ȢD]0 \n()z^|%N6|_tӭېkB2rm=-5N:j'O}ylm휉" 208tAIi:e Nv6֯ZJu!H׉ ~6t.9iZ7 s HCQEgaXWGyERu$n48:7IAC, h8 lۼay[5QxNhga :.euk=a,uc4U4WZKB, ?m>7|qmD2ɓP jkjYFF8|(˖P]UwSg_#]ċkBԆadR@hWx%Ow# v 5'vPŲ 5 Mfa'D)B&%q*Y׏1Qbe339v4IҘJ`Nn'2&#.|\6C޴P=n Qa ,,%AwqP(!4\A*38R]]$g ?^eI0s K'MҖ&tK)4݉1]\JZy0p: &Lzp!2M$Bd2BzH24YStq94%.e2%^\qm}@ip:{(IUE%ZYdxd|>ϒ&CTUv_ "1&O8[$ bi@ZQ]Yk nV6 h8,gIg7pfE._hcÁE&!gih l)Qhƾŋ 󌴲&ӔTvG9Χґ - EyOo6|z#|WO!9CWL11}鏁!36ލ+8/7k//=+=ʞމX^dIyceTN>Bǐ=<S'8|ٲ|_Cfj԰{=s/7$u/\0f(2::;Tסsh,F>oRS],`l|*tJ92JdʈιN:_ !'KyVd,AzQkW9ۿڃBs  "ϙ1,zj©$鼅X;/"JWhMoc9dQ4!B@fN$7XTHOT7[}&ӘJe=[׽'G_ea7256m9t >Ŭ\[WmmWz~/d.A¢.Q\)Bֲni 58AKb 95J,1C(P(T8!SUM.AHchg1wG(dQ[ >BBC)R鸅aR"tHЅB)&AM 0b3J!ltoz=R6X`-*&90ɉSyxY̑HHM2KaId;6scx*ufмfs?fϑtwr)2:}P>8~3=A"'>Ů3wOᠪ~rRH4?_[tE2{sO*ݴ91D58:gG J˺ap F8s] q|L:YjHS5(Hܜ*DT e)fE았R"-F[P&%~%rH)1bUFH > C`ZF+tC[˂SSVy Ũ8JZxhS-q*h$#yc_'+M&frlD) t?t2g9~~Ξb<%JlFk~G:NOO'Gb,eޒv(x>]ZEah8Eush'~1K.b߱DsAv*E "4W;wG0h.]̣H$6672N?y̤09ʬϤ'XJ!t>Ϝݔ"NH}3OLR vMe H2WL%V>C"$/tLJe|r$I0BII&'Ρt'`L2A2cp{u,pt$dt@fߍIKfB$G,T/ OgAsppT*7H#=7-.ȥ" RUY1$)$p"΁IWǩ b9I¤g6z.rd&Ng$)NrC), tD*8ȧ3(Á4dSIűy(])%CCC,[rmccsXNjk>2H84B _"7i.Bv<,,dB8j<\l]y~39ܑyFJ##c .'eevz׹|OKq6w .țݗ3/t:w)!v#aƼ!dl>OT$(he%do^r,^4Em4,̕b !y:F]c}R\|ttS8R7rA|udgznA4(--Subz3jaЋ4?xF][mBϊ`eRy΄X~qvpQ-؏>hcc3[eb.]46sjc/չ:B7 /_b/lg@IAlt6666666kne4Z!wɚs>7Y Sq66w2LL whӧKlBde]{nжX5[+QJt:H&LNEȅx;^*j|O/sg 66w%6gB]dgkZqѵ CdYmlnۼ[5 >@ٰ\ZW[pll4--ք܉N;mics-՘I4ou6C7p8a K$R*;\͍@kxEĞlZL$Jwr9xp8J) Þlln0y"Ȣ$iV!|M:;L"$t:jӌRL&ҥ-8 +_mcc\.GGgpxQ̟bsעCp'.B^og!bcsм;Wms[#4 6ws(vgb !6ru=g!.rʙJT0yi,"4 $TX,F,'H[p?!4muv'ň$Ri]&ə_/_!,*ia&PkY˷"N25%-G4h8BC_9Awnd|u$S>xІ)PR2r#vⷾ i)E圢ʪ LFYl3e\".~nGԏ t{^e,qXpmQ@OO/==h0 TX˵+wKyh{{&ux{cWwWWFL$DIV%3ޝ3jx{l(1$"S7:X]9Q AHF s߻{y.t$av>3vcE}qE /"|`g[e#"~rAN;WQ/MJ,"B@ 9j06p7LvpMr G;O*Ԋ584-i{ 3>*ʂ8Rh*!B>9I ̒ yǃ{Fqae۝,y7/i$R˴$if֬21ҿ5 !%e.0ZLJxs-ɥO,>4Gmq tJ ÄҶKu9R8V p80ML&COo'NdUހ(EߡxGs؀dG8>!, tftv,˚n ʜ,]ф4jz+[xzEg3Xld:tѬ19|e$S)FG|$)wl ׇuA,.lcYֆ]gK-uFK7}( AE7iҵ̵"XR!DQǖe!)U4]3MEדB<\"d9 ݴ@ZH[m} q:{e HE]s ibQlog"`,+8E{p37̩!I|b0=KQպ maCݜ!I nUj$>CtWE=+Z,Rqz6Iwrf`OrYF9O;0uH*mY5y]ä󂺕X^BL1ؼi#)u59~'Of&2`2^m׮)gC;=Lƴ]e.oҿ q;ΐtղyeZf>si{r)8H 6oڝi5bӚf6S#CF * 38f6`HWfwYFGF)A"p(/7/J32:FE(D(TF6chx$TV^!ڈ<9`{"c@Wp_έ5Ngi X)5l` ?9ћ\+Gw jjXFwes^~+3M{G;㱦9~ GsF6Ox,IЩm]AcOQ(>..jPDng6?u!H? Ǧ RS+<xK=o?߰ l/GyŽ N%IMyꠠy'x~IR9NɣM~+#'~ģ?{!Єdi0Ԟ.)^cϼvxi~o7`"ЅNHw<@v?29oJ{!R'ֳ<:wZA55x^ \fMM$I<HWpye^ykf,~,Sz R]ooéC.C?S~qrtc 4f1x5c?{=c2Ӽ?g8x ť(*[&fd 7orm &͏Mw$T rJ}nc|m 1?N"`+lVom?0չ8#ir }>SI0xUƓLOMKKj[)sW%"ҤeÍrv>GhgN6DYrnv;7oƘb^zu7m85x?'Nw,@ D"AyyX{z:@?2#iLcRbUj>͓qkhm[Ͷ;n=t_5q2[P\Aw%䶗t"-+8ӸZa-y'yΕl\ϭv/<:9dYFK ̶w?D0?΁Z4QR<3G&QV\T2C߽.3=I+7.tʚj]GÊ%buϙSEn<yCGPVQǝqaUFFǴ@x.\.M\rNVh4\̴% iլꦻ k5U^eY8B=jYMRly)a:/ k/BJu\wF<G86D4+=+2Kt:NސϷf5?[ʳbh'[ G$iYȪ \'D"26ݼjee"$RR0Lb5lM pvXN`dW)fIIap V1@β,Ǹtڹrߞ|7yw9@e6SRy'\۽@6o=[Ec.rrc1 k',SGh)x^o.eڽ۳gI Gh]VJMd/[uRX앒RR(4Kod &n,㺀 9kKҼr-՞i^3,XPY #MǑ=n Mcu Htt02f }=4 ŕ増cm(g8Id6#E4/z ʕk>P2u4f?=^_I`sUt'cE{C,k/>*3)b3bƾ)v ,)Ilt#ٿᑛk"g@6Ǯo=~O׳;@ѱ!xB T^v(p#eznd~3A|0>*z&f$P߼,RnFl:N02e2dMkV5By֦5%t-fZzw iPC͆ x"i16>~A1!X^wۋȌ1Lc[Ee_Z>iIM+D./~e~]3V|ؐE=I@[`IĒ(dҤMYhXDnO|DBZ&vP\:! 3)~oWЭ ^;YMea Nj/F҂rx]|2cL:'Jd -&FJD"QbL& Q`tdtiTIN3a(F'Mu|OUvV] QFǣ\22%cE|bX}tXf5ewn88a*&iHM%p.s]K2ddtHD"T4JuUńH !eRQ!Y׸F'Cq!\u-O f:!~Wȩ_WG+4uT?{~ǹyMv@brT#v~c$e}K%+a5o+B1{7`{sh/ +sfCCL$RY ضu3ag ̺ p碌O(8pnXUMLJzTUP2QQNUy5a0)'U‘jlidz+k(&R# WQ^QA]V6jGk7 FSeHU4Tbl2Iy&n܊[8<^u_J=UvqD2UiiꦢZN_9+6lf]S8#I9hpllmnfZrSO(8#368"\QNuMEEM#M>9d֯ں00 =H8)F WTQ['564^Dkqšʪ"A#~j*ʉUt/-B<!p\/ᠦJ7C깔5P( Ņc BP\P( ⊠BP(.~)QFBP#Jox.n"Zmj[g?{G4ҙfe( |.8a>WZKKFih$6[ǻH*K4t9LXB@|8?0lB7TvB@yܺ/]0QA! s8]Nl6ZZR]E|Ě< #> ZCv3X/9﻾)yh5-?#2B ' vts,,nqwr`H&{S/2jf-ײ܇&Nq|yI͐ł@vVߞg\̎ bX8 3>YR,WueY, c:rSHN1` a/wI*6E,%N5%Bʫ'$&S^F\2x棦M#]zZBj*q$t** zAcNHҘRi:T` 3@SVQI]Z~OHv\Zފ*:(Ic$cX:ev SL3`T-6Ll~g$2$rPPp'j!359I2[@9i羞t|;DM$4;M255啔@y&'Nd2\SA>cb*NO XFD"F*kౙL2:]QKC8,Ntth2;XI"Mi~]7%\>R26 uBU:(#DPf$I䄝1@"zY̌74FBĻ[$.4Ҝ|yy7+tqL&;˖sCwSyC)*b%GX]n1x0oCRclJGN92QΜ|sC+6 l/uvG48q Y?;L0ރg_m,zo~۾چ?̴ Gj 1 L X̯Ah募^zжFqڏ؈Ɲݸ ;c̮nV="?M[nҷ@u]<6#EOU<ȱ.G9|O_Hz)ZuuSttH/Nx^VVHz+xv㣷=PC-W_LECu}QᎻXF|8ow<ϺO9;ًYs|&,+GŲd\?v;^;ܵhOqMؾX?%_˗VV1s1T?N'pt Ih?`|+GVU`N %it9tSэ{|{®+k8L{j6rk yNk~?Ƨ X!OUO_c3(>r$'7/ dj87BЖWwV!qkV%B1hbϒ d4zz. :Ma$文>W?{tsfb*N6e4=ib=yPvnC;(cTUq㽏_ 7-p'yb1F'NfȤ&8CҜ"A'omc瓜# KgxhDTC{W7`LWq}.|,;\w|˟g{W_C'y/cM7sC$ҶC~ Ҽn~>ȧ58r&ي<ɇXRPQUmUm?c]x_#ӤyO\M~O ne}7ϝaMر};wy+COҗ$F8>A[~kj $]L$8=ǺG㢐eL7C#c~eLz=<- "Nø]'?u?չQv@ȏ?&ܺIm_ca{E^?cv>z6V׻4ݼ|k*3̞#}X 1pgw|5>G5; Ny=?g?07OUqs<$*ƱitƞWe+[o?'xNu:V{Yn=7.'޹ zm<\ƥ9(wKDDpcAUu5 --4bIà}%݄H!Wlv2MɄۃfb&R4MCMӰң;*,w܍t z$MM] @7uuH2*$VW:˛|4BALD `d?dy-iMS̓?1;niG8ʨ{梦@:e> s97M @&3hU'ȑLe0,}V&f$8Mmԕ{1 WY C`3lȃxʱ |'2_b. 53V+؝N2$Sv;܁#)`'xs#XS]lcm<}辗k+ikn"K |2d=vk_~^Řfqt]?o,>qvZ|NJ WǽD 1fg:o`@9u 0 uUm:6*+=L'3XF^vp W^bhKia7p߽5An'Y0@ǡ7p$-myfz7w~× {5 "X2`S<ו;VK SPݺuM݇Ul kHi͎᧦?I]C-!$kx! oy5αgo=Ƨ? [V`)OBxpGؼ c/y[sAПeaYqQrxܸ].\NvM`w{=.v,7{blK.HL4e.X)m@EmceJKLKܔJdο?V,]_Ko'qe&8NEc+W?q\DZ ".)V|6K|4?czٰq 5A/%gAQ2=pW% L'oXM0f2es , 5E>kдo=Dxu ҅K_`O-( xiX#(ƅdGJz-__L;eב8oz|.K6#NcZQVnks?."~k$bY7nd$l$3ت0r3Athxn{;4oۄJsse "͐ H\Bt>G.+>e\\.G6/=rd9,b}7fuLR{oUijʜXA.!˓7 $sy2|q \!!3ʳS-K7ũOe3pl^6o=o FE4)O2:g4#a=22{VSuSѸm[_7}\$Rz#)~]ym^4LB8ʸ;8/:ɧo[l.iS(H3 ##ϓ(: 熵oc.ո%% Ռ:B5먫!D+$1>@nL2}f<zĒ9!$OuS69;d*AlU4o_9/(`Etd tgokܳm#~&c s͆ |6:G766b~z-<v(jD՗^'xc#c N%ђ >F.#˒HX\Ucs x9vNўD+ckC5WCEpzAf^( }&5Թƽ ?X8H#Ϫr'b6P1C^ڨYL3˱7Uօ9uc]Q GF"8C.]G:r' lyIi9;uM4x > ֖jgػ)N*Gxwyy>JkwI੨cՊgȻ*X~-M5<]}cʚX\m.+#iNK{_eU|r)tC˪4U8Ɂç|mܰY :k%H"ao9MҴ74S[^wM`YKMXQeӸ„6uTW)^py}ج .gmsDxe^݊=3N{Gqe4EBTֶ1P7c8ٰ~%WS58MWO/c)[ﺗk[*ѥ,BӠt;SYzN7r"a }TOJ}siiAѮvby*j Iu~Dd-߼["9?~t ?J Ò`$1[R.(f&ZiFb MGז*Ek`Y34 MP:Ni )@4]/ƏH*zz䱐Қ Jm` 3Px N^?6A(R {^ߍ}gq>et JYK~ӲfQ-:xieF'i!躎`{OTy*0{Ww?[H,Ӝ;nCoaaI444M+noB˹q1.QlƹΊ)4M"\s@sVlfQ~X=XKM\_TlV]/ ̹1kZq^^JEd*,C3 q.stҒPqĴL;xx8T\ZQ(>95c:,Eן}s-HN\keXN:g tyV,ЄA+ɳssͫ9_f,% Mg~:,y~;-,4DZģs\K>fiB*Kx\k칫s1/^I,Ţ S|K2/0tfΜgA4,9݂X<Η9 꽪殌C`S s&sFB ?د!1Omxl^:ڱ%_EjzǺ9ݳkaGMlY[åP\Bx"fz/=ccxʫ*L%KM"5sOSU5VS ߼O8r2B `H%dݎroB`2$LN<vڤx_8*&DP(>H _WNRJ4rx(#DP(>'c,TTBP(We( B"(#DP( A! BP(Q( BqEPFBP(+2B BP\P( ⊠BP(We( B"(#DP( A! BP(Q( BqEPFBP(+2B BP\P( ⊠BP(WۅnhYiMV( B~A6 HQ( BlNBx_"K(@^i BPo%'YZQ( BTBP(We( B"(#DP( A! BP(Q( BqE" BxH)7P4X-@ćTPFBP\ `||L6VzZ墲ݱHh|.^Da' aT('q ?wMee6C! B# L"%47_S4%SYYy)lNVU6AgW7D t]jn=8Cxe( e$6 ]ב=mфa,.mY_f.4̋_! BqYH9yXs.b.RFBP( ,1ݮ_cJ)KȻjebhRbg' |f{GFVAa~%Q) BqϥB躎ih]IBǏƸЉd],-?G| 3Y']N1ϕfvg(&dc??֣F|??Jc|u\q9oN!.+"Sj -~ q.O*x+˪kp֛-k MV.S_7-DXo殺z=9}-n$zFMZV8KȌN>@-Yk6]Öka#?}ʺ][$+Ěu+ ;AyB ⃀0)B+qF"476,u/yM݄Qz_gΦʙe63Hi句/Wn'S.C2,e-d(Nה/|"אb;K͜J8hXxv1ocVb)3/B!.ku L կqZl󬍺0o`ds{I].ٗ>YY?e&~DP(6nMt\.bv?QL5h.^A0JDȥLhn?]tx"MxA^׬QSLR .ĒsS{-)hUȡeIf. $NSMM)ࠬ<ǡfWI>$oxN4$%1,e5\1&qMyy~&po/S2]T! ';Yq#5eœy,YOY)g/oHcCSoqͳO=MldۊJFNsX7m|'h?v,=C7|n_> "==FhMbKsE!Q(ˆ?7v"na͍wX))LiAl2_o0 -u?Zdž8ѝ4z! 55L0{fE-Nuj矫V ~(=gMCu+.h6<glLϽ-q ?@·钑{xzW?_5]S:s)v56Pʯ^|[ˊv޴u*M:2M9kgG(k[ vA-۴'<ŁRïRA_c4r`>-V3wWiYh,nX;C! Bq8$'`hlOkoZKYCX|=Pźk={Oԯ~ߟ_vT!B),:)B`Y85lTB1ڹߌmZ*:d+sHJ%mD7p;wAzmnlvt.A|d T>7|: ӒT4RhDS\qb7m D?+\ 1Q1 Bq}_=`~^}ײer!vi[ڐq v=ɫ]B<';#gN[Y3LLӈeYX5w|,s#Hr_xD5VRp(+QY%g< RK L;K13a%\q#_ǰN=㙃>M"4mloy$_BpRJLl:\eL ;ϖؾ8M*g,0,%="J,2{e<9Jr  ~|n M,sP(wUJ"-yhO7ޢ{D,&}&Y4-:n 00LIj}tB\LV2^*L@MӐFl*NRNGwoowuoWcEzXDVmm?ba]9%ֳ¬j[X`>˚#9Mz Bp 䍝d@ZJ3ܹme( G`][wZ7Ý'ٽ5!?`22cc2Il o=v.:ޓ]2yL󌏍06ym,O<C|-F,+0-~OoO˳Ș3ܜg+%idHffgla yB@J|Biar2BF+K9Me*Y͊'-/(I ̌]$Ggng?/f"0-,#Hubh)' O3>4x,iZAY$1F!CPgl+|{dׁc9݇;1[6^%s:yr?Zd >?K^( ! Nc&~U'% 4;*;5bcP4@<}HyS vst/G_Ḱ:C飵m9v{8C(\OkSHz.%6WZabǎrn&.u.. Om915 =ÛOhhYF$ 9o7)*hm^FSK+*tؙ!WPQ*wS'K᫨eyk8{E`_֖jKdDn^:o,s3'?^+SP(>! RS]}.l2 ,)ki%gMi8Nl=e(݁M ͎+ &h6;Bi!l˒+XNKNAWw7>OLL :9ҢcRPfᰡ>X y S"4Î4 &x@0Ahvtds"fwiH)1 y UCGhUC3]n"bIpܲ &(b4!t&^2%6W !b? v$!dQ)v6&!2KRҹ&W<B/R}E(TFU9kc }DZ 4%!a/Nqs8 t;N>wN6l6)q.v~w͎>Xݎ>\Wg kq;nls)nǥs#@ե132gs8Nrn mAw ңB\ؽO9_ |pyRWUvBx#9?mMTަPծwP(-sI:'Kvu|PB\\n[Zc.e( eX^v5N__^RP(!i^,/ /`͖]z@0,HvIQj i"zP(Ct:ʙN.gvw%GJ\Y>Xֻr^Q()%.ښRUT,t.)t"N_vS[[{.r.je( ext3.;B^|%?Ԩ]BP(We( B"(#DP( A! BP(Q( BqE8;;P S( B9Wz)_?|J7ZP( ]( BP( BP( BP( BP( BP(fFJ͎#%tEXtdate:create2017-10-09T14:20:15+02:00%tEXtdate:modify2017-10-09T14:19:26+02:00=0itEXtSoftwaregnome-screenshot>IENDB`Eqonomize-1.5.3/doc/html/C/figures/currencyconverter.png000066400000000000000000000351311416454732000233260ustar00rootroot00000000000000PNG  IHDRrungAMA a cHRMz&u0`:pQ<bKGD9KIDATxwxu3g{ID5Krlˎkʍɻ_<}y_rs8InoĶ&*V E{@I>3q (@gfgY{^P( BP(6?u} Bq Ok? BP|P}x꯾)4h,N*sֵU( Mr@%J׺ Bᰲ2f eP( B Bf(!P(kB Bf.[#u MKLCGqY))..KDjĕ2sC%FJI<@JZWSP\.B`.e4e![[풇}Tkl}]`g35MGd쌹m 4MDZq@3m9?RN8Vs&_NLv>djo'>9#m4.ÍKSk9y%_Y#@ jdc+1r2 i+JKS-ø#E,[!! 5éMXW,dqUn҃lgY-h:$8s0bF -磛n!E9~ rfͬ\R[hǏ6pˆYqp~ZzѽArn4bi  )pzW;WǮJo K-,rəG - w!ѝ$}ܳi#~q:L|0%^: ],=_o5r0.k͏N*XL>v5e<&!0{^{7OQ\V=n')Bl奧dGY;N-,N=BCcTh&AynwE5 Xl9kV`wu;C8q͟NB .2P38-NJrB^ o?l9%Yd)e!m?W{>b3S4bOpá89!x7HGXd)V좥kdyDj&ᰟfrlr֬\롣?qc$RRsX ;2Qм@ <3p1{>Cp˪S9;X#Mp?ϣ,[Cn o}Xɯn({n{o|~e4ϼ-Y瞢!H[0 g:ړpSPD^^1B,'#I~qE&Eѳ5PVŋWZ°& Jz\Ka,f_dםujŽr9 *WS4Χ,?pf%,.uHX)BHF Pn1Enr/^LY@CE8B3^ Ծ‰l\so֟9$1ǜ3u@>px `; [+*%QG[ Y`ti:7ak0簣:z:e,yR-HY>('LK+-gy쑏PVZBiI <.=O3~.@t\ř3M0KeŮ04m!QdІuQoBH! ĀAEUuR]MX`!๣<˄g^{I~SɟaY.4K{\n+wsǛرE)t/9]<|k Eϰq%'>MU4iw 终RuwWp}Sh;JKIPp9񛟢&w7|vn/7i:y#M=T̲MhhC_{ܼ$2My:nx3Px?GJPV?gNf;p ŊHv H+'*J P{o\9e1 3?2ߝX,e՚ЍD:Si|C,0їINzJbd7sn ] ;e8:L26rH A7GϟGOYsɡQdIK@4Ë_̾;`a;%(HH)of<)ty?_4ͽM_P{=#i.YĚ啤㉌JJc'm1mm@<}'4yXoM} GL,pd|iIRͼo"H9m'k9[;Sj߲u܏@@jC=Kl)|<:ޗXGtg54Zx??|tF =D<Ϟ#HdjVH%R'Zٽo'm -/"Ѽ'"yy{u?}Xjg0T?WL&y=v,k^ ƛosIcJP<@Sn~)SO~yteaNI&Z.mp0M/ɔ=wNƵt0\aO2K1MmuMB:NY O^̘OA5޺HRօ/g\D3 fIFqR֭284biFƤ7Cv?kz0+Тjz]98H n`ZFg{(_A*5h?3/RB8NJ[olXKtS`9؅TG=q;H?@[﹛ArwnX5mYBiq.x nA4A#|5,)ǥkܴv%E;;e͓rݲ|3Moi~W4u-3DQΌ˛Crr X%>3}%|futW]oE.@8Mw! dFͭ)%^իVUV dšWp/% R/s?fZ'!"Nzv-"- 3#pn1}$C2$7D8ϡoGJtM`YiM҉ 3tRAc rg\pd^S}||cG^/n$%#nI5Δeav&XV tx|d1 )'h\۸"'32@@t\+$KQYw^2QLţ #$qQcQ}5|j*JqǨcu5M('J i{VR t]#lۑXрd;@'(7# c/&[m|:#9߫脣˺u7y:t(!t#) /1;>L̕džURbFٴ67ĩNVoD xa?Eժ Q:{{[tpm1 sCGYׅ㜪k¿l7WG%d{`=8C,oM31f;Jj/pRJbl4Oumzg_z3ä-X;w__fNIYɴјyϲ2 O>;ۘi"5!DAk\slR4#!FƄv:=?t3g9{m$Ib$$9faYV5/(Zv;,^ڇ-pRW,; Ν$).jcݛX\tzٓOΣ47Сct ZA׈ ` D:m=!ml;eO"v3O 9$f$p*h>Ns}==$14m;XV%{fA~';NC9p{u)`7f5_2RJ*+}mx=iЕtآ׿ ٟioWȍ1~)A0A=Ή[ŖۗA 7rdnZKԱc+y#TUx3gi튳eA>~9!cWsߖMTzi`vGבH&y# kII@ڔbz CYInNvi`8:hutL.`ɂB6r.D6LOG"HcԞ'm))+ ,éCml+(c/R t<^/Kdd ={h2hLv v]t !8~9| BIN ڼvz/-rM'$ |Bx" N&VJ6Okyj l]7L^/> mx"N8'x=uf˽4J%'S!Gf<v 7]0斴$NjIRi¥= 24HHn񺍌K?߻ԗ–Eal4^/6!8YJHA7zlE,49^Ş:˯ߕcc΁karAI)}];3}k5 )\a%WJR\sv:"AB; aᆏUi C%yDV,xƤ /_ʎ bfT zygn@_B}/ 9Y.`8- BͼFdLή.ܦyy+keYhamtBH!_㧍1t5cU\&4B dd$zP(. i\֮5u9r$e+_|s k^k]EBqhܜ/K E%W(.2s b~sq) Bq%BP( )7Z\PT*i,!8###c b~I(+`^@nP\DqBQ^ żCA($ h;&HI<gL+Y#`hh#p(Iq+P(fR4h6$Ra8B̸B)㡣T*5 \U1G.3?vѾBd2Jg<#!< Eb._}ih[-&cv&}~/g&sa|lvm=P O3YMmD l좭MCr;3vK}"tIC3;ҕ0,ƸP})$M!>4L4A<&Lp{ 8Vhqx~<34#m;8 BCˍ?6. !>親234%mKt@(@ap$H\nCedFM H8tӓiEN2<JR|_ oE G:8Rt:n_{=jf0+O>ɋXsOn,C`3K>c/kxo̱}=;cgAw`;_x^Gᢕ^\IB:#(Y$׫_:" ,:uJ* z$=9aHG5sÀʬz# _x'7bIt{S^}կ~J_ן'z Gr8|[o9v~ m=ĺz8c.a !ho_"7'G?0``k0Yxj&pٕ`x~H4w.+V VMX2*[A,bGG14f 5BcI:z]Gan#Ӓc%*PNcgogPKAYVok~xy2х ]&I: `fH0 G2R!MtT  ͥv|bxW8CՏ?˗YJ=‰hK#Kå \PH~3۶4IWQ; ppt?+7߅e]v$@>7 /<}NZVpO0Jd{Yx"kcBHh'TU1fs N)|<.3t-^xnN'Y{zrb,4'~ BBLB*!a{4f !~ŋx`˽`9ӗDL\{'EnQѫ/jXbn\~/C"x964Í1@/`q`&\7ϘTSQww{ 1k4l45›Mqb?*k=g?oug=سVQƢbheJ%')AJIEy7[+h*$sdžȉDf.$'FMBf M:.%K{pvs7dlv}\x&$Ӥ$Mpq3Pdߥt|W/,ǿҌf{.(WxL7.iHi}4;YVUJ$9*mJ$4Ǒh9{rOG|rjxƑJ;O,,_̱VNv&zU~ZE]w{\9Mq.yBabrZu0ش."9~ƛܵiFɄ< %6=ob)f[˫q6՟7z?9UI3iGS}+ݲԞf &)έS{ȩ39[6K2u 8P(8>}|>q?5k㦏c HMG-X0>DqC 84!k??Y[VT3ɔ8c7IUI+ӥ|EJ4ټi#Q]U5ЋPuvq%K( t+g5޶ cW={ks)4 Q׉4쏟D<2p8,. 1̩.Ak;&Uuf{TJIue%xWy쑇mxם j8xX1>e߫@zvӍg^EMoES@ƺ9ٟ˧?05a`'gz,$bÜ?Bs/1WO+%f0݋]PY_c<3uKg8Uڅ\n~^|ۂ m}pۊ .s'Y|dmIrj`|! R#}>`#v'/GX$c#k7ݺ#hs^WvYUHbdq2uWiH'Op&sfC:^6{{zlds'E5ifsڰ&F3:w]acz ` 7){W)DŽ!KAAL(4:Sd\KNH.p#r2G.^)g}ԝ\#̦LgI)gYgKiBS˿H&RLdv혹o$uAyuA;5ɜ6^7˹d!Qܕܼ$_@.78dg^ upRn)e,.H1 Rm}Qk]uS\s&*y|&NPU#JR\(Pg~kBLYP\hH>D"UڐB1MraA !BJ!W^~sU,3--0˾^ !BضF$g& 秄BP\U2ou+hS(y@)y

ZB>v _(̙t;[2w%<*URFKӜQR) b?4 {,/%Zk5 L̳fm$-OHBDl:PHGa `8B`%cDXWdf-J) UevBkĉ>9J}.i2TF'RB>#=%Bl|7KJ${yC$AjUbb}9q,)&IKͭ[dMYhMT. Bq"'hB3 m o".yTr8W?x +-w:otĒ[r#<XTIgyk#):9YJ!&P(׋G20J*|;˪ 1%~}taޏrԣ,BvL7fU;yEjϕ! ) Df.M8 }iI 4ȞdMur#p^\z<P.!G@5'7ӵ9͎ýtFI /99D"a"0A9ɵZ$RBHP(6xAK]<|/#>ҠMH  Ёl)Z/} cǣCčsXú?7E&^qnjsa,C2eRF !B.Hܬq~'aҶD{qt@+maS-7?(yv8I–8|c]ɉCoKRl .YDUa_R7“oɶY+7E[P(SFf[ė#m|%u5uS~חcwQWwXWGO.'xXǗn]G:yQs'c1V v/z:Xz%kgA2 )g) ֳgy}D"$h$S)l'T0M]H&l^*ti̦V:Irv2ұH8R2ݘ.ձcĥ󺱱\ f:YS9JR(Ǒ=ީGaz<\'%.u\= O,OtS]mR(̨WۍOHh+ ʕ9/ zFBsG *s ) U"LG ) u$A:a ˲R(\9NP("pqәRq9]BP\%AD _\x<{% *"   uUKԚBP(J) ⚡BP(J) 1& ØBP(z`^xG}µBP(n(v ;?0WBP(CJInNZWCP( BP( BP( BP( Ň}-|) .%tEXtdate:create2017-10-09T14:11:41+02:00\r%tEXtdate:modify2017-10-09T14:05:56+02:00G_tEXtSoftwaregnome-screenshot>IENDB`Eqonomize-1.5.3/doc/html/C/figures/debtpayment.png000066400000000000000000001714471416454732000220730ustar00rootroot00000000000000PNG  IHDRTgAMA a cHRMz&u0`:pQ<bKGDIDATxw}{OUu3=9cA΁ A(1H$[r]{}7{y]^9Ie+J$Ŝ)3stp?g0 `gtB;@QEQEQEQ럘G46Q((@dύ_EQEQOOKt|>G(/ϻG~_EQEP^QEQn@*+( HxEQEt)G7! W(rC@>0!Q !#A*4M BzWEQ>R;K)ƨ(&ҡx\9"m^/ZE@%x)')4 kSciq*˲Ò(x ~6BLS(1+,&JyX5vVv冥*)(x!y{'~ܘD)toE.ւôDI~F& !Iqa:Fxå iPѰ勛?5)(!#@f$,Z;oʚz7~,g 6z;wlL#,Zh!fTKaW=YR " v;I[MXXfs?09UEQ>2/%[m'\^߀]G:0I@b*b`H3Z0/RNsEմ|R:\T\_\t3 4>ڣn5U #5" )7/KeM3 _~\q(+H ]'Cܴq5.9'3y5%lj6sp$SdkLHaq #˾יx)|>dDxTyH8)t\hB+|&_V+$qai&9Be|.LI,CyE,TMf2F"m G(+QV6D,NKhBǣdHyA63K4#1qBEd.<̧Igl%2$g9h.v% ]#g݌ja:ARFw!I/Y˒2Oq3G^_JS H !947`B`g&d2/prI/kۈfl2(T;;?Pp>>ExlWԲC~yd=ηz_L4'+{D?}I,b#CD2ݹPwMGM+\k7zj>ٻ 3FX+ado!޷`n>2( t#jpEQYI`azn5y~m7xKͤ;s)sb}kaaˆܴjwwqKVbGyv+[rG$v;&9/ {6Y.cVߢ.0]::hŒj?}yd9M,n%-oges>~&EQ<xpeuU~f/]Oqrin^eIDˑ [4/\@eč.ay]5'<2_r:Y<lG:;tc{h^ $!t ]B-<±B w&˞7Qsԋeٔ4`˒:M ij .e%<$ X" {~znjsLkεXDlڌnQB8VИUڵ }%TGB j47/ i"WM$q ֡cѾ&۷RH6urQ[VJ{Jš"JKKf1i?qQҶTT`Nq8+unjb;i64(ʬ槟U1J5`6P4=}N2"ťFG{st! ~w"~'yg!:>I:>XGiMΌ乩0q1XL%2s &5^t]DJBSLR:M/LJ8BQݼ{Hn^},i|dHظ?~ }49]*̡{ޭ[N'isf kS E:` Csy ~n]c)g:)&Ojh?|۹mGM1Ȓ6%`@?uyEQ^Z$?^D?Oyb٪4ѐcD7 H̼M8sX<'y*֕ƒ7XF[{O2]аfs8R@1KMorv{Mbz"eGy>gS>HtܶCos84=HES苚hV#!ʝ玟d4# 5lBRXH)mQ}:2da M8iB%9.Jʂt_8C[ 'LѓM3oһ(UiRbe,\ضϑB-;9ĩ'HL2M0oӶ0&#osҶș&f.e ÞqU Xv=Kkjp[t2<-@-Q^~wO o݌8Ɠϼ̑3h=s8:l[ٷy9zsc[D*:ωl[lL*Hc[f˚,|\q$ԩZ`c]hsLplLʛN!,۶iZM FsxܙS9JRmK=OS8{8)Nk_#şY% JǢ||C{Hnkh(:qzt"r*{}$9_͊e&q7ROqCtFRWd v=G*B#I:wn,Owmm#X| Zb-,YIۙӴ LRZ }<:N1_&f:,h2BMc K :_-[᳓>hZ,`ߞ􎚄+XT!f2A< Nr.;hG%61 zJ|p%!A_G+Xh *D@HIKymuavbKkXD&TZkSYBs\TQ^ gIX'LuU) چ䅋H9a/.OƦ\q:zuijvNϹcB44RU]Ksc9:H ?--Ԕ)m&,,7R¦ZnKQ4WNEQn,瀟׿~ńpM1'AJI >fiY8V]70tmYXqM1 0`Y.]~:YX-,FJn5mZtelӴ@q:e!kWJ4r*~ncǡj)q\h^8N!4 S<zafVTkF_?c+ne_,q!o3\jk۶yӵntB:X}c[1tSetll ۱nB6m )nCΘ߶-x:ZqǞ?~qd`[6N;׵su]]SEQҒ+&mpW|.tc5\Rnd%>(.]n\\f* pͲea1L7\>vq|өZ)Thݞ;Wº_vlńE05vQh:vyH"4 czIzmS|3w9EQRSQEQn@sRU_ER((گ4%'?fzH 5d+(\b4 䥤+Hd6䩷͍9MSEQ>Ʈ@ޜ@^>j> ?s,z)%S=T0 m34485஢(ǒpIP0+-a\9,5ȯDJIUe%((˲ZBއQEQnLb7_QuSEQ (rR^QEQn@s;T PQJX*+²lFFFH*[SQeP0HEE)nTW⚖EsjCEQ>`&=x .wjv{1DWZ\!>&9.n{ݵ&E,dCmDXvee;Kֱ~q .Qܰh˲:?ewM-zcv/oh#M&;8t@bn:OUByEĐRb88~.52#uMDJvt|^?BOWOPFJPx˪${I 4+/eӧ>oljw4մz]3 1MM$ծs8/qOjyst au??~< y7R#dso?ſ-XA8d2zg mgMs~6EpiI Ozүv1Zw38=m EҤDh:aZq@_ q>/@Q6m@oRR~jj/+\.ob"BCS;qq/ߵ N,ʩԊJT;SiU^Fi ًN:^:6#v Kv78z*6pfdkB2:ܮt|j`$m# ARilݦ:e<>B! \1G%(26lX.s=wS]Us5/Q!36IkX8gs;;s=+0Jٺ.āW 7EftӸuK+hd,A.#Ɏ' =\Ư_/xXh KcY~ P߲eH&Ә],;8Lg[&8ye\"Z̶[#?}hݥguwlNcϠƲ% ͑J1nr*˟~I$NA>犢;!֯ ~y{k_#şY% JJ³6Oߙc˝ǰqvsiN>yt&n2}ٵ iBMԄ=$zpT:C.qY=FmȅH$cIr<<7*ae.UTn!HҘI(9PekV6nbsg0 q*ܙ!:x*Иb4맹ɮxk? ՔWPg6`<L8y(oC7/yA=v:G&IFGik=G*GB_0ΩHc2݇TWwxiy| Yb/_PO%kXTBSQ^Q>qhO bd@ _w9g_ݩ_I?d5H)隣a YD#h.;C6>0)Mem%~t80p}Th*NIr(FdS^CUW%]GNgfi{*LVaF Q(]{!**{tl>RkƉ0sQ[[Fn|(ޱ2 $ \cP`1 hlQDw&֐@>1Nw0WFCu 2ubC +ine#4T]U TVVPUUyŴ^*+q\W[iHi(_63=mf[D:rAE.>\6OqpH\ڧYЊ0VUTBөLu1q_ 7FW^63chqCάꟹ3Y83]xM4@54}_u(,Un O 0˄J%7{U|qei۞1՞1WUu)ʙ1s_uu(r4/(JeE(0UwGe\6Y(3q {}2TpWEHk4#Ӫ(u>C7s$)4MxEQ>`f}-sTkNJI8"LϵRExф )%UWaR]UI:JU+@aw+S^7a\XQZ%+E(2?T(܀T ^W(rk}Xxe^8C,#J}Ի(r} 4A%Ҟ*+לd2m;,jnV(I 1!Yxe^ض\66EQO00(z*NG$EQZB/@ou_W斸zC"b!](mM|lIL)ma躎7PUU4Mqw BhH+tۑx%TU3\Y!еbE3a!1>BY}ˏ%r&Irnݬj,E /(d<~M5]ֈO)Nv}ob0 L kB /Bm$¦Fn qG/<"|:n}#M]|(skXj~ɲ'>;/?oh+ZG{[M ]%\f~l6/qرoQsB}Gη~\mT=in}V~7ܾ6xYL_CDSy<:/H0|c~>KlS<82A@N7hH҉4n&E(ɮ.tZȇl Gjr~{Iymb7)Qb['w{ ]UW=!,x7Nfٰe#Km+"/(/΍̍Ͼrw5!mc;Ygר7, ׍$x׎ Byn)Shswv@_2aۖ%y#I4ardєfO0#UҴ)Y_?o6~s(k[QoNɉ -P;ƎSܶt;~;`y>@.{bimXaq,S,\wakNF&&Ջװnq \ 7nCu  j) HGm2i=Mv[#^P#4x1^=Omv- .ks3|eSJʹGx+ }osPSXwC|fcCj_"дdIw)մn]R8џr3vgv8x0gΞ"]75DZ,e^unfݲǢP^!b%,`>^SQñJQftrԍcEA6=_9w~aReqlT qÜDeK=Gyy6oe}5aJ+T44|"jK}WS!`$=2Fza_,!og4\x%8/""G=7..bEؓRq{4^y!?pGQRR|2HvB$'Ig2D5S.g;H'b|2gP)ΐq/emT Mױg%_^ljP(*Ǟ&G6cH9(T7S"Zytd+gYS' kAPӵBtU +=X{ì H;DiCe)n&HtnGz XQn.Cm[B/R[S~~45˘sVna.@s2\8s|%m_GIrxqQb9\%(.P2$CghHHqmYQw?$:f6nȢ {vqg9tIiV:%&:Dh3._d&9{ ,ʝ+I4v q]LUB5B2G0VɧojƠa/U,I 1~? *gr 0'9 % 7*@$`:۶ʊstl8)0 Cאf#;yVVe[[K~6nE^Mfə&%HeREʛ_Nxt*@/cI +O>['{ȻKcs_WFظr.3Ug_}4tt]Gsr}^_`I囨Fy'T8TmdiI޴.'d9kUG\7YO5[o_XqFh`:6/8piH’0%qͷ,ã#D5nv+ۿECCv9Ϭ%%a4@j2x$oM0|\hm̩c;AG[(H3ɹ;44rz&(ob3R9y9y 1h\P?wrfB&7B2 B¡}ۭ^xcWĪU" [tIN188@g9N37-vsqFihYHY:M'DYY(vï3vwr흼ƛKZ{"*kp ?}C V*JG v:g&,]@yKNӯ~XZFRcIQ|&QN+:Ͼ+;K46 ̶)%466̲!.{I[x:Ozjӕ6)[H}Ȧk`8(mۈY.<2 ;<v>AW[/FE#!S^wLLL PbN6M4F+ɧap< <uTg./3Eg(WFT #]mBWxJYiΞc(YWRg^h-(uQ:Kpe= j"hJVznH7Uu4/hīc'{lPPKINee%ni=TUVrҒ+&Q/S5튡?,kj}Y\JgjStN;i3sM856ì^g;Q_q LTM8M)#4 MeMjֶy`f)?}^%62u*'۵ sVtnC~kzvFHm[/\ sǂhrV*GQ=jIkxוWMJyu8(JS>r(sOxEQE((7 (2/Te^A&('fe|Ox嚓R 1-^{vEQO&4"wW2/E"E"(|"6xEQE((7 EQ(܀T2/b$ɏzWEQB+$ 9_ 5' H`Z&M~jyEQ>4MqsUNxe^X|*ؙqv?/?sM|7S z('+@)C<29. 3K`7=HoMbk@Zzeձ6VĆ +=57SSnZLw=EGXG{_-By!sx|^gB ݒ}|/f"B%6_KwWE:KؼG{Q. 57l pk*+I#v^gtW0aKعIN{/1boB8S/! ~%v^k'9syl]˱O̅ 1pgyFn$?cO @6_㙝0uC/𝟾pFkB01\yLӚ&ٹ EUc3M{m;#6~hNg4X5r93QF&e n^'%eMwqMq_(׎ >x7vf:6yl\&'8{`'z&?_o+i.u\7rˆ qbG^8Bcm/ͷqӭܱ:®ԕͮv=/=9m[6mT/t~~ ܼqyq_UQ~y3z9 +Dh:Bw,v$';7pA'|\.i;3z!jD/1v$ΐ^ w$8E>of$ˑ˛8\|B \.G6Ü^)m Ӵpda-3O6ds92,yL'g9Kpܹ\Ux )L6f\0Bh﫭IQ壖K6A,Ɩp* cK_"_gaǺ ;^K*AJՋXd[lji9:,X=3ȏ]୓/]LH8eӪZFNXCYM:V&ɑCȉYFFFyijlweBsR"ݥle35a

Aw&$Q&3n~;+kɥo?Cw %fy}Y~.Bg&9;͟ ]U5ݾ!p9kS:v7&+c#L316z9wlYCG3IJR9?B+ɉCQ.}>*U!p:\C>9N[k+=# z>3^Ʈm6~?wpxǛE6`F9v(},&flVnMD}4+lӌ5<ܼ ќAuU \$*su~[=^)7L}S Hʆfj7ý0N TQut &KHt $:J) !H2N4\%EMSZrn%>/H_XA~b)*>}XB ;wMC}=wy;n|_~ϰqk~zbXJT. f2crv<1y^i2œOƉ Vn{'"Xreu}I R<ϳ/Λ.^-W6xgOr3 Dn7y /= zD3ww?7+ %^zvSG; K׮̓f,!f;_d{˿Y64"A,Ur_?- q&Ƌ/UI>fG^9ҋ%vp?NͲx1{HHo=M~Ly 0EQ>)%+icIn~801؋[ĖMh2O"$q*$.a#>b"Gzzh>JJ%<.2a$b@׵ ɬyI-]׸u-l6\.P]Ug~y96#h'hjb;M4-Z'H԰rr47T;Ya@p8\Z 57KS]UwJݱ]shJq%>45vFy#/qMo~s CE-5O!4<^/.+B t@ U<2˔zulw->]\ԋe() [_7E8M! ;tn܇Hmusou_aeTx:VTp۪]0 GRoYMJ=*sOQn5_xo;k9j|p Nz}z垇Y_2蚎cNKGu4]%2cbOmLhn i1Pn iMF0 mc4@Yn7 H) RJʦ,{!'I2l^Fi~ֱ[",nrR"d᫘ R:HGTwMkBz,4{npegd te=D2і}&z09AGS4 %plb&&q$hHǺY8*+r} JvoM??2{הa;M8wlyEap87C"kC M>m!\X( M2im>7iVpI( \[4D8RC"!́(Tr*^sYp|vpfih$G&/޻V&?|U|8۲y- w#ɩ, a/鮃dc[X!o,Wx(&=(c#h#n 'Z{O~Bm; r>Az"Er"l&CyikW-s(r=2@(#`[ y%eMH;Np&Zo:BCb95Pk UvhFhYWM:H.x2qFMM "qllH5,z G>6>B0ĢˉDcM"qL&F,jh,3"YA&ԙ3$%y9s9v{dɼS:Llw^W[Jq:N?{e?t?Kk(6#)c%F8yfJ?ˍfٌ O$'=#b_J,p3M ޏ}^ΜyfMpu[E٢Ml_lsi DmoueAK4.򫯑Lv^zUR}fH$() i?d<_xdV9ʩsm & n}Qe)^ T76KrpAa 7uT\d11:(]}POݱWCswqYby("4UH;;ys)y7u5+XXb19h"+\EsC%jt?>rJ1sQ]L}e)%%]w,!'hjPV^ɂd[ٽ &|,\L߇&L2Vv\e˗PԲw2˅^"smY1zwN/bբv~[MRleZ@'lںrGMA&AA8R5 +9zgu] 8wOy\[dy{r˓73Cq,=ҏ/.?sY|(#xX}*.+ 3Q13!Q^zy3 !f6JOGu3g{yE9]^ +?ގflǖNIRknXگ ﵽw>vgy*ϖpÕ~EQ)%'UBS.Jӯvۚm~χ{WEQ+4ި>zʼn(܀TWEQ < ~EQʵ/6xe~1*+vbUW9)%(]*+90~P2yv)+/#˩EQ4!z˅gEQ>ɮU:yQE*^QEQn@+`(2{R^7eaYJSE)nJS>L"H~Ի(r]RC9T^y!PEQ놔hlqf}2/${O(A\>^ih^EQzrpus(݃dk`!44ue)|dcN币_ ?(K|t:M:&*ds&+= _~lj3O5lG/)4V dXˑ8R'RYE58&qY Ƕ}a+KqWfRMȚ- D*(gIYJt{7s5c4D,ƜZ¯ۿܺP?yK~-?]|}lRs\Ep4} ? j+pYYD ''OcU<#}݌e]4SF+sq<jZ1;zIYݼ$~2D먫{8Dg馮rMwG'c ]kOC:s;gnx#A.[ʺ-w&$.kC~Yw!n41cZa9mj2/{2Ø&ЄM#} #T?$?! 7 41s~i|>_<'B1\.\13.& 禰/za_flK|[.4 M+kød@ Ɂ,K/(+$ѤCħ l+G:kSVYXg|h3c$×tasy`;&4i;]'#8;_}h^79'v7x h0~w&?Ʉ)q3;~^>LVjhNf y?| Nu='ٹCQ934(v4RZ}>2ù<'vw|9|Xt>g陴ф&xAC0tzSJ(r!F'L^I_L&AHM GwlL3BV\.#7Y6B׋Nn1r.-ěyG}sHy|.V݄BuϛX}E8H)PV!)4y9s>Ѝ9ǡ;<F뿱1H.89B岵ӱ uۼp|ϱ&n3|) ďʺ&| :Bӈw_aMm/a-Y< .jCB֗-ɗ<_غ~9jW?Te3U,X؀?L͒ vS#[J9-ܡ:7y5Olms|/ ַ|>%z#K`Uj>8>R'ȝM pi|u˸5xو?3w _UUA6.` \,,} ^:2Mk=X@ USk SIT4eld}4A˲r.j>Ń+XvO0 ngU}y~EEK] sT PFtd4R/H v3˩Rd-l)ٙ[upԺq+ ^m$rF1Ф8,SYQ~IHd^=~QOXW/e&}mg?P~+*1g"f  Tw,en&%7m4DT._x-k6䥃sal% tKeY9!?^ M'*L+t[)ZǻA>fJ80>FiU ӴlA# /,PPW\>kI&$)3NOW7J*zp'd.#Y&UqL[ǥiH˚Q# Rk3Ӷ$Q,ZӹM.5!8*#+s\[|UsΪ/DJMKw-؋O6LBmtu1L@)%qeӌ'-b޶,|5'S$MY\+%]m=?^D\8reԇJ ܆Fzo`gú:@n]D>ӎqS<^w36j3aDLwa!f=eb|ZV.kīvxEQ'ULR VвɒL秓|$% m ǃ.dSۇ5,yx#p{|$.wy.G O?cuL 75 )=s;1wL>h(c1}z|G/qf(?~|cMK*Zu̲~,Թ75R"²2wl.FSWNf$A66PpSֲU PUUAb#6qf"d4bAE2:N4#%SGyb-,[cE$GId,<ccⓌFj$ǁoRc./JߠC_eDj)8f6zƲIƇik.^Dm2zÌ]1"H}eMPF$**ѡn.H]IuCu}5QFÔMAum^M7L]m cDzv0, C `6w}k3D"AIIxdN&> D,`AcJ-KXf-KJqLOik7!(cD& u,]ōuTWW +XIaKYj koX@EP+ײ;GղM, ~*Y飡19HE2BuM=!j`EC~ǣ%h,`t"eDi]IJ)*̗ !<;c,lZ(I';dE]MR؈۶0Bt-4UVXW[ͅ -ʆ@14`O7YQFIZ< :& WD_ H:*+Xf5 Rg_< qxTQoxQEQޏ9F_YᡩW>VXc(/* +(JU+(Gͪ2/tM'gțTǏzEQ>bתe}5 5'qc;6tEQ`0p|*+BA'!EQ>T(܀TWEQ (rRmʼS(ry!$L>]QEn!D"9_ 5' O`6 4QEQ̛ x0 *+¶-\.7^xEQaPx-U2z(EOG; ,ŧ&OFzhXB}yQ\&]t LhYOϖǩw 5}%MK}<)(aF;y7CYLy /44!Iv?{sqT@1'Ӽu&J8sыGH;̅`O> "?DŅ}/gpŒx|ESλ p)5ykM:e V୨gQc ^ h"pe"w4Cd//UEQ/f~Xb r]Y)!9}G4Y؋O4q M;-YswmeO';;;/@[7mѐo秿Cdx僄obܱ}3у N <Ͽ2o|lnbݜK)AhLi!@&#qv/_C|w t=Ip!s{M#hXrg B#?z Ѱx! }lXUؙh2r0nZ+_ ui9xf䅗^a%|Q~N켜9IƻOos':f>Xߊx即D9\{z-Mz; dd<łwr˒0vʙI/n==tΦߴoY=z=N0iKQ[Y~yOux3_6MuUWEI$ZZ2ȣ JХDJt=TSv}&FVhm#%7P,>2i mT76Na}MS\Eb)jO?;iٽ--~V\>/©3gٴa5?l 79Ȟwଯe۸Q3᧿O"kW/b}u)ׯto.#7;iYN&,n᎓xIIN WRWƉwQ.er׋\wtuih&~ EgM^J. 7꒡(qAݯSOk)qK֤oEҚ 23DDz\S3i^¥lvl^ g ?LނxQtTuBMfHLۥm Cq2yALӜw:Mhn^ƪ% pl;3#ǃx|~~/Vv_6bے`}JX| Knehvw>{F҆٪y,ssL-w#qҍ'~Z6 |zNQEH'm-\ ο}d3~B0sS!Tx2ASKC 4!/&I0 7Rh5]G4 ]py0m˞qNi:&f~vҒ߯k;TH44q$&t.C8Z66"ODp~..]86gl mDgSv#|aGNuiH Ld& R˦,)'ugrӖS\D(!Ѝ ef nM'.ؖ=f. ~'34m<|_GWfl8ُ=}bߤ|L6(5th H ٺe>MgQ +#qn-KBZ2̒  OXh@cXkDbY,YR>4aB, Qp%(18N8P/L&ñ'MN^5I{G缜¹ RbydĒs/8-g 88], ja&&L?7ݳO_t{Os\/YicR|VN<ϱSMD9}p/Q-wņ5-np A2pX4F&gϿ_B wNQ##8GvF[4iX6[nL];7ɡן#c=nӰt]4i;ֆ%` ~t+_>/~Ĺ4FB>}bFNXchⶻXXbPp#w/O0iBfwܱRF]]㥗_e2G?{Ϭ%%a+t8o`$fRV_KcMCgcI)cŔj߹xkta!9"eyb9;̩x_r-];8ڏ*߅rT;ƪ}f.:,񸲜;s Q\5lǦ )i$?GfC!u^EyoB`y9hIPjݱ ͅ/>͙N:y{Z5ܻ}5eU4t=K]C96)5FФEϩ=cMԄT7'z9s.2+x`&"^w=HܵaY aPOwO/gϞ#˱g>ݺիV^2D4J @+39괢s_NM1'AJI? lHK%I ]^?; .0^&O^?`C)G(6I%dM'$s#\ayAwyx]g=L*E:kˤHerHaBc'{ l{U ~ !@A}m-Ꝡ(Xya4_=/$t&L&ȩW ?Z16ax|g\t^E^e ڥ1Br>$1P(K\}P˯A}Q+BRy{(ζ}Qx嚓R٥ (bsUW3wEQ M<*+o.}EQ>U:yq˪(qEQ(܀TWEN !>&NhN!4W-.cz?[}(r!4t]/hZg>ov>MoQr>cfk=͑cd% Jh/9`{be\8zCX䥝gC{O~c$;\ k^?yF*+rC.ޅ,ɑ~ZϜ3m@kGZr^qB2xz'gu Xbupv\ I+^ M2rϾ/v|;B`x{_}:/,m.TyKE{( 99j/x581nDGT~`!4ZǒKүys].^C!dFD d3;v3gaZ{{'OoQh*%t]vD~_-H3MڴwE cF fxyY`)R^Q&01 r7㍞㩧^#Y1'ݪEQ_ކSyVFt3$-a'LjRw5i"Rq,PYO/Qل;/$gIKO7Nj!lqi@ ^ACwyXi~+%|w/3ugOelz+kW!3uB'd~,Rvijjdxxl6;z  s\ʍXm w?ܺm+Tϛ؅(9pD U, xAz-M@K;Y;Gc[YY$ufR`{#)Bv?p2U[qN=񧻈>}kι罒ϹΖeɒ%QDQ"% 9؜sى]] wvzgv~/Fj;iQPQ;7o63ҢL<0{Nʳ,Ğ*+r[1d$.)pk2W23 '%^@zߴ̞vs2^_J2'uul޹2 FƦYl.jKb\hI [A8{} ')lܵ5W_a4Pr,*jSU6P(a~ uOXtgS񓗎218w]!M shw԰@ڕ.DG0tOXi 9djE-TL9~M\2Rs|C< -:/*]2T\M}s|a'$X\NMM^8evwyرL?kwK<́։yfrh73رL?ZTSi>֌';;>!VxSp)WqZn}KYg2j9Q\QEuE ~v^Qۊ`! k hÚY 7H̒YrY s#UctҒJWcY/>L|F'ڸ[,D{gSl߱ 4>X--x| ĚmYM7HRkeaמ4mfۇvQuT 3CR"@uD`%i>?B QeϥXQYqw&, @NL@Xi:ژLmCJ6*ηY;0ii$H#|/аut7{x]a,K'9"9pf~e^d$j9S>)>CEd$1Y:6m~ϒP nX亯IV_Gϕ?%N^ m$2 z&\GrGd^CUǹxp˲LӴb9IvoqH$H$7Lz z׮(4⣭el[UVa[u0c4ZTSCLK1[ֹ% 98h$qU`:AHLvј,LIJ'?e|pow̻=r81K>>sq;ٯ@b"y%pnuPw}$,eYuNt)tN;l|pd%(&\|.=U;T4>Qn'jt <5B -Mb"fk^k]I(qDJna}?{"r*0=5FWO?Ii?mC$0MӺ*)-rr1 x)%==}dggr杳9-ˏ׮c[–-%\>yso>>C0,&I`IFQu=墑WwsxiMW^B~v+\.4Ad3'Х`'!*.N7rX>g#v`79(I r waFB8MM-D],!aft:ikoyNk[;xR^-}/2SW[N!hMϳ1.**k[^F]`d:I26MļTVWRZ\D#±7qy`d2@G #Qj)˥9t=okQ| 3={#:M"\؎R#m¢{0,͓Mmm 9)]"i$̙);]K)52{9(=14M *).(8CC=zƦbd낾Vښ{I ArzLgTнti49Is(xYdzߺarr ׋_w}#׾+ڃ^JKKnt EQ[N${bD5+l]C26HPt^$#]vB+K"aZ)*kԤlM3h>vp;^}.Stut2JWLYq.m=D8I^^.m5t\P޾~v;UdeeͯI\Az[F~#՟rs |Y$Fho"d(*+DENnL aFol`y^Ɠ$7+]݌GEd XLO8Iw`n. .Z:TUwL0T @^E~0tv0ɰI2sd؄`]C?%NecdtP PT\מj=J2LP@~ %lovvu .83iYE H49 1[ .C:; Vg0-(khfez72R <|]4;uN f+#дIr,+/KZo;1KJ$ݽ}- +4]KMj іibI@Y5k;#}Z]k@K'4 MC~fE7qΆr IDATiڧi:MWYܖ$qYS"i`u]n8ܲ0n-SnWLN1B<=ɫ^;oż_"ZAVV&~:oMӰllʗuRb_]֫%e22^ )gߗ?7vL^7 :꽑זٲXݓo&TW嶕J\p8WjqK6FIԫk}x y'8`ӎm&8?eAn:y(mN`F9ϝ䌿wo&hwϵN&I/k6oȿ@w@&hq>~G$b(Hpi/v={7u^d x+O?s+y]d[~yMK&-gY^Pȱ_|h21? GzAN>G:ЮS;B`Y{=No_M/Z۰;]Zv7PDBmvbM7ڦ(( HryDN Ag}wP&'rv59ls 9?xU'pl:MVvT{8F-& W7qQ.-,ӈM#\x{znZ_$;L&@ #e|rÆxΜȑc4u`ș`P( ]9˜@ t &$ *x2bNP4"}938IiQe!"GOf})|j46c$d]L\#>aV,_.z191 gpbR3<{CgZ$Lb?l3"VREyEQe[6؎0?U5u370qσ=|ʠ'07^a(^ I>O̒ nqy=&Ccyr!xd2ɇ"l۲5W1>1H=_܉n 1ξoaijC:xFZ ) fC,F:D,F$<Ι}Js6nEQEQԩq_;-m~>Jl` .$0IC٥1(aۿƴ$hxl)sKtyĒUxnc'N:[6mĺI U|lL25=Fۄ}4uL+! } ?js"*+(H]m&k9śO;%ed6d-LÆaW%<~Lg&NN׃7#X LAJ,qq\JlkfB,2 YndƝMQq-w`ޑt'm} n* EQYD24RJg+ݜMR(*v 0I#TD' Zj m 5XB D8d0)%E99=kD2yea\RT) YȤ%>&ȯWJޘXPo~u0N|HQEI4P[ -CH#GVfˊri>VX5IkBH#߲ e2ȡ'qֱGυF MKKn&zȫ]OChX)ZW\34Mz{f1c|b\v +P(D vI;aaice pxxcgۆhF ))kfU7wIcUN5h4FjQtgyYMN&#LAAof.s\(|c٫ȝ xq_~x-)&opYdVX{OX] NpyL`?r'5!4 bٰtH&ٮ4ӏzlF}lX/0uRV 8 Aar (Oݚugi-+nczY@e~5ˑCg KA,<-o9~T(M&1"95|ȯx?;?#(vIpn([- ҂`.4< ۨr 9Z CnF޴{LXy^x%^}y/?| bs/K'2BØ_`S=(O>${s֙O43yn_;՛{6=?{)SGa'<\=Xbñ (7SulmBfnu}̖YO\AMh7[fgAev*r &a=;goıypqK'95}s_95>ft#}: 8mvl6sMpt(ZFyЋ_m՜;˃"sʵ 8lUfu1kѓU($%ҝʪfb-_!R D3G.?RUWOmifsn/qT@1w>\0-\nGϭdۂ0s8X a* }q/ラ%^F{;hlLpҕٰ m}Qz:;a]ʮ'bhp 4 HGitQ W6+׬0`߾#Lk 2bQ$6 ?u[X&4v%AbŊ,4-uRn;*`d*iIܙelhB9lٺ\d<ӠXh]=BaEY6l캗L+VDZ>ȧ'h⭪Gf)<+332Э$ɬ=!{X>>/MYL\s`K.^$#TEW/""I"q.s~#4t MqOu)aMl@^ZDj=y|h#d,&1n:Y]ʱ9@84?LC;uC#-9iI,,ei$,k5݁Ó$HL5{v%\LDD(#8p NL—SDEQ!oRc۷ksKj2ЯѲ ;_e&at@h7ʔOkBҧRkc '[jf r"?i'X\p_e 1;l_)=ƫ?~>T\tbCd Ӱp.YŇ^[ןCx,A04 2<8myUxLĦclH40^|>^͋'%IX 2 #EQރe"BkZ:M  d4> .T6 \ݳ\7ɞ=1*V-Gsh:$kعJծebdC:ݩeE?eɫl`|ޡ L ArzǛq۪s҂>!`sQTf:4F ƦTXA84My~J+$0qgy9<2}{ Kh$<5WLkgQ;QM(Hծ @U\Li@щ U;: sP8F2dz~.mI]aBJ"x2}H@'e[ع"38`Êtasuߧq:mאұ(ӑ(ISjSl6br`pX4Lh*e$qL-k&;~ľ ]LLNN`#|JXl;͊rƁ(6]G tBJ C]V306o"o*$QFFJR|uf;4dtq'4pJ&z.Hvk}͗ d /%'Ϸ@CKL7Nٖ5z>~M/J,( dazEQt{xp#qQTʂl9g0N[RF8mpmѱ B '9k#Pd8N;h?'棟灆B4C:}aa2i9v;@_Ʋ T .qFlc0Υe^.;;8q"]PS UFlg %W5Z/rx9Ekg7cQ|5gs(o> p~˯,YOǾ ~qKs_{=(^ڒ\\. ;k:M^K?~[XYZ{)N\gϴQsl(92z,Ο<3wÂ]MI`~rr ׋_ xk_BIz=H)FREQ.! wpIz `68DJh/MMqs(H5kO vpE&eXVKڰP_x9:&4W09v"cqG -ۨu/T4BC=CѺTdAL|/[IUӍ"ji=˩,lݸdHz`l+䤸`.^N<6Hotb]C"MJcnHd7Zr=60™1׬(BRs7qa'eyWå@[#ҚZJr}T; = |"+3p{8EQn!fOmNM #RcG=5̜9-yռ5J7B@XuUtpGZ&ḺTVeb2͜BCI&Us§U%EmȩnNtSVr(rs,şd,ٱj$Wyi`:b:@ &t.7>&j>7cF?WX,%Vxޗ);0段ikX~'XS]Z`DN}IEyo,M ~ 3?z>C E=⫃`Ncd:LbsхE<:3Xͮ;WTA_#fݓK}USmNFL @1.z./(!KG^t\8 {S^͝+𼏪!B@2i^bBxqcCUA&vJo:OѰ\7]?xeiYdo˹w! >5_ew`YY40,M)-^`"6}\"'UQBh-*4QMCKWiYX/}(kO !}L M %Lh$i! GGztLT5E SZHwuO>LUeYXI%A9"ٕ@[efQJkv-+b+5;,|wkJC44m5`~2´DƸ|UkMLoSFdQdԹ.pD WasԬ$]-4w30# r05_rj qv.MZh.?5WPA1zڛ=FEV|plV&Z;b]bsdU}: 2F[y%]*Y#m!0@_T$Cfu/wr>?;^J,lWаZIFht6< p/L#ey2vN(;S=@`FF8 . CMl+ GՔe:HF'lHSJҥˌYٴeEHўVZ&=]VǝV֮K3`U;0ro:H&90g~V.;IDc7^z + jc:~iSse퇯yOp($㧞y4dQj#.2ˏw ~1⍟|oQ v ݎtj.++*# @3tuu1sR}:SE2ȅg^ichvW0ap9-οS~IbHFN V.$sHļuw^99h$StL$HzOqy o?KTMw?x1{;A;5mVwG/eY^wAVcgIJ{ڣnj gxiiDV +194aE8xbejXV] Kow4 Y^7&+lIVoNCu9}3{ ;ɩ^ƍLuϝdRfcrrW^},ΟȱٵywK7h5xM +ʧ\Vo!0mDoX'B`w:ьi^pevtN;δY×CMU9'.30$)v ݎD l.3جƜXHKbY&“C}?B[S_V,ɜd9(GA,; ].DÝc4 r};޻{ȣCscBuNaMU~mfk@q8]NlBa3Hho 4aoIg0s0eJP^VE~n&r܎qg@D"LFbv?~oa'6Ŧ!Y~lwit\,ӂ@b;V 3z΍ؕ"8\v7.#F$FVF9ߠZ.Ν 8x'NpΝTVߜ2,n$h SzHt9{۽dgD"@{?}Q3 SޖeC8lW ]$I,:蚎nӯ;&u|k~)/$)!1i(7pq2V9gLNLbH7yޙnt* 4ڙ^#]s3k-}JL/ġG6᳓a*7V+7rXRPal}SXa*Gwn%@&l \RDܜ=ww;݅2'"v2Ot2&ѐ-]f -aHX3yBCh:MHʹٕ̽rGƕk4{2)n;voΜ=ǃGUUK(5x c S ekW2;{21Iqe- }M0Ejy=^啣$ 4$=el\ir#MnjL7D֕zvF<$eL3cRLŕ:@B@,NJg;Q.+/1bxGȚ8*4t]G4`,T X4bN5ny$LD,(r/=˩1Ilz޾Q R} }ĥ6'>3s3ۺ OeK{{]Q_ă;0`VL;BerVW{|c\>jy]"70QIڃT{EN0LqF(_*Y:6]#<Șζj\6 tti N&ɠC A,DJkѧV)%;>9***nꍯ> +P(D $9Ox(t-qKcR,ȹ&eE$/\觿Z?P҆͜I's,˅>}Z$ |#JIǙ7yHYYks'-k)bC&$gm9avI#I7gNNi-3p$b&'tDhذov9Ŏ5d :aPWZLQQ& 3CԝKiq1%9vZNdt Ճ*kt|/fzܱe~n{={[HMK{/Z6ԗѢ4<̞CWfYQ-Ƀ1G<%+`i~/U-K&b \>c瘔YTUWPYZ5޽P_/#1|t;CoӕGuM Νkt8I9w$6>^mrr ׋{y#׾k6,JFK[THVNl_j,dl| o~%+eRXRDu*V-+#;K QaUTx)m`ed5e^Yb*E(d=wRhLjpel*VP[WF0+n01# EyYbJz(-&?X@nBJ8PC0eVR[M}Yc>i]5ի*` S ;۷P`jb˞M]Iy1J&3 +) p2X|lBϯ`uC=x2Yz=+˃16,) 'B*k*:lNs20[VA~0H~6)Ņyj &VQ%/K{ϝ ]q˗Uⳃa%'̦(;ܼ > $ 1SQ[Ga< X@MI>>z6#\?_ֱ:,eyY I%+kZ]RJ\Uu-bEJUUS[OfHL8((!/G0azb2r,#$P\RAK͢ K!Rz?φIz 멉/,Ӝ7h 5iΝH#=e^]K5JJ%nsn.LTrU9f|H7&MYfks-2SJP}4!CCD" LТ d4- >XRy?g>WW>#B̟%um8-~NbZ X4Rsci?wNV2b4yM? ݳ'멑]&1WΛ9&m?q΂8m8psMѴ>-H}th.LKξ'ɢL9&z (o`0kuvu bۯOde^$Iia T:GZ_pg9,\4Wia n)1s_[~!gs%-z;4yAۼY58ה%5b!5ϼߣiFh+X7<@׎%߲-\V/Y\}.?k˲{cLbS+7l|MKv>#?On ;{ЫϫY+A4*+7uj \>" ZO#r$'ífwSecS MZpF~ GJ`)w_fvS*f,JW&QE1DiF2$aj6EQ]y,9)%LLL6.(-!ӟ~ Mt8(-)!} EQ!R Z*+cNy(TJEQnr(܆T ^iPu( YMBJPVEQ=Cߏߟ1ELNM j(ida4- ML$q8~h(2(x|ro,]'n< +AQ%Z!D'˕+ W/9ϒe09Kkq@ OOy軽yPE=,R "6!4RBea"3ÇM Sұ]J dh4)L^nXR/ˬq? N?K+!&{yge_?lܺ(B%[L{@1~8;w%S$꧗"OЃu?$WH#]xH/e Y]Id2]R#$BC4:E1"BJ9[ n*=e3 '+(8`TG?Iφ4\:}Hm8W5MuX̐R(e"w-W3xe/f"b+pz)RwBwէ(hIvBhN4{: 0MGe"@5eaZ RPJ蚆ikB RZ3RJ9'k,+~|&i iaޠav[L&-3! :Kv:Tfa$ ,)R}ijΔ!H_y2k.`ܥDt@DzSt]GH ü9^r?mv'ׅDC~ 8vقc!t;iL^iJ>G)S-C2>(AKմxT;"5]#"3ȾC>nNsO#زa [F6zK-8s+XL#=tM&WQ[CL 3!$`KarX .`Ǝ k) a19AG(ӑ(KdnC1ZYKx cmu!6c/{k/s[PcjaBQBWi`kmob^&<Ja 2Bws SV+-"ct y !{MRVMj0.ElekkC-.}>]WD?!1 n^L]d/8>nA^m#2 YKWA^Qyųho3e!jÜi@ӗ9pǟ9#2sb\4_ϾIpF~?h4}10}<ͦa]?cv"1Ѷ#/B'y}brmazI"l:KY SC-.@-^2K(KKhf9ʤ%S40-(([c=M2'w7a #{81^y:~$y' R?ߞh A^.Ͽqsy#-I6]l:ME^9K|I+7ZI'+3O~l0"cx{w~Lxع7#|96G(* bt2Z^QAFc=wy{qSʱc=8zOrۗ*6P~-ѥEeC-%|[wĶy=ž?26^w_i>e#L٥ԖxSҰqk.,3G/tLpdUwqē}W^AH!Aby{֕"G/~<]jt1Wj/Qڛ8vL`"oO.˪I@"f_?I^S-䡢(Kxr(WH)qN+NeUgΜcTݔr,ZH$˗I^ovOvkjs?sS- LyK8q:mH"NfW'N]ӻ+\l_Q̇Wy{r)Iڹ5i絁$ ;<!G1N,-&'im%a1{LKJ-;>iJSk sv>mkvt~1K˚-Ɍ7sYZ&2YQ4UK߀"̜eYrV^h%ϟ,gC ; >˟O}@0G?.]p!oB}}5CgK%JIi!14MG44$ [X1/QtL&dx<** +*#g;GJxhpF3eaҤ,ꉁ '7Տ==ϼRJӘs˗5s`p:L&3{ۼ900͇00 )-@1 I"gz&RG°(]Cq@]~퓬S\@MKBGSl]Y]R[ZTyg/ s޳DGrw9/yHf'Iƒk!L1P]s!f^6"=F#w!H&'2c} P(r{/稭ǟm˿? B3o_|Kb)hx_67D.ݹmxÊe8a:Lbcݜ8Hع/@-ʡ=9(=øs8":GZYe%~6^yM"+cb $(_g.S Mы)] ۟`=jadhA|E%D|?h7I,krib\*}4˾͌MLIܓOQ 6'B\V2MN282sbzff`8~(ɒ|50OSC,,/0 ͍͋Sz~* ёdw;7ZB#$$>GddyP |3t77Eiqvx& ƻʛt'\G>bfy(!(QדV)*r麎q^mSx^t}_W=?]O0ôbY]1"!<5@_=C!WSk2 sѥ۟&Lm}/U[CW6(]m ؅aj9kjKp5 +׬00& (054$/b3=RPkqj@a5km؜~ZK}EUqNܔ5&q Yy#Uy%d{\6m?|*Iy_\͚:r<:jZ*ۜ~v{ჼ˼q#C'_c~0540v-0;ɌJO|0כZ1&!u|MRMM`#g'4==Εq:L9{2ee$yw_!eD7r1I齴WqWCޜ`On!&PPP0A"Օ3r.e:)QΟ@H?qlҝeZX$CVO5K5ɍ(im9]`~? |"+3p͆EˢÐLcϟ V/l4:3]=;]员u.nX˝Jis~32%WSh: 9L (f"X>._WcIN-XyO*n z[']KK[]t{} c~ޏI(nTf{b=x!-4SD&ܼۇ^z|vBÝY%{;jB2pq{|=gLһM+^^l]drWa4]κ[]KJE+*muRQ"NkV[`jADEQu,@``]`O0'lo3 ¿ur75WfUfưcEQ/f{'W$LEQ%mW>4L&1L3.(ʭ%$ #=t6MSn 㴴%Q*\M"|^n]xeI)q9F*+A;7˅5*(GMέ((!EQ6蕛f)DEhXR\ط M3 1q\Mvmx2M1ĢW@ &[8Xlя+AFoo"TWpxt,&l7\K@,cttༀ'`xx4ЉD x<;:6N4%##c$I222u*+7E"tUOQ륥mmX`n.>w'˲,1e$_c75(,^VZ6˲2KpT_4"ݜVK &Є@J i]CQEYt.T/aO*yKi6vyy0͗qo6o\OkWAwl[Gdj^6PRA^Q妑_h6M[jn0}meo|*m s˒>y $#%) pM[^ (6/h'I^}=eY? ֤mz/l6L|2~ӻ^5 $6&gS &G6bN,$(M8wX;رhN]`h|wm#ϭK L0-'ku,:ijjf]-`"ƨYw'Uv,+@Bouw?$ZygG9?F~`~!=] M!_@^+ͽx9Fru+F34w0ķiݍeD 6<ħ]wOe01Es{?S)b"kQ`%DDžZE HGUl8N< ,jY[ԶYӽiZlݺ[aZ7|z~փ_"xtMRf-Yܷ5?L}k˶-ys_]MN8⃼'aJ6Vp^&X t?Y~"ïrj*+VryG( PK/C8 ͇^u›/Я-kOs`$GF3ɩPɘ\MxhE39o\< 5Z !j__ K}&(&+g[>ukڅM'i6$Zټe J*^sf߬ B`Ntq%mw%n<>jV!&l<ÙƭZe:zA.m+܉Z- z H{6kOg:>ޗ_u_dyI IYY3aˡarj+n,~1ex((m'9k[X ]=>(ޢ"}yF}(D+k{Cۄן&,/cvM@@|COsՑu ,kw}/DxE]~mYl߾+V | 8kF,iaaǹtuuuxkny[5ͤuk..U`<, X{?>QVpû2/-e!N b M]D+&89DON-ݡ>0HO4͆]qR s|)A<]QyMWi$I øX9q7MNNμ7 AdW95o>M0bb&"īOBE [7g:`D/{6z meb K|w0ks=I{S?9Tf!u}U#? --f6J##4706J473:2ƥml)gC?bϏE˩ԔRr%EgxNEusfBREyϐ3٥PCN5/w@sjWw>y-v&^iX^@.Q_>xzˇfr?/$ ?PVj,"77sxE8)f^{eI$}rnjlQjRJLceeb\5;,uIR7:ŵX1on'Hb5s/Uf#w7*(hnIee%UUXƶ8[{^QEQnŨ/ VY@NbP^QEy3_b7u0b WUK)(,xi;3RP^QEy_XP/5RPMM"R#sVEڍ6it]_ 4M,N<6#IdjŦrS\N&'L(x"^ Jtu01>GhFvv6.CggעWhY^UTW2=SjTs \M6r2x]LfR t]n_rQQQ>;bWӴ+,"znu1EyQ3XvK MUe1ܪwʢWEQې (rRMMc&ar+EVEy/B`ۗ$@x0 ѱ1EQfH!+3sу ʒBOcmTՅREńA[{>߂C RZ躎i*+u!ĒdD.(^4ߋ*+(mh"=];W-2((7ע& ѩaZ/_Pˁnw,dz} ((Kjzv/ɼUg{iesOrq8o}ܚy{QpEQfQ|@lG>HK 2دwZHLu 6gּ̟+!4@R!Բ,kJiaYr^9YGK۲djI>-Ѳy9:1StAfOt1i⨇uJ Ӓck1[[6+(4S9f ϣaW,\elϒؿ#D ᥠ COH6?N3L=b|z>'( c1KgF^Q)yOy(-)cKuCNFH|2,S )  4w9m;V]XF]i.~G&1p_\Lǎ (M^Ú2s7QֵLaBjWcdWRec|葇̶}v?,V6Td2~cg(|/[*L p1Z%旿l/h6[6Cs)y ܻu(r)ĝ#g9B{+O8b 8Ü?q#_Y`z3m2xDy/!9Ij(e &YqeYNEQ%4$hf.!1xp=ws]|Ly>})ӆ'<͸zN>k_ AtdvwO=$, 7Gr)IyZgҧwwMq/ܿѸ sg{S 'Cf1"r5w?(=yw` :j*rx_oj.bI䣏>,'_?Ù xEQeiQ81X(JM&BD8r|eYhH>W Tg/¡((i[h"6m$. V'"1vL;%H6&HO|&T@zl=k-f#ҕ+cHp0I Ánna4Hߗ\ɚ{|Kj6}S{yL/awHA]5+(Knq&z&s0C4;|;9AVntW^/uKF"-@^a*&Fh"G^B"9/4ŒTm{AmǰA.t0Ԅ?(ʒ[/WoW+88dHn<,'qyqtfNcQNrz=%>I<%24-iFD"Db , DDH& 2=M4%HHD#LGcDDsbLGJWr {|㱧({}> ym%dԱ~M6%9^T((Kk*9>1 W_/D)%w(R=JONM<#g gDI_^CT? rNHM*s)3kuUktO; ccc-ͪ(@n4rShFNNjEQ4mizUWn!jWEIT(܆TWEQې (rzG}3QUQEQVj_>1x$NV( @_:mx!99OLDoy+(mM4uz;l6[}Ί(jq`(*^QEQnC*+(mHMU(>'Oo4ߊ (cda8RCNN6A>CxEQ)!l6nuqattvp8R(>f]o˦jÁ@`:wHxEQ~1'k [QY(-"dӺ=(Xj9:i45M&8EçF׮WyG}"u4 ]д똾ba--u3)(%2k! Fhmm{`is`Σ\?Mi%tY\NC38!4lY Ź~t!AJ&91bKWpǝ)^8k#lc'չ^]#(mK`&8O>Mgòլ]$~LD^YƭmK sfv3)dլ[]s}_yjs=Yy×y=8Do3Ӕ,#?ɻ +] qA>/sC!9(a8}\M_x3\|Bǥz4y-> _O\࡯; -"sW.wduOp[S+|wUyoExEQTG5Bk9^O_ᮕH9l35waaǔ SLMǰdfff2FqiS0 Kvó  1k!0‘)}NL'"iuFd}x'VIذYVח4avu?kHZ]'(wmdxtynM^,$ÝN=HWYf^xVQ5Y7rR'{OMφr=cQ'G'kC|:}\l"nD&JY_yt {w5eHg&  –Qƶ-†\{hWEy0a$ ,uN;R3>cI7OXO>X 6 !H|s]o{up{fwfv+Klcc&ihKiJdEi4xH9}j>&MVi KS`..| &lwg>hay3{~9s򫶱wk{ ]Mq(8IÎU^߿|i=yۣ<}︆o25Tnj_|s;:-hĝ!n1I}(zI,ãx@F8ie&Hx5H ^!Y"$ƀ/?jҊ*&00@nq%9OR_SAa? 22"Hޢm8ޤ2&І*E2qivϕ/4v~ZEZq`uxn4F\'t8D#vcP|^"uOMZ?H ^!lPK j> ȵh3LXs֙V Zk1XB019AanN$IB ('/pOtU|Jrqk[,*/sP_P05BeVFKB? :]"f~C 'Q $ !DVK'{;;iz4VfYx\Gk;`m[El?GdV²&[D$5F3z&3&3["e}m6UlcK|zn ^c)R#?9s;wlmF빲kfˎF~}cG՟?!1}NW& ^!bceyk4#5w2<$q453j@kuf<;#CLOqFSA@L/|C4"e|kL\n}Hk:δr\/AQ=;=>}]T`IMafE>mnQΥjs9th 0IENDB`Eqonomize-1.5.3/doc/html/C/figures/editbudget.png000066400000000000000000000631111416454732000216630ustar00rootroot00000000000000PNG  IHDRc6m cHRMz&u0`:pQ<bKGDjtEXtRaw profile type iptc iptc 34 3842494d04040000000000161c02410007646967694b616d1c02460005352e372e30 b^bbIDATxw]}{ާ`7 vDU˖e'V'ν}$.7JHS"A{3齞^ e}g$}^o~KOLJEQEQEQcJPEQEQEQ;6׋B].#JJՁ@QEQEQk_4byvGXI<Ħkh*P{v(((L& IJ];"QR\E5le2998] EQEQEQ`7H`YGnVJ&El_nZ|8ێ !Ecp:UgEQEQEQ>n1hvUKDZ=9&mavmH2Ew P)A4tMSm!,,k5ZD9d)rRbR7yx@״Æ+ۖҌwp%Q%((|Rk&Ct3Mc5R뻭i.~.)tir* 9ͶR?\L-B`%tw;A6TH,M^y=K*@ 5Q|1~s1Mxo1.^d$Dq97܈iKfl~ϚD}ViEQEQEQ;bUirz&C\:K;Iixr,Ǯz`&%x +_]ͲCd$7+dl|KwI nK %[VMmY m qQZ?~goFNsiaTri^~+((wK-vo y9lnj ٧yŗ(.,-qRwZ M(kzAq8l^ʷA7ͧۼ؂G3t ѣÉne+ҽ,8KW $1Ǔ)U+q喲x< m;Yf#?L|O||SmtSp8_0D&b8~*UEQEQ#Z|@.iw>Uh!\hg3A3)ZeH)m:XNcj^*+ NWhYҚ#-!t{g8dšsl ni1LWJI/50Nhr[5Kq? t8h?OYr[(dEQEQEQ䣚& 1ɖobyodm795v#sfߛmg&pxvv[0⾭_*8/Y F:[w0d/cŚ5^6C`/S_>=Wx}RN΂$-_}[}/=9hfj:/H4UTWȝݯ8,I_ɯ~,=5|  t'Zv`$a t7U $/7)4Hg9-N^ymQKjpKYYCJe! OoMJm%VEQEQE nWR踽>>76- 6FØSɓ,s:Iͬt$hs:Xn5Aj`ɴES\x^2ٖa ,K"45F`n{vyO񆙫%XiR^Sݸv% t[De689Xi=y{ص g%lNd'G,,4MLkvKBMk(((G-UeJi#/pm'26GX ijqճMs F,l6dd4+'w,{_&21Rq"i4l$b<4l66N:g14[ߢe iC$)iKJ4iŶlv"DӚ#۵FhMa&}D%V66OhΞA±c 04FFE)tA:mj=ƱP!o ȓOMJe ,gϳ&a{;:v'I8eL(((ʝ_7fD0 ctlGs|IMaa>9~hŅ>F.py& ,p>Sa9quc=:xah(?ƒ LJ*/&2'8s$cQL3poNIUeai3c~] q]&Gy7uUv"jJ'؜^rڻI Uuݘ=]]씔Sn&f,4NPVZ'It|Ξ!,W"!77 Vncxr)J ܾ\re>K69<m_i]Yd%^7WMev{ٱylB2e+j-?1W\,6}̦ eYW*̌"{LS(.$n|3 ~|?%r~jUEQEQcGiߣ -]JJ*Xv9\QEQEQCi:Gun WK+-zb^P*((rW]ݓvTn1?cTo~,HiFFGFw{GEQEQEjJIU^Vz<2~$$?/T*GQEQEQ;I<@JI0nW`cNww((| !$ _sUQ׍(((w׵TTEQEQEQcM(((ǚQ((K Qz=\q+ |)%!R.(v|w|iB֝RQ>B.WLi((%"( }x<0i(ʇtRPiv-D1jʢQߚ; Q\TD0Dܴ((! A,J)" qŊ"ddd!*++д+x,HT'18c㳦,!REQnaT w݌^s)azu(xV|ji)ԏ(G4OP8kvn&Խ݃b!BKR._;1Miq6q% =Dʼ(|4Ǻ9th?g/_&Ǒak2{%0%(+ $}8|qaU >z]Ov:c7}qi >vpcQox hRb%8o1'8f\ Z)%pӅX4'?5C߲1SӠw1}?q܁jQ"m4am=B9 'f|ǎ6@HH,7 VgY} v ]9@uylmP>xɈq֞ E,_GЙt9±8\u7sς2ԅ#NW0"N@`DG8{a1N•nr B0tWg$w&% LbkwPYz%yܗW8e6~e4q]_>2JTS)|8ǷxEM+xYߐO: lț-:7tMWhMX ^<ϟ}Qw5Ǽ˜dKq:e˪*NS~s K̮:/_>Du<؃T~ӗHk mzXE̛蕣ߥx|};d\YOsU.NebvK4; q,f^Y.<H3a]QvxEYdb n=|O= Om^;ҁq3[at˔6>?6] V>fnK+!Nz׶fo__e" ćoլ33?S2 /ra$&2ݧŷ-?pTݦ;FAGg'Ox嵭Dc||+`2%IZOUqB&ӍHA76Bym12]44]u]Ӯ)ih>w7:c3?}f7ִig[mEQ>̱YXJE|X2ƥU av'V3wH9><@&|6%,yka֌z&>v%ykjo} GRj6yl\^E7hM^8wodú$u, $8ouFl"-#6:OAνsgbk/rvnә6g|~zSHnIcpilkK6?Ȓ|4ia@))VhO~@[ ˶=lj@&ʴgap:ufu0vW^Yw$% ׾G>+/Bh; 7 7֯E?ǎ#HMd|1Lap3w͏w?>(tLJֶv^c+/Hy}9uRNKk;х NٙDD"dAeNiqkV2œ{bOlZ!AZ^B[?(H7/uhEBsWP.`;FS%${y?#,n-=F K*VE3$&2x"\/'vlH4GUH9̪H/h->i]bY! :qS$8=ԔWŒ;LUYV<ŶH rBlRg=ccTZxgn6nŋX˯Ǝwvq8~, y?{.>L͚jAS/\HäcXO;z-4 "c^LU@630g˃_{8T==ECNd{YEߞ9Vbo&YEhbjOeJٸa%ێ[/++qa6zǑ<ZAN,?ϸ,Bije*"FOEzGI[g q[$%3NAR.mgH҈sѸAaMkIz8ty6PuRy~ojבSy 7kׯ%M ̥zrܙ:Oyn֕ Ĺo,(YHq# ݬ|t)^]bޑLAgW7onYj%HW_onGvֺo?|?Tds<{ò2/BIM^ʅ(h6r Iaۑ My7ыX|{T2Yh&xG䄗M؇OUM( _FY2l}' %aV;oFo+md"[,"mn\6-(F Ǖb{[JZ׹+ } w];FiM-AF L`([w^TϲōX#8>ݗW/fU4ז" vy,_M|;6Ddo1η_=Jc۶rmF:y{Oscy~z@GG=㱻R> Z[9weF(G'ِSH8LasEAHF %^7;!>9B,i.a^FӇaU/c~ KeR)%aqzV\Gt:}k&Ghd0No(aiM.@@d{,x}撯A"Dh0z ؓWpJ^e/6>A1֭{˙Gy$LZj4.](s(+ qp J>>pp(rcR J<_G;|| 7"{.qo!էW_y20L+Zh]vtGTJE[a15}6lvd:idϲ Tz[y v)%yM][},e+mdxmϧ,,D!Fן~ĂϱfI#]RY-L^ ƅE/\g4Acn>?҅%!9&67 Wa}-Xͤ._bKLX)&Ɔ0$8w޳7B %I&eMwr $NN, b[{1<ŢJ,Sر[a\Vt d>y$~YPMZx6om^3 eaмt%\XL ֭Y@c{OQ4H(.arl/e^q><,$zl'nc=i,^vJlXv-~Nxߦ6ώ-ː\ T7fMcQy갽OYve.5ԗ@5WNvzIܝW ю|/ۗ?GzZ>{̌ 9 6<\.-,)f5ՍJ Ǒ2@"sIqwmEWnb HiaIh~kMrRECHl/Xʽl9^{<7?runJN2zMYz9 *?]p/.3mՙp%`9s1u,,ˠ Nj d4>]4邂wΖM-[G ާƥ89˲2z۷1Z(ŋ.2clxK)niH\k鏦q9pngf(K#ZTGiI,i!4]r 0579y.4)<ҿf s7k(!;#cGT\#x NN2ÒldҜ*vvza19Źإa TV9x2ǖe]#h\VlXk3D }ʽWoLbptҽN8t/w! CQQ!7nno5$-w-_ϗa,Eݎ^I:rjt$Fؿ%[ؑRqVKͩgn퐴$ebX[y 7O}1 \X$SÜM4L3dz\K pلz¥(raEI&L,'>}KhƜQyݎ4@ %˩SK;CJ <A+`:Q塤ўA"i Y4/(g}a,2CQ[b zJm##7Y`FJr];vyen: idU NcMMF"m:8^•7]×WDiaB~R<ϑnYɯ@m,+7,o&gl<㿥DhZ dzNRez1#W^r=NܮL˝t Ob&a`F>btYE}]-mgRXXn_~\:Ιp1}5t?uN™e1&ۚksfq 6TЫYBYeYJn{ʟiIqh141Cq ɴl&ȩ0DlIdH$ee~4\U4mڻLFK3'Ux|f\–[Ƣm}H&xIL 6 b(mO({H&(\`R {p [6r NʆbVJ4L>?~S_4M >ΛЩ(dX ;'28Xly|jr]:HN]g PSLmG؝:sp'F9y [xdM."S \c[:"hdJ1G/q+J쩳86Z욝gӟtqe[fqE` *8y 'O{7RXX9BH ^X O୷O0`.-pN}nz%Z\OA^!AzϜf(mnƸ|sSPcc,f?*/mŹtm^?C弥4Wb3#;~v-{vgT,`EcVlC۶qb¼wya_ y1vO.#9regG/^ɗ?"fQTF('i٨j^ɽ (A%(1o fʃNCiEy/,' K/mb+(X-dA"},ZyL4'euM,l"&XTɒ%( :N.ϥ '&C"FXd2yS 1=*J(.*UX^Wf~3E48f[#;J124@\?9L9AUzQnܶ~~p 5N/s;I)]ׯ))aOuSK@4h܍13U@ӵYg7ee3mNXC5˴2]IJf$ҴEd{ΌR)P2iҊBdu5׼?11eԥPP8LIq{YpoLI#M~i~ uJ2wݖ1c3Ҳ0f&230fofe^/inI6kix_ϧ(2iYiYfzw=~- sb^A)oXgj va§3uEu{zVε3yz֊ef,kV|UyuygnWS:-9Ru{^J)#s"QfSDQ2wAQx?۞/f#b[gk^Ê6qӣ)(rHU'+,RErv&%6o>+{Ŭ7mIQEQڌ9oEQr|<߬۝\QEQZ{(ᅬuap,+(<3RhBH&h*RYZ2p^_*lՕ*\N'p]QE%Rq8w$!yd.TNaa5>k|b z<(s G87__}&$77qvqEQC ra.|(h1v2>>eEvɹRwib((Q2uPEYY.|hJ};tӢ((|0=IBQEQEQEXS(((_EQEQEQcM(((ǚ |EQEQEQ5*(((k*UEQEQEQ>>B@LeBiniX˹XͮJ|d|\2sln<`%B ͗ \`w0]((s Mfa۰2ݰLsj^?ˮs#m:{z 0q֕kzu:*y_x$i;((A)Ϝ Lmsذp ilj(vmrFf*ĉÛ,d>T4 oc˟)>HB 8-.Ǟ̜: [8t$Uo,ǥY a…vd~=Kgurֵr5,Ô6rʮ.MiDO˗n |O3a^iaī~yf>+{x(GhDZy_#7nd6S1.'W|X$hK]vK!$xXtr2i m>H͆!<;:㤯- I)pz6eH$0L tGd8?^zUx}\v}yB#\HfI ݚW_ѵ 8 !j% '{;GhX^8=^[hGi/Wi*bqI0@#'⪣,ϋeJ SƉ4o-N,?BtOEQEQ-3eIK4@"D_m]}D F05ܿe db0P ן`Srqߋ|c,ܟoh`f"Av2У3_4ž+-Vx틔\J0Cg`e]>lۺ!ndW96:ioie$'29H֑nʷ~/E0[mK~l;8z%eQ]@8X0qXq%>x/n%F7N_PiDJKy4{nF:عMΧKP)N\r< 8~t!YX$:΁C'4ص4UVfQ-.ǎ=]x^Nj`ArE̸TA4Ͼ I iMe,Hcol%/XPsVxM.4}].-kSAeq|??t?)D\4F2ā޺Ɵ|v g?yH?K/[?bן@O.|_*Щ?E>X 0 ts|'8ߛ`_3p9FsG<|&N ;.H;/i Ҝc>NK$.rm{TE#;O h̞%ֲ-~I05o`x7p!XGiV]+/Fq&ny:#!vv~o玳/ÆDX?Jai'r RVX6Q3~]{[3jm?keyy⡍JפE f8HԲjq%Z*LJF@Yɓ_"okX@*̩#}S?C}axGLj2>o~sv8c|S$ϿcvGT-\)< ;% V-G5Ԉ3,X _=ϽK۰аckG9zJ4g!`_{?zS=H!VL:_zY^~IC@ {"{%X\|6*)O^8ވV#Dy^`Ye3UNOKt"a8^rx}9֞c McB* XͣK3Mx(?#l}E.O$mxXFgֽދOwtI`Y+I#4asm^yU-k(gCOFWm} > 6emc>gb?ϛ;0dYdjڿbiUάfP4FzO?3]J KZ\ݮ/4oeyS^{HZG)v[GFJ4$1&=5=$2L9ѳ-HEʌNhMjw "ҙN'.D*(1>[)ni%=*=LWq:> 8t݆r_fRDyy󩭨ifXws;Bne95|~>j\C9[XE˗77aBN:!=͐g>+k Нɟ,_X#XνW1{. ÉnL][;_)$=+[EU4Ԕ/fQSe,_*FAm#U[%􎎒4$cvy+WR֐ɼiZٱ!飾qj-Y}p!tN=tL'`9pe4/^ƼF',{>XL9wc)!njh<?e8pi*s1&8sHw}OfۂW?,|5z"$1l ,[O?Df)tV}?<_q+zeB@:E1Ռ--sM J]tlnәawhH'm\ܞ ɎiaIL+M͚&Ij:ˆ'1Uܫ((rr+h.?euJ(:J.GABA41N"} Mq\f!W֊(([|!32q4< ϟCI]b4Mt/}ӯï'een&-ILKJMUwYȮH%J ܳךysN rYBƕiz $ޒz,PZZy8%."aB13SH'bȣ LJ&$iL@]Hi)Y_~_}C͟:9)ğW&C)D:yzfy2!Y̵kNƉ%s[ē&`!57MWR[D<L#3WßKaЅJFe{tE"0椨DžaU>KBni# L$=Ѥ1kk&;o{F㒥l\Y¹pu ˰M9ZY03 N"@tσ;ۜx}~xں М9}h3Eh1_ﱨ؉s'Og4} 1Ms֩;-#t3%qְnM^v\ }8,osy%,`"iNNwi-B$Dh"&Z˽c!D49) #Df{zPuulVfi"VA((򁻅7F 20%XFݪGgVҹY~~ƒ:U Wzg~3>OWg;'Oti ;Yn/B qb8DiXeX 5.0DO㣄Ɯ%1:{IKLreJV?r`aiLqճyS)G_g^G[g7ΜBiaպ%$Z(r#, x{'ai s)a4€ 9}.IH$cyW-[Xќ&_ 1- əWh@Zi!E~:W̙{Lk\ճ58tOĒ)4.AzF'2̶3"mZ\ y?{C;3ڲ=.44L{q.b4%בoc0Cmgrtz94R8<< A4d \X<-c)g~m)9x>FH-vV-a~"E_@QZb+HYf6N{`l2%- 23Y -3{ήZjN;0LsW<ʪ4bAϙtƥab$D͝NJ8wf,e|d0DD 9K[Pa`#?ʱk ^߂u?|eN\Nk'duFfb|hj+mha%'4hZq/U9Z6FϜO# 6ϋN/Az8w()Hvpa=V, sehY&ٸNØeAYQEQ/3_kZ={22/-MEu9ɞSJ[8W&$2f_DJdw8|@E 5TXb]\nocLIN@Q_#)KRPZCYˇr]#.^g$S>z47R08hGTW1;y] @Orh_ՄpulLrΝovRlشyS\I1ƅvz{z1Y!Vul/l#X>DXY ==ъYTu;s^|~*v&;O;Iy 챣$qF\sOBC(gEo*1j0N3SX"il83 q;:vy|n E-rwbDΡKki.aDAJF dxx.J6߿x0g;15Ą*J ()$Wct LlC!;2{_|'qqhPZ^Iy҉#E̴SRYCiFxGN]&f)()!rlu;9}r7LY2شx/eߡ Etrss(((cEioiqZ6LqP2=KB֯壬pZ'дVo:[Zk ƂM:7D&s8_EQEQLA2"J>>1yIJz{{@VaDXn/_f^O! c:v37헻Y[S3#`#:Ѱ>;{3)=UTPW_Ouiq4FbhN.-Ω=9:Zjgʕat[䕔SSWO}U)^0Tbכ;]iVTy2&M\.gfN\iHNzpI4"H>L Xσ2Md`f -./AԼ3ŖA:&cHp|JO17$fHvg&&$pyVt:q)N<œ@R tr;g|ft#I4!2q.Dvy*%I`sy{g샙"uC&.,#E4%4n7>'(+3T,>5ϋMW86SQ8>|n{vݒd,J+׬tj&#EQEQP(L(x_]A՝r{3k^cƸ=)I3syweuM,o'%:sAYzbF5{?۝ZnxMa)\e~2\7\ õq,T%KtNR\_s7d6u0qjgʼ>MXtAݷvcySѕc(f_\ZW+k񘻌WCv|q<o~>eΘZv׻/{w]ݎans~48G!O5*(/ni-zoo\7sTDMܼÕV)ϻeJyVUە7Z^7P7󚼙| ̟jzeܻ~nVsuɾ,S69K8u]u!M\)߃YSjM0z#u>E&hB 6+S\w~n.)%E3\QEQEsn-R!Z_|SOt=5mGIJZ>2 MAղ,8 /'k(&+6Jz !%[{((7#F ::`RUUA~WM ;@$ )*.!TA((rG?]?bq!Zf*&񽊢 Re!%T=EQEQX.G|Iiaw((U((((ʇ |EQEQEQ5*(((k*UEQEQEQ>T(((|WQEQEQEXS(((6VXu >5nYQEQEQEQnDb`)4A'iqM((((VvNsB.(((:)Wd{9ykSEQEQEQ?˷&eXIfII* VX d1tidigiKam-5.7.0editbudget.pngdigiKam-5.7.0XUDj%tEXtdate:create2017-10-09T14:57:59+02:00%tEXtdate:modify2017-10-09T14:57:59+02:00oSL tEXtexif:DocumentNameeditbudget.png'tEXtexif:ExifImageLength141 tEXtexif:ExifImageWidth1368*%tEXtexif:ExifOffset130aHtEXtexif:ImageLength141nܗtEXtexif:ImageWidth1368MѠtEXtexif:SoftwaredigiKam-5.7.0yEBtEXtSoftwaredigiKam 5.7.0 ( libpng version 1.6.32 - August 24, 2017 )tEXtunknowndigiKam-5.7.0IENDB`Eqonomize-1.5.3/doc/html/C/figures/editquotes.png000066400000000000000000000661371416454732000217440ustar00rootroot00000000000000PNG  IHDR]LɬgAMA a cHRMz&u0`:pQ<bKGDkQIDATxw\uj9N`"39T%9$9G>}޳߱}mɒ-Q9PH" "&< @ ~$w]]jUkBP( BP\k?׿7k].BP\G8y/y|J X׺ BЁcR_;h7u Bq]k!/:]) G BP%L B1o0Q( ż1!!۶ER(+&B_Hɍ4 ѡNNlb b,. Y !B &!H=z'['ȋKPܴ\0h$`"IJm$ sH۾Σ:>JqXкm?/W^~+`l|) xs 34q_'2}4mL0O!U(MO2pZbwW( d"O)]O~3|Ygn"-H#3Јq=B ߏ&@>A7*xu R|NΎ Divh&-`tl46Ň263XrX[[HpXv=u>I^dBnaACԳGz/JqeKbn{ܾ(/Cvf6eah81{Ab_pB0{ͼF̾Ftt]q31vbԀrL^iN9 Xdropsh$h:كpq3;\ Yy5:#[X'۷cfUf-&+W+ 04 +r"{o]8~0}\-i%a,\ƚj iOF[y[PGHxY: ('e!oUh0tl8eʫ`Ecy^vwgO_#JOz1%,-LOsXRRVP^ٙ Ch7w-敳l<RZĆ{i \XB};v-\0HK,ˠn6_];踵D+)Xָ}J f m㒆+&ygOaVP]V?';iCam+<"ipyخbV]-4;uÅwN 0s_Gy#K~ٝMdtޣ;*XVfwxc/M~̛4 $=t|_:fk@WHtpdiZw{Bqti-2eQ)r{V{=6h$TXDύnd1g7Q6V-f9޻уo;MH_BV+H3;&!5bi=̺M(p720aQVn%Ys`/* c骵l\m?$5k6ڥufb_=YYG4Sl=_??|A rוض;YL}F6v:JW0+; %,WeäL ~14!Ǭ 28LYa/JfFdn/JK40<ꦦ<6R u4M6f"Xa{Y0PKC+Y__}p3|(;fs5{Z9-|8nۘR.Bc6-0}>~۶4r]̻o۽guHvSs p8v& і_M-!wq/y &FJ˅t#/2ؖM^j6-s~/~q4ÉDPAL[bE8x8D]npW(72w)=p+!%gx4ahƻV@N)R{ M3Sö ;iZظ=K83H/-M B0 YtQ2)4))U[1/oajÁ0m,B^YvOpl?^"WTGx?\7~w~=w{98;1'!CJ_鍐 b!pj.-;+9ubIu{ >#Il,X4e[$Q iضAF io##4t]#5Ia2HX6% Qŗ6DzLcEi#_C!&FGhuYr1tH/#^r 0/0 !D"&Mʖs%,{Ԕ u&r@52V)s%5L$cZؖd1KIz%NE,DtXN"$+pv}Y E<;WXJwrHh M*{iӂ#+r*B,fyeMowu4-2(=݃$3 ڎG\8U(? v/_N GHi"cuwp y'2̺4gvXd6Ov⮨~QEex28zŎrh2x:>Ǡm *mޣ ?d{jÌ10V-.9d9w';ohe#!%>rrȇHn݂Wh9?蠬Eepj_@ŒZ>'vPl#51ѽyNjXZWb;`T c$? &,6J 718:JwW )Wb*JĆK Yvd70x͞aXi;OKҥrY#%ac]ywհf$8sdn| WQUbϙ~::XT xW?⹽,ߴR(nNO_y.KbiE`>Ώ:,/zeI. PP+YZWKrN%KYVG||h"Cj%n_GGÖWPVT@ym(x䗱rZj^( KְyuydIJA {=6:Ll|h"Cz%XG['08pa9&!F0p!a/N_u 5,]  tS^9AQUYMqq1a/ ch%TKGtETP\+) Yf-KBX#QŕUSR$5>DJ/R*˂G-ZǭkΩbh`x *+Mth*ҒRzŕQROUkVPS Pl-4Vv9/njj qM ōɹ9ե1#]y3,q|h+5~28=xNtMd ɶDhZ/)PJYg#iٍRb6R\c\GײmcGcuymkhꅲwβ,M7wT6lg4Uf۲1rDXVM|y^h-[>1fKUo"ml–yMo?MHlP(&5d^8tށ+&S7;=w^g *aժe,\-) Qaf bApAa2|&RJ#>Kut׃7.دBP \X) kR\t;P(iѶU BQ~4 B7J( b\KI LJ$B&IFqy8L]0XfϠ$ 1zG J-G".C4㊮dabIxkhT$71}DH3?\?5 !FR)BBA066F~A2^K&J脯Lp)>nT!"`a#6I++LfL&|KeR҂mY0@^SuX24D6Wg%L|V%~TT,4fcS(WUٴ(6g5;~](7{wdg;e)ǒ뎙>*Ϗ$s룞5}\^rsI9qv19GYǥt Y ! ]1w6S Iek섺0H(3+m# cCL$RB )4|0y!z.y 7Ͻ5j}M#2mp'w5 !$G!f:/@|bxfg Gƈg 6.:h fbtH)44] qhcCFb< m116x;L08Bȣ(?344D&_Dq{Qec8&L< eRN,$(7QSSAJp_Ȅo5? =2Bpu+s_kBpFvsr0C(!̘=OcūALN]o,:ga=jϟcٷk?0i?w?x݀${]Na9$V s1|.~oVWc wip#NH6 +˃siBxIvьvc` [k:O t_Kq Mwn;s?+ g$y~׏s݄ۗt=o;2YA2$L ~퀗nr^75⏾U<="O?pwԓVi]J|VmXCAMn#~I~Ka]a<98wǒ6z'>|j㍵*`~~!JVma۶yؼ2)$KЕ$O^<)~ʑyÈKG⬿^o#So#a dz/<ǩT < n~Kv#tDI~8joᡇgMq덣o],z7/'?ͧ? c5fQ\>qZ{OxRpxYAZK歬-f6>`I$%[M> I$|OqySH4@88t´l4Ek(]|]54IG=MCݘaWCKf8.tB Xy=1ȾdĴVKh% ǃSU&ϙG.]ϛ>?gB(Ft 1p$^ֳ,8k/re's2>UO3WJMcղRtbf,v³d5~#VӾuN vc,Yш_o`SaH:Ù9(`R4I)9ȎgɤG$VP_FyJ"` H4M?:2N8('?)*yS [ηb_XK  xĶk>_4%ݰm+K``Bd;oSW]ŨYw-(Xֿo6I-eXqΞ8x*װ4w>Ƿ~2Fmw·my9nv3C,[6č|s=LB I|wj6V>A`%kjW[Iz[h>Ax@i6У()aj=&>3+qpSeܾy5^)LB8XV4TSu4jPYvI~>ċGң,0D~7%K$f:ʙû9tڂ\3 vpã anNxV6δ%)_ex:me<vjU#r$gt ] {%Թ\=+ȃ)#vb D⠬itWI ZE y<ށgO!B[8 *g; pi!`KJpu{O'4Cx/; SEsH)X7w|_WXZBJiSףyg_ zt9|d*om'HG& zywNKʛ=J}-o@=@d_O7?.Ό#tGhPb=wy+KCD:+J <^7]_ga$}z]);;r~ Mq>ku$g|pFc:@xVY1z,^[Kl>JxX)^zi;=q Myg39qg]q^|O76#ifE8>Տy{?bש!gy>c- ?#oPl O<O^K$=c6)f'9<;Zor;EYco>^:LR'y[}N3OH<>84NkzI&Wtσs> : Ԍ$ !uc Gzхty%ƒD"Lq9ap `"2J<:/=<6+tvt0pRSwdBbP=NK_;j溩կoi#}\o?x•YT辠Q4M**y U+Wpﶻ3ifExCe4\0Z"D!yń.kX-3;RHLHIVlJW['RD7b|nHA{kX2+G>C=)uaS۸{-r7)bII sY$8Z -T6aj+("k3u[I&)ֻJ(JkX^S=QxD` }MGJ{>Us/;ˏPxƵl޼c?8ycq&e4-]#nAQA%+2a'vr#ƃةq nيWD1m˴ZKO`GSX1m۶f H3X4´lҦeX w_Mt`&5tÁ&3{6RbZi$H_r%47=ۖ"L=e4aB&NIv~ lڸ26I:"Y5ϕx넂>n'A hH?{FF2Xp϶eHKN=ӶN'NӉD^mXO/?̐h;ϧmKp>Ae ?b]S׸=~/xui#_E=tˉ.@ (IJlD;ﻍd,Jw?#8'ﯡ.g>!Mw`9=;~{J,FFH N7yN'b$J&?˕5cќnc,";w($iO@x@J2 ADXegXf&{?`,gRrXI&pQVRJXKq̭sN21167~\b{%)en?M ȑߙ*(а}Clkl5`5+tvgd M` -' NGo)y;O }Ιdah#am D Uua26&lg!QAꝼ%tuI iY\"|XQubl d,!2)Kʋ R.r`Vm`lrbꍣT"d|lXVYi2i{j{yʗS=d}l&HF=ɐJ] ꣘0sIz< (x=~442~8eֱ]ڤRi,Kvi$ile }:px:C*>͡4.m{vcY<})maLlq;ӣI&7B"{2{Md*JNo1 N12NjZ?|?M4!1?@<߅!O VzV,*"b m<[dҌ32-g/9'\EflC'jg7U95,_T6oM'ՕK5}y`SˆUK:&g.1Be.[ϱxɌI26FyHaFGFzv3Ȧ[yϾ Eܵ鎁&2tvZU^B5k(gKg:,_%ֳ(~#YϧnlYS7X̭ZqvDvDZ6,tȕ۶˿E*'ӯpv8h:a'yoMNDO"ri)%FOb=p,sN 4Fl^W A*H4z۔K׿w|!uJGi>7wd<tqL aoKmm\KHz#DJG;PI* -z]]y4U=wro~z|74t]9KBЬsc8]6V掽&|WSa蓮6Nv F}4,0CǤ~xw/嬫 |GwfzzRPSǒJ2='xg`h <cS`Mt+Mp( kB|a&` ?%\^7Ǯp{E+PŬkw5V^NlƱv}9^t7˯@,bj(w{IVғݜ##TVK7ɡﰷieTp|jwc`~,_!!_'7R♵4tzuwCzpz59շЖF<?;+ɣ$LtuhZl1\~6txo?x)=rnoO}16Eah8k7o"jW_cO[~&3PDc}g0Kײmyɴܲ3 Wަ5Sr-5 uMp?-%ى墤mFQ^NO_y>:6 溃%Oez Lt(RrRS[SMaНU1q:"X@q`cMrQwtcPRR\* JpcQ=Fs梸 U#l{8|4MMm xE#;ӏ_-);3q[[h@ill$ʪ&9| ז]:hwS{XНVRUIz9/~ Aѡv=HJ-ey]%A~Nlkip9 ˩,ƥgݎ;sO^%koYtU XS`INS\[Outs*I9Ao$CAV4:#452f:UBFNVQ8X~A/v*ӧ[,YRCȭxgUz m"jX\-/N(Kz¹q &b`!KtzX/:IJPI5Kq .nB`&lkoSsq:p򩪪 aGM:Xlrk=I,e+Mϙ)/=i:mcؤ'D]͡m_RL["mndߚ񜩲\Y/`nRuo]אn*CzV|-l)~M}uZyplrHvڌ`6f2w 3#DKl܀Ȥ߇u﹋/ (sN/39=j"Wޙh s ' Ϲ079?5˥MYQ!VmYiC)m9oٶ_{?b{*gðl;X1s\sbE9n2&zY;UF#{#sۏzҞ}vY}\$%on9..TJYcgf$apHҜ= 5E o!1zmn[DqMᛧP,\~+;)DsY3rȩW(nn0Q\.V(7-LNudF8E^8j'>R,|b\0RJ&1 QW<7i*a\Nb8cccN!ȆWrnWe ]),Y+!H)D&"]b*n04M#//b/e&3)  fG s'ԺYYGSfOkݟGb({ZpC ieHRX8'z8/F@PMO;B"AsY԰٘?U !0I pѧL[;̉c!,_ߌpٰV&̿.%T)g[Jt|WIc cFtE!3=3}ƕ4VMoؤ R˃e\0 @21-$l*Y.{fdSj!!6:?K-Ǐ>0BVZIe'f#=8~H_q-VtiEqrÍ>B8&/?uLGE6>ywYYdhۿ_q۸8X)^yx1|q=[qٟ&vɞ}Gē<|2|:`G/ O?o~(__}I9A;o}–^~O9ƿҲCwï5p ?)O>w;~]b'7xIGToGчGgMU>KVR-H`i7/wbW(gO=Oׄ9+Ld`s"h>xY]ԉVώ:#n K7m}b#Rpyv;1+$iG=>>>wolEe8yX~><_y};9[Ʈ^r0/Vvp;E{C8*Գ7D"m[k[|ȖV߾L̈́!~EN;Wt= yyS 6 ӌ3a;|O|-C7exȟ'Ċ-w ёziin v]jʽضWTҲ =Kݔ/^NHVW.iܡZ>GJ8*vCU,!nl$3U8iĺ+(ǐ6U y4?Zk9A ;?>LHcƊUIVM 6^ǿHs/E= tb}_AETzmB/{we|Nq ~I6?$BiLh)?4!n> 埣:qYsdV;{c)~9M ^Xew^NyصIy )ɳ7~@Z|~A Ch$!(. Vsc)IIЍ̆˞1NaW6%4"ߡqߓ1͓B|#.cZ`7 3M6t *;gse> E/4>`(L^8Xlʂ>-̝WLy&0)O6  ch|LW>#2gFtp- F*-H)).B0r֯Cqɘwvv1 70*B=f-k#ٹDǣEn 7H,@c)+M/Nw!_佔uv0`WXV ~ =pZ^|X7p&4!Jv3݉*sIDfvp6*&O~f#-3+'w'%${hjY{C, i3؉8RRO95Ã7 ƉZ.478TOt ،K0fY|n| }EXדʹrpf20'طsUhwb!)n^t ܱi:fI(c7P3,I^U=8d=v =-!*}:h:c"IzV6ٓKrЄ<6,D$FĻ-pt" X-o[rؤYBpܸn#B /.DOu/. -0)bptu.ѥ[k +L4 ql,Ė59H)W|I#o@c@l Da8lyEo!ax- Vc$OLC&/&9s 0U()wяBJI \:\A2vReYih5}L\=ž412g23>yaByaB(#TؤILp|ZĤI"j  )A||YI |\m'\u]fԴkE0Jd^ܘDX?t&ιTi>KC.S2@ 3߱s<Orf,gӃ&c L;b"v8~Nrby+2$֩]HKSNd$5[VQhXcH 9;};h3ٲRRZNGs; 4ln$bS 5H%h)eՖ:0BVlIeXܐTK;`U˩ xu^w7-&9AxE[VP(`JF[ˠiGS i3]4jti_pwPD3og|MXw R7,{oc7_YfQQmw6sT;"l/(%OFX!Wb[IzRyaoe9sw7>~nF9{m[$q$xma$~6<+o.Tl;M" Ol7Bd*M;(#<s<]z6f|!OvcY[04˶>@{O`3Q+y!ɉAΞic(WNc}5A>DL4"nL2؁]Y]'"H+}HM lXYH!}}G y qn쓬 ٕ vqz C4P}q++D-Z+n$ZL 6׉?,\©_K. 5ȮP~|G,eݲ*n|xh9ۅg"OAB =J֬n(%g,' R]^83/ޠcdNnӴg,AdK+C&kラА;Cwa} #q ]ÓWBEA]dhٻnbuٜi'8{p/?Barj |}'B@& 8{lFؾ=G9.{=%\T!,Nk?ܲ46-çKQǏxÝVwjh$9~Zhok#&Z{651u3##xދ{< <7Ecj;XdV}`a|8+/[6֑-23];w/Bb&-uCצα-Ӓ膑ؙQ4"cN9tFeU Bö,,Ϊj@t ]C OL]KT\MzfxGBma0N,35c?G7 Fm6OmHL3-Ai8Y41=;> XKJnPOWB{&`hhGQa;jȉ/* Ji;ſ_C1uAmm4]c}]923sj(;1+/UuoAZ35TMȝ=" |$O⃲OUJ> +_F |S_,0~1v=wt=?/SLVLoE^taF:x(xPin9CAABx2/|~ Rͅp*,Ӯs=W &'S3ϙyE9g`>Oh:m泎k6@"CxF tB/% 1=d8[Zv0YgV|T4Ø2j^:S Q>B/]ߣ!mXݤ7GH^:1βO4d`ȍcےPEmX9([S$[UYC_S{wO.\$R[kAe?,nXtwN)bz-_9݋T~%"'5avp+M׶m,1c`Y]Wd.nELKCs_젫8-$ XX)sQ te̶q(A8VUF86~ÑA7[yOܿc)KjzY|-K 9ׇ*{3ed\u+j#Y<.T It8B&{Y ,s3|prWoMYgoK{GT Ld8qU{֍+L % Z~Ezwəv\PPUxB@$Kaq{D919Py0Š()^}3,-=QSYNy $}Mw屻VֲO$=: 7`[*w]%n햔ۍW_Ӳرs7(**j^me? q9R JW+/wel\^ Fqhc<} E9A(Ak ozXK?frH.<8nl[KD +=ɐ8{ Z]K\ й-h_&?/H$'{y>rNO|TeuT(W G,4q9?DPQy%<~+}eb$n3mxˉ{{Ir%X!>o]ܶ$HP],j>MYp~~a~x{Uy.تD"C^IH(D.s[@jHa6x氕Dun [Zxч)--j.S "^CmQ(%tN^z%O^YD>m=~T,* Q6G'7e)%ql޴0&.M2 p];//m_û?}Ts(RB[5K+/@mY^+9Aw߳ a[k_OlR+jZj673<[֬={^wEiOY/W.fݟgLԸ83OK+q!N2l6sI6'1l05}EMFEX6;ߘLgA/iM()ؙ] A3pyUiAx]TE@J`-Bjk*8gO=rFԗR:H@a)\;1R8(()KNJx?KV-'ߣͷDP\B`lQB^ҪFJp\I>gf+AsRTYGq`U7k,bCθdz瘟Jι 4,/{Z/%'Hu]%L1|W̦MsjW%LbV(/M̼TC\i3s]wŐH˺Aly{(A񣄉Bq*>nԎBP%L B1o0Q(3=&fP, A2$H P\! N}ek %L@08׺8 M0qeq0Q(˃k]M( b(aP(yBP(& B7P, ,fttd"UǪX$K0D.B@B011&(iTΤB4eC ba&>}US*>N!E b!'?r_ ť3BQ]6͢1GQDXHd%۶?h}@p5wk9+}@ZIzΞds/K M6:*`b]iMHp->\{Al?N?;z5f\)J( +Vr~wzJ]|t7ډ)fcJٲqnW.5o-%L09 H+{2Ç$fp5Y \yQ6b1IO|ccܷNl2[ ɔ D9m1-@1m/SQDXpL|7a{h ឵6O;xV6rC 31ZOD mxG v@b#IaN foLR(7,B<˷l%fϾfҹBXx_Ģw裏rF|";rf NJBNss\ "M,)3B:1>u ;^ۅ{[EV4|&Ȓ:\2A-'J( w#k!ǨBѐ~y[*$ioSōͤbKh9_a3B$%)j۬8Zq!0Q(7^C28Ř;6h:i,|7wU84nc>2|BNohI'ҳ%b[I߅Wϓg=4B yAV.[EZ\Ht6>cF&8}!+h#kJ(aP,(VVSPe.>AE)d[IJy4H)% ~xX9Rs)I-X/PI5W_)fMGs7UD b\R(09,lCW(SEQ6Bv7ˮEUf~0Q(,1[mMy] J( t&L줘e"p\J( )%~!kF8^J( M(/ ?/ZEqr+Z%LRq)~(`BP%L B1oKX`Xe1XqhWt& "D~Ee#D8˾^ b /z*ⲐRD'J(7=2+T$RR\jQ۾BR*5e!cyz P(cAvW+$#5\YY!rYg$L6%XxN=*aP,(&,ޘLBL}wy3V`Be>+91HGWŕ%85I:>H&/?Zbltx*0gKql |(aP, &ud.ƒ)/bqqm۹ZDK1d>ʲ|ؙ}dt^g"a doat3bYh1!74BK'&&iXVG9X ๑^+Y@6p/?0E*9u9 9뫬FQfpt tvcJ[P+b1Co4 RX @$#$Ų%Rh8=^\"I$FʬוI%nhdDڞ'9;cGF s!Yn|PDX@=~퇦+HiL&I',9/mؚKC&ib6TӒx 3Hb;0/)HDhdX̤HgL0M21-ef0ML:3K $n JoLQK 2xp?LE #1S1)Bh8EIUޱ"C#HmmSCJJYhё1%e$qc[+EJ: 5I$A:XK߅@9y@z#UD brê%8/)S^k XPBfp5g;(u߼*Jν3t\qBИR|!;q9,uQL7jeP, dwKZEq!l\"J( )%.h,F$Q܀8.UDX@\. I ⷉ0pWt& r]񀠸D bV%6ʛKP(FLȕz(nnKP Hd(4ry)q8 <7B\J b HH$q:mDQ|˾& ²lt]a8rKE'LN0Q(drI%JͥP(jMb凞B Y aE΍`gFq>$cyaBhv:K`:G)1Md-7\J( +7i:H["DBdMEHZ 2P[Ypx*ɩ\>J( 93$Ƃ(Lf*bžF 8dHi4y|9g[$R&ibxIER󒎏 RUN'Θ'p/ as}fᴁBfr}S,ua&=$LadbC4NI+@g;)t]G)z[py<8܁|*+)c''j"lѤt Q+bAښd_rƿ3Z |:,(#(9[" m \M􆩬 r9t а.>݃l'./\'4R+◊& cz`G81mJНx4D( >F4[gjdwBh؉1 u@+@c⼕͎( gzٲel@Jdt~` %!4I8'wD$N1LW#MOg7c$3C<%1BC!cYF @O3H,!IƲZ((Bd]$DHi%CKyAXfD"PWVϩ!% KHfe‡ID&Hf(T7Dee݃mq}z@w x".4M`->n_BgP(F߳8f._Ф]Kb9PZPa)qx.tl4Gz7ht@J A9Ka BwzpRjU &xhNay5tq1f>&F b!3 ,M`8݄\ Vv͇Bw 8:G Υv8>\^1u$"vO^}f^74*mBDNZ(w%yBN w'ORs),YAPDXPܴĉr PDX@LQKesyE F䣢*A-sYĖ`P\3,;RJrWU\6۟tD\B[JV 5@#)Cxgua&8Rܤ28S+҅*u\z+7-Dߘ)%T:E"P+e!qxK&:J}6BqLla z?A44e3b) !4PSP\1ʔP(yBP(gP(. 4텩";^٦ea[ֵ.Vw];6Bqsr#]hR),,0fDA,^uwp8.z%L %!`dt0pZc!pY<^`hV\b~,V(yyy}(Kƶ%1jaR=G۶q PV& 2H9B\U~!5_?D@#\VK'pRsm1V- qDP\$sۃ%ɟ}5esD}ߑft$+4!Fr;$rJ#ĞiO6y=UgJ\J;{ɺ̱¸|2!V&BYQK~0_`"{2#_ֈ'!?/K8{==b/2T~.J(bF^;~UeٻD~}>BӰ%i2>4H$7\LQؓl[$dhx4.JbIFG%\~ :u$G-7O~3xGKy `8/.uº Ҟ*hVqËy[W3%5as}vePŶg%L e V&9C^ԔI+j;9NsYٿg'}_!,ig^x^룧4SwD9r 51D˙Nʶ~la ' ;4C]4Ǹҗ[YMre"̶TӴt&9 =bÆj^iN 6p'7Ħ>ŲR jiQP(f2J2:NC![a gs  4;sc ߴ~ȿ mCh'Da1q1G>V|wQҪ46{hy;]q[j^_0@ʹݦmB~^7"ե чhyi?"5Ok֠P(n4]RJl#Ȳ?| }^bY)q{d;yn%cIԬ)llƶ%RhewaچDlI)-2:@lXZxݸzn1iF:L"D^KԱA s wy5+ sE [/?N}<t^ݯP6)aP(ĶuoGWpݗ}i3faEDh;2*_ʊ%U8:6iyb9-t_>%(ilRR}s k2tI2Q^AUmI+y[4#=XL>ᶻayE@?fKpc/?~αu/L %saT#ϟ_3Wp`h;e 6slQHEbt3&ɐȤXR!ɤSqR F{Z?% ojHVs<S~ "ܺN%Ҥ2~-( [ɧy O.;m|'DАvDB?FUy bA!pAK]-Ěr]hkSٖ%υliH]' MeZ Bu&RbY& akY&r -BNeYs4]3~K)inntVN!x=^1z̙$0rv\l s2$躑 @&M0yGhi9CAAEE:yyKP\5Nns:>s9 }JP(n rLUr3Z]GbZP\,!J~|T{],> %L eq ޘܬhKP\&gri{JL jeP(.?ΥuRDP\2B̂ !d2dF,些&R+MBdazExzq 2:6zKqv_YF%L %!$ iTZcA㞝O]J梨d2yqU˅뽢˕0Q(@ @ E&uk]eW( żQDP(F BP%L B1o0Q( ż9כ$`^) ޻Y[׿7k]hBP\G8y|+_EQ( BP( BP( BP( b)]'I%tEXtdate:create2017-10-09T14:11:41+02:00\r%tEXtdate:modify2017-10-09T13:55:31+02:00tEXtSoftwaregnome-screenshot>IENDB`Eqonomize-1.5.3/doc/html/C/figures/editsecurity.png000066400000000000000000001013321416454732000222560ustar00rootroot00000000000000PNG  IHDR8ZCA;gAMA a cHRMz&u0`:pQ<bKGDIDATxwxGz }2ppsb")FIDy49x~/w]k=䤙QQeJs`sp8)E @տzz@P( BBLcx$xˣP(&qmхU(Yp~7qɎ\8%H7 B1 ~p8/١H$]RB%FZ.AeF BA BX(S( %p bb,e7b*S̙`a)fzFYN1' `xxbv;J$m6>Pr(0VHs:^ bHyB -U^\ÃzMhz `KnaY}TN΄iXJ>>ε]@Kpr-O*N`Di%flԁ iOq]ձ33@ѤiZrs !Q~>T<7AR1\t/׻/\8?*@{Ov;QDvg@xrh=§a԰5 .?KW.F'󩞊U,]ǒrVIX衾 U>\,Q0i>6/ۿ{nd \I,C\X"p83G0]TiYjLbJ ݍp4aسX꺦K$%hza/m›(s1iSܴL>0t°$a ~֭Y ,ˠ;h0n#]Z/.qSz/R2U fh ; ذ(skc+Ҩ?s!{ #(ć$M4w3:O!kn]Iۆ0.kplV'H"5;ؚ_;?.O`qI6M";xQ?u'gN2VZAQD>ϝFʍlZS5 9ƁWVoWeWoFXuۯ3OO_]TEc#':qeyN228mK˿wO)/˧# ЄIá7ySu7^˿Αbz`M)M)mTXM뮧7M܌q|׻tjEX\?;U[co$K]\IdOߺ@ mjMcYtO7ަ˲8pgΜ˜~5ys,Aլ|Nrt{Y&D:v ݎ&BhrjoOh3}q&%SmeYl|Ymdx.w|Sfݶ']_yYrۜ_ODޖVFF\yDb+#9h%MaڄMiΨi7iW?%a/wN:X֍9+aزyN `pp{wCQQwwQi!>S9 2hdT*=2tģKoG$SmRhdְfjR68ޜbV ˲ғ9%䦷)q-49,-'/h9XiW"Y[: pn! ŵap86#E bh6/Bq\C P7͌ZYP,XT N1g{b%p90f"Q .3_6sn+)S̉PRnWAKSR0x-J 23(S$-HHXmS]UurkMv(S\ᦸ\kRW?s<6GUZ9Vrz]4To^@ӵԜ1KbZ|`N_杕b :xu%Sߛ +]^ttocwtJ53d:#tSט8b9v"t90iC"CqdN=u)̬GQ%6Jom柞_;AӰ( :8[5o.FP42_ 5 WPp# tAp,ܶ~)^w-#F׏4= [3LKǡg%y3M>Of"Wl/ސm7)qgacy '9(s.v'`E@lQ[cq-irɡDh&WgW t6yEغTx/Bl)il"+u^M~!u MQΜ&K`іGG؋/ߦ/jnZ n9+oǷd [Wsg8ܖ顾f|E9v+;wCO0J٪Mcm=+Γ:H+/Y"Dן}="]'?M~ "h@$^Q]%OǗ\گ YSORUơ Vld'$!yGM&Ò1I0!f&1\bB y:O:詩>nAӐ=^Γ> դ)?p lpL㰽ƦTLOkX"XcC0nr)xAq9nk7k@̔;uȥ+q`]UJX<\ c'2x?N ! 6gϼD(dggqNw+gSJ^#iDB˲MGO5=hrh n)ѹ'h IFT R"L|b@:W1E,z6=M>: 94()̶;xlKZĚ:򩋉֙`zͰ@hO8CJEXu +!9,/"Z`iƆLKAkYy1[o)QJ)_7OԐptPsK&K΀F]חX1pΊpgN]h kI䗾9XI N[)0zx套0榶' t(ha8sp7g42L dK_xY~{hp;lXQZTy46h5 ZU- 2!kh,XK2n`_AIsD:5Pb1 QRfeBFڸ7[K.Xp~ X%6>WicSFI1k:SC1WkJFCX!R};4lp€?\j%K2fߥQT1G Ռ) C0 ;'yQ7dthԑf–h`\aEðk3`4j&/` '7lj$bx,͕INvN4 yy'z"&3&3lvxRҟLLC2fS.R-ј$ 7-d $.S|vH0$mGʨ< 'ti` ϙG r ôz-. WO\ F㒠 ٮe@L6C)pk0RH{U:dh'܎iDǑe^> |ihI!M k]RUnf$/"͌ 83ncf߲)LP+eM$eT zVPM8ż eN_x1`V,յj-yF b^Gl/U@l/h3IaSufj8)Dks<#źϔ)drUfD}~ łEׄ \o8Ŝ1MX,S !mn+(S ˲ Lk.bb&B@~~Nk+S 4DTWUJ4H8Q`in-7E)L*Ɓ7Zj5MS }ĹX6t]OWF9҈rJj ~"g%C;C0~Vm5U7.tRZlz&1Ytս?}MJov!ThFl#'߇M܈!ЮfBhWW0{6g85kɉ9'(}839w?]21ub5/s 93#V֖NM"|8'4YdQ1 g>%zEu#Dcc'Qúl3ǹߋLjk$' l-uM-qs]ẮFPSăԮRЯy PaN]TA4@~2ւi !0BЄ@H K 4IIf2I$6Wn #3{j-G#`s!aB.+Fá.|*d8!LKlv\E&4&A"E"K=xh͑?ӃIhtPp͊3229p&Xx33qhJDCcX,2]gG|{(gX,i##py80F˜v:0L Cf+F*? #!M`seFd3_CCTe;gFh]]Tl,˯{J3)uQ E,"c L=+Ih,D4Dwf`Sd,:F%Ht b pKJɃ4DNF49\kVB=]]%.v, FĖ' oЛu鄆0ux,:OoG%]w±]A+Q r$wJ/?W-/Yg{2#ɞgiIY ƦR+F#'X>'Ys{rlrICS\ᅢp#?"Z!N0MÞ&->ROU˪ɩOENcugsYw׃|旻ɮXCO>ŝ5vv=-qԽk^u`ir}`fpt|ORno`8*-b͒\JkWC)H,K^rς}It]TMw$̣0onhyI>X]nF*Gܺ'y|fn?Y{w:{mb3h bgx$yW׆-dGw>:;5v /gY >帥%_pxwwɓuH)B y7him^~Ϊ'4hW+gZnog]#L7D#-:HK>RCH,O5rF7M} UY`dղDWɿ+T买L@J6w@׵t36H]UV㥬jye~ua!:v Mm:665zum[MYeLʪk)+%|oPҢ0[qţ4r vyiyg?]|;Zrݭl4^7Mnz.͏ȃlvlpdSU]BIUm5Ns9et )/¦KV\O05Iں8r|;=dƻ]ʪS^[CIA.r2OhN=U͖*͚1ءV.6Iz۷: 0Gw˰> r0M̘rMBϲz(/c/eo@oK|:;{8^ʍ8Q/ [Ĕ`C"M DzhcqH_eI4-H(ɸ .K2iM/~K;K 46>> %mwg>j\y]}UmdTsp\ur9ۇ4Ν?Ái2Yu} );t{\oBidc{L;r8'3gi"%40$&-dj[+r{p vC_ 0_.2lpWL4F4ARG40 ð&4 oKۼP -@ߎ[=3?Ʌ g9rv+QrMq]h4w;H84LL#9ѫI4D4L #Uwleܽc)yS8}u}4MIs|]JL3Ir$8GkG7tw3 efDSwexJ}<ъe;q{l1>MԿ7TpgzNϱ }E9xw7ݡ$B&h>~ܵunMǗ4ƉF + 91TZ&F2a$3>V&qQu8Znb_sm'Bc5BdQS Iiap`x2/B-R˲k:ñS I7USV2AS[Zij`ܷe^@sȳ98!\<=3b.3wq|/FF!KK~GVSYc#sYf3z标uVTce q ' KS\JWr{ku`j px\Peò$pFeUT6b46w*[Mtq95FQ܏qtA{x +.ʦ!9K(zQ>=ȡwpsgn)奔VTQNp 2s KrhnN4.d=wcТBz[z9ⲁ!4~^;`AIe9YN q1ZzUPΒe+XTࡷ,O7"EK(ϡ[Npu%s)G|C+Mtܱ^n42}YPGO\`$$FFN Eyl{iKPPZIeqg`=CKeu >/.g gƛ[H~N&6qu"S xxk>~4A1ԽErڱ ,c :t̴?N MN ]NJ"ʊ;'lU]Wf_ W|K㒴SM]Ur]|eyI^꽹ܳ},pj$ܘb}}fJ/wBt׸\aN ll<0c=JTT-QtFqP ^*77lKG%mՂS̙͸ba~.$8Ŝu MMU#0 t]>:jbNNaA>}#]E9dddx%p9f̭)A6\NqM̵)v*8B`Q]TŜRL&!nI bNH) bNq˅/7zN1'L$RSU 0hljƛS=S5S1'ƻ.⺡S åo43ۯP(M)pBh-HB Fg7a\t]Goa#QbIP­QRԹ(@G0F`p>UG 32iü+ϻsa -9 *g68G[>*rgxWְ|q%5d],Ci5|'|xK7il8Ϩo sDZxP"ϋrikcv>iM#u8[<}Mݞ{'zm󥏱2ߋLFl8/9O?-9s~-4*7>YfQ@R 4ēƕSՕh,k*8ѳ __`7<)%'Owm%1qQAtyQX@ia~_@!+˗=o?KP|;".zyt]G״cܾ| qSbmhZN?aCk'f'L1Q266fϠqq"~6:1LD4)`fy=rwJ&˫ͿM1.=F@vKłS޻^~5GF浮MD a8DWS'M I"d`phMQ~*#6Fwo?pݓMqQ>Ddp, ddpf7tdQV^[Fa8$+tB&g8LF]ݽDbE;il Fi0HT(, Njvi% t08Cw()cKK!Mo0NVny>RzC ))c aA "L;~F#$ 7P@ύ& 66@w1K',BhhXuMk8Is45kjxмUX,8oKC=/白̡Sx%W?tWĩFd+ϙmy7Thz;Hgϵϱ4˿)| _ƟVaMΆ:ϒMw*nVoWY[ sl##C "<״ vvQ_p/clV24sR(usg˗~V9?9G#XsG\~*DNt .ɡ86#Β9Oc3H4& ~;AΟ:`xx(/\!~uF|ፃ-l^ND4s#ݏ?RO?-:șn'^hIԏj:J|u 6 n#qpJ祺*B‘ܳnp=ywik777) 66@([/FzzHl&a[a/gmsOO?Ś,?9D[0ц/!M`K,ߋXʶ+{ @`']yN86¥dIom"V|QĎ5=\$kgBKi4)_z ;8_r|+ăؽd-wl Þ>FnYi!G՚;ɦ~,$EOwO9o~`,f v?F!9LѪf#pgH<->1^SCn.YIrx|(!cC/ A8ǒS RMiY./Sex;r: $2(,'+ÍKFw,aYd擏deH\ *JKh݇ɹ\;RԐBhH[ >O=ƝkBRa07̢lfTFXqN|Jբ>HzΟ&ޝ,/rh t]L%H)q8o fo!`x,Iڕd`0vÎnn{l`(2er\|@EӾwBK8AV%Sew5{nzHZo _dN38'uOD$ek.74OV/}N; ]͋| RZDCABCtN͎M_zߢ*y֓@#x wޱ|}N"dzf׮ ur9qu#ߧMAL&m8_ZI/S4ARJƕNdo&Yx'OܽwfyDzWI,ř]/1{'jIhⓊs_A9~Q&_o~+Y]ǚ>D),??U6=h̺^Lb6F"QhO]ؔ\.VԵ ͢~|9kWeK1O)؂-ƛ dW5cD1F#I c1*!죡P|n.0f{g>>)>O%8 XVVλwLLL{y;,d>GM2ChQ68E )%n +?@AAv辰GzpΥ9]h>yA6;inSi_GeiZe3N`ZV..#馸f)5n;Z_[V`5sDcA);Mu'87gcG3p[LMSfP\]Meqn%KoaYHFye 3nŎ r ?Ʌ6s:/9r8U =݄W\Ni9rfR^Q9h¢<'N71hm `;9r$(@C'1]Nj.C$HRTeNBQAiE юshCj\Js}/$ˢE˩-Ö!o%l]CS' 2rr̈́eYD99M#DhcdtՂSEYi x죥޾>yAJ Hx<~7qɎH/\..2 &RH}GRԩHKbAIu9&΋t.2ޒHv>9=L'R6Tڔ/L6B\b2̥LwkJ2~"[_z5m3z$,}ߴT("0M?@Cc/hȅFvrY= |ob)٢N1'Ldddw&J+dr+wY)eYI 'GuS )%CCXNqcPq GQE:Xl3P(8!4t]Gu4m6"!1$yecLICI@'< J2Qρ. Pܜ4MCӴbMh3}-皚zBLF;8}8Gq o~ir~&$]'o4 /ofϯ7+. ѯ*FbW~-7菪8O! ]tY|}4620:=#.B+Xhll/9}~0c58 <\SKý456=DB^;v츳 h?o7e?mpsk ,9-UtJD)֮YQ*- ֭,ݝcq\p"C8zְ~e5^@ ]X^!6GP @:#?kH]G%0L[5+s7)ќ~n h$&yMN6skK MXyWrر9~銂ng9Ꮋo &i' B'yCd/=lgS !th;:;q]%/A_BXu]{Z_㧯ב{-Ul߾L? !W~8qԍ :#Dh:8T)a+ ]e}z{ &Ftl6esPS-Wj\k)繺|AؘmO/XrCPҀi5;±!"wbÚB:@g01j2A\0rY^t*Wo2Zc$b}Y,;ҙͭ"ym8G;)] M_mK8mZG?~kJ%/*W'{gf>W^v#A?1"7;7hf[Mcut쬻6--!,N=+'?1{ݜk8OŢUH%Bh y,_Rc#Gù1|KrpjiAfqï̀젳mٞTL\NQI9#&7RuvRӓKq4tXH]XBwmCl45; , bF7Df9b>D(񲳣`$+s2h4oqr:yxn-]2/,Qo[MOLH4* Q|9z~N.+m0ٲ}HH剎ڏ| $ox k{ʫ{0sjXo֯~ 5G??{e7 @g{6"n2^/n~~iŶU8RB7.Zn#DPmnjҗ>Lr2"eDw)hx23ML3fѡN;}v9t2:6B44b͸ݙv7C$./@$a#8ԍæcu$M˥o$D8ė͒˖r;xH)Y^&G_)tJWQ]` 6_f39 ūK.";ˉǖMYy,V-wGfXzYB'}y( +X&#==5†ֱi԰%™˚[7Aɱ}tc2j K/F7A5)-Ρ!P]l-Sv 7ni_=> 6Ntt֖nUHb.V~+{r5MאptMrDieXœB8kwշ3~w#֜gO=ȗ>2[r#Du.>Dzԋ$'\Lat$Jggዄ EikH&|^BLv uN/(IL, #%bp, 40 !M Ydfb`#pd"NFnf&IHJ"'7+,cv\]q-\{ 8Wok$ ålx|]>y kdj酀H^z7k'Ν0͎mn J4ML+㉯G1p|#D- )RJU $3%DcFxQrE3YGȢ2Jn$~JIIY ^1Ƃqȣ,'NR"hx`qiYEIAGg?feėYHiZazTwJQU\Jv{&㴵wH$'?B뛷;˙ )-HZ)Oe!IƧOɔK@H ]' %H$"&"5R;/}+VacqbfkF,Dz|aCu&L[-R. xjveXFH$B00S=!-;=g; O[K#=?} f,FۏOD 08-Ng*m?@Hf]m:KSo!BV*.Ǜ_e9| Gm)vn?)j!9Y|F[! ҝ,涵qfq棜닣 l%PǕ+h>q@o֭Tg;)\k% 9EM[ dϾgai=Kt0f}pm&}Mw%)_RCY{jܲn{ol8!Qʥ6o46'=o~%KQYiζudlnمh<6j!d˫ O@&ÜNu!Y295\R\Ņ[NֲYGSI"4IސNee ޳s{=]Yf{(?F[C# r m&F Y&3;r,A|'[E$!s!E 0G_9_~~7|_yd9[7/0/p}d kʲ‚lzΞ3`H;,'|od*1ֵLFi<߀gɝ층 da 4P:Lk[r椰(sM2UOc4Ja GLS$_8K<=ݹ (N^^.&fy7bb} xY7fiG ytwM.(@+m}$~jk ڛ -h_m}MuM536F[S3C 互452UQUM|EmBJ[ mk 2}n!ZHrJ*Y\Mh^=E58t471tRVQ{TPRV줩pSX^NI^6v-e GRϠ\X>FfllT9:G.)%u\Td2kkotQ>yZG:UXQ&0mm]D,̜ &z"@7Ø2}Δ)%=@-=M7PDi}\Hh AnQ>W,JFo0͕IiY 튳zz{Km6cO]hh$\igg}34/p)dބk(MY˜) vI$i)_iFRwSRKJd*sșʚKJ~9.S~.BiXeMv69yy|Ӷ)@4,˼V C |0Y.AZPxWգ\&DZrHf*#&'K9M,]g{RbI}mhxJv% "pE5}$ib]1M^4X政q9f*%L3LY/m&:յ&rֳX>u{v_l)%@i.#rR(7h8B`QP(,J łEQ̝)C(׃kxPZSH& l6ۜB84 X(D<Q,P6Ǖw)nWSEU0Tg͌EU( %p b9#0 MU\7H{stERRJFGGFW\-n7YYYs9%p9a&hʉe0 [ȘS=S68Ŝ*qS\Oƻs5|tnpfa@|CgHġxs)aimY.5 ,:Ow+gysrm@2ι3؜_`3/=hX$Bӈ槯cmg~bA1ǹzNJ*ƾ˾?sb%t5gË+'fe-4*6<ZlQzCS\NEas'o1ڟGț="HG6Q"zCk[;[o߂:;.e,*ܜ J6hOǣgi&ߧOD XTY&&hk,Sy\6-e*tF9Wא~\lrhWa&~Ə/ǴM7eB#>̉^ѵ&aRƯ8ǎ=FeT̩Ӽk7mGGu}Y !l:y2Pʓl{#JQG%L>s}褄d4C(mHF Fx3q@Jё1ͅngd~F"Ir H@`0EHON.$# 7[H ˍ}'#CAprI"2H\# C ;<'Nf"OHZ2< QG#7;+:JOW7#MEi1Y.)B&'I#; R?>$.Ǘ_BuQ 8#é#-CaQ>GG^I}눤!k[yeY;͞}mo˿?C0{'&9F VPxN1JNN5b8]Οn䶇]v8ORw܅NY.?Ts4O^:@FjV9ha߶5.:9u0j/R>{VWYVr 1ɻod]3܇U#C3'/׊rWxl׸we!z~_p,5$;8~$#U|Oȋ+2ȱGѼd9$g9z<ڪ'?pw0V}>qzl3~??,dC!\..tXslZXwrrh\' g0Ag {<҆ Ql5^n"2 A|熨pƑ Րb!Hu'K,{wΝ4ֿz^5o^RǛ'KhHַ_'+ F4Md:0Pwpg8j!sJXb i=CxKr0$ck,ZJMew|S[p=v+] D"B[o}AÑ';Oؙ~v cUֲ/߬*21©CլciauRNDMW( eܷ]·kv8BXlS,3)^JPVj qᰤ9=q^x}.]fdLPRt:'~f+!d8kVa:F8n\.'NN<8@W(h$6evLM yZR"zA)$dE|TC7 S܈oJʼwN3Y49O !4!  !aWKtb#N0Gڜd&NA$J1~}2 z AsӁ,qzfX*H`Y01 ˴@ZX9T 9+\eY3n+8.%INyC0ƺxro牻̣iMG=%H ?({v/fk`Eq*&=M9~Q&-_o~6e^RˡOy'Se_q_GI@'SR-u V Σ9Ѓd"N,'no[p `o$c*v+oo}|s[n yn'?za'=t7$7E4Ǟ#8w8Gδ 1"I#?Ȋfcmrg]VZzƨ^s;so9|QI`@q5+VQ奟|st$UĄO꣨k)ƑRr5W^}^,bϾԝ>C?o皈9]h>q=N`wMs)ȮXC=ZHEř u4!+,"`ց%^V5#QkQNv`syȡ::yx8w-* vF/^ŒlXTpG';,UQ|c+I-\OwyR&G9}alYTW$6K)sZw IʪJ|(IDžs4w9Rn[Pn=+ʒ\2Sŕ-kh w޾\ԝx5:'j-Fڅd2s</py;([s(ǩbdsˊj<Em,H4rŠ3B@4@2kW֕Mi Gػ?wtCSRR<-0J7qɎH/\.ҲRǝoK<B k4 RbY&RΧ˲ ,Jr ]ʦiz`aYSHBK2S -%obk-@:Yq3=AbZ& {ǿtc|bך(6e xs^'1N.44S\TtÅFvrY= |<{߹Y MW匢 T73K1Kc" T,)njfH;5DMWG{BJ .bn\\n"mrMͩ\NEI*>jH)uƖ͛p7p. -AܴTMD4~]Mߔ}Tfh m<É#rP-.*ok՝HxvB1o( 7 rS(%p7_8ŜiD"q{H&sA bNl6^/-m TTqf9<8Ŝb(8W(S\RS( %p b"J)-x)S+QXi? +gCnLY䄀zuP(n,ld//&#:yfg3UbY-9}5B: Ŕs8,N,ZJ[Wη `V˗,%s?ʼ d2JW)^Oy*>'Y_;sLFZko?r&f-QvP$'TP,fpőGa oF^_%/ӿщd'#DӣO.=МuhҋDGj[B D !$82ҧ{(>\NGEpW(n&f%)6-g-n?l橵8$w`h͡(.0but$)8]"vuK;e2f vh1758(#8}d{t,3 1݋ =yTЉvV'o룠*qGᱥԈi#0ln KJw_-˅頤,gjj*7Ei9oilr_i_o'|~y k(w΃G9u=q;6 {O|Nw?^jfٶU:Gx?OX>d; ;P?y'>Ey47s.> "cugvq~*exyKY^ ( `^# 0x g gcY/rTdPr~ D|I>c3"JCzw4Ll?ŞT9_P0-iI5+52sr%Am۷rl,[4>4lX{v^}:a*fZ^~OlgCQy^b98p,J5EJQHH%-_Si\nt)/ <=* Da!Ѹۓ3'n0OjT_p|ܺy#$8)-d$ARJ}5-{X%x%8s'HƂXY|?::sTPR^D>.$#3Szwe "K 93Y{:;—6-eFwW+Hz-*dr| -2ryC$8I,fttXW m 08GC<çi` _O8ljp񭈶]|_c;;9:L4oc0,.dY2 Y!z{ɷŏ_xwwî3L#1liCcD#Q"x$t:IS(9~7PO'tQ]V39Ȯ^]؋c:rRspFh#3\[sMJr-fUM#M43`sr$l8˙nE㜯;`<ExtpRg[(nBqW"56+;i:,BC }_m]ᥓ2+Ŕ3}EQ(+J\%{j)vqWs2)qS(n nE_0IDKJBÿ O@A^ƐJ* 'ASk6P|dY@)Qsasr(EU(̺/KP(>\'¬NJI$Q r9nxxd2aWc(LarsѴ[ԮZ[o5U"B#ӲЀiWxj)d2\ÑJ Ň&P(,J łE BX(S( %p bNP,X)8B`QP(,J łE BX(S( %p bNP,X)8B`QP(,J łE BX(S( %p bNP,X)8B`QP(,J łE BX(S( %p bNP,X)8B`QP(,J łE BX(S( %p bNP,X)8B`QP(,J łE BX(S( %p bNP,X)8B`QP(,J łE BX(S( %p bNP,X)8B`QP(,J łE BX(S( %p bNP,X)8B`QP(,J łE BX(S( %p bNP,X)8B`QP(,J łE BX(S( lB]nB@Jr_ !:}xDc1Xa)%.KFc}BNH;itmKڇn")-+!olG`oxz\E]+@E5fGMKKMZk8Ň.eZpB,#Fo{3 Mt 9lrK('~3ICQ'>6.(3\_ΓP f64%Yy,Y< -iNRRS#{xmie; >}S` 2/wup:u!2{NTbޙU]qw2gvbo؉@@4,%$.@TBHTU+* UJF~T- ZQ(@ !8x{㙷~I <{=c9R:)Xj.bT'+?,px^l66&;qao_I+"彣=h},'rkא|(S,|Xp:^g=#En-DVG4K}p*GhW@Uu+Hܦ Q_e&z8#/4#gXV3"7K]mm9t ?JYHR]ɮ7c w=4Ԟxu;KnO>xFb'D#44wR!bzZ멮$]-4tklk<1g!m56Ǹ]>+]6m(]9ŊSoq=]r%pA .m8ZOkwwB^ʊlsuY]P<6m,2szq +F$I.̀V-699N#7I"x,J{({\Yz+Y '3@ov6OXNN~19 KYR:oZF} : 6@ +"XAQ#oࡧvRH[ \9N>~pl&iA2rR*).d.RJnw+5oW + A<7"mH@KHO6kV/PUUKwEjnR 0D[8Gkr3L֦IВ7M} D2oq$XC$&  {ԕLa(b p1/]FiNz,yY /-(p. Boca6煗_71*sq.V(Ҁ )Jw`l#MC|sqZ:|CYO*M+ǺcG0㏎K>$EHI|(oQtI]&4p6r\ m*]:kv| YT :9laeQ 4aNxD>yQx8E0_CJ<<ӟqo0w((Շg5Ic);@f"8mVʛVˊHxʸg*_ >>c5mJnf-9}>;}C4tEA:$qb T/NF{1x9?|PĐe86}m~ˣ;66$k1 \=?k}_hfR2!/bd|i nXAqiD V-#;dr~Ξ!Kq"%99>RBW%22|I{<^f/DeRjř5\m:䖯-t3O%2”-'jh]_Lߘ"@@ 0%+}#/zz~ f/!M_GF 0m&Yd+ꆉi裓eaKivA7tca;.a&X5L@4t-  Ltm,FaxLt`YV4IWJR]s&  Qyh$mK Bfv9cc٩aH9;V 4c2T''g1999] x0{,"mbaX#A1GbIǃ9rIDATazFoA2b,_J&z'YuSCS~NjW7jfx_#r CRpFqw2Y.պQup ȴc_gnEU,x$cjUJO)҂dz QC by¯3*S,x&H$,t7HXִ"y>M7۶e&J )%PN::;{8_㙼CnVf&mmDzHGWNJΨ8ł'iD"-gQ  yB!`xxxz 2f^ bipx1/!BxC(E BH[)E BH[FL>lByW B1/)|b ߹4P1ߣU(AeEԲ540{M죮P(6T( BP( BP( B13/܉`%tEXtdate:create2017-10-09T14:11:41+02:00\r%tEXtdate:modify2017-10-09T13:54:57+02:00֕JtEXtSoftwaregnome-screenshot>IENDB`Eqonomize-1.5.3/doc/html/C/figures/edittransaction.png000066400000000000000000001221331416454732000227360ustar00rootroot00000000000000PNG  IHDR!yo cHRMz&u0`:pQ<bKGDjtEXtRaw profile type iptc iptc 34 3842494d04040000000000161c02410007646967694b616d1c02460005352e372e30 b^bIDATxw|WzNUn4A`HʢrM&ώkݵwkگ㰞kf4IiDQLb rjѹAf$g0"3!B!AB!B!@HB!B! B!B!!A!B!B| Z3>e"6qI\t 7(u=Q'B!ݠ% e$H|ضGFx/XP @:B6 HfXS!B!4/sCabǬe_f9hƲlzIhӃ0rƶml=+Tc9:;aQmg q)z[ai?yh6mG2 Iy & 2lFηqP+KֱzB!c΋n{xSSٍa9c<7#PHI*eți [^C3ߊrp3WZ+b5,[xQ7nD=_C,_e` ;>):\vAi!K-6,Oh 7`挛\ ?KݘMkP +1L׸IuiC]<.BŢeYVEX<EEp(+/' Q]y 4NU6+c(a8(c4a TZr#B!#`hAk̚|kR=?IN&s7F<‘ M* O(L81R mgODNOeh2Ēi2F:82R׀P mYXV,nJE!v6E<c"#κU lT& (;Oqxa5 A3[ɠEQv&YƢĒil"`l,J"Β,l+C<6A,jzFL@[$ bTvjLX,ɦLD'k͹sN̹6g3.001dMm**2&`]&`9U^yXPhDD2yrI,fH$dmK!B!5qLIZ9w ??+taT&F>@ghoD|qn`~Qo~)^yPO||fNo?OݶZTTRJ10 #W(293'QP6Vn!nm{Kr7 vv߹;yt{1Ѿ񘗺Ua2K8+嗏WZYlfˏ~̑t 4#l{SŲ0p'ɲ[S6mi4J|"BH海)DDZݼEVQiqQrjvC{9OJ5}k :ts0B<>@8KqF\꽻yWaLt*(HOLu} w㍭o3"F}RtJ%,_MXٹtq=E>v| !B!b& rO_{lc49P6w_mk4Lbxc]#B?V.glp/!\RLՒ ܱv-Q 8-})xfq25ɋ|o3ww?p7zzk[wpz8ʤa iA1_}n7Tomz~/:J TrCs]\Gx`b>C,+Žql;Ҏ*gF+=K;Hb>rMMoM@%#QinXPfm~A|A<{SAvl?o:Y^{Hz'_(BU4Ux_}biMoqv go`#8',ib,tOB!B:=iv/y8̿,w@'ؿ ܸ Yh $`-4N%U1>̓j8Ǽ˩𛌜b4dUC0yYr:#8(ξF<(~^#]T7QU\Hrrk..ۍÁ}Sp12Ԗt Z+{Lsw>ҚŠ,n*WձyEnG>ϙo<lq5pRКV\|nM ~6TaJn{{&Lv7/?,a͂8ډk-ܼ 5-^cwMIU Vbo􇨫ߒӅapz4gOa=V/ekhh` 믧 ,]aak53B!B|H]U"w~Q0?uƣOE &:U|5,kr+h.⺅弹 q{m F,ZTij;6<`36Lʪh׈hf v Kzp9g?iж\ى2Uuu4{W?elYvW{~C8TNh\mOA)u3Mښǧ5dP¶ml Nm۸x_`-!B!ć eeH2OOgh7Bs>O21Vmǩ7O_H['ZOqd; U+n`1ȑcPXu3dl@ۤʈv346"ذ{:?.wo]sp'=,Z:<{7 V4IR "U 6eMM 0q&T-ZKy#mLK;cI{*d7|!B! g_Ri,Y+h+[ؼu)'UՔph 37BT\˪ٜ>C-]-'T1E'#xjpòJLÍט`7/şfsT5/l"bۖ7DP/bl޲]R/]'qdIۄTѬzj^OGH؅,^x,PDgR kR:e<'k,2Y ⰗX$ VYIflBk*FgD'b-uMOePNS q:P$q ˃&1Hc+׋Lr~B!BkA]#2R>}~o_ZOesY37sZ3nltK~F;ZO3Yǚ?9[(!g6__{yy/^ޥֹkoz\]K.cuzgB!Bk*gǸ ۥy] +~czzKl__ᕖ_b3R(ꝷwۻu^2\:!B!jv [R6#=m'ډ̒B!B!>f*B48%MIi#!B!;A}װƶml[\ _w-"B!=3sT¶mVZG6VvPXE:"2]WB!BAQ B(0 $qe6e%B,\N"B!BSdiFFF(//0A$EppH!B! Ԑ I}B!B!gF!B!B B!B!>R2̌*bnр"-B!g91קBqrSs۶g͹.B\Km^dL-8DZB"/ž!L,ǝs ]CB!i(())a︪!` d~Cd!RtNX RJsQ&%VB1giutz ︮^ך2V!Ĝ`\$#1.5J)B!˅`Yו qI F!zZɢT*yB|\tU^eBaƬ"zԶ} n$5T,&󷸁פIlÅe[m =dWfs7VXw., ^S4wE@SK8#CD[(12ԇ4ɌBB1r lr6"1Éty(.-JacUǟC7 ;sDƣE@%ThXq>P(e^EGR` iMR3v,55!ߝgr\Mh4a7[a!2Cw p(-+# N_ϥBg ?4FF^s|KJ(.*i̍ |ǒS !ćW?~ufλ]E$Ў׉8Y^W ᠴ`wP RnbG E^5qMo&ĄYD@c"kCgT3bx7A \!(H[_Q7an7nb ^\!%S@CatӦ;sSSViI^{೷5c΅5P% dhB|4W148},Y.>sn&I1|q/uah[>|G(2q▗B_+g?)4eAL}* 8Yaj~jq(۹.LP0j]`$fs6#">ϾCZ|Cs䍮&bS`w lP \WQ F9y/M&M'SJoSM`JB!U<L2Y2夸~#?{U&6Ca<;e\mZkPJO5N:=jryJ*:N?;' ZUV&Ptrۙ}ƌmڏ:ΌQȻyʣ X_`cHԉ {[cF'3=}g6:^6Y_b2H0˹ 3ܕ̽4. i)@Av]/>˭="lf0S;r# T)c/LVCt0s ۶gݨjMl+ AɴP<#rr[{/}1N g?;/a|\~qZ ggWZcv~F>@0}Rh6Ƭ{ #Rnz߶ G!Ĝo"W訠fw/^32o]5AZ[L(]x3#;1 7uJP]gOEOw G17޹aͩ97좡>WRa]r׺%u+ɢyU >ȑsԮn^Ig߫O_coY縡4ɞPei}.mЁ# &,LWRW&FfS2i=ʁ]1<+kRk!umcY֬RdYl[t )\ݿI˪ ab}'ǟa:γ~ܳ 'Ypf+uSDGWr'AݒU,*'^?LTO4>7+` xGw1;בmy/h!3΁/㟽Ô_uz'bQ@y'/W0<2gd⢱ S3e_ 5ʠ  ͸ zQg| Z Wgyb P2zKL*MżɃ&)\L X^*r3NYWd:&NŃ -g:-N5󪿫B!FziRZ4/ow~0^xt)k-gl 63Q]<GIe3yg8D^WNplǫ'K).a%G,0t;7-GI)'>ṭLj߀|ޛ(0djB|t(F'xsVzzz$[ol(R<5'p_ay .M|Im 8V$;xMofW%UE~qǧ>ۮdRNWpw1V !Nq nꉳb TxYPAm{y.ťTb]&fRF$_({ PwzvĿyR9eU0-wtVTBTz(H#WQr*9s/O؜9yۢ/ >7dz5[bpo!hdςy,\8=ڝŲ!jkیtr<ʦa:?|MnZD㒥4B W-oç-P[fގ8}~5n\&}**(9)zp 8، z2Gkg/denjy UOYweh槛wS7LeYt{q:V77-KofƎwʶVOyȃm- db_ҸYTe(Sta;lt<"`#eGg4{wgyF,iHB!OZk|>/^̽E8\[omcdtU+_4j'Amz:0 K(d+Ē+nTs95շpOO{_~@;}q_ث|ˏ :MaXt S#D.8۟Ia>(Ŕ(5+$j΍tcki8p{d-; mRW]Jjz<5p)SoXmpR6dV]:zP5 "`@ƞ>6SQfBEs' k:+cf\`Gs`&kLoPyF?Z,[$B!: xJjXRex<\,:_,WƚuaFh`p,œrh@iZOyi^3%hV4Qp#?Փ3>Kjf !x8֯_ 6*>{﹛Ь!]iRIf,o~h.r3|$-,Ƒؖ@ώ_'Tç+M3oz/≹b@I!nYQӅf ׋#5F4a19y,Ҧq<3xaGpr:l٬f{Mcpo¯ :ږuB3ΥsC!y`igcg`BE^E?lMZA#8 Wr~E(Td85['+`M꿬B!qs۽奷Opv*Üh%bKo|bt$FГEm ˲ ]ǣwaVغa__=TLGimeB>׌v8_0+wlcX gveO'E]b&. ML 5qKHz󕪵jkpF(L9h.OH4imɂTf-PSFÅ3D3۲?3n<3u;S爥ȢM/<4+tG3ަȏȏ?a5,\wm$*^= &AHH GɚNDғU+_x ;?{ H sFT*Ca"W/m GsR8;}Hଁ}YiphA# pz&ٳTDӚC6afw.v(z-͈dCxeG` hJC&1UTkBɀH>/?[oȦ*zگXUhP35y{~k !L/k__9n?x48LqNĖ!;^!i8x[9pbLR$ Jg|{}ci"G8x&ŭͪe+OpjJ stOko ԙnz= a_o3g`k[G+{;(ctx}v87\5Uĭ W`˱.Y0LSͤɤdiLKl$V-fŲ >P0ITݲrn@nop?gΜąfêB498];?L6kKO}\'L ղbu);_xm!Z9ޓy|RbZl9~m#Bki[{=xABgU)E:&RPP0{ 0zN&It9ѣ9zr>qCs SvqfNv8()Gmu }wyF{UtuTSW]lݾS}D&lkqƻf&)4ۄ#ꛜKY'gh +1Vf۸p(Μij?@/%KC Dc uqm7ƕo;PhM5%LtLe('ru(t.e(82bSwPR0ݟPqͰX6X^`PU4 VMMh9єM6VT9a$IM܂t.4+ Jlͯ;-:HkF,łɭK B Nٜ8]ueքxRs6XZ[eHRӗPiPJڜibӭXW6&6粊M<ڀ"6a7X'9Bq -E!ᄦWPsI:ꦻ3'9q6kh,6h9vm}.'v2N1•uV`$:}(GE}3eaϺWCs'?V)9yΓuQ3Hg F&>TɽnFl7ՔZDLK慸(8=µ, A˲D"B^wJY|T?'OCgyΝ6RRV.[ɂG[{a) zqzՔ1q(nNlS6aRP\EkvH c(O:*Hfd|"IbG;9<T:HDƛr2UQ]YFv죽wXnrzS4/_ L5wB|(5cZ h0Xh4ڣ1z%LPUYyQTJOq$SV&*KfCtс>G&0!* g B%P<# .*k( ID'n)rjq^:r"+Y旸Q/el4^:F1TIG8; R[_GD)Gch()Dc&dx"Kbc}#TQraeEYt וyXSҹ }8Ư&q6EnE[nKkӚ EWa'+D} 1Ќdg~̫(v)kF;EW3r=d mMڜO QrSy3&jo#6 Fș^(n/$6PO!>L8f(SN2,0&66Ltp PTAag$Aay =}ztutn*xQ:p?cUUeNnc2AG>d 01J* zh+CdQ顸₩Jg9na&18}cUg5T/qiT< 18!i)%T&T h_7cXN/0eұ}#d48qQJ3 K),w69}}mzSQw3M)("t|݌5E5Ԕ0 B/vz~&6._ʊb<\ !Zsښj.ZIeE%i^]"7녁15pT62;R _vn,GV-I[2*m ,WYVƲ5ڶ/a1Pӟ+7eX30~1zֱض;n ѸDUʫ BtM+ |=wC% t˜}\_ͨq6b!b DRjzxֳt{;T۞k'/|O֠3޾Bcm3zn7/sGWɷ93%St/:Yq=esק\Z!pk3=XAK_\˞f ]x gg-ߙ5& 3Ym9YBKA!w~лm{xh2k˺5eYW^Ȳ& c%2s_x..y?~J. Jۺ{/^W+ﴮt Kk/YO0/նzȎw>'^-E,n^Ƣ`zNǑt"BPH1֗\0K=ŘtW3׺u~-˺hN]lC!njḒB&6JgW#IZvPlp5dm)BKю.d V̯&a`d/_W'f\f4B!栫m?"A\`ZaN\-k}hWnrQ73/<=ٺ"bh,S>FyD8x6\4{][AcmZ+eB!w3EG$qVr=+897ְɺr>az$~e|]mOKoԤ~ 4a/|X! B1h_}H!x_L;4m%lcB!枏pd5`(LIB1(EV1Lᤌܼh=)bnJӘ.O׀aa4CI[:{B![Cw,˚%9pPRRL?eKH!ĵ0 Ex+.AkְiX3B1g ,(4jPJQRRLaaC5B:4*KO׈VMV_#B!idAqaxa!\mh B\CB!o@Bae\B!B!ǃ!B!BP6Ųdr!s4k} f 4!v5%q$)FGGs!b.йp.Zt:x4)LBaxW\W׀R1 Kq)!sR޾~ƣQJKJ},ˢ4qԷBq)dq*+8![8rB-I:և!.#kYk0 ĉB\kJeٜn9C2 Ĝ&!RJIQe TJzZw^!%_M;!c!Y&Xr?&zo(G !:dE,AMCDmͥ?; /^o6۲̨5ڶ@jwiozgoG-=!0Ik[;IrR]7E 8 !hRJr^vk=Hena!>3)F#Ҷ¢BcQ)E&et,r pKRjD "\tQbzTtB+P03ضǷm՝W%45$&h_( KeB(nKvq;py (cт&wIVlϰQզ !xZ_u B(tj}oγplc%e9c_S7~ ]BQt/=MYLSJ֮3 nbE61oy.G/J3EwkV:Q7x&Z>x1;I9(PNo wtd/q^߅6mRQF,^t՟p0A~_Cdcyщ4k}>J2x ;]oܶjV7I߅ eӋ?f@1X^QHiQdNq!ڗB( yG-Y[cF;T>zXAPg6xJaL.[t#.;k~Bq )V_v ~2$YΦ8nucIR/߻n=/|ifnZ5W`$?i*n2 5C\ٜ @((YCk|F|/ Xh`ْWwS ||eBE@q!wC=? eLpPO=g2@~ӑ*e !"۞<g[4ֳZrIsO}+'rh':ҬXހ*Jau&í[⚑PV>wpƲ>oPS}fϫgHO!ǝ~5!Pb4="rz\wPf*,[+Eİ SV\5Z)T!biʐ'wOlhܺ:~LCƛJ#'bOД)E`yMšJLӀZJKS]FT4Sl*MrZƊpA6E2r7}'u7pZ6_M|| ŗ6 x3onيm,[3t.PI$^ L8.^R%8tAƓY097dlhRj8(o26pyTJop g0B318IˤB&꫊Hurfn>V =g5'blPO}O`THFFh;~#I1.vޭ .N):[[q=@#Šr9Wç^A]VGOq1g& .kW]/}#ƙ:nZ_OCqtۧm>/;U8˛,!56voBa[1ZQ̱CUsu*T!K)E"`d4BYi Nc*nhhpьwG1$c2VXQ*:wݹLOh-+rXb)]+Ѷ&~K!WyB!?<r*L40yW_5[x\q.{eeq5  po-d>4o^n|֮ oܿqJK-d]m/]y'Wo`3|zzr{lN>y17Ya`rK_?yd&z'?25A?~z'T/6Ċi_-^|w#8 -?{/+ irD7.)euݏ<Ҋ鵫97Йp4Y#BأY{q^Տi?;e>7wc? ]DɠpS=9| 7tZzǹ[gÚy|om=ņ%PV?DB{w'$ٳ њi^PM/vc f5uI/W_K)2vl=ɢ?KNur*zmeۉgh$g װf]#W-k^s[p5-BUL;vR[Sڵptw-_p]t$:@870e_>ڭt‰pi K8=%Twït1=X>ɳnq( !<ͯ+1wMLeA"n|s|z=](魵_̧6|'2A~e$N]t^hRf?'Ϧ>1f\ @@IF4MAx|?4Q?%B8*}[`֏bJYa%]s}w0p9!( (*²*TGIꋇ8Cȏ;kHp] %4- gMlقfA"kAQujaϮV/]L )j\"Np1-d|r*2 U~5M,*  Ցo#q7/z楂 3\ Qwx`5fy>7"cYhUF|} +#@EU%᠟*+X}B!>TnqOw>:;x7hDccUMII78QmYxe4rZp fiN(js_X?1Ol7G6xg ڒ"B!5eih0], -/ pQRYC ƚ gvӌg55e4PꋳwscJO8wǪ^̢ \]Tσul6;/Ktz*_ wjlC ۶ѩ84*Tz(SsybsUnvKj4Nj9ɞݤq&RLQQZɟ3M*%2ҁ'B|HFd5MҦPD`)aZacqדj/ Y6ejB 4((odys!:̙;XSCOd26.go"J0~,o~%͏vσkk8]T6FMB ^}u޵ 7guaT{4Yj\9T.OOoO 3E4}zheLrhrl+Mz5VűwӛP(f*T)DZw!k Hrx+c ZiOUq vz(, PT^1,O.wÔq(8P4']GӖ`KkPW_+yؽw P(:m'H\9 [-= fOԁ T  1.agnP l;c"Ybo>PQ"zx;[3XdqlbǛ;8?0 e%˩9O&? | (-P tLʟP. K(5Wvzc}׵q'?AMzq {V?M)hQbk?2kYl%3MB;q=_B!>TWWЃp0M7!*jkle]v7c{{ONkdt*Iüknm%A'&^}XQRt VD'9IA"-r'cjSldo|5M)FOsC;{Az:M`/'va<ŵ,^RMCS,R$dshVd*I,fB>5%oj0~??J)4lK^j,eŢ:TGsY:::NPh-2BOpHqicTs]7S].=Av,7u5Izz,YKv>RD'&yxB oVS䁡̑JRXZԔ1c<|zo pL?))E0]kR)28z$457S]@]!XK^aܴY9R  '(++}So Smug6 shR ۶ 41dZ=塔a0c?*u.L+0Lҹ~2>j;_cA3aeck=red'BlBO[f,S0}>4 mOոR15d¶-l;g^ΔJho8qF?-6Vf(m;r0~Ӥg_}!Ek͙Vjk)**hYGg'n A!pvp //骔R:_ Qr.ܗ iEsA*l9]&!B\ DU!8;B!fSp4}SE!cO+q_M 1B1L, B!5}l*'CLB!"i2%!bS6_o7B!B!ULkII !]: .BWMl B\#aIg:B!ĵ&p8p\?ߝ.S!rA׀֚P(#pB).p8,94M*+!JVBkO ,]qu B\#.2lC\^]!Ga 1~~B9J]9:.AkH:zB!M]MGO!kX!B! B!B!!1!IB1IOB!暫?HZ366F2և"B(y\# N366.ŭBiPXXRd'bR $#b,~?NBB!5GF(/+b!x"AqQEEEB1'(mx"AP!$˲Ze2$C!Ĝa6-ضi︮!)ZB!&/B%*;2;B!S!!B1 fTe?ɟxmkaȃ! J]/;&`\) $oQP4{1X]gZpp~ NhBU*&e"5n!p!nk)C>SO>"?B0a%'x!BSwJA6he, wWPJ3DĒ( ̕_J)(#A0&hUʢcK߽D'Z\> !uխR0{{P&J2a{*i*s-`I!sR/E]cҹ{J'i;3=#p/7.`%سm+ܩznx߱Z3zxYΎ1 3o c\w۝:[{_;qyk$ɫatXf5^ ӏ>—Yny#}2[5P۞}6n﹏O+!ѿ#w8 ߨI2C!>WB(;˿|=Ce@s';OMCxVP_`biUwɡeoĎ;[v[lz5U4:.;7e3Īv9RG`j[RiΨ)og>_P_{2i/ć8|hP_5r0|웙ͦ^S_}35K\m^Og\eR$ߛwN WwI赾Bw v]g 8tضlu{u z{;y}a֭%UZvEx+wRs&1C81FӺذGz9y,Z]9J[MHSYx'?C~'Q[wM>*-1 {_}-BM'9+Ibٺ[&[k(^}_Sga!B!;Z4.[ 0YQl !,ѳL(ZY\V˩1֖raBĩ3l߱oKhA3Ͻ2ol=w݉O9& PCnjōܲjcx]L8;YVĶv:bmC!c]w361AY̊K(/ C9{~fKP3Y,[pG]@m7_)OT+)9q:sլ[Yx)|5z<'@h9%uGZORy5~Z+t6Ngk IbQn;Iw)NYNc! V݋=(Tf8z} kneӇst'uZʼ&3q:NaXs|TS enx[B (,~%Pw>좿݃Ecx^s(?cluv W{ngHi1!x\N[i#PS¼(ܬQKG{i??(^5o  _I9EyѴRS{ٴ*C<9AԎgym/UAZ6f6w!ea:Tڛnu+)uػ|/>BnJJЪo[ױ[`\p9.b)*+a,?W?!+($>+=2Ft|T2mQ e8^rh4΍,Y5>A,BkBVѲX0q8YiMg&:.t&{ɦz~SߵB M~u54=Gn3377LlNW5s7R착5{y;(Va{qicp&Ee,YE|#dhdBT)f)m8nl;9g.+_EEEj 6Mz8QȺ;7R\S^oTtJʼ6-3!A BelW?)g^"F 931i\}u$# FOWLӅ̽f21:0LΗF5_=6 :n9HnOha5nx>_.cJ#⃧Í?f45ӁO鰲Y4ЄÅa&uIFO(XtV>z|;lC cZD46UNqGu5hmOMa:&纣m^!Jmcw< eJ ׯ 7=~X쏩 Ӆr:Z?Kׯgb6gmwX8gkb&0Ae*Vn'ngf_ 㞱mg,l5216B@/,S&60T.(m ^'}O(/pmMb' >۸3}Z2&W!x]q8 JWpM:sT-Y嘶=lf#kj9O9s|g7u Zuc'ԔN K ﱥB!_Q*7=>*#ɂRdR qR J*(9G\sii ]20<2ͪRL&KL]Ƥ \F]mF+o^cv&Ne0YRᖛ~t?N/:h`G3žRV<B~rEmTqg>Ǫ^|~+=,ip80T;_ȧ> Ma`wx:K&'2>Aʲmg?b$ˮ"/JJg頹ڹ*ғiII[Y&f&M*&kV \W`1 *L@M xhY-͐BZm\QG{=3gA,g+Vt${ ; lXRVT9q1t"8o+} ho?s/h0,]d+PܝmSlڶAgpʃΐNm&*OV*-`9+h wOgH"\d3fAҙ !Vֽo{Iͣ0,>Cd 3_jJj (Ågpxx:K:c426;dŒ eֆa1(]H,|'ȤS0<.f8oP ύr;{rUijoo۴ jpbIH[vn0eQ/YNO9'˚Y]gӯeLhdV~D"I:kZ !3R*If)((-FE# v[Yv'y8({vM FߨͼT8Ǻtts WYH^}c/FR7ULofeԗb8m}Zmrn^Jٲe,+ũ߿cݣt) z1~ntl|.* "1x'{5jyE#i щ |^/ߠB+9NǙ更 Xd?nIm;Ypq 9E9Rɓxm@}d2Y~k;IǑ}eQ ) qIc>| Ċq:B^'^ V 8F*+m;ě;`_Y_ښjt~v{h޾a<**I^} Ͳqe 2Oy^"iM|lSqrg`Qp %qs4/4b8i.t1}" ) d8Mlehh:6;4-_@y0ˡi^VZFef~Y1/L|o< I+׬ gߎt%Ȧ;JhyR=R4/kӰl?KϽ A4i1~`>J}} {IkA-M6Bx]2KB[##`:66FA 쪃Xr)e^6|W<{[wǥr0Tk  Hm"V._MT nX@My*V[DzUPU KnhV MyTSR\@ >J+k,rKB͢Fj+)+)-aAE/rj9rcN,UULpxT56j*|S B!ǑBcG),ǚE C8 \0 M XrqBJ=6Eɼܲf>3 dq=LvXXnŝN'uFy>wB`S\Kj CvNv4SW[JaײfYV6 'D_BT;XβUi.(\%+XXK)\J*Xb0L,\u͐K!@i5u$'bdm+e72ZLU\]y jR-X@]y~/v/TVZcF++C4]w#uAsְg1P* 1cQNd~SKߕ/Tgj $}7C<&?/|}mEn+ggz33զ1{|:F]~t~jV_u'f=Bq15gZۨ4͋utvRY[vUSt^yl ʚSD3Oҏ}i>VfEy5֬fӖ5϶e~o6;- {+ŚڶKJI !!1^qSwwڡεSl3I:ΓuQtfؗެ=-՞4?{5uMfuƲUrEm]^gfRW\'Bofۚ@|>?bg_ZǢx{u+4~~[UB>E !SQ^yqtwnVc 2(2 !-Yż%칚հb-! !} ryۻ8;ߗYw }I7)R-"Ӓ,nwonLtxb"&fbfwv7f{;ciƖ-[mɺ,Y)7A}V|GH$x'R~||eFet20i5Ɩ}B!k&!DC;vr&nυ姤(-Ɉm ˾ST0KX*vVNie8#eVظl-̹1Qd*;ʙ#G87`xFw?iH>ux'~,ϒo&=wG?ȿ{ Pb#D TSdÜ>Oޢ*YYBRJ3xfW07|~}kwE͉f:skN7y0.ͧP=3kڵצq1RDG:MR[= mB!ĵ* 1q@9 8Elzy/7XOYUAih$x< s֌u絗_qdz<@N.A鴅{Q9eO5ʑCXۑI't7^\V/) w6ʫ{)ǬC6r<ɇ;/~YSGT3KXx6e ^NÃpoC1܎ɶ 򫖱em.^=%t>njDe1SOi+ի;8۷ '\SQ䥟L wwؒO`ޭ*L#7_l9"(9.aPAqR)wV*N$#Ř|IţhӃN&0=~|(+I(!V.sNHiRD"Q,E0mڌÌ-\>?{2I$ab46@iX$I f<74K˙ H;LŚM<@{T.%}{15YeX&='{Yؗ:.It#7[ui!j1ݽ<+?űl'YK/Mt8T槞<MAgmn6y90 Exi^HZVa o8,&kø(>J ƲmtQr3~=S!ett ӁXX`0q[ :®0>4mV`Vfߑ| # #Kqed Zm罏\25Ci[0Ü;{g/yo#v7b$~ڎ7s Kƚ 8tf _XWPitJ&dܻ-n7oO{"kJ;ucY{q+4-ֶ&șV< il`<eX]e4aJB! nI^)ECc=owtüe'>aQ gWP]`ȿ?h>?k=#&y{9w9hJkFaރĊP5SC}.{EyiVzӼ'8*/e+klΙJ@\Զhh1w6(+ IDAT2! P4LР8~HLbĶgufx¦DKPB[~a @k?F25656DgqchcW-[xǹo7eij2Bk:HWDQ>LW Tpgy%|:{ύ2p0yUyx?yC+yWǼq 9tM-DbI҉;q'E4.瑧_ŇдD9,Y|?Oo<~g<_gb(gB!n͏АNІ ˉ͛RZKbA4B)ӉifvN?Mٴ67lpyv;Z~'ϰBfΥR>ZM|Y>hH4 = iwGNJٺC[j6=N'atqXU:0vp3Pm.7eO&Yrpru ekaVl*N- ilXBk[o.o̩gh:͏Z_5axd14پ(`~><]_&E6Z{?k^wi‚K./Bcu} GNeSx'}Enq $˫Y\SߑfU~DYm5%X.V;?2Lw5z>|&lzR \,ʥ#YɒEQFFhÉiLܷ(3Qp7PBia}y.eFtE+Y]8!xbf˓[PSS}ͿT>O`EZk#$ X}lh"MV淨e Le`F^=Q4'WГŔA[kaQuÙ9J2;JēOk =mj⚨цyiljl|,ώל8$ 绩۰:F !r1C){0LP[f=.#?x2}mSv@'6ST OQ-k tuәs=2GVEA/gqYsC<Ύ7 ֌B1AkgG;ygx32~q*G{M1mʁRp;/ᠧo=q]3)+$mNt y_esddÞShedsVԥC  T?|[X8$ B+UBt;:Xw?iPh҉qڎD-~?za])kbFID v32pشv08HÝ<.7h:#8t'o`_B)tl͝港rO1|E<‹+m~񣟲l?)[6Ӽ6|+m0Yq6owĉܹN0m 1O8^hf^;Dt3~wycfW+i?s1ұ*ܐ)4dX2}o*ābgyE ?B܌ gEU5VN%Ol~&vɛ@ܺ l]]85C)M_CKGcYi,"}!5i"&e"=1JR6"eYdeIV+$m[ؖAڻi,Jwv6rI:^+=8,Ri +mFF0״>+Țaum/1sZ%hB1TJL&I6P v1GDFlC?xK/=Jmgrv Fn"TQMU] %AttJ(K*Yd1yp!NvPSWCQ@ lʃn H׋a@=D v~]l=طoNRAXOaY%Y^ld [\EЩJ;pIN^.x&f;P\_ZMmy|~P^lC-eqC 9A?ǚ:'9Oҍ<iy'Fc^gr-,h4J^^|]B 0:ʼFFǴRp8L,'#NU scMM"%a)^ ǍP$hmyݘ-b)Kx2tDJ1o J){z#''{j0q\Y>R&HY L ׋CBfK2#H.>/t2F4pyLziى _V#3N'ؘx|^\k iN'stlQMyiYE!uSJ108H4 #%R b8)Kgn( ǃaL4V`i0km5K.|>b<Dzq$Q4N|^* Ob+χDcQiӍADc ,e8Mt">yzܘq$Rc:xx22x^BhsC:I,uJ%HZ g5x3L200@}]|]BIZkΜm4/{ҒkJB\pt^H•5qŕs\'^q- y{tY )%hvIKÍ_ʙ^Mrǥ׮)y.+@.RB]O]ogj[_i_ys\WuKvcAB!n}`e3"ǵ1f!B\/.B!B9!I!B!B IB̧ۤЦB!B1UBZᒉB0\8X@A!$!cl,D:{ ! ֚(~o"Bȶ˪ !%Nz[IB5`9B!$OV_FD,P6 Cb!Xl[0]A(;;8MB!.# K)Enn.dRΓBC)UIB#yB!2 #uB,ӷ$B!<By$Kt !B!bNHB!B!sBc!B!k\m~4AIB!B!,!b8܆}RC)rrr.tK_/%I!B!J)IRws>I&a~_b>IB!B!I&d*7d2yYgTbb~)IB!B!ĜѠ5mߖLLWKbb~1YC!B!|uARל pAvg|b͹f$!B!bꎨRƬj+A﹣|NzǙ1ѐ8Lt񹜌mCakn`에B!B1gn~IG dײ'w':YVcbJAlN7 mh;Eʪx@;g[6nBlu[QRZ,f*g35>B@M$Kq:Zs+9}!Vl䑻W58z`CJI7f㦇XWWtQX)H~[t ◸3;]ݬ%^VĊ]]}e-jjAZQZ3"W\kavt 7c~~us7/=FuVt q,s7=FFB!B!\>`ljB*;d10 ӅidjB(O!+VTs -a:p&l/6!,KOkFۚ` kB)j)6*xñO 1sG3ׁ(+-$6gW>ǘ\nU6EL9*L[WmM@{m3>AKɃ+X["WI{-1B!bNhGN pŊKش*SGp/44ё";@(#Bg03x33۾Sh5316,QgwTt(.$Sh" e8)ΙHL68rY Z0Rʳ* \rboSy+Yعs mOϜ(yqH2]:q=mڲ)`ٱx)Hvp/'XiEU{;P"JF2,% wC+0n>7Av'.QZʭg$RTmeUvU=2V8'F+JPZ&e:Yr 6a[u*Sk᳌ ɟ/#0LBcb^Zۙi#81yJzFQ ed{Mw>;,K*nmKx>"i2JPm9ed{=%t a9()/#wv1$ !B! TƶN6ҚekLp(i\1y#W1m?xsi+4QL.58y4.@)2)f]im5ms"d%49U39_CC x4ZgbVx$C-(-17p\EmBL}\&9ŕTM\BV.F)m{2VwV g?PZ@*>1XX>ݰoAB!B17Dme.{IcY,yBbL]kWh,l ;t-˚Jpt&9aXں35=}˜*a]0,lŮSmY'Hjd=|0B!B=+nitl9wH"}6^lwU0qvxI5.f!d$B!B[h: ҉8l}oB!B2$\)uZŌB!B95x}^FFFIғ&NR.4%v}FB!B9&?/T2E$0(,J$ !B!spP^^WD)a>#IB!B!RJԵߎ$/f];M!B!Bq HB!B!sBB!B! MeXIfII* V  d1ridigiKam-5.7.0expenses.pngdigiKam-5.7.0e*%tEXtdate:create2017-10-09T15:17:56+02:001%tEXtdate:modify2017-10-09T15:17:56+02:00tEXtexif:DocumentNameexpenses.pngX>tEXtexif:ExifImageLength275'tEXtexif:ExifImageWidth1510o2tEXtexif:ExifOffset128;tEXtexif:ImageLength275@tEXtexif:ImageWidth1510 tEXtexif:SoftwaredigiKam-5.7.0yEBtEXtSoftwaredigiKam 5.7.0 ( libpng version 1.6.32 - August 24, 2017 )tEXtunknowndigiKam-5.7.0IENDB`Eqonomize-1.5.3/doc/html/C/figures/edittransaction2.png000066400000000000000000001234331416454732000230240ustar00rootroot00000000000000PNG  IHDRQ;YgAMA a cHRMz&u0`:pQ<bKGDIDATxw}'lyX,r&@$H0Q$%Ye9ӝGξ=|mrEI$rysavtw=lzb{{8߮oU((((>1c7<(|9YnL?l((r;~WWmG1_fVQEQ%j6K20ovIEQEyLw((ǀ (2(( (2 Rʛ]Bb Ĝ&;QEQޗc#cHir__RO$Bʇ'0\]EQy}x)%#cqϕZ!4M[Z 8U5›]EQyॴq\hw\8炔Ӳnv1EQ>>p&APJli~,A_Jj(MG:9m]_ZϝwŒb#GN3a{(gAe]WEQn}]J\|JbRMJ"9ЊիR?}HHjWEQn9iםr v'5V&+¿SCҮ>=~ywf21D.DNܜ (..8s~8VReHZzmtwG0Hb:<@Sśz]fO"+r+k*(-nNd2A@ $pI2Fv<], Om)\U}\='"?B{DZ`%c${αCD,ʅn֑ة/2N݇r ޱ@'mC Vܹ(7u&t\8L];˿ Q&f1{3O>t9.F.?}gFw+>tuZ+?Ӝp9H rtZx ygF^'ܽ@w;B! 8dўK:ׅ 'g;?Exp\B"3©D a)NZ'8z }۹5dq"6PWnS5j!j?CPʥyP[@FGim9G6H$o{Q& R-gp`R!Ia<[Wq¢![;﹗’DllCRCma(7u }TTQr#aRڏΩ8u˖f/>\o,)F-d[ϲH;$5e.̅WJyq-ɢE N${.Ν)rbwÉ%xsXr59q mCV!=aN|c, ֔luc8$Ns>[GX( 1 Q}N DQ%Uոl4HQQ]EMAϝE+YΖcX=Br ) /0,8>H8B&8z=HnmY +`e?-:np8lU}WEY_=3ߐ 4c^'%RYIF'$e89rȵ 22 L@hض!4t>)YY,$L7pT/=.=oT ꊐ۲3ca"Zb* υ1%Ֆ=kWVS]VJmra.9KP.(#+E k8JkkzT纉 #bVQU&&dϾtDSSUNe]= ]REC]9^~ٹ !Ų,tm&C8~ NR|Nbr(M/Ҁޑ(R+{WVHLH*j]dg 3&?ۋC󐟟GnРδ ?,gf(h$;EQETWEQyHxEQE>9Ys0H`$AEQ[uj?OuFl^ﶈ|F6*|hn/Yy" ԛ=wyh?a)|<`<)ybZ %Zy*fJJ}n}n?0()uVIv~WE]ϯ@>zڜcM3V(9kAP7iTx%ڇ{RJ* qi 6c>)mB;pq˃{JT^Q6G>A=|8.~N WDu]ե8uq;_5i$> 5D8wP$HUjrs q|snY((4 '9yAzm_xJ֯]%u"m<OIh.$f=_,,|mf/H۠r]|R 'xWuѰhΞ9Aɵn_aKp|%PEN0‚Kv{6q-O|So4bb)vyimkʿߢw_/{iAjh/Y>(xw%!tRSpG.u]` SO~ĽzAÍ"+Ma6EQ؍Ne&, ˏsP+`pƭNٍ'1+?>~brwXVH$|!5UNSװK @uu)S=@jNkj)ˡʒl yxo^^mu4Ct`-OMi^@b×x6*~arؖMQJV/|G\LEM l\UV`XsE -]ǧe%70qOgOg xӗ_ G?gsϧ?Eqi!z>p8HaliJHI,[S M0>Gg()LRq[hbn_s{SjFi>GIY9ƅ>VqgR !AsPXYG7ť3hÕSLjb#q|3=Q7%A,Ȣ ϴ7,Ю=l'i).*"7&>wp/XoPDGho {6Pp]8ͥB ;Dx:*K (YH'Eӥ3Fw}=^\:wN6a:5,oph;-gQ]VvXj-U99?4d2߉o[pH;8~,Mmv̪⁇Pr><Ԕz'x;#"b0'Oa{ XP[ JJ]޹KΥ 5ivy($5|յ>]wyW0ѱq?|=H)|Id >qnF].ls!ҶH&RppZoDz|vN#M*$iZI"Ĵm:N!mD"ef QwVbIJ~/m).:Dz43ID<)A \.'HO] rIӴr9"euӹ$OI"H`X|ˍSSyV*I"eb885IyF;!^ S.9(Gpc$=qrcAϼ=E~\(r=ݘnn:.AwE|׆6VE('$N0?g0GQUEQ |g UN( k?I ƒ6 U]VE,:Dz!YdJ[ovaEQk%,s<$lb REQnYV\,K)(K 󘪻+|r}B&QEQOUĭ7NNQENUl& 2͛]EQ4M#+x>41@♱›(rLdxdZCQ~DTWVx[(H)ԌeY*+ oaEQni+]Jecޮ($@T2g>}#54MSۊ(pBH?mCH]Sn O~֭o9sDogl")._9>( $Ds?/0rVqN1 Mgro{) (ƚe nMgdmHLD Ep pk-Y-XDlj$l,<&!J06") AV)B|9 í'\o6,'ۥEQ>YX9́#p|r1n["o:ɑӭXYe[cx! 1ǹ4CLZ$M-t wE uk/YH/p)nYM@Žs~vEp9S&Xq罬 p`!,e"y / H 7{nI,Uvu#nEQ>iyeyWaiK8y^m[=(M\fFѨ$倍-%jo>S~v4c zX1Ɠ,h?Wʛa)tIE7D3.]D{Gu,C [scm{YMtK.6kV}x?O?NʍlXRS#s^[ MKòTz@ژOEQN f?}⎥[G&x Y9ʙ9ttjWV$RwS]d[K}f 9Y@lrR)Aˢ>@X"#SHk,،)[RIU,NF,Rt]H)c,-.f2+H$6cccAw9+S M੭+b]w>iN?I_2SضmqN7i2,mg.Ĵ)J+7f8qxRR腗RxXzԿ'5,ad']H dML ht|48uì,/D7bIeZ/2<ÁL_ZׇihH)p{x}ɔmsd7[ٺu)XS/ضMp5(ʇ"gV+ogF8۴y6 G݊Mԯ /ΒUT޳ͺ: oݽ]C,)L?Hpoqmo3^]?O"H$Y^Yü ! kh?v#O'jI&‹h\ɁEQ136JJ ]GH%VQ랞FJd,Uɂ"Bbb,ne&pfZ)dŒJXX?MXc_n-E^&R5FKGūo,l_h(h߱@ M!lc8XUX}[ M2tv|% Kf# ekIJ,4Mctl^yֶr/F}+ %3 ,4ᎋ}$V-,/X)ڶaOkb;{/l9 TT1tp.b"Q[ƒVlG3'L3Eɽ8F V"½ھ&/(`{odRVWPZQwRd\z?~79 +hA|Wa Bdg1xu"EQkh2ťor=x_;mDCwY "cCsz#mZ[3z%p7yym;vK/XȲ8w)C2`rd9+@At7-ᑇ6S;oO-[ƅEd!/r+ۈsY Ö%膋¼ gћ0.4rۃXjA0+}O$x<vzt(>oCܖqx毿ի6Qz ,|zP(/.0/@n1V`aE!9,XՍ85A Dx_-w) *QYZHIaz2JdJ 8LD)mE(( (2&y,jWEU !K?ob1FFFmLQE>ddee%*S##nvQEQk0M^{- ?OYT3)Bҝ)mCEQe.kE_)%}cW6 ʿRbK[-<(r sS CԔH. 0gQZZB^G-xt-`'=DIlᤰYXa&6&Xp۽b}j&B urWZef!21wqǦ;$ȧW"}Sg Li>s}G0aͬ-DC"^^9O OͽSRӐ23>A{yF\լL+~v]]O?DBxhXw'[V]+szj*yчr`['~o~h 3QҌ1 \\"R-{x3 oÒe]mMmҿ o7ß|l{> ,FG¸~܎&k&ř?]'* ;˿x k}be};XR߈n'yݬ_nA=894 -0>oNM"hBEQ9J %B^'mc&-qXw|zC4oK7 ruӻJpi= Ed-㍴-LĴ,$b_h*Y !Hw϶\ʒRkai^~bF1߾5hƲ,,QX<'#jO֊ҶHR̽C2toZ"L J)\̓_{;ƛ;[OqݤaA @QG"1/.Вؗew=_[~ǟx#l(ܻ(5iΒ)a( qItpqO>V..6u2`ll6^[$G:Qq{i=ac>tRDA'XZfNZIh O.I53mԬ8mZXò|Ho;g7Xwp2ttKT,?0 =Sߺ3tB0( ?ki1F'BH *u3IPQCH(aYVw)4vO>SEdmd25=\YA*ebY&.뺗 젟ѮVFxEMdywyvq)AVI .mFysmAvҳ?XwxI/qU Noy9Nc}N3V޶v̠יObdG}&Nk{pV~7/FOD4._/'_|lmn=rr6LS4k~_8T&Y,'/3}LrQ"U,Q9!Xm;vr⥩D"η77| z9 9B,.-1\^|'7?E˞}-{]SDKdQ[@a]I]ɭӿ_moXavbe%i9#O!,#녁˧ݎqx:d]niQ.jM8\98U@Ɔ9|w< ?4-RS n}`3Gώ 5(sMJ㦴;u*ٱz{Xb d6XP_;G 3X _"fSӰ"}:I?@*$Rs/W`<.&_vdœ324C%x_;ʥ!.*'7Eya~ EѦߥidn5 ,O߱GīhxB݄I RL&I Cg;]{Wcy(i^Myx<t]G |Y%3BhhfSG1B5[^/9Η~Ϋ\~L"tb1x.zOsms,ʜPIvfWDeyvr*\Co&uq9X^n3y{~bڌM916EU  Nh8323TB@(4m?ɉADp$JT$ӿhs}4]Ir}I>A`umΝ"w^/mV~KG/Dut]0wW8@mOsYyw~:l鋌l.''"Re0r8[凉Gl0˹mCO3aB*<@S֑H 2IrDd|=o'q=( !`e<ħϻIS?ؒ`vsAپsDcQ:.q N;Os_߬-<_Wsѱq?|=H)|YL 18"%%R t])qrA l{j c1<|r0<4#+܀1?@/ F&c G1sEz!2d&KNL-l2S|gEmf:KCtG\Tuz qYpO߻5+6Kt\o}LM>s٫QqzWn=c"+fk$9ace6A f, $ҶGDJlW޳쿢*+Ir+7˻*(7 NQEQKxEQET<%S)(u1 *SCovQEQk0M.99so)۲qhJPEUX9V~ޒnYk5Պt(s: i.;!OhhjNZihhƯ3d};ަi$~OKQe^p]*Ns\!?@(jMn^y> MA\^bH4qx(.*N]_M][M(2Wnr|j STr}64*|dW^?G *#4wr{kK.%ZbEQ>& ⍧n>ŧX[_@Ҵe H5tWsMd4 T#$OmǹK`'(k:ØegD`8EQnusM{m3>o]4_$9}j[#GYv9~&nI9BgIeMyuU~/r\ Iv",[@K#ܩc4sYg(l\Fngxl}}w+'h 3 _N%]i}M˪ tl;-9x)(7͞itp1]zx]D,J,i"vȭem"j ^!bI#%+ P\RL>#,߉*+$6p,/%uFKoљK%ڕܻ7Yvw-dIy 2oyBF(/ĚR4_NUt_TH0F}ѓ%CY|?+ kOﰶDÙ[ʲFj Vs(Q91FJm!AdAmbi=ol"@Qt)Y(_}wԂe!ͽVps &(ɋX|^]N"(.`VoJKٻ߽nTD 2?yu?}8B1 Mtx׏_$4K/ă/§tqR00 X|LK%̘ͶXYc>z h+xp 3u!e3|B5OaXG7~u5%8H&LI 49Ρ T*D8itmgf^߶ W^mXTEׄX'>7t}|Od~f511A05&pSٰRNEgg']]=\n򫗲:9نҢ#XFmU8y0ͽa XXP v;BWV4/_`ѾN.;s̈́L'VVcs8gibqӼ]ZUWR W<:zF/O_&U8ŭG}S >m MKK77qmx0<͑sݘ%rrgmx+XX^Hj'.d G5E>:NgS$T2^rɺt(\!22:]m|{ɒw&4x?vlK*NQO ),,j[{G' s96@nۖ8A*j9Ifb[Bc~)RH uAh  T&EO,#P7Rk[ $LRenO!\tte!N^JgvEtҪ$A@.dQNQAEM`5 eǓM]Ctfj{OJET14a320ÕEYitEQ)Ʋfۚ۶~{Hra7nŔMWc}<.sWʏϐ >swz>xuؗe-B4bN@?6QQzu)T6,%N~SkԐpXYjB\zi07HЙ~nعrd$4P;|tnO68EQI,1 LG՜Nd| ʥ)~q)5,;ʡm7Ftܞ\~( m@8(nv 0ݏQZn6VmټYgYe~Zε>4)-)jiۘs%m0͗6]]EQ[Tnٙ[0|DxWEQ.'T*?,穢":EQEQAh9ٳNrQ?O^jgަ(J4M{l>4)!㲙EQ[JV~EQ((c(r^ݨ?OEc11U(-K d˛r*SdggQyEQ[q]]8rrrt*Sex (HG LӜ}?o_l{Su_ZpFQz5MMH H`2a`wj !2?ӟ ;p5<8gJFiHk,ۗVc2ö-ltCFL[? s(r5xA*2LGw?qS0t4&WH4YŔ՗ ^`ڷ@ ehhpDut`N.~/Zy#ʳ/ 7}}Я~}E|Qu^! 61FLx:Լxj ^h:#vž6JJj zWu: o$Zn&BCf9DGrY Áe`&lܻf˗7 sXhU5PSMigWFt [F1}=4Ꮯî}ylǭif( sP|urMhLۖ7£ i8 X:d6tfj3]~@?z4/R )+^ԇMdnzU^w9^2O~RJȶYpY}LEvӝ$;L]!v4ӓ8Xl f%J3@E8J{Ý~@ S1[/r 6mHUxhK.H8II6oįkNbDbPѸՅdK'w5O_a^zu/;fS'O([w.0,a}4[?d '(nXSI$f <׍{ro%_ͪ* l6ȢT $$S>D*PýIuX0-Mt(gZ 3"mF-b5]>zr;h>{ޘ&[q3MW/&uS: o&ʲ 51SMx$y%,p["OH0RxYn.͞gٺ>IV.\j͚Mw, ; ,ͫ)jqT) WճlQ5~`{U;V֒ηHC:qY" <N?M_;9k?ꦾmb)sy(RJl۾jDoŠqRt=wݱEaO\6M@X:--e Yz-qvܵ#O_(ArmɐQ[ wt5m:ƿMy&'x_ I.\~AH!tk pt'I)Nr|;?} Y/O?hJ*ćj =lZAa/?}"upV3kz'YRN55D6bs_$>׏üßvr}^|͚pz)Ɔ0rr=H !n9z>Վ3EUS~)BCKM1y]"oz/(*`%(ZHYQ6dDfȦ.8BaZzeFv2^ԐbE$8clܴ [nsݗ96_FyK'l4,o_ބŋ0 qʋ|dpC؃wQUpW[D,ctuuOY#G9 Ӻ^a ?oi,Vo=zɇ2Dd6սkC:O`[t/ey~ OU.BSo<ϙ\~wi-${VVKHn#YWlV}; ;XBѴt80\^~/ΰ@"~, o?KrR4dyM'Ceu Á@oCseQLj%S kwL6';}-]VçVk'a[h;ɑs,ԈC>|'=g%gXL~P`g6V2rADzxwSw Y%Y AH[ȲOXr-j%=þY#<ĩp/`%+53:qi]drNv~ 3@l"]tc^w> 2/Gj:g`E @üқ kdׯbˊ}Yf)r|x=DI3>F"%dP\Y+ NF[Z5iK,2-,$]tf\C9O v9wc?yfMNwȩ)~sqCSi{9znՏ?Ɲ/;)$h?KUC#POâ}Rƻp\/v& .qR'7YJl"iHn9&nO_3۲0tۑ9G{ڶd\3g8/ڟyՏQ?iYE1:6ƽCII1}z>#2ͻKaNt0k^IsPh%%,YX[$Q"1Fg^XpVbԭ@n}y#Lܱc1VlK],}U9t=xa$M ˶g,3s果UD'I$v*}/v1y+Itj>o>q^ṝ'tCхM߹qq[C|SQ{FpsHd.B *l4ϾM}c'lko$2M)~G? 5M>Z:;2Yb2}aG9qk7%Om{A@%C8rJXTW tEAE5eh-- J**)11E_AuU1.Ƥ_xbN,6O;h4pbr (°v41]̂2M:5J*( bQ'Hyy^)q{GQUYFKgb4XO TRID(/ji7"PTŠ.t jur_=؄F/o^0IoƸtMNq%UEg7EsG1S.ba]% 2:HWw/aIqy%%8v.мTUqkVFI loG䗔L?'Cn@؞ 5uRt=#WJ]m)8م唗ɓ+)57PPOaaU;:),(p\Od0>ZƶEiĖ6jhӯ4 MC 32AMl.23^}|!DŽ>2?ݟβGXVz Jl ˖lN7jp%EE8]kܧMrFLu\Ph.fR^u~Mߞ2Ee}ؙ{>dYl,;t?)mC-u/`xdo܁szRt]ܳ.ۦ<_/ۖ]fmX2$gm{"3ЄV9) s^,utrNNۺ}Ҷ8Rb[nk_J#e_ؓnYǸxfU@e^u-l۞e?W\a]{\Y9,&t#wcKٔ.ø|%5?W㽟s|?@fg(U$s١(GusG?_߼eURKTEQnwW(TMet澑6}nX1.<©(=~.>BHz(0G>I׹s8Bgov1 Ptg%C\8zs؆`Ѓ 3:%~= şez&w!b#?vց(*VZAE[.(2oQ!9'{Hr(vri/}NtԔpJ_%XP@Qq EAAөf&RgU)%-?-p=Nq9U(| ejYjYAəw|E4]UMk /X̺+pثYՏS~ǖRpu/js,Һ5ʦ(2"AJ#:mcZSTEEEw [6^]J&'- S6S l4 SLI$-tӁ&H`4ˉicl ˉk.>H_KJ %YiT"AҒ8]n\N; Hb 5՟/XBCZI) J׌335XDhn mR;]:f2>_ˉ"Ob6v?3b r]{ D +L&H6B`[L| T(9kR0Q&E j6]45aÌ/|pgwxp}5]G^/g哿ǓJoowht er.=g[ș96Xɯb8馴$j54tMC'3dQZN8o'Or9th߷ 9Ήc8fCK$; V/d<ܶǕ!b>x Cq\$U;6.m/lxKﬥ[|GYoU ^:O81j;{_Z??/XƾV&s'đ/> Ilg.38L_wG>iT(li stn\+҃kxn|ytr;gT4rhQ9x `~᎕U7Fp[$k%<H(eKnc%dcl?|紎UhI墳<_ۯg($k ;Xr}<u?2}u!~WhN I"o]g(?xE:GђlݰW˜sBqV>؝O3;O50_yv?oS[P1c(ʭ`3<Ϲn,OYƢQ6]L]e1[CaƱXmޅ+'m,ՋqH P UwY7mc[jVasu} RhdTt2kp l$7ƅla%Ԕ5Vr6m6޾_:p$ŹT/[J YX]V]o&zN_cIQt >W}’,4e7ygoЖԮvsy][LwKW5RY8W a#ſr*WqS=B_=\S2u;[Xr)%~(pfs!|qO%9vv9w>Pj8(9 3)5r~1nkMu6B)R!3[Wi~Ew! *_Gyy% ZB#aKaJЄ?r)5yRhKXPWɂt߹DYHy@0\.tMdD3ԊӵWDbKȭj:QffC0H[" yh LK+|g#_ujN:*+y`$ˆ`J)8qٹg dӾdt.C ON(rY$$&%q%Ed9IIBÒMkݷw3^2iK$D8aQl=1Sk#bNبo F^I~l'mC"6fUHU0Ͽy|ʊhoa-y)>8BkS6Ofw~#g95L?kUumtjDg#ZeO߽]# ; Xʐz!e57]:I}4';rUlUYW{Wy e9xk-ݫU Xa-9GɬcPVO_իVvFz}.JM2>@o<V'2XnO<{ Nq}uPlIvf.j`UZsӢwnf]^G[9Pu5[P:A7y*:H!Je$~N3OPK.{^H+1Dٶ}#lM_^_++|<,Ag~G;Yv7mƛdt[,ecu9"U}uCiCÊ?אj=J~zL"e (m$#{PhRI8j[mm;;uvYζ LCc[66&95Z.`XN;gp(cx2]H|Q{o~ `" Whq$qR&! fw-meDgc+vX[-C$Қ`$J4Ͼ6H'sP*}g8,eHo+`4TJq^{A^݅;>crS)) ,~G8BjJ , -~pcϪ4MynyKzM!.e^BKc>*2YG]_g>Π2g)fBL벯QD*Q8Qh3]w,+\PɲB»B\sLsԪ.|. |[,{J8(YlG!>iZˉՅixl!rK c}8@DN*RJ1aV6 X0ܗ Ƕ觴Phn%/P0UAd@!A)4MMSPP@N4:]J)lD}drJk:&C~~. $#Ņ3!"h=n}6(mc(eeidsI3*3Qv}3aӵLXHel]9I]d:)Mk=뗦F ?TUfz_=k;VvTn %9.Gᦆhjh{HQ5Ufvr j(zg]!i8xm"޶_>?l]^B2+5?Z#a=yz4+}-t{_ɎMg5(;9Έ)_~ *p}=^GW_nׯ ǧpZ8; rKjXyTf:N`Xf-5A{;h꧰z%%@Ԑױ,Jz~}~ 7 rro<+Xܶe Ӽԣ6xr}uq Bq`vb6?8FO;XxN=FGb %KᘊS/ls9֭,AF{j">6{/>{{ |,Y4> xrj%Z֗=8FPSYB^$j/G_"r8Px ѐAL>.T1 B:^}b1KAi1h>+6mᎍ:_~tʊ79pv)XLn7CGZYw}, ޅ ݌YZb ***).)f[͝Hmf]s`]颷m˲8} LӜTle~蕡9َ&bP=k;ե#rq0)]/_'+)ăq4?H3ߏi(uH 18be[z] wRߞͶt6r&+rQq^y?K~H]zm,[ܷ;W-*"*3;u]nfSض5sqqL_R$I{1֮Y-o!˝vќxa9gwrpq=9zV6 g<ћ6OM}+৿|? 8N& /I%L vgCxKxqh;ކ 2eJDpoDk7VG! FxeIq4vLW?gŘ`n KXBXĮ 6zX@.z&=&tuvP_OcS#_)--/w%>'P$;!:cDXa5~oeb>'/ݲS ws:Go>L^ abzRXPa9C};tgof<>w4~ [6SSDk u( Ic;PA%UE>xywZc%VZEaq7o<ưIm{L?Bٛ~@Icrޯ?5N:Az7Ù_6Q! Υ5iRSS_O4eQ>v"oKSss'/mܰ+rbV0ܱf T'naG=,[wʣo?wߠ6z#Q>sew=U~io{6,d[z-78 !5͇{~=P+(,o/R.}6!P:6,Zw̏^-?TCl۰6{4(XµF9N@?O3{ =yJ9tuv100H{R5rϴqz;Wׂ*B+ C漀2^i !bE?eyfvn/⊐I_,sari|y\kX!>JaJs:RNZ-^sQehZy"]Ʉ#vH֚|Oܶ5 ENN9hk;E(Yo2 TAA! ^KB 1=Lۢ1,kΧoW ~@&S[SM*r}>xq<Ғ}Bqf\C)"G~=J)BФ v0V!^E/B,@BH0B,~J̺tBK)Enn.'J_z{{),($ _KB1˲hk mH@َC04})B!f`& d@)y#!kBh^20 RO맵v*BxLI艧}x|!J**,#B!|h i_>MkXZ5HuGٵ>tfj R pe̹B9 J)F{?O6g_, BT晼}Jc.~24+Mo|2 陻CfSTN &5z|B!<NsBӝ,) ]=]ǭ%A3v- lWLHSel+nQO4ƣaK &tnmI;1!92"Q>E*1H2  Ƴ Rة$jA:XigI0jBBhO֓?e/ܹp$B^4N0H*p8c%3 !皃px,(.S: ?hMn aώDA%KMxߓ*Ċ|ssMͺbm `QygEiѾVx9F"\j1 µ۸m"9x !>om0ьtPh.(7~U!v{ԧX FZ9p8v>ŇX]Lnzڃ]؝|'wn,AjMItZBy!҇)%>5g6϶Ν~^7n{;7W1g95H |ϱhYGl.M?+4ccvh=G[Q9z|Zv=$jVzj<[Y&$SO)\n9с4O|sm}U|$2)]ͲŅ,^o[Wy5~h ߿`oo}mE3B1fnļ& 8C*tMTenwws_8?j m%7_XY,-kXlf z"*J#ءkY]U|Q {;Yl1aMdT8y,*C9l^_ȑNiE_Av<[nn˖ߦXrQȪ7h|^/^`g-{4¥t ܛgEiyH![Z"el\YP{u-q::P|pv/Va?μF6;ՙ3LIrs] &i}5vkEA9 27GII %Ŕ A2 1^fJɖhŇGnCcPb+{XV;!nf(O-P7=ք z@b{rȉэ4Ãp1QAPM_m ?|w5vJ)dW`SӜq+4co7?U_|y:,Wᦓ I܅B̿9VkEmɷLen~'8p375Ⱦמ㭺66Ocm6|860]L];85v\3qiŶ5k~c 1~Nطwghqlױqƺ]qp,0<^>?-tp#ޣn`~*ba åi]M ^!ļn4ZX^e{C4kXN!]p0̦8UIV9^NPw3Cu4wbI t7h}GhZO}׵T-h%pS+"cctn"'IRC:̢몸 _|y>x9N.gݺk 8ѦFGxSe'Nm`}E[og?OxF} ELXn\GiaAYF!|oJ 57Y 5 X$IR22(D`(F$S:W$I,  zqS$FӸ$ "Hak/$5H&Im K(p-Ql ^P"9U ^;3eje{ pL=A ăM2Aw,F-ߏ4NQSS?RB!.FCc#EEEnim;OƦl]eE2Ϯ<  85] ՄY ‘l\X 48?X : &'GW5H}=S Ht;oJ%(K !/ =5|tz Sʼ}f 9ص&B\2Y^!X$ ! x!b@i@F !ĕ`~5N\>Rضܗ"bcuf&~͍Յ1!s՚P(3XD|y B|,)|҂' !UKBHBIB! B!$^!X$ ! E [u> !~1 >!T!G ,01~^)EA~$d!!bh0 0MCZ]o!⪐p.zK)L! ɢB! B!$ !Nk*f}5|$ !̲,twJ`Ao҄! x&BB\R x(/ܗ3/ldK > mR$^!pcϡb'k~>E/2Q(v܅/'i !,ɅG2R#th^rV{q~7sf_b( #Bkw{a`Ap] (edո;GWd'DgZ)vvH[W?/̏< ]4= 0sy~Qyio)`F1 v{8ٗj%۶]KYIѽ(b70̥uV.z!X:5>;G,]k֯e RI vJreO_#,au\v9ch3yƚKkz_`GB\2Saװ_x[ɭkq'<6ylV\ѠЌ 14!񏷫kQ$`8äI4CЛ J\8#4~(R ;dddu#DC~صg+/~_ e$x}ˋQem2ìN6>< W)*BP`(M\ݟ$ !oj0(%-jf~St:IfV/}ˬ- 2QK/@e\ڛXUJI؃S0m Fim=MwȶkaqHOkЁZ `Z^'Zkx8Tɺe穎,~>FB\2 z˜pPv$1c?hΣ~bo{nf}֝t4M'r̶EԽ .'kG⬺~|sCyy撗G,cRظ)i~q?YZP==);0 ʨ*ƃreRf{*{p-<$ !-$''i\WQv+q%_mFf1'p]=i勫dh8 *ɱh1LC=ČH{4R(Rid;cL⸮&|w޹m:ԉVxr2F}k†EhvW{Xrý|[<˴mK^xOB\ih,/~+>Bp ոN{xwTzOaǑ6F->=8KڶIZ6n68m',(e'72\ ص(bׁ&e|4+~W9TWρ={8~?{`Y6}qh'ʖ{>o[kO]\%ʫ/JFЭڵIZɴ6\w#hzW|/1W!sJ)(SZZkFh$ZCo_jtO>PCG]ԝ!*b٢Zj/*é#n |rcQjSMP'ό/e*|g;4 -eɢjj' /Ek %VQSt4q18G|wܾhc~:l|(Ue"1/7G֔UU^ҵMWs~M|?0O!20(,(uXVtFPJax<^<48- 5~QXaht:ek<>?~ofW2t _vױI8F^~ MQTTtu(Ja)R( $֍:VF)߇ixQ?K"p ؔ E/ Jgz|=sf'+<^?sZ7'  xߞLw҆I%Nsx+#!^!d,&Ws/$ !ĕ*@C۸isɯ_ Bq[QNHB\x7Qj/WX.Ju5BHB+֙bm/8hWs`J Fi蠡C35>@`гBB\քB!H$,Ȍ3Sfr~$ !L)E$!\K3x!b/B,@BHBx ևB!Ǟ'n駞Ssxr_B!.Χ>lOtB!£&?/r_B!B!B!B!Bqe1. m%tEXtdate:create2017-10-09T20:31:02+02:00 dD'%tEXtdate:modify2017-10-09T20:31:02+02:00|9tEXtSoftwaregnome-screenshot>IENDB`Eqonomize-1.5.3/doc/html/C/figures/eqonomize-accountsview.png000066400000000000000000010000461416454732000242600ustar00rootroot00000000000000PNG  IHDRJz0 gAMA a cHRMz&u0`:pQ<bKGDIDATxw`^U?眻<{7m6IG[VA" _"*" {t;mYmF W޸|J"2\i?|c{oٶ6dR};*Y/֟L:ǃ@mw W޸\0`Z>vԐYn8 2Gv%#F,:0m۲,۶YΨe1Mwm~ЖMM6ؖeY6}ER瘖MY8-q-˶\\..\yr@G`^1QYq $( ` a"C8o AHCA` QEO# q) qGXE8`"ӢłYw [Yy+#0)8k=pf*})L#S A6,^ulWkm<|i*NQeJ9B>ב=q00F ڷ_{:fʄ01B`[vmqXi&N'p!wx-߸.'\x-veOOW޸\`0bM2fo"w]|cހ>7-MVt' W_7W>{w߿ѿa/Ԇ@W(do6o|gk{(A,oq?f$E7oK"(x9'_b 㷧faukο9GH{ oe2(ص㸸\i.......1lz.~y7ag9n?2흝5KJ:[??/A+o4fIU?غɨ=?tU5G'FX<E=<=-Ǜt?rS4vD[[G@ x|/{g^(jW޸\h`LoL:g&0j{c_8 CkKC)2Logw+(ئlhiѷ>+50۲,ojn[`uX/}o'am^ 5Fݢ?^\((~zO;A_*Ō{QrQ޲.......g-ZQayΟ&j@`*}߼R ekCkHb q'93J&G8oC `ƝW޸| j|kߵݏ/ 54h N rg%N.pyDABU41  O~ ɂHMoĈHw @lqqp卋˧bMmqOz0}W p0(7yC 1=ɨOWu &%L!`I25HmKX3\H[ aKhcG q֍ŋ{rA g?C3  ppÝo]0ύ# ~ !)-h\2GEk~z5ύ.Yn&4o ͈ðu[{lML[n/6P7L.-(='iTZ\;e_{s;\5q)p{̭]ضAg=tmSv!9¢(dU傁0@\^3 ԶmFS8gx(=^;tx;xIɹC\2+Srnvq2Ro-[9ua7S߹~ADqc}O[ՑiҧG8J+~2oHC~o#߾vʤ*Pc3opz~.NDIď"Iҹkn_fo>}~l]\_9?}~98{Cx7W٬xE@V<"aZXgxa=ڈƯ&zBnKsngײIQ 9c"F1F)łQ1ƜV }RIS6*Q!16GD Sr > K_QDIla4=HYrӦZ5F%T;x3 |qA`J9BcW(rytB"aOh+ɣDgN6Yz߷8 F8wj\\.qqqqqqq ܝtoaS^!S^@w xOi? E -DkdMyi=u:派a541۶tٶes0A{Rx#>Á&m;. r+e`aݰ6`wLY2lU=TQAqmW,R:rw|hB}N$ٸo^:dȘ7()}u '-+);-eBܑF;ڿk& n6 +o\\\\\\\\h861BqBDpZ>jiÎ,|h̄;l !jƍGG̼|D©fK:z~ZMZD0l|_*s5gF~V@3Tc]u,sQE>.4.7\4/>V7Olzɞgr;kӿO}(wlRg~WxS+:?z=r5?wF?~y_2${*B1km׽\p).6t5 nw<.`'s Nss~B@d@ߛ 0t[+8@*re4L . `ʕ6tgi64o-Pu+5Z_ycF;jƆBN6o^>*̈M;.W޸|`ٶm6/K9Zo ʓE,H"v:pK"H"Y[RPL $/ _?jWo]vu_3FP8d`[6HOTKvi.......1e73kkk]| z꩒9 & @AD ֡gFA$` Y!Nމ4l޶uM!*&.՚?ĶlA,Brlq卋g#fȕ^Lss֭[lٲcǎ͛7wvvB|ˀσlt~CN@j2ggKXis Zx+-jaX߁EbZGo<1DTl0t0$Xox\is\>=u<cL)\|wYZZ:t뮻G{7mڴk׮+V+oBA$@s㝙]n.{+W! ?Ȣ@cHʷn&Q_2C_R! oF JvA o<ȑ-X}1 "qS |ZOG?H={lݺu=x૮jǏeo;%];hFl;B֤>cPɕ=o!?;A"uŊ˖-۱cGSSӉ'bbbN:gΜ&%%~ؑ4ߎ.O"ѓsA `ڪ.s@ݻs_u3 V!a#aMU0tԐXs;i+i%üntٴP7%oa "޸)I&I0mIiQ"@צ3~EÕ7.......3IMݻf͚ŋ|bG9A5Ryo@YM1@cqqc3:qb |Mwan W޸'ui!\rӦM{쩪u=77wԩcƌ)++:tyJ)8~ki] }%M$ٸqo6G72J">2'TeK>(e3Jsç6c6S&n˧+o\\\\\\\΁IZ]BPSS͛?e˖aQ'N8{iӦ%%%W̸^gLYWWzzk۶m;v$$$K.k,)4۷WTTرcƍղ,=zĈ'N}"A]\p卋 @q,ttt޽{k֬YfM{{{BBKJJL2uԴ-kS2hD}9sRRR6iq卋Nz4ĉׯ_~;7f̘'>4338jwaΔa͚5VڹsgUUi 9sQʆ D;qq9qqqqqqb7pհmۭ.\xYA())={ٳ ^o Hs g2Muގ1VUuͻKEq>Isŕ7......_H۶mۺumۜ:#F?~ȑ#O8?d%kllؼyonnj3zqƍ9|]\W޸\60eƍަM:;;^g͚5~[j5Ay رc{キtҖ@ 3.ѣGgee~͠rAp卋Ň#f#IMbܹfJNNp,@zȑ͛7{֭G%&$O6m̙nj9%` qqqMtqrqqqq J nZeKEEž}:1.))?~ByyyIiIiI,@)m2J)CqWPBDI8B;֭[yFEQƎ7i⤲#F`Yڔ`0rEBHQϺ.+o8֙'I }%YV=@0tĉu~xΝ;K&Oyqqqq@tÌD">b{/!9\#KbDښׯ_mp ''g93g,,,#MtNp'ɢYwqO2Ps0&  t2Qa , ( jkܹr۷nRRVVV>jԨQPJ-˲,YgJo XB(@Nwٽ{[*TlzeeF1lI.)((pƿw ɸ].F0BQ WޜyW x_a8,cn[u=n/n8cYla:C}cy)qF9`y8 .ۃsI"0腲SJUUuֻgZ:iXxYP0gޥK^ر@Wt̙SLIȈfknӚk"8?zhx$Qt# Y߽gw8 yyy]6uڴܬXyDMw b\ys1ʛsFyƈ3 RʸxU"MIML|{598g g=}֝ OpdmOE0B7p|txGf9` V$ۧsAVUȧ3Es 9ȪWFv09i\@|QfhL= Gv8$IƦ(#ݶm[tttVVS>l@ ˲(M>|۷oذ~-m問5a„q'$$!IJ,0lvƘAQdUUlذqMMMQQQyyeeeƍ6mzNNc^m0 ˲]+W\^ `TV$f867A+g%H-o}kNnį ( 2gp[t"ģ(@-0%}}3,zW?;ʯdz /lӠ$Y&_Ug\Dv0 Y^x*xs'79*7U,ZXɯƥ ܴ/Y$Z(h WCy3v.~B˻149ecݫ5Əvv1pA# `B%"s8Α -oH-7oXrD&fDDYA-X$Ȳ[qP$|d;~╨ǍI Oκ9&&f…7m+( Xknn޴i+vU__zǎ7mڴ҂$Zz%J#˲ mSnljZze srr̝;~EEEq11Mmvm=6)ʛ7?LΕEUO54Io?Q}Γ?_\Qc+/<Cm-J)IH[m/"!;[;ħJƻ/a߼u0(ENV7ͼE1^zόs,z{ݶMfP;qs,W>7 n7/Ցs,Hl\b]+xXx{/_729ta!ݵ9w잀l䘶kmheIq 2+/j{evV0jK8DBу{6u_=|0FuWAgn9XnɊ _,!xs!0![Ŏ䔉GAľCq,/,DQ_ğXM{8>cT8(<Nz[+{,*FD{MMÇ׮]r*UUvwM^\\(Et sL4΀B>I=I!$I(UUV\hFϗ8bĈ~S2ţȒiّHD{G !;.. 9B̲g>"`utݍVu?D0ʌ;ǧs~^:9#Gk3ϵ .6: Cv0An]γ! 'ps(LH/n@0q $b0lBr,`-MS wйog^~3Z?6RHwc`Y.zç93&g"PݰñCOD4;~sݟGpƜũsо8@, '._hաkz&~O}Cb;#Ͽ{HwL/*;hIG`wC=j"$c=yqΜU4cqCd_ Ftq5 !_Οaw.y=?9"pqdճߟZ#۳eiܻu]vY p$HYi#B#O1."PӰ&4K󳙈HcxqQeՇ\${O'o~\:4v?",v^j@(sCDSHH3l$HQѪh(0 DUEd*j顰]}"TpS" sDQѲpX]#TY@P8 Xt|[sy5qDSS-6`8AV,X$6HGZBR*+[;1<^$p4B'Z^Up $ `YLJHĴB"ǂh[VWjmer]nFL8Q!pDgPߡfv$Y^togjEEDf(籴pİe_a˾Xa=zW q"Ɋ,lC6"FE"ь~3"I][m3%[O@Lэ %v/wђ4r,^G7.y;㊘ &}1E FlC iVtj;՞)WL4pȰ%'  'GUdehb@#xp, Mc~;ȇ6-wl]7&{T `i$,z?qZDE{`2H(h\Fcfj&G J" *Ǩ2CD G0=uY82V}Qe#F o> TA̴{ zɂH(esγs)M{t$K4Jafoc o^5B>x /Ǎ77>)99..Ϋzl"H{{! NtGDxɲ(r%|hcM!,3k_qĉ ,Y;kAU5..?m @.1DEIEZH=47 J>>L cЎfı#Ɣj#o:k'ծX͍_~r=M79PSG,jwWf# J$`MoQX4@󑊚:%dxnBi;pGĚ*q=yҨDX??Sg$%Ou鈔+kBq++pF10`g^Tcm_XެQS'jW.z̊7ebl T9ڽq{USL# Aбիv! 1c%UmP:!ɊiQ,*پcښv>jlyBxdm(mJ4mhۻ>:h Ȋݱuͺ֠ RtIh֩(B{vK1,bG0 I2LȨnڝ؛6z|y¡{;9~ߖu6"ie#%"[+T2&0nkfˆDh9 ƥǝxsQZDCA=[;7}Ԉ"Qd߽a6M9zd'RSH1cnZz2ai*>^l()>}[;SGL)ϋi9CruV~KWN (+P98ۧmՙB숱cb? 0c/=E"RdâCZA Ŏ(/KXx7cR|X1dv`K2zS'8+Ƣ\koay޺orڵkmDaÆ_{ucƌVmی1۶M41Ѹ+dz%TUܳ{m6oڸcN-Y^n5|ܸ1Ѷ= H$ E58D8 h>t td}gݫkMBsD޾WOҏ~l+Dߠθ UM9sRt$42l:7Vم1;ޮ11^]Pє?8+W5kGVqV#?%ECo1VkXE|x+}cϼP+5Ww..37%-55%)^VGlB2~^_;gXC~}痬o:>^W{_Oycͪ][~dKdρEzg1I~?AݰՕՊOͰ#wF ]6}}ўU~}Ϗz왕5:vӾN-\kkYC!QXcDW=-ܗSD^Gֽʺa8_)wp+AekHǨ9v[ncol@0cG]~IL7UU0фԔX߳_!*{/i  "WU)&+g\@ 7<Fb#;Q____P___P\#<۬yTOz[έ9vۃ[ao0߿s/G6\Q-[6ϙ=kڵ!J)!)_ӦM3fa~? E"4S\ōP?'YB)e966&66uaee//YxxU׬ZW^>};OBow\\ĵVUwyLƐA~Wp$"_{:'Ʀ5ԗ]4DtTO@"⽇w&:Y{—ːef?_X OY!Bʥ/n!gImĿ|l;v.R}Q^I QOlVِ%#Sb-䍚?g+I0n}pmW&z'l>j%iOeQ S./]/しΘ=Z[yjᅾ7 3{xXW:/Yw;N6]F-tڴqEP񣁙moJGߚR,h.yc!r5BV+DTD{s,xꙩ.+n>b?:(mf_/Cԙw?:3z׆Mw=lLavs6?3Q#W}ߟXMaHVps_IkZc̼ebܲCKqpw1PtیI/W.ɻ?_}[׬kᣳZu2~F`K|7?Xk7kMKl *z|:i 3F ]4d?P9'QK 37(HM#&|`^?禯̿JG^#(hBVQး#ef8^,;cvH2/z-M6Wāo=|ف/_=aТ1ܿ,t3KdL_GoܸGiIrMḯ}ymG6ԇ:eۿ@7fe*Oaش- 56%lڸp]+XjGة)Mp\$A,@@Mۗ5px~Z{Sw߫>%djc2-Ӻkkjj4AoS'IQE,ˮ?xjǎ+Wܴia t޼'?^UU'ip$ >srqq/ʛOBF]zwe0N8LbUUuRp[Nu2J "a`?I6]+|kn[ջ4;鷐(Uذqe3$B'XPe~ņƔ!S5$EG1~s#eg܌hE9peH>v5>1I>3 3;Ul;g߻.7'7ݾ,KiIq4_v?LDjTT)@RBjt[4>l'~pofJ1dH>XcHiP$,)lbYm&堅#-Oyd9m+?;ݰ3? zaSf Rcc<57Q6Q-N_Jws͸0ЇEt~-_ؿ~W5[\7t$" rZH480)e`HZxc+:?HŨ'%F(((̨VCQTSmEi sߟ{Sq@ٖW6b6䵏gfX־2n-7_7Fu,"St 9)D tyӆΟ4˶Wa0TLs ӧO)mll=R]]s۶ڵkm  'CXeIsǗl֭+/[~ѣGs&L1d !i뺦iZoWոoʛO#鑠i;VTv1F986'خ6 "C*~᠑~]7[-JBmZオ>2Ʀ.L„ֶ#!-Br 9㔲!, ;`8c 6pQJ;qN1˖~%=?v;r=qn)I4ޓjqۦ6HmtSFRQJ9 `-GrS4xW%6u'Zussk'# 8҆98peН aF9)uA1gq>GO~x?^>1Y/Z'Nq$D)QΜC6%|xۊMڒs fKuPʘ2lfg}?78V!D[Jf$`Y߼X'T6RF85L$~2;M T8@w5Rzﹽ;%3G's0456>> 5yo~c{g3LQJc &T, f˲Mi srLvP :foG7'~}ҝ !t0 Xd[!@AS'#?3ȟor@;qv0ThFwlzzwK:IqP>EB4A=}'˰ 80Fw&yB0)ceIï}@2ztWn` i<=sgC_t@3<(8 ti (^fP q@'v87Y8@#s,uONe3XEVEs:B SLѴ"߲y(OJ3cU*hvCCcccm.\nylllfVUW_=sG|>Wk tKӸ %A@XIm3Ʊ Ȓ(J( H$I Ď,k_ҫ-q ^Ut#߃d6VK)+@D@OZUHGob#5E HZ6o׫tBD0p$$ , $K J$˒ `w鑽$s(9 ,J 29DI$I%@XX߻ڟK Jg %IDQ$Q$Q>Vs܊Y{vL?vgF19:t3/;bdZZG93" H(( ,gck |>G"cUH$I"F$I HZVJϑူ XG-VF\2]扉dK \˟<.격cb "#"Ȓ($ H$fnH1g:-iV"H䌋2޷}'EDI-QR v%${el5ɀq^`(jki YDP[gKH# D@ I J";O+$$ $ܝDīI$Q"JFɘJf]Ǐ/ǿ?zNq8i\aW'6Χ @Ƀeza# U|;Z( X879)zڤq^vg^*Ɉo|GB{ЂD=ڍ5 L8" l^E D+_{;ڛT=wb׋/X[S})Fkܺb1~xKWͽiQL"v,xMHǫ+6lV:oG%#W;}fg7pƱO k CRYr`ؕߞY ƺh9b!A;;kMYDZ*7nn'E⽵V-1uB"zv\;jۻӽ jŸAӦ %m+Vn9ԙb &M.JMIW{e&ssn|cc-أL+LWm&rtGZz$!>ʈ*W,?\Č,԰ޯ9n;r긞; ֮Y^QGeD[K.=FbFbzio%KD̜syEʟ7u˦/JYZDgȓw`Q8*W?A.?uQ 5j=shA@#m] w60c`7-;] kN[;lZv7˃)= m"ocgu2Ɖx\d(c޲!Ɠ R>eLk!9y$K&LUbbb̹3r)N:i8X W}mfI6 M]fQʊ f$%&$DKrVR|tFvNt?|"&?->:!#-%:68x;(--֚V J󯝛.Y9s@ۡpXɛzds$>=5^6v@NZSs3bR̶jԲk揕PX I2oKJI<}DpisrVNt%tpGLvv|\BVZ2eX_-"MSř^wيIˈKHEj訴A%`v>~s/$tx_^V̻[Nh=@}L9:*8mh}`Mc?mTOJ༴pGWJFIEik %'9.!=7[蠦gŤ ̊%G8'Ѻٯ]g0,)Tuh{G{%]ի$f S' Q4j!O8rneoS &U9~+*3=Y k'+9!6#3'Kie_\g2SK+QYDG/:|@͵/%[:EgLCsj E1wiWfjbvAi27qn!eJG9| UM-c!C i{m.JNNIJZ=ʫg$"MKHk/+?>66#3#st˚x؈Ɔ}5Up^YF5 ZPzѰT(=e7陛ʓ(X61X񪊀5!HV8ٌT٫Sz a_|xuoޓJŨigrzz(#Iapmݺu.رcG0̜3w)S 80| _!Yq9r/g2r<|0 7F!Bxκ=>a1G:$wN3NT38)9˜`3_͞J=N093Y;u;y.qN)=Ae'}J) qςw׋s&w&uLC|ΌtG?}aDCz>{):0q#L0䄭 "O=Xw|fyw?F}NNr]=\l'os0Tn)_MS`cLNG\J}/~{wS ![W;qδdN>Nsފ=7>&h^&c0SjG|cmwOa9.^z'O^9'{QM+|}$=lt{pn4AY鯮:p`Æ ˖-x<%%&Nd% :%h(a8}n9W\츙>rD'WN=op]‡_Ci}/z_G~اﻧo\8#{{.!Է5&RwQ:LGF4cxʌ|\>|tOs |Afq)x+×idw?:9B ?uNOws8ɏ^!C~4ԟti?DzfCƅ[;2+t[v[eL!y{9݃9(ftVаRptXxϞ(,;*RҲf͚˖ڽgdd̜9'?A)nٛ9E9|p7g~9`kvq51=//oHAq,?3=9D4[w5ёtщoEQTUXSSz ?r狍---vxccceŋZJӴ9sN:mܸq1>`F8 Ci>-ZoΎkqqqqq(p$6qB4M۽{ 6o\Y#ƏPZR2bҒô,ˢ:zUbǕ7gǕ7.. ; 0 .ud{rAq~/~'+!DQ<,qD[EEł[n딲䤙3gΜ5,111>>`醦iי+o.v\ysv\y\oLg %:1ۤO(sSOS*ZR0 ''s #t `8@=Aݍ8΁s@[86>:I@EQ@0ʝ6n:xPŢaÇ>|ҤKJJJSJ-˲,˵Ҹ+o.v\ysv>^pg${Sm^6{w( uPg1_tꂟX{!a|~ng A:6<$sV< * sfnݎwv'O\$Xe1El0)Ɵ!`ԹHzc9`A } D9(6~΁`DbפXdD ``$ bcR4 U5 ("˒iZHcƍ om.WrRsg̘9hРԔdia PrZ\ysʛ1s.=(F"4C$pΣjod3)ek7Lɴ9v>*_y0InFEYM4M9`0!wv8m?:B{G9>S["pYavODt5鿼! 9quv,bBbU('cdXq8#)ѫWk^z3fOr2=֥U7uu| JDE xi|zY`1^Ɂ`BW"'X=L! BKG^^'3vRJ9R16-;35]?;ګPzgsYQyl?AT?v m؀VCx(|C( ؓ~73B((@0tСÇmڼy:(JVVCƍ7} "Tu4ҸW\츙ι, /GQX_cO.?????/ \󩶶6I{Eyyy`wBeZ?|#Gt~u)9mc#Q>(e^z7uN>J)!@ѣ[l)-+V0s.bkKs8,(,5 ݩp OSj PشyE?怌sE=i3-KC^75-2M@`bFN21G6jP ltKR}Cö/Oe<{hTSt8$Ԅ7m+Vs嗃iy _`v4s1ֶa˖YyhgGGRRo!C IMIf8ai,Ͻ 7(O=1}?`Ozvvip8!xㆍGT+sG iMM3x )!~Bӝ^^zʔ)曁@ 555==c&M s.ŋɒ`"kVV6lܹ48pQ;~V1Ex ]UU=W"ǣ=&&&oڴŋjk&%%~Դ3g,/ B^1 l.,,<!r>E@:I!fgU`a Rs&r%TnCG,]^Dl B0Hu }U ^73# >ۏ78€)1-PuCaI#K4EO&$Y{OhD7jEHMf5sϱHcg5}ɴ(ˆspB1Ƣcb2 šx<=&-? :鳔c46=/1T`9Fx I)1P$&::M3t DAB#dž4G*b[k+/ws"7*.!Ewv`Hz:B*DPK ?~ | \ }'{/SQ=@pW xњ5kV/\FGG:뮝:uj~~ꡔF"ډGZ{.й\T9|ιINN޳g;''\ؾ^d~_^>wˊ|WSDEE%&&:f%ϗsUUmۖey۶m_~ݤpDQS̺?J?11)&}WC9 Ё&GՃZ{>M_Ι,Kxr6h&8{s(3ݢ|^qGreюQw?"g -^mɗL$%%e͚ɲI֯_L|//oytCQ.Sb^B`&IeDt3&:b{Qvf0zwwvm0L2uJ)CPF0$uEr<!ĆC1q1e]5FwUq@8[/ι * KT2<=Us&NqUgZ:#;wyqz ɚ;woȒWU/Crb&ϕ0@aĉ 77h%Y-cDhoiecz+uԶD5Jl@0ڎYF$"žʆy9d̏Lk=ƀXFh0T!׮d::h[re[w"aiq0v︔RjS;)1oBnC c@^+M[[ѣG/[`jee~û.<9;;;))ɫzl"H{Gg ׵Ҹŕ7sNq(eiz#G}䑻'++F(r,6;'WkN*+һg餣pvd'O6 ^8BHwm4zFc6D; ׬^]RR޷o?QSRRn馦+V\qŕqqqg8Փc:/ZZZD `Yճ 4 SēZg@j]Cas|# iD|3Όѳ^c&LRHm tݖUկI0 °_V[cRDɒ0uxFOZeS@zimC cR b%#KsN:Pua|sp8gx|8~J΁`]?(3&rcȎD"#q$؀eQJA >2~1UL?02-[crr CG h"HޠDŽ9j_׵hE79 q@<x?@4* _1a-ZțxG {F :; Bk^msu^:~4'AA$`شvm۶nڴi˖NRRRٰaf5zԤI$'';6+crw\ ϩK....;!zhY}>_KKˋ/, oD4};Y֩1Y_}U]׽^9yd9wvv?D"9J!d/_~͢1:cB0Ǘ_X ӧϸ9EEg{NlL+!In;ce2FYFC[q.J@q΁Sb$c۴GՔuJ)@1MBBHtL$ԣO]`Bې2 M[$O>f0дtQTmG"!AeGm:p@|tJÿU@VZD+ gg]%$d{YfJlA&9D7 ʢ9'D:o}*?p[DXrˀe/O{umm,d"S8Gf=Ĺn2Æ^ƔĜ<>&5q1z۹((.7Ibccs~7L;֔}]LM T"Lճ{U91X<ϳpۭ'{Bs(L?޵s$SA{'Ϻ׀P4޶460IPJcbb*wo3MSEU`#MӴ%K>XdI]]]GGFn?~€rrrǦ4~߮x]qqqqĕ7 !0~_:!<_U,+)9{>axPtWbpqY6pͤ(>03F3E fw_.cb/ܺ靨3!8cAwݳ-"+ Kf*߲ Uh>Hy{{ǢbNJm&b07-(_Sf&5b::h(zs58`=q5utł~>-]替u1رceّHx۶mwZr5@bbRnn.-t|Hz՗9@׋Mu22aɎf&* SJrlPuh1(cttt]رc٩))c߿f֖K&Oz1n?v10$cb5MۙR mB8IŐV(㫛lfw 7vz7b;3pO1fMPY8(3δμiں0L<@8{7@d7'پ{tuuB(~Koni,|JKJ eI2mj躣jzkjVƕ7"}99euܹsmc!$H٧EѶݻw|Q U28/5'7vܽ޻z^xw9r}ꫯ>䓳gϾ?{3ioi,(:O>uo]d֙D%ߍBe=ztu%%%~7^/,*ZÇgg顽iyW/3>c3f|InPcs8N ]$GĢL̎fF'c17oBiy8jĩ_:yVjF)B U5`WE,k[Aô8'G<;-$"jƘ,~m8p %%ilUU޽{V^ -?|!;R߲,{1@ʉvC-aXf2`]f?LP( r(e(Ÿﺋ}œAhbIngn!CafF37^ea/B;1.{=9!DB X{&4n۩;dOQY=TUe9>>|>$I111zܝ ǻoޥsAxw\cFB3iI֮YS]S8wlZQ8cƌ60!K_gM;j$WζXLB i%mVzPz1nE RK{@3M+UKknبiᴴ촴֦eEEK omX7kI5^&۷sd4O)ɣF3fN+XzJ1ь.ш8碨zc9NJH*dER:0Á\" n!',;764y].*Grg&Pƫ;[F }`VV<2FԶS}㻎eY)))'NtmCo2mڴ\HO$IѣG'%'k&MnYVAAAYY{#r\\\nnn.CT%mRGMCxjZI>9kbnqDHCsY8ܛ2, zO}}ҫʽ)?륎R07>Ab(n2l`='G3q+Лq߿gr<9y򔧞zJ7Ly rm|3ȉi]]]}>39Nş~믽6qҤ9`/^K&''%k9UMN1 w2upx銬#wl4)ܼ܄g ?,+h(IRggӥ\~UUvK)uDy2UK>lfG7SV RԽ B(o=\Q>j={„ AT՘ɓ`b[]RݱqêHh/p8GGZ˖Wj4 cA[W>P!&64Yaٵyr3 E0hlaLlJ}]#TYqm[1q\m?Ok$taS˂mH<NF5tPܾ8BK.gUgmv.g<>|7c_y9Km۶s3zÆ#F|4eIL\IY_pfLOz0;54n~ +8#}aS/glo{g'é 1!++DP/B'ucI^>A0tH@BvzN&`1/..nnnr"-ۼr瞽rss p#j\\\\>m\y clڴ3!!o|c@?~|AAA|`uMkhox<YgW_s͗4so1II/!{Ɨݷ&SX*)Aw{vKBa痔jE|EEE!  N'!6o+xUӸiNO`X{vNWdx^( $#FT\94,\80- zK>mQ',HҼ 䚱 c*kMq(g)Ps{&Ƙ ii99&LÚL71bĈ? &|[c hXA/%p+Q +2.2 Kw_:_|'~}s9UUUvcԓt]o~wy}{[{KK˶m۾˵kתW_8p oܸ󕕕榦,MUVVO 5KKK%ID a%p85999V}XK,鈻₾y%I37^;!!^թ]@K=h%kLSONɋO۱}!C ^4 a@Mu r J؃"?@&5>RlC]bArHJC@Q ƨlKR-rfɺoر8pfg 3jRvn׉3 alZB~sƌ]MDs !kY#CЙRPPeV ocǎ;waax=cr o[wd"F˺u55 ߷/lIɆl))8"6JR Ca28`r~~mŗؒX4(~ p7dHo~[twnaG$ 6O7d¢rlВ7 "$M,wH#F17ƹa'G%qvDFHmw: fs:(v($I(6E6~)?{-ͮ%˯2..NӴ_zc>vŢt!$I]zՅ]XR2`{wn'D+Wz꩹{q87xc(ڲeѣ !V3f[p]w 7.Vj¢t9q>E,!dڨgFdg~`IS*ݽl튷p7@#Ψ *qk_ǦrIZZ`vh7 GR3?E?Ѣǎty߾e鄙"X2a-c1Wmu8jj;&d4#;EN)uMcSx Nzy @UP(d7Zq2>/mݺe̘H.,,ZiFI|#ʮ(GQUUiF; v'~28(vuUEcƜ+G II]CYWu.PUDd_xRvFvSXIvVrTc{.;TK1̭#F1NLVpY^tHávҷMojl|/DBs/-٦O>WVV={tR X P(٭rb1rfum=jn"}(;&M.=Jpāc+++" ۴i+.2[gNٖDŤ_~y#F에vp>ﰋ7 qaYn0VSUBmF&'tyf}`nBm,8s5f !lZBbU7~/>cCQQ~iu #J5`Ĕ?ה LJɚa:B3Nf_ү9X^8ݺ:b|MKb0+**8犢,[<..>??ĈU.UVm޼e7 4M׳m}a!M6uu)K3L&B,b)cBhƹ([m0BbP81|^5FA.ȯ޽{ZA4&Ɛ-uh13Lcq>F1bo@2y{ WVɶ_9c)}tԴcn'33 V[{bI(VL`Er}-VY:suF[-#d=VkLà޽x=YoAhhhꫯsʬn謪L)S&''2 8h)cLI˕k׮!TTV0lٲ1cKAC -l-ݼz( 9S爒ir~GaqwS% gL=ZחE04S872¢(9jRS1ŶwK.7P(tcďRhTSUU. :皪FZU}}ݔ)St]Ѝumݺu䨒ɓ&†a4Iո$k~qkYW0B*mÆ_Z nظQԎ_V'Bni}C8coڴuۢ&D@%ađLjbĈq]UěsB Al *IRߍ%.W4+TK_)o)ku!tp:go8g$0h(%!:gSpYG6CYkiT4̨?FN)%Dn0ʍֺ2Θ/-_0ň'&ěsdߝ~8{i3 `=7~g,4)ƈ1ncfy4"nƻwv۱iңmZkMMpNdÑi4Gm}E]Lᣗd}_K? @DFaňLL9މ7GM3l= 93P<~`E!c𫕉 c3 +8cgƨ}r\?1bsbN,@s]׏pqQ;.8^?%c勅0cƈ#Fob8Έmb|Ol ň#FL#F1bĈ# 7 [:5 %S0 ,9"1M1bĈ#F1;XΪHVJvrd¢7qe㒘&F1bĈ#FcgsB0BU [k gl0ŸY^(@L#F1bĈ9[.ҔIͺ?^o%ס]߾ xo}; 0|뵋{EhK 7l/ln tobĈ#F1b8pb 9ooM95khUOS;zg9;X Z$N*XP0Z~v ?[XM8c}7v<1bĈ#Fe&Eк9o__ʈ 0>>!n`ZM# 1cY'aHp0 C] C0⬣tDL&`9zW D{{70ƌo `j#coƸ l[0O 2jss}3 4j5#~S78M bEP"^o;:^ Kߜ?Iw_eq8ńewՁؙ#Lݞ.u{+oK9^pbMK!2F#2 1c# yTmXF(ȲL0ґEQQAmF(HDb].X̍q<1 ]8AD9 @#hlnSsNh?f.[sf9`@ÊO;;ۯ2D9wYwr/x[l'd#2@3/Ƴo1i{~U3.x7s)b%&i >`qWx=@y㉙#ߜQvK#9p[lkjr:,džY_t=9)pxA؞ .tIaBs$ {z9_s"%=?[0c !FvfϜ< 5w8FML(}/sכo>x.P/8 Ow-jT8eOoX7 BHrR'%/w !XQs  sI"ͤGk8"("a}zu7B?Ylu](;0sO~$}eSU' 9ce]uT 1D$ ^oE7<W{8dbШ \ `L$g]8.FN]/_0TO xO8i5Fsi'?x={#@0uY0eY1fBدJW1Gf1Q !a cQBÏLȉc S|UeY.8gok[899 "SӲ9F`XzY` B`,@BB'0&|CB[o=hABėҦS8bWUc;J$897c>9&PA3ܻvi JuHcpxbp1Ɗ477aA 1J0))V?iiY} 6#3 ç o/hxb"h0&f1&IoH >],[ 7=opJu@ӂa2QH(l &|Wpc l alF4E G8g!ɳIa !pL`edqF!ʰ{ёx2cHFPESdoD8 %LHa涍sNDYa&nEBH[[k0^TT* .YcFk~f|G1~H*wڥ榦P(dզ(JbbbccCZZzBb<1`A9g zu1ͻf޺G/<31 F]0g+y5p=n`LВ'\ǾΛu|yfR @AaS&_._ `EU?}B:X&xs,6(:ֶ%K|'<+;;0H$bR<~}1{}os.p}3BݎLÒdj|%1r H' 5)mH &sI{nb\&zBtA[+u%1-q SiUD>&זyyU$1TEOMٿ `0(I/lcM(cHMڏVs:ٸDK2ը5asl̈G}W[[[YQ kkkNgnnjuuNg4i7P|tWGϡ#8Ǣ"]UNcpd#4oӜnG?H6 9E9#F;9ǎ(}60󻇜lT>\^Ƅsnrpuo=K5K%]|€ۈs?]ʩ'_2\;  >.;a.~+2'>gwL#80sG'|(0NEjL9H$buu믿⫯0'No***9kQBaQIwqA0D0 ~' $&F 75uQYQL<ƅtnoմi#ů0g>"ǒi!85?᷅6{0h45 lpGd敳)7cAD$I঩扱"F5~mo 5~L8DI*ʲOqDu* zPsD( i !i; vU+nb/hvBG"h4J)UUUU;v:tPav5Mcr8GDe@D mbCo ZWq@bj' W9]oQkDQ Rf[Ֆ1β0?2A䢇/}Ѭ@ϞyƯ4tn#N5jٟ?_O"D7i 0L TJ.h9cch88!)eI缬?xs짣Rz8c!1{.֑T!&K,/>|ii7xcII .\sϾnN>|$IGuD$|oShO T{W-wՎz"iڶnkf҄gC 99dEKW/߲]t8d$gFy9pbrQk6cl`c  5j~E[C!9s))Ls5ۛd;oijj /nj.L"ʁ5ڞN! SāP2+ ΩyEVH_Z$H||}9yd{Cp::}lW&(n q_|JCVmmZ0J䯋vl'ek>}ӝ$5AlKK'fߒ3³GZOfm~qB!҉$I$飏>;wnqQ ㈙39G# nmӁjLsrT9"h^~/ ӰbBҕ K`k'?.BsssEE,IҕW^N)5)mh C)cȐ!ŋ-Zr%clߞ=u]-@DQmܿv> jUIc<ʵ++kI$ϲ# y: {pDw㌶zdI7 b}K.jm F9|)I nM$ɺ=0.̾IQ71%5rYI>`%lɶ {EVx/ Ӯ%`")+}ܟXzkMUSn%edDx$&30ƑHOԩSg}pBM,?Q}>ߧ~o׿:th$-3ծ#Ib Üdnp]pwƦuJ 5;g  cQWˇvsE5mxw^i=~)yRD( 3JYw G{\~,10mEN3jrq@An:,S<`"C\- HSn}dU !z"$:^I6fp!2~9DiC}w{hOϜQ+vhiE)\)B!U`_X4?Q{U{zѫ}uQ ń`PM38(q$pA5^g&fQ)']<<'A5SaC!5Cza{<-(8kϩ`L!7IVhxdn\%L &*vIj9"MS4vي" u5j0UPUuIVdZT7:;cAE#nnr8`q]S:6qhA] )%W0#6Sc6 : #Pu\8b|D 6/'86@i0’M!̈j:""MC!{0HRրD$i5!KzYK8EDD3uFdrIJ]L " 0DJb4MnuLZ.=ϑM7XR{7( \v`' Rۨ9gn2Z("FS!I&3SW5 g9UUkES"TKrrS n8ZweQ ͖f(x7fn +a$\WUDt(ZߝWW^uuu$niiK222x3f5*B K0ٳgWTV677ލ1.ؼlo9$d)3/`w(@03fpjeq$(HTú9GjTcR#Ya,P p(Ial6Y,U A-4@9IG[QFn[U1~ L缛!ܕѩY?]>s8TFc9%gZ M;o11t'Nҫc߰aCzzX.$f[}}MpKV5,9ǢM0*J7T;mЀ\DH5(=PNY48;Nio'## 7oYGCLc.JF[S!y +=`D;b׽#ƞ߾7`섂[T%_Ơ Ꚇ@5Ց=~;[̼ʩp)'zϙ\2iɁ3[_/{ΨUE9 qc93u&:em֕m(xpW`Lm񰳵Iraļm{G4ɗ50TX`Һ`0>*%KZ[MwJ$#fDZ_M.u_BDmU[*#;(?QVM$Vk$8'e!Ng\~EÚAYPqa8 {M#b{|CEyv Pˎih熍Ƨzkִj)yr<4^-Y qY6L ʐ fb`D=)I\ 7"ZʷV6œU6׵ޔT/"c-e ?C4u$ -{DOR~Nܷ]AՂqZ.kUMj5Pk2Rr箠PHy(,(H!(  ' M7(7U`" F-m')#739Zoo]SSx ڱ7k̠7F) x7Tަ4ҟ:86cJi `0ص1)sFdRx.Ԉn9/k313/ͣE5,)8):2X9OJhoڳ"" Ǣ Da 'ySU <>ҺgsϽNT;xPR_% qę$}΄H[kTlˍ> 0Ɨ\r /4{l c+cLQqc~GM64q&֭-*Ԉ.Sƈ(#}A͙`CQ̙oGYd{a L'6/mPU)Q5PjxYW9E gKk %8ڋ+g1fB>쳭[|-j$rcޓ"^|]H>,C$}@4RFHhTysB+W666HTZZZQQQ[[}UUU8p`Ϟ=uuu߾}I'M#s->ҸoOs)IJd 2),Jfg/,SeZ)cx-J8dtO1=#hko9 G&H݋q}̓FzlKW'۵u ӆ; 7>[Y&>|uEUR}%4$KY"b^|™pDur=F_rOO``&^|:/~!3 2*?[=_'2f$!᳷oN5T8"]pѪQw_]0بZ䓯)]kyYy?_ n\K+`ĨJ/'q=Iuqk&MI5WWvEkoRƌJ ԛ ~j=aMMvC#Fd~zisYiUXi߶glxK5h %@O6Ή$7\U^2~r궮ޯg& Y'^i~:ؑĿ=p} .xuÊp5ڸM-54uo+K7urư G7~FJwLukՅ"н?482Jd򣵵(EjY:1{7ZuؓPݑ^,_]26V.`& O2'L!u<` }j>ږzլ׻+R7kR(H5-8)I͗6=eBkvx hmx]щo$Z*wC :8H50H$h(/>cFnn>O?ݵkȑ#u]eaLl6eΝ&,wϘZw}їXFnv[2 H޴u/I4,Um!LZ,[{ÆƉ}lj+>Їږ}y@ek7̒Y%9( !n""?$ i e›_fB5;,ZiC{p&''[ۛopOuVt(C)sQ@'^㗘aP'L;WX1wܦ7|$33s׮]w2dHaaݻo~wh4{ GߴBnʈoueO+`p5,\g L=Vu}=>4uz lx%o_9?kN)޲Hܫ%`v!7?7d72o S&8phq?<ON唩K؎%md7Lyq9|u_-Kʟ;ckX?G{%gC"_47'jS͏UI"Y֋obb$5^W_ͧFf?kׇ $6΢-Ue;_9|@VVPbgʽ{naZV}Aؽ>"2 e9W"-dHo6%ԙef8,6qa~ײ}5/Z_"hd-i3Ǧg'R ='}FA'M`ӲgYuG<~8Umf=m_~7:dVfY0nVJ!=E~$BHkk6߿.Ȩڷ;쮌#p Ψ&8B iGɌ=m?p'kwO|2/\U?Va%J\7wj׿_M桩>VR0j\3iHǶq^35gj?㵧M,u)a!DhDݸpC/νq&5z_/53#_Ý=hЦ9+mKvE\ΰ@xT!3FlX*+ f]zٹ=/}UzVr--5QSp|ιs^?_0$V.Y;YXL+57#N5hg0Mh o[&"g_t f{kdOa!Հ:\tƅaQF}0@4AѨ(HӸce7y}Sŧvcu'.'A.)J^?C v%NDM5zHAr38>P!\%(k!)rᔌj̕2j@KC LHKnug 5Gec<8bț/<{tŧd{+";3fNp;g{?mokho8iD)ܾ>RX[~ֶVILw;D]ii;wsZZMLKs&%ױ1)Tug(73Ofkamcu?9*G#?9#g+n(""BMh?b)\dĻddX(>G\JVF n?uNB-a x}{|bS )P5L.' K.7փn3EڂQZnG o7 Yj:b|mt;9@ -|nSb5Y //sn⋚S3[47MpUJF?|wuc"Jӯ ֮OrYs@K$/Ia`R fj2s6BFNBD="a0] Gǹ9$t}0KΰBLOO(Cd<_wOG>.]VyUJā۰25%hp4$iСhtO?qch]~Ŭ,N81WbԸk?ܩJW _tfDK9g:ބ8䤴,Qt*[CNpOkW& z[msq8c9ęDuvHM#ˌ8-B1sD!yVol:`dپ*=M6BHu0 (}JiGH.97њ|8cQ5I8 RvdkxvvzdYN^͘kqi;$O6 cVv( vO4ȱ ]>1X&坵9Ksc9swXnGh3&8):kbX* ?,xeWKjm%Dx&`lv7HQDj* ȶ`(sUܙgQ0)A`^p  hQSו{48CL+wkovʊ@Cv}5ym~/9Aۣe&1*>-/_sP)#MUm{}Όvw8!!E͠^M`27?; n8˧*CaQStţaRFM0iPP5 1tM6m/oGڙa4Ƣw-{kұHVE8@6z!ڶpݭnO7zЙ41zBZ=:RqF&I(&A5H;`+[;)ig0MƩi2(Iv3l5HmcsxDGXh4%P9g]y}jymhk50&8ۉ޸[. 뗄8EU kx#u#/E@O Wfâ(_i148g8AC95( 2äa9 f0L2FM`e@e2A@L7kլDnjz#W|=#uWxɬ(AĨf6n^2_瞪ʲ׺/#SsS<;?I,]0 V+0g4M $m 8&&8PFę~rq=<+1 :f[YMsQ` Da0ƩiR f W57{>}$Ҵ~;z/E2Bck׮8p`\\\}}} HII G#`pĞ97U{ԱMmfOM#jjC2Bm pk * daA[ V9FMRL4Mj".uj;#]0F` a9Gh0ol +F8+/rʉץ/|ӤV<Ż=t{IB8p@LV2щ/857^y}n[[p6cF$w%vuEs Jn^y"/@.HG;* 7!.0^nyONhF="a; MN$Lk[7N0u-  ŧʹ $Q2(4ނIFc#,Ƒ$_ uiw^K/0nHBdA>+^Zӆ:U݌5BA!LƘE)WQ߽joCr^xsƟQ5]F š3/{ wg~t:p$S8pLu)!C'nٲEʒl =K=Qmp;ƈ 1Q*,"`(OˋKo:c0lP KV %[=Ν b0&cB0UVQOFm'K֍b[P S Gt(In݂N1ҋ&-ȉ pϖgCKTd!j¶I#hDym'j۲Di9)zo(0cԒCBxƢ|c͂UA"1ѡB1&M;[r}dzg#>#ñ捽&-C %[eoտ~ {_^ʄT9OY׮@VP uuu$s9h8Ò]|ѩVUśi>'}#'Kf<ťinr#~Wn&ajBM$ !n"Bu@:cB5V+AdYK dyz[.u8Q=i0zp~JOC";څ0Fvb@4u<:駟6 +™ IHp8{)H ;65iFjSnOZˑ|/V^S !#``uWeO)tnN{fbu `Dt.+2FTk<[ɫA4)+-|ˈ8U+bǔRXXXt}VW`p3y4t(͎(ܞW9.ɲe" (rd7EQ@z 8pQYˊ*P Iz8c6MA!tȺ(1!^#Iy≢gaEoæ9uL#U,YpfR)wQfsjr]CG!μy1J9nR#Q @UzsQʭMf%&H/yuYf &DD0 ^p֘e^rכn^0o'ZrѼi7wsS9f+2':s%gLn^{rfa^]3yŷ_TFn6G2ӹTm ̋x]LtsMI$TS>`9#%Gn>쨧bD")%sϝX9ot>8t{~3Zst#0ߞC' rJDΏ̚Ϙbmr>quOŧ1eRyQ€s.h/妻~rLO.xiCz׍GiF5.7W= _46's-MvM$XE90G}?1{hYS$Fm-֖M[J줳ND1-;/<}ZѸqcW`tH蛸S3`jh8Ҽg!k׮&Xdk0ԶcbbHXV?$4FLx{{[=BPm-~iNODfǷ6䌛53K?;_N/Qw-|YqDB큶V-AZ[[]mA{m`rKN{8\3uhZ9k yǻ#\9FW1fxzsD RS:l"`ѪKO6f箝~b`Yшrmkj 4˭ω5&s[Pl755W:ؠkm lۼ#J! xڂ&[Z[(3RO7q#f$8mm- ш$xϝ/?zɣ`3Olmimimivw~ 2H(˺A/o=_4UU/$}K,YfMeegxLSp{,Ϝ1Hxe 44eŧlx:e0 4Cic]4^~n< 獙Z8INs7N[ZUB--m0v݉Voʦ`N[~ INOͧ4G1 }-s _}DV_QU}`w뛔ic ,tG@*0p$ H(_@y+I3t;WuS3* ](kKv{zV-\ W(۽m:uܓm&UFfmMb\֨޺}灺isGf: XC3`,Fkv[EyՌsvno +wI[ș{qJXuw'1=Qh_u#>;;|ʀBorjR7舂Dմ 7a@ KKe;TT4$uڔ"3u6Epťg&7oIDeggɁu,8IIqCe*[4h"ܹ% 9mvT=^2eje7(.&KqN[rNV|w|IL+"s@"2l۰{\L)zöT!$˖+"Sܸ[C2jƭeCP yѪ-{isg{K)٣-u5MĜAF &%{6Yvޯ<{t[uD%Z˖E{2RmZ69a(m)nWIBmEU\GM}׮]{+g/`gN^yHXF-'4c(s>|UEQ\hQ(JKKON9XUɞDg+jjQO%fCsڪkY1ceWn߶ K6g|j^ٹy[l#53:rx W5`ofq}#g+ige$$$xq>bON{_ƠDÓ苏Um-- ILMҋ LWVJQinhwL8lCC nhh'%%]vmѨDF#Q5~EѨFGۣk~4o5=̷I9eY[fZYׯ۸<^G2Owkm3$T عu;?ڲRA^rʝؓo},۶nM<5-fhFzƘ6ؾz Js!=,%K4 P8aujl p y{ hM0BּlИ3v>uuuSLy'O?>9+< ~ߛ6  bIiDQrARlL3t] GXVl,pJuM q0[QU:6p] $&$]!F#rIz$Rb"54U3(j|fWD̨kV=," 4M? @dIpgwN C7L$H Q=lDUʑl+"a2NDnS0PC74MQTpEyZ~0S .em2ivY@qTr& ըj0m9M95uCudS$`siZ G";}#Vdg~yϔI L~⦙i3RL_"d0.4l1coF?xss3tuuuk֬1Msɒ%+W6ΛwZoy9h=술ԃ*@0!SWjrV=p-;\;4 pWZuJNPg[]SoFcP4;)j5­ݲ ~MuT "ޘV iC)w+BZXS);nz{jUCfBZ@r@q$:M=ߓ~<{$m(W2朂E w ڃ%BV;V#L=6BY#Ӳn]~mh;qʓuCڶeCbf.ɘiZ֥sZ‘FCΉpDRct>RѢ}`FAι_jl]0#һAvU㜉RP<}٧$$$wy1YŞoymԴ\X4zlpXp(yGCCEjD+gF8u6VY V3FՈ'6o=,99`JS3:G)Oԣ5=F#H;a a0Öwڽ{~WLjh!]=xp=Vy*dȷn$rY;Qs5l۶z ,iDw.B`ZТʻ %E:F]\|kp4ҹЮ1F\]a=ozYٺ555gq,˪ {oi8=rIMB,[l\nwJje!fi:CjBp@뜘}Qb$>*BX],h8Uu P{u5m; kSn۶-d1qd߇u? ^u;|)/]YZTug>i~0[>xyjP\B []N@ȧ]{]^>ف|+"h/rkU~nvmX[ng!mՇ1U߮Fzsthr9l-܆aXcr𵶶^oNHHQab'Mwx"CjtuwD'NH8\N;$!E^@IwMqFwo_sI AC6ZPܨAc3L8c>=r?}XJ7s;Ic'ǧ#d-VKW8RFlVzAln(]_vI-0\ j E'\[Ց7M󒒒p8,IRs:C8UUB`p5ٹSǞz9DiϞ5U@0!1a޼yɢ(h`pŊ˗/ONJr\#FB=j, `Qq\7'@m1QܜZb7:~%'Y2BZi OCY{#T,ӨdՇ7t*J??sbqΕ'9n1V?h&Cnt|욓v˦< \L 4pxCua]ʿ^)Uӓ& |oNY^I-6wғFώ~qSQ"`~X;#՘m;\~zZœYtk_R~U97٠\<b֛cUWW[vʔ){_k sjƍ矩ia!Ll3gQ2xiCVvvnN֔9geza8m>A'g.m]ﯖ/`xsYG.OُpDܼ{Ki[mBb[^9 -979}_ѻ1Eg1f~WC!dzRڈN{Wo߆Rq}!dF~A&+,,t:M6UWWjx k^K66Mb t+wLIFaS4ˢǓ샆0b.z.:@sMXt ^ӬXm?i` 8x&N-_1u sO] ?]ecm5PptF]y͐s_|CsYc\#[߽[mR exwL, ``ml+ໆ K&Qr(:vz 椑$:,-q롴ƚuwRKDQ9V X*Cs8A09!g X&MLx)yJ ܙ(GBXׂ6o)&pcm:2F+tFg0B'0 vGMMu(طwor9 >_\^At&ǏfcX 3w wFvZ喸( 6#l(3=&m pΡ1ІS]mSਓ'@TL$dcF#Lp1] O?W&bGĠ '١߾pdi;K_mmYd4γZg#} )gZ7m8wi_/~7` )2o^|K{O٭׍z·k6=_^zqI#. & ~XhL8y}ꮸ\ggO1wPvvޢ5E|Wɞu0uSfL)s~~ @WcL,19$14!mm |頋q`UF߸iSbWmB~ ",?7!FEQ!H4"R%K{=XOG$'wǤ'tjWܤq՘30_MrLaܯ7Ew?|N8c}0v[zZ%V}1&I!c~0}vNT8FXDflĺp :N߅!d ;ňQ*eVm@M(9e̪Kll)}CMΎSV]%=si`""`;鼾#CFq!E;~#i5q)c:k7ěaEʲ#FAQ*3b|G[~t~[8c9^LsB?ACaSN)! pK3֑֬ /m~^/bʘ9 0-----D ދ;s",֟RxYrN>`ehj`œ7xdqt1toHe&mmm&$ ~RS ݂1D클Ԕs:d0!+ZoQɏ(?B1Y%/FADI˲?0dLjGDQ 1J(2$^(2@>#m &(#FcK}>:#|8gjٿ_qơ?<8+c|Vl9ƈX۹e~děo=7L u$LqsG1N<=ޙM`ieMƜ8-٥;*dq"bjbZcs;Ib$)+|\/@o ' M3y5=xs,cA7 xBLJODm`%djqqG1Nd8Iqk 2ӈD"JAQ&:rvA,>RqNSF, MW~A((9i|>kO(7s6M5hTcؽꫯ=2%PqK8Gp  顠`^j#Ιr֘P.#F=osA4CNS@jHB_-X}D- Z׭QݦʲD[faq~Foʥ#(Fc v纭u1!@Mŗ9rԐDRcJ/}c!j~96u͍7}evV{@'] B\۵ݵAHbCMU}P1r W{?>aDr/\pƈla@u&E35oZu%Ofw83O4"$bjnQ+8֣9G|p{Ϥ J Ԫ'^È{gUMpOdΰh ZbOqNα`Uor烯I> \7sNbq?$@@7qf {Hns؄5nnF#gO%JpD$4IDAT6r'E~t ,I㶥Vc"@9"sGXϜ5(+Ǧ\ǔ9bk "bž&AVڎdNxÏR:{!\8sd1f")=Db _ r X8qHɕokr~(`4$+wk[8np㊬Z'9n JIn]/#}X2߻5,B`(hEmɝwBLYqť8x.:6 Cg L!}eTdBaξ\f=k*@lpΰ;f°{SOJszd7NFAVZ۴蘒qC3A<sV{wFw=,KcCѣbgL[v׳s9e``PT'g ΙUj*_0|:t_1cE/xX wz?&L5%I 3Ӡt<ɎG a> %-|@)@L#1%L:6pNܺq o%-9I7 3Q05 #Ŧ(0(M&6Q>E,]IdY% +(Hhֿ_43}RFM2f\fϭ8D0wl}]rٵgikٲyKQU]ei|u𐲼˷'N}i#fΏwJk|ԤѾ a3xSXkEk:4jy+?]s͓;w5ښk=9#\1ڪ|" ھb>o>O<ġf]E`g8'sFV7KXÆ/~i=o1_= 9=°~QthQ넶5w/j\F@REˁ}uj{U/\6aD¾ {5uk֗uX@ p`ۖ﬋鷷 O 7k=_x~XPgќ52=7;6a=5pε;2`ލg6}XBsCڥ5:N)Xj]^yi|i.4߰tKiZ-O.fh[)Fq-B yQMjlvսgص}s_o; Cb[ eA8)v%"yׅ闌NE{նt ^{/c]M37? Q_[6<汱3_B b#AI@S5WfOaй_q+wg SQo8%#5˗-n'5 HۺKJQEٽ9+&* M5UVls&uMl)L1FC!Qbq"Z;֖>7?yVDm/ _M,+ػ}k <Bl-={@"q:}}3ݪ&Yow%;t{7M4"?{257_]-ssoNᚫ~ηz͓T"QGLVVkRJt% Wr˘y/;~a9Wmh3hȐ$ l_S>l3. @B{ʪxZi(h'~gإ]8<ӧj*aƏι޿>[d~OַK͟Ҍ.8j qSvkƋË/yk>y5ֈ& ;igXվ謔0J'g9e&=T%sg=>ӴABH:WT2G3-Qv3V ]wҢ^cnڥ(\N4녧7g|ӵ1uI*. V|=W%s?zo粛nWg^o&n6_ŕ&cHe܏f-^WkDv7N>V Ȧ=?bG_~-K#/#X&,"0j.YG{uA {k08 5tܰfT-~_zU\{@aߟ|.+IMr<s{?"H0qL>?sUF ۷iUU gZjr櫭ݧ_zU z"Ë־Q\{Hۯ}r;hS鎏tm^;c ߪНϟo|pu/9p-מW|YAq8yKORIV'q I!J_3+Ko+?{f]:bTZf̘~?zʼnd0{キ62'G{vo?+}G'ZV] NUQDc'84-j:'_xE#.<)}D7|l=f9}-Zڨ_]>37;̣P$kNvڠ茁c 镒=gTVM2BUùˆ gUeyfYZ[QE1"*LI MC<{G >$ޠ ;4Qh; [/[YML~܈h($N1sSzN:8Ғk_nƽ>2@D,PbW IANK yʔuv %eAmț!B"E%E=Xmm~թ4v+r1fڃ⃮C#̀ !dwb]*(Zj >}8_ޙ nnJCbNj遠@J!yɣC[֯^W\ժ)P~c날inun$@@~K`-kBAu]7Qlqq^woXvnGfH>9}O9uE<>^u{@J/uP"LӢHQFKع@-GMԞ4ٙ=CS3lhnn^tFDʸJ~] ð i' l_n݅A* )@,0tC7LBJא #{c P]\ʬ 8ٽ#4{"㤵j_3DБPУ3DՕ7}$ȠG]vÆň+Oo9)ݛ2)+vG2s6Sʨ;n+a*.[!"fo))mDhMwݜX/2Aᎉm۸naT7L)QXvZ%YZJA@R"հ񣗟}CUrZFRBDuatDKp$NH0neHl[n2cѻ3>}UӐRJ$ -gMMA;tXjkscCLUeP9J q{Z+J"RrUSCd$ ƋsBe}]/umXlC4a)gRJ=zJ̀KZ8YyQa(,KTuw SH: )%k>}aYia#S&tD H@}^}Ť3=SMܴzg+W04ihtztȠ͍4&Po{'!R)A Sx )S# %fcb7\Nڴc~,PCN=5iɌf pbO?= zEnk?}zcqfek"/~|_lkW|5yL0-uZSWXfX)p( ͩ2;Ts8( TZWԮ[A/H n7OH׬njфR :{Ŕ*BDTddDDTlWeo\>8z[[n1F|kk.>7aˏtOٶ5aWK_vݵ玎s2Cоϟ~wvٰ\57EP&:}Z~31\vg(Q ;?٧>3cฉuۓݛ4pj : A9p*( U1g[| Hjou8Aө$áh$Pá2ƝâLqhU43p0J9Wj/X܇%+wO#¸ ͌kI)ȨFyޠ0k+ Z4/o[i.l ?Rg_usoԲ=/{g3ksWع%\rPԦfoP7>_兿B &x|䁏חȨ(W40.͠}.f#vok .ƐCa@TdLU5K͎)sӯՕgfƸLqps{l׸{C gv%D;X(." vѵJ}j{LByȹS%)͚fPVϝޢ )C{ʶ%`QC2ll~(?|g0@Td0N_{h|f"%|E^;ݟΚiOH'Ц%_QPJ;5)gPnekـ[o0E5 52alZ0ke~ɹhmnY Y hΪJH6o,b 7廳zL5<15%ʭHi{YL::!`Vt3NTcˎݻvwpߞ&Ȇ5V-SZ ~}rcZ\vOR3jʟ={}~!5V.ZP3$FťZy݁K3Ho>\6,""%5ͣDTtKΟ6 av8ɡADtRJUYuY "3)쁃yٺ?W 3l!9y+>] 1}氦}<{[QsƠ9μf.ؤ-pi}WܦDԴ>==|G}zV6,pjDڴdV K'z碏?^K K1,۬5Yj 8asVy: vl^lي{HB(~2cfўMK d~ϭW;,pDŽO?YDԬլiQѽśf/XYbr )I=Kؼ|UZa )q)9ds7 ڻORpik-Q$FMM[[{!(MtĞ2ib:ߴq[^{ۺ}W81j>d{ѧ߀^)|sg,8|XZqfRjbwQspҍߞNw6wmN3|4oua額kW/Zbg7.%5:2~՟.XY\=w pUxx̏V,;w(Nɛ7lQQ]{ѷ_{V41+ZhEifn_+>)([20xn4iˆ9a u%>>.!ġi'l;Z(mkoojj0LP "XW]#ŕBzoQbr0i45ԵI|RJjui5 5<99C2[mm ő#hJB(WH[c}׈HL'\s9z_Hʢb<̨k;6&JeDm<,*.CPa`׵Ǥ%⢶%@N K AA9imjJjho phnH7cPILbbn7瑧?“=\4הGT$[*j,dIqa,[54$)Qq.Di%{*?u@ED757 !L$f(J戋UBِZ\RbdQX M"8ѱQXU7JI-JDBR$owt7olh@iDL|87d<,66>K`lkIOt\T0 0OLBr,[?^_U) r|9'KH !h57-BP@wTZJ"AS*[$>)Q@䚦1]j qTo J(H:Z_.{xx^ΠMu~ dU >wTlLt*SX UTFWdrR voscK; U=Qjk]CaD$;DS]}&o]cE ^âD;_l B5g|ri}E;./0cү|h寫k2+))Z)жR ҚdVh! 74 Ixt|J.RSYՙJJMREP0D>Xڄ#%%A4JLX J Jd|['p֢ׄrλ F{mN{|{C @!bOWE @(i$2EU9HaJDh uQU+ g2 Q BJ X!**@iZPeX)J"i \2L )%*#RMNѲQ; (.F;c+n$}:u;xzsޠ7JTN-c/2s @PZTv9~ʓ7@0@@ Ӵ:V2* % SH¸p0LBS8'-$STNMӔT%eP-ðPQDU 2L3z"$PBP LQ%4̎iCJ+?YTugŜoc3)ov@KK *@D*`F( Cij@iHA8-II\AԶ=w̛w\L}p8TNeDJ"R i ۷9>qoQHd)J2LR-Qqx24Mw *B%f|kv+/NvhSwW! jm'_L ,SȐpUUEnPV\GQo4 CQ6W9A\Q;ޜe=7(`0 v"Ji&!iĔR3PJe+ԐveQϲ:޶"c!A wu(MK|uG(e[9~bG(jCf,Z[rΤ^٬r7у8 ]{A)Ν*:iܖ&_v/iAsmLKPJA CYD7v_<Bzt=ص?nqB7<@vzHhl[9wY`M p!ڈ>S'э.T^3 7@0)$E k~9,)؉}X؈̠eƺބ](@a1oTBQ4 JIx`g (2ia#n{Bv LCt\n,q]:/7i갱soϽ%torߨqȕ>O&9fyQWS^eͭM uE ~ } @J |^!(%w/γ=ˮܛnmL?>~տz* ljjnW<`R\)=~yG6GX 2@ 0Ǜ$͜|^2{'='n@0@= `xjf$/Ǿ'#{] PJ oQ|mP8:c4oRJ_D?bo ġ0ZuI4eOb!H('ϡ!7)ecm?@ @Oͱۖ;ݛoGhR O -2-!E0,a?j6?N9JiB`0إcsR4+|a7B:)E' Ox;gQ:4ФvILo B(b?'{ H)GTd$"#:66666666?SB\uM۽D ?5]! 6|{N+I;ݛ1_:RJ)U2qN@ ecccc  2#:~r@Cח~@ J)dGVrb@j+}%R =Dx@ᥝW/X'|Rcn` 9yOÀMEQ4MS%CDQ@KM_rh|^mlllllN$1hUk_(cPṂsQ¸* P)SMS4S*1[X@) {}ǫjÂ@8WEQ8>(STUUUUx>Mw."2UE9a "EUC{O1 u#Ra11JơGsN)˖-;w.c,!!![ 9+=DeS{XYH(cO`Zu[` aiMK!,SX0t7LKLKMqU!zSʥW9\NRBڼOJkLGRR*2+,CPڣGLQLo傏?X m!eCy[*0R"0Υje+D'~Z ڃeeC2M@ e,CIRrEi+kccccc?qJ\ST~)Nƒn}с&E㈒* HOO |hƥF sPws,Ys8U>7åSy 9XBP"Sx۾ջ 6~s;Aݿj-wPb@B&ϼ8(gTŮ'o8V,ќ;ڕ ?_6JL{񑫢eI WfwyˣH!z.NA,{οTŘ~}ȥzhZHםw\0qxumTF@Q9Д#/x&}3z[ElA۽ bh29gyfMMMMM "qqqq{ !@DCJ;+Wl/trMz㇣F ͻwnB !)c "CӞ'VK>Ji ؜HPRDٚ IxU HH{>p(2'ޗ2&.;WzdֲuI}l~샫 G;%*:sǿpMRPfAb i3\Twli9T xMu?>m`Z ,;@ +e?=ɮeʊ.|{/~WN0WYKƤPg_;g{\J pR3ʫ5Ӣh)2yOECW&F }'RctgQ$,gei j=fM{I#S,KxTnq۝}w&{Բ99ݛ":999RJƘiÇ뮻>Ӷ6T<-abf74޹kwO✖Z1o{K]~a`Li +6jjj9G~6ܿ1{.VΞ~wq;O8NmZ؜X$"V|~t0>@Kء6I9oS"<H9ο#eĕOr2.4I5\8gY߻zngH͎%RXOha$P"^eo5A`u9,ږu͂lQ^)R>S4 ̝pVշzݾ{Ռs @trV;F@+|۹ txg紻^-`g=oI^z(.{n>?+Nʱ9ayڈgͫJKBAb#>%4?ﳝ[3ZiY?@Jy5w? n¹SfMt[Y6(%¿+#0(HiY"&׸a IN?XᇓЙui͛ό-kV-Bimބ̑C#&&yMe~&CWtaul @HNѬ'3Hu>M<|_#4M o޳dsY~!]":GB~?P(]s%0 Ӵ[{ hI;Xvo~O<>c=&k7lذe˖9sܛ_(Ƃ })դcr oMQAYu1eW_P^SwE.|phGy͗g#Qy@ZR8a,6gbZ* ܰqsϙi A}mllllNPHS7n\y󍟿(@8K жeS.Jpe" !0Smp$E\~woؘeJSb]@9z+-_VU|ZR"A F !l0˲M+O]7:v\qoIUnXUNnɀ$]zoFF{cqimM JMDI36 p!edz[-ʑ+W2oILMtBGk;\T/yo)M0% 4nZHpɊm~/BNKxxxllȑ#SRRƏ6|I&EGG{5@ ^Kp(0-!{3_yO^~6aò%Pw;]~Jɯ'`ygь+2,#?y iz'F)H!@Qy۟u=[( -x\37H6I={t5@H=)Ơt*_b,'I,"^q8Wݮ˶}ksy}q0 y+hʹ_fϊFWyϯ-+ wUF}m-"Xhm>'qImS<[(2YG~5.),PAiCoyM> cP=ZQT ]o|EzXy‰:1)]띫X\sEeZ!4/֦魬l)*(Ƙ( &@t'VO29_^^u>Օ]VRe?Eڱ%Xލ?nNAk?|:i!Q DQTUQ,*&1.#1BD ^5~+InPwsϻCQDBϙ2",֜Uu~/I={@), La Ɏ*AD+ç=2*+| ^\׀X38/.Zrh24M~q}K{_/7dpn)Ξ==ƤZ9w-=" ϸK/hN9!jSMmfT22.j6<@=$!P"WyS h@HQ7SyOχ8"B6~_?I@ƗE]}Ljr GgOWBBͦVϨ/= BcΓX}aGr٥no>p?g\1OI"lo8s2lDz\ IT{YU>~Az7]؅PB f.d9+2@D$dFSP,KH͈tC{CSuEm͐7ZI:$cToܷۤzdǦBάڶvߴꝕs$s' }RYRu Z%%Uk\?OR {TaGe'fffqq bԤ3' i"4}o>7F\i>yp?[&P"+4?` =`> JAT +7?wh)p&'E)Ĝ=k.z '{6JM#RQYI "r틉u:\BHDDu|=_ޘ(Jcc;3St]w:a(R]]rj!DmR:^㈢Y f uƹI˒BY( @8gP !P4P I:wҲ$J66666?c(Vԧއ&X@1ڛM t6 ٫#T 0" a!PF !TZ?j K !PzLygls0J/-7$Q1L(e 1-M^, BG9j?lMF:T0JRq4BΡuw\_KR--xKawRæޜ7zO) =!u6;>{(;sIUС.B;A:!9b;ePB# J 1FoRJfQ(c>I?DB Q x2VN;98' vaeQ"Rv:OeZc//"PJ D)C_sTc'2D!Gx=d7'%v"T|I5uG(] C:j69}[؜PRXLXK%]}`hذ9v7"dNHa!6V=Ci cRR=nRKE(RrlGu8R?B۽ bgc;666666ǃv.ċ9чNlA0=N`7?G90h366666666A)~qa7 2R;g I|k!iu0̣D5ԇ{UUEЕSv d{~6_COPKܑ|l[ѲeYG7t8c(Kκ ۛPEUzPG@5-K{Yɝ''@ qFЀ"I7np\*TN+8ɰݛL;a@P t*""4aoԜC6\O6s866666'({H<53:m.$IJہj4J@Bvh6 D2:d\OKLR:RHRvlX J ҄41VX et[TC 1.=6|2a7ߕ267RP̖{kZLQ{D;MCǯmC)=zsc@GdveD`5VrBwqR"7cģ 7(Mr LQÜ F ZvWhܱhY;$Oj0Q>_t;uLՠJH)UGrgNpk J/{eIͥo3cuaX];w~3apN0H.`577)!ġi'|wٛJt3.K;B{W'PO[gP!@@ZiciǤqj}@J)yڰC{:Btvt1}7TlXSS-A j-}̓Ϲmf;?Zl۵zϫDXԍ[e" trղgk~X'LOݸpgAdys7Ko'~ŦdLXg}_kDu}V9Sn:AUh{{;[˿B% ^|s=gTR.=xS/eTf %sx}гSxHxOjt6 c+PK W4%"0;&_)SuØM==dcccc3#ކ*9=f!at. H_˺Wqe]S`I1w8IP#!HZ,!h \VuP0EŦڀ;c/b~S2u2w(\6WЈjOc@0S$ְ>o7 [zy׍mk &:yԝ ۙ,Y_^}Ãm6(Ddjs3$F;b ۰JtƵ>Ӆvzlؓ; G"PJp\PNtk1TLU| ~?2w{-W(a4 <191Uo?sEŤ%L~#I²F0uebXˆ/ltGtC)Fsw>_nJ*~6_4Ma>{a SϦo<2ݡXBv*71N9V[Om_%(QҵDq]dS>TeܫDGq.PRSX0R'9q'$媿!ለuns Sq*ymAgN6^~R!+x)T B(Wt:zʙf'@BA7UüOܡa * %hB" 1#F s3aqSo<coy='ōʍq-BuQ XA=2g{_|sw(L]7@Q⃼WΨ~)JPU{V_5 . ͡ok.zGWUxңGqQj_}⩽dg"!P6U5R@Dʘ'5|ືX+LꚶZ]1]-Ə@l 2rRpgɺpZeSƥaA1WdûWS|u6_D eU^:5@ $Q5rҢs._5j>CU\SD+]<J'@Խ4-J\@,KΪ7 !۽Q9ڪjo[;C;cd3Un/S)á:sGX8P'JԫnZ%W5cgP0[f4+DhmllllNhQ)q9[/>`~鲢V (.hړ*+TC08$#Qq)ݲq~STglzA4ag/̎\`*i;Ʊw|}w=q+hZQw,Y>ɽB JxL#r= w|o}9ᑉu~e J ?1&\\"I($'%鑑V0uѴaj jQew& ~Qcs+ҘHԴHI׽bKsR2$F!Q766666?{C#vfF*+ ,sݏN| Oܗ)-Lwhˢ\e@š@uɲa0k6/0 I@"4F8k*ouA(<~)tMEF k@s,[ט/G9 "ت!CE sDD:Vkhr%at95JD ɖ`jЌ8#h>FQu}Р7շО;ݛ!RGPܙ?ܬZS ~%m>GVzS'LRMSO|O7t0Ctr\.PIR3(jN8M6xy\jX;"fLUd֌=rc|uM%Y SCSD)#]u(ќ "PHHs5vRD`9eҕVyY}F搾INUg,7y\+۹ s0!R9r`4 .YqQF$z~nm·zmQNwXxCZBu:48]7>Lj|k'"\k;c0Ke=߶T嫷I1M;bҰԂM+6).+.3Jۛ232 h]|DWVVFGG; >Dv@Z/񨤌DeY sSh$Q=ӢUԵ)9=h8T`1#'=o1yXlv4A$\Zܬ ;}m]DH yzD̖j;$aRK47ux]NJ!X[jrzb L̊a YSqh׶-yozx#*, PX4ǘQ>~cΆ}{?# /3AګG} 5ph{oѻgZbrVa2#Dp6gLr$ e니**JLLtvZnpω>w6۽z~TPJI(2t@tRi:w8hNUah@P8A0nT8EaYjcccc`D2rR~ _Xp1 DM" TS03stm~Xi*,8OIս:a)ˡpR,=hbupT $T7Qu8 a遠I( nqMCөT3wHtTZ?`óݛ۽z~liץ @ǖCPBPJ }t r#_-(9Tq@*N(!HW!"PF(R1i?(%R( A밻rI(%@)NF꼞!(eB"n#ݛ~&qN%_8Ba/r>o=%PDΓB)in~+QZqq6'!(8^/lNZl%ۿb7;QRvO:ݛo !(uh=fh"PQ"|%?Oɳ"s2'[ωP v.I|{9g)={civ_+d&PJq]ЩVFo` / ?Grgx6_|BxT*#vwF D$)Bl8cƪFÝnYq!".1)?P/(mcccc5 "V2%B QPA)B%HBO F8G)v$"BHV%@Q_#Ӣ˒kw#e*#T=bQc RcxI?@O{o#0Re|>8g3طn덭5D|ہDʹQ7`ӻAK^y{N8\(sFJ(cLhFW6(`mUSu3rSp/I"D¸pS8@RRʹpwEQh߲fZJT9Nn1EQTE+ QΏ;X F0`JT!@B9RmN2ٛ b-]Mw1~>~`z^= ~D@t&fĐFCUDth5c/ 9`3}gn5Gs@ӴNxDOD¹h:tQ͡F{4H;"WoqfMLuΌ~(.%p%LCc];LpdaQi"JDn4U4hjYhDdM[/]eHuWDVT8 !Gdd)5 slc@)6`rzZBSXPo,h2B% RwLjr{&tKlZ@e{~L˲!DQTlmjg7Aɏޜ0s{pC| _5(\ J(VŖUtMr5ds}+4RYb }?#F$X)߂5/}~#Qw֧/kٜ7t1[فā-kG0EG;Z6"D,mz)㳆ߺ݂2_NU8JILp?s"ZV@ 弽b¥߽dmř?xU#l梭nkt?8Xv $h^D`׿μ}a)Uf\֫oD{(, Ď]:ɱ/ %a_kz\/ΈiZi:4'" woiM2^Spho#%^lu-3"a y_i왱V숆xR)t FDPY_O4 xJE5-Z\*^OjΈD ֭KtU&JBF$D{ @2uJ|g/|AWץsBPJB+O d-ʔp@6xxҫ6^/9`ᾔodrgo~kH2)<E%DZ"TF%恵W*כ^J2ym Pf|k}W|Ku-J3&.m>zbv  U6EO>vd%2J+jti5˗Dgҙ}pdg%Ϸ3v/yk%.=#28WSj,x鑗ŧg$o-<Ѹ>?~aNPWeW[zߝ/}95ж'o0Eoo Kך͉%h!x=W l-%J)d*g<[玹|T"S:E[ɂ0ʉWi!PΠr|=uh3 !G "v *0%cum~"Ao/wi l /̿'^]QTD%Ri[,\^;t@S&D6sw:AHB eYmiMֻ@"aE.{xÃzRvC}8995>pgذ^@|YgqF8ك<~uF;1iG@!~66666BвXW?|ߨ>|B&H(Ќ9b^^x*[qf.Hu%++bxxs+ |FovJ)Q@ G!1E[z?꬘DȈL:5v+~HcAA),5ڷވz/4eZR깋{4I7m{֯9{rUӣe!!X.PJ ?_0hZVX"hBt_w8 jG >]6KlGTT)NM$@,!"cDhk* T%n@)CzЈ(@w0Km:DFΗU/hr^C3`¨%(Ry"@02Ce@把xbb\A.0 hVH06GEjX}͘U9$@pw0(< [f[vUfDq107]Skx@#`cFxC/Ζ]UL0CA ,"*2 0 ˴2rQ5RaI5 ms+gzgZ8m5=LHNIzԢgZ }gh䐏zGdzҴ~M~}ɛK{N@7ZъӳlϨ"T`)>l G}%,[y@)1I4[Ư+Gco":whzѲ/h#~!(&)g~<6ϯNKADBfzx0 Tֶ[o@HHH"DD&P vT0M"N6~q͏B||8⃈94/7繅63AAS`(Bۛۉ3\% $(,..*i ML_KQcs]#s0%6e~寿ʰALB2YBXBH!!-IB3<>Z5-/. s**ooUg 4Ƿ.7vhhno (mQt d3nBP=S\1-sҥ%#%RKp 芚 m i@܈ pek{}N 'jjD֯zg:܀ Mk_i.ohO)0i}e ͜WpE! a 9^Z3iXnD(~oci3-{ tNhhuwѮqb !ޜcMwi`QFD DJd72yiYQi @ H8= ׵I2,Ea(LϞה{R dle()Ħd mƸ(!Ih$-*νQp9NumB &FE<gOU )vn!@'>EIӤ] 9kf X l)#U׭8""z v_M>),|B EI8#0)n!kq9Zf粽uWMK-5APRz.9Q(PrƠKtS#Zn ޼^Cd; \(*me`7? RJD_D@ZqOtטy8XX\VU~h/m/ &&ƯΩ{뵿;|{J Pq{[[ \{M_(>TVZVTV/J ??~OկFRD[]MWcp5[2oA!$e1)ܴ?~eL׿"7víOodg;conxƣ?W}ξgE›*;o+pA@:xO9o͚V^oeQ`աCťE5(Ce% ޏޞuփ~Fanh~͡j4o뒖)eYBX&Bˆ_5oj]E=.UF4x Mdطd[k3@XB˲La!@hk x&0ÿ2'}Icg> S(/, 'LP::(^y7eˢ-ӯ=3$@w ;8 y߷\v,iPM9T; .>:/WdɒП˯oǗI?$( l}7jY,;Xuޜ8 @NpaQeAAaS)7?|gR] ÈRD)mjn)5Zd ={ kj#zOf8EI%GDdrNVY@sdz|dtBfJlB֐P1b=Mlmq:gX[v@;!>,*.;ȑǐ@dZBt\ju4<#22Wvo-]³9~?5dPZgzÚ[-K"r\_?74IO?}lF95J>)#D{DO8=…PO<#Ѽg_aYesڟZ3t@j1`ء=cc"[Kڝ )Qq)2~MN#"6Ėc`4]'!@³qoe]5.bCP҉^{OsMkMMA?οjh9'3|贱*X] Rp\\>0CeVε>[NO?S@ `gMi22Et | ֺc뮝9q(b!c;_]IL{K*'g6Z}=kORo*B}'>g\]A^8i H=x؈)LX=SѮyeTӔ vrf w3IJG*GPJ\.WFqhډ>6bZzsz$&缰()!r7K @䡬#XD ,QJ!%au!CuŷJaIXbJF)KMJ@CȈH,ܸ|Wkptj <9E >ّm J!$a"2TA_’qIG-sB% US v~u`66666? aUG3:v)_6MӐ0FQvփ['!,a}[76"2Fxe bG3K(clںqsztnHhh!ע( t"J) ]GjB1v-RHzII)Cv S"5$ id],Bi=5@z9"PF()ǞU uoC.l$D`wn5axZuqZեat̓dž̠vPîFH׷{sa+4 v=Svx2;<وcPݚ'qʺ55X (aѤvGqiPkKs썗Z;v`Gjjőq~c8ʑ*W;5؏(䳱@b_`ǀQ4Cy(%JՃa6D!!݊t.Q@D)w&fQomB vIѲ#K6!u}(NYұ SMCo}uQ?Ӿ'{]!ffW=.BSȐPv " "S]*XAô*lllll|D qũQ -:A: +Jr1´:ݐpGXkDoS0'cP~$ei[H L3v ~]RatԜ HHr*J yd>A\@Z`PZ""e3"-#4iLnSe@ A/hzNH *Z)HI. 3/ϯ$>7-o87,>h̄}i:!,o}mM2+/TԢ*zK ㈥Ǭun{~uqoiн&p)Jig) @dZҀ(i|k_-~4^y%uQgNZ8﹇^Ye9,ڹO=k{+c[dSVY܁ >o™_}.a HMk翳_}gwgMgBXX{m==@,wJMKbzq#w]3p qU?_? iKvoNDGLOK9+.Hp9%CU"P 4͡i<ޫTbUU>_Yw*WR"STPrxODNC鬞)$Tnsi(~YyPMЦJUWU_ P=bccc0+vhmOT9 .+&Odf{LMSrՐ{j߈ާr͏quݿuqcUKmǷ} zN$tJqcJIĤeGFHƠ&rgDF;99,3 sF3,_:#HQai1}D$e_q[Q%]SJNR>}Y2r԰ ?ޭHӤ7nx^ w)]ump% =IDAT E(vF#?)՝γkv{ 8.P+Zp՟~Q8k)I)tO_W59ډ@))ɩѽzf葙6o2YpxRӢ22RÝ\Jٻ~rd9q=RsJNu7_0RyYeAP]voN$RӒ@ hok  g}>C2 C%yQu%˒-[`il[$$@B7{-ޥ;8I[ _f/vgvvySY@氃DZjkZL L_iQQAQd.'.2tp[%Ӽp&n'"0]U:p #(AkԨ*=?H`H 6S +q4%(.,. @iLQQYRXT^+ e[?Z-oo^yC踈R HLJwFZ }hTRn#Gg ^dXlvOz$ .QhZ4$ke&orvoA%5cDu[MFzĹe9/.=xxU tt0MBf(iݫ)(BiJAah#)$D)P@Nw  {cn~{=ىT쎆}wT?+A6L0)ٹͳ`(ΣǏLO4_lYR&s2FctgeZYaOf\Ψ`ɺ-f?j!)0 #ƀ朢iB)$]ϓ"BHB4HCHLLCkjݏ۝NNjusӟjztnTdpyౙ+׾nkuvOsފd{.WoP1JBmFþR[izo] HDȎ߶c7l/h?P .F-ܺ{^Kk 5D>zOtAuݹ+S<WZ9'箇Q'ewܷy2n-[XXX@(C(aB["h t@TSSvЃ u*QNv6U40B0jtU![8H SdEm!( :=ObL?έ"PŦ-Yvc?@(=Elh j6[LK!ii6S&9,{oC%Dj5{%%t3Ι_?撳'84؉}X #bi XXXX@vW96)t55DGDspyuI cu^89)3]JQ5DPr*5uASU*7F~-o?8lXͰݮ}PS/-Oս "Dzɿc]ק<ۄPc-۟>f)c `FZB>U6 Ue*}8 67B!m ΁RhE}҉ !__cHZZL? Nq/^Rly=ghosV,[yϬM2fW9 Z=!\)]s3KX~;8-}qmdaB B!ڣXXXXLA*k޶|%Ss2'㥧cPTΛ;vr/3CͰH"6t&V.ѥ)-SS4kv#j=!@)q8=7!ETDAjBR&^Ѝ:⼁tۏzpzw=O|ߜ'w&-d lwW$?܍%[C |A7 _;B(sT (E#yӬ'误?xn@H'َlvCzMTU2BCSiMk#@1 6+̐Zc(Ob[QN^Ϝrwai%+2o~RxOH"љ*DTT6Wl6FíكACaCH#7Ǩ rј)sb9FEL H@PJ2y_)9xݽ溚ɦ%F(__uFD:(%2PltD8S:*IDBDg  FXD$i6vjZXXX@$by&<RRC/Xt`Z=ojBA E)B"PN"%!I EEJ9=H]a9Qht>fw^j9)"bA@4;E.aI𨖗`ZkK2b\4K|v[ߞ.j ;={%BJUݳ҇׮?$LLGfvBD5. YTPB'QSV4f6Ӂm{W⿨ D00&$X,'H@/䲥y=WщFpO Ʊ%kю?񉉉I'!9)rI)!j4M4H$KEA_s`aI99%6a ť¡\3[J|ZjL'%F;"bR#] Z͜mBIysW4v=Naj|p˂5wpUS7ҺTU7ELS(ژ] *lvŦ2 Xx&cj UUU%caaaaӁPaLt՘u_r0ѵ DI5 ZS[2cA Irv4P2?IB!8hJI=$ªRUBқS}YM#eH/*cV$A! L!z0lu"MԮp@m7+  1.|~4"~=G‚T4V@46$e I$G^|CxYnwI}3Y"?SEbԐhz8Tw ϯ aȮG1/^S5Κˊe zU!"PeEszm",ƥu21Mi Rn4LjY8  Ue`$%zi"F0Dθi]}/?tۙ2o~̨r cr!3.,l sM\}ɕjZ2{ξ[Wo9R4"@J= ME3.;/{USn9KR hʍncGl{gǫ 6o/{އ_]sƥ]cҿx/?߾] f}f_ݠ o>Yg-+f6<JVoK6,;wźmu-ƦfS#D"!)ׄá@j.WUWT7u7ZXXX z _ HF$hDU!PL=}Y弋쨱DuvH豷Ԟ6]Y|H}q.LLʟmWC{NN@ 4jZjJMCa*Gp -# m~_GXȆ͟mH8QJ d8#Ba{Ķu~GՍOPfl,ƴ#Byxef A !D"PHF3/[.wp)C#zv1]SL137\[ /μdXd9}k{q΀P m)@sB(™ݮZɼ%1 z}2F*v-}oޑ^K$)'#~!)a͹K^^9BSXnGy!i x52CV/ѣ/(!BXWHyI)>p(d"(l[5g6G__Ma^ob$kE I (ngbzF#fmE~Hfd$z4Ō9tpw7xUx1D¹Q?f+۳OShmUk˫Z{P#[ٖ֬ެsc<=R֮\%!9Gq][w۳'ŝs-i"=]u=!.Kg2;5m^&;+>6֣֕ !#[G袖OaLˏYXyHa]R.ݗ>WTnTgG}Z1#2UOFb7r݆}wβ سa b)ItY2Grj߬]ohr⒄8jHq5L@93ꪃk8xj梅<1cP~z'5m)[l`z)~ڄ Gz >ඍ֯[agqrEg HC:Ԫ,,"&seggt[lŮ▬>)..FF˥VWBM~v'n@_5744defq܃9qqq6M(%PEUR"Ql*RHPI(A)LS Dp.L]=Wm¡D!: pa@R$2qjBUU4 0DL¹* L]H+Ҍ&rUS n' $ UTNMSΠcu9c )%Q\ S"B‰4u#bDTUH hT)JT2BP 0M3ll6"u)(eQ"0*!d*WoF4:lHac%0Ui @ %0q mDf8"%PE*5#ֱH9Dm@i"ð9 `4^vWIsLrZN^3dXnj4Eo]A!1 x}j `P4;SB׬_O0pPNHXBPEUݔ*P( \quATh6n KEG P"e4z(KjBZ+:*'n " 0%9*1)(HII!1fߝgޠDBɢ?ڽ{\~yި 4?yD)JiK[g:~w1ײFP۟BIk裧h;sm핉 Mw8WhNmZ[z9DU&GJHw3ݡq*G"iP oˆ*>vxG:ؐׄ IP9ӌú)#O,${tqlu'kփ%ysqj42[러?\Ҭ'tZoSzt@v#Kzf><.C׿c WՓIcOt'Fkd#+==OmUL'}c^ `ki߮^r꘵c_8;sbhJ_JU [FNb#M>{ZQi1ɉ s̛=@3k#-G8B9IZ[$:SoAqg89Z̜&<3,T, У8Gk@~:f;'!?JD(Du& 1R[b2X&$egxw~PNa g*w+U+ug.-ܬḪ̂xxg}%9mTZrRjZzS^!]Or^VjbBRsnPb`|E]V(@#o{G杳/t|{Jiϝy?=91@99)5sfyclaaaaaas 7+ba}qr4DT(3ߝW7jRg0PQ Se97ЮWj˖\bYvצ:+vʳ{o-߾Ҵq\ \SQUh*4 #YE=rM+tzyůF]=i}e Jfڛt]<l#ߗ:yyO_xh]S7@%olS޼"y5V_]E{6HyW8lGzݮݸJ$tTԧ/sdq ]d(SY{r"uɝWgw}˷L:jJaρ5QAw/߰Ww?v](AӔ {C"*[qvaRZ &QUΘ5%}:qR&*=_+#~sVNۇ'6Z$̰!0ȶ '"Dm*a,tՃ@F'q_s3/vD4S&w#fNWF 0 `9+[>N٩{i8b2ї~2RXBJ8ׇ2FP ө8)H( i l6[^]ds}K GiO\QxeBD Pڕ#=^HK.bcdaPEAރ#wt \QUKݻwǷe 9ݽ & ٽc:Ƣ>@~TUk=Rb4 سL5Gi TFS7U{Rߜ򼼪5gF̺X̀q(kgILmZv|5G~G~W3yjHj7LwJ)Lxss~Pid lZY?&n&ƛMPPxah}9!c ) QiB]rq@ M<=G7(?>N\D$(%i_q7{}Rc7DRҏ[ Ӕ`j[ O_ǧs.94-E>Ԛ085}RGqt Q",G_ݘ_ *f80\M⎯TS@1P#xM1T8k4)EA;1\A Axߺ|W>YTCΉs^m Ȳ_x-s$ ~~sN~?)Z/}QI9+Z߮wzy.9g3GD™Yk+J?wU Αp,3 q`y0VS0gn_}oGauSsK /£~e!P͆7_aށfΙ2D6GfT%Tѻ~u_(jIٰ?<(pxFJ -_Ǽ\}+kK.hD..W-=E3]Y0iWR^Z|xgo9kniC͛;s_/0.//=qͷZ{I9,N捇𖽅{lZY9z t$čZwpe1_`FxoѐH8ok9c}}~qEK>zw<3FsPgO@7S2)M_>^G D굿WrSOrYϻۯ>hc.5;ѕEU0 g?oQ{߳nw*(i>}^g@1[b2gmZ W +Ǐ81W^o[O:f룅?hMam |s\|M>yDQn^61#\9/` N_JNa7.2) y! ?~ƴgq"`Jp3y_*[t괋Ο|֤ ]{#[v{ӯNM[;륪R!<}Ϟ~阁g3esrWH)g c׍UQZ+65'0 Ystea) I ^}@tfdTvn=+fw2-䞾ٙ=zxyM_Ɍ~8OfνIo9sDH쳻d|vу-M@FBnD{%42I>S9ޝ2FWbJŦWMJ@FB7s4-D2ƹVEQ8B(DO(U@$1Bs cm37_]Ua\9 Ǟ-e3%P8c(1@ pG?D],%|Z`O=P]$:IV&mi4Q_rt?9x%eX3ޡm%r*{E,,,,,A uv&" 5vD/7kD4Z;hlɓ_(h:c{qCtp6Ӟ_!(TJDpVxo^Nn2aO;iq_كDU0Xl0zε7ML66\Q})60"?? $3;~}KYdk(\`Osㅎdɯglh"%Qm٪Pm!],]?kOpĘ:Muf&cĀ ]2VΟ;sĨ'ZlW#@q>O>G T^Ίu0 FLu{e:S!AҘd(̰.Ͽq0 P˦%Z8> 5iUPU9G߹{dK̑OҲ{R] JpO_ciyJlRj8N-U aH(@p^{KUCЕ)-Rbx52&(`Oz|搧Ggz)p$6+OUV72R^.AQB^tN-7;iق-E1p͸^?(^`U[/O^ba6@ enT׆{=shV|؞}/Xy9J̦<{rJlzli@eU@zyQBחn!= @iڍy.#$ TZywqIQQ>pҴ_t&D|=r92(yKf#xuW@޺o_}̩wspfJlZOfvajf V77nK&ZXXXX_APW!Iq @Dxzǧ,ۜW $T.4)$@L.ئ)quDKNU +!E@di= %*&OIGiG<}|U9Ii0YW[]˽Ltd )#>W.5.- )6YV,ǛqK^#LDEᵻkN>ɳ<zoWGS 95 P[c0ܛdz0(6: # <]zt.\RPϬ.i&z98Jb/6%(~ ӠGgIilJa3HAW z32퇧 DQm3  `ɷۥ>꧓&#. Ԛ<9Y ֹ=:k]XdSf5ޥB@W|ZrsEhR$?h@ߌDiWC hr)%Xj=hZJ>C{Ǵ +1oÆnseu0h`7NG/)>D"5;3W=gN.MO=p\I$H:xq{ggtn7zva|._OMcxYSnŇ3`_ze֪=ʫ.y_k.6c^ObVoɗwԘБ%R`מ}[lSG~_zA4)eW$kil9W^2pg8 Yȼ[~oA^pwٷq#k9Oy胼_qu׏+sOiX @5 +/mD/?[Wo.s` %3˸y['zmcaaaH(Y< @0oXdP@D M_n)n M-L 11I-!Y`)Qq1Sf9 m/zw,~d@;zLôu;7Ӈ?ڟzٹ4ѶiRB>;0 T =v fUG /aqM MUmInXPUںzbR2:LC`65Vsi8$x1PPJ;t<";zh[[En iH@LQ%:ydשּׁSo~\p坌5[=u ľU ;,գ370Z6~9sE@˺x񨜻1 F=׈ C{u{uעk옡ݳ&\yD{ˁU/ʙcŷ?+aHr#Gյm7Gǩ0뎍w(#@" ZKO?kKcblOŤpu~Wu_a(s°n!HmsM{ E׌yo@LLסFDuy\vM%ƞyoBƘgꞙ3&zk8=.$bV %V3B%vH$CBupJ$I @FUMFIKǧ+i6ng×nyo}EQo֠s&gI~.?~O!L^NPFWv=%T}lHAEX2?U0[ m>i) Pco0um n ~\ˎ,#D蠒DWOwMX]p  E6~Oץ@G˸EpҴidN ɩBS~LR͉WvYP^YI Sz49߾1`H}_~MCFEL0llАhFK;o7K! d B:pbhݭPqzPR`+]ٿoNz2J( Ҫ-$" L}d lͺ斳{%uMЂ\3U8ȵDb9b{A{fk(+*D뜺tr&h j}~;3l0*4U0}I)%JiFpKB<} @ 엜("@`[ 0(1:y< O8LB(ԑ=ޟ[~i@?/Jڽ^Hux?3nLQE.OUv!]k.R6%5(5v_uoo$"5=Ʈ~q) !P(u*)6: pH -cD${!_K@E(쏋R@.Auqh,XLRvEZ*Hh4"2}@(D :{}v+qnC@u1Kir?A5{ڵWIBCj}ԶWG3_ ִ`;sKgDG} 7)LR N?٣y|q(eMu4kPShU!ӡ}-Ky(Ir0YEBJi1}5JQ6(6]nvp@D@!gEvAC*],:PK(?Pu]Vw7|: f0Duj ]o4m?+Miر}v)Ӣ:*ST@J ?dD RSIx"S .]کb`gzͭ<^IsD6- %N;sdɌg3 d`͆}j'dxFåAӞ%G_qQ,{k@QEhB2RшJ+J%Pa"XXXX Gp (*4PL <ȋb.^Jy r B|kvVeu',{omp>2#w,/iF i&Jg^:$Ôa }:{wQE]:bW3UD6!b۵UZB$)5nw?ugd'ڐx4w|0֕6bNzu,yܮ5;zXZ5v7_e/عq1I܊H“O=phvSJ˜q`ƕs/+wȡέKK+JjNn}sRO?nOyU7[i3 oo 7]ɝ;+qz͇_./m!bߞޣw%r.99;wtN wY6Z|-GD٩?Me= PP޶be$7mtegtWjv+zN<77X6\#VH{^}JBm-Wᦢ=ʜ"L1쑙7ܸБÇ[./5gܙ:Xk_)u; jc7rPG 2B+f}ْ>Gjߜ^g "Jh?oKgŷ|޻+S.93Օзm {6nIqQY`͛wN;&͌5 1UbY)#y~] ȫ5l*s 43Gzٚ0vlٝ4iR)@ϟ|c$)]{Pt' p^~A?L !($t;qVضСJKسvK~suO(8>Um51AA`K38`AMRLQ30g[␡l(ں:á(Jtb,sg Vc))/xfc=("6c---~g' G4.(HMNv8]N(#ҪgFf&i)+h6(O씑*Jj!EswR՛Mr8T@DbPcLҒ;)#L0nj$nqŕM!jsdtvN YiҒQl:g:8%h(9Sc4|R3HIQQs+.+#ٮHS͑J픝@Q =z`[8'^6cD1%#׾cA~tm[s J?ޏRQ}y{_ߓyV?9Yd'(IauXh9䃣Jv,n՗/$"el)߶n 82IT>R|ֲ–H_ų(mdKŚes*vOmw/ֶ_BthMB?]N(|m'Oݏ۹ JO%6[ɻڶ}UpxO-_ɼ?k׮/r]]iS'{hm=Z>'=1=B(nj:\% 5>dq'mS7wkߣq[ӖH)[\v飿_UqBJF)x Q<2Mח^')<+ eإ}wp?fmo\=G}׻N.0@D#w @ aaB]׏FbBaiqf뮻^z[onzQѿhcW⇃P V/vtxQ}&O=?_q7!ohJyK843VA-g]3E[7)5oOߺœg86[,ߧh{~ܱkMwCmac1ƾ% mvҨ0vixө*]+ LW9M73cBO7̙a.߾an%RGDdVV~ ADh :?cQH)h ~m!6v[b2oq/B@oA fidik4V^߶`cq^BRV'v {{-7@wn@Qx{2z2Z|l]OtNS,>.f7!S(eL08u3`Y1 r6- i[jyTKǮ04k+KYlvjDRⴥ!R";H(J! k 1[8ɽ Y&þ&j`D qhp f;cݚ rCɧn Bz"Qrzy׍hDTQ͊Ӷ;d8` وEGu**&4 ELB"f["RL45qjz8 "Sm 65CaݴMԈ%.mx*;K3B $(.^CM}a% 2XQ^N k97<'@t<ࢇgڏNu$_lKfzvWgА١2j6IT|pŬ?_uٞ.~g‰C$J藛{7_rɥ^7 74F%,,,,~Z "S^rMگɡS5ZdK 1^J   פu>!M l 2X5}"s,L,XPZA^(m{E 9chrH*o(ݻ'xF[* &tK#KmsP;q=bCaS)e{֭UBi;sоpmQfъb7Z}]07CLG*w-Z#ij:aYHIJpNsNUO. aHH!|域kןyU~٤@LuƦFH,@L{_ᚬW9^w%W_w㲫JjgR4M3P S4Wָ'?xLGDãBBt\&cBf$*B)8Ty`>paPqQ۶PMRW ڼPnǶ@4 SXYOPJgϞ .[Einn6MӲm,,,~H./וj&𲫇feeM u;_x n6yC~^Ҷ ]|7??~uAկ?bCW/rn -/?:qADզm^1&Lqeu@)0Kv-{쾻^TH"~{|-xnSIȮ \￳)ӯ\s/V⋇7\wؔ~vgq85/6+a%7t#לD n_6䆫:#r{T¥Veo~xLѣ ~8~0.%&|7NQ21i]@ %V/J񦯿b Nc{d.PTujJt7z^V_\=]kXF+ATќ8N%yБn':-Ŝ 斋.T cքO`;{hz}tLܽtn;_/DϺًԨ6nPyr:3AQ'|ͼ&6-[O'; 4M)i( nXޫ1ʌ覍wnW^Wo_c%0M.O9ݣ7+fS$$tMN.?PcB9}!LR|8Ϧsf' <^yN+8lQ)dͮ/ 4)6swaw9U-4yM9czA^ٳzݬa#hMΜrq#~dՏ@k#a?^"NEP _C[럞}mgZ7@HA<ɝҏ^y=;81)%9hjܹa)U߮[5rt^dLJB/8+]mڱ4{N^;H}oknu7~tFthP-KZjKj*G{RYgM YlGe3dXt0 jPZ]sr /mņAͦZPe3ph M,ו^J 5k4L:,S+<.[Lw_ة;̡N`޼=GVm9P:x^*HvObouN[rUxi?vE,,,,(:^%D4S5~b=c_ր=%I]3:v+\:~ο|P-\>|1cOOtզ"k|bޥ__[\Bn|[;¼ @̚gd_t8+j MRJ9螥_R3o7R=W&Gzn=uAy!_ݧq?8`wXS3Ͼ41NLm{_ 6U4/|?W 4z?=7g*g$%v햝ˉg{Z@@%W: ފušRpsC餄p$UQ@(`c};5N$ \8mhhih D.;)#)p[Ţn;Wc=G^zsֆM;jc4u]7E{LPn )scK(`OuB65 Fԙ_j qD$NpsCJIC]'®iqi!X8#R"c7!A7!Vә`Bc2&1%Bcx@1?D"`$"s/W6.ooS738͙8^3YUiuꆰމw]y;ppnLM:<'6L7{ʡmNuע؇}9W^4d}, g_v兓<2`DH;͌U;% 3bsxoIoxOHz!<3Ιr=uoN[+˯S_բ)kBLi䐞̮9'?_kFI]rړ{LgBxtRԡ3>ؘ4" `TlXQ5?$Cmh0 AkwB>="MuyoF rݭjkrw G6tNs!Sj6" Wlvprba͛B.8^@#D9 L)wA:8b\%23s I,|^]l^kn"mnؼaHԠ6Th.ش:/M1x8Z9 "H0Gur4&" D u #Ҍ4#́XXXXҠac%^xôa+)^jk" i$źy4-& fD #xW+5 ($Di%CeLa5orc珿,buT`8VzH"9Eٗqu!ţ9+nvm?mb4H9&*9q7 1Q"IaJ0 Pcn'96ZBi$ĺ4jK""HNJB)R*FҴy޽{w6 ]%ΰ) #b&v5^0Cm*p#:j.lznΌW#A]/:XlQC eH[&eR|#$Y MBPR !Bh7%Q1z b-+[XXX1Ca;`t^xWu@L>:1p%}H 2` tť%U I471)[z,f҉HssXKψW6i!"q3DSטwD@4w@Ըq:گ\14n!(M:"_|Gz%yw޽ok6>p茬XTPL 4N) Bi#&ӞJS؜."O,@xd6louR))JVX7?EQT䨪9߮(jظ`z PB=W+/BpU2RS;{l͜B"5UU US #@i WUUQ9T:&?0ьd@bĄ@ő[y)5vՆBt%!.z_K}SD3i=kn]PMy;pXҏ?Z}uYmYSOYv[.Fg\DS[A.A GTMUTESUHB A U[捅/DT8=auQAdZKQb]q^gPY8m5,])9֮ك[ďeF*7ty`АsGƘ((۠vϢ6icb)9=i P5MDQMeP"x]kx^=}TT! tC iRTJ UmD 3vnSj]ưs`=epōu y3}n cYq-[-o_YA=d| WjcG qB(t=#?v~D"z%DP( )&JM3P8 ouz-ke1¼ n&e:~0T?aG_6ql1ͥ{>1z:0i;1lԐK+]4ƫPc]_IH ʢ=RPnOzсB) {7FORFQo?H]~%_|ڼC;Ug;7; k/g4w#8Sp۲y[^&UWj lٸX$=0e5?tM)>{T*߷l*;F4ȱT5Rk^z$K =Kp"Օ=λl\>󗇾5X‰] 7W5=\Bd$Jڛ#h2K&dMk 9ͮ@#uŵ+/3R~d׌>+s;ۦq;f>5mX8wޒeAǠOzs GL獥Mk6ǥ[_| L?`m~zCfVz]?m,5I6n_f'.5}ʐ4 ?y'$:b ݠh}_MKa-÷wI{V-p~PcrXccRxk~?BM~Koݱ̛ݼ!LI- ʚMw. !B;(D - U] ]3;) -G{ىI!!gZ'KFBݑC!O純䴬x|>K$olJFzFsw_zoފfꓯױF(<5wڔv@ʹ`^/.-JT9RdK'-#=+1u&zu|Τl/ 3& ̌7B!Of"2iP/.,l]~t{0=dpJ!յ[RlG w*, kݓ:%y=I]:u=3݀Kjaaaa&L꒝`;w۹^1KMA#y#TtuA4A&7xp #νGT/)cLaG${1#AW''!vBsTޟVsï.ú 7TWeJvsŖj11nwlR c< {zNoºyeg GtSnCFtsDbz]2xD5vjcIS'(Z\|ZIRc .:xVwO:o)^CGehCbeO (fYWG}( Ya_S)F(HA4F Q#@4#A=MTH3 D ɜNʈ0"aCT_9hP/Ğy?o$L@D3UT*0"@X fwU Ҍaᴫ   ;6 C "S(`D %$s"C`6GtANʈ4u_ vjPa(;H(ְ ]Կq|%\gc Dp:J #@ r1J TӦH81Z(As8mJiAR:^1TB&lvz$ .zW8 H%^ ,Zf9>[m Iᰫ p(jS""ik# lLL# 1jwژ 96RÑ6SDF0:."*r %%nE} !1}-;y,A$ֶY RFPH$]Y[JIH6J!%"Qm2BP )@3w}~`(m~Я]l#c-J!D)AT*-QbkcdQ(%%4Z/Qh\N[@q'c:.tPv}*5GzC6F@9+oKxwHa[GaiusxG& kKjҡ9}-RNq!nfJM'O)=v?F;)=#J%AP^sۯv^իk'xU-(I*o9NF(9$ǝB| _ G;NBOɩ6Bɺ#J??8n`K֣+()F'i6rPuXX7de3XF$\  ^LLKs@q6]7I -X7%w[UޏbS$lf]r}B!0#(g ?S] ˼.c#" @43!ƭZ _4#,o ˼ADsMS8u-,,,,,,,~H)9q˸9̛?R";.Q屣B1mj!т)di-,,,,,/PJ~ʥx}_6y=u;h4+%! SP$) B~"3Qiey‡+UXPmPE(O,‰89z|ۏaLO=FHOz )HaR'^,`y4M&q|+5 ͑2F?Ͱ|7Q9W1&84>(bpKߐ w… NO@D--%AXy2̛1j vd2 \rGcбz@W̛1jZXXXX` вuf?W5#J s3*$D)\Q8'GDd\Q0(OZ ot;aZJ8o.\HPQr|!9?!2L:"Uv4 (( ۛ;n&d( m݅` D^e|Dg c-]RUUXDB݁"?s>A)"%&7@)~I@wf?ǾWW 7=^^o)[XXXXp g4в޶9K-kl'3( aƕx9ҍh Tἦj+p|牌)huh݆AF8WBͅSU L?)U T0[͐{ ,]v}햵]G(H)›k60~Uf] Ε_>rbW6lpa18ᥫ8C>]quHj6d\ myn޻U]}72$F(c|4z*HAY?rZc+M$2bO=|؁NË+g?esrL!O&%U8g Lw3F-z/]rﮨpܕ!pso/.g@flK5z=WyxW_*3bHG9o4'{m-qg*;ں:á(J7M~nݱVoO "Jiƛo{|ݻu뛓ӹs犊n?x  3mSb|(m𘱹]ѥJRuՖ*")u™#;9 L/ءgLm&SVOVJ*gLB@EUUUmJU4MUuXXXXX a |[^2'Es=M͈" fsƒeÇĔۺ}5+܌X׎#;F|G] ܦq&P`K_}3Ͻ^棫A㺿-~gOzԕ6dÊί&K˅ D`>}aay\7M kXu˪BRU ݸi҅[MJd +_Jt,[ G_veW6%wK1zd+/|MpI? Ȩ u?LkW^rﯧ-{wceO>MW]q鵷Mxgfl \Oow'e%/v9bݺ+RJnݺrB'4%xڭ J+_}dѬ>< vTT**/n=bP۵vsaCՙM(p;P[~oOT)=3F%pN7.(8'H o}4cgq=.߃H uM卦 u/) (={ꨋuۯp]YjA8}|vwduQ oiXš%F'rU͋39w,:b} Cڤn= =cܠTeƦ%!{k'UQY~g;) a}+ISĕ9k/9sXK9g ]PȈ$q܊k,vFL'+y,Hտo 3/:Өț )%c9#|ؘA:/i뒙E-rmI5‰jWKX{:c7EQ~I/]:yǎ!K \dIJec뮼ꪫ .ɁZB]^_?1c$گpIUA ,P!^BH) 3*}RbwawpvKT *KoZ|V^ Htt^x lWk615Dgr~g h c'o쁧EQU!Ѝ ( 0Lݔ%Y1gye0 _PT@b}Ey52)N/eGV J ycY\}_QpL88gu#{L2o+R@I˖ ٳ7}R_̘2kv믟yY_z*&&*4WU/T̩zg_@Ϙ_v?{qs^jj* t(g1׆@L֐!]5Lvᕗ_uΰDOҰzP48fnM#Ze+Q5ka\H[⿇4Q˾sfgT~}~ys(SUU%n mW겮)/ P ٝ* "Pݦm PcU>:U5 8/j "Des8c_S^?^>{ww>YI9Z6=h8|bl=p Dj"06%jĚ檖jjUDm$5AD- ǩnimh֖eOk7Bq4Mn )a{[Z:mڴ)%%;d.G ݽxz zEwxܥ$@\t_]\iIvۣ6b=b"(&*q;DJW͊7Vǣ)Ǝ4/{tFLSZPfL1OwO_Y״_U8nx\ɾ|9:OrN*0몄Ǯ>N4"P~lBUˮJSf*pv?hmuNESl-ۦ#0cu{ܳk;N!57 W^.: !T b35 .[#V RRw|0g^ԫ-7޻LP )@$$HBH%wS\pWٖlYV<'rO"-;y<@ !$hN/Ҋ6@8#c@Vq8itlT"b-\ҜΘ~qKƫ暫/ڼp- p~6m DJDRH k|§|viBP1O.82!u7aZNIDAT &!=cY7|SN1}Ff0oi<陁痄)UEQ!`D&]/~2Eɒ%kW߸nDw1@Jb 11 IVC] "e$]S9庡MB[Vk JKLkՕ(a6ufjoC#& {]2hvmgsPtՊN9ckcw=˼an.I$RUՂ@ H%{J|rO4j6+!69)08$whz3R3SeyCK@3`wMꠦVTx?@䆮\npCseRSC$6hrMvn.is~|ɕz깳OMrPKY(%6P طso3v`8 /*+?+I;=4|^@kkA~ky/˷ 6|DfŠ=;l,,۞{bkהV7U|J(`OL׀M-CcD:<:(%eu~;qxѰ~CG鲙瀁3ز~K!@}gM!fƜa9&$&O2 ՇO+MHyDoӖ;Mƭ;}L ٣޸a&֢mEgN9iѥM BBHt=vŘ)ؿ{ws֝Co uynicCUElGU~j'[x5;=/v]Y}_ ܰ/oom]ɮ=gK)ݻybwwI^nA]7qZ84R>gRe5yXCa~aIל9_ݺGkqәەWョrϹh' }j(rl Z=e}}5%/km6JiǽoNݷp}f`s_WHê; =;S_M_=W_Nvׂo`YMg^]qgeͤH=P;X+VbGEK~; 7zm2$oس#(ošqs*Ɏm5b|z;qL< HB>-^56]9=9}`E|/neC|;gRh/}i]oy.o7xH}.Y>+f.'91e=m۶rժĭ[F"ñeYSSe˖3fG@BDjm6zVmJ։Lg.?pXwӗgqӸnt492=-ޕ>qLڐ\CSBpO9|t_={sJ5_;6{2]4xTF;%#+)H5t`FG{Ǚ9˓N?bҌq2]Kg>5ɽq5{s~/N@'(rWgصKlj7FOp-2B uջm2c%w53װgcYNV_͸"-@Oorx 7蒂0w 2!unNar϶-zӇLf\鐶ց@1郻y+woܲ%vpn^۲9M۶x%. 4%#3A Sg7[qY:bbr-cPXiZ]435\s BQD)2WI?H9C# i_&( %BNJ()P k"(|gJ>^Qz mZJّDB"!#BDCDm3H>m+#,ڟ'JZKN2-ssHm$z!$a -`g,R טݺ9 )h`m$P ! :-z-ɏ9yy NSJ XỏSͷfݦirΣjJBm;&&fGU yȄPƨl1F BHD~)c`'phVRhE賁 ) e#^mHBi4"ѯ5ᙢ(|;RJ6uuz;0H)$ B)\SR" ڑ QH$~%v~yቹ+{=k/cKߪ( "cz_&wƚFJz]8~R ڲ}*+(RZ9z%rl) 3HtuBާML;Zj6.)(l妑#$qWHIwVT2X`f)CgLHEl[=:;C :7-^v_˗w]'_4w\IJf]e2hCn'XVg{у D =_;#LJ\es2qݽm8ʼ J0[Ife:yr]4[-S੧5VM9[S鉘|OrAl/w޷5+o7]^9,_NJDRBȃ mkJ)hCxib9S%G$GR!xqD(?ud%SNl4eBDNYE痽҇=W[9!EwU(ӯ:55Vכn -9]̘yRKthN-%8 }׎_x_^1fAWm}qͤg8ʣu"b_?|K~`-0*+vϝp;.B_ e<$6~wx]ܖI}d5fl\Cw?\H>a޿4ܴ*#tϼ#ϻʋ'$?v >;k>/ T›%a.Ҵw[vDܐu9.):󔄰?fgxga+6|2q`h(_|rTɟNf*91$7l~AEv[-Rʨ 7%:r.>otaxκ`xt]+ft̿<"g5rv-O>]c?q9ApƢϝ;o]I8$ U[w7^ŋ/ttEQ F< 佾JxҔά'ii挊*lj_pFiCLW^sge'!Ӎh _@Btj7Wkd{L$=2ɒŶYXn0-K8o&NdƖ%|,6S&egxGO1{Aq\$ԝʝ_4SfNP3oîVĔA)Kwa,5Hݳ_iiz-63-Ӵb M,\[DE[sv, o~%R07,w$#6pJвLb8|lϻu$o?z۟e_.-DcGU"%8\ڞ/4k.;B y?d' |~Q1Z{|5͑oo>u]+(ǏHaRgGڱ7JV;u-(%@&)̰e )‘ NtNMv Cͭ*"HvK$ 0.7Qq%KC(=N`+LԌN"5h/F;}vަ-`цU66޴!5BJ4m5Sntٵhcةfk$P NZn JH\pS}.9XWΉp9 DĄ̆Yhn(8 JɘK_`ڂߜTx߈RlVe#g!P' ޞ3g{cZו7b$>z2{ᑛ0h7%Ap[|轌i>nHQ|v>e߹9?yYxivRfֽ6czϽw)_!'LL5h)(J0"رy< 47*34[s4ֶMq5m۴Qv讠ee: s-n  @$3̰%d2#H)Cy&m7$hkxF;D;q͊> qBt`6N D/5jAt#`8P$(l-&B H!":ia+l/uJT֥ʜԴ !BMܱ}c5K4]ci\466Spcn)Da?cQ]5YO ZwJʊI8!b or7E]QJ;)L 8_@8 (<1.]wA 41PZǘgR*"aG.ʬ^=g1 ll%}iGMO䯷fx.iD8W;$MAĶCNӫiol H$e[s{DlbsMX2ڶ}1sB7'B"99G_sgp4v3&&}754-(D:milѝn,[bM##m3_BJ˶32TmXrsR@@DJL#MZq=)ad$v0B!FQEv'@Q>a[[^65kؙRPݑI,T]&\5%6=ZRvl4fDOfy}Mjp0;]MD+=QQD7!2i1$c&H4[#K<:ǃa(ڡo \m0ҶCk R"ao0ƶ#Tw|]eKNHQTB4[8"K˃i#3%3Yp%;*X475$I IΪb1J)ZZz&:$}(!v(>;u9NaccwX\[\~.kqppzH!TshB).D6=_lW;*.+&4W9e|B;NgJR]c2]ש:'t]Xn!EQEnA69$ל^K#36{9<$&gU_ιpySsGՕI#y]tDXoͺAwCP9몷طûá0zv+6Hఁ|& %p\v *@sz9Zq04J4M3tڱnӘM74Nu g6iiSϜ>yʰ9iZWgZiw'gkrjQ45̡yKڟ_e^,߲bsaĶckٺ5^7א]cK1^.WO7 a|2csωHČ@ 1M3 |nvd!Y{Rsw^Ό!;@rloʭF\>=jv,;oyLCzHُ֞5p5x3uuՕUW%Vƴ2[eňe>*цrݙ`',,mI^s4f쑙ٷVTL4);n^S[C]OD5fUQE9>sow>(nv~ف}FԋV%L )*__Gsí _s;O%v'-^5ql3>KfJ\m~ Kթi|EE~i~)5>X4 /+ׁ}tjL' o 7Xü?krBU{++p֥!WѫoӿӠ n\'bM!3V=ۛy铓X$hZmI[cƽ t߽pټcZ]{guR}nݓVSRS3]RSEQKtwJrYb׮꾃/dP.ÒPB265tGf 23 py4Qgf9ДB=F{vUz\4d.W\ϴa#3I0652wrdws+[:=M,@ݳ{*窫.bM5+ۙ2tw3͑j rKS iKJa ,(t27lJFhL|ٱ:,{Fkn޾; NKiKtď0UqAf&e6w*fBz8 v 9gw-b6F`uE|ߋΝU7'VQ744tʹQt9E(l31Dl4 ˰?d;nD MSf5IdžXW ";](`(,pz Lp{2qil3FtCP_(kLy6DyJ-$`hnS"l@prBHNw9)"AMť9\# #V(bh4H mPh̠&e j,YVo(nw8:0p8@;N]gd8dxgpт/یFkXRBhX'=Kg Pv2ŠC&`!D 2 FAaÆ"iEEN#!$sorTx~=$J<8p-ωR RJPH$Q"@G=yb6mYD)e[iE)2F@HI(ێDo'<EQ!ӂԇn:rTaUqP4rKBېNwrB$%yۈvDD8Xx_;OEH)ejNyPCJ)(ڶ?ӒEs(%׾8Ju.s9Wu6PjV(|DV,dM5]^mVCC4&snܒ[Q 5-t`{J(((' s-hW*l!Ltf5X-/i@[}=4M{wn߼cOC;E@)׍6:g(̮*޳cg~]HpΎ^JG:@uц ZU?{9(H4ĄF鮲ekYfs@F_Im=}V|:7Orٖ&GB(eݲض3}WD@PB y螀Rv,G(H(k_a[_n14aiwto=z߭# rͬ/Xt'.-7|x)E+{| >x}ygk?K8~[kT<&|q]~iDɊ|6N0̈́@<ƪŻXÇv PJqGzI][o~b 4yyњ_-[?C3W}w{glk4vtZ siDy_tɚU˗n)nw@9 _}m‰#veR`ri֖$a?58!B=mw2@7/*-/mLJ)j1t0@((H @=Y"ӴB)%J@nP 2h }@3 v(ֿ((!Rc !u,aMU- U?x+y_]w>~rT2lI H8|ޅTkW#+uy_K_:>xk_bJ(g? &TIK7 ptJH)ғC+PFť2[¾M ꬞C(l -ٔv2|`T6,JږM9ܚ.ҝ[{?'i)_yG:ztvjmYklٴœoҨ޺ w,[r4göQ}+('Z3[F0{ t2L|Vu%h6.r&jpYn|aog% _N]GMs_;2Q@Y:vS%ǨYNGW!fecYS[ }3l Nqp0`ずZSVYU;8Ӹɭg˿39|PFff&, ~mـn.D@@ 7C:$zM?gڽ9dQuНܛD¹#~ou  kt^Uov~naBv@h~sM>r{w_9g~lvOJ)_L~?Ύ==M|k]cۺǫ|rw5_y]fݶO.Ϋ7|dt%wd/@?IQgJJ)BH5?"4lE[L K'b2XwڲTotM+V87xlTMmC&W~_MRǘap-KheP}'M{_^tѧKK.}9Rؔ \]fO_=?w z΋<(lG^{卥aFm"!0j5|rxS"R d'y!Ҳ$Yc\3zfZl=YZK/J>{5+_n=$_cE߰%;Z v]}_&WΥ+ l|+<~e7}7<ػ#rѵp>u?+;3|2xI>SWlk%e9My;mxPM_9;~ם}d{%9hr՟-SM#]o+0:Oz~?`ksd"ÜN5--!]?G7ǏDg 5uz/.;>z+?#)u1 P#J)w w\b,/#! 6|0y$VD5˗ J7 hǎI_^X1i2t_RR !G&#4,ڰ0,U6<^C ='a .?Wo-MN`jh(?S@m]G:\1I!<.K%g(v0b(a)pcd hZSQ \ ëj9@uckuB(=\{?J σyl# Rxz [Wrn'mِ4NkV-K\:pM>g^|^Yd〈ȜIgt#?u;D!l!6d|_𷿾x G ȰiVR@ᠠ › \/s䝧ƲyHۭ˴/Fho !] XE$o˝RXȶUh-$ Ҷ% ; H&k"N:O;uS&$i{ȶ;?Ρ(ۿ}ݪ_.]䫜t Fq=#s^JBjjfYR"v$"3jCobzP EͼKZfrXîj@ Yo46; T~;Bl@ӹ0!" EBFa܎g nyc (~_w}_q*LgϿ?/֔2w4`EWMR!Q醮1Ҋli7uÜ@μ5awRV,klhԮɱztbrR@!ֿv;6vIcJmK phO(L׈E5M5ED5MӁ@Ac_<0CZK cUC phc8c^`8 kh5ftQnLL$oϬ(F ⊆3o^߼&'*EY"`i7oo?B=Q1Vu2 J%6!!%3]|kmѾڞN9_}oaq+X=uڄ>m.-nK!@sꪡgLЅ(`њ/rJKHꑔKLsRQYZҳ{'6`İMjjzZj= @ƨ=EsB5Υ ,pLy/=53Aa#g&PJ( pf Z%; Ϙ4 `KXd›AGnK:m^Zt@YBo-.)-/?koJ(>PX\PStuϼ ]]_vuo/S.>`7.HSᾂں=RYAJf]s~UGle-xo/j>pƩ]*u(?_ei-ĉ4Ǟٰ5nۯq͗Mg]~x'_/-]/!q >ziݾF0_u/o?x'~E^c9-j'ٷ]0Pi/W..|wa?\ 1%{w﫨/޻g-9G+J|Bߜ.6qy5eIr9_κ}幫>[+/EQ~~M.[לz= ˷b˾*W s5@پt3-rF_>.%t{uf{-E1LYAZHTd<&G]SI# Yݤo.} ѽ{eeeߡ%%gJyPFkv#tΨ^%K훪oߺ3&3;+3#5u̔u1K5K0ٽcZs”Arﮒa]o]+wlqIߴcA<.L9}`!FaΞ5c8\rϿqYhFQ5BR'!|i=;6oڐ7?|AjIO ٸ7qԜ\>-a.]8u>n"GMQm]^n7޶-  m\)7__A[L@ ИΒ6nj ',sTo|iސ$]:^3&jߺ!$q\nAaiNuI'M6XluMF$uk(uNqR07si)_pٿvFOa jdv5rSFt08H:@7\ H='OhXn6KӅ-ڨe=O>DӴm ڟ`(@H11L"R )QG !v\6۴&uo5R:7G*Rҏ>l͚}Έ:`Suaf[K%^0Mե׻wv^#QfiaQuڥWL[B{RF;!Uh-7//!!tFW3'zcN=W o17(9V-y45-{!#+1aGB(ge۪ 2FD@'v&L@mP !eQB@aE?RJ@(~1ч}EQ3m-B>`RHBn躮qf&HhG P-z묽811n葺k1U?DB(Y.91æ-3f EBa ڕJptٕ4TAT'EQD.ׯj|ZցXmZwK-Y6#!qiY1<8X #۾Z% p> #30Xxɚ:ੳvM[|;Ddn׮Ylz>c‚0JD87ChqV[VdL2.Q@Bp}C%PÝu ۺ2=oG/Ml ڒnzWmk A9AiΈ)TT (5v3ձ.57pyo5%?4 m aKڭK!$"J!8ti,,h@Q!jPEQ~$S%bԴqs.x`r@Ц}H]t88i{I;WTϼguY_;NSnkW<rqpaz%t ^xaPQYQ!yO\|7xkCYXʢDc,̂q_p3}MBaszӼ[_k~2a@iϾo|y4zh3Ȝ~_ox7ŕeU$o>_ T›%a.h!tHnCE|g'ޥEgLXjI5(Xe 抋8;:iiOLL/~EQŸ((N+lI02e7Eq\2Crؽӭ遰K'k?^[g84 /p>NIOϩM-h[Eyꙣwhnjӷ@Ŋ9F9"Mki&kmja>1>mZ}( w5+6ERt#yx]{3krpO?ཏ?|Փ-6}7=o-j:]T9w<=ЭWN/,=eP8we]/9 @5d›CJ0<僷7g!fpSN9ʑtoI/=^z{ϾA~tpH ny7?]+'(%GzߺU+-Z[rauᆯ潿< 4((?M(:}yW8u`ZiO."Mr%ݵjͶ"$:!vݺږiJs`{Uuw@tI'fؔEK61I.[ 9 [6O2h!Cdh;Ji{>{sQQGLa䚿 縡C 2h@J&͜z(M6$;# 桤3RfOڰC ҿ[FfGvlҒ,bupȦ;:7'5 J#R1LBFB-})J+]@@t0sV/Y[Rٻo54 |Gp?ܿ'-[ܹ5EQc`ejϹ#,:P.u'HSCEMRR\]ѣ0z88hKjEԕsejj7#i9Iso`RbʯݵH(r>]Q')@B`$k"6(F|xp  @P eX-1I3.8qm>W3S2sn~.y_{;. M!`PJ*[γKo|x_>IssPPH>ǟN5{eo??JbRg_ss7} ꣗_ J B҆'i#oyg?%- !` ;6Cs˲rQ7?_ll|%ǻ\.@3,&/^)vQdT 8uRWJ P mQ",Z `Ҁ0CMMaKhv5ˎP(1"@ZQcO=u3o IT ]z]`6,6-)@M!Զ#!Wz dvDw|ZblEE]*-ͦ'%KNP̖戞%AB=00-`7XҕL;g{~%hmnsӼy`Dv(V;o#:i}""[ykU36,8%6X'~4d7\nNm9On̋qIewEt֭4EkSsdCQ}Ob*Ap8GtjPK澴(aXX[ŮY]2m$LIu9!kƹkk:u"!DV;σN_ףC%D躦iaUcEQ7n٧~a]c-!Uc6n_ #+.-6#+6jϞ$.n(.Nٛu[!k;F=ž;Q>G]xUzX( tFoB Z ' p2RJ ZRFOhG!C'%=k1M74Fp_\bvKu:fĴ%X=0!ڂmkw[204(- }񉞄>Z3{厭X/ WTjƍpѰ@U>{D_O@$Ҷ&%4P(󉣍ݤ:Nצ !'n}{F=.`kK%nyXͬԭ0ҐƋCtѬ-K{c[c33f-_]e`͹ZJXy+GKԐ EQFXmlF+`L׃U;}gc|hoYiU̼Yi'de4jy ýκlf/wmSz$ySϿdY=9(uUc|]c_e+?ܚKN`X@Z&:f/xfL@snrMs2 /=yl/6Ʈ^$GHOM= ݴ}{KLݗce-ڐ6I#XwkњUξ꒾q&zQ~ų}!##5ڔ6zΤv06}a`ܯk.Òle566z<%&8 DbGxiڷd'{{ ss**k_vnX$4eU<^[I ̬lG`Β$o|rzJ\fG- A;jҔ[S9BjLFj(]NB.rrrӮd]Z7rH('o539tD-\53ohhޭiY=s^^^p8)kS8)%vrl:Gm4à "PFJ 0iccҨ1#ppV$ؤ|f8 H;6VQ;:Šn3wn`A87˷<'LHo|c1*@㚏hjl'KλO~ބs J9^>fcn͕sʙ\clz7)3a8}J/>I9Gy9+[ï>qv;8K_~ݜȌS4x涇>PvH$›p u_,'{) ]OY=c0ڧ8 E$vN;MVcM G_SJ6qԠbEQ' r_4iT7&y]=0V@Ū{Ğd_ZUa3-:%Zy]cجS/%P^Gǟ{f;~e]Th~ 'fq\j$)Ab/~?]oH@4YW瑩q)hq41 Ie\;~Ke_,oyg$/7^]SC .|sEM$>hp(Y꫋|<g^Y ,zaiìf&]t9_ɖF pNn*9Q@ڭ[nTXʊ s&+ʫ0--HVG PΉ@y)ۖ1ZXSVZ^YQjRbW(k?Č(򍢣m *l S2ӼUkh]9}& پp>JQ"`mY44 c*^hp=4%$+iǫm`-Y\aqfʊ(;>s#}r@ &NЯKbc AQ.ڸ1 @xNoR=+WU^HH7<+v'pէ[}=$Xt01hlB(oժ2_` e}[_Z72hE!yȥS>~z^iԶ,dDr7[?tvXDˆ?gӯ׻5T,?zs.{uܩ7>6D(5;ғ+( B yi/BPS=.J*%R2WDԄTq^=$]bJfREEeȮ,m8/H 'p'0|Wn}`^cPm %Bڇ|>dQh[Yhp@ )eU,m8Zť!h(-q^fO#̪U@ԕ}Rzf*rz %wjD}Ob* 3J)R $Ɯso7=;5Npo:rNu/~/ =AϩukxEMw)\wьHz5OM:pEQM4璦kg{1$/ÃӲiܱpGS'`uCt89ފF V 4\.F\]s9 ;uDOiU T 6 CɌT>v-O~t "␞DB"M>龿>Er3h=&zSC-Mhq[Rh"NH@-Z SAt N[ض6!8k['̺pVc}qTʜ]S[t:<":)銉H)qOyi-ٞOZw:M-P 85:mEm'bt5huhM m@tt#["6mCUT)ɔӴl۲gٖe ) 1i̡=#؋? 93MTn^dj1rh/Ħv \tB?0@CP ` !LNyr2pTFQPHU-\)'u}t2@)aG 8KJں0%V0gB[W4J @ lswzJUh]b[,{jh )1>3{N_ rڊP Rp'ʼnH"j$q.ReYjX%@C~W\B 79#ְ Z"H'*?|Ϥ^ofFFFzZFzҺdfb 7]hwr${>p3FF-}ދ1c>qR%FQF8oJKWr_ U(1!!}]w{1]Rb4 h,:RMF "w(1@umk"mOlUm%_ ؝B#?SGjR"a̮U'"& sX"ڶmY&8R3}$fٿaˮhE@1jP7cgo)uӆ0FZ?+KCGfmZ#6xlhK]u1p E[Qr2J7?! %@l݊^YYpj#_5Ap͒/rl6 [*(X_Xϙ]x$-H%$>w|5 EQ mYeYB}1?ks|mp4jm?v9#/UZN9}D@dw_0;syoGrن` <>ޏߙ@;C5 @!P>;#sV3/;;B)斠hWΘi4oU}S.xG^_bz]p-U"_m>9Nf|ڵ,Ova0_Tlhul]9┙ ?y~́gUd ]μ 23{}-o[>6RU>{D_O@$bFF"4<9@P-)U۳e͹x/L@KOwm[rO 3i o-:I=(eg,Uqō>oœw7=.Q[! Yf6 ܵ[H 4&0i@(խ8ꎍ]r-95"+.-Ʋ,98sϺ.nۚ1}\ukv]:m}L_U+TBWI P,ݺL?m0cb{۷gԋ/EX&↍PzK^j}R ˖a)uu.KӴ`;B0)'Q9"6Ff> 2aF,53='e)c$^'mKi60!(Ҷ%4D-+ZxΨ lPэ(FNiZQ6i3AJ)PJ)! D)RF02f@0- kjVƑ(%H(ݵ]iW\24h"D)rC'e dD g͒5*)] 14;-Ht\{g?"޴ΩmFlY Q RuB@(P& @0F̈ iF,)Dt9KHHt:RJ zcN=W o "ք('lRFh['!G}czKϽ|nYRLSEQ~PvCC iTD0lzϔ)eN;= "ɨcv)I(( 㭌 *9;#ض G,~REQEQ(D4BUN&*@" !l+#A$!̪?%BJ$@ ,'7ҩENO !Ж?@@5›A:-v'A)qKQQ!Fl[;>J 7|#aۺ"k%v8ܖ-5`cRZ6~MrƈlTjk LKxF2ͷؾ&ljb{›Ց B1|8uy?fkkX2EQ~jPMgx% hyl=x. ; F0 ʣ5Q"pCAˆCjGv|sF*v|=8i2 PEk˕å#/~D4"L^!kqBh+}I'pHmܶ&EDvh> mHZbD冎=^}'ЪbxGD8:/i J7|p=cH3ms{oTxsDjL{Eض4ͯ?0ꖾ*4""'| T(ʱC)uWl7o;ӁaKJ0í D4QӜJfrVSiw Jz,*L8#+;h14#w/׿Lƕٷ\xa@1^Y΅\;3Ik6mٹVAew2@s­oȔ F!h@Fl5C!K3XwpB:"#j>KV\< eu&0(#"Aܥ P)ldAeE,j85iړ@5Q aY%Rá @D,)T1CDa\4" } .NDL!k(0 Ž B"J4ZH(%0{5f%k"YsRSqBDy0xwj*~S&{zksSw쭛<1U YtZ Gi8r3+|v#aGى劢Et^lM9-9IW1mbSum|Ґ9"tΆMo_z zuxJߑ \D+K%u7e!Mq'3+?XzQI 95Hu 4M60 ]7Ҷ_wmx\߯e̜X^sR eJرpˁOo2|N7P׭{h}Ӹn9us?4I)P+P%a<܉)v ?_T%t%`t͊ +~.h8o.U@d޿Ս{[rjC6IDʨRT "R5[ ڟJRy] VB gF ̆_. >dWdݟ/q1$VE} iZfٲEkE/wcӵ쩏KR~u1v 6e|ކ0eDJ=ͣ@EΛ"wگoaZ턽k?쫭8r#}xRRåx{3GH T= u]-gL )L7PJr׿om q/4BBؑ'@gt둑d6O7|䀞( ADD!p3 ²,[ )k-i:(lӲR(0FkV!13I - \9%RX%' Ls ˲TK^W+G8*YrDL ۼK:nrt4n{koƙ5zl/Կ^%mg J]e];3rWkqQiaEJ hDLl" N)l"Asa{qX!G۴D9ťո5eB{?/oFDM寤ʀHS"2ӠX#"P+w׮k{K>5Y[.x+o<ѳ7v5}ii⁧R_NQu Oz@ϰfH~Psa ;vxrf9n V6uǯzs>YtSRs1xիr'&_п㇖v<|쑧w'?}yNڸKw(-\Ϳ?vFPȢkpǽi5cqk/tD91}}/xDÞTxsJMVD%eeN 2mz;Ҷlۖ@B ҸY M5 ~[ap'&{͛M0|>/%% uPcMEc&$xpN'Z[-Wh:,vMiam$$5%sxKmUCKN5̈ 43ObJyw#ܷp{UrZ?z^Z;Ҵ ݮ};/ˮ? yincn?,ݷpj65;n:˲-uz8ޏ83OƆfɚm̽];+$h7A1&25eq%zbloRj<l =82*9u1;gԅ $$ ys}tD9E݋_fCn F́O.3:k.笘8kf ьS=!\ڑil/goe z{n^4&Qbj%r-ٳFz(U2i\ 4' I5̕W5a=۵G2\v@[ ƪf@P5z ˭ _Tmhu?Į vk>^Rs)Ympj*Zbm祹#9]TdlFC>]|8%Es h GBJ!B6pYB|rɠdoUM'-h8sf߯{<(%BP0uOL\c}YU6˛5Rh-ycLWձF ؽ,|粴6﴿Zz,,jJvjo.x꥿T0bOsBٽuo賯3qypM>oӞm_.[ݧ~ۍ2c Rv4ޓdaOVB)pO۸k[6bŷ2m5!OQ~D񾴦w)Q8bI'8t͖$5/9.[OҚ3B4w.?t}*CAV[ %XǍ ]n0#ZS^1\mV{/f#1($TKFר˘ti)[U}zI^ooۦ(t=6zyC4%ݍu.cV✰`hQ4ie\TG-y{[æ8bʛV9|ĞriG‘m %;և^Kg O"RMꕚ恵U;o 83.WzgC8yӴG_̻ht֊~ɄSϋ,9aܩ9|?t鉟K*]rRfڿpOQ塷zr7fZU+@H[Pjv].n;t^أ, MTMjryʸS3",% b-`Tl\>Y4E @*pͲ7wpgo>Qu Ĺ@XE_է٬CDJ@y}XU/g;?h:{qS{J9/_x}0%!aW`*ƣo~VG [ 6|UreRe6,L>{nʓy"mSLY&gzPuSsH 53'#->6kkq3F-Ή۪S#Rz缝9W7:bRn[.zUIq\"("CAKTﲴ47=D'>{F=vsC7m'єt;ש=iG,ah5kϼ<1-bG!80++okK)3E Rzpx]{LL:2&i!m(ʫsÆyB{JJ 7o[I>DH5'k+wkte"Hfm]O5noO:_z{)@%ʬ?B0-w\Kn[nq^aIjn}7M_/,rYzum`߮NgazgvNe*6/$>Kk;47v}l*G ~1i~@^?5/~\V̞Ju.Wz]4<̆#e66Gek|1g{^u?.FAjŷEO!Kģ;.׆9d.MXEQ 3es!DT,[Da3|󞹓MǡnU:Y!=|㣸˗Mݷ[ƈN/Mw1kW:U!tCLz <%֜_>`D736 Q# 9~'Zu_>+ň*'(%BD_ X4%\uQ~# 5HZ.zاТO޿?SBhG8i+^go[X~ \駏MPN_Ԧe Pii1PXL{zTE޴c]9sRr~2:|ghVnЭa|:W-7?pO'6:\~n%J[ՙ %R7\~퍇/WysF#u*檢Z|Nϥ>RCNs׏ H)Z}M 1<4jЀ}x3H!ڳZ F fث7 BiDWk*sW/~2qW⒓YAQiԌ4&n&PRyff-ܲtPC@P(4qS76-)H|΍wDs(,߬a!P0ŏn>)4aP0TQbZ"[J\j#1 E3~ai=?˜4t5sJsT͓r~p/{gD Sf Sռ %>(xiY:HW^`Nc 5Sd ¦nZsR~: :W@'6o|Ǿ1'^FIh5 !(^o E8c۪!!>.ng>Y1ifY} [5oqd=: ]JumWں3>F!Q7 KDspD) Ѭ7j58OB3.^4a@J҅n@zGva- Y63w?ͰIݩ8'w(pFAB7**HEAp۷᫅}ᙏF׽;bYBƉ0 pBs9:iu=ź:)@Gؿdܒwݝ'LR.B0L&rҘ3^y}wkto5v>y[w7RElAQN=fouE_WZ^Vw84 56w>ķ}wi"a+[W).{B Z@ բXpRЈ!^E0TG4vwѥ;ca?(XW0 ~db2Qٽ-T:D+h pnB̒QqنǞ3WBE}SA@ezRn(%0B(*=u% YPq0i{Giꙻ68c oD%~\qOʩOv;JÓ=$Ž:l9FWJĎYyƪSW E,)lSWS?j 4{K{5]ֲg ɵngݢiNO)}AKY}ѕK5͵MDQ=ERBHaCzS@IRq8,oׂ||Co趦OmF&C>1z%cHjM5K'NŬ T2srpƹ52L4d"M#MLȎk\JtEEX#OW'ګV_=@Mna  q3Kv K]dWS*G14-my`򆤤+J\>cɂ7)V` /" AxnEU%&}0V.W^s5j'EP2N};ccMsm^}Y^su#烯~:g_|܏e SG%4mViиKJtxcƞvvOc}xï.?k E3`?I>q;gehh8mݔakl!Ni~9r}[^w6ԛԿ?_=歅ǖ|]2uּd*7-T_ޫ/ }v~캚PV֨33VnY.-=Ž=Tp^}s`n*L;yFtfny7,7U쒁FAXat rHg潳q' m޽3blv.'^֧}4ܛuqC~ѽ/nS͊G5~D'125RW`>'*^9띫^߾Wu<"l̢2m_ݷ飒Zt{ ٵM~ j.zV ;jp/wQ^(ZС{4Lpr;81ozTtػ} bհi 5o'-Qq2](߿y>$vQ5MOªݽ' B{Otۡc *uy+ҠrbYq' wg_|o}ǟqG w=^[z>ЃO) Q3Eq\Ń}a!hNq1kڠJT⁧'W+⩉sI^qu\WL6% Y*9kH([3.kͶwl]c=g__]7"/(!aBؘѪ(RJXevic۷KHϨ.o>B('zٷN) jo[lE~p̐1k_z:w1#5߶c= ǐls7UQnٲ s~ o?lHwYw s~SJ6v 1vI<[keLԫۯ._+pGr!;oY+2ggߦ%3]vka/rlO^o?k1J|yK 7egz}o^ 7T3g2|6,f߾UsW\?Ǖ~}R;qm] J[F$-j֢{۵8/g]qAFֹww}|MʄЍС ل4A5l_hJa_ҳb-4mum-ʆ:#[Rl2*<ߢy֖ _>,!*l0Mi IB{>]3ÝyN =: 5*VٿKM{SY`q Wg:<}ĵ2ѲBj3 Zt\Ѹf6c̘GtdcɺҮݮwO"t;@A^.d꽵Z}>+1Y+U.W۵=Y}ߺN!Kq{u'=Bw H٢%ūzqS. h*ݡ飚羰tZ5-*2u}ڕՙka>4Z_c{ź2~TR qmZ`$8G iZ)MyaȸQogLmn硣O~95+(2e^}Jܣ3vɮ]˾K$D_zo{IsEn߶a>'{b}E$' Rݽ VX~snsnl\ 4?3ξ>`Mc G@C~/bs`{'~DljE^3J}~}}},4ϡoogOn׾kM.]D\q`KꁓJ˒LQG̀yc"Kp*-(@ /ZSgV!ÒңDX(rh<c V/gN:ѓ҃~A4 Q^Se&-amvUM?xPd[ 5lXd^ש[ϡC$9DDRS9moJ@gҲ\8^C!85ޝltgEWPt8dk(zl tˊw\0%q'N%&-:PJVɡ #U?}9nEwZ/!D4-/D"C>+B)ARjcs()sXNq{%ic!?G|J ($BĖDFD[ @n0kPJ]LEJ@z8"\*} no QN0ӌTZFJ{ҖkfF>RmwDyPvǂ*_x BMqi-K0[KBp-r'QBD8TFHaݲZvDWq0k*՘vъ%N' F ,Q7x)4 hY KBp:5iaݒxHWq8dCY!@(e͛c[9 4&v9gM3Bmhc~6[$q85@[Ә6 h;jpFǵ #[ncsTCEsWF;" aCrvit/߷-"O~_&bj̕%._"F?p;`|h _GemwRDk4a!SC8BZOС Zm4#жm~PӲ-sj58pO522206ԃPlnl?a~aK PL3Ҳo/ *ݫ۴2Ը杏TPvlccs-ϐ- P?F̞´ZZ(c5淂1i7ciQT7%E89H߱m^REWGVTq2QKͥPvM[1R6Gn2?kBׅmm͛_X" uÔh4U8J ; 6o~ Dd wOimBADsӡ*{i9Wr"dl؆؃_j3Efns;X6o~Q !Zmq0 )HiɟV+(Dds[|-M]G(B{K+ȑ-*i˕"!6mGR^MiV=4BT]PTaHV]S/|83f6Ϛo~UKئ1J홝[l(rhw \QUH㪪 cm3 0(؉ 8VRVj{$"aLQUUL~4GK[e\7"D>p#Տ)՛?Dv`U΢< jN:ax0o+WN&\h's>( 1usEQmX*_0 MS@8)B"a kՖ=]vEVzE ; >lxBbYr;ז)c]v2˒Gi"Q84߽`"K{f/Y( %r"5=9羲k6+ όD$a3iY9;p}%;n5ICFMuS˒@(Vk2!řu! $du5{ciLrknyrk * 2G]dP"5vDjBw8uTwA__ D¹ٱ/|!CMvɏ1 E&e}yu %gikWz;V2Eơ5dwoG% ypNnnyI#E' {HiDY?%c}:mvN{ּCwkvA o?t'ϻ\pn?뛯Ϧ!NmKz['\v3rt9șąiCN g7QN(gr/|7a {+B1#_qlOC `n;6wW~wɳ0tWJ`60ZM(sP1"RjݺAJxu]' Z%Z365֊#a\ƕwlz1ēuE}PT)Z@!gY c/޹ԬeNcc{_z>ldJʸ4 rʩSV$=KL|v \cPn喆\'np_e( k)2v 0ּ'p=?1]:x῿4?e\̄(4qg~iQλsÆ7'Fù ޙWu™S/Hb86yALSXD ԙ~= 1N1z݄,Jzh,)閽nccccsl`67n05bR:$ aф:iHJ,0M `/[!;QA xzJsoڻ&"Hd eJ6i!-o^JCn㋿^iۼ)-{Ka4 ТۧB}^Rz4*DbP"}eH R_K:Nh`GL%v|%:n>8wɷ-A*Y:@ g^"&GE!xaڗ.X6m[ۼC@l~;MCQp.]t U3|&WD .-ٴKCHgccc(e˟ݻ  ybG *DP%NdWQ茋!(bݙ1孧"@.ܮ(@"#%]Z|EuBs)112dZ;Ň^rˊX2D"ܜWpDV2B+j($VH*g, $%'1 %(ޘ8D @m>aeZݡ&P5(D ē[VP;6ogR6P`Όx7V輑^Ru ֯SjGb#3m})'^tݍ?Z 86666qEo?ςPa OsN{for˿]=kTA3P<_9fXoJ%pUqDjZ榰sR<,6\A˩R$h񊤕aӶo~ZN'o=l|M(1N|WwHZe"?jTѢ++*}S^QZgK!*B:(T{'7[c 47V)8olxc}ΧUIfqV6%ؓcۼC=쯶S"NH%=}%?͍x@;xpaA+@JbЬo{&aMt:P™V̈+xE/J[ pbsۍ.NaZaBT;Tt]O"NPxnp8ápش,\K9kƗz}RuyH$n+f`=@ .عhƢm}!Ka@/=) LZ,:9ovO{nc&Gl ,{S"pd#BA!\ .g6ek4Y̕j hdI32w^߼{w("6K~}?/>gʲPRp%Zuz9@ЀԤXs]N^ټ*r5f..)@3 ~j _[K&1  'hB`lQ7iNލTm@ BZ%#*:)Z5a D-GR_Br{矝4~=5bIdccc!OQakT "Ť%%PY4b$ i )No3ZВ{6m{ j|}nDu;]=z7+ˠ8 |@7:eJM!&g1`Ss70w4e e >g@a,'1==qH( iĴݽnӮ:wre@aZHT zckL-CWT-X}^MU@AB3DdcPO}};e~4p5u&L e}9% M]՛?aYRJBFQY_FϾgwq$4#l(M04J܉z aeu (vky߻??c)\QU8=@vO6+$ի2vw=[QzIU_Qc@Uڢ qh}N=e6j[QH=~-}׭U]uii(8SN~)KʙE %9'O83hț?ZQ5r /NnͫZg-T|ݗNwe_ͨ#Vqڅg*)8C@öŻHO`!'2/R] H?Ji}CQU -˦Xh*J/].4o*w͘>wg׮ovgX#L}F Ҫ6|1uq~s(q}*7oOr֕sY.lcccѶg5yKWnTSN=>w4'7ojnܻj߮MaZ̓+rZ_t/JHεUcGxݳ(_zGw܀S{Qːԛ>{pךƬ uΎ!@]mo^+ιaf͎HɌ)=S??cW'wK[fIϸnTXTa=ޞT~ET.*}ٙn^xŚUKg-2!ٞM+ɧ%С`gÎekwK9Y4`M˷.5NiӒma)5.KQH*!ġiol!v᪟}׌fߵKg:Lnn~AAjrGCw Ӕa]H$Lq95"Ҳ$e™e3BѲ2Bha`á2!`acJʿ{,!CR-â*kڹbҭBѧnGb("0PFd'(B)@ 2JPBoD9ցkF-!RƢsI9I°MKYիҩ$$\e9Ӿd=aPaI#4%o9E#N#Xfkʌ4- C)HeD@)C!ID`XAUƉ\dkBk͛2oE@"RPBͩ "B ARm96@DʹYWIQ^EJ (e:)Eہ R* E@mB)#/ `Vv1)  ŠcXc*eCe!(B\K*룓3T,gBCSP #'DR8#m&j|Jy;tl]K!P2UŒKRQ: CdкIxBr&J!1E4%FtZBp :F>C)e#sfdfJ4-ru[}vln/捍Q !NJ чďvR`rDaY@ߊm~666666 k%, ~Tjm{va7ҷG~ 9(g_QQ;/" ,d\WX 3c~ȿBeZa]7 @LpnY" D f$PK΃ɪ\`rǑTzOZTSjϔϋX;{#GO[(.8iHcwv(f (ܰuu>3@)̪ݲƊLlkؘ+ukZ>K%(6wӗ ^8st8xO'm) }2CL;7vٔoJuFk}sU 6nvK tR@s8^[q/R*AqUs&npj kP1o;­?wK%s(JɜО;٧sJ$Qp͟o[|06?JNZ7wƂW|˭%U+ݵoph&.f/ U ƍM}5c֊mD葌)Qs*szuR(r˜g, }A,R\%w:ṭ=7x;}d;%';Ң6 QTW7)hBX̏iC;.,DdQPao/ݺer@Fed޼aǠ %:]橯λK?K!=*am; e "pL3 @QXDMvS-KjmR !54 Ef=%KF=[*j|>rH*(Bw|^ qhqc{\n]U8K8tԼNv{;qrlX}7bx3{EPEiܹ.D)j,9q1>wyt}~``S-=W҈3^ gӭ9_nķo3n'wJq]V.bJP܎Xܳ{]pQ!/,کr'S˻:3inr6? JP\lݶ#'KSŋ`+({ׯEE CAI䯊Mũ [3HQF8̑+>Sp+v˱ }wk]C}  ӊ}e&@D$-2T5@}B֥]N} I!!n<3\M@v>>uۣ7sn7bqC/䞥#+K.;t໋ B)c%sxw|o]tuc{XK0ψa6$D9M4TH)ޝe jFGhqLmc⽄rh9<ި([aj1QTD]NM5mln+P_Z]@]*Z+mи$0EZDFɲ%qp\S&Q=J#nɥFۺWnaݲ:=+_V h u LQRDI"Kk],BU ׹A)\9mv;QES!9)$((Өu7O }p8d7_xeW_y[z9 ZM |E &c];oUu-yLy{FRUo\ʹof_O#3)1&_)S_7[FA~=ϿѿHi#"G$U`#:00MS A@R>xcƟхg',ާv4OLրvݯ޻.?3i0];<=q.Bjė'$cϾ>qDشZ66G1a_?>{UUREBQ;a K(W`&$^! ZS@clkCV&pFB4s0֣_0s߻˫s[ѪN4۳kD^Ny/\<5!%*6Ι>wd&H.pxgI왵4 "4 CDB U tNJ:MJech)e-t ̥Yv4f,̔(WvP4,cNj>%*Xpv,ۃㆵaP3Hs2ngҶ^q~mCBKaUm^-h a]_eؘSU@uhsNPi~_u&E ֡B˲Pʈ "PK?{҅t㖚xeW4zyzELl1Ғ'\FQcT\QiQ1VF"v9W_ɷT9nWBP ($!D )e)*C KJBJ- @ؒR QZ"!`D9w]ІUw޾fZ8JuokN. MfBBDDFPF9GK8(޶۵Q=;F"xrE6;gr۳;A(ACuoXW\}BZUJ4ՔȯMpo1ku.i j@H4-AC!$NBPaj)B7LJ S!Q' pF 1gg^5pI~Etv`d8twMi#6oyYYa)û[ɀ^&OH@&EP+\`YQ ŘzBW-2F= Ãl܍.h@ 59nVq*94D)$Z@ zRϿ,vdͶ?6r)Ic/L8$z @'EE9c0ش4(CRaMAI)|Qh5.Jml(J@3t(B'ݛaW'ٯ] aq~}$QYj69xbWBJYs3H +L!p&*V-(Rwf>ןw<>`scO]wMzjɋ/l{ #jLeRhtFnx&}8:F_@хK&3|Or٭{+%/)eCz:_2}aս&4#1UqJ #;#wDfzTXWcB3LSB#Dw!)D-pƜiPYRi2 pBzpDEp4(=C?gNsְUӧG\%;x "@(g PH$ҠQ. 8B))"F % E-kAآr)H(!l ;θ0{(5.Q퍀;樆R B̓aֺ}YʹM%NʤJAX:ϲnrk͕M4Hju%OTx46ɗY9^|kNp5/"z[!t:iZ 2]I\f!Hb{a%+g|Ek2heR_I5M4w79x@،,I (U&UH'Λpe՗:"NvȎҤSJ!m#-x9H  f]yoU M9~l mȓ7$lcsR* (3H9)#RŌtQX57Nu=hB{fY_aEdliF!u,3ET+:7L'}DtlCb3o|,FL1.C/z? {hV_цGchNAByw='u/^7yesŭgܴ7B h2a(@!>;_(3}f2oc EpHv@s'O@ ZJH(tYxs}h! BaOTN|ދO_ucwUPNsB}]_B}to#ZR %ėeIO{˩_SJHjyAI8dt{;)8'ʭ훒2wJkW+p^LFRB.}S=m2{ 2/>I#yܲ]kVmuzp[K%Z2r]6^zvOO[e5kVZաu^!hj^ KFы-x]qLcnM^Q\ڄ;tP&bdH@!4@%yIK7Msz{`9O taMn8CiZh0)PXejUk|ihWCiSv/`^Ash϶4wBmY{胗''Ƃ{w#QJybp}n_sefwq!*~ڂ%}UEΉ=7#B4;j;uobF;(67AT~*盯Dדޱt+ l͝6_uAV'n̕󣏂*;/6nW?%`p”(̟~clmM5bS{|m:+_zB_qվqNRRXBH "p}_~k˯M a=[ݙg버 $!)%85w񔝁^Fq;!۲~PJ]YCA,wPQJѺ/̻}@ L(DZZ%D:ķ￯]qS;i 1swvCVa󲲲8!OK)IBEyyELspbSR,WV`Ts`ҰwbFV($pF-%dvʊ%–'*S pq})Y_^^i@ИI&;um+һvl}|.*ds}Ea ~c\5 ncs@*۸uMU/m5K(͍kv.d/-FGl| R!EpiIҝAKPCWygGE1StH#\__LdufBZԸ"+D!ʦ] M;*Ob_ U{b\ ,:!T][j1WlNEK"PÕJhtRBLb(h4j4 #ᆽyAzwSL"Ds`se]Aţ:wrpò?J/j8:WGF"> ;C{:LS̢9ZA<_CXKɊψ0pE4WԛHj1 `m}ϓޡDqpq^s]cc;R3PfeY E]EIF($õk.Ӡ9a^?@NIceq씙@`scz?7RJR3䘈 czSUIU(5I K}>]&vΠfC'EQ8[gnHf_HJG و Ԓ7RHB#96p`-#DJ)JDB(VHT㇪EjMR[{y(2tݰ2Us z(lID))NF HS&PJ"4Se-t8iNUCLdXF8lH䜠¡0RTiI/%i)V-{vt\>l(h^'Zܹ L¸C.( ˈCPs9@@*P =,#t(%U\e(¡>\SaM<8Tt>oǡ.jBU)Qi*NPpH D:2Ͱ$" ͙ʤa F~(w9A-S\UškDMTlI$iNH!C2"GxPt2NI(DU2&Z PEQu٪N)H ֿ#sA2MъVB`uSP@6mהݭGzdkE+ujGGTEaB:te7$`6жD! JlcET05]?mVG7HL" 6-Ӻao=#QJ\DSЃV(Tс\Ȓ&?6a)t׺OF(l66G;(24(Cw+}Z>D[KDs;b4/JUEC%9Ď:p@sRgTЋ?6(03kd?q wn8dA)2EQ[`\T)v%(f%a{G`OGͱo}=[9l#ߤ?xC=O4mg9U9=m$#_ГJ % ~N߾gjO#닋î_mccWP4~N:Bw:G @(iaB:l?K;چ BHӒ ~w-n7ID2Lԭnֽ[Gp؅S?_ʿk̛hGFYV,H98n(iK,?X(G:q#_|'B # B@KTTy c_c޴5*IhyV~sEO$M['EDERUQ4M_{stF(BMWsǣGG.Q-#"Gߣɽiյ9F捴|6Qs5~F,v5 !mu?39g)=ycithDZOFJoP -J"?8"z@Sv_z-ge HD/3%φhQv]o(%([sZљ/`8?yGШ qojR =r0 SǷe{+eQ΋2}u"$_Q *B49#IE"xتOň~#uUkc8)66@obѢyvp?Ӄ1"8JD}t?6BDYC}"gl~ A @J;*K,P뇖u%QU(đ((`J {2$ēcѪizJidCE_w_FnQ 6팯DD76XiZphwQt=[,hxPYz3(R|_ȷeh7AYL),4MӴ'(eiHDA\݆ @^@CuOBDfЖeiYmt"wpZv)iiJlsߒ(,4m|=Ѣ./o `t%(0EL@ 0(."aL69cGcWQ /:ZBą@STEQrXۣ8ʢzbG4J1(1~LMs e@^1"?( ; rFe0B8?<Ƕm18@K?e0@DS$#%Ҏ//1 UTyTUΏ49?p/rM \Qٙ\SD/(1blcE "~\i3XK 1 H(p2*oDd [dmi}0%SJ40qM,W 0}[W̶\N %ADƹѴJMJt?hWWօJk(;F{,D@A,yUx'8G TQlhBgSI}ՍE%Ub=.',KߎkyOԫL%Shr%}ws3ӒP($ ј)(! ᄈ`wү=,%ֲ6`,_]RbY!܁ioE`0H:q|׎`;W~ת]v7jj==,I^oÐ'zboŲ$!75# tf˹QrYEu%w;&ʉB ! DW`Y7*m;~+x6߇)'#k8LQY_Rią `mCaQdX­P}mc1zcc܊غ 3_]zOjVh"DIbnf]6-ˎ?-"3+7Z.؈J"x'ﭵzte\ ~sce{゚7gz/ "%Q4}߽ꜝq^r]@H %3>_Iୋ;۳3y뾮l?r@|E[WbDN=ǝzJӮ9w>T6*Mh7/yyP7^;2-B *]9اoU}9޵ysf~U?uK'rCA+z{;adzY6@x*O_'L TT^jU,:WuVw]K~ѯ v~Wu)QYs[;k=;7λ_ݗ^5Gqׄn>ƃ` KBhxߣԌ<+Ͼuc>~4i &;A2͟=۰f"IVOCoۥ1dR/6[lk(Ck}ߥ㷭OKfzL@_ r%3h3ovt%)[>oܕχi瘳`QϬDuN왹)uf-ZC.Cm|77Sr]6m'ӡ.+ +қ,Hf~ϣ$\M{i0MaU)pPE 9BH+]!, #HS8o)Q"\RD )Jds[42"jMX#8~_G1)j6c@OrÙrqY 4ׄsFAUo|y]AL ]YɔX|ܺv N0Ρ{ΉKBa84C\9qU]}JE%!h޳g(ۚ;nASJThpU6(Pi(3G}L/Y0=z- " ňL&v1R$!= 4 Rt  +%^tӽOㅧ3tcYYsJ^ N:;/;4U޶_J~'|jޢvZRyw1(}ƪu^;_ܭM3ꎦ^H 7wٺmOѮov}~ ys:;a+?>iRW/L RJ)!B7tN"P_ -ղȸBBW͛`넢H T[)_[ɐ0NdѮͫV._bcNڲfi_ͫ3s cQkhF |of̘h}m0;h^ ģ0)R⻟5b€v;uV6yfB݋ ~vlaAiYqǜ֭oIZWc}A$ݒ:tKϰ*"0Nµ,nCP5uk__9u~DJ(7͟tf8UQP {=5DC}r;ok;!-\MHwHv|sN s3% ]mMF}h@e nܫg8Պ%v,-Sb<ȝ%'~ZhXR^(4\SRNߵKb U@h1 M'.4m{j˫6۱sBbG.D& ؄9_(̩QŠ8p̸Swip 10wo+lߧSvNݺtNp3KBd=k]:d8yBI9Y.ŕr;y2`uVRZ j߯vV ُ1 ̘?Rt87uf\?cKn{tX, M0["2r-#\nq C&?o4mg#p4,6BZX62PH{ )oԦԵSa2xù]DMf'>)RJo3cwTԥ!,4":ԭV&wH怲%MU e4]w?Ҵ+d66dt'_/6sVMb蘪,m  |YsjUqkH6smw>Ɣe|8-zي_uw;(Kr;|_$xŧ~߱s4gPj/BJ  _ww*mHHiN_H9!;N+ĸ݉铑DK<L@ -ǧ&!іA`yf^{ݞӔb]1', wK֯,"E2PF`ͪr! pj܊H@5Ii_k"!r9U L`csy#"1*hEJB@ʸky}eJ:Ͼ%__GYE=y37@ȃb҄P/ǀo^s:4W}1i[O ~!'_0/NߵE1@V߻⪇k&-K")z{}p${2!efطkn'RqI j?4WRVWsЧW~}ݷwE%@Qaii~}q/pPBD)=i'C. 9A0{v6c VڞKRSg:ݔ vlϏ%&$۳c{qgCzջO߾}zk*@#J" ۪ RF)i4  \*&_S]YiFu/<2WcOyK9{K' ҟy]@|Ӣ;oy;$zʹi+wj%cό:+~.@9g}ݣRo@YI dJM#el`GIc~_vYhJ%q'{7%]΍_)G~j +gl18iԪ\wQ0ߛ$%03_̹+6Pv1RsO>oz~=ϻY/@m):19ϥ:wy %` _H{k޻7II笭/Pme2W;>޹t;UO鲥@33?pN+ t|M;V !hY43t\ާnv+A2-o~Reۇj+TX"~N\ެ^ 3Nܼeخn%-fϤKvVҴQ~|:s \a;_C`I>?aOM%y~Ι-a-dWrëuEᄠ%dx٫fxC$W,@} 2B8f_А`:h=-ݧ FP4k @hXFX=t!i,Bj#CoC2L90= L=W@A7gR|w TM~H4KLWCa'IȀ7O֒ndәH3:^ V(̜~ǟ k. MSs +8zNn %P)@Dy:,rx\L 9Kr~W^~pђ' ?4/~U1k\[!BA|K6<27#aC:TػifkRi|/m.[m xp7 aq#’@RGgw{>"(AD `ڶ>&ftFXnN:eE%vipXMɻvs};󩴄kc:#Y5֣::6]j.=C;ԨNfb-,D,2h'* D dBi#hJl>NS1uҢ_xM%Q>~}/ܹw882Lz$_;2,\Q6jVW]cS.L]?7^qݚfB IV 0j7U&5ܟv\DT۩!DJL1oo/}2Cg1PMu^|w hY-ڿ)r9F\1,4BX['XF$%:/뮻뮿뮽25"saYP_%@߷!HqDQ_[$RlTE P)a~ {Yhg=h УWv& `Kӱl_ypu]v]8.-AD'/k|_JrrzZZTT4 uư蚼K7!0QDk}hrmwY[?#XC`I kBK)Rꥮ޺m{{RڢBЄݝMB:O>>3+s;Zdia&8!$01rU`" &]9>_ә@L20ZsYvמ&P}>_g1ҷ_j[oۃMflBNUTj Q:Fd,qVKLN U Qv+mv@l9,󡧺D7C@ ;Ҧ>?&{!D%Xhzp{{^1F/B((x> @zL}+rr`E,z~_pt*06./"v6%IQHV~ۭW|U;vUGk~ 0g}crtY ^<:{O0@ ?8P^8So<,_ 9 isa0\S[)8u(|ם@l2rX ] I^hY-PC/ <6+~+ JL3n 92WP*V5ʛ7}@pp޳rzlx+k058jZmjdIt]čuߥ+yaz"+J0K @$I @qɇd5(`oYT^-)54|Ηn,SҥvoÍDXlttE$Yuv@%E@aKbs%X-w]iu}P7xkd`ͺ}L41S0ZU }@Dbh8 l9GFt$$:lT Oи}cWإ E@"`l#L(%͵¢,mh9r]J X/_?6$H ⍙NA`Eć!\FL1PjBRH(@6 #zsTV*A)Cn-9;+| PԈ v2 jK"G $g<]EiC;7Dgcwp @[Z@:QV):(.8(QL풕p .W*_R@llUdxn`DH(МeX]2&قۇ%&E  @%4A]25 !R B0 }@Pbx Pvo]"L$+WoY=%@v:}c訔̭%n |G#G 2[O}R{ 1_!$:V8dn/$U {pNuw;# <.[Xm+, Q?W^#M5%Ӕ7/}㻶ֳWK%Pe@bǾ_>)ۈMRO-UԪλαm}:OR[5Ow?Wv^.'7`Mu1Xi:(/*,:fi_e>\PTQWeEo.*+))\xTH31o?x/}4矯̖$w__118`b Ԕ5yuΒ;fT$J-\ϲ`뺦55x.M@}骛fqn =~_ny^Ie4Տ5ΩBBHF9jt| p5 C>wߔdd'5U{?ۖ5~m`K s}L' +[f~^Ee}Sź]+,L򂢺9GqEVS:e @ЀeT4|y˜?\z܏,^/w܀;+8ꁗ X~;f 33Apy_۞Xk\VX }|bwKU[VzO:?ߧQYX#UJ׋^";Oٹ:gCeYA4686IA92 ΅,xŮU{?:㺫:YA3(-0ԭrWga]c.9`k@h='_{׃_JuHB,z͎ Qc߯jxXd'Ƹ>ᐤSD e ;UVU5 &[ݕyEjd\ 6!>pFC;XXZ3ʋ%9Dw?vh*46鶁& ƹװѽ N[\ژQlxJ) KDRL(ž{LDDP\|R=װQmM?OrTh.dPb3ɟds,ޛ]]խuWt"4RTI56.RgYF Jꕘ HAvcSPUZ_BT0I@{O.ԏ<  &[Dp}SKuJ68;]zEz$xM\ %Dp-013윜pjBAgęvZ(g"/38Ƅ`t D1-!0$`Lu."3qqhi`B1p1L$^~-WN?/#{'&s.Z4o=1EKɣڙ5oZvV!jn>Mwr˥jk{o`B}f 5&F1&N>gviU7/MLDk=/+@D Ap8Gy˜/4Sc:?oYmn009)sv ΅1`"F_`Ä%hM`~5D[7:vٵ܄6+x#3#Z.$:B6Oyih@p]gu1&>\ B81e Zg7Ahɩ7BU?Jr7mJ a"o-.Cs/Iq?M8"oBc_I' 'ON섫 ͗k̏ɟ+~r}!L}H :aT ?O0A!|Jjȉ=aK:oM ~݃N2]oYk{;g:kMLЏ̲N1gi-am/us5l=I3l?qV1ا=Ʌwp,X$\:kbbbrAfY=w49SJL5A\.w gsݼiVGln=FN;^ *j=?3ݳDɿymeδlQ0N\pƛocbbܭ:S}uvb u4fnB*s3?BʝiGqR|~KL8s&!DiM~H1FeV\&?-&]WFa&[ ~M8e/فB0B BQWo%zv{s΄B `0 ";u>S  ]@ AҪeT]F:D2# B$r|]sӸJńgZ -g T%듘6_.@}ߖ#GrBU~x%Jb!qܐ" GFZ[G5.Iàan 8(-@"y%kj-nG[f{ZjZSFP_mXqX,vy d` p(|[H)Bh)LO>GVV vY~cy:HRdGS&-6% @[`7eyCCi bɟ--]f@)U$<9_{7n)q.!w7p%&T$I(5F]O4֒`,Km0$KB>]x>ͯHO$J0B~%DQySI1(D%$6-$훥 $QO~'v%c9gBi!Pg+6!6#Q!u|,5<97 bjP(\]8/$w,8.@YzDUĮXk2We!8;~(KDۖ勊9(! 1.@dw}ޚڥnabwO U.oh>ޖW&]yӌ #AӺ/ޝxW'mV$~iY̹AUVVN p,ClJzwsuI "DZBSx쟗n/7 ˗=;R˧'\EHrE͉OSrWO!I>\SZA%@eۗleΟsu #/so'6W9%B/@W'Mi˖g= K2OV/ۍymK6$ũ\֊kmڇIE/j,|aayB K4IaϞK?];]aa:@iO>7OrGkr\OUɞ9Pz6,;P]Q@̰'/'ޚwtG: >O:5?y9xsz xl_6Ɯ#<3yen+iRv{E}e vfosü1.@CCÐ!C&L'8N':g?-_#v`#,YBe !Wj4$Ԋe=&? +q`׮;8,#ڕ@ p="9Q=˷"nis6.׬v뜽u)"8NaN:uj7򲎡_n$odGmxޑQ}]G:Ʈ̰ೊ,"F[$%uDkllk3˄)&Nb j*$SQs𳅴ySFMK /5wn [w gL m:L\;cΑͪmfQcL]{ ]<8=1ܶˈi7^]![aBPi,>_b^ϞFp Ən? W6j~chvwӌnk_\ ZfV@n+Zl7.ޘ @ PhN7>51q'F>pڕ++~^N0L{~ie neU{s ycln֬Y)))zkNNWgW\7s̚,˨QZXe;R[X lhtt5T9TxKv*&YSQLe G W9elstP*"kBRs.>1t&D .:-#& J1jQl$^boWK".-,ߡMd٠);v/̪68V٦{k kUdIzmaMSȁJF6bv.s`GTt!>~& 41L r$fFozL";!|PB|uCN8zxm50iԡўE[t B@rƜvi6kj:չj\ {HZɏdl*k6W*̛W/k4%q#W[oN5΃op`-]Eg&ƭу{5TvV?!,A5˿쓤U'1RNK\}-(6*}Jd 3.;735J 9cQ#9,,BIݲgtl5ջIоEWAε5)ѩDXn.gFMHox鮑;gԱ V0?׎uOcCP3u^s;a#0]_+@]]paD;ˋ:5 GDtLH@AW05àų.D@k)6}yμf֣{PU]g^U*(ɼۮKsH"zCCЌo`7"?|8Ё_;=̊#捁,˗_~yVVۧOwߥ sEYr@?[ GuڣgWʠyh(sU$º&Zz%$?(w: ^),)!>DT4"%>Q/.ܒǥ*$) Ilt2 ENƅ/H)wor˱Vĕ:$+5)YY<\ ŎNɡ! $㭲u.I @W^ofuuի|͛n;vw٧O^a3cPJ)&!xs#hܷt<:)ŪP ;wea`\ |k3˺Lq#OvY _|M탨޺ruT@=-v&&& })q=90)EYL0Toj6f8q"{- .׀$ѯ߿6:kԅn{X|בc:oՏ6lީ7qGPPO3pKi1!K/޽믿Сwѻw3fXВ !t]2\p?v!])&WQ?88(8(a`i:`qCv` 7G%pΛe9c0_`p>PSWyఐ@EB5ss 8z>y}o᲌NBa\⻗#Wpd*}0EtwMpiLb]RO>9P1-bJn5FFDppkh%؎^嫩Nc,6iݜAƇibS%1$ v8'_wI49PDhx[g%M6%<S^U5vƇ(BIgD|Gz 0hHzC°I\G,jA@HP̨[s\83o /_xכU2:GDVDŽHԯݥTe`C:u=e2^l;Q$!CծS'R_l joڌA`@u4ٷF% 1IgLDLd]Y,۷{a!C%*(2jJČP1ƃSM ~$HE&DhNt @ThebV=CZ10,ݼqqa b>-*U%*ŕ%P׮8DF=Z۔bLW&&9y>F%J}ņtLl}I^Q_fbQt͡,1K5Gi-kX 0$۴;:AM(Ď]>i֮kX7WEv2wz]%O&ОL !P V=rĥsӀ، *KxuCf2Sl II% hqv`̼F&ҥwtRQvh=ڇBbZߐCM,I5iz:f=^GH  %ζa׾m}>˪'RtK휜6٫}2@QG;v<`;9c$G.\;]q~I:5+@[}:Oص{Z_{R@45H=;rC)]$FwιKP>|ֿ/ͣ:wNIWf9@/NT|7_f`W__`ɜڧ}.R'v7K|{]W{ؘnna}G3xf8ǂN BHt1}kG?'x'NxW\xᅆcXDcL4In}#UJ<}b#2q+kΟqqU>xϓwpQί G|\w!ӆLH0@P\GoX]-׭uPn8U0^]\Coxs W3hMQʊ6ᄩzpa:u1U@b7ήݭ",HIQbCn}2.:uZ}#b?6,cCSoLn_ԭ9=dݾ4(}vBo4`,/(TUcQro]CkC^8]/ܻǠgKzv{|]=;e\U=w0f ᕻ)b-֭hu1s7xy7't7ũCU^wa06B$zCo%[j).?VxWibAmDvcGm\2^̲ĩwمRG'uZ)O^w-G)~ `qjηحMG*3.BsٸM ZS]UcUa4Oӭja볷2 kh$uekJqS`=qm뎑]'~0?76emR-8*c}e, ϥO+DҞm)US.rxid]d)qpFۥhWIͦ~?,_=I~CGH5z3W^W3 N_Op6B#G̟?^+))kvBs~OdM0nrՓr !(Plh쭇]ćiRGgu !9[>lF[F>\m/}Ѝu_<f a mޟ:}QR [U:Hׯ3.xx]"l:hP@qzLLLH eZYskԡAdݽ&{Ź qv;>ZuY-)jxCiOU\6h'~/"zk63=)T]7/;;J"?GܻpC/Ji@^.~ !w/ٿ݅V2،aT^s =nPoc=*ōIqOH!(]j= [EWO|0]oژ5KwRT(]02' $"-_hPҢ`GN4UȊhX9GvP{L4|L,"S./X}P<YXMt0jH= Ԏ|~wB/_V-,gtATVh˞g ú2*S$kys~#8 GN|xOӰ`c_<7CT&[V8D6²0M&DeH~R B)0մm4X]@ƍLhs!I2!$\ HXk i1!X~s*2{} QB4UD%=^?-2~^@-i &ǭgaL B@J̷("gLgH> B0.Fv+ºnU|^ S1`5 D hJ`&om=2/˰L;LsOZ:;ftLgP錮e4V#G,]^ۿ'Ocǎ?a9u/.h-rϖuWrPjhc7?}ps!Uav"8Cq#ԸD`bhڬ bdtOS2vDamZ>d@ijb+m:EzH+Y @ nv쟲S!H@toC-GYs>a_ !Đ6L=z̞={|+ѣ 7ܐE0c0LLLL8>y ! dtӶ195DWyk g϶$E LE&\Z#mqc^{u<8uŋ7##cΜ9-v)\3@(q|Z:u`ļ1End=tGNast~7}CBBLr饗9RRU㩫OJLTU䇒Rz44$bQ4?-@(&: Nw7o *zAA_~wn|Ebcv[YyE}}}j..$I/,٬k~D䯁'LG7fn9íV2o ~o3덥SÄd}tmKGFr&0ӝ?BYߏ1B:w? ,3gΓO<.O~AAA!J ڠ-a #)ES!l7vc!Pڠ079hu(F<&}oW/L#ZV1F1/is}')SKiJLgǘ׾E c}1ܳ3I)-,Lpku_x43={w7iBRjiӦN+kųgp_4emXD)=\a-y:99X9twGP}voHZ;f𱉉ɹ`J&߹2`qCc|Dž89@I_jbRdۢeҌ8)m8\z M1j&FQc; ~|Ռ0QZ"]G#ڰN]{oP 9`Bq˯M6'BZۜ BL$5nJ\@r9k9QKP\ Q$I6 M/ cs޽{yd} .ڵs|75~ B$ɒZ{4suׯݴH&m%!`|hrV"O v~xwo*I")2icJcaJWgj R B$KD"I,Kn=jnv;Jj]yˈJ(,6TƜPI$SJJ/؜g/L$IeI,3#$'7^~ѷ*Wqo[SZ0\ec̜;֯\xm\` ۻ`o76-ٻtтM٥ٹpZո:kŋ޺·0nƨHʍ52k`zo~it6O8iћ6o:[o]tE;v .]据/\j[=5r>ynolQ; ΀dpP*>1&&&&&&!JPnabbsX}O'[SRcc:$EqDg=tY̔Q\@"9P}1],Vem<\# z`]t`s|ۗ-|/پjcu⭷~ +8so6v±BE* 78N@@-zpZ !0"#1¦k:";K>zK\gEmLrUv65BXG]%>8X+دAIw|8?Dzn{mwO.Ӭq3{Fwq]^u˼G,6VG^9-yYuJ!V1jmVj&`zo~!3svk;tH?m۶>}{iiiÆ [`a]]]LLf㜷9%\ 7~rjQcǎ<;o=C(PS<9G0Dbc|bhZ65111119(яl9$~̠Ȍ3%{8"ݵY.gM:_͑Us=hJ*{S8w%b?{dbv*԰vRƌ lغ⁧˜R0_DQe6=w.94@mE^z.{p!-߹斻?UZ Z7;k~HxW_zw{F=K8D^9[^BGa9,aJiSPJC,~OW6VW,*fwk^yu k^{;^u  `X[EF$5K-OrƆCk 랭@)/=SP]uU044o~F!XTB}~繹/iӧO֭?YvB(Rι'93Jsguu=©uͯG=z=Jr;픛ի"Q$ť+ BF)5 (RI$b^n? Bp 9D*<^fп.c4ciDNO3DƤ#DJar!#m~# ~v1ic{o~h՞5g$NݾmĴo~?h@miIA1(sg؀8gS'O3~Ɲ3V9(!@HJH Iփ%J6-u#Q G@gܚ>G~ `E9FL,'.vX{_Pa>d"d:X3M|y/LP$9yM `{s\؜YÓ2Et5}'K {rF_WUz,7d~O^|KӐIw=v1΋ͨ,0͛b麮iZdd5kl۶W>qcgBEX A[=W"(%,t~Ǧ:}-~ꟷ>ܮ*8loz<2/! B0{׺5k}nAw_ݗ_}{ 7ۮ{@xLLLL~B4crAsG nߨY2p]35mxC%rEV3ACzħuPlm(Gիrv:o<\>[wPi 03d9jv3od@pڴ C.c7KS%-;≜|tRz%&0D[WC}!Շvr%62:ה/ա`;]AQߟ߬v<s`^6 ޣGd=;Y<뮾kY7=`PfAãx޿-zw0HHpޝc@l=LЪ@$o}8gW_uUbb?u1dc-or` @4cA1ImGԐQX:κg.5@ò»]q4ޘ$QmG/xPlAuK( 調o< =i=B׀0PJ(8AXh:8h7>Zs9[0m7P`EpLoc m1zR :ǘ*Urp5Ъ= V_^_:&F[ w7` 6o*6= tۓ}U-p{(Y0*>y)SFw4JIB5 8o,QN@\>n-L#G=~:e6 a,@ i>?@[@X?t[!XUt3V dU^(ݢPb| `˄͘N@*g]X,H /'[ofFFƬY⊐Q~,#*I 2:(B"t 5k!#zwp%^~!j&ii 47l'  U21111՗5hlEحfaU-zCC=n~?J.9IU˖\;$ʺ>^Y`J¹_{Sz* G|~]mؾl[.؛<Z';33σ7:!TN{ 4{?ߋ=}pzOs7$/fQ3wM7. j{SuٔX@\8v>;kIy{z nsuA#'\|В2$N`Rz_S$tE?_L "FuB|44WCJ$HFw䤨n'@JHygf!4c7 !sjk222u |yިn~;0- }Cׁ`0l(%^c #Z.Çjj}2:Ra0 í2U(@2&&&&[﫪u,}==;q]7 N&1[hPʝvعlˋt?%Fҹ%И~eI۶/ NTB{ 6lkYkZS_kzl4B10.mjڱoj?@ 8]8R|Svgt7~gyoH?S%N䢵SOKGDic,wՋw-g{ +}ޥ>u5&<'{N>\B:: /|͑|Nj9,S޾Wtxt`wLi1V 缵 G @/UOC/UfO} \FSz& LFO 3:νj f뤡ӇD@$Y\f~d @P?jiޜF us!ocۯJUU6[zZjZj[ny㏧Oֽ[%_{!#g-]fz)2~   3gi/B0@uZJ1 tЀ`wC֪ :p&@9g @&72111ہ00&/dR1f6Xâ˥i|?9XUA9NB0Bw!P`ʠHW\[q/PTIE930R1z Ӈc`:\0xbrK\2/aƚPv>Of)om[q$S2OxkC0.%ߍ$c/CAU$Lߑ ~\iuLH|v-R,\idAHӸ-[g?zK,pNixƵ:hb)/sc9vP}Lk5gBЀ0L[Gm;h˒WV_'## 4'/+/pe5vנ ΥqfcDq @`f[bJF&E 8/Z!ĵg%}(@@`9> 0n2O!{,[!Dany.z!ĢH @&jq~)#1Bu)@p-6fZm6 6!(V7u.tx7W{I2h̨H hK_GoiKy|V|xcgHT U'|j.=n=3 ,C`CkpzZ;p?yG9jaK}o2@D>Wy+sF_1#cΘޛXDFDEo@5#h TU1nq},m_}ŬɣGGGו׋WT.YӇ ^?fĨ+3fظqZKÛ*˶oqxڀ[{7 }q} ۗN /\x-LӰDGvPZto٘ۧSBF"k.~0>vmeza*)~>\pic A޼Oؗ>ۢ R.>BE%()ݽwN 8uƲvx}ߵOTtU4U^HёM #@p qN ͲZMa _=o ngKvh1„"7v{Yq]Oq a`]2SGsOB83>y߁Wo3b='Jiw}36TFq3/{ٲE"ht6BNܩ'C֒$qGf'͙>Ui?Ͻv@H4Xw.)lc>)L1⺻%c :k {8YDwUo_x<嗆X5%w[?YƂRCSwKBatWRNCb(:V!.-ep;Hy"KW5ٓNh5  d]c6緫Ou$ǍRnZ!̝+MJ{1UB! ΏB5-q1}tܾ'XpѬuF  i~y Y6QEeg~hm[tMӦMٳg`n [s5 gFiBA(CG,IX7&!U$aΘC)^n#  4qbg:ceM9y8sT:7]tg!RTSzT ʔ6.3t|1BcsǮ/;_]jR$]c#֔u(c! cj{] #Y4o~_e.zl駟̝;s޷ooqԩt]ucanGE%o󁉉ɟ 9:חQ\L Z묞&aM! cKyST1.L!8,9?v}ECϽqyE-c-a1BLg"B5]y Ы7-c`FOiI&&&&&&&&ۼLgM.ɟsZ碵6(cLUUА!C^}/oE!i=-0c{yw-[VTTԯ_믿~ĉƷ-qtayvkŠP://///o޽;wܶm JHHҥK>}zݿ~1 ֒gGLikJ%*8Gn\ l6͖{0w5,ܻwOTT԰aæϸ[nFfB0LMLLLLLLL~  3,IEIBCB5M+))ٱc;vgeUTTTWW{ޘC0 ###..}VۤB4i:y` UUv~;ƃm,ŋJ;tp77.5-Mp1WsfuTX,ViZYyyyYÇٳu۷\аq;`Ĝpd?c8gџӼyN@s 9CuoY$fWX.]4$$d1^vٸYur;vfbbbbbbE`$H$Id|[Zztǎ;w.....)ir:322zեK.;w9:*#3 Ӥc7?)͛Қ(rϝ?hw 7N<9Ct;QNZ!˲!N`>&&&&&&&ؖ|ebHp!vefnݶu-55ղ,#"""z5lGDD8!įo( g&ӼyNiΛA)eYe%Λ7oժ?a&M |es_}5722khh0TvoaJ&&&&&&%g(J)qȑ윜svgv\VcǎݺuOOOt8cFs] %BHpPo4o~q!.>M#Q1:k@q:߽Gn׮%3/eiv UVjzTyl# ˲(,1]n㩮޵+sӦM6l~@7::&<<<""&Q.ㄲ&y``|>Ofִຮ`~11lcUVÜ9mt:Ǎ7Kұe.4_~?!Oqc A(Q81111111jacB(PU]SXXwݻw̬qqqvڣG}tlM1VcUUe:"4ouLik 4M+ۭ9sp3ښrWW8~h!0delv,ɇrnڼiܹ'L8z5)<䅗^FEiŧ/ clpLLLLLL$Igܹ#333sgfiYimmm]mf٫W>}뗔ԡ]\X1k֚F4ouL9gSCc}ΝTX&&vUYWM$s]ՙ8Pwm̄06v"Le5MeRs!f#|={vg[ms66s/sk6iם1fڷk3fᘘh[.x;BŢjjJKKʲso߾u֒bcAIjnSR4oun>0BeYм<\׼>?Å_΃0בn=:_iaWqŅ,Qf3\8㓻D؄&EL4]x^ k/ap K, }4WuOBP[کc45gbbbbbbr:h럡͆LƸz˖-w޽;+С‚Iu>f̘䔔:Ȓ3*csv[YTٿ&g ӼMR,().1)elBL":> AB 4111119kϴ57FgVV޽{d<2JitBB %f.?!\A)X"a<^ػw϶m۶l\TTNLHFFƴiӆ aQ.wAK4iҘ*Lh[F8(T+ t\HVI"85aI S_C@RgbIuT%L`bbbbbbrVf0"!de #l:x0(/={oߞOLHH?aBϞ={.2B455U0͛B!:Pu99u MZrUoͫ䋯w 涡7voGw\z4>̯2![KhRʍjY¯Oivl = ]չAد#ImKj=HK(i/@|G, s}&SUˈǦ:BuUU l~M1q6ɬ$O\?|fw嗦ɢtSVvTC KD=Q;WXǃ쎤n "yj6^־k_p# ku@^4;LLLLLLL~'wsN)UEeiܹs͇򪫫jk@nFy}'&%ƵKHl j(UN$l/iޜn"Iv>.I+_+m/.^v^ڻ>~kSɊV5':F6٧/<5 n<9;F\u݈Xk>n%"+M0pߡ}e4g=~dkZge.֛h,f\ MK^uHv1{J&vu`11#&DsKmy᭗v9}AraV˅#%pfQO X]їハp~A7=0()n7д`g7VSCu{RacE*`om0jl,#n۷m߾=qXXXPPPJǎ3fׯ_=,ˊ"s~{u!CӼjMyszzMYYnﲋ{~oueZ@O;˨t!>jD[;\4˦Nئ LO ,xs>$u֬9?0:w4[ˣu8r`<7cjl@`ngCbMnf $+K~(7NҡO.߮z` YhhLB.??1 MՍjlr nL58( X qH+2_tQQ+$gϮ:D%ݶ>eZp5u@. A~XUn|)f&@""$)82kئ:@Ĥ!0Ʋ$S.۽cǎ={vٽ' ÜĤ=zL:kjN:$;v΅뚪1μ^톖cJiy^8":L?!.F@lܝFO6\P|*W}ĥ .YyҸv}^ (`^!ݯ"8z =2k'W=(vPX;YףKTcp@U5tBT_'mLdV5w|彏":Y:ә .w}({=:4.<8 ˽fS`6baPApM&]`:㘘 &&&&&&?JsդX,Z]S[_Wm۶M7ޝ3F)&L6m!v UWS[,Dcc7 !@@䈍{|Zy^R%WK@u ,6w80\ح1G#G+ešX_< IDSBf jcmac ܬvBq3jqKxფݣ@ F6' LVDQ7W^Y1{E; f3WT>=v{2 dT,5111111iKRJ 9s0'++ ?sѭ[k555---###8(Pc\H6^[[-2πy M4!"5N Uu~%1ʝGyprEf'U%j-E'u(ߗYV~ W"낞=l@X,[eIpU'0I.<`0[2փ׏uf\@Ģ(R٢P#Ue~,2w{dB"[)G-<ߚG ,G˜ a=-]&rfmڹmwP)SuH=LwL 3WeY% MDp#`,_211111!Z41Ʋ,[,Jϯz<Ƣ-[]nhֱSC{iiaaa111!@4[W`uq4iLl'xlW?0B|ZkPuh'_.Ϫ NP n^:wm*E_|qf]pZEF)iLcU[7\fOʤ/(9C٨Ȗ XT\`rBe$qZWf"Om^n][_V:_!PbJC{DrBRl\ü:uPRwˮ\/g D8Atd"j{w_5jꥣ({nY5vה.l9."]b8uj]:7]Gb_PUMӄ&/M8qy!N͡cWymk(|yyBݞ-(@qg&L 6 ޹qrGBVq˷nX"Hvy.bmYaG5Q OȊ۽qrR|f~x-`ej0CQ;RJ K]1BZ{Ci!ud& /(G%uZaBbPc2o|Zn(&)ٶqOLj.ã0|+)?/-[J~϶{j.-Ω:*3޹m6JEy8b"\,+/mVU?6N· %#Rsb|{ ;GrSM:4Y4HdEq\+**v9wΜy-X9BHJJj}oᆞ%#"<+䬦flf+y͟Qh$[p5kb3sGvI"nql*db`#E$KYf wڹruk׮_n͚5֭|ڵ;vuֹsTι3uVN mv<޿ ۼcX?1@JBuq*td =1_f9"=&Ƙ,ˡ0@!-0~IDAT0YE\[V{ .\xqMMzSz,9q{tOJJNJJ&i>5G,3~ hrn|&lAAD4vOUUEDJs+ 66"@yYY%iccccc׃M$*Dw.++۵k׆ /Z4|'IR|||zzƐúwֽ{ DbbfmmmyE J-߆ +Imk͛??GvmPA, Gfccccc;AD(PCQEEa|Ϟ%K̝;w%Uvcŝ:%''f& ny%N~@pnVTT0Fm߁mA)!QIIIw/"mlllll8Y SY' @`Ϟ=k.[ls)//LHH}={׷oVv%L A4u]FF<9B $Ik֮3 C\vǿۼO([6666666Vę’ezwڵ|+VZrm[6ou\:tyݻw/,($9>j3\ԪisdAD@lQ$柎ma)OMhcccccsd lY>_EEEUU͝;{RK|9**wgqF޽322"""zCc#Wp3?B 6ۼOcg+#ocG lf$3f5˖-[nU/_jժZѶ]SO=s‚F@lln4[2>G䙵[͖meDF鿻#666c摵F!,݇ec"ET4]u+W9cw .kӧOFff6mbcbzlI$أٚ(ȄEl}0%Zdcx84m%=y_%Iz^bǛm 8EQkbfEE3y0$ {EJ(aYUWڵkΝ6mZt颅 wA)ILL,ԩk׮ (,,d1J)cƪj! %WO":G||\A9[^,>.NpkRQQiڡ H))UUՁ`z@q:-#cV111nF!u蔲ԏȅ 6o0Ƽ^_mm]dd(fcsA76 B8NS$ml {%*( !0L!xmm9s-\4e5>O;=_~j4UUU]7ihQv[K ʪDιUaO;5Ms(EBhhdgɲl$I|^'"pZVmsGsuu6pY۶or\-WVUVFFFN˦in/ݞ!4 I>u"d[eF@QC+,FDxڴNz*׮[i9"据idy buUm֯_7ӧZvGGG׷W^+,, -m)'2"0MR! \.!{q e4MkSJ23Yr,^4 \.+1VWߐhFt%K>_rCCCl\\Fzaâ,KhhlBIVZKGJMkأI=xhhuڜyPV49hۼ<1MӞUXG$ #o?VKի-[hѢumڼyOY$Iݺu;s +Cr4 ~( ckqR45MB$@D94s~-JB44eYߒ5M3 ZB#7QܳgYq5'q"%޵>݁~N @OvPpBM.9eȑHG ApN%iϜcO鲙!blsUgt 3pM{a%!AĖv`}[\޶o6|Zu G?'gYq~mšBX"|˗ϙ3gΜ9WZj:vx߿sM˺~ M7 UÇj>I؋PmnZ XBb at{yaݻ{e!/s 2n݇|CMy@DB4ҦRrD84 Z "yƒ5ǣ"7;DH{{H2L?bV/,1 {WFBo"Dnnx(vB $yD$F7yS5=oڍ\̈́@J hQ~雅@'Bk׮]vݺuW^|͛\rInݺu떟BQ4Mlz<+s$=t@B>%uZ{.JM28#Gab.H(efÄ WtW""4 #"#5ހcIӅm>lYXSBxeR،PϖD@+*Y#{5l:y0 8U A ~$-WA %"v~{S'dIR6oLq];@$,a2ycD$v[4ٺ@3ݱꙗM 57,!&S4iqKDXjv=om&5M AD$,$AՄ a:]6"WWG LV.0`PWDLfb""eakj&o@Y|[_A4" XR&IA!Z1Iz5D9%\ $(uݵ^%`^17"*4 Ή$Y+jA?[gM`.CfjfIp z׮];o޼3gYYTT4jԨ~'%%%&&6.ss9,Q"ׄ!Z=MNh_P[ft{oQV &6/G_]BEeVi!\9^xCU 2Ez1h/9:w<{sHcS=9=X!4ǟ{gَz%6kor؉F!~9w?4Nj4m5>q%|/R%tW/%~W]Mn}j#Ӈ{'}u\20~z?jP2l7^,m{A.9ʈ`ݽK.tׯ?{ аǟG3C-]\ }8U];R"j,]1eZwldmydn4di쉏h95<Y3o<7&Hi2I0!K )]ӗMh}%&(f{sſ9Voԑ)_OW9iAwιF$#׃O7C2Ma?G9ֽb ~V֭Ob׮]۶m۸qҥK-ۣGݻ;f9窪6! $d5xt]m|J:N@Adx].(ph5޼,+`0|,&EQ5AbvS2x雧O)x{qOn5BA3 uۢ傷xaOp/ n}/:6߃!9o[L{y?ߘ%u[DK;LC>Nv;,^yWN”(4<_uWH]'ud@<66;RP}{G.N_ G^{I_l US8Yر&o?}}wl5﯊|i44k&ˁSr:k@R5ۯ9R>xxj<<T9Im)]d6+Ǟoay([^-9n̷׾6';}-ݾ>ߐrEOTt+ mvpaQ:O aXsЃ o[XaÆsΚ5kak׮W^W\qEAAAVVVNNNx Yf1 LNE^su7x9ӽ^5?yw-!DQg~s.C ȶܷe!DDd̙3疛o19SJ޷V>;!$=S=KJQ[S$I^x.kZK '>q/R}8hk1zJ']s=G;侫o=iz-Ǿ3muY~6 s3WvbZW '^qNN늯mN9#@Aa&w~վ/>7.7vp `sة)C.+Icc36?1 :WN|,nٔpED/Zf84{c`*L\{WѳӭN[pq8f9d'_\q׷ƿ;djh5n&8bs= +7QS#?G|,RS#d"P !xkkuꌊpQW ^rҝ5q% .ZJDST֖Λ=g2P}%/ӈL~w+1#G)(@fpJ5͚h&9)zqYHY2k/3o*h랷~>sܵ{V % уf}ɥ']·֥vl :@qI sXTzc)S0"8.?ea'3+-נd8e$hd4/rQMKRD@;$Eˊ;&**:*ʥײ$[fNY6a<4Тo&0 O|Rs<0u(QEW]1zӗo6LB߾aռ9Vm-7)3jh_z!')Q 2s5՛֖3Vمm47I5d=  i&{M9bK>MJэBzj۶m1kRnUtZ_zIn.]~3gx|x~~>TUU] hjp_i$=f<Φɣ͝svpX[tt;o);޼|qO?u닊gZB`|Op8(r1$ 7!`nݟ}晙3fYSym0tvݪ j1>h-Lz}uYGK> &_v9Q>_Hq_ٕuܘ>^`~L윮7z:y\oz歛J=sN D؋:M@oO *<;:Î`W Eg_qb<(oŞq+n{Gp2Q:zX>}falYCbN?i=mO 4~]h&P[+LN3HHvj?m5sÐHfW_=0YP$daebϿu(0~cHZ? a$Zv:ySW;8ZcmlpucU( z^%99xyBZV8]y!\7=SV6EPЧOO FRTD)P/g1i `[o9]?G\)=fcoߗsA8oV::1_RoDG pO]!8@D傚߬'\@mXk㧟~ `֭s:@ P__m۶y͚5kܹ@\2dȽ۵k׸fU\% 9< |wN?⢎t/'}QQQ kkjcΤIz𠬃hZ'\'luO?jFB{MdY~Gn u]߿ׁt2!~BG~n644\rɥB[oGKKK}qz`a '^w=?pyth4 rHMb.ajpuq'ƽ6O3ũOp |i'}} eP)>5:dZ5@BVUR8bhտ,YK`#yEWe+?z)Ϛ}NHT۰xZw:$ fp#==?QU^h߾p&tEх9yrƹǶMIwCz9; BZK& ;>?]Oj-[dNOtD'ew><@zJZ-zVmqώ1)Yin 7MaT\ 33{ pF8=>H G~ZPϓFuXM\[!a/ѣ,ʴi~gy .߿vvv|ɆO>owܹt^xNk۶m\\T4 |5G!46)3?ٸq5k'~Ņ;yDTy>>lX]]GN:l6p`*r) ">ܳ۶m'n\ؚ}B)5 1CC! ܯeJicc_/8יn^%\:do-쓁4WwwV'*.n<`{v׬ D0XmԻgG$;f}O&z2>@A|gdt*ءcQX"M ,; PY:c~%|Â(@a#S}?엕1%{@V/(/!t&ώ kfAiuSIWܵz6VΩA^m% rAN$7 0t=@d(HOsn0@ rn Tf=!D/+.\>5H`~;zT"0L@Kplˠ= >)W5`ݠ^_C Mx3BoO?- 6nlr!\Ib^}z]: ,XxO?ꫯ?~111FV$I$]3ڮ]^oGW_qYNva@Q盆9h`?`yt]Oz٥s'W]0|>ԩS&5%!֪9!ա2P 6鵵,90tk'6 6pҿ[nT."MݓeՍqN|%?J K$좎c6y]d{roFa\w2v|l ??rC33G79Ora`o<̝`1D*;"LǏn;)ׂ \Wve#:$9YǍɛ9Z; L'bbU-M9b7\;]NAn ufrg{svE= m` iH6J(%C7C$cԂ☪[8ĀiNHV$,BCMO)J n>ӿo!QB u8$hX]w]WTo? 9YԨ[")D / +rpe\tjTr`GvU6^vlJ-5ЙDHPzc?g F$v޹g;rJ=ZVm z UOLJarB~O|R%nX} L/wWF`PJ`~d䙧M`11.uȲ@}ju1 E"3u^;%P ph]FMG>4x@F@ӟRkxC;YMT666n߾?kJJJcjf0robv97k0~3:5+Ji8}9gλќ{Cf>5Q0I>쳸84@1dafttO?k>c)@k-zB*(]wM[^"22rӦ/8hp 4l^iSÀ^@Ji7L?>x{b2zݸOߺ#Bsc.=?re[siI< r?7&Mffz^cbh< A 3ex^dLt|v_~ p<A޷O @^9IJE]@(8mc_DLBRANhg[!0|Р%4@@pJ0qy\#;HB pD2+؇j@]m܏iP[]{ :,o{KrG2wʬ1wQ(TS3[_S['A$Q xkFt );Ba7ux_O훧0ocFyׅ}^g^>Wzޠ][ #))=X`$tJiU=!u lڥ#? _}t63<%D@U! `8Chr0tAmIVȊ,~DDv*2er4;sKgDsK:eU;P2"pB'xu-w\*P*LCJLx;Ə;&A~,sK]ӆr9']#g "2?;æyIّ35? ( hpk7#ve)^wn|uGziSG%iEV難25eȅ|0!cC dWU^r%4ΤZH+ϾyTIq(ii8 nzn{Gm۵IN=t1l0iGh־C &{tO[__jW6b<*:י3ygI?x&Z(=`mucO|7 ŧ|6 J)y%={DmC Y٢yWcڍx/^qGP*NKfK*y9/~gڥG߼dgb䓉Rq?P0 {%Jh@/ +v?uY*1F u1m,NzSSHIho?oI,{l{gȡha{_qhZL꺮j\\\RpJdq )U.W͐k e>,2Ł"*6La!w{䶙q.@b3+']fRA,Zv:6Kwռ9˫+cǷyӝ57v_uȮHI[\1f,(^Hilj^JT ! u?wv%-^v]N; ROc] ät⥻Ž IDfXďo{ݦҝ;wl]~%1~+Y~[LۑetזgJjZFaOg6zDR0w.vBN~st]үeҞ,Q}o2jȯA1L'%& !&1^~{}˺y9}%n-Ďuβ5nw'fE1 $WNɻ,_Sڐmve&5XtKCzAHHnlww-;vmٴQӯwZS?o 01\5˫ɍ&;)EHÔe =gz:G#͹Æ   a|>KH-??_~,^jB,JZ+uuc2&&YB;@s`SsY|>_ZZZ.]9JI.]t]k~u#beeURR8Db2QV,Q:>nSUuu\%p:]N54c9Uf;[WWw7VVVFGEEDD4\SSKx@(呇|')EDxn:acƌ9{9^1Ð1VYUvOummi#8üvE]2Tp&JTΙqV Eն}qtmΌ¢N bd1BJX\\ԡ0'##uSն}qSgRLnWԩS8{w)ꘕws;s)QM+iy r"[w6GWKyɒ%+Vw;hFUPJAu֭Z8(+23[f#RJeYn!io/=z%wfYcHKǡ(+VNNI^q^j5 jvms6p8k֬5Ôn{ŏ=ȭַ_Beyՙi-oܸI$0t<{=ē@%2^[[{>smllla0[5k&$g[kw6mNJJj!QG"$TjɌhf(FKBՙ\0Ї zhZ*8@g8w\P&eMbFguiطzE4@!QH%6m.~7 3O%ȹFrD 4QB׆*/7 {.0.Q!ԜU?аQC JՂ:"!ђ'`f"0TZl~8MÊLݷKJ p j՟ a}Fn")# L7-47i"] m;̕ULFn,%` '(HBv;8e4 kB)ny̛ah~ZByaGC!GFM[>ԩ0{mUq9pܸqwyƱm?Bpmټ $$]~?ЀMoEI bnQq wt8T@X7æ{}ŝ:,A]7zݥkWʘiVXE]y}H$j8LB(G$QM(=ar akAXk׈*Z=6oނfI:,{X92PR=,+2p }UH3 B~0] ?!'񷆌VUAB%-A!݃icoBkPjl J~kYa114 7ܼq9ZZ QG`n :B迻wG;ʵuru]u[Jiccc^۶`0h%HPEk-C-7C)z݅*&MjnnfUtZ~LɴW i%]mmv{uhj8`ysĠt:?ClŸ=ϱ/JMS܄aض?$gEd&n-Ƭ`?Z,[h}iEy)D["lgbU? ; !&Ԣ}ip&Gp3p@eO,k7Gmlll?kV6aym?-> LװF E}HZ^n_稅J8 !TVIhmiukccm=ՠx%mll-83z`7QВV$^E9^\#&MV,ۏQ%9CÏVzڲ^ sB9ZI#MCUMIňsxݧM=?ACp!߷lzc"k!QR_kx|-( `H4wR"4)Iߖd}W e}gmd6osXq6n BMr:Hp\u7Hdlml*0Zhf:!L)@`M)@ UU1V`0jB4]o1D`` 3:UOBpA^[!^JQ.s+ɒ"e@-IB&|/"WQA{dYrCkA!m!Ц[Kf(B(4Œ)rã8G͛"p8RSRkcsBxԖE\lLdd_QԼ~$$EHU=mh(R#Ix  `m;AS ʘlQMtSKZBB$겭eumƭDtRʶj) klj ٩фajkNJs0Ҵ_^cG@HՔW6cS2c݌RUx娤(86o!dY=666V#՚TLt}X666`Dۡ0ip8k !ڷ/TeEQNgxOaaiס( Oq9TU=S-˲ B dOo/rWrUw?U#]ҵ7|w?ltًzu4H䦣~q}p[@\+NVl5Wny'~tnBf~f:YaW^yL ItgHo*E'>_p޶6y5/ .lcxB)>^zr@lD*g^W/=|ӥ\ΗNMƭzz'$Ϯ\f7]ֳQgZZ=ODDaN2[mr9Y":N}㿠 A)UO3槌|E~ǫ/^+{Q; Djv{!(|즇λn<"H]ss2c]e_pƵsמpҲwn9g?ӓcӜkUU+9'0_&{X'?]UkU'6oޮҩӪo\ ^wܝwЫV1s/̟H DDMWwM#\D.iT;k.ۼ!8|^?e&FDDȊ5¶>#U1鈟#f~دg26?BG76/Σ^y'% hκ.ȹhgVȈP?@ ~i0h =o|:$9|fJm7%o}cݣG_|w\б \P?w{a FCY)9=EM[[x,=}충')('\މ=PYQrMcOz{`̬OΨ|IU^z1O_- y/R?W=b ,9+icccccs@e4%I_3ΰ<GsīFO`d8ϒ p@18Gb(>6XtJ[^ztnU/]a;~sRC.⨻g7 >ʮol~c׍.^6y:Lcv˲|72c.r\PUeBsbɟIqU pIkG H1.B~*P*40t]vhR$TMzf_>sՉuخzwvtND0 i&`!O?:?y7 ܆)H]{YS00 ta/~?~̿{\/nL} }TC$$gD|,Y4a\S?wg7Gh0ܵ,)1R𗖋׀Ъ;wdgQj666666G3B3g>+VJ"iӦ"ʒ}{tJHdd:.+99yoBQc/>_~u}do-Ͻg! 0 ۟0zˀ0N \]zo;/n᭶I iRF A33acݨ\ )JƿOewc6t\z7AiM />7Tfuojb PSo.~53&~WÖ8!hΘ&5Eմï1ڵ.acccccsbq_wg}F)ʲ,cX\Tww19vO_v} 6K3F2n3O ww~ɏ1z}. W>펫o.l;: *ޯGο!!_e}([9G n~c%'w8#Գ͛#ay8k(HE߽)Uת|; !Z=wюB"2={v"0Ƭ$O&NxT ݻccb'xܮ?3M3!!cC)"/O9w-/vפ)㣗4u!)Tvc"7+)L7j;_{^:W {V*rٻwwI#n6;ힻpwpwP1e %o q޹WMީ{ i3*aP8!a(L`7?~@.{+"I7O}ʖAA=QwH1o 7}չĦw׎{cZIሩW@ĆF7c׵u9aOyE|M[y2IpahGBQ_޿@30!KtQ媪={%&ɊDu-;x4B(S=!)!KIC& {9N1gϞ_{.-- !+**G-Hٺ}{jj^y,̚BB+U 92Y"\pIb@)@P0TH PJ 5cE]DMA%MvVM"1ּiLBHkJ~ Ĭi7M$Tb4(,'!~#9v" ˩Xi"Aӷfѯu1C=7q"!휷fK|^ũJCrXo-0TљrC@.#jp$Dl_b{]aA]D!B0br~BxnтȂR!\]sȽƆFé\Q+<]BCF^+eAgPIR5 %5 lH!<ט$0ːlnٻ!};!a@گe9OC!t~Pdΰm1Z-ۂ"jMDy%(;3>J?ֻG!V\![W)n"KM5A[]}kߓò_??߃O{o7"D=W8p SLݾaKf dIi 1PoYt_ Tv4Z7 K?e~Ti&\ ,ݫ~mN "(Nf7Ӆj3HZ7<%t<2X6666669i wqE]ꫯ~5iT]9 єOi5C 'MZ|Vg{s%͟ "%Z['f OΆNIA}?7@bD? e-T߽{_vEc=?ཤ'_}@߂@8rs#H"D;}^_9r5-l[]Ii^zFEF*wiN0k̽liE 8kH Θ+D$Yz(8ue - "=%Cɛ8o0#AQrBL݈(1YJ ؋ (# :#!D$M4U.b+?ۼ9x 7^_{ыczהoC>! A%'Cue+aB*1P}~p:^NCGc.8{l@O?G"2s֦ѫKSV." Y}q0US O7g=%n氤eYe /).r0l>}ƨFZNp!֧S_bLP/ #$B@iBBK,Rb *%@@ ÿb`^9G&רPn=S84`(/ Z! " n\'Q\!Io9!t 5&H2h^˒LaӰ<9ah$ۼ9b&z{Bʗol@$Iƨ0u]1$[%1 Qn""(2%2Є ]yY=}$ DI'>3F8c圕ޑ *I;7tCPIr9%a.¹@@.Eܝk.9PEqP) gtHfjh"ȲT]SЭKgM[Ķ"bAfݺ$n0 |6Vy)Q5 @ @(DSj:ADB%[FK iQ妮jU\TUp{@kIQdq&+ nUMDdS3 U9PIq)4cD.hom 4(%H@ 98QnhAM %! I GDF2F45Pq04A )sx\ %8D% NYMYPtJ%h@,10UGD_~e{)~_uB6%sAQ͛#JmAI~Շpq#T ,]ޏ &SuҊneG,\tOnN>ycVƒYQAg^ybX.(@S]P5MeZbmu A@Ιm'Whz̞9cAĻB7݆i dƺyV#$E69ȼVQKw-qO@ e!7H ܴ)r\y?~'&\<:#FU!jvl4_Vr:ˆFdLnVyP߶1G߽yNd܀LG^~R[gQ~GʑJYi• 6mю'~lwSӨ?I)L_i[lWɛRGlgwEdDo=7{}YQq.9Na=ݎ=s<0@'=Pf񔯿Y'Umɴ2%;u\=axVΜ:ސy& @2іNqϬڸ|vbrlǝ4DVY6չoΩ˿z' v-B*{:-Voa6G-ǞB%_WMX! '\qɝkw]u-OZ_8d^sq k} l%, $NYKڮDFGAɲX1wWwN۾,\\Iw7]q~tf0+x"9c=ƴ&y N?}ݹ/FDկ_M+=;px_rF%6·WO>!jNʼn?eDr]Ii-F.[>=n7pTTV~$M,k mKa;RӨsǟ{ћw~N(NdWsڝ=2_}ϗx"Է'QN#N;sxO>uP'^y}+:U Awϻ86mPʚlk0yw[ w3# 6eYu'3fFF }N԰p/UK SYn`ΙD]ʒ҅ZFb$n ?Zs*r|ܜXEP ;VVw5l66vNu5l?/&#K2'v٣\TYҷgF `.|ڏ3"6gZӿDc{S U]ƞf6|&oP4M,ǀwԝ9hLZmƍl( 0ED@] f&6zxB ufFoX#e04-td"KXҫ͔;X!ιir!h֭ #" ))82KIxw-m[@dr[Z;6.oL?O,LAqU ?V`=T&\n݉VYp[P"8afuSfM.(P`\c / %)?a !9Hn]Xknvɳ'G lh}x1q;kvי%uAa~5{Q.bU 74AUBݺE[X"0a)乐P+ 9 JDLJr<5&#J nUU ! ӴJF% 8G5 A[v0|uS΁1fy@0vݽGÇ666uy޲Hա:X0sښZ9@ y<R)$BF _}0 zp_NYP+}oYEI%er&֭0b=4"09&56Be(kRSMs^zexE&a ϡAH@0Qd5}gU@%B)&1{?zŗ cbKnPb%ҽ_666666QDHti6{bc]^w`>K|_5ɉj Mrs= !J+OLTXjt?XēCuۚś*UC .TM n7%pR MC e u-}Guɉj 9s{ƜnGQ"a%v9QJĔHذha]AId>Qt@}m\Xh짔vއ-jQͧ巡|fC\GȄh'@Ei}nqvɲqnSV\k]?}5 rj>/ƶ=繓A3#n3}ݦ};PJUU'.J1gZҶm'q usA]B!QF@m@3 o BBH'\.+\P k{Wܱ[萗W \ l߫O}rczLo޿iTuUU8ƤMoRC@!$3XO?mVW_p3wIIGdoe**rjQ~e3>x]JjؘQkgNy;***Iv^frF^~<㗓ۺsWU0}hy¹DƧ:@JPkҦ(/f?h%.;#=>M_}1i= Sc3s#f^,K.*Δ_X@/]3s}zfۼx !LӴm~?%%yw]rs8猱ֻX|effFTT\!g|5gktӪ}/:vf;O=tωUe_{6,vWkgҵu#:;!뗯m7b\ jbxU*9U|3Qxh`òk}{RlX㌅;}C[6.'n{j(L8\zK6%_3q}zm7*Z3ܩm/<5dS% \m]t*sopuMs~vMrvmR=}0iuypu[HAQ~VLZuk/[] qiR诓>v֪e6?;%UX7iw|(6 cȲ\pN6''ݽ(/~W=esOL haļO^}f\t9nP5_/OswKIs's\ܼ'u|K>}N.?YjʤcG X/{s9Yw/_* wӵ{=4nm=osc^{QN퓅\7 ? sjT~}nØSMTHݧ>i\ӧO; Q/<2Oql!8TlsgɅ.}O;Gޞ=ǝQ }䃅5] գS"l恇K퓇r3g()ʴ 6fy޺yya}}Ν ?D`WشdEvQ 2!cՎ-[˽Q)9Պ[7O06n٭+9tt_厍ʄ;cM`~ͻHT4i wD} { D]q =V{DCʝ[{Sre&۽}*/2%)5++-- O|62Qci91R h!ܺf9.#?-ገrPC"ʲ\UUUYUեs166u:7oYbՐcZXedyYs64&&ZDEzAeٙѶM 4}oo4it⬸ҍKrdNA~Gv: 6n]'[tB !"X'' UHs+4A;a=W=#х#D5i\NYq{6o]ɝ&mٸצm(sڍ*D$uppELN]v"sjJחVx>/-5 aj`}uٞ:MVO voY:"m4*DF9)[7lMk55~gltbRݗw*hrSW#xMg pZ_s )Ma, D@u|JBa~NB=XsM6'%%\.!B"q0!1U'wxlse Ln=<]~y_ QW/z+mMh{C1Ջ{ ڸ>}V}-`駷=^N.(<=y??$8bF D|d  j͠k>)n&PT3fl9(I-_v4s`g#ξ\!Sp4$Ϟw|4@iШ,X||u#.xæ#2 D26_!QG}rK 8] ! RJ=xgEs'Vi;~>WhK 9 NPZIQB` V@H\f< 5i,mqVBhjhhAI+ 3TuP ZPsgJk Tg`[z07)U!%$_PǦnI|f6@yuULPb:)TumڕdKkA%!z0. iTNUUsroB@5P޽zl MI T(Q=dQܶsV!ZP53%ՠ/fDna&&KJ!;BbQ%S449UU5%hRwǒ~~SԆjv.)uM A&I+ۑzP3I>aAM3;{3AH/ב UU +P*{ I(L]ԦzfTz܎Ԃi n8IU@M]NH ?Ȁo,X8cS5Obvvȍ@0`JI]Ð*m$(@u?ӗnHX[CV-䁈JqTUL' S(/GxUޞ.;¯?^97sOT׋郓~^Zn0ut޵nxOlX 4(&T(.]wQӧݳnY)"DvdKqO J]Ӊ;sӟ<}Nݕb zy`t(rs?ap?vwW[c4}FЇ=WHbw]!Nqj[ngA\N&hGl 봜:Wۼ9r`s>p=ب-ˇ!PWZd! |jpc6jЇڨ@5 6Y[;{Sẁ%ZРzA X? ! Sy&iv\ܩn-]c!ۦiϧ7Z>@|"J(!Z_ ^-t -,!`:e @y5Xit WP!lԬK j.1!PW~Ι+Z%EIX'pN4]#ґ1$" A ''@EY tG R)(Q &!JTb JMR@VdpG:6r"DocCm=B 9\W\`JB\J4( %LBؑM|/>0&$j>սMk + 1G޹񌋞7]W*5HMJU`U 4lV֦ `&yֺ߳C~CbSYS}N_PbU}Ǿ@qHxu֯(ahh׬ٺuҥk.1~~`4ۯ b хVZ~DZ>GלP&LݓյwW|z]Jc{ߩ0H({$vLїPvI'MI/,s#-kea ANM˚{&  poiH@7(|__/nʚwC(@AP Y^ۿ߃obRϹxp*g>z\<31֩}8m]?Oo7L&K)ozyW XVN;=;| 4Y# PIŗ_xQ|pgU@L!\7# n}ыf޸aӶ,өcƂfMkX/]wzڶOkk)"t_@ϘX :;i LBԤٷ HOo+[/DS@n r5+r ݃|0qY L$%sׄM~%deegh*k|/i>}͛# i448s x0BН:t^u'ꑟljy^:9(:7]4tp5H ,d)BNA[/l¼h6|mt$JԖ$IO3 +ͮ  ~}ɒDZFLO+/8ׇ/y|rWO8Jgq0&It+<?隩&@eޘa?rgMC]muUٌzIbܷٗ‡jŤ.}tpDŽN4& Lofs43g{} nx[l4 k˷%!.`=c9r`UW=ԃ1զ} =^\^^K?귺^Ի \hqoܾWi5+OyT+W /x54>TC5Ï0 zSgsBB\tbgW>G:`T _B g 1K$ɒ;>~0f]22sssҠ/uMMLl{$펻΁@s <ά- o CK՗Q\QDelϞn]w͟ yЈ@Pz H)b'oqܳ~=1ݢB4.i!57J_) A`k70!#c~K I17_sWֺJJFI5mmr$m3wGޠr%w]K;=*aټz DF}ܹ5yrxe0i}1{赣_&T,(Pk5>ǚdZTb;u뚈?/ܻM_|-gaUQ6o~4o([!221aZ6 Bn#77捥rDpR>B JwdK$wɉČozת}($dY&@ U4}*LVN;!NgfFƮݻ6(񤦦ض?B>?%mlllllllpbת`Bbjsr[n[o@kLrƎwMN0ЙD e[nč,, &6ee/3 +]:6~59 s4v9Gn' fMsƛFw)7\z/hsԠ2DdD۶.#*pWJ5o7azo6J-Jiݭo&lzm Mlf}MěJ)/5L.8@*pm T@f @[nsTxIw!Ͼm7p*!oJ7@%_7w%tEXtdate:create2017-10-09T20:25:25+02:00Bn%tEXtdate:modify2017-10-09T20:25:25+02:003޺IENDB`Eqonomize-1.5.3/doc/html/C/figures/expenses.png000066400000000000000000013403741416454732000214070ustar00rootroot00000000000000PNG  IHDR0pgAMA a cHRMz&u0`:pQ<bKGDIDATxwy'9ir $$RD*rZ9]{ks[`9)YђH)b@Dy094'qf3`I<5t*t_BP( BP( BP( BP( ŕ!fO$ot} BP( BP| .1 n`덮BP( BP($_X`d9 ?7 BP( BP(>K8,ExBeV^@Xvc9 A9;+O?ˁ{ecKX<U&CJRaz(P2b3JV _^8>V) B`aCGG?Ѩ[VMq'<>ƪ(Mk¸x#G!$lv·ee9(^B?W{pD9s9>T< f>O䶮")3x|{KY~%^Tw!(gn/8kvq09I#]wɢ zv䢽w΍,v^d ٻ!'wׯB@.>ġG$#)мn.A^|{bٸc?)bf!m!u?Ervc˝w֍u\oٹZMIxq Ƶ|>Ǝtr^{ȝp[D$RwR_axlEx* BP\ZvQ>/cߎ%!jB?HQA Ь^}7lCI%AAPuܶ͝sgpg L1C)7$Rs&G~S|)1!֬[ɷg"6mǮrMhّ#oeZ1% ]\JEGwsf /oS.zZj d)kO=z~cʜ=cQJ]e@bs/ >w R /Wah5¯dF~i4kA+%ٹcx YD^`Qs3)m3ǫq7:'%ؽ]>:U^T>D2\,Zyn5k㵉Kw X]K BP(#t݉ }&VV @$z!44]G@AfbKC#YyQSri躁as.hn>V }j]?[i:͘3L@u è3cٶ$f`ڜrϯe!M5KwcAf|x CjfíwR6M9S?MC?3}9.}]iES';-6nè[,w vnMW =7_k0Oppx 'NMsChc d bf1~(GNԆp+mF?rd5{珋YcfzL#>wJ HuQo֙YS&w]{{EKbzovc wt;mohezL}/BU̮m/`*p6K!B@i{Ln @89w^jթ"+ ,4hqO ʖrZ"f9=@zs;}i @4ʙ1:#y2>4p$65ML"skffT9u2vÁv~=t;n ݎݘډK8W\Q( B\ B&DeTfA|L_ aoG`p4F&_jʌO BG,Wr4_bV^I5j[l $g{cګ>A$9Gp)q#6sR>F2EKۋ:Ρ1:Wji eMFO W39xIuXc_x-q6 㽜%o4v.5Y|43fB4!fD6 F{N"FN?igUme&r{-exmiI@0h0xECr7* xY)crj20+W,!1bNw`d] Kk="'K2z讼ۖCU1?DUKNOVxYܵ`},tweKq,tIB&ӯR4]8n*o+s=``$N6_jdQs "L|A&9t6aDlCO/Wmf9 %OmCE[M4Cxj:J{}qw0v敛Xe|`塹CJ3>!_Զ=Rږ-BMKGsi ðۑVӻ4G\!(9si­XV^r'nvS3oP0G5u~HrgljۗX|'[Yn}cBԅ˅r^Fɔ4/!ff>P4tb ^ÅH駷h \ƒBjQҹ8C,hm%yg;Ϟ`=i:tus؎Q6%iv&2ɩFj,HtpimsxAm j}/_B]u) BP\d@2 C<6LY8ƠguB2zz?;vcP}qf)Ol4Fv:VΆo=F4`e8s;ocw)M䙗`,kRLK;H<.Sɫ$-;nOO{T !$3&ʛRmWC~S)Fx_}x skWS{*m7LLLR(kahgw0)hc8/?qpۏ^{e?|;( A>#I:"~ܱqtM;?θiV&RQet@um$,&HrIW*9gppI ҂3]X ܾ{Ẕ˿]ɖ*c !Ma+{O)SyG|LA61dP)˵t|t\C!?gxCDk_ӌ ů '& =pNI?=^<0Fy鉟r:)p"g&%F BfX4JtXL\N!h7۷f,\H5a!vk_?|?#g;3?*?Td( BxOp/P8k^g8۟mfin\LQrfמ{^RaeR !rYJۤadD[ICXY(O|W-`ܒ)ssukeWQ6̱<[ܶq NMR?H *~dEi۩iiCN^b`ܱȇ yok%PDk} }5|6LN}?ˊfeʥg):#2r}K\5~=M9ֶT%W GXӲ(Zuf8+ic<' pFwGͧVҀ`*lamSk}p;w!m,߸,~-k歟?Kߟ*#Б/LO4xsA[Ț5t-N#um1 ȣ?ɏ*__?v'Ռ^e݄Fa HH>ͳϼMbtk9]kShN?2e"gz|mf6JB7?xaɷ4uTyViYTe&_MxJY2.B~( :̞#9nyp+W/"SXxl9Y}/g~?%>o}3nA]ê[呍JM;6ğFXմvR<;?ćVaYB#f>Gޔh$6pOҴl\e2vE#9nl8&R!Ln3~WRѵl)[Pxa>]waղN X |iaxxW-x|b¯}b+"{^|}cN4 w D*!A> 0k4,)IF8Jb%a)6jr;u.&9gMCS;_gױ2={TɢG^սY~Vo^OW&.4@3{N1X EV/a+4 w IlrΉH"55B6j=OuOGBP(e+0$_G>I:xxDH]\,LJC[픭ڰЭ$czU:cd I2ˉc4MН:IчpӴ4Ic>u؄EلP"|1-!)-fFhv~?nW*c4] ,,4%/E>I}(6py'Zjʅ"Ӵ 3o:?)]׆UsC>hбX؍4M$U*i1IeYH)nn{ťI9AwO r-KXᷱk>q{WpmuHɴн -cGu->%z!(&8|d?%Ke,\լjx`&>@/BNŚ]>|^%_ p]=sba͒GOna>kWh6.pSA5<IMc3kP#lj`x- aRWdIU'iaZ$ˋe'PWKC`;?+=^pld@飤\#vXS 7֣eg7_O}7,'l^dQ۞!|OS3ntRV$vGty"T{ۆ,"@ zS˒ t<M`8}.ܞ*|'"t k QHtM -[-v!>1>];tl~: kz 1~rny\Hʥ2fYMIquUƲΫT1@"aWͯ?S/~/|IUq! -r4R]6VlId)o]OW}Pڙ 7GVsvfT-('{JgW E>!3d"}|q d6G(&%RabL )+9n_e_?y,XiM0)E|2{hƬdh4w3FΧi%v!?> (Mf#ke\9Yqgaę| ̂]HU&%) m>+lJpg\L0ʙ1fȊnNE$cQY$Xew>ȝK aϞ&J366_]~v?M-^ np8.g XI8龱YJK_ɩC$f3TBP( .{"- TPsLG0ne ʥ .8C I0BZ&ؼ޽91e\G<`G)4x8Q0V$P*c!VD"aV8v0JhaMwͬ.@h0~Uc65 8f3̼1\$OYq'ϖ4|dyaN!(eb"hZeֻ|!4E4RxfUʐHm$d4]F\d)tLWӢX,V3 .H<;sGyNQ3RQԊwdϼ~Tg2d8w{fq{\<˦L783FhHМ~ֵLgN)O)t+~>{E6zQ=SBӀrkf !MR(WG|N![Є9e}!*˩_tl/$iEI$3&+ 2N .S2$vXAVȩB5a:jC|9őB "d%ф%f/ *qfs2/Px͞2є] >t4FY~o>Gϲ`Eι::9m(%7HGm#۞cOO$t3kJbTY(YKS;+ B`p.$Dh =TFp*ܤUf2c2a"PVL3HJ%4[xp{/Mr8I d\aǶtpWS)[T7E_ȪOx}}?1zEͷo#/yj[̖+gGo0jC1޿ 楴gw̓OR޼s,c<(taIMHj(dDi&]Q!ŷvFI fH9f|"Jdl,JXfE0:2B*S*'9o$fdbDc)&S1t"NԘpkG<6g(k6b5nž|}k3$1 |g<^ԎfޏEA=# Gcqlhʼn'Ҕ12 Q$LMI1>1n56`m޵tq,(nlxq__er\Iun]Gz'Mжz3++OPɑʦh6o5DD2#cGc1R4Iʭ.lunw[ P-Ld,d֤n&w?7b]G7+,eUkY[]&ش !Ž^gϥ1Hk#3z轄eO@o " Lx{.7pa۫ko ff8TW4N@ԲiE`+w,chh:7xkTکLIdScqF }mHg|}4KI⍬jzwKCܿa1p Zy%v[xC+m#N {n[*҈(dǫc_YGuC;]x ̥5ԑŘLMOR> X1-wI&c1h؎yT (3 'jc%تjY:½r4q"22i%&9x|+_Ԗ9%ܺE6%J+5AX^YǚZ;`-#uT\VuBP(L2?pԿPd)F3 UhHu,g>K?@ZFx>zkԶ,a&Rt޵B^[ XqMPL; m"V^ESA&la5Wkc\H6gQx%Vvq8kby>G&0}iR\E.lbɊ.jhl# b+p WZWEj&~q,IѾ$ZURP^D'&Wb]9{ew B2ej;Wimf{vޱHm#u~nf}= Esp43Yu*Nƺ-[ɒlf]~j(M mXA&Pj~ڗã㔼-鈸JizO47֣g9=!?Gw9{[uͽIΜlk)L ;8B4Y}Jߎ%ZڀVQN:VISg]ma|еnZf|ZdDy1][in:L`l7IU0D8F>;p Eh pi PNJ-u.J!? !-_I{B.e4EgиVh~vF$=Edʖ BJ 0D&Ftt&4U47 EUO`:C5 3TԷ4rh_7}CQܭk{2<6 /BSA21H_?9` Dcc=P+WtOm'6ʍ` Ͱw2`޻*HDYV"S^֊uzl$ lU6Vi$D2;HCoO(TMSSp/I oOM} .򺓐?Dc[~KO˯?[aVh&=GeߵS_sQNC z +V* Th QU̪je2I]2V/oMݔqo(r쵝ιi"}&vP( Bq3q_u3{x" ?ԯUL|2e9ihSA9-B zbMɛo𭓘*saogNMSA,,z 1|ف:3ݟL{@''ϫ5-Є@ΑՔ犘.GLT7_1ӮY#ScKu,fX̚y9GӿM̚}ݥkoO)yT8X_/H)m,Y qn.}9]g&ihneʅ4'|߳:4ؼĹ1|=6e>=/%m@ 01u՞+ BP(W .ⲲHiaeaν"7\2/Q S2nu@6sq%e^{[J,yuWsiy{Q9\ u5~2Eyr:K"W^ tac`n^d_E;碗Ӝ~wNp˘q5b NMsLϿbo\T(-Q|<;Bh/P `ZM͕xn/WM\{>#sAUrc-GP( F+ B1 ioG{FIe2ĆOsևɣV@P ɒ+SuW( BF)0 B0|(Tj6]!$) BP(7 ʅDP( BP( MR`( BP( BQ BP( BP(7=JP( BP( G)0 BP( BP(BP( BP(P( BP( Bqc (+1_H "DER~peLԸS( B>@)0b氺C@0͛cZ9166ƱGٵmRa/еu؈IJbH)q8\jB& g|+:IIIcpP੭z b$>:a vX'w`Ye<"VBx"kG'(I݆ ˜-0UW WQ`HOR.qx|Hցkw`ngx^Δ?̱TN]@$LDÁ44#941Ζ5躠P2,Ӿi%I%lYelJ3k&|rDP4-KM_nfh&B KJLKX2KØ  JH(dLYt(;gkr8b6!d*u\!5MHr9D>?.w^) BP\cf8iSm!\nFt^ä|>m.ZF\3,VZ۶X)%>˗s1+vX~=Z!GjҺ,JīSǏOl66mDgg'^#G Du.]୷^dҥ?W R )MT( BێfY~|vb K]-t|aѵ|9tR__E.eaӜ:uǏfvg.FMXx1mmmWB/X,!">0h 8x Xpc#Kei O)a/B>N|-m+hn 292_t`|d?uB^˒82krR$qt p`tYdK&:.&uYJtַWQS-@0&R]=cįk %XItǡϹn^eMAJ:GpgJH(q,s `,ch+O+b߄W__pCӰ(o߆G&al:o@NL N|5EP( &+0 ?dZ}6/^̚5k0_֮]߁n\jө hPـg2|~]H)]lyo}p$a{1lS^5\L6mӴ,i ۹LYbh6Me+- g[޺ZrH6\cUlN}K[VC8(ZF!{&H[(KګoiLJ6;Ȥc x~N<#DCC4mnܵa'ʔ,:Y A!ѕ6 TUm<r݃)3(9[q*`&aGm J3;6r?d\Xxi[QkZBn[]s{G)a+[MH:،^%ظCK.ҁ %Odd2I]]]ȴ8qRs۸\%+hhlNwUVx{S пI Edv-ax]Y4d4 :s/%BJ_|(bris]Vy6!|}r[;y_P( B^\ui,y`mә+2io}ill|4MhI)xZVϘ; &,,KhZ8uISEkRJ?z !kHFZZZn_tr.]?&9GYلǥaCG9}8A׆?hi4]wσ=*O5UFh\#'1:a.)TE '>~Ke7Բb}5`$g19(Je"$6 :X`HlvK>oqNU[ԭLgB0ܿ{kDvaW;äѡ8j"Nd J/ā}L rwz})2N,1%N[5]ZH$Y*keY p2 pÁ1IRX1$ΙCCCTWW΍BAF*~rJI-tcL8s ߁ַGz8;2[Oc7k[TpX˔ Jif),-5 u"PDFFQP( Bqf10x9ˊwAXRC?<0M}a!Lo9V uZZ[y_e $?(,??;ueieKyxrۭ3g{Sx>ONNlj's444kz\LSS>o wrg?c)ٰnvm1Մj>ľO31{NN%wd3S1& abMVXϕA Dc)Ξ}@r-PD$6(;tGt4I\StRE즎.*.vh^V싹TWbwɉ4 Q^nf3"55Mtv6SL% ӟd <5)8]N G-0|jƅd(GZh. ˶v&Q*fr~FGGijjb֭b(`|#G8r0b +.?Yߥ!5ĒI+LH8ӺB%g%Iݵgs3ڒ%"Ub384\byk5.XΔRiDTQvk s.LqBH?%%B`( ByOtMˤ\.ŵforEJɁhF\fU}=W\n;f0 ո\.N'8J|&,fa;/H$‡|?vxQW[;l={e/p(J7tӧNǢET*9q?}IZ[[C~.71,tƆ:2Nw4@UTee%M_4P(Nԯe w}T L+p;KdS'qEM]'}INkb^XJ9:O!44Db=vW3r8B%u(tX BP(7RJ&''%fzi]$ 7+g~FKk+:GEA__/cc[vC_fH M`P(ϡCYtɼAKK r\Ω[M)N/^̇?JYV lݺÇůHٻNt$R B b1p3P/?\9 A|_gz{Ϣiໆ-ӳ9B:Rs4/~@* Ng l-SGwשn,=ӝLTPuT ;d#nwcwUdţM:Nawkyl7R!8$M{GS-!{ 6b|۔ 40AM)Yr%6NOpݲG8u.h63N>ilܸh4ݻYv-^ofl6VZ 'O`Ѣy[.[Ӵ?B`64MR'z+ ;Z[.][3x3 ֶs_bsakc, +(%6*.S@BB~=糁LB\> BP(nf2) رЬ}c&l{w^16`㔹g= uW4{v!qm[nZ#$ ;/;fF) TUUQL% 檷m|riݨCarNұx=eQK9_&6p1W\*$Ҫ4Mlnʥp5gNCuƆS]dldHC/}2I.(K7r FǢ8xJ +B}V&pMP(9ikc*sf.w_ >~ Mj-wx8o0?U~ $ :w 0999x͆iB}}=>|7|&jkkx<3;;;9p hںwJik !XxqrV?-旾WTV$'3%95a6:l8V*c\V˵\P( L,s뭷^{!R7xo}~?B;bObv$h2c۹;y l򾊷1Yz\d#b֭S0^஻T*w^O슂y^Ur˒hdž 9™'Hgx}U Rjt]!,HbvGul\E:xN'NWbnxsam6lX*bpSDA. qsV좾aRYG=Iz @:K6Kת𻣤bi%=F27ꅩm]3:i \uY9,raBPHdxRJN &S 3gEkƉ'0 buuEXv-wfǎ,Yua#CS%ݳHKX?ԩS!zsrOO^p$bǽR+[V<͸兀|d_u^iUTWi 8 S'?G܉6Vҡ)%NdW!t˚ 3%$ :(;t<~8+\%*ŭBuvMU( B?OׁK*Ox-ˏD"Y~ښZ&&&X,aY<߈=r1,˚:JsaVZu]3L[LMӴ9YXdܘx[H)gBn7|e˖d^زe O<֭#˱pW^Bhu9BVBםHd3 l~fD.Px㚆cٚ:;;gj٨4Mbxf欔!)V#۷04+ D;SrqJ86I[n.+BP( ōB)0#H)gVlٲFGY|9l۷k֬"%eY]斖˲سg7m36h{2P(sNFGG"J{n8\4ٳgRJHi`Qő֬_9]>[ְTˏĉiN5pCAzAL3_7%)Ta#Ҳ^/i]!D|D֬Y` J i2͆pz"Ovyud2/̇>!֬Y3|>?ǎ4Mj.c}3etbeu"HH?z@TGlx bB6[m0ah8v )U.ᬩlʼn,Ga&5|4eFn, fL`fXC$4$bjV)/ BPgX0 Ø0 4]/eA 2B\. !p5]ׯ0*0 {~)j-[ֻ9,;v&D" >K) 3>,b]h'>Ijjj.ht~FFG;IӜ8qLСCXŖ-[,GpwF9zoe>l,]R!5 ~Rzoiݼ K.BZEF0<`]*6e;>۾ř3gԮE8ر ,nXn|ѵ# 99{uցn?F4cj.oM>`ߋruHtFԵ>/R3fVHˢٸ]-4]/ ˑdsʼt:vmmm#<4}&K2ٳ~ʕH2̜ Tj;WqrS_"]p+QSkvAB3ae)r,Kr+E>:VRޖJΗЧ QM[tgDC KDΕo b; S,PEOlg˖lV( B^\^AXg~3,q)nWT48@.l!#B p))LLLwK*&L$@cttt,\)%NX,6+H"sd~@N !{ZN8ΑÇl0%|cNnmF歭skllwCCǏg+Yz5w%N$m4`B)y "r|>eY3-9 7G=cdu;RфkgkC|4k6|P];+I]}|6Ajr>Auk8~6kk͝okejVmeBhԷ=D|0HhZzjd5T;XfrxW,`I)qܜ9}ޞ)yujn aW; BPl|$ AssitR.7[]vRJ-Z4]*w\DB (l6V\Rar~ !ur|XI `QgjhƐRt2\ne[[WOǢk N1RN8A8fϞ=y<;v젭]v!$Ox)-߭~v|tF&5v[oA7JJFt:n_Uρ]1Կlvˊ ҕ`]뀂RһtCW?д`)!4l*ƚ ihv]CJJo\.q1+!`llÇϳn:jjj(Si$`|bV0s@߄c1xӸ/ǓRbӴyg,k`w8cYxFWث$p>M{ azU[چ)P( BbfO$3vӴbYւ7L1c>;HBq=8;fP]H)Ozp:ӕ)Vy.t <װ- VMӧMR|>Mawx\<BqcP&2>>NssuW]iN|ds9ѹx1/[>6G"O?\M"t;jj<abTtvlv;ڔBP( MOOU| BX8x|>.W \.@FWWqiq{!f2Dc14T ˅離+/ʟ}HnFҢP( BqpIBP\gBмؾvsǃŲtϺ_.-> BPP :2riP( BṖ#BP( BP(JP( BP( G)0 BP( BP(BP( BP(P( BP( Bqӣ BP( BP(nzCP( BP( M17 BP( UCJyP(]e(J7 u4-rTGl7 v3>.ǵm:e*|5B P.7 *}EB͙˲7 BLC"{{ĴXfGJuS882geaYPPP(JP(w3=(Ҩwښ_pC|B`Mnt>  B\Fz> -r|0iY$ iR,a;BuP( k4 ˲R}uG1>͘m;2 =a|:#%(06ia )%: ACi"67'`2D BH)g캉svrrd2 dhxl&CrJ1L"P*7>v⵸GP(C42sCR,Xr%'r1::ʡCxWٷo/Yex(uku!}b&& HFc!IFgdtTApo0BGg'~Ǎn5YHrp׫DgqC]\1 4CDM3w8Eez&oz 4'駶3jfegebtQO}4,sd)wDxP(sSP.#]D? K-Ld۶789kݾS)e&e fi9ih$'2nǰ)H/ljp;tbPyg@i:'q=(0><RtS.Șnk>?9uý:ww+ӟp78< L[ R)oN$!311ڵkvz~I&9=DdR琶 k6'⸾B:/ᮦ6nۅqϓݯ2^alB0::X~4 4LMb:5uD`>}!yA&NQ4M7K6Z們~DpdB`I%tCb B\CÇyO2O$ay^ym6schhSoƖo瑏>n̿*_gOriDk*;{ o?3/eOކ_TӖ%Gpf[ yB Wy>Wao慴|svuS^LcJ"!D6-M+m,^/>w(.(g&sB~,`q"6)!_| )+)WB ^bCT{>D$kqh$qcHM'c9З99g"7ϻXFHkQl8znr9l"Y=B^.JU?;ͪeY>}X,Fkk+-rQVH)헕UA~ =E!l{06Yv]e ;7X?x_H pG>i] @>ghpDoQ*D+TCOqvB ӛye63֦s\(3;*fZ4YZ3]1d$Ss2TڦNiZing[1N0x=C婷LLBp8gEO~<[>G]8wr5.1f Ě):ᷙ60w|i!OZ5sWChS4".0!faqk+ i˂4")4qq@, q.ڬT7a/x~ǃ)_-)WʪOt֔d,xhΛ7ƿ<'c)1-kνܼ?֔M`se#ҴR5^{2!,szkVݎ0]Z FLe9Kn1GXPe^Myy߼W%- 3N~BUbquos7DQ` R$L%mKbj\.76] >^vqDt@Tg߹93-q)Pr'%ib_®i-s8aj]J]յbv~,Út  Q`$sQ VÚ[PYc= ]hZe?9=?TGk:@eFN!e H͍ycS),Kr=zy'[ikk Rxa2$vߡLe(C!6 {[X6=}ԫ5],W}yL퍄6^3cbgL=<.h1b) G}2,),xK!4H `.ΈEOrt6hSȧbOIʸ"U Ei#\BRn8fsQ][Ǯ#-t2J<[@20ձ).*IF'^t$]ٻ^82Ɇ[4Ԅhmmm-ZxõԆ=K,iQ;_'ʴs@|bU,[h@ݱf+i)nCyK)qXﳦ PH#'<46u'y'=`mj!Z[q&Dx*K,"TܕmU"6%+N(Xk zf"RT".E&1I2pYG3{ 1򺏰߅ HeA@b191D"MYwQWWϹ/-5kzǍMG@hJybgHFXx}`]GL˜ XP4:0'Ol4vR*pt/{:Mq, dp$R[S (G)˸uԇ0E1;I4b,SD[cF>e`x\Yih.APLO/1u('"/VZpP8],⠉M1GӢ0KBw DZ yRb&8f9astנ36LTB.=d^L*BuL*dɉQIR'%kr>x\B9uL)I* 8[z`}+m5^DbS (L8<##0MuAQFA~ՌGP(s!ićx{ao_ߡqL&BLS(ZTO=;c1҅2. 2$ ' Prhmn($Bfe (0 p$'v;vm`U[uMԇ#\uI mDsR[_ϓ龘 Bss36׳m6֮]{kTWWb  ﰷdlu WUpƂ 'b%u~B:ى8 RDl]Fpٴw,ccdKc$%'l1"c9CԇL]u6s\Bd2#Q2H aM P(1t?OwO*l6KP!MA&ѣ8~lAߏ墱ihVSh{t?c"wC)KXI!<'rDFd,۶$ZMOdaj 4FNO| u-!x?/ ^tp6l8 Z/ ;9%z(j#lE.h?O!!Cgdҽl{yZMS:ZYB9zN/Z@9ĮcԵR>+oAsӂ4Dz((KTWGgGvO֭}#=z@b,H9{| oϧ vYLg/gV{̈́i8(xox򶱤9oc#y 3᷶g_a !vb!J2n^yMv꜓o'"k$ٷ?{$ǕYunx9g4N3F#5w{#^F(jZI#ixC AxWuUw'$@0 2syGR˼d}D#)JN%i$c㢌l}JǢMq7IC}%˵Cr#lVUeRYMk},+]t>7d3Ko>$flF#?A"zl:QxH"8yVV]:5=nPDPw}$a,gzT5ף`>&s*v wgVrLv祗,*i;ؽk])L~|?iUjak?TC2w'(AN`T0YҐwxxm2 tB|Y觡EuUEcP8>4C2>']K`#ϢycBLSXږ$dk/88>ͨz4&]hnoڻ{j63t>}'jh(B"߻H3.d.ÃS؊JpgG85!u>N[E=Ɂw_}gHsٳY'!C{:2QV@d4BIn^($zLNNyfEaddjl66 ՊnnJy!vX):X,/T3PHb=7 !?毦*h'6ũa4) pylM]54ǣ<;C9O7v1;ΎTTзm^p̈́0~=zP>,R M敗^eZCkMg:`$Բp$euuueartSUqNb*A,e:零bJKK9x SSSTTT@ P{aXv-qI `ڵʡC|߽d!N.ƚSqe[A66̾ç(_0Ba[:ю>*ܒEDgٳgRPHWy~x$y@E5eA:sՎ$eŊjl+pS=(P~ZJr8wD><E HFb+IDATi}h9ںӊV̉NR"Qp<(2;6_1Ux-Wwl;VS浣%2;Kd&CCy/ܔFii{ٴi###D"OD"0?\.) B׭tbI&)9&s3C,.i" bHV!JHq-xTt]GuQROp"dMױjXϬTU/ϗ3@Xx\neeX'X X=%TxW|{ִ`̱̀Lx7,Z٭7yu XTb+tODuk P=,v1jeE%|ۨs3?CO7 jaSbXQA>=J&k`Ҍ|>7xF<ȿq*TPP 'w= },Lq6b+J\ȊZB%~Fd,qDzm8x >±C9d !RlBqi9d&z3QWS\duTR@w(蚎[ʒjjgtzZE].dQׅM +Jpdq 74$[̓ŧ jE0B{'Ч2`Jg16g=(\.B՗r'VKL4ajO\1=Eσ+4D]Eyw݋@1UE# Q:lHG1>#irxTg3=ĖXUEArr߾}!' B**"^o2C0*cGڿzxd/Im!\Mˣ*|gi0B455rĉ477/T4K-jNɤ3P2Zᵷ>_4;8? \?/+χn UVԇut'QU7'K<;S#އw|S.|v;r(s.gq 'T݇#\Hh~q);_|?EQ !X,X,, .~#Z)xx<_{)6KN>O4YX1&)Ef$cdy/\/$,+e!|{}"e!bQJ(/~C⦩>B`q|>\^***(..fttt׍ }aqѴ^xYjY&L'3uB&>M }U\O*e!Qڨʯc MN$W'e[Sa8/~?>XZCpҼQ`Af˹D|GxAF`C,jb2QlEZ!񶔨"zlC12its\hShT;y cR,Lt^d] .Ց ij"~f*rsWE%B7馪d!Vg/!q#1oIOv /=%V)v0u}хM_.5.ccvd6PYZFk/! _T-@5]H\(RϹDKq_rz:N$Bqt>A$= h`IC19|z1Rv!C˪Rg{JWXȡNC‹|Y E˪2)3 &'@*%<ՇXPT;5 &L%G$gfQN}B}^RTV0=tgNB|t.C<Mk~z#LWyq&08}uT'(&˦ $"~]^RB:KYH)BL력fCe1y ai""*@b?TZ/T^r2kn.Xzv_&6|f+L syڜr$Y(y<ԵBUZS\iJG9z*$ ?FOO櫈'@x<Ϋg֭vD"A*B>"B:فaRJeQ%`9(eVZd2sEh osS0q g Jl*tx(nog*c,TB:Ø] :We) *N I> 11111ݹ)!$F>EtK0sG (.' v{ *Y}Ochȥ/^A˦wyy2e}kysko`mCy:^w%N+q|nhŖ 38p&IfdRi4tȓLɤu³e'R3yfI4Éг$32.fRd2*+oxڰJnuE=MKȄSU4lL2EVXA:"ɒd҂!"IʚVqWY" 48U50un?auv/ W(^EQ)ވQttixK 7a nd=,o- )FG_B)rUɤ$dt6ås$i2tՅ̥Gˎ2 z;Ŧ2vb V5`Aclj+شu }g8k[* EKh^N·Lb!LA5*>v_$80Λ{de 4$)R4bIHeҤRi4utky +(ud+ձq*:^:xgAg̦TsAԹ2&ȇ\KJeHdEu,;{,MiԶ.vULLLLL|*$ɶmۨfϞ=LLLSOx71 z ʋ/HQ+V\.}C$`%7 =}LkVTC:TWVҰRBtrnr?._ k &&QܽG~v>@HPE%e4/CIN28< lY 2Cx*Vb4:j(v7[sDQ {͔0]}LRڲU˱]UH>fj ~O1==˪KNDdlB})**9& Iz&% :9@Nlhٳ ښjfN3=JWo`f cZɃ[V bEnbcdUj/cI] z|SzI(*P%u~9;fqPV[G[s }#m"Q [MQw%ꚛͫYu4,HE.h(؈_~ɩLl|MK֬5IYI@3ڮg,:;: gv|E!J.RL*vŁ"~+Dkb\WB`ټ'@My0C q%>+}] wVq2DV"ԖG#s M4Ttv6TJ4nEfgex,z)5ຎ=T!̅G!/OUd2 @ tJp8ljŦ? IЭ09HM)ڐJIu=.0Yf+l.)YMN׬.j2ꠤ}v,*j8!J~|Pw< Qs%"ttVbK8.> RAiYX#Sy2M}b/̙}21CiZV/.}r*$}H$HSЀvNRlڴV t:ͮ]rWP\Rr͹:<t$<5b -%P⤪Jy 5Zi*">KP΂l!q}WP( knXGEu9lxKp3=6L_I)AҒCIi14cYEeUy{̌t?BXSSHG2"o^Dea$fۖkV!Y_ / A8affc7 ;w믾ʟqF/>}$ |>ϏcN'㷿Uiʙ|Nti6MOv,T l&ڰY>n]pQ.Q*\yg%8vᴃ߅"uf{{ŷX }s}2$KZYIJXT#߅>ιdA7 ӰqZl6u_ZE\ Z'P􂃮Spq{~|]4`(L`Z)-qצ&SMWfLJh]JJ>ָ)͑;7onH)_\F7π MT@FpKQ>rgJV g ~vs/T\|Y!IJK3LLLp!,˂b۶m,]Q{z).)Dr6k˫OHOʕkd23Xd <Ns ߿ Xܲ ܧ17q%tRYQ3%/ܔ]יG4z-N>MGGDW^y\.G*B4^ul6t$3337TEG,T|_'5IJ*vzV\hKs>^fWOzYC!;= _ݔZ m14 EsޤYDžPXIO3`|cE-8=UNT;(>N8LN&lFn9ts:ύ+h=~/eU\(6xTZku@ {1s444 F46mDqqihkv3麲}nsvSV^itvvvٰa. )%ׅEUio }iGСCx^BnʘT׸v6S0EE׋.Ir`\|>X#@蔖RZ 2#r9rB`گ#O'́q BksL'aw8 .b /_L>mF!,;br`LcY(/GJPг F w`j8&۷+cy1&'' ui4M}tp\RYUff ۚ6Fqq1%%%½Ñw~K)XT,zpq%VmJYrJ*yeލMbc/f?L|>T X(.|).`޹ &&RJEPq1SS 8t 8N<^/N@0'ˠSMLLLLLn8ML>3,CQ/dbr#rp>UQMŤAuu ^`G( Vb.LLLLLt&&&&&&w8* 3os9fU/# eۇ϶:]|N/Sznc LoD7[} &a:l֔I8\.wodUQ漸Q 0շabbbE6@ pݟHߏfbrKRb1+6(BScs(lrݘqcmebbbrkjp8j|17B|f%;B G"nFnަsI11bc;Ð/DQ̞35Ơ(VL̏E(.3&(BܰD na# B"SSl6ϭn `*rcwMT/(`n$"SSX̜_$ šЭ/)3&)%)C!3!RZZ*U>Y‘UU=>vEen n߆!l6+v#/(B, V͔w }jbZ:!_w\4U(jm[N!\a, 3m6 P(H4n4SH>21#\Sp3碉>V߄m% 3ب_&]3A}' ("I!1ab|DIaܚ>ҲI9FXK%Hi3R! p:-(AEC)ζ=&KbaRS]EmcH#Mv'\G6Bs}|~*{>&?'X Hs埲coJtk3 9"# ȃbRV^AIЋլBe04:AJX.BZ.mBy5sCJkW(VÎ>3ΙHdP_w^8ЏBPU>0w.r֏A/_~λz͆*tF?&i+[}?\ӧ25efvg1u'2(&JHP5R} ֆB)|&!T5MMTHǗ_ӿMx9ϡ%Eꢹ߯+FvHR.Xc~VuML\G.2(wx(ċ|&LB!l?5m{ (P-Jg q!Ify~,8}%46Vc Xj-6Ԃ.1֭f4C'ν9#E0u. %$cc%9SR,*{`ūq]5/gtq: #'w򣟼C};(CA 7Φzo=79bM L.,R|qI܍4C\ iEyMCqWuo< G(s'Drhq|7??;1!ᰢ:`+`[=áK(ϓC{),\"X>Zl6K.}o(rZ~ zqo) \.nȹ.0~9^N"%/1cN@H|>0Ƅp =Of`+Ư`Ó_Fc躎P,(w-.G07w>f.=e[ʁnҙ,9M~"F6ƮW~x)_}]9ߧ'>ן9U^~l\^/hgQs| ttk.#͑fͭ$Z>?'#9[|J9]͍\.fȅ;oU'ްtEye5^kaTk}:סƥ}B@f:J\l#=tSrroẅ1.է cj:?͍ C1RdQA\'Fss:}^rٙRv^Ϝ+\޴$1+=Ѿl͐W][|vܔs4 To [ZGzX_|l:| Y׿5ZJ x_63EMeýOOƉN([j~ EQ67/o2iJk9}Դ%Qj nҕ ͐I$ m8en:#7X~(c!Jx]1ghh+?xû97ʝe$쥤l/Nt Kxm,.s2x~;=LIbN>PǞ@xSǎ32C:9CvZV7cEc4"Xߌ_sLf<'Rjq܎zٻ<5ߥ7( rIN;H,hs*MװЙ9S=$riҎ:ܶo$bl)7?om]t{a >޽ݔ߿}ڊ(6 z:9vr'YVf~Y?WV!t03R=Qt<4\}{pWtz^jYΝ8N B@.j\e-v> 4=I֯ 9o6w8y^8.w8*$RXT4-G˗q}x)U¼A'S9}3Y 5mkYИ9:479~S2e'Nqk7j-AtjZ8n9=mexyEN$##>~QVIEGhoalb%|-: uD$Bdye _S?쮇xzf:x7朲?ߡ/d׾jԉ T6?U[ӀWwO?T#++)GqxN,C=?z9z[<Л7SaOp`3 2CwW3-wĩ;Lo},I~/6}Cq(`2fiR*VHc#$SIn*w#FO[G\0x^!5~~/P| Oضk):ko 5XTW7qT@3rϽS3/^ýZ<"?یS]'7ڦE8{|&0>|'r*{f'ʯw|4&N 99v=|~һLҍ+/&Q66yg Ф$>ۿy]ۑZV.meF6Q^ʂ.ʆʝ8@d9wxo&g#|%^8XJ#Þ'Y!xafxO ss_rzn,?Owu(JK9cp{ذi I^8ayC:<75A~vwmO<ͷJWA74FN?r'xGٶSo|>p4B!Xz7)rtf;xŷ8pjKI? uJ?>1 %-5CfI4^|RjDtm<Ċ2񰝻Bq:LRjFJ(iIӎ_LQjx0 mNs/pw W2ڋIyL0U)=D"MO~xyފ7rwN!,wt46/ IʹXg^wFG)^-wl8%gZ7!+vr߼Eo4 ;qW_|F|^{='z}!ZW 85୨o>eUqw^zq290x{3ԔFRUUIʍTKd)+aSN7~䱃\ܻnPY-YėJ !LEyLLLGxx7‹  p'L{h*Fk b=xC*8X4u^Ce *6:d&t\JN[K n]c6;FiXMXfr3CH J_TDgIy (dz4`&',[x靣lnyemTжZ mC"$R­4LnKL WBQ8[;hoQcd,~?܄a,ۚ*pZ|s_&b& "3BGiba~/ƓUiTPp:8V~.`!NGrW:d"-) y17Zw_:i.B5mY.zs7ifI+ >?z]+ـБ|wO93$DxRg%xϵQ]ua1PͬMwKf/:D1$m^zw-ym8ORߺō(Z[WN_ŭhAk olcl"!JR(!wXETaZ7Pf3FJv'R1"Ŀ$ UtrU*Lxx6MY=D]px'<.VY dxJhpp KZ !Q\-06Atp\s˹$Sý$sT6,*13-7$K(uZȏO7-i+*¢HNyy%1"T-؜BCP(mXEoshydZ=;X_K:kfٲJ `e:dptP(P#c sB~ GeC#Lkŀ* }%jw`QQXlHֺd(]}oyǖԢ )?{Eyf& GQ 048df10rY&Ɔ-+¦(Ht ᠬ2bd8buu,[U !%;~n=u,3lvE%DLJ858T9/4._x(T6S0d4QZDKPA uRL\1 & :v{d%M[@'<܋9(r9 @ 2*Bq# 9EN8,T V .^!* 2D(Ŋբ"DQ,XlΒ F:OE c> 䳅)bNF!Qv`/ C oxh >)>+>Eɜ%G< EE&gJGgp?e_H9!bttb0.(h)1 K%q*++زn>p?vcǎיdOؙG(*25C籖`&\7rlB頺YӐ=ů^E,gfN9((XH9ף y?/$3t [sx.I=E8xBC#尖p+WAs+@EJlyt+Ecx3@WS(hIE7ӂ"Jw?rN;/|6H P={A^AKTA.9Ήscfy_gWQƼ B).g9tf%OnYN>v|x|Z~;*N/!K4cNKI6"vy#%r]w.%ӳRVYǡ1 ]7 ݎzɼ {8x C|3tR?n2EW*U ӜըbJe"'8Eb s0PPE] lV+gON!TE)ljΐ3 lh(OPJrxc>)F F ݁fA'f ."2@QocE;vӞTcAt{!41tdb,g{cp\ѿDrK1a9micwj(WEvO IgMe s[l}E\rX \{ek##g7]84 }쥿*˿W_HL& Ȁ!(lT -GnrT*  CvdGټ~#?eA$6#=Tt&QUtt=Slܶ*ÐHݸ+\ wdBsL|V2 &)W-e"N:l* Zւgab̂1x@( #]tE(rNSJkػAnk3O~3 WO3Ln6nk1E@ ӓ>7NٲGXQDQizz:15>h\^#/dKps6y=Ddd2N"n #*\Zn/~| 4~4bVBc4a:Y݄]q tҐB2谴`L '.S:RJplٷ8?0{&`,6F&K82E"&:ѮAykbU33d?OM^</X.DH-}i±Yis)ut17gY;{Ǐ[32?FrGN3`ؼ"q|/dO/Bt8 aX F!T vY%9w`7}Yi |6%%]a/ v&dv{ݓHPI%W4Hhu`ǎmTQRRᡦ99@#tRz/ՊHp=pim~v3UM4UzO=М,imgL_x]'"ki"2py?J+D7ft LI]c=5T;8s}GN3:(:J\):; GaQcOOunMpaFu-3K$碦J3x{ K6bp;M/odI}).HO'' rYʶ0H3x.c@qeA܉dkv<; 7Enj+ .Pm?BKȆ}TW<'đ5uUeԖ9i?΁c瘜IBזbWӗd2)mRBjz{`h`Ξ^fkW/j/} M0Ʀ 8vǁ)U-U=[$sh"jcQeYRanekƇN ƩniЩ}}i[m™C;t:;TEmsywbV?KP Gχ'\n!uph[(rKΝ$<3)fRt)@"<~\vJ$bbio [ddqxLH  vXA1;=l*]D(EŌϾ!p׃n_N`R]dSqbY4ņ?cgSDcd4Y B #"&3|.d6I8vw(KʼnfhUUQ-6<"_AJdlX2;£Np9p8tRib3)`EA/1ۆedxtp9g†im,6M&/Qv@a)"3)Px!^DžEw7lZ>b>'6=MiIɥOǙHk:bXh4,yaW_" [&Nϒ7bsaU@yfb,:JK"ex!=6SDfSVťŸVZ6D. Rmhu1"It.$]RqV>uKB'1%O8-#ӘFItb[eMEH| .%Lt[HLIZyIiOib25{|6 }iLEc^63 "Qy}K>w!R>C4a6( x'b(v%xX8lZSp)NPZnL΃/PL 5aj:() [zˮ97̮79-+/!$Ig/Os. s /#rStYk0.|_]\Zm4Q9㤸ů]zxkū_Tr}W{(]vo_f|-%}0\" U2tz\Z?{qQc s\U]E~ .]\wb9Z~}K|(w\M~.Ǘ{n|O'o"4 2e1F->bCsՉz_C6/4Iȵ*W_-M-$g&IR^Lo^SAplAkxUA9timjZ*| yn]}Jxl[תpGgy}y:ʸ̍ɕ}>kU~u/O4e}L.êAԫzzǵ0WY_E^./>>2*1sn|~| Lnz6N_wѩ0]gN3<Ƭ bbbbrHV??{%v>0CxO'_4VaÛܦAv ?a\(/$_H&ڵ?Z蜉C"vM F0lVE4( :YҬP鳚'P&&+Rb 5?#jp51110 &bиl >BuPFM8]0>AXh\J%=s к<4/|]//mOdr{RH E#B&&w8MF!ׅo}J CǸB0[\7fbr]!hrp] ][}&WC3}dbFDw B`/ #7[k(Bkڭ/9R(t- X>0'u,y3?m!31BxHf9T/4٧_8T/o&gAߴ5P,^dxp#Vɵ0}LL ̹|ՈGJݮwޖu9!Kds(\P̿S1cP(>{21az`|V-XcAdfH"_] 1g4DᯬơlbrFQŔ&&$ ^O׾m(H=O& %H׌%f7PPI\~OB'Js]^$)"0Y8D_:FӍB[.A|0;|nyMLL>!~Ϟ`j6Mt (%UUQT#š5drE1m]eH'.tC^~o]CCk7;yh<,[ $lIryO| 9v/y㵽$tock#@y$T̸̜3|53Cf/5"R05M4/;-k$vzzI3hfQZYeg8?;Ls$L w*5P/x"ј"<qa+;XAiyv a$cQlᾑ躆wXz[,Ll~=HO5}LLL$':8iլ\"G-}} '\ Igxp )]W%=M"!%6_ eT >9tndI Q>A7p`r{"@ul7Hb{9;GJy[9l$'gDoЍRuVᴪE0QM<s/nm޼j % - IխB4a\wQPʼWR/|G]cN ]&&&w)W/OsꭟX?fycb[]_2< sA.gX0ɏ*B膁jsu\*/eNB!7u9_ԭ,<(iʇp kE v\'0.rPPT1wh_:LLp\{eSAa3* %.e49wܽhdV( WB"eaK0F:rn|Uσ"+)Ϲ0n)/%!VXf5nD< u0g- 6C[A^PRcN8x\% 30śc`~r@'ablQ޸їG,!X)焪Dh^6C f̌t0ssW ! Cy]5;Ot3^@ûw/ xXK@ Nwv]TnfB@vcBY]5#䥋Z) TgAt-MtKr8kJbI4MGqnh=4^FI TJ]}6E2>>I*FuQTӪO(e,#a&c+H!DG NQ}6 3c Ofq5Tt51 Qd;._b`6{3@KAF>'H(8Jq)*aq P{?<Bh ?+sgΒ򯧤U\u.$9֚ż4 lrJ- 24+h:o"䂙.FƦtz<˂|Z&VJڨ.*t!&&#Sljjgx2I(b qW#+֑JjlkA"#L6.>&12zjjO_#fBL _ի㲚Q(&&_Tn@/ P A:WkXTx`&zΐ.*&P26OKh(29d,ԇ;`E9L''mH-GFsRT\F0f<Z"DJbi-lSSdlVl9N͐`.QU)$.hq.n,ȒyKqX-5(Xp& &Ͼ ?oۜ9y3O1q=|=2V?񮝼gJ97MOSTV#?Ω=JC8(<($8/ٱw~ʯ~OݵS9y(^/ 2l1>A2/8O`9`AqFxrdƸ]'MLL. {i+k״1r}>yz.da)G(.fK|*J̸rk_M U+*%v΍dh^܄M")rRA c rSgy痿gt:7݌dNgcSd _ʋsN`$ya1_4i|8,grT7y) ;ƞgQ-Dy {[ݥ&&&!ts [mW.ؤF.#\Hސ =#K3x}zxp*AubYJyum6`Ѝk!Bt?+ bȋBbcMeׇHG8Յ<+Nn5F.Cz-r;=5Ml&A'P`/ Ysllx^~LGxI!˗aU<[|{[wWz?s9'  9s KdYl>}Oq6˜AD 09ԹG fr 9Cnݺ ̴BG]CDiyu$fuoD՘]cUR,-^Q_UG6JQW)HlGЯa# ] u,Νȫ-b&ːᓇËϾ̯v=nݼ H2sG>@DA=Y/OĉH߻mlzg0管 @] e_G:~og*.\O%bĤD_"/d:ImK/@nY v˯ќlac"O[:TEw?f<3oqe[V+װ,c҆9kc@i%.EG6%%>tij1(ʳښJ68ydZleE'<5Boh٭$Ltx2ARjhB&ưQv9O11kPk9PN[$ )S!6oP6So<]3)Abd7/˿Dz62 l\rs0GUaQ^UB`9U+XU+px_^GA4NWPy͆:lG @%MRurMc|6=yVUe(g/.tqMqYi9&s*$[UHSߥʼn Sar1K}n-9^6x,qa&԰G܎Ӭ|; Ռ/;͎Yՙb3L݅BbRYm9Dx#-' ӄ렘Stzy 㬅D6̮,,6f@(`ZQ =!j?{'[躜6Fl?AMfȐᓀj Pn #=/'/)ee+Q߾3ȭ߂YHNnfZMޟWȮK Ah!3kƂhmY%l|oi/B` GtӂH0|u>~;nŜaQUW4$C[A5.3-UK_YەsSbZ"y&VÁ#MyjsL dT:=/2dC+ 2Fk+W0Z)]^"Γ{"AIZDCCK\]2]M q[$k>3;a!Lyv ځK+ BA~*Vc VIae1?3r).%4Ì) ׉XB @:BbVSV|A"<ȽUHP0`o? 9w7Ȃ )Wz0GG&a,8!Q~Oxu3h .[Vo!%^&:ܶeLUm2X>+&̦TNC#ÌO _KS:SS  I_]LjRh r^>,d֏y7?!~\<[G\OBgg4AZ LdRbf/x?k4<*=zf7wԈC$Q-f}ye-̅J8p[,L*c2NdȈ剻 %ӣ\ {tڣopZ +2͡^bp*6TL12:Peޟ >GF*eDZP< ݰ$nsg_l F:;(=LCxr**QM9ȹT*";WydzN5 G!v9YN;yՌ~3:si٩1Bʽ!}ޱ0I~@s{P{+sbODR9ba¡YÄ6yN|K|u;[^sDT9ƈrAF'i=:7J͔h$brBRQxCD 毹O$x{8>%N3M"T5$bp+ L0pCOF*34-+L `) Y8E0ԉfbWBJA^ #bUCtr] ܏f-X0t=]}yY$3'e tɋf2*qTQlo12C éMK!4=v32dxO;_ 9 UՌˇ8t)۶㳫o{raWQOEb‚Тg&k>Bk?ϲl0 N09ANIJd# N6\qfgN pg15RQVC r|'lb-t ޹ $#ӌ&JsX( ĕI"HDCi>IOʵSU٬bq5:/\B: ]3q;; 39F^yqb/[: !, iwO\Iŧh?mIW'/tKNBiFeΜPMȯaȭl ߕ# M%$G"DGi?&C5i? N+:;UJmiN;1UkpMUg9p4ԕ*NQUB]'8y ݎ3̕UwCi*C'9sCGhMEM=^;ɩ9LҜEvh;vE>lnfm3?Fxz)\9EX\8S*YQD7g|YWu 5؈2r)kXCIt?θhC\8q1z/䖖`Mpf>F*+qY(`#[ST(n ߯v-ZN2?ųvIˍIɐDR1/4M MӀm5oLR299vCx꯮{2`("xO/&U"z bWjvJa fw9dӸՄ͓Cvx4#PHnru?9;Ho@NՆ ڦ&v+&FGJn$dA-: N_;VDž@pe0ݼ֋t(8KY,33O°b_Wݤ35O\ xpx}xn)"0SSVߺTjQָ\R8s+i\ Â#PFU]-@*NjWR]^fdx{0L0>řǟG߇7\V:(YIey6mvqבPobR >H0`JL2Xw~m`$^|ޑi" fB;) H%=T0Hpr6sR`qfPQ׈c#>5TMp"gx c2P~3>o@pUPbNgrb SgJ,"5ӉvYTdffz%۶뱂]9T4.#BOQ+ᶙqUQU[,졨~5%#c3r;\x98&3#LLssTS]S ⡸~5e9X&CO` ԱjJ֏"AT,d|hY"ZVoH ˅/O͔z)(*,Doo%:1DH (T@ybdh35`MѸV* @J*<SHeU%9>N;$Q15RW VW-(kV!Ve!<6TBşeaVufG ހ^1att',_.<! J8046a-GΎ]~>&djՇßWJAE yH(9*ê(6?Mk("@!>A,+(D!CӀ1 B70Ȥ)8kH*M)B 8RI0@|b1c>7 %]\M y5~/,ŋPҡb}|P ]*9=1(K2n~>tg.R)wlc WO^(zowRK!C>E5Mqo-)y"F19ⴚeabdhl?ucEZ͕NWL^ENIDAT\gflPCV ǂk=77*ʼ4w.&ݒe VqUcW"挏|N3}c~}9DQHC\~:\>r7RU~&ccHb^d[}6n,9 C1Ƶ`J:oN~ YFZޤۙ%N%L?EbyS5 #ɐG"ςt5Od4g#){CA~^:W;(,,ր )_k*$*່$dK|J,y)TRܨB1Ϛ[CQ)>0 _]еv 2|zSNCDQFja%E WɞEA?}v.{ʍ B+6A\{wi}T2|&oTJ|y猏 i}FrK)>'w׿Wd)#ߨh:׿K) kJ/7ĵ: uɷ 2|$(3dȐ!CuwȐ!CiA`Wʐ!'VlP06C 2|D!~m=5!C n$]L\ 2d=}d 7B$0m+yV-%8mFpLj.=6e3dȐ@.2 ZO!?mި|wt/q(7~6Y?EAwf >Thc|@B7=ICXtKE2w!zd#/??stƯ~c0{ WH6?n4Nю3/@ 7?ħ8SɈtNcwݲ_~ v? fcwus 7;ﻌ%*|Bb1-Bqa8Ii&ΗCKő͊*朏Qz;G39j\Fy@ԓ$u4gߑh8qMOG%&3V&! Btut;HXWZXn˨*о8vq7l'9]YOF28©#{ 5;w2*>a ~.gȐ##Fc ,_ǥup-!19]Hb$HaFY\/ڟ>XXp &f+&zu -GJjy& =jF(gŷNހH&[9qýY›bL#G)Kٶ#e+] Q-VL&3<*)&f9} |!Pf(Km(Cًڹ YA!Nyw':?y>/؅4@1{'O/וNO"մFJ˶g\M,.T)CM<9|uغN+*:=~<<|?7 ƋToǭlپMY*Zt ^ *L?oo?6 =6CyE>Q~EZ/Z#/?I^=I3hloLq^?&5 PL.6~k|uG=| zݽn{3 LvU^iW$~ bdx׼/L2֮1# ݴ8hA^9_v\ro)[+ 6ɴzJJ\IZ_pgyGU_xdenxNyAc+{݇VR[A:۸|(O_ٔRqll݌=<85ظYs{w_Sw,DZ!˥ҪOF~~yXr=ܵۯq[xdM,WÌ@CFv^e(,eVOvs ~C@F:rnY}(9Tx%)#Qxǧo<亮iKAZ0 t)dgF,4x2#?@ï$]I~m EY;pX;* χēC~ bHrrs+Ť4@.咛2FF4θd4-4F4yuxLF*79>p9)]\rqDWP_H c.p;gyCF`DGx'?A?/Ƚr4md,s6SqMg5f%;ՓGW,%5}Z [=лY.:^g|l@+ZF\:N^]{|IK( `,E.sKL˨s㦶d/~ċv~O2ϳɽS85 }* iKɚk~_8v}Z 0 -BW_?@^>a5瞽x4:}]@nNfEH& z 8y>V^.|BpNt]dug= ə.%h,Ly_}1:1ykɷn04S~;~=5~ OwSTC=*y,`s>~{7W J~| ۾JeQxRkXo&û}0tF.Ri; P0 t}q({yaȹ^RbrΝ?RRgvr0j4{,/@IQ>n5arRrnPո]δUyu_”Y@uP_w/43v:rJqfxѫ]J{?^ve.vՈ~~|k5^᝸|VT#5մ86(,ጤ)l&ݨ7 29=K,DX0+3Fƙd&Erj{p: 0a1 (YNdj|p\C*fٸm#%)0=1A8 sYw&Gf&$NSآłLLi=>}&L0>F98-,B19ϟdWbU}&dUG.k{lXh)4AnnG:"^dj6D"cqfB!xa&'XYp,؄@O&xsr:A FH ٍe|riq4HDfE5"01-a31ƆQܽr, m0bßaA#albP$!Oy!L0bHuH2;$,cbl$;+兕 l B 7;lh ~gm y JoZsHí4>Y[x*lV #㣄bI0g㱛d4H868aM2gb:cQ=N0ds`:YffØ>\ViFGlj<-_oi,",D,LxRSӡ6a Ƿh\ 99gVKNJ! H2v%[asܢR[ʐ=>B(]GXpRŦjOc%౑L/ɤ'io -!cfaqg;ˍYU$i=we1+K \#tT(ߏjr`( Aq}E)9zab c ʼ~;\aqΝ[jD{5wVbUnuB#0IC*&%/Bט 쯡з CwEFzw 2'$(v/3 4P|F^6 g c-E8q8̘=@`eg_-1b!twCL l1&bcaLZ*T etl),%;)#aHHp\7eյ,u3}{vSd g/0$t_w?9yCyxU5qUOr:źr?gs\<6."S L 6%Y[x_iny vΞV}AjVf//3XcYgvS@L>SǞ×0}Ɔp7[f(,ζL:($ Y%ٜ26BL^Izۛ92H2Ax&Q\֐Kx$P 3źϢq{y?g&o߱)מ`k,IOٗaIOEvpc|U8TAh_? 9e;ٵc fڥ ehϦ5v4֓gԻ5YiHYB:":CGGjFo P/ζôLcU=gry܂dV5U(i{j׿@Q毟no[~f/piκmućz9;JX;dMEx;/=$-!kW-#>|3ūٵczI_-U( y7NwQ}y7cVS$:]/ckLݝ^<ɴ1Z%@ 3܂RDv3s)[x^[LtQNa#EDHV,\W:&V ӫ9'6B#=%%m(Bt~QTd M1*Ǝd!{p dq䕰:~[k10h1_r˖m|kQ=9t>XC|'_?J$6A˨ڰopjFs1;DGBQ0">L+ouX|*pgw0n@cB$E}7ҷcrR|kׯ"g/Vsg80bYu&#-0sW*a5uvA}AR㸧g폰aj-DOX36Aoo;yдv97"s}2j]r9^?=j[)=g԰cszwk!`"S|£jc9| 6`A"Ai6?u_L3 *}#/Q=(\h3ݴWqWYW%߽٢>k;k-O{em5f;m֮jn/`,/'eD[PŲ2Mfw+W/} =g j08!Z{Ը}7sg-8U!%5&:s,;|w y./M ]և}M>auY~%?aGM6FdgQnذ۷>Wcq8YxiEh f{5\l|$`;a9}z$FObL/0+ S|Wó|%^~s-|&$5T%-%(6Nl&BBGHmjۧI>J3ܘB"?*( 'M}͟¦ ,7rjP )XO]VJIACpfS"E0 d/Ϗζ԰h0 꾉 V,K-`C }-C*"i8{{ /2lP]{wD^gws 2dxHʣ/`$h;Gw~CHi»bٴ)&~V &Vi, 6_&6;E߫{ݶg{2^e!k Bl +޻䆍0؃R;A aZ(^XH"*3,4gN51R 6s/o@_\CH=~u BYp gF o+y%PT7u5 N )9;[mue5se6HB7p\wcO|e^^90X\8p]+β$8z֊ʢ0_CʫX9()kWm7 φ EA&3YN'$ Ơ@&œ;f#u cݺe9q?U).ƣgSRe`~oNy/h.0I$.QNJJz)**ﵑȃw翽t+r&ADgY?T5v݋u(&Cׯ"%eѴr O=h?T%()a%>ɉfyi[>67s4ͦ /,lQNFX_@7;C51sm(ڷ#d9Mzk{iʅm!ɭ^eeL\@29sᅦM9X($g:8|few| o:$d" $ff́NWL/[@8,X|i6U*y3G>{?.t{-@T4#[~[ k8Aia5EY*]Wr&"=v3W&k:L$L'ǣ9^!21/@G)3:rI"PRи.:`XxYrzuK( ^Bjo _7=yFRaZ#㌇c󯁔hpɮ"$sc0$0-)T؜v&fB)ϒk^(s9%ӵmn&mmo|үa$ XT~3@JۉMm*,L+2km̏:{r BB'^l4_ ?a*}smS$/XVJ ; nOru}e$̆h6+8Rt0#^ЉECt>VVUv;Wδ_"O*hp8D8!IKDW|'hi1Z Hcg~~Q]^DgH̕KG xx~af1 !REѲ=xuexUJj}.Lr@Rj'n-̛ori$P2E;e{vRqsQZj*qK<#4bCJh/]n>Ao]ת"$Ѹz8R $cא.r^h-(a8mFPoBwW)%֬|Ab-CGE9=GZxDwZ"mOZW#X]t]b2:1 AxjpG~!C Il St- yud#%bqgaa/(ZAY/K_dW@-سJx.rxHr= P͂30x.u~aBĻ]k(7!S-FBCO`vv8z(,4h>~aس(Tœ?t$2#aR Ĝ< v6$IAq9CĒ"0R-,= >'$}^1k-=FDOq‘ ;>oQnnدW*\:sM1B:s9=37^L I8HHK86Q>͌ԉcsHTO1}᫬1KÑ7+ym8+PR=9ue~ח6As)׊I5*JSm#%&MRBGYx;tXʠ&dh"?CT"JhxTRWY =n0=+CvՐF*D~6zCtNRCWx\cPF8w$EeL0Ļ. x,F0ǚScE Ǐ>EpC$bs- 'RNIS`$8ړqnٸlJ?{\d&$:=ɳ]m|ueR} Q˅A(:`wy1&iNA#0u8|<\84H$ģ1bZfBGyq9&qdܶVBU5Z[R{0~.xEf~vlBӒ1B(aHl۱}O_<8v(-}O44$dD2efJp'7o_&H1*v_ 5^z;ž2cz& ra4 &koۊm _aݭd[+rk N;!8AnY*o<ûe7/?H`ݎlb ?6G8Gɺ[YUkkӴ9BGK3.qw}m5v$ " z͞CF N.'JdKCH\feDG[x7flN;*Xl78b#^4Dպll(H'L^ 'RbQ`).NekJ\i (V+jYP%6 oiޡiزktcG=cV䇒DvQ5+tqε24i=[WWby+eȐᣄ6/\de2?Lm?9#&5Tb:$0㧏1CRS@bwZɩ";9㰩f&qխ"P0u$G;m5 ISÌ8@(/)$BÜ8p(F2@WZ.pA^WƬf(ÕSLYq.y%ԗeꢽo ՓOC}.;\r8@)+wXpyu18#6ʩ癙Ѱ:㴨8ig.:{Fɪ]=; &z/qeVrK*()9ٞMEeɡV$+(/ʚZr,:(n*D7N]gova+@ʕTm \衻ɤk6P_1δtPVUGLqizf"س ()l3W-(EIm˭G)cYm)T7GfjZ(f٪T癹x8]3y~3\?SBysh&iSUY=>±gDpSQKt^~}o+qlW@inVڸ$ >C8)*c5!dv W$ -\Bv ]y4-'Rr+=!Kh)!맺[t+tv;qO[t=T%yXr|$:8zIM]TIBO)N!Uefp*L$w+w2h衧h(/PW:Q{@Cezc'ZSSh;{scv/e(3=;v7?f8z L6N®^}` ?l7N\n/:m> ("pzFBJi-tO΂ي?7U*wB3}K32cl.65clwcI[֭ۘSPTJ}m v.wu=| HCa"ϴ=rss[P+ NUQ_Y?RX[PNEKiMsevM Q,.J+tC,weE)VE!:ƾ!ܹv;^``V#+P@eU~;&ߚiv;()WCэT읪^$) MOţbA!q]^C2(s& u \' I>s}9/Z S;jBxS]O'"W[ ]K}G*>7A'C =f(uS\hNkQZ2=੨"8jUm@"u}q8U]:'4FJ7% 6K ezUfJN2p!wY=N;J0NCtNUH4@"bN&_?7TWI)nkR>Jo"}l:dƔ'չQ*|z:^QU4usǤǥHIE`FD7okC-T<C1dJPTu=/ts0d긹~x~KwrJ O cuRS)e@UUEˤ &f,Y8MxhsǏ/QZ@'t'<}?ʍu:!@Kj˱XWzE2uT? )ӹ`Ƣ~?ƫKu]CԏHA}Kw:5V Lezw VYŠa{WIԫk2C22y7RTkԂe~wAp<[)(O=h,} ?^nΕ Ӟ>^ww]DJٙmN)_ƻ%;F5P&/Eõ)2dZ.<^j( (9o0K&T»sXlen 2|%gCO&LvWn!*b.bA$L&zwӫ2ZT ,%w-8:ꂒꊊ Sbg?Wk՝wo),+E?usN^}eU5%v8z͵1ɒm{.XSU_7F$|PaFQ0]ɵXhTG0yzw]yYNjm*f =mغ6ʵ\Zc^f=V?]b}].:cR!6XrIdޮ_S^+#m{>2,T2?C >DkVuZJM$黾3 'ݨ >d+|-^Jtf;&iʌ )RG7Rs3dmI3 exoGF 2d!;b!W-GW#.P\\L~N@*ʋa 3A"8݄̅g#:xf >t2 2dȐ!CO"Q6H(@1ٝ6/2-M}(& n5cȐ!wmB|2dȐ!C > HPL8=>/2\P-xbn)I!C|xр!͊n'!C 2dȐ!C 2dX|8ߕ.s8*ΐ!C1"L3:Vߜ߭N*!p;0Hq~PQHoj;$a|X٩FƍdPTtbV?2U3dȐ* kV߷EAsӟrs4Ѝ&=%հ] @k5k Mv<A7XG `qാ[(*z&d0qf<+VXRJ :3}t'хJ s>@Bk\$8G桴Un,e="^˵׸YB`h1! &6rn, ]E7T3̐!CB`$L4{|%XO# ya"}.0K((_gB' qY*3-:MffQlnj.nmNJ*;>Λr8#Ă22B̘L(,e3(`!㽍mT̰!0b\j>bEEG ՄA"d+g~ rPDzJoPŌl'66ywW*DF#$12B BI5 rc-D`Y{uWPЧ:w~\eHrhW+}aM%X3mZݟ=4aA]M B"4΁1n*0Zz8Lr$O^dZaY[DH!^89B}}y`!UL? 6-#|ilUMI ;zl7Q1!$CmFE<6m?/bgGv7u?(2d tP*$q+\+F)CF2N J\ݲטs ڟ؃s}4mA1L5W8%BQ Yk544 6$n&o $4}TՐc(hiIw=_ٍ̃w- 6>(F NF)D]ey7E #8ɽ}ְ{x/$C#'zTהuQLқ^ ޶ x2=!t+.+4ǃYU13ly1Yo40SGmV7Vo(C D],?mʬˀ! :BK%+aRHw_-oAn\Ӵ-'qsDxywlo{/V8߾s|eѾ>^˲/w6! 'N6se4fB #V*n}yb|oL|s( R$uR/3ˀ/,C 3Bγ fƴ*^$LߥŌT(Z:H.̶paJTL8kןcx-6c̞8#,2(dˢ,yi(Q)W˯3Ç}`w{mUo ϫۘh˖L%cȰ4k6YJjk 2]ꠤa5۷4 $ %X̂Ye7B |31VS:T{g' l|^@dʫ~I/Z=?

ۂ߅%Rd?{8_O.!(dWmgŋŗn)dWKɄ* .wwqPl2-`:FٰeO}[$>Z )PÚ:8ͧv4R`Ӊ$EXMrޞ'x?Ky8&/+-/XN#61XݬaWa#O?@4*&+`h&L$54]ҟ:#Q0իS! iH)0ߛ n 2,$:IhD2f*$j[6r=D )N߲Ȑ+e]ʳbz5S?lyGpu76+p}|]*<oTaJ&_2R CGt$̨ iOA0t1BihPLMJ:7*"%{u٤"D4a\~ ݐ)wtE:ߵ"}}ܳb`MJ]&1RhZ] L&|b2- #DKυ*;')%UY0t !lF5+HT(ZֈRc-IHǦ8rœ5F'a>`Cuǽ;$]MH0i<iP4 kd "HC R:"BM}.d=J{!id A3$+>çvke<g{ƍyF^5lFW7OSsRj`Z[) hC{jReQUL ˈN&SM fsjLn@UMOcfUA[ PMx.>'vU{6`t5fYņBFw=AɷuŘc[b*k6*%K=Y0>E SиW{x?奓t/Y>wTTy1 J^qIEHzU'>!%,1y~PB:–"%+&w:߅PЃ>3NֻYM HTHX|,m`$C\>s7;bmuvfG:8!w9Opշ?=44 DvLmJ>F~&p3'ζ4[0Ovsi{,! F"h'gOjv~lǚs2d>pԠw?i4؋kpBZN3eYSajnG6D?fD :~"M \("5? KbftY:D\R".S2Iql޲b'5P d6qך&\hj0C=?uç(Zg5Nd#'ZE[me $ct].YC vRc'vd,5 P Och:@3,Ԯ)3q-=D4d|#W˗~gԄUz.Lko%w^ĩ ųӏ.EOs{A ݉!8zL(0};VHGr!c\ZH)p261tپalekyGyhJz+j\7?=TlXUcL :+mE H$ISʚ:Hpe&D>ǵB.eAN9z&i;{M-%L 9+003\:%ŞL'SyBB~[+I~_qv0"\z9,aCf5qгz"$gvsw¦Mܽ}:M;og3(h\>g֝4y#ѫUF@ƹ<awȀ' ׹2H甛C,,es?SE!<|'~$鶈+i# ; Z&(hۖIBR*$&;yDصuC3*>phIFF,gɎc|~Lr~ݹO 1ൟ|l^NM=|#'AQ:Ϟ| s>پlʵ 8x'^;@ƪmskW;<nc;3{O#N|>n]a_q oZ6y PN9T4ndUe6Syi"l?/2&+(?kvLb6/;fZM~xO+~̕Bsx4HO;nr 2*&lH,rn'ʄաL2ƩbȼOWb:e+R"5&7ˇkې$'OwQA֔Aj(JBHmR xqBt߉,~q~( 0 maŲZC*i,v3PȚs6> {RNJ6G˖?l)/(3!9~0B((bdb9+Y] v/+XDJ絒nllbeS-^RBV~=uUO RPд??/_~!;>u\WՉV*fZ}oa0/J 9߶r%ŖfFf((, 擏-5^zsnmA7@+Rltɩ)RW/yBtHuX߇bFJpTs[ك$]A"<,,z,V&1ӗ0R n#|'@&i;<|Aasdf 2'@E u5+1t=S#̻ědZ9XEtH0]!"mxjKq %F@ INO-$+{|btg0H$c9ÙNdl*JyM; կ95HucA2=@/ fW,'Kԇ6s>H iqml.1sl+ U$hoghlӯgd"ib1͙;,^jȻܩɐ U >]7 f?'5z/vxX(cs:E%7;!YXIr:޶-o6,6/8•4RP6Rl=VqwL-3|YpglxnI|*k8ppGF3N2 bP=Lji)L]OT.L&ƍcQN'ylDk?/頠R18][iK]BTn@J2|ǻ7`˚PL&n/Xit_W(gOc0@QUTUjWS|8l.Vn܎qu~WhbژXVL3M &kD)~$JV>rj+W8q$.gZ'_ -4ʕ['P0ݥu:shiuʱߤޜT'=r.SsH2*ZtcP,J9NHZHRsٴ'b`dގV.-wI-$4歔21Ła\T-A,dr:D"F!C@$>x8IA&;L:[9NO9 r"0IE*9H,ɻ׻߮-kK-+ZDRbsΓsN=9V@ tWߺuֹ:H wF|n3A,m)*4cwbg8 E7߆%H(p{ T., DΝڋgM䗸粯GJ q$?NpVy?C-J\u,eJp |:ߎPŊjcE&'%JLwzF b)k=NY? (B.r+fV1Og  5 ] BԲy~`v.3%knj{iv16F)O0=%#=AyT+ 2tRDqӗy.3Iƒ[=řh2* Jy?RʌV^/”WFC  cN!u,|K_dKA_'l!g"ӄ1R$Xe֭Ԇϱ h!Νib#,+WԡcFu&ZxpJ|6D s@,I,g|&J" L_O!Б$ ȾYoYÇ]EGͫ-M/@EUI9ya-Q_hGo6K0eg׬דDP)]~,ne"$BJsG9;A+َo{/O{v;Pz* (-1~){{`Ҍ l}<C*MR`Kqf﫼q V h?k! ե&hE/2vɁ0܊ct_"u B#ڞ 5)+SdJnJt=#&prkYm]tutOow-X\s9M`di=2{rvhI7pӪ:y7hNSt%A۱7xqypri.Q`pw5 u9,! 81C^2k;s¯;ijn\9t` {NeX/W,-.6:h줷6h\R;m-^Vf ;87bI3yV/7^l\9x@ [Ney;X܈;{gUK v;cyJrm7AMS^]Kqȃ!pWzU0-tvvMGEZW7e]3e.r*( :[;? ͥ.TںR]12K[0 T 1\v3z"ęOqD`щFAQ1^`3')$l' E026EBs N19Cy(*a,Y0iLyEx0>2N0)q)uN22D6 :,=ŌpK~^!D0~4X U5L89xv=8f#~RJ^Q>312d0'70E-I`t0N&bw`N !5?S3p/%s94M Oxhm0fT$輬M&K L EY_vs9.HfɄ5ȫ1ۿ}̸ܾKw]B\1&r."㾪K9^Q 7lLRN)#w?Ύ)\^f?fW֥K AV%G[ ),aA5yf b .a|_y7MVnS.%Ǜb2[ɺ}_Yy-Yk\-vnK]dEi:0o_ KgN i^3+f煲jQNdr͗%Wӵ~ZqEs*:#_e&̅0+ 9q< 'r\Vҫf9{6[T1Vׯ6|^ivN^ZX\u*m#W b=2k)oq~]zRJ0u+^t8vi(ko36Q"2\.Ly.;[Xߴ9r6WS ~w뾞++lM,z['v=CȵtuW<f_]Urg,+cn&poڳ؜z+^1,X?^m~20000`"uC900000000aU 7 !@"B5%ߟI X+ j\WT*E2M#K.f`%16+olA!d``0LBHݑ+seE?79B s{EoSbF EXQgo̷wb!Ih=H02Mr];zMt&Fz BJW-}( D`(JJA8\n\k&K;h(뺾-#Ɇ@6N_FQչ󑺆vdK@AGh2)& v 7m]d^:2¶?FO5ޘ 2٣'`YUdgWסLMl+K  )&,h"!z (& č#a~!ΝGK|PВ!( BNv[N,&G)ɿţ .GND ätP/V$"A(bⰨo_z^2{o<}^yMW-,FkCAR$SO.^8=$ KI+bٞ PV<^VCg$/X&Ȋ+d n$%AKH$h:ԯa˚zQ:3}t 4P[_Kdvl%%UbA?foZ4* :!ftl).{2Qz +VSWSFR7 tGIJŠzݭ\zcdq"7hcϟbT'3=1oaMNbj R,+,Id2BhdX$S$uVx SG&Hls]*0Nbp&UG %,i;7 Lĉ$WGhVItJbHx4z%nZt %T{ݡ4`&xx]{ȿ 7CJc:uj2Mhr3LZ84QZ/_F" wni@$ȟv慞"^cT~߃<\+9wtoojVn g/>ub` EWɋhܹUEKh=:?m.=?ڲIH4, !i?C}/?Jim C +< tdtx~A /Vb:. #jƀ!5R"h-aL?/g YEJGwcll.oR//6lfnD B9E c*o&QMi'#iiz),/BGym)o-Bѝ0TbU!8s|]DOtj>=,*jRz{^}'zXTMK)Q lvC+:Ǟ܋gͅсy Rb)eͼO[Td<T/gJziZLLJ5t]Tx]g``k0y"l@?+b77Ptt]GXܬv~r 1A(I3|۶Rk%iA:1dɶ?A]Ҳ/ٝ $۾܀ˬ[g}$7//çDma:d`g:c{BSTiJ82U#çyx`q K?W&g 9|ߣuL-NBQ2\1-K1RE: d_I!E\r|69s:,,;E(m```ӄ^*=vRb-]Ima$Hpxe!< 2Of&\{GMu)zi\ӯSYrs LԏyŸʃ *4 /gMC Cds& |Z:P_.[Stjᶀ>O>ŧP?t|;(Kt]"6܁x!11Rᬙ50"D^S((j60X7RJT&LslyuX PM0j@C]>m9 UA QdB2ŚÊ.tePaɡN^?OmN)z;HӄY]}I\%%]UL-+QaCS 26'oـ!/|U=zS9_jn9H'u4agԾx;w}}-d,@OG53KVT$y?GhnBϖ4KTk+eEy:8T0:N:N>#DTTU=Lh\8/b8H(JnRU֔tGtn[vѩ8}ﰾ&/=)u҉$EXjf嚙wFqHQ-k)T $%u+X* 38F0Cq|E9V0)*aJ9wݴ}f?WQdW]#QTO1˖6cSOsbP W6,=I n ,7Ѯt{K(*jVC(+.@5:+ށGV@qߎ#DŽQ]-eyǧB1fDJ+ZgOڬZٻ4Wl^cvѰ4$ Wk܀Ʀ;n¥3N鴆S%,HxzFLT6dEC)Vfz B_9˗2I“\PQ)&MܽcQ7g)5$aͫ`YS n z8L4Anu31+g,PD{8=E+Y]`ACQl GHٗmd.ΜiaTM7,NJԒL3Ok3X+?ʷ߃oE+'JYw-iG|rނOUƺtKەٽZ"9>+\i:Jcp*J:8W`8i2 ?_$&l8mfRj.M+VjIb[V)%HI"dg]} BfYLYN $Rke;%۶@g4} /u(7ԶY}L8?2wh%TQ!K7_ݴ]!r~FD2DG0I{B=Ϣ9;#a,'U.E %2Ptfƻ8>b3y8=7b!p')Vm\K}6lDC$;%icw1z6,& L:<·m^8҇v<=wpS^XU1oyJI?JOON̤Z@j)tWwܵ9ʁ$?KX`IeN*F Zs_`S/ӻ*q/>.IHˁ5QѰի(ٍ7]CӜ:rQ"DF"#Q篲R'LAJCӮT5R(%T\JYRQ^ɆͪPZ\Ûyzr-hղ by`kcRjh)]>&&K,r}@:2S=2o="N"BJ O21Rœ_Hq ~ƨ{>v E'=w~ذ"ȷ8vyzp;sOSۛ)w*Y%I;t  !jVoGZ,ƻ#IDAT]ш! lk>I,%ue${cDa$DB j*:uw lȝUΊo``0` 68Sfٗ~87Rp_tZ< DzXlXyrSR}{h5(Wqn糜 WW2=H2߃ݝ8ZV>'ShI<8T84STDU2=ϡ5CPuI|_ ϬmD~+Kw#8w]F*+YQüc%) JڵxLW>˖bu7AҺbYZ4BQHqCHBӚDf<}T]jzHIi4,|OXb™[M%Z9q&: }'i)nz)H rmB[eEo/+.'Lt u'ߍ~w0MzXT XInD!*]ӱ䗲 [2JS]@bl|W0wIH$Ʉ!'ljlBU$Bɔ xh(>+w76"%ZbMѳOϲҜ{2쫤lZrv%[ү)]T޼ոkcSNCl[y(&>v"!pU1d/ڵx B-Ԣ=8F"c6]"`.~ =?Ydl6dFU5{/ƹKl,X9z:ϟ#Q0k&gBb5uTG^Jd80(D(YgI?HnϼP I*`|~o2}]Zߛo)ѭN* r1z'E)ojV*4Q8az&_jvzijO'HMLˋb!z >Hs~'O>sRB"%5mf{'϶kK9yʘPԸUUY`BNϿ?MgS{KZgy2E+*EK7[HT I}6⺉[܄4Ҋ*a۝n=n&.qEh(Sx[fnۉɤ!7 y&| |_>xsn_.fscтp Zh\s+MI@r7RT7Rk&ox!?<@8Ȳ>ʲ!3QL6# Br7WBٰ+%'wa70s0G&?xfg>#d.!P$ym+PN21x?PzA #ItMCӴpDgXz~:O;woys R2#Kd$WBG6Nj WA۩޲DI¦b"21b6HƎu^J*]H]:s)XwշobLmv/L>'BnR6)e~N N|)| \[["I"5oc+LtIG 97n! +h&?QB3YxZBodȯO^gr^ޟHp Ժ߳vE54!4S~.ɱsEͼHʊ?ѧ([_Ky [P} >`\C-`ɒ%,[˖Aquyu)(lħ>~3sod/I)PUUU!9} 6u8mjbNv H'j‰$)MG׵+2 G9raEd"$cSa|X^|k?)fPh^L˔呩p/.\ Ċ{cQŞ>/y.BɎP2<.sJ{d^Ni u.Νk'ITUEN5l]V p0/=M0"35>Œ(duʱ/rk!M& 'T%2''3mDB3C ml3oݎLykBCH$A f3:\N5 5m80H}RRD"H{ccf94̌%l:`?;hnPDqR꘽e|O1ʳ|H&φp0(BTB&=SB23:gԴԬZIAmRFíd2V'˜!i#Ah"#*d1磨ʭ:Ͽšd4m|/l "%y [Go'ձ_?t<R39<{v6P["NO10/rd(JfK?jGkC**BѸr#EsvRW&W_<*Ռ23opU/A1ӴA>Z'޸pѸl)K.Y4t(:hG˩`ҥ,[2&!"a$5[:"wF)/+$R){LyظMJP]A8]WV100x2W_s۲` BvLˣM)~VVPm/ѳL5Sc=Aˤ}5^&r H\`瞃0:4LLEu)$e4 RV<חtd~=~iƆ8|`?{wKjfyM >[s';.V&q66qvųԩkZCsS}eUmflIT`α$ťI}}IjPĬ-Nw~Ώ$0 ,N<.[^```ft:MKkt:{uɃKJin5Z_׾vŹކ#&_jrENYrV4)%|MT\ :6XLmyNe_݄ۢRU.td )((q k7c3+Eh:@cݶγeO/ISTDuׇDU 85F奘ndEv<׬E,g:%cUr˝}CUczb SEYa.>_9^'xjh^R0pm[ɔUm7T]f Wk7-y9nl.uW%ab&AAu9>9yxfR * )y)`劥幱|/[Ų6;tLk~ 7ݴ\rC +$iDE)5wNQUf['m ӍeM8\&bbbVSG>2+cȆБsPV/LͲX(OpVvetEeNХ%,/2ϑ3sX,Ư~X,=FRR\<֥i]^nx/{ŹBEAy}\סWm3plR'~6\>.O!"sEE꣖1"苏ț3y{2;i+۔-F6HNaXO9"k0_GQu/(xeA&Wo)`V@vC5uM]ϳ^!K9 ym}D.2>rZk=1\H_f@R_Ƞ9B^V{ S\m(Ҹy{ \Qd6^כĖW98۾4^'`7BdCfߍ%/zep!$ײ$g35000U}ʥ2 d:Td4D~Boo!@KD2dw-kw7Bұ tt0I4w S3DlELy_# mik1ļ7 k]r3YX~p-7qez!]If( o$b```6MϩSDאWY Kao&<HsrMښ k@&f8u!xo"# G9W&{;&P3fyoᯣ!|L$*\i)lUxIo#Έu7^ν=s#nLpWǜ"!,H1x84(*cShK?Ƨ֕-2{ăt50N8'Vl j<(39B҉`]ĜR't\@IJ튵,CwvEQRqb2;#-S;/ }UǸ}EaĻtst ISD#Q oe Lo*Z|}/\qy ~_n:>~'n iALs(ww'P(3Ki\RAɘ[ w>_8F*>BHNطǞ5ࡇ⡻6c9yHX'=s|W!P_{gOOӼf?pOUMO1~?96@f Цx_?GʗOʿ ~q+lpWgȳ{VS]][/퍾kQLR$ճ^KbcDCiF mNl =讧h9:Lmz8=shŹ-+{#$HBvsWGp4mzǿ}hyEH W˗qK>0w-?h3iRÜWoAJ,<*q6(w?!~rwZxa|M31mĖSJCuJoQ-͵9>x S1mB|_z3}ST74౪HL}'p<{e/ c:[ڙN粬P1oxHѾ~u[ټ$!0<@ ^e-6rr}liF0;@}'Y>wy}Q_QY*]QXW m]ĄR~|F֮ņ~0/ʺF;t@j{m2`1e^(675&@(g= E 8Ap%l(*2ߠ# :=P-$ӆb7o?I}U!Hо"-Qfr /tOblAUݼ !RwF+nwj|m'@ C(&\/6Oi!n+7]1j"mޯ2/ۿ5xwmn^YKaEnQ%nYNFQԅL>ާR"R.;;BnE5OhB@LxvngV˨./2g8<d@&9x"3.Jv* npB,/G˃Z.} eQ#bȽ {p^%5E98.*o K)MgsGL[枫@R+½!syϻٹrdN.jSy󽝘wW>oQ95%>T.-4ҳXAOrD;QM,_s1⨨o;|ooTQU[i4矡S+(i82<'OKYIv@O'@Pc m>+KqYy# 0I`)$b` O]%(f>l,̧lz,ԱLtKRGڋ)^Qfo$Oɮ+0|{'@[#:c'71rOK1߲OarOK.O"%YeCjI,y,0b\ AFMN+ȱnhtzN p1yc<֮ BAG@: 4U@j1F 19*/$# {BaE%90H&oyu^~(77G R3c4-#0:1I%2_=ǹ?]LCs揥h,Rd >+L΄I%}NtI\.'ӣLSSQCE"$:3ਟRXVIzeePh1RK091V'jr?CUUy֫lhx13abvoF}@*AǾuBlCfzt@ ;< 'jdb?@Ue4œGSDϞw ?675(zU ˫w03OH:Jxq)져Ue. M16FJ sޕSj &'-n)ǦC +,H_fӜ>فane:A繣*H=Krjͯ:3QJKҜ9r zk%~p)[F8\ّ+*Ʉ4!uScL[8-oTyňQ?$8=|kf+ 3@ fqGKtǽ:#^: 쨝5M\|ELH9< Fzhk ^Ņt[n>vZzztsAPr+)s st+iՎ vj|eǟٍo}4* v?{6Ny~'5oj:h```0KI#y~8}ps 0۱٬&2/Alb)$f%kUq84N<|% Otaʖ+.nNdlxJ$Rνq1 ' OG.ktGi3!g߹MDxawLO3s"!H&%v"i' (R2PA|zm}{u›ْ:t*Jtq]QW"$0G;tdzO>K}a2$hΆ|$ŷT6Kn&UF*P ?|Q*L C6:/).t\8MX h2H dODpan34x'?Аm∍pӥ|<"#'qi yxc ʛG2ASG_5U6;/rD? 6fH r97zp(<|RLWAH[>7߶7 NO|o[K3k R9AL1b|/G(ɛΗk,k 맦0Y=BdsPl򷱶( ЌiDKHX|lN~:pM5#tPncIk: y Ɔ7,3R~닿O)#*W.)aO|, 3/2[G}="olEyiVofc}?Ŷ\F.ca}y Kfr]ڇYSm歔_vs7*/Ƒ˽Oo݈ˬn q՛l3xWBm࿘\gO5ǎIV2yqj7}?qM-3 ?“ؾRJF=l&Nxg凜*%K6[R(8YXrɂ`qK]6*_ZXS>v >EC;o[Y)|`+o|r]FZ(`6̶mkp܎clo=7mcCneTzI xYTB[x#"&zM5S*E9~s$ RS$O tiH'+ֱ$ŦϿ.rzK-4m1u h>勘˖rD;3yIjmY\wE- +T4 ӎ۔D (njiؼTd9ymo!N&2"H c3gb4gLtU|YOJ㮭^d.SJ p EijZ-mg%U /騟۩9E`2qRXTBׅ6k+pMj,B|Oݻry8H6S .`)~]bFE^AChYIb5c/-RņE*DBqtQ% ʼneKy[Ht`YKtB :;gioz~֓iP)&‹ߥg>=}`Qr'&韘Aԕ\ulT\;&N`bA1Ik줪 }'gCQe7qTp ))iʚZ\}FYsKZ )uo3}t~d#VU[YAuRZOQD@̽Л7_FNs!ǩud^Gg򙩘TAIq>nJIQ!.kiȵ2B!Ћ3#l_]"c]x)p+.!BkH!IMuH?_x 4 rK*Ro0Xrj^sO);/V4 t ]XYq GtmL~skʒ R·a9FD=/ryXmTa:L]z-SR4 [n=[73~ '8ߓÿ[^hXe ISQMfBu/ksܽ~]M j7?¿I\|7uq-0XnbRDGNOE6JJ$8݇IUo{8w9]S싁ͤ>F}\HSxvk.︛Bqv?OK4,fLfMfCH #3/X2#AŌld2cRż6Y}]d*@~O@Y t-sq-.QJlz ^85w3j=?wC~?#uۗҾ9^9MZ.J:Ç·^nf늰9NGI(<>NH2f~z"A囹yu{9fŘ*Hi:v5nt$=k- T`N @QDbikuL%(Yu7/=UߙRr3^͓OGg{$3Kd`(N11M\5oEo=OKBlUJ K9=T-+#o$47 &+J]c.--[֢uӧ(.eպ T+yɷWʒ\'.)?)&F&()8?J !:A24*\,W[KsW=p?3m6-c|@+ Ճh#Z*I,gZ'5 [/&GNVGx  L }xYԏ mvұ)/Uu?2M~wdס 4ׇkg[I,'_{>3<~׿tq5rK8|tOp-p27]K' D"fKBf@Ca )5f&g*'-UW֚4]+*rF<!MN2M,%&$Xl^<)Ν9K[gAL6sNdmS87~c?>N"!FIb"ѩN^u pE n ~gc#&Zo|D6nVGHDHFB$Qt-9;< с MQ}z&Pa;Qp7E }G=qKMTʷߍ:pa Rzr,W5 `FC9+sG)XFnj B(ph<hH$J8#8^ZXsJXb*FKx Vʞ'zi‘(cm`Q衣oN&tu12́1+d:s]`X,L,F"I"b1i`NřgftP2ppͨQw%^Tp$A$a  lj#Ē39Nl70'OT*~?/{;OT]O DI$t2F$' Jh=}CG]Uʰ^rJ$!(H c:hp,F4%D"aHu;/wϽ7^Qao%}AaQ`端pqO4?ɹ[Zڛz'{EThpcN@cQh.9=Xm~N8KgW'#Q.{R*5ڮMZ)*t.mdum)3c)* Qp>r: FuhﻇJW_AHhhc.oiĤFDQ8bXft0#έՑpFgjI"% GIi:Z2N(%Oixvqb+CDR` Ϸ1b%w^'?9<Ȯ=I1b0df I3 G$SIڏ̉ L|jW*߷:\կ~n2P(b,0,k^Eu}ѐPVSr3-mtvV}tl[UUdܐ\lAE)g{9ؙg S@Uyv:V{ G!$۴ FrNIVlMY+dN05aQ\8I{nk!n-  N>cLl,[2 nP_SJtQpݬagRUh?{(vr64!4&{sH;pga9e^<y9YevDG*v5eh㝜87Hlyx,ގ2m18`}mf)n~n h1;X*+rd@9~"-*Nct TՖkLfi< A܅eT瓗ߏ-*._AKcn~JJ}DG:9|_VMyh[9Dd9!hSd?=c䜋͕1EV2g1[WQ&Z$@Qbin%p/k-KSfoB̶X dr#֥500 tvذ][(:fe,U3?k0("IYp-W+׳o\\L^*oA6ٚ:RY|W{Ui2g}Z{\{=6<1d5~7sgمr*rI& !T^}H!c=QsmvN{9~MH'}}>fx39Vk?Bcٵgv?ϣ>+X_=,X|nL|^J84Mi26bt 'bŹ\_1/ d8Xbo}=b\w~7]ܗٯl``GJLԸ5,J1OF-vdZȹx )aÄ<0f3ny7Cxb$X400000000000000mLUwХ+uba"S>KȈnN3"?(,,&Bk/旇 ^!@wxjܐ)6ו b20T:A CU>:@QULf3f47oQ,?yxP {*BQ0L͙o9.@OLJ7%3OHmF"S@Q" _H"mz T^\EAQy%0- TմP6}SLON@xGvOhf,/KjCd/XuOq;D^a>NjfRm#=?/,(*$g8zx,rj x*Xpυj"1~BLBl\jMp-25޸q&`kL (nW'smE*BnOezy W}zŹdO/1vɃW_!Uh2krCa-<Ǣ<Ŀ*rS#r~Q%"~icv€^fasyJ6ngi0` pzK<)+\/9^7MQݴ\-/\K1oS݅_ᮭɷWB!"jj*p[BsBA'YyKBA1000x'f}9NF:#hjlrRJinV]qe0akBÓ?Iw@]ZdbݿO;ظf6l>t|e"&`)F'$ҋ+S!ZOc4Nqy)Ѯ|yX˖zr6m݄lŋZI"dv$_rr8D!1.LKѝ }Xss y/PLkz)\6~Z6mC$TzHŲqoo~)ՕEXJ"Ǯ6H_!{# luܵyԒLE]!H#gXX Bjub9b՚? {o{WFJ O2>QQ{-'@QУct VPj96"бej{v(Z^xBFye|֬dV,HJaˡi9kW;`7k?{@EJ{ƚ*ߥʂ;|G|6VnukYbm@!K!Ȅ =QT'WI޺R׻y38c~;`W ޒy^J-7vMܱ +Q" X!~b+ [nRG44].^}l%޶_t6 ҩHH4NZ _Ͽ>~X}rVrG|!^Bd GUr*Y`sLE2V!L*kp;yJT}l/_UvA6Po$@(*i`qr˃avׁ.'9gF΁$,$*ڲa<c{< sslV&Hb&r"rh@y~ӍnT"2<9Ԯ]U{UQW^p0DDH$L(lAdB e*h8~*-3!K4MC%XP(L,/%ƣa|# H$H H$Ht#PP8.!X`0D4\xH8L(E[ )H]# %\UcQ:ۅ'MCQ2AξCL8x(ϲ&j#1Px?;W 9߮ܳ($ozRJ 6B 8pP8 BDP(Dd d͍[I-h* :8wgk]d9{? Nj?IGH詟i 'sP89>RHb{10~w3 %њMQ 젨U563E\Y³@ lNRK*~g>Ú<3zѶ!tlfl$UOdT_ed eSY#ˈT2Vecpc4'k 0;ɂ 9P Ndt@$)hZbʚkz"F(Lɵ^ L{/RcV`R@׵yf˭b(ty=/gCy9_H=A4rNp@0H8z]N.v'o]K2%Ӄ"ƍI%$Fb!2err=e+S7mtqjN_SHh$L |ƅ'bádh&7b\;oRk-^T/o%65ҤI&ͽ]HjU5$=B3l} 3YDKyr~ХBu4fé'{lkr}t 191,Y[yxc6^)Gxfp/S6NJҮIq D*ydfpXbDᲙRH~a)c̄9UVCUus+lšrCM8#"~GZǛ_ȅ}XIlr~fa3SD l+hr 4Oބ;>ʡ~cNx9]ZΣO}Uxm9ˡnq8txF=O>+Jܐ3>ON~]&׿ɩ >/ئb.w¦ĮRG3VH2׆B,0[˭ vt >4ˋ\w`($v}F3Y^UHe;GY?"[kꛇ Fkg'yzm#r v4 ıv2럦2߽Kj'۝_񰇾nڛ/puu}ǷaLio:Ɏ *j8a:~sOcweCBV„-,_Lsgъ?Ų<;!N=ȵH.[*wp}󙧶wcLZxZ3*|c=zDO<yNre+hʴRS}5Yy'sȌ6HAj>8t LOwkF\ ;I߬Z#^Ō3 {ըߺ5.L8Z$ "h;g%/df'xdC5&w}$>ASk5ǟ2˂z'Rǔ]'cIdBJ09qk9{"}$=D`YV@}7JӒ^}>Ԛ Dd:Q"+ǠmCs^1sU8&Jg降R H]cc'^{VQ8~D_DqlBψ@x+j md,i Ns錇+Ogyjk f!}]]LB3ٵeN:f||O| % %eܿa6Wx^=< K=zb %4-W<1gNeѫ8݊b%k7o$atȊ=kp o}d+KmcN㽝239ФybY:bllcK}6CILDnaVF9ti⾕ uB~ QIV(Xvn\Pv*"c_B4"GO%299I?7_!D s(|Hg;~]6X8 YWY_|IfE)_IUM~?c2 HpQLcC̊gX]_ϊzV#FCQ2+̧-T-?~sQ 01Z P(hwLj##D8l^L񰗸OLQP ָba"Fq&px|?=Qm!+ 03Q5tO^>,O=LQ' f\6-U. =~y<ryx{ &z棯#-x#:AtB\>Llz1>ع,($%n;_ ZQQl9ͱ3DRxGe`̊F j üF tzv.~fv#uV:Ds` 0sh\5$SAEx'UrmE1:nXNy]|?a{}^x&M4wD#J[@1կ? EE*& SinT*hT1(Mgʲ,T=A~Z jA!l  l6v@Mr ;ded`$_b(*]D';|4>vE2'\GK$(LFhwg,f3fn5pGIz23k,^LClɯfgʂ<%حWF4bvvּwsWU$[mV0WQU7U U ij8F~Mե(fV4i4M2v|>ZfN3ۆ\ACuRV.%ߪeF폛 PLf3&ŊnG=-[7QZzCvh®ϟ\nco͔UTlOhL1n7d]H.B^hmhd]95jb()2;KV_(\yeUsSNLPS!t)n0h 0Ռq~!&eR_OXR.e8Pl95$z'9#`fc7( =Őv#,[L si.e͔Y?6.t)[ªx~:gP* & ݎеg3jvCg{ɴ(hzvNG$ǵgZٶ~&t)1s-ЉfYAՌɞGƩ ț/ ^#Ab"ęxfgEv%# &ߍE )QK8Ŧ׽=z,DTEpM|p jЂ48^|GxΝИGڜW{CFn奔QQQB:5("5l+1 R[gs^d $Kš:b` wayW/]wH|.|-M={azf3YY"%Y?d3!ynj0Idf`8Ffa)e-/+%fLyIӥalJMq%]%ւϲcycV).ƺ{BIMtqsS4)FQŨ*)]cjxx́˖ &%Fw.S`ɧp. ů?^8&Ru(n齤4M~1x7?)'q}H]`4`C8)c:EL jB: MG=BZ3(+/K]_Fq'? ×ۿދ 7t !jw;iٝACOS;>X$R$h$\9Oд]+0-[2rX0<>j0F͒,|nc*h^/ =68 +S 3ab0Ly$h 7-#Ҳ V!w_XPVm!,XɁo=_BD%R"M.K$,@MTT.o(Fg(0MdboxHɓy"A"0ΉorupzDc]Pc{ I=K0 FVm%3:ouu8J$bS٫엾̗>/s QR9Ք:Rf {y?`frYِ `wep["qC%:T(0PRz@j"Tih4iҤIsrlTy;|fRYۗ9y$C)EUՐ¦](0cIZ02AU"IC_`ԘKayA$u^=(pIBJ``‡.LΒWUFühv 4qa̶5UK I<U%>ӽmfKc 6 AS 1RO[sV:Lsz1`U:a{Z,1E~ᦽ|C RRuf:6lX\@tRt;ʥ!S@tR#.Tb)x,ޙ ZdGzǼ~<]sW7Ld@ƃ"w0]U[&1s}eZ&u q\!=͉&AyGͷ €@o|$:S[r7M",\-g\%44MR>?)6Z[GP| ՉscL*i~FQDVar~3 sB{21mѝ;KǢFSb4BS8pdZD8d՘MGا"YBŠz(Z@&_}I %RtMUAѸxQӿWs NW47"ѥm4CQ1DhAVD;t1Tv3\j&((")R]ɓ=M{ h1V^0(,ƃYt=ʱ}>,_q( FƱs(.vvgQf-E1NWU5b1\pPUUP]QLVL.Փ+4 Ό\Y<#f`E22qw2I&=0=M.Bb1"֬&8J).%U~!EAفf;x XLv7ߏ8z :j6f"ł3 YTәh?ͫ{/ltp%;Is4lZsD$Q#:۷'"RKH\Ó:L g?A2E MВLB_$.eؼ\^S- r3;_Oyєů. nyMoe`*\t 20C'  aY2$dKŐ3b$a )_N?LT`J@o@ZEH0wzo .Aׯ@<ͻ>R򨌏2L,^-ݹ.SE'RibWGYeŒW=oehxW2쉀]D23 VĮj</~az;r{p+g:=QդLLq<^P2L04=.~9$f[:"Q֒Ww :&NegSr׸x`0C[pX!{/0>,$ކ^9L3AB̴ ޴<;7 @FMAA!ȵ4OXXf=y.CI_N%lv(JfBz]{ع&|}agCJ,|1^~Gn%:hY;ͬ  Vd-]C`rWkgW̏;M0]WiZ]^=|ށZ4q6 WW$ыoa"HNt=9.dj1B蚖4WMVÏ?}so>$2<Åv}{ Ă;tsA):65N馇Ğ-d´=ʱ ]mE,)ccȫ,[GyR7ZFUE^=Nz05}K㼗\Gv VaMI[[=v3'(n"@iB mDfǹxو;%&M4!h4.L$H$Rjq:RJfffq:7z?˛5YzE##defbZ ifJ˨4zhBQ>? &Ƃr!zO0dsvPHzN6 =XY?D1jIFA5t91#A0ѸPT'U@3dBYq-܂?H=N#M\Ϝ"gV;.A, A0RIِ{HĈFD"qP&  u$ %e. y?۽?ц,c:ьbqq"AΪ uxBC:raP.H_0h㲛R" ӅEXT= j#U%h&l!UcRd"!^?1bwp~PThv! ӅfFHK(cupXM(b` \.&5{}!L;.mD?@$V Ո~BQ dr`Hba^?dT ]~vr\F<$+ȳT~@8jtcN1MG*\Lq>?hr[QAR$.3_Q\MG`q$ 0X8F"B5b!q)98A`pfT ^iv:0iE4i|X՚NkNeyBԓQXP:i]hx x63}A % \@d;E"/kTХ[a7K}dsm̊pv~mAs?95$3HkaV#?LQl[talTy7_pϥ~u\u?wn wC?~/>[ݢ7nr.-%Z ^͎M,>ErqA,^"؁([^oBAz"81KBsl-#3KdLߗ%a_K\`ԺQީYp%fX}8.Zh}?}x1?Gh>_;O7)wn'bۏ觥\+Kqn;L&M4w/ӀqiTB ;|+Er{svbw2-vq ɐ[K_%a:.×$>sh wzUsv];&M4$€&"ZGG{ .]dEn+w22Nї)?ƽ\q钠Z)ȷ} 'Ig@b̬<*YE*dK&M4i>B i~qHJ]?݄6fCRiykzx1[lc4iu1&5CCLxBs(Ƌ4iҤI i!F+5 ԓ(Wn)n!M&M4i|PLJkS&`.Ι138I&M_,L0`6ZiegDًH&M4iҤI&M4)nHy` *F12&M4iB.smR@vZ:R ̌1M: ]햺L <PTC%JU:m%@Q 2=#א€+3,W E7MA= 4GfY KMu3f:!5H"Q&4GJCF,7qBSA0b4$+[+I e' TUhj2މK5vN1x^ñ7eoL*to?H/ӄAn^.6 8;ĴF^~>v}W"cS;+cD_Bh9/Z 21!QTUNrr2/]&;i,㬥Is! p]aFYe [\+zK8>fA "0~W:ޱ,s @ƙJk/ac+WRD #8xNpjH xp& z^fd5T1Ϟyv#@a `KJMQ,9hǞڀ=y䙇j? J&ͯB a<=C(%Qf;ZF o\˝4 !w4{Ahpsfv.peX Ngo(|f(kStlF3=#َ̕zI$>:F?683}\`duߔ&}3ulߠԅ\ mak 88ջYg 6­m3gN0蓘 dB7'n恧cYvEr.>~@Yf\I]U$jEDI7?(lf'ܶR~ٍ'q?^W{/>EKAIxv;yˣ"_~a& o=ICܣQ#JJ[(-gͭaMgy($o~%[<ɖ2 #C|ه(q~a(ԇDeGKׅ2`!wsJ1%VqW滽/К &=;_ї!׬VH `@U-g9rɩ.]X~6Nr7+|{d3C<>'yz?~eO)Xdd/PdRݼ?VR8ŝv g:8H=,XK ]tH4i1Rotc\n+HLpFz6s3l0i雨>ux]̅A]O 'XLcK7\] x Fe#[e<{\ =wJrJuS'(r[ A Lʵ䖻1VS)uhNX*RM>gyݎtУ*VSR+f N[#uԌr>A-7#BVI-ˋZ|l{ 4d>C qK/<}?r3Cۈ5:hŌrGU1MȴE4\,6xO}w4¨_ܬP`+XU4 Z۲v/Zq}I((2/4Ə~z!_шwCy lQ^ ;ʰ2Lk܆嬬KoKuo8\WCH)78wzsߥIWPЃLMtBf2io/id} t#B#U(dDrB)XFv a)|kkG 9걘•/S8qO[DEBGj:[ Ո0&^=HE*p,|TP `@&\q&zYr>,22|=f>X_IIE]3Ǟ<+,^RN B\9SiFQԔ\,żn]XbΝQ_d]߫suU_R0$ׅ:YTF]UNYO.=u1Oϳ&k';GYƾoX|Xr\]cHY0^=EBi}AH䑋Dp+'Z>f3&m匸c1%nc.|]VQQf6 ˺y.~HSK'xSGUՀbA]TYWoϝ&Mwa lc [ z 97şJ܉)t˶壼 XF}B?M{k+}#x U6\:;3͵k4ɧ:ۚ:z"Q٬\ иC1ԙKw"D-VT0p)7Pe@:4gڧEv#8KQ*T}(=aq(.8}2F{i։'KFVVcV4&9Ԋn'7jac ǫoV&~H¾ :{ čԮZC]X`fJVNͲORmūVc:2M̞R4?*lc> Ȃ: ؄j%wz\VhEW2:H%AgU1[S2@G `]GIJ4ӽc22Q@A"#jBgt9o' U%6=M QTxVMEl nZQ Pt3$2 qM23xCG._"ߎ~C$KeT ܼ);Gˍr31ZO?~ s*5C ]V6=U9(<]kA/,+t,ˆk͗HPq';WWbQ$.;FiIPuW\ÃwPcHƟI](y(, ^\s+`{uxo f+#[gvUD{4d瞠 #^4=U-2>MǠ-m{Nu,PhB@?E۵VzG 4nbÊ2"pW:Arٸm;uvY:^oKl٥]@H?A 祉83\8t;U 1JFOs3m>JFs_>z.bٶ~)=2]qn ,f`',ԯ^Ouo+׈԰Ct\map*@\E~SNk0jL ᧸ɵOZ3{Vacy\jyM5adңl*W&Hh 5+WRD8?gmTgJ:.a߁Km|X˥uʪ-[GRzȫE&4AHVbib!m]@D1Ty<׉Mz {IT FC,ѝqO8!BM3}ᦳt})!T#L\m\;MkKXܪH~bE<ԏ.ZAxwΛ'ȩ]a :ANכfhXkj?2/?ߛdQ8}k!$`ɠFi#x櫜QP[ſ;]. dF}aG b^Nlu2+`Gګ2d~7rsm^gL4n̦JHD|m' l8G~'$~oWǡ LzK У!Fzht|5{0̿rlٴEoS}U^z(#8`pI. \21_Gm+1'97xѐ9oGϭfM-7G/atE95O{vysh3|{ vMD>>iiJٛDnzvoEHS'4O qeѥs:#9]UKAa1z/<9NXY6,gemz -W(X8k34-bo00E$;""F8ȶ[:Vdc9YiOJwWM]_+o:pb4hqva5PhCWKQƮ-[(u&h>> FA,_Gvj0Rݰl'?}jZ7{v=@]>&ͽ@Fgk!G/rԐэRz2qk F# z,k*K1Pv[2$0:w`]A'}ax_[axJ5X-q4|].^:ݑBo.ӓQrq;mְj2rGC%b۷of}'ցhvJr*LO.2cv5;vnax'QHCa K+ajLli%! afb!G&̧U; ׏NN,d3aQ85<92soɊ-짽q &ܼJ`x'zi!E( B2Dd( RG *s&h$|4T93&5i3YlXl6bǣLz}lf_f{woge;Om,m$KC8>ă^\DB 4 tWqV0% }n CdZT) ! gJfٺ-h/?TǮO_"I04ie@\c_GtSnF\%$gI.#gWն$•G@t`L#a,Ŝ[BF܋܋HYQ 7o:zBKzv,X\DjrMX3sc" (qLg2$wJޮOа)W^i} ժKAvJveN o  } |ՀY#Aj)%NjF.c̨or~Ui,@s$ĭ[xK"ǡD`$b4ZPu@2=>OTsٰ~=6l⡇ɾDdL-1MG/hN%w|QBYd!O-xd\PƂ.5W=ty#+2?)Qm<dzcIyτP0&B ]ma4z.4"3#̆1õQdY(dNyH#ue֐oM1a0Fc,ITzuKJߺ $Kw\Hļ>]$/h"M_we"q7 ȤjYuuȩo~1myVB$?>m|dXԯZx%fY5TI, (Dg8|:5HD-O<J8!+M4Dґ"tkŵr%NF?td)a&ZЄ 13m`z`e&d֑(P,yu0F4haf&]wigܢLhx,*("2c#A0Xɬoo51tdU磤I ']Rg)p!nL-uT{!O|x2!级H h9Gzfeuk3ANg䴂IhD2+ܺg.ż|CFsM.c!yX7A[vn]4Ol27 G(` W& 32}RzR.hk{R,oPp|a)PUH]UWa$(2FOeDrWA+s!:gmnZwxfC;*Xfkq}p$wrI wPsPPv3eӪ,ٮ 01!!zj~nC놏q(E'HhW.u5r_qksM̷}J> %klk. EOH&B:p+NJH#H$H$$Jko5wO$8c^y%}n5wJR0#qxZgG!Eײ|y&7KTU!>=L'J͖Xɂ;ؔha !(YAmƥsMN1:2D&"9z? ܷHu4 zp/C'2xKm-L6ѡf.vKtHPU`oř L0tF-FyEX,!_dfKhdپ.pzIFͻmd}Cc"وGЌ6\vkN'ʼn!T`SUrWPSE|c;;Ig3Q3uju_:{GqPjΣ,Hgs ބ ex8A&t7;K"UXRY:NĹ&<j*,v8¥~FF&*N(3p$gpi̹P sZ71]| ˰̆Nrcpi(AF8w?M1Vmnmas6vfRVHeFCt O}>r 9z@(8=}m\TmmxS H2-'ޥ)XEmy Nr_L#23ĉSWP+7R F#8g&H;`o/#Sq*WRWDiY6g9xq t0԰Q!">z&P &J+)ζ{^mg6ngl&BfQ!NN&1,k+ɴ@ .FfdRSYMI0Q4ʆ Q~z0TTm3~;M=z D1dTαbr1M R;YJXM*$"x{yc(YXɴ$a&{gqp@HqP1疐]`QgfxV啸3mKxڙ F3Մ2)޶ x>q DQ+*̼q*`]@}9w6jEKYʶ/@ODxPBb1a:((*&/A7+-V&$n+%>4Ԗ#\lC7f|M#W.5"^jr֮椡q%yF[3]ʺUpk#|owNcsYӳ!?o؎~/ƉZ!tC\d(PmD"?F:ٶiva׮vV*jEf'.*"e`)#e&W tϐ@`vP]Q(h`*ezr͜gmY,ol,N?EggQK.@cvlʺz*]I'zgzt1PgSU^y.FeQ?R 쌌cP\VfV4R[L W:Ѭ^B WufS[WCvOewe!?9̵6ƃ"VXǸ1.ss cf) L?&U  ͨ7ANI5X]m4w !2 h\|DKo{;y4r )vcTY:zWPk'5F<2 *Y^_At(W FQLV3B1STJUY!Vu>QLj`eP^QFՐgH/:GMU |dRPP@L?AKs;>i|kOU5&h 8(+5_}5/?{;f]~ou}q.).)W!շrry}&M_BY,Ss/ Yjڼ O^ S/EȅY%~SunKY?:TD 37=M2j jPļ>S84_?6rzӓ(^ PEϣS/'R3zۃ߲LRg o,F~49]:Hq+=y6:9\ U7<TqΗ( /zƯPc19/d>ʍͧk$v}wqe8o8%ڍs<᪤b邹I,]ߓ[C+e滥CRR}II{ܨcM|[Ӕ(ŒҍH6P1N07]'POrɂnY͘n͉n[KE7;m[4Z[%bKșE6cNn]J}PΏX-)́ҤI4pwӤI&M4$+}]~13ȊbuӤI棊xƆxcfUW+M4 kF4iҤIOR|+]0MqI)kwQiGDI&MLDdJ01 ,{A4iI0ҤI&M4wjrj#4nO}:R*?fGGҤIk(f+=ʔlKfI0 x&'~|2ϦIsF'03ɴ7Fi|ef*2HK$TosA"ZQH{.o]qooae-I̵{*[ƺL%;L4m-Ы 4w_Gïo3 M|Y0M,w /Wy|H%i:x !RcZ1m0m ODj|j7RWA|k/j#+;IAfZx֖k O E kX]UaAdaEQG4#N1zO(6 bwihM8DN:{@A őM]ɨ0;pGqխa"&M[" b%Ʈ^ZI5Xǯ7~kq a_ƚBUnC@"DFL _ QbE5ܦ0l|^MuWʩ'Lv֐mQmh`G1XAY VT`V|N#](ⴅ(m$\¨?)Y5)Cvx'M4|(F7ΥSG8)g&ۺy4!$S]y#Xcl"j |GYgyfG=1=?v˭mNY -Ĺ}s2X~7G跾®,.Zk8tUmӼN"ɞ߳X@pzwe>ʃ+qUqyeTO;z uIGq2 I棋D3^ªb&:X՚1&NMx cx[w"SD34ܷ[d,Lyz8Xxn%`Q4^x\g@ s8g#g{ V̎t[{y}-rsA$3SBwW_y1S9{nFDp_͝yȡő"ͭz¹h=_}:#8;:^< b -4iJ @֎^NstHj!L}=o"˜T&s;zogru]G"i^zr & mAERz[wpiޛ/W>.;٫QO^f]nGǕVz9~4jJCupL!yz8d*|D| <'U.0䕯qqy-I7j)B*MKmLJQH.&eBQPJ٭HH'T?B2y_$c) ,c<~]gi:"TbcMSB#1S^ 9E(Fe^F ! 536`T+C~f}&x~tC2;%Ed2yoetlud?L6f:MbI 1/s^LzJ>_z׳ EeߥF(a:-hN]82a. -1 Dt%e,N#|%RJ璟'U׏uK]INqln0yBQw:P"S]\YqA{I<0[V1k7q1,MQS:2- rN@JYl}?*uu*е(cCCNLQYSoȷvRRXLzrdS2Xq=&EQyt7Gt1D&+jKP"&| KqR@7,H+|,*Ă ŰR]#u'M4P-,\ U 䂅x| +W0{Js)Q3(Xd@(ȇ[!3(2|+ >Z/P!QD&nB(ngﻇ12-+X`HKylRk1fFYb`FzYYVA`jq ]̡8Qg(CÌNF *(uaS‘8|ʊs0 H< τrZ%`)`EU>Zp0E%8ksBLzDcX )-ƤB?EFFA9ΰ]pc~!j/R4f|j@AG t2ꉑWQKE!z,P03bUk}̄:^iL\mk+QT+ z?b sm&!,bU}5v$"~ QM^ddNyFb -&2` HMCS$޾++l_[񑑀D/"Tl(a6>Z }i[(3Ls4rXoFFmN?^'{R rYf -_zdAxK{)>93oaDh56' Mo{|?>vη aseBd<yjX cxc)Ca Wǩc|UXE۫CnEJ2el8mdly)~_yry'g=}S,)@D$2 YPUȡTȒz)+?eci-וnR^W_gAyo=b E>+`%I  -hFqgah8rVrp~U΅yl^S?~3'[ض`+~V׸?}uYd LH~i6H`"c:# > z-c8kXPGXS<Ϛ -1Q&&w/R[AQdQ ō_#x\:O'VY]ӱ2s"@BxD8w-kty14 H Ki }NV;jq-KKQĝ3=͢"'37'B=¡QK6)dذM5|+WFY *4oY-+{-)FXG~]V7+\l拿C|sժˡ\ @(pc$b>.L_Eh1 ÈPWfAti޽01B%$ ƕo?? 2c;_FA~z 8UPDI"Z [Mh R,rq1&-:FFzd L|nYf砪Gϗc@ f Kݯry-s$gAtT< w$[ٓlpMUx3|2()';דʿ t2}.,jʃ/4IC_{{=mE!6/{&>jg)6>/2>FQeB 5)WXD*׫b`aAm1{!'<ʧEHpffrډĒܒb@"l^x<|ךOt> (2sdfesw&^EFQ2aOcwxC %L%,Ӹ&:C:(}KkUW-bb/(•NH'M?99Y" wN5Bvi|t9KXKظ|!% t,R'OL{Nmu(ZD"I8$SE8GΞӾ|.}9`%v3<FjCr?%}|#L&Cd,!Ο8HnJI,%4zt$ oO%OtXhodޣ Tdޑ !sgtwϯ g!Ӯh' ˶h=Sc)W"\;unG =BBLtxj,uK@"s^ζ5HF#LbT.bq!t)Z ."keI]MF4+'?E-y^.':rv.2)((LrLvGMɮZLNQE9NrB$$bɥΗ{qm$ڑ240:g8 g ;Hh =I$& ,g`0n21@ a&ښ"^őS4gwY=UςvSnfE QGߙWo*A"$0b~F409siEzNlgOWn5<8KˣƌT!7ÁnEUf;%w rr\kHͽB C􆡰\bZNTS?A(4IYHmO$`d& BVWf9{ɔ|ppp#v[0t}|f zO'[HH1K*sÃ]ԭ<,d2D0aSObl}8tpQ O"4DG_( %O%TRz(h)`Lħ 4-يdrxki9E9?;ǯSc2%K(j)L7 =LW{7Ru൨) Px]xrx(K Etp Cﳆ011!$F$`l|ؤ1xFzDu~?g/ƒ$U @cǿ5 dGYu_szʼ*Ik7ěCaNyqLe"ɷ/짧R1=˪ٱs/=Aíu ܪD'"L #-e(H+.ϓe30 Rj/T^x ?ƃR"$Db|$qi 0 B.+zy~|0Ǯ;x ,*fopfj\u7cǓ;977ܷi^'' &3+CGL(l{A}mnZK&/FpgnJq &&& B$qQFǒ6Gaev$=:k(g k?!=QJd,HLͦO:Åy3 0ca"hq"ltBhC' OB@˲ސBb`Gciŷ Qv߳LhoBӬ  $8X݂|%=Lm lt>Ep1?jgٖGYw;A֍TdXH߸ʕoٱWn@`P`IN@OFL %P [n9;ɕ+XUKNqrٸ,oBp V/O1ByY.;N$UG2hjl@#p*UZŕuuTz!a¡H #'$"THۍbGlcOc?rfVMjY~zy6tSQo!ȕ.?X e/1>Ջ l(]%<髓l(5~_>ɑ&TYz v c,q*H@ B08I4aTBa&t" 1N' vsW8dX[eBC!1pQA44d[ BɮO7?w/Z'ٲHRp +dg8~PIiI.I?U_oٿؑR`0bxkWqau%eVWKVRS`gk] |NVbI;9Y22:35&o`[VŹ-3 9:H\#!0›˪ի(9)`Ŗ,L{SH}\l&Z-3aQH% ٶ)VrjXz)9hneýЖ%d:tz+V,r3+Y\a~&e6Ͳ̔7Gz 2]dհtA D%5X^W56ΕV"Nfn91N|9ERPZ"DRTeu%0Bs{!k!wn8n/LL~KGmL[Wt*7.$f!s|N­glb`DhZ([ ta#{22r`$ \cZ/V ݂rAF]ev;\ePTֳzB2H۵&Z;{#ٵj#Car2=X,6kQW`"v=pu82 Ycdď=5kuWVq&c KYR]AuTvٹd-FijA\dSZCQe-+s &Tꗱ1q^*vn_GMnQd+JHNsZ3]C bxKg* 2.YOeiϠ}F"I}@^9e: LJ+?e&w\- Y^JjsSR^2ɫX@]E!9e&9ǛD'Rz+,)&$f2,'Y,Z=-4Lp,[4ښK`z(.$IaHYTf2JpE~Q5%q:%u+Y]nX()-&9AXSEuPUnl7vZ-'GL9]ΦMYXI?JHwPd rPU+98cO**8wחw61VxMhlisux=%)%x=ꛀ_ךe? ?鈠,ǜtI;[Srdbnmnck 1+yќsbfO$tݤDqsOXƴ u{X3^׷?vyLgwޯibbۂ@(*U)\qn~SCf*t-bjBDoO7yRʛ S($,L~ziƷo3Oy|I61MdzٞnHsI*oόy5\+}.7^f߉Ѐ!Î4 &&&&&&&&&&&&&&&sy-y`ΙF*g TkЄ蚆U1ӭfaHWwE3Y@HM ВBEU~nG4t4,m}B 0H& Ue>Uj0HUe*_bs b:V\n;Z!GnUuRZ%%8U x;?ַqnEȤ[CKy+h>kM{ϙ3GC?KKk#A Nv~1UUd8 /2d霋C"ĥ~uM E0x]態<[iL$0Ƶq+J&&&&&ʀ! #<~qͶe ʕ&FQBAY=+WT#:;/xz.AF9EZKYW}2!0?#vd0|`ս\i<{kW?o^xql;Y_aЋ!^J( #Gy+S]QJu*yb#61tS?}f7bt\:Gp)~rCQ >"WϚ%ذ8?! w\7o|wG3J}0"(/+(d M~c]Y% a-aa} dvI>"mI7@Da&ߵx\*3xޠ7&&&7Br*-{Z\OFqy+7`I.?\x ԇ26BOH[km;\rX;us@2yq?a7&*jGzw$`-lB n8g%7,ꢤov&uu,e]+_< ,VҒ\/@ 4UgϏcSXdu h3j"})E~Ǧʔg|H;֑Qg C0&9Y(~qs~Z?I ;Ʌ.|x>\Qt#Kr)5ϹÃKrz|/r]yoۧE)& 3>V-@Fy R"I-dp$fHl7n-yC'Ob$"abvXnK]V*l[OO_sD3jCm`bDqdx~E:?UvL- YPb_cw~.{myLV,|@(WU!D7$ E"0 9yI4 ԑ(lAB@2!Ot{qҊ$0ZPz[ڈGC1,v^}!'%ՎB)ÏbCQjucI+KBDH4f㰚*&&@N0]# IVYH ŊBGg߈څJ;z %?Z,הY e#Mx,d.Z-rOTV+ \70'> yHNuBUTx%V'^7BON!I#h†zkbZHDC"qb`Se@( {ɾ,͖BGYlْjS =e2P|s喞IVR&Bē ɜ)LNNMr%PHK(jGhQB f*5##L$Um.2}n{d2P gΩgxhcduPp,x8j*XO %t,v'"  &R`wu?5b8: NEj"ᶩ @jII*B5py}4u"<YOU31111>Cs!n(xryt118L`\CQ |l^&4L̎4$+Y?N`<{39C\N('41BϘdXQ ,]h3^A䳟ye9'B]Fjaeņdl|I^G*Wb!'C LFYY&J/EQFȱf<@St=! ?J,cwDG!tK(?:x"T;opʶMՌ6_^rl㋟,{=F{#G;sPK\QOr1bܻu vIIx]{Ht AV<9x \LI('8>Lߤ{͒"nb{~ٹyOQZ937+,]֔c#Mڞusm%JVg L,Dd! ]D&FQV(q&0ĨϞ7DihXF壼Q ~֔| 8̾I&:6= sd!(F'3stq vY)$*n vNs\ ]p x,I?BpdMeA`S_dkgWB!oٿ:xA6Ty|\ ˲Qx{?T;\tƁ$"ݺ .;Jԝ{ϒU-wxxda7k[NZ_jvT{S2}'"k6>!._jb`dqu=ey Йv,.7hA뷳ia Fx=?mϓoѰ'<h'x+CVVmf*.6cW4>+GCQ=>ǽJPfܑ|ȔK3BpWjB(TrpzxLO0BfA=P8^w7/ua9v@COx=gѤdw70axY}#|ν?|/#1y'4RB}[sعe$p*w&;8~& $)YDi/ Eht_>π%y7*4Bx*?Gǒ1=̵\璩x?c.8҈pg ކ<ي-aC{k;KJLOԬ e aIMr!6 =p}WI#2ƙ3'hSTO}l+7ަc2Zc771!4y'4P2+XկR8w_`L5)NtT㎎!FznogrЏ "3!%6 ULdOr2DL((S @zBQ?$Nѓ 4_g ZpN3n ‘. ;4yd+9R.OLPl)ロ*g{\JI,S>y %F{^RzǚjAN{+,=(_ylJr> gw/+ܻƻ.s|; r)ZG-gyy=F(RAn3}y V}1^J {2Au8r.N*Wo~/?EeYX g}1v=—߹`#} cR]ysQ]tՓǪupSW[ƎGK[qŚ!S]ן1 ]H%o tqzv  n2:ws=##}d. Oc-}=.?&YS`mمphQ-c55(u^~SX1'.QajMH)#BaڂD'.uQ󥐤ql|iv|Z{܂'Ë4&gFHF/4`ᡯ'6Ppz|8e'kN1`RYWOUqb|{Fimg?Si0p&V˨Ї"Tav2:Ѐ?nlPC˲U `:w  ~@8<dyG&}mpG߻3wFʽ=T;0ۅŊnGO00BT9>лO :V ɚUx5&cqӧ{X?gK]ºauxβd7ൂnXa+` 0"Kt%N˂aHjKKuBRZUGqzj+ nb;d\G`i_nAdSv>8JԐnGJå^ (M߷J%1ƑHV~\R-XAOv12 aɺ q;WR$-[xu-rv5I%H?$K0]٥Us(ea n5??$:Պ*Xlvv0&&&&w CQ.;Cj#V +XÛ<7,e̛)cg _hf=C }s!LIi Zr$4BکUS+L2e0V%xM峧˭)DӇ౪̛+П$F12srK` |s $~ 7{L#v{8ZD DXs[Dcʽ.Lx(,"K !a1QgRPdb*&&H)|=\I"7@ᶧ0,v-{h>]"t9p$== .$qvjX @F2gp!MHͫX )ͷpҫvPȇ˝$QX|e :ך[VyLYt7!%c*\r<=#9ׁ'U@EUP,dzheV3a>B( 5uHkWrR.ܡwX˚m(tOOFs^ 0$EIP (6Iϛh%7o~KȘGmBlьzw "8~7=EH&gU;KEhb ڴD:A&.@Rӓkhm&3N]fؒH' ed*ǛhCIґ( FRק9\aq̵sy)9eEHNrN5U[q%&9|T^ !I&irZ $Hgq ʙ*ۑ2T$u|yTiD3BGFQ,2Ǔ.Z%T"}W5Ά-Kq!{9b!3+œnE] MGufk+3KU]l#ai6,IHTSYI˩I \./}}#hS2No+ mAN|mH(HXOUQI=W @Q&{$ UM5d^rz@uyc}n'+P 4D'$:(Y+$o%@ +nV\a- BJdg-ʬ cCb$uth#ۣGtnμS4 G!|_X+ m@bHu[e9[P@%ʥ"]sœMfxS2d:oLbf q"REUT2x2*XrWHݗ'n!fNI(.XǮt;́3}ԗ܎Z,I[qX(*vp|ԭ\Myѽ'@99\>z8-aqxp>DD"$I #QFQd:az2!ש*ÒZj3DQHtD;sC fe2Iwy3h2F9r_zK)Yhwr[`!8| Hю- pjzᄌ6.9ŕt. ]}#$ lIMcdžo3hѣGx79r%[{mcQ(W[GYq=fR74x2I2 8W{ ]GK&У R"Qz#KFÛG/|S/1L 0HjzBCܪl_>bʠs(0Dè]CE`Ϙ}4-UGn`{ɞKqeCZ"ꛮkIt^s+ʅ3h!F$ۇ@Q4&lW#݃uFksГQ4FW+VAp) loorKmRg2bK Q]oJY'1te+9NKB%B:H=F#qe=yt]C5s7zZ$n ?gb(fgmlY[Hvˇ0 ]Ǘ]= *Fx e5]KC[f5?P}?;/Z+ϝr0<"#?Ͼrk;qKcH$$4^?Ko2}$zcu)9#Ι~NC8ˎ Kt/ 0rqI[ƚLDҝ˶-O9|*W/ȩFDn[qp'sm;y:Gipw5OnZ*Ōv]̅&z:D8J,!DKt)'i$4=cVբ0#abbbr0H)7`0ncδw3g9}gFkIDATz ݳl^yp]ЫV2b,eS @^w &h[,.~Ȼg3g9u4')]y䗔sZ;]}JqdR<J牋bWaNO*$0{ g󟢰;]29C&k)*#3XU{{mT?p_Z ΢23DwI_ [9w@9=. EzB,OZODi8终 YRW6"<n4_! Tn9ˑ WhnSⳙʷWv W-#K/N[k+=cq*fyU.}xC2q9aEUUSY\5sicAm% *jkp%F8w zrJXu7L~q5k6[{h (Z| ~ XP~ gq]r(ji> <ęg8tᄏӍ}r( /=GBdA}%>H&:8s4}Tֱha=6"C:ʋ !KsGg|j*I upV=(*Px6sR AJvDHRPPHYI.ks@Tx}v s|?^f,.+*%0=LLLLn#t MKy !̄I^zo&yCgM'3Ғbn7z2F(ŀ>k=߆KjqYc^ԉE$4Pݚ M'FhRta{?n{*RraQg44B0I9N!D**nE0Pq\Tfy_$hTÆ" dԯ[Nh*v'N{)wxbt"I&bDq v ͂"z2N4P,8N@Qb#6_|2Xq9(B" X$JLQT+.HФp[Y5"P\TxF5jra:HnZT%:*ECcEov Xl}}1uϤF8 )bǓHǁYQq<:?5Ӎ5 ,<^B\S;YfÉlq.1!,NLYԿ:X3(r? Wj^>CXYH,.(1%lϬ??łkhjT<8ܳN Ձ`.>a I-m׫C2tp霭+(>RtR,8\7SDŽj!wJ{|ttrFfN{`>vu2͘zطƒ+ :A#$t9[8^\P,6ۏg3oJH-b>V}+ssܼڅy#aΞDI6-e$#~&^ۼ|uM{~g~<-} eToB#A!.5\#<˙'Nފ $<ɅnFO6]lzrLLL~ 21+Xx/fyK.8Ô&&&&&wwߪ_b|ח&ۋ!ZH g|Y+3U&&&&&&w’{]ddfE}OπD)^HY*0̵njŝIM}v:@~p;PVQX6BMLLLLLnh@,G(* v}%[4c~F҆S]H6wDXvZ=01HI'Οy>wМLLn0n)yG((?O EAU9?|rjbbb't\&E3EA(Ciy_veܬ* h$zīt7qƓ:I?ȅcGh E̖J]I/ۺF&X(9& dRVB|!P玏GO5QsB 1 -8qm\H.;ΥɻX71J90H-Ab ; BLR_kI&FDh ?zG!a  00e@CX*HOf8TaZMLL|@2|8zQ3;<&%2"Լlsw  Bc`uzDd05#wTd"LhxařekDOe,C**6b'; WMOӟcͧ #opbreRr>Ϸ_jWC}q&ߊ(CLcUEQ-x2P . {ކ+MʳhQ|@푣(\ˏDzG뼔֛F 9nsQ"$}6R2]]*;!uo3// ۅdkc|덋F]t>'6V]Mu/ 0 vw;Gz((= \S#j O?Ē"mupb#q;u+V2 >Qsr>|N*2S ihL Q_[q +C2<@\R2f; krAAn)O ۟^'Z6E@}틋Rn&B&i83X3qYUhQ0T/$ojT8X7iWO(vy9&8_} Wrlwٻx/I"273_ r:42YVX|1M[rGH=F -rsg幾't@$MLL~-Hރ|Si;kjIHF=-ok{= (*d? H𕽜+E ~z(bV7-d@^?7 vy2Vlzv&iˌMj($9=Q}4qv]؞+e+Pt?O=P+?ktGt4P}<ٽ(HUTVYlwق.Fށen{}wf=!XXbn]N(7RJrj6>Cm##4^l!.Q^)B`BwG~7)2jX śUq~UT vsf. 6v`;XIP[-CxxS[X ::e-f4?z\dʅ=Ϣفs4lodHLÐ:H kץ<敼v*31*3A7I#$q>Cx~_7eNh'NRxm5+\Am?s@ATi/ ,t􎡉rԛi&_4O&!Hy=dm]w.#&Dr+5'd׆PVZ5Ru)VUb8)ݶB~vCk&N@DzTn& B6sr1F i%ă׮o'{Bk87[A[@+ؽg{NhLiEh|jK8pjDZ,Nb 'y'oXeر%B @V 61mӟ!?68 zumosas = ;>rU6Vmɭͦը[A\w鍸G8ƫ>}K ka  XT!ni3-P9 H2𐕜,'H4'Ontv肄2{bl\XӪKcw38d *d횥:%MkpWۆɭ[vs꠼> Z rt07,+Z/.~>ٙ-o5q1s’ɒUYi7Da\h&cZ*lX PP-*4FF:YY_%-Fhb<"SZEe\x"g 0YW_q.S2α,},?&&&}W_$j JE+W?B&iiB-_FN;\؅ ukuX_+qC`A\dT9E؟ hjO24l#VD`+ƫZ,(xć"R #Gq9FÓyq R"h@dHielɹ1c~ΞsO7nfQ׬Vk#Pxm-'*X/D"E'i|.3ua.-GA`΁1 #UVP!ݭ\kxݙ;˵B|מd`cm>cM\mTx#\xD.72&r}I}!Z\s"FxK-8s X7/cqyOPm+I:XŒ\$]kwјz6-N6v;0e=G"8•KWGu#+Ps pQd>ݎO¡y$#w}g=,^YiX왔䒙O=LM4^zHePF|oel(47-e%n E+Q}N8Vt( %10`Z,JllhD$6#!Q KO''GE[(./6$`)W19 gx/q1g(nit_<ơ- Zì>ہ($p鹩Qh vFn-wޠ?r]^\|%^HB&i9WYf L1?z] "DD.켏E'9?1&!5/gcYXX~w |d/XKцxٹn!.< B!2D*2X};F\!9 Ax7=wI=I;?H<{+j o<]w޼mjxKtXnFrl+q,j nn{"n}Gr/Lq}^wyIaI)9^3rvlĂB7$(j@h\< ܋A ܷw_.#Wni9}#Uȴ A ~PZ˛[?.MWE9pqT'q砺Xr!-,Z5,Dα<} ٵ1庖4u9jA6niM. _B~H0txx#L{YR"0 PD#EHjK>%Kq^ukV`h;'vK2/.9ɯY?bʳzYOLas@O&K, $Q\! SgHyjKՆ4s LhĀHUB t;@H$ )q7pR5 ucpUl["f6ۈ$ Fl|Pȫ^Ɔ5˱:6N:|Ut[[{On>O1n OU#@N*5h`ãR[J,br޻6{Nj-8/+YrZCʹX\W0i]LQN69Zfsg@'E.$m?'K<@1œ;!=<^]],˄ 9».QW(/NȫB|߭( xٺ}9;dXk]PB|sP :;oǨoQb+'oͪee5)-Φ-)|kY #dP_ט+0 zNN\[M<2y!X;XBV\!HAʭz^!|M^<ODfCcEUZT,ޱxr' F-9ߧULJ/!ML0d"cK^")A)Z#%<c.z= %lv߽X̿vHiDVuw.zT`)q/ L0W(*6J*π&tP,-b"aB/IP0}S};VQrΏ9ޝZm.,HEH7m!l)ibd~W&^BJt2Vhh'>7(USħZup5da)gK^%5 + EEZS 9\+'tb-_ê E0sk (R.3byi*d`w$Lc@Qcχ)q[rSeR՝IeB+2i;yɼZS=7Bh!!z,v2>AX##\IܐxU̺Eŝq(B2Ǚ}nyU R ANU611-H1b 'y[Kr2.B}-Y37BXm(wQ%YUI-e(KHW&8pfS2N$Mt-ՖD,I2j2tQB&#Āyt%5_QΉ7wۀ͛YkpzZicd":$EՆ>>Ncca}]1^c4w+j4̵Xsپm5^_"ygn;!,(;-9rc[gXc$b0ُÕϲKv1n =#W*@@sck]SÅ5%",v),eb17GЈn`Sҏ㝼n#.8U8 |)=NQ KinjHo# ՎSQ&$@u6+.|)ÚO71-ֵ 55Xc uΑL=z=ƵcﲿUcAq1"( x4,f2<5/uq8x`8Pi_d8B CHhmrjs'P?#(2Ka|t6Z:VzuK-Bg%PLY" iD(3BS!Ǚpײ*!Y<ԑ: @uO*ϋSm`b:['MO8OטrJx+~EŊ.cQ8k$m#J~ "`rZ\McLU,)DvݾB,a  PUd)MtuG]G!>BOJW'6 ݌u!*v♕(Χp"W &QuX" `z~N&Ih* t:PSQKJ:H i1SjJR M:Y5<񅯰sX,fw4W;/KX)T,U` {?,Dgfa*a`Ϫbb;G/t WVgx/r`(p="U#),$ ,?{ʴ^"aaZϪ&@$m˨e.YSO=D}Fd+mh"CJ ]]Rǚ,ZOP 7<:?{!(,\dcϋȕn OPp=lALXTPw+d;WUcQn7c EÌH$u cR0uSKPU (I&o<}BQR,Hbb`(bgWȪ2ߋ#>$˙q~*.hC'1M' EuM7ڮUƶZNsm(-i WQ[Iۃ%E0$E5,Ļ:04x!&&&:˟ٿؑR`0jmB{E<V: (M'<-.D^,^$dx>뷲{C-lF.p9:ǙQ\JIp79MBbzڛpx-FÏ^?J{W3dŬXTFaN&c Lur}6J)e2699t,MIy!>VU!2x77,w|F2Dөüw@ m(9XE3'تݱM ,Nܹ.&D UT\!v\$Q|Yb ^%c䁰#XXcIl܍NZc8x2ժSIO=@۠Q9O"XBػV,4S(eqUrѡ!lm^Oz/,ձ6+\igxh!z;i@P-`Bgy<,%\8G/uS%ġcgeSXNqAepYzȭ&Cw9vr6o^w_}q%+Gp S砷8{#[28+.YFMƫzn[ aeuNtZS{+Hf%e,L|0/4T,Kcq Q]]Mea6-9p-=dS]UAYJsc }]\idCܿ"TNbK/h9EeԔOp}4hT/]Fik>KVTlLC7 ]&c ~BH#o FO{sΞm.\N#L 08S\U-;7jgʅ%+jוQ\RoK"$!:[[ Ux 1j./}Q].ӕ,vSia,{?⤶L +\'Nrj7ѤNt+dWPSn&&wBjc4ƦkhZګNjzfbK)^o8o7^k $|#~p:C46va:0˒UÜ?uaC,,ͼ mhAqՊ+#LӖrIxr!bIaI y.T!;sw>êvtZn0 D-E+zZPGY'@WlaV@ z1T'م%fc"c=4u]f0(O*Jr3PDj:4)bAEb`_^!nZ{FQT/!ӚRj+ q(:ctpfRQRr Sؖ=C"TTx'Cqbr Ws4y5_y |,2(G ]Tm$F,@gK~9=ePOœ8u-0F`` "y=D޶t`PÓEII1>CO0F$2N1/HG=AlV"'c(6rJ)ȼscw3BxAF!PmX*.o6y8-01I{5UdtUP]Z"G$"P&bdo⢤ '팇%TbihhGsPSpJ25Gx.#´v0J]TIuY>|;/2)Ă< eOz6zC8yV೫=Q:ڻ&Q^*kP@NX(AF~)eE9@HBcCt3WB20@Kq~6V1w&w4;\'CX>rr2 2F[kAC|.]س$ۭw՛KEY1k'GӐBa$crYh}]D,b7Q\V%:JKg? P0JPե {z -bՂLUrsrp1: Jʩ.æN^Q1nЙ줣wpRXVFq^V%U=irq+<VL;y܀r:QfFQ^zUXc>DQatؤ봴Q\\|ě50G*)'1Qz:ٔപIXEvyRb\B%k*" Z?7l4nU1mνV*{0T_;a7@c4Df=)T&~Rj:AnH9zSc;qDLLL>cQL-FI=CKh ӁPLɞ: A0f>#B(|SAܴYe7#EM"k%UI01 9}n2]0]?J.T3e9~3}yfp5,1BQS:ޥqiI.Ҟ V.UD2罓do)}@O}fJw;nl-e kTсn|&/7}ͼsS]1B %}lf\GN녆1DHD;~&ytg1GabbrU!=r}V$A:vO1TNJ'k|_kn_B[yH@SVlva`f011ݤg ֐2ppRmᛖMy(Syny>3$GRF^p9|H[s+[}ga7VC{L>E[e餜uܗa)olc67}7N7s1&&&̯TF瞔Z?ctuv1YXjf[7111W*lbX|,,sq6PY0]kȰ~yMLLLLLn0>r(2$B|<>Ѐ!͊n<1LLLLLLʸo.;!teӣCȻB"Rh0G3o =0Ȥ?M97I?LwWٚZ$#tw|Lis 0mLDtWf0˯dBAUUTJUMs MLňFcēG fOCB 0HcI$b>tc:;Bj{IbHH$J,$]&! xNcs1111 qnd*?u(7# R='OTvHExRPN(/Kw0i.>PP$cH4FR3UP|oo0ɍHDҌj6O6+׭,J`}[)\ nh``G5i:\2Db~ņrQ'zH$b$Hhr] A&:8Z4-bb6uN3B@,0›=ăVO}v6/mBH&;9(ILNDusyzME0TŬơw+R3;tBR9_>@g$tNN5[^CYo 8={0ݍ<Ȅɰa)0,]\ǎ$/Y(8X"dj)$z K3#gۖ5|I&+hWo^"R!Gp\0_$ʀ!n=koZmiͿi0)b&3z!Y(Rv=\W9^a3C vv[8O漍|caA7p[ߺ٭5o:Ͽ/w xZlHpoOEÍw|?\VǘV!ã#:;ګ㺭UxL0ȳ5)&oUg{G!v3UP:D>}S1t l-(MI9^{7[h?9zӤ;tƎ7s'鲍~/S7-Ä>s[R5+$dka~tMPd;Rn 郻e/뮦2/I8^EUԤ.,&<7) >ǡf [Vm#ߩyٳ^sm1G8 j#//=p{.~qn庫7ubR$a{vP]|5~~Şb[Xjb}[#_Gtܐ+T;9y?h ǜwe'hMly-ǟo<uʖd3=e9XB^gpՙs E0r3]~Vfa5)hn%jbB!%RSRJt|.3D!mck: gK/Ak'5Ŭ4VVRJpΞN8y[ldQNl2<&>z5=‰=-ܲEj{SO}Ni*}Zde9um>S"yRgEO'E( uι=@M\򙁁pߤ|c Wj ${~,L&݌VWA3ͦ7/?^*j%]Ty.R"}oAՆdY.څvLV sjeLYKduedH$Ld̜(T[z<ᠥB /O,Bk1uo"M7TW˷݂L Iz;2ܹU" ƻ7Nd(b|3 pyP.fUA8Y}z>QPdAsC.!$#w'so۶V/*?GVWEf3YsLrZ)/U__^ ѹKGsZT~f#XTGjh e?+G3xd)/ުD"g]א\XC\~|] RU0n.o/ڝ8v.+#owe0;2Xz & !WG^ Rx K͘STy]=ve^'ѩ&>L'& LZɑnؼE̫ǦB?B$^o:}t)2-T;UW( U,yD$>NS(B"L6J+=D4//ʸ`Fh 5 b1Lm{Zq+2! ZTZ=LH)qzˌhad5W-Ū68 cP;AkI%ӌl'X`fL٨i]5qnFg#IET+ܿ@cb BiyeT`o)rkȰID470 bI/`amjhnȨ,x'Ne0eöe8L(]D환Pr%&&: H/8'6@qm>n2^ utɍ ZGSca /aA7+짥_S ܖ #!4Ѷ&$euW5͘,)T$1;]sdJ"4Fڇdձ ݌OVJf+qݦuYERP\E,Kq$=}."׍OkyU Y8'拾{"kGGfTg ܎Ow`q=N&Z{pWx~.LجGlY SR\J-AT*82qLwr|+SK4x]tNI^ڕshh)tlQ[{IسYd!fGT,jBt618D*eT #=|8U+&6cMX zqr%%Ť;̀ZGx WY,0]d:l6$?sռ(@US$qTTa&!4 =䱣 PaIJ+uu\bf1=%%íGyy9b=c8M"4̋}kGgwFPjRAf Jq! M3[L/Pp{"QPMfLD+T&ebhdo[% }ZP;g:ⰨW4 xg~$8w 15t266̿| E0~/ѽ-D>||c;/|]:H?{)' %PueSL ыD5#믁DZ s#= }OψBdNzi:R ҿ(pv~Ħ(.;*)ú݃Ӯ#0;,Iy%&Ov# !廗b:}76iĦzxG!{U:ƃ'5"y LJA"">ICcQ#tt-ȑfq<+ I31ˏoᘑ 1y@RW9v{o[0(^MS1p5'%.$Q3Iw^ y!D"șxuEx;?'t cc4|?C 22ʾvЗsgq/?Ρ3ڣ?|>^xmt?<](QΙIF;ʯ4R'bb|cJOy=vc^ljDhLέo N{'AYn1ёNgA$ԭ⶝)L$럿X'|VM30x+Dux]m\og(LsL:Wfxl1tthlnh"N\.=Hbb01)@3R/+6}|?'Ͼs}E>^ht6QܢRXiqw_㧠x]x7xD 1 v'YoO#h1m%$o/f'4>TD"Ck[nJtn#(g'ȯ_ Xd%V."r)Քʯam/5nZZȨ^7ۿ) -ǓUV 'unV68 -̓$lR1gyj5^.B!nVnl;Å+!M0VH= #[6B8%zW 6to}O"gQlaB.HbHbIsaVUL mv1t=Bskq !rHpSf# d<fLbq`{Hs1)gf6vH]vZJnm@ 9Hs:pyp̨ 3'twɄJÛA E[v 7" 77pUă0{[ky!M5l=Kc^#Xl+-VWn' ń;錒rbV"3|D8i>{NO 9.5taj|lOɾ=켥Kc-';EEqҜZ#B|]-\]鞳.@쥴"4H>=0 >ǡSTmN6(4:OC氺+E8`M '[cLziGsđ).O&U]>vSUl_QJȝ3=qǦХt" qg.9wR y5Ty-|y$ΛǺֵ+o)Br4-AN[_q!ĬrBptkq4Cd``` qDBJY|ZLIY@Ʋ)]QzQr;1!LthWFhԂ#?' WV.@HP%wL\H-N(=CTϋebgխ_g1óʘϱY\VR^%DںB2ڟh]L+i,Z"k#(O!tSS"('{狤P &;o*<8;1xSۘ ޒs*QRwR+H#i\y~k=fi _.oO) KJed@EJI<{{ur>*~:Zp_}3#$b#H`mԘz}ݯ\)BJ0SػT*h𫼰 uZM0~$`PTTmԭLyZ/^JɞA9 \((@/gBT]':9TBT,[CSl' M qaCUIktyzs-SJMgv2@RTZ2L0?HƼyf];"Bq!z2]CSqTpq %@qzI_R HBB3f-Ef?grYx0 %&W.;?u7kyO8TEIe `ѮWX`:AijgRnHZy]4%wXdTW> Dt7c^A:Ѝ7T=D)V`HQYn k$cJҝ$habt8Jm7D( >BlrUp*QNe^YEpW$ D &TEAQUhok&᭠Jc׮I<gB ,K? :GK"!%RjDbs*D*yM&w`8yO(R->'8CHFQط1?Ou,(D 4]Xu҇; &m 1bw>7Б, kY27KS87L$7aaw鵹xQ<7@ (DGxfq|Q"DxZEͫVJ*j  ϺP$1CQecCg^=+X4L} d*%G@bIVr235o~ٸ~)iUXFA; c%XW_TB9-:FZh P?!!l+jLJ(NWU4*9ĚYDUʛ=`Dq_].cĤ |xW!$Zpo>0HyMH揎ZVga8s]]Hb31xQ3׬jt;vQ>7}Mq8y V* 6ő'vGd[oB:7ih"="e8 Ɲ;mǵ4>v}gsh\s=Y6%Z4>?SOQ*|ݼSf}DoOÿ|s޲432?˫0IEXr|,^ulka/.'i$#{c Ka9t 0gNBpN$,ش4qMF0a?x0d$ID  320?Rǜ4i C#O32gbdjvnYqOFZ7LV]})%Vo?'GOؼ%8fdt#bIa|rq"BDȈ˜/LI~#P*nYy]'mXP V])0ΈϘup]gld ߔ1b7|Och#8|R X9Z{ʨ*bʰD$ aZϞish/D*>w*'q3N(hb7\sG $nfͼl[C8M156$bd`\ǡD: N129 #ykwrGS?{_|bs[?ͶyYDqj^! Т!FFMLeq˭ؼv %Afr֤o~7\WQnHu%$SSSX,ƺ9~[F:VUL ΢j,_@9H~j6l*Dew ?ּZ޾>i %XRWUST/eay.f&{^ ?ś"=<ʉ-hNNޓ9%+R_Nmn'5y("}nFy(pbrEF9Yq)Ӈ NKXj9fz:hdl|ɘ[PW =D+\ Ә`0b!=+2LQڻ&˛EQi5,YXMƈan (l3)+$n믔c 6Dz^^yd:-$uN`ʥ;f3/.$˛E%[t14 w:ݲe{GŝNfaI:L3J;<3*b ĈH S_40 !P-nͫ"aׂ M$ BTvf6yOv/.V(L~Ԙ3gBQSaRcv{飚_Fdd;sޑϜ1xtȺdgZ3LYxf+·}/{\B;.~ϩyho2]yk.i3I.KuO8-tZN:6˾K7{/l\_^މ>:4doUKd|m tR^ (S.?I߇ΓF$b*&  -BT9C`|U M=~j3,8L׸Q'G/+=OywOBa 9Ȁz*ʇ$200000000000000xQ'5`H P> O bn%*s|7c`!D .N4':8ňk/L+!˕5000ZD,[qY\\c0o!RKDЌUŢDc9u >,oD"  joy(PEJM%n}VI= ɘi"q~ZT=B( &00KWnu/_g$.> O.>"7P~vBo]'Bkqb(&,3 r !'j>OJmbVuq1 DEHk.W-$azo 9BQX̨ʅv{ I+U,̺ ! MT ]O\jd&:!mtӓdu[HyEn}c[ο}ϴp -󎪁G d,ǺM)/'I&@őj1'"ڌw ¤"T35O̶H-q(zyc15>D{[;=$fb**J:+Nݮsܷ?ȗ~X|bˆ'=%N$ŊlGEE9wezd5EmkcG4# WQǹ<Ԗn<700$ B 'z9va4b57p8 DhA"-&mH@??$ъl^8"|4]ddI'!;z}O>`5dUsoCݱ̱ZA |/0[I:&HZۯ^~) ́WueYd53›>\)Kwb4ɕB86e٪:lVZ/s|s%߱^J#lZ +#dso>NvXǔnNSSuYn\'H:M qΒԏ@(03${y~tw>B[x; T4bL5Hp쐐wSct2'%x\+K+EiSVT,/x|$yW!$N5ԧ{0 8ώE٘$GxO-mǥ^a) pd+[4 \yERʖx$T DLӱ8I^1aL Dui^<.+B%t/V4ھMvWCs!ȲŒFM]%OF_pBKHOA-ӣL5b)%bBHě$.Ld~ARI'iE-br*H,c9SLcX,&">BHCbB59)i@x\pu;P]21#Ӱ|S ?=&oa{NRXq&eSFzr\BV?21@bT">hǧ) ut]/{EcO" Qt lWzpo)is <ή!X~ׯƪpFv"0I H"IaIzfvB"2dMnӜ3E&' 3i^\v3y5cuqcL,*AIp ӍYmHX\^B|'sòtȇ+2Q@ Q;#4[*$H&Qm.2ݘ=fd|pB!-#=5h"-Ac :QnCz(]B8 D,8ظiuM3]#-$B~& tiYIxO C8&$baBq]I0`qg0 I(fTBWmddf`S'& %QR$Nhr0g:'x4DDSe|2#=22@bBSL"CJ"8ާkCܶc^򲼘d3YޱCJb!u M(X]i9LC9+OZA )K슥{~-&n֝KC/}m&! ?ײ@pgy8K tqBiӷ̋cm6#$DbE261hiIZ|Uo|s c ;X1-(gΚg@8ؚu&4t b1:{F\{-kܜ> Sl\eYOk')u,9d[hy!6@ޢMIdǑڽAc BAfh㴝`n $qUHPVar >@9;nlIedf4OQuO56KPM؜&tó^iK*bm gR .]UTqgi"Յ\o6GcS'aa0=A^u-+ G^~]1/,mOoYvqnŭ_ 7Gih%[gYtMk>ܸinGy .P4?g13%='QYmăutʾ=0U^Wx59<) z&ʲ}9v@w'O\?#N# D Xo>K-4"즤|m??:Hg>MKOqJ|'sG;)_<}#GO0f*;>Tg!L06H|hS~q^>H,X_3z328s]٬z=wy-72_oo%-aE RT%Y!f T0nrZشB3JW1Lj MM02v7H&}JĉE5*tۏq{W/AkF\lv\r8<_^soJvpv6/!y){q?X P''VTh{ᄇM7׮"i#6Ec`qbs<~B86Μoe|W;ZomK+)|cwBj>W1ygw#SN :Nb(ZX*\J6@ox1cQjb#HN}62';9Nrߦ@e|'}jrOxR>'@QZ[0coX ?L4mۯ;8+ϮcH^?FQV>[XW_UOfF&&cpt7q -8BþL󙭋p,ZiC Q?^~53$O0ٖ.[yxnfC]1f>z!&0<9ELMW|)%8'r5̒m7sӆb:J yܸqFDS0o4w]cpoxT7kn"_cS / $ w@TJjkI08rΒ n!{8?}Yzt<o`b2D<Z66NuaXg?Y6`Ra$ jWp˝c ^|X:~73‘d_ǧnۆ}ÍH`&_>'ʼH=B \>p׍5cv1xF6 .yy,W{ܽca00(󮫐@2[{lCزv|!纐f+KxG߻&BNJ'"r?wQؙ!.ZЁۮE1Y1[,UNP\RLv rq:9ݗ %Ǐb֔{RGXDcڅPT!PL ["i檍A UN<1QŦ9y4MmJ6l\Eqn Y6%j=R{Ȱ+$4ȯ[Ryim(^uRAjB3 Ga[M†W,8LV J(a^]6RӑBRT{9ςktd,q^|~lYVbLD(^_-3pe¬/kQt}'zy=yaK*(wïg̍?#"|z)XTbŻl + 8ߣ$O(̷͑KR-4|h4mA p)Բa r JɰVVMZTU{ d˟/mM,Y_Gjig̶\RK$sXBh'ώaME5[r^ ihz&vwLYU$K6mفjCNOX/K4[Hb LL!l\iґR;5;yrdx0[%B]?D-4QTpz (/+k8r w}VC_|?{#Ɍ|s0&f&%xҺ(()!7Ӌ]ŭ7/~B "ڹ,k2Lj Jqv&[)j0%7br܌P\Sj-r"r2\$\uYhjKz7^[EvQMcqt\yef0^AyE2)nd Z TUQЙh|{.KAyjD0Ynդ*Fn:B-SPjֱqQa2fMHb(ZCie KYjveC;NIwb_Bk':N ,xO'K90$))Νnb Ϥ:Tp{Hs`AzHɣ͆V?/73T'@q`d"N)%VnuUӰg?-uRMIKrtI<%1FxpHKsa3I9rRG4t}:p*ѥj2Z Hz2[]'xC'el u4m tqxQ4vJ$0qavn5Gwi D%;6/c5#^p8V\8sR}.fj!+;ˁ¦Y2uK{L\ Azv)N L'NϏx ;2\* 6W&^K7{K!|'Ȯ_pb;zP#_T*ksξ}C*KN=ȏ;,L+W?k olxce0@!L&F#E u3<.vB((@s*TbZP$0)'/^o`$ D|9x{ 6>G!kH$ܾ*'%H3+vpxtw)yswY4L+uYkGw^FU5Ul aڻXYTx_G׊1pAzbzQO092|V~*- O1ҍ72ڒcQ"(PcVR;} 8j-Y9~ʂͷՠן~k7/%/݁%dj*e*DTIGbhIHٶu5z3Jw0x易-'bFY>7n-Ǩg뵋9g][)#,bI]Z"N,%3"u8xx\ǒYmk8s)ع'"[@W#Ei^ x<:-$xP~u%d MmtV-keHH{kt)KAIaG39LkK3*uK*8đ3}c*Ydez0mPJgg]c7^͆Es#:-5;U( JOK~l̫)Ё4!-62s Jct#J)+̥2?BjJq!96Cm@U^G}Pd)ϜeuKʯZOz`-O>h86?߈ HuO=C.iNbC u۴LcǼdx -WKauzt/ eT(ʺLR,.*jP[A`gNsfz&$u+6u d0lnL'Ud+>lofkXYUHMEV6VҘW7/U85:9ĝ[LMe1@?s699ydLL ) ePTVI3NkcݣAܹTa|:|vd&$A [Zu);Z9} Mmttt22Qhueym&Z[ J 1)]Td3r t E[%LvgdWQQh?F}dx6t-A,PT J5KO$]J2R\L9dlPzTxM Lf3&%swM>JhRl1\ZR'(K`XqzBǑ(fT&5,8fSr7. 1L~ ]('RVqYb2Pd%-'%}cT IM !R'KPMX:AH$i/QHx<7UIxMJ &9yF<@ń٬"f!dJ1Iu5 >QHM#ζ WmJb]Qjjd1̪͂rnr4ZbW' TUA 3p$S|xr<[$CGDX<5lBbFiD 20yKyJ(jJn^,q⚞<)+gUеK_'fgUM3s> $ zJ>?~YD2)$q4,RK0%Hh:%EbSf 6vd2)boڗ)٪J&7܋ `Xrrx6ff5 >QՄ%"W Fzk~ RyHr1z.H0ՕK֝3K3$bj5]ȺK>W^>X/K۞ѕyn̜̾lb5?NLRMfԋ;gDrQ8jI8e$2"TOaq5|i6 ?SR'KR I>zl 65-9~] wKc!H8so:#_"GCJ[:+-]dHbq`]|kjqYp>3]NbSH`qg.j]@F*㘦z[l6+ts]7;PUU?45!e"<'yد%H퉼nk4ۍ c> 1EJ%@( =|$e@Q;H./}.=!6T#Ek;+NW4=l\A(!%RcH{q!BAdUwphS݉=g9ڗ`䦙9)69Bs|֯rF Ef+VS+\@aΞfZeSLDm=ǑV c⡨kQ >S>7.F50U}b!;95BTd:]#2J: CR+)~p(=$&Gey3HgߛDc 6 p^0^β-\*I]O:B.AجToVEyiU'x){I3;p<bKȂƝŜ"O.k\\-#NҊ +8za` 53OB /!>|4"\i6 @&" ;8FT*M*6g:yy$=՗ ́W^!mԮ*Gȼ~Z^GmQP侬!@_؍ϜEqN:V t\uoKyj ޅlyKE S+xH8_)eGi>&/j[Tin"#"SyuT-{9JlZVÓsg-u:v7k 28Į+CuϿyV>B ~a>m* >y =w%^'X|\x珶ϲfY/ '='~gFxK|oѡ/_>2000x txGGE8˼r"' r0?œLT}o.l[BQo<եn 'X콛?ƾ-Q:Kܶ*khwwo)4&Gh>~_b2 u!K*8hMEmvaYmۮH=]1;ĭk0 qPGL000!|t:/`ބ'D F,mǘj:L {}OX~BLB'륿yGyS>NkC.7h d'˪dQxjT^le!e%*桳ya+,WwG/ 7텀| `'_n%YnLJrL.# (ق]M-:?j!m$&lzTJTW>ń-]?翟ocgU5x{Vxyp+A\ {G*&|(o n/]f{RP?Mss7z> Y@"0NP8ݼ5RG3XӔ!tJ:Ǩ/=լ0[E"=aj>ecmTXTe|;pQgI0CSܤ9LNfcͯxG^-9?oz=޳9IBtSXݙحFnGzФ. /&ۃmiZҨ1=|ekhZ2oe7%X=_o^z,!Enk+p.`ٲR?Bx!fcVuR̼8)5ηw7׹曹ySVD:-(iR!-[?Y <șp*[;f+2yO5.!.%EgpO0-bp8J,)'ԍhkoca_!EO lAuRm+5W`፛ccD1D{O$3:) dHΑMRso]b9NAzનn(, W2q(SC-ϳR>svʳ\cqevǧYVBt4=*zo1=s>EyK)8~ĖŘt(Wcm=D^ \˂t- ka tM1JKzU cIj``aAZ=4=32Ba$R).ʩ9J7Y r P@ koHf )!BT=͙Tα^KQ2M082YjV>Mc`n 7H`+(߰4"$#سOt+@RbqfQ}-H)]%դ[4y3D:he;c$N:N`پ iX`ۂbÜٮI*V][*H=N_ #c9p15\s+չK~$tTǭ]Ktdef';j*Qѣ[Yl]TIHX:}DP浣t4C 5^Ϣ|녻 щV~ilڱ5D(hO3D ;yrMlI@"4\ wk|~ZnX|L t|]olI%z|2HWkm] RY{,/ر3bhZ#+WP"e+/ҥrM;&8kWLs!C j7dE˿|=҆Aϲ@Gr'nc"~"ln$?ϦO6w./ 41G̷&ENy l66&t6go$8zD|neyN&O}fs_l`A.}䬉 Wª%ЗR.yRHXW)rgw~ɮ $!#}q} ae|Q~Fho>Yu(=^&J]G|M.֮IdʏO5c1);i7C}2 HNIg"x3STYY 1O 0ƾgW֓0íGy_]lز̩|O=CaZ?Ɂsֳm&=ɏx\A&T Ox2AH> ry÷d+|'I-veY!CLiV*6; z&Ll@A~ ~ !5_ ZXaa}%ʫo憍8X3-Ƒ_w~߹ɗ`Xtxv7aՙF0Nṳ^'c! 7gޤ?jM+O/զw(?}v7a re쪥l[?7gO&+RCIjݯpk ㅁͯVFUdl#Yz~a;yzy~:fۮ'?Êp*ebvfbY,\*+Ӷs + uzs5 U"HL  ]%h8OaMLH:&#EeٗrV̔.ЍmV-*0x#H(N7(xdWd~.$8 u4 5d;L%|)bHcB^,_%*# @`/]Ί?sνS=ߡ5BgB9Xy> z19/_VL>蚖ꐠ)Lrΐh}ưP"ǧe@& O੨$ &wB6G^f´ՋJu+fK^bÚ%raZpg4h \V 6*דr[X͂"#լ]E!co$R0±qɺLL`:ي?f¤l*x¹䦹jn1/PPPD%SHt6 l'7Mtv(lG "?0}g_G'Fxsqn8MqOhԮA>î=gYQDlftw''O/&eQmx|o/4RSBla3f߮jVŠ) 2f3cˍj$7'C{=Y,]" Z`KC#g:5QA[./L\.+ _2&t/2ۮLw`$hE'(JZ9.={oWZI+Q@': <`0㽟VUwy? s]ykt9aɍk$yr;GsZ>vr[L(bWPHQM(h%T$װ5B2#6S. ;v9g V)_b&u\= Gh -`Tհ%L*z Xr1YF/;̖^)617EE ).CA>

TkEc .E%zL7dR<pט(s-#ѥ%7ºr[P ER4] K0s_(V"0Ɖeְ:LF9CFQQeN G)u̅umdξ~@J^\VU=D&9Mmd}|v2*Pv[M 먪u7P`玓D% s9SJńvp|?H\tmCm_6eOO_LveE&8-Ŭ-ltHHIUUQ$:<͡|~KaImG5Ϊ=+䒷aVYl6,/Ogۉƃz[rxwzG$vM UIK(^݀UhQ:^yq=[0X OwiS/5Y7 S*T,n'21HWwi99Nɦ0z:?Pbm- \UUDՄO#LNk3w-a-OO\W_WMɬV21<Y )IlJa+滗>ʱq">yֲ҇b8\]Jr 'S)g{]|6/Й:R2:07lVE>Ɍb-_K?Ǚ r" tm;Jf״dz:znZeϋO[g2A{Κl*x󌎍Ls(znMaL?/`"{w'>=2n |&lZ}w8HMr 8r}M>p7)UI{z'tqT;cclnd{=jY#Ho9²{74`R\/ýtO($N\2bG>˒c2YJxH<}ބ@J HmFS~`5U+6P6=2ͽ A0u=LkH!w7p쥟-'ifbK'8>J{k;cA:cnzܷkn#d' &D[xWiOy*BɤG#Q2飣wd>TMJ@پ`O>2m\Zx4m3ŗB2PHmV.I$ MƉE#+}L;}? a<79~gi>}m۷-7I*4ر *%Xͳ&U0¡ 2E[8UவuX,*K8?N$S\]Md^R(m wFJg d|~e/mgٵc;[;N]Ś:C}dwܵg$U<{ع(I+%Yn_^I@|-oh5˗R]`[f*V.%{s Ntk\LcS}YP6_hOƅ"֣{ H;^ :SQVCgT=c9“ yn`uM3t>]>`[3=vбm_Fb1Ba!][Wc309p8Xpy%4ݺ U>_^EX|%8C͝㌴Qt˝TAp 37NlФͷ7e/9JWw흽v|qKW9iuWhia<0NW%7aZ%|V?:駧3g#=5]ZKu//n˸Ϛ pxN` MՕԔjf[8;B$_YCiaU:N}>ugJU44NW:Aelܴd77 hN* ͜&{Z)l\NC;xmQZV.ƚ`> .,ݿ-B5Θa|>M8-Y '`ϩN),jíN,h3dQIɄ(߃:$&  2<ʊ  R##24H]XV|eELpOp& s*z̓m}e1ݍoE jq8M$%ɊM z*Jd$WieDI%&g<%@0aO32$)*&|>nL,Doo? bo6Yd|dxEͮUy8}hfe{(TUV2NaSU%:xQ]Q?LRQ\QNLp0‘GUe(:+φLF$[7un 362B`2bsy)bQ%􍄐&ex-i{qK(c5A2bxdn_\L{S04 CSwJAc> &Q'(=C2x J)+`V}!s,Э0:X8WDU=w& K+(9!cQ5y@ֶPZR[4m픕]hx/{Qɀ!Uﱕ*dYKzB&/ʀ,D6}'s[゚ZW~ Q\:oŜ~_P9}ze,\|c$D6v5\<*Ht]G1bj>9h>o;lr&aS1\UE-AhyPyc֥͕g2 bA'O 8G.f,{%Bg .:5PDk99{sڜK=gӥSsyf%ЩQdfg=!DN/'.¹DIW-Qo~¿D4'Mio֘L O]ܱPg7s_N=}pߋdf9=$5;>yٺ{ѩ238Gw5:^ͼgeͅzmrs9UE(U!$>t̻~ű Ι[3I wْy؝Q<ߡW"weK^<6R.js'C?RHwuRAXկ߽]"b2_%KJ 1Pٜ~5FwFNKlL9g}^#Fy_gKOb[K}E!=AP)18ˌ\\Uo|a9yTX] . oߨlkX4Yep#QEJzFD J+~E 60 \}\ gY=( >8jjjM}rq X],P/oa`````p tS*e(&fiB7h@*FUSWz\ f!)\䒓_2IW&zY 杖TLؓM\m{yY3 B !&hkUpZE̙ v[fH-pg]CA4)10긜wȁ!=_ߩH5ln| f/̛!ib80p80)ߛZ0VQ;<];Jő X"5S]5a۱ի&@AfÝPU[E( @g)Yy#<+Y}B!9ۇ۔JY2~qB!KÁUN2#L!emdna1WW;ќ) !Lerjf %>~ ?¥~KN! .JV3zA_?⇿GFiS*C$ĕ24 $AaAqq1nz '@1wcIB ZYPx_8! >9JWWBYu5>WV-6CģHo-_A]d$H *(,2uա'V%bj*_neDx'O>")YBIHjfV ߝ _fQBCix9g+@*0ڍ7gșAƛIjvp;\j1&:H&3xJ Q/B q#ģiL|bAh C̝߳B)X:!\=0eWx}4R"Hq-whXPJl$;v$B| <}n_TD8>":AL@v|O/-*VV$9ew߃3t|)8aF'3z^IvSס"A9tk˱[T{|4ja1ڻt]QiA200z 2C [@yC c;I20Oҷ0};l_z;g SLǑBM`˧z"a/Wkie9FJ-8r.ieCk137D|Ӊb|p3늱:βz?6ywlxCg!$_mT7f@KFi;-'RߴyQZ\+}W/_zs|8LKɇ C`sv .Qfy\@Id~F{8=P[(DOg?aJq7gOo-/?,!XiZ0 TKoDF1!r6dC%jgB7r (y+=`xxƍ+_ںE_5[Qt)rY0~wu T5?O8P=Ϛ9K͞7EA 5a tM۵ BhU# ƺFn%XSA"Plxjÿf>Ş'O܉)$ R`rcS.0 ^d=L߄[`^UMme]G,zO rMƥYgM@Bz ^:>/OI=>)ڻ9CA6tEH BA闐s|~u5.hjvൂ2R)/h[Q\_9Bb$?S f"HP.]~\J (jv&KۅRTG!yfft^ s!B((9.MGR>sNt{ٟgysϕ粟g?+O{|wySE}|rID1vzj<&f 60yl>ga JI9R([eJBX|,(g >2#0$8^X;?}7 %T 5$ 38F8ĚW*&I,0L@A>G)]ʊX/pBR(l`q^GB$:MgB`P^]|` 򅫩,uu˛E5݈IUHӲ8yndY1 Nvp]CȹBZJcJTNB,NYq#5> hN? kL:zL@i"4cS%~&P]E,ZX"HLe)D)7[?@q m 7J4CU s@$UMU+Ib``#(V$:xy5(STeZ*<(f;8Y%X((#ؗބ R^  iFnřoFk^J2))E8kPP$hfoTy/zySȢe %DNt_)r:k6@F{Zh'=45sgs:BwG;]}CD2&fhMU8ThRVIznYUC|lMYtBC]t 4-iG{8D,M~"V,(t5exS)2^LODW6QHi=sKװE@&\ (Zsԉv,:Kװ )oJ_˪&v6[F7.KC[ׯ!&O7WHzy Y)j ; %%5ԕhIƆzڨG8zױB{7q)LvxXf5eS2 $k=>ō_ՄZ&@#i%8 R3!wNt.ndݺ%T:pװpAS<qp"/p[>A7js ٻ+5&0}Caq2: v[poZN׮_w"πtƞf҄93_t#^}Px@F`2yH;'vuo 'F^ @8ʸ;ק1A"r޿=p3%ڳvf2 !_sۏ2I9O-~ RAhn]Dj'~$'&?+E9αcGh`nO~=kO~̫{O1׈!@ Zl[ߢ/,񟲭y U߿m+<~ǎ1#Bi{J+JpYtڏŮ %3+7b2[e姦?%(>ɰ~$V5bU%$|+71vr7<ŕTֲ"b fntJas*V/>C~Z\M`)4TƜv:enwtpzTQęMk\A5]5U >p$=T>%TO‘f_`ѭ+Ajig}іƇX>0%'z>o_GDew_OOwp?dQ&pyQhSkG.P,TdRIHZe%g$˝ZSPHՂxϣ{|\ f'F<&gH߾iƆPXT'~ :ssh+(޲\jBL5nmbyi`mY 1SCgo /~]N8scC!Q맴ď%"% kHnr nXS5K-a"j'9Jb%MXZsVwo֑&J\PH2^Rφ7U5 V/cSc>U Ν$~} c[gf= z*u/k7?]dbG%:{RyGٹm75tJ&Tͩ! :|!PaQb Nӌ׈@geϽu]|w1[ZLpXmXTn:lxh%y|8Ñ9} q#^͙!T36NwEY;gmz6ibq{`0k:BՌdAcܻԟY͡%]UϞ㽛G說ʵ"7EO_WWCuO/uq\@gn&*%,;L ۨHBg}]Kw[elT4%"O RCf\XVfBRb%̮;`|"lf VA>vU8N_dUU!tpֱcӌh=yDClټB(fAs[dtf!bǟba%BѱZM9,z9/;TJ8YͳCP˷H $Gה4Sz5N2 8C#Z\OSk Hn5!8=>l tJUB6%ʥJu#˷<Ǐz)\";ELƹ ,Nl n\S002u<s_n]*E dՊ_iŪD66's6w7Ϗ[L*]C:T@OKljuXJ3A@h2݇R걠k:B>wĔ=sJD2g+c`})Q+kֻf+W] MCO's f~c,;FZ9BFN 9%[ǏŽNn\Z(8(14FID"d<%y63o29ƾ)^jdj;96 YP]D84@$1eWItffI**f I%dt'ôuԙN4`YsO:g뺎bqgƎ?E#ࣂ$X*GG M"bv{y(XDCsWcP{׍Xn&,لt9"L]G)0r ʻ)r8 pňеl m-&c/w3PJʅYQɦoPh`Bu"e6DXT5?2@$\$8g\^^(\;)?FZsY{ҶI7 $9kĵDW\,n 58Gv7]3 Hz9xLC(ٍXYq}kvdܱok/;M͊Ւuga E=ߚ6{juʝ;J́=s#3ŕ5xb}hK䒍JFFC3r300|lUN!uk ǫ{XZbPТ#9vf+JX6".-W87Ft"X0ldRii-li{7--©CSk~Y%!1bx4%K}m'UO37o2joHsYܧQ;ut\)o)19 Og^u4j(*f459I5[2/:ϴ@UUdxP%+)q[l\H~shZGRGE,/Co]A4)I'cd95~b&@esP@_TO]QB !n| go!5:H0א 8` PKU)J}їH-ԭkQU%o`jR`qaɯȺ]g&۵0S[xR$[~C@ְ뱪`Q$:xo?J"|ys=)uyȣ4=<7&+bCUMrӯ#Lg]zepLIFAT76w`ۏ$cc#$e,)9;F:x`06˹۔#WAue-lu8m#&41D`q>e:& >Z@PpMDnmǘL9sEصw#!C~}l6PE M# 00G}0q!Y/ CA֨qZ:f NF (fTSdZ&E, F2A #}8jP_^@qE-S!!21A8o( S\3 "gTEț{[Mh Z. yf`3]]×l=oO@TSRG}_Fx)u0((B!ΠR ʹ7_n#cۧ_z"82}9p>My]XLJ. P~!*oz7.Ħ\`M3 Nˉv$:1FĽx=x;F`b^2Y^y0OXO3ܸ.sS&WOog(0̉Cٽgv)r=A჉^NcwXRaL*,[XnEUR.^y ogeJ\,n$tZѤN"a"0Jc횠f%떕ka֭ZY^_fȣ$JۉDL2JC' xwP6c>{g`4AY}#ڎ#͌C tRU:7vQvk~j)8]#e-e[mXl01đ_˺U ؍43y8gz` @[jV"Q]LJÌ߱ [!{dǐU+^ZjDr_'_BEC S n{vO?JieV cT(.J*roc[uIH8_Gz[L²+(+uq-a"#G*LveH# Ԩ­MCP:Ǝ2&zhn>G_FJ$y7H<l8rz5wlfELJ]b20L$y%eXC޺qW. aäLt7wVjYNⴝ+GhZR@^}~ի[ٻ B0m{b[vѓpdY-yv+0"^Ħ6$Û/m\H}؞8D(@_ &9%^ vcLL,\\[(K-buz)y0Xp`upWYW/gŚUmF L0Mwp4H[K(呟F_i=JIDMU{ ."P+gݺ88 *Yt!En M,+A$ L)+q0QPXH?_q+4RචZ]-ZɒbV+26h%o\aP50 [a!f}N&FAF,A8/ J7/q!J#D'FG8+ZU)P-Ym!1A߾Ln=3kR2Q1Iފ(o*{0-b՚TxUƇ N G0r{iU VR #\v&#8\m^O'[J*`T &֭^BD^I˗4PQy4,[ɢ*?z,x E|D|bIR )RP^NJu͘y4.YASuvtxI%Mln)뇧TPm-f&!4%K*[7礨ϲױw^ՕeM1H߸|+a+(,*2:2]DOqi!.a(# C2:%,.fVq+Xj9yV&GJ+e>NE^,FphGq2\"X")ExVܔPTTNum5ebz֯RQ^ Vx)wciȸ(.Q\RAujV 2VZ͊xl*gVbASQIjfJ**)9ci>*tD?0@χf̔R2?IpJUMEywD"k{9d3T)Q%Dj\dsd{&T:PN"gڜ9W.uS*LM'/RG$jS0JΝo&e`d0@Jty1Ч1[XdCY*hmOTE͹Hό۵11<@&v(Z%+Od&I||dQXժN/z2JtttJbr0\sRlC,(ήb|0Eବ&]$u"Oi<>uuJ+"FhSȆL%+kCt>,\ҳ-f0[#E.lN#lbC]Jʯ"uk˙=qLtzمϥE0M n>92gy%ͺO՜l"%KtMCE={=FGdAOs3)\hgMz\Cp6x<γϽ@<#x{(-)>iokBs|yދ[T!Ӊ}Z([Bj)@,;M 4O72+,5M }Lw͞_]K!IV~떺D^#7&[me^x)Ѵ{j#LᩢriBѦxa,YFnkPPl.r%s6ٝ7H]ت s߿OY;Ɔ3DÓQ Bf``pmreTdހj?mgH]^\}5cU]Ѯt1j\jIJ̞Rn{.QRHs}_gΆm``p9_ߕCUTjKPi``````````````p ;0`Yqm9!c``pE]jFd+qk\뼫gQ1B Q4c400BTT]d7ַe|1J BLH8BX2 > LH8Bڸ a>$3ձI!%1x^ɻϜ/ǙDG;xF0ed600(*} R'IINV\w d5de繲kLr9&F?`9>][V~񽟽HJlp ft̹F;xP>300fyW90.B!I&(&,)($cb fÊ"NB@<ϩS-)o]K&Bk)"&NVȝCL1̹~be,+,f!1[L L&% )& v r-2^ [40P[Se.eLFoIH/z@e .B1zFd-H(dƚ9>>i* *@?+XCRhw]$SWbʛ*0]f"BO3Mk[4n0YK*YRJbޣ[QW`y-)+@KEl0& j/q!e~Lȹ5J54BuW~(*Jl`rhZ7aU.}d3XINWlҕ,ߊ!  rroJL[0r__zgGI]O=lK_,FtK Jw{ȫ_}K/?^`"l+}5ɀ!DF8v[_}ٝ#@huko3،shѯi $V(4gϙI,u+嶇o1`H(B!P\l|r K8}~+}zGly2]Xꖲڥ׳x^C  Zsn|EDrF 1/▻я?'>6 Yd1yVyYB1pzܸ+K)ϧf:nZQCۛ/sz(1P3~33c~kb6ZEgߠ]402⦸CXeθi- e"qng`L&ܥol"5zÈ$[.X@i]Ƶ4ο~Z{|w|Gn[MEq>"W̗>IVi9崢/oPPݬ2#r+qe}~M#c|*|%soU9nJ{ !B-w>sórTnEd;n",)sv( s}V㳩8 Jp}0ɴB⌇6bQ oA ENąarZn̊`y';9CKч8y& cR$E):l\*on}˹D(ngqys+ȩm$]ܶ 3լJXfT"%@fѬ.dtѰNIEn+DcqҚSPe^L 04>E[IDATSHY>+d '0_\ Tpo͍&yr&h/o pVR`pTm8= Rw"m 2_eϗc2Fd^>X_ߒBвP(@+/<"ſ}k1s;z1fPDJhhrVHh3BfENE 2ƆLE{6w>E~O6r!gd2a&8f蚆*VR?~X;KױvzfT11}ANqsŽ慓p?ĨOslZT4Lj!BJMWPV%ՅؑGMXq9| B%_H^$# p6 ʊWLMvH 7݇|eKUI=;Ozïgvfi:+#-`SÝK m1xҟ 7z(C&Ǒ6bMedzzs4ȭXwpԱfiMueR`@"0Y g[:e盻H_#ZSݷq }m) 8@zCO"*㏿Yj=5<~?]ɤc9Hrs#yh=CH֜c_:)enP OIǏ04c!^Ƨ?voa_2[?o $eӜ<Ϸ9.Q'񔒬O(&(Yqm4;J/_g'n[,+”It ,F9> װiuZ?gt9!) v2M I%bDrYf cp4RyPR4=J]Ϣ[Bct9`"JPLfN?X{NϾL$b7d`/]CTr;⦅N?s 7{~*$0ܼx xtnUΛKJj9 7l?%?ֿ`|-iG4~E5a6, S^VCls4L{qe!c#8pś`]KLi3Dn{C$64$R(s=7z+-_=m}~|#EYS[S tyS*i}\-I7zx!y'ÍSQ2Br^B5,(:Na^>kyŌo坬8g3 lw2oƿ"@CAڟ=7QT[;$`b HMl&Lf& s]hA5Ʉ( wg>-jv)lDO76_ nc51tҤ3䠼ɋ/Lj=;,@)* q[sDV}CJptݍܷ4n'?]7ύ tHo_/>cl՛=KpQN86>ȺE`6[8먭ƞϰe09=4UD炬^ ӥ4g#uMӐRX,?{;uN2gUP RGJ=+6<+6/'z`de=&2d2=~j="0S 7|(܌Zt܂5ׇ!6ήB'Ùȶ1-+XRq' $gA%y)NkAIt)U- pd̂լN,-v.t2D<"8D4L&;Bf$6cz]ʂɲk4;DNFl 0԰NV&Y7¿;/'Z$ҕ1ɉçeļFL&zNc^Zh2;1_OcLM'+=뵢ΗY@(-VvՋ۱-hf;L{vh+8Avws~$JK21!$mcٰ٬XVT%TfxJ@t4 Vѽ'l%SDdܵ(C]^RґAjx٭l\TIDxfNN:N0-B"Q)i||2-o1s5b9u=`!@Hp0|'s3HfwH ZX, Higd%:Hh2k<}B`ax]S0re:z2ӕrUE&uq`WR5~v#g3I̤<_-h`ͲF|:dѳg Dg)b1F*j˅P v%)P/QbwSr]Xϱ拟8|U47f-"Won;XLV*5D W7pS{vf$-H]{Ħ[YaEBh8tq{KV)k2q4[97o_{9?0T/sYiLF?UE fpQCTfbJffIRM|Hu8i#nOog߹l"x!Вq ٱ:^-7-eܫ/BSm1k=kUo#JFHFDI2Ҋ"~^{qw:b9[ppg5cҜ9ְUcg΢+_<ͷ1Є/amc1B(dhnb]yZC~#YrYzɏ~ # I =7s7ؖ_bG\w;Ut#ex,J4#Kg0*"kQ N>ܗ)u(Hn'㔪):Ɂ<:J'N" hBan[XsB"8U˗|k ## &ueY2$MHItE!LM$ƓhFk0 /Os7quM$Gֆ2 gdž좳NӚ ,QPQG=N:(^z#o$F:ص0}ÓX@q(fV;";|`$ٵ8bt;Gxe8E3p'LB3/, ߍ~"Jq:: T7.fAE>Ct D(]j;4euֳ@O+͝( <.Q8k e1 0Pzm,n!\A$'F%lXӦ''Ļt %TW!uD;%Ҹ&<TscYKӦ\],ZƪE>qsyb6߲7,gO|gt!f;5Mri>JGGI{k)pTlq`?-{8Yz9e~ YPdc@F6V{(椨Pc<jʋobA6) XP]p!N1a*λ6R}h\ Zârm?~.:zmEE{\Lv1дb%j⡡>BϸΚbem>39|P(*O>Z{BX,>T%)?3}=ϒP 9EgaEˍG]%'T`3AJXb% |N>J_¢Ua hB/]L:Nh0 E)ě{6b KnbmY2 [bZ456vfAHI v_ L*GTSu_: kZnDNݴ~k0] %[r]ײu10h3>䏢^;MEϲIg4 &"DN.sԳݜΟp`Q6I[_Ly@V7y{(-)Aq >^o)PPimcN˶PٿՆ(Y%@sVQxiԙ.q6T _1f_|85n%ɎbŬiCV }J!cI/mPb |3̊Y2U;NN-T4w\ZNOٲ't̞rsѺ:ݗ7W_p~ESkWŚ>3kLrWP=)L c|ɹ72ﳘc?Y/fen;e&2~/PU@+cz6 ㅁ NF"! "$3'WqÂ@=}gJBp Naqx.:ǓWWWR rj.c'qy`HY-KnxTG1YpV8R 0۰Fǻ2`HuZP͸}ҝ2000000000 >\Όh@i( _:_K֕[?X* >1@LMy 300000x2BԘ䭷0I]^V^uja31t8Oy-PoOt t`c2g.RRgD s7ɥB\UcAwB@|W~^;D 6Bb}8ُ Lm_'^ 59ĩvTHPX,eQޓz/nߜ9`va'Bm{a붽3WIot?lEF=tHTG(1~l'~$=}De>RR%ֲxDu:I4ə[o`iKEU\XsPfvӴb%^4H.B 3QN~C,[QLVcs,eZH'*J(r"TV:Qxjli+bFTӇnbͬq['9grNAsre9Nwwwz׶ֶ,+ V(Q)F$raAs89ws&H}POuUuuW_}zqzt75=EڕWZױeޕЕCtf>II:™_h yh=׭N3W'pZmCmC-lܰRZ^fŲ?ѣ8sXnP_"-"+?Cc <\+;DEEitZC`rpGa(JdYji$dMf̌$I%$RiKDi~/< O^^U-"L7vDvl%I$hY_i8DTZ$dX<1;VcDDDr~Z:E" Gio*hm] L{g՟N"8TʍhQN ,<}QhiX^s?[V"gڔyvzؚۏTj RnoH&$׾u]Kg^_ $>JÅd:`G?EKjg,2t}NB玓gOKO}f>px<}7ߧ:d*3}Ύҩ$lSav3cőOYֶ1Km} bʹM!w!bDP]/ZmFj%4>K?938C܇.OSSQj)11yKc w-[gdxkXs _hfj8xFfK TŪB:{(GLwS壄k'fw[׏QAYU$г󸦃wmL̳snٹ>;9su 9ӿ[̮˱t==(S]23'S5 [8xk֠tѱak)Nm&+׭3kqIMKֲOS>fzAu*T/;,. shn&Jhc lZ)gm2̓AM!=`ocD"!)Wl`]}ݗ8xh Oo.Gf͢'RWRdϡ%'HRʣFIl,ǕWFnCVf26 9"*VͶI];<%&Gb<!09(cӖY2= OvmOqi0NÆyո vlcǟby-+ ^9ˁ,Ĺ+Kxi(v!qFrYU N9HRBts7]Ob?;9|Ǟ|U^By/pU|≎ً??9 ܹ Wj3G=dѢ4v|xfK9#mO Ll̲rC9~iD,Sld{u|c>V$[E5-U$/sK93ȶ:׎j$UԱᴇhO0%9xKfP*3]lR"*"6L, e40WGD-8Q`).6zXYBG%jRtO)[j kvp)羥/ f,'4jvf\P ~BFx4Qhġ\Gb"'d*?w 5XI:[7S_$ zQG lyq֔TK!o>G:=9sL_Ɲ<=+0+qIRC wy#o-+q=S 4ݿw>r8mw>32f;QJn˱jA:Z?>\:spZSh%X#ҩUS̞_CckJF8{(+Jtm.F-I΃ڂя}Y)B :));ߧ8 yJ/ 痾kǮIC<iTpiqH@ /'Fp/w`;?9Z'E2sr-ah2ͫ(vZca&jb:br$GBS%̖-OrV/mzoM4LU`㌍ O<@57^pRKxj5;Ϻr?jg1˗T⮨>OАM0-Փ^ZC.^=3q˳;i^=Λ)[-ݜ"G-aӚj#!\^,ܒB*fJt?{z=[I9z,yp%xpν΋ ;HՌg/q/L::ũ;xnl_e^tŋ)+ag^]IW_CĜ((49Nz_ĸ5N ܱ^YzyL$BKr MX^[E6Mv@?90|}Y. GIy=r_z7 hqG.^u?ۖp86L)B'cζ_@:C%|w`Ҧ <&}c *ʨ(_oO݅/5›/ích„9K q(#I׮A7y~q&` ]<; Ƌ-Y3O?R^B(~WT`BGXQC_>gX*v+a#u_- /\.F]UE'91DҺ%N28(:c dqyIǒ$da5~ת'M2' y֕P:0;q o=XW WRE7>IJ:m7NpbԙvI!d_ŽV tc\8SC ??ks3)tg$PHUO|cܵ~z?ol!5kaoqmGI?tev~÷Qh?2N-'>$P$>͋cyla}.ܓgˣQ,./ɑZ:GIK0 X-$K%ۿe!}?.)}IӌL9׊g#W.3u]d2ՄPb( T<5;SP, b: kRCOiY=0< O.eUx6GⓟeR)m%1#t\>țxΥU]B* VT*D(D>&V6-BUu6oXƉ˝Luک,.rʫcwl'sB604qaaMK7c5drwPf(VPV䦸~Qr_Ι0Ԩ@R֥:؝%8?JRQp] (͗hn=E_ A9)v( %\ %>T4*mJĆu5]3{QѸuvvgcU;ɮpv %4*&3:8 YRWrVXJݛٹ)t ͆٬bwf "6ȸxKge^w{fpT,ZEjL%h%S j0"8"B p+xŅ6t]uI]d IqOfHCKA<'Ml{=_ ɾBglm8aG*+0r[I 3wM?10[DvEU5yWtZΌ,6e3$brh BQu5Ό"CJdäH4mcjr +x{x0ݟʓoamuꃎH2C|I.wVPL& I71Z'l/7/:1(YF(BQEl++3dV~S ̚!l1cRtt]"35Kb`"D32Sv D/Z>U;"x<=s`h23J#&FU3L 1pᶙkrX%-Ay$cgAgՌ]Qև@30000ǯfs4F2t$&ֲym%RJ ΟIJQndž`A$Ҹi+m6(ܾ"IGGc9. ͓eZv^:ZZCڈM|( ٠Rjxɇ;a4JՊmېC˱}?A=cY`*Jl|*#/kPtPTUpEFiTEA*5Ź+}$u%F'G @0${AK'ylF<}:Q" /Y?LF:U#ئ4锆"4:N.RDhmV_5W?M[0=KecL2>4JLWPe .Z榢kLcz|#oA$*ϟĉU[ 3 \hk >nҲ i_Npi.M8ذ \SCA6{K*I|dT0j&p;\=M׊rsA._o< L OhBx w=BDa'm˗|}1bZ]-WZoBlYR&x4o$FNA>mf8_ۇu}lZs%;#g0Ly.py u)1< +4&' 3096HwMku E`2) _:F~An .vu`\CKįq߽wR6x"#$\ɉqvjk:, aBVr]+p*#gxk1Fv4F9oG.tc+]DCe с sI )/H[3ϴ0avS]UH| {G딉Ty46s'9s /G\ƲEZT4.pWmwKgG;}%+VRU!> W ;n+R8顤m7'Dю>@$X^.={w)źM+)+)cQ_;c u>cش3IZsu`LJ[ 10K={1&hllħy0{7T_CMW/E ^#^DcZٷk/Uu)s&8{xWTWL|}o|QU9XMQ\>?l幌w5sE3#W!ڦJ)+b5Y/ę̉\!TVLr :QN4a5>d4W@A%Sh̳i+'G={VBJFae.+\w:FaζY798K 250FYMMX,Pݻ!WS\9-"LE)ڶ*bPhܻM'؅v(9Uy-\=}'w5ۻqi @q}#y cVt_92~(ǯv;R;7"+YC.dE(AvFGw/=u,gUCcWS9,]R[9{/'[pVS_YNEUP?'$JQYULbGOpo䠪~wlg߱b1Wߦ/f$LWEv`KDle,kĖ[@]޳;yi_3}\<Oqo\mV rozD(H [&/ߒOa)LV%X̙q- ja2gbH-A"FqzX:">5E:d8fLFMQ1{XcLuDƺLQT6>_6UiBSqE~clbD9 T\/$BQta-VE+BRv`Hp@0iLMNj\^n̪ I*9LHFLon..t"sA2I~O$awͱO0IAH21>I$'&sdSҎӢ3k$?9?du_͔Ӊ0~)T3/Ocw{32B&X)n›;~E$1T: hpPÍe!,6HE7B,8D 0⴪$#A&`u`5 ?_!a̱Fb{?0%W]@4;(--Vϛsr  dx#1iڷpZ^sNWSd$|Yfʜyk7,c:kaPeA)3\7Ϭkomo_G?ѕyk!2椫~ zbCSsL9egd,}٘ڛy{gDŽ 5}L_M[&D6~lٳm7'(9g\q̳fG;>_)D:ĉ{aˊJ\Jߝ2Wk{Ț@+y6_N8k/ZFj*_PT(S1ŕi7|Ė?oeřDY`q3mBs| {D_HuWul{׬ ͉"5'hv [kٵr^9cc`hLsF[ mE1BJ).1=co %RJBp)oP: GbUeUvFRSV$I8*{ò@nN+> )`1{E(V7&HE<5 7/;!;>Jm7`o߰;1 >?E꺻`+(80 ~y,3+W,|ҩ4MMxPIŜTt 7JAF(?׆ddKZ gGr+Aޗ4\J(A[B #L+'fA.|مw` 5==yRGO1Bٴ Z*J_ENnR'4+LE7axs,CUUQU5{{fpRHbBq;(ccOH˅i J >?SLKOo/} &y )_Qw>w̡ ͻV!w?/L+e`Pc:hbމPUEQ("{]Q՛d @'"46N,? z8)RiyCE%>#KF(~^xBDZWėɴZc|WLoCd0#Qbhx(. ='z]hɩN~/WϾHT^nQ&Zo+~ EF B"$vN_zXv-Щ*N{Ony|ChmF@3и<'mȉ;dܶyNp)r)/A dZ&2cU"Q5=M#\_užUzt' $@I|=\eBE@:c.Cw7O2tя6/.ђDa҉4R \ԗ汿?SWavST6; tƺ9|Mi:VEOpUm멮T͗"yYRW I'bĢ!8pdO3\͟|~(^ZAtgS;3Ԗ ӉWOK3\p?G E#%l_][y1f4o?H//tX|}%NH9KX7F}ϑrMk$~: ?Ac@cUigcttAGw" Z>S=}p?NG1"k* !0?-}s=Lг{dtd>)򜂫_h|tv/.%,qGKs~"X>rS $ss }φxpC &dBQf3j &xKX'O51ǔ (deia{?DY 5};b]c:罫*3ir%ה(kMH_4 */B# Qu Z"pR{G#ԧp8c߿D(xl% :8*/庐R`s2DD9rA-p%z.[={b[y<^ &YEjqQZj f EJUZT',e&T97JOJ#㻉P[OK 4=#dSF0xpMp<3{N*q1oS Ռ%XάOޤ.scIAHdplO?r;> u2̸5lo}7S ə>bf3-/!e*ٷ_#~i*[6 pc HDe]tTVS^ˡ7] )(:#]C8JYx/ XY8D/g4m`FT/䔛y%b[?WVs疭[3G+lWm`i"1$0}8 RMMCdbM6PܳR}elP]`"7Q"֬sɡPTT5G1S5#ddKWUȡ ؃Tt[;IZKcr|YE9ɥvq9BVؾROz\%҈\`:3VI:L'/v!rkٺy-%9'3 vV*r,#}\HS[E(iZu+ʥ+b5?m(1 ~SAIvs;ߺJEL9^@鲂j?%gpf"E5bVdv~$g1jtO2TK7Z  XI0w䰟2s bLB@:?Q@'ThoV[T i'xXa F_"M3ʋD6*+k2d:FӜ=¸厭[XR͸1EG(PSN9V5cQƦPsʹcz*M$ʛtŝs  9FbQ.5qb+AS!w޵b̺;~ ^'4恍puJt"X_{wgO4xչgO$Ó]BW kYU_Yh{|IO kׯЉBX*-kSIFx,c2 J|t/:l1%1N߸Fif:TĖՋܮoseyql,FvsDdwrt#MM9% LPX\Ke*\Y¹]ey 9GyX]}@2OB-m@KA-m^$JʌКHXQWYб͐&f)o_:mgaJL[ԉGl[GK󭠧h=*̳~g|o܌UIiWNfQr ܴ9_a"iPHr+xEKXƯDKKq7_}` ptN)W\FT??x:.X7y RQHO_5a銕,H Ots?D ^GV)}\2$mj 5"O<͙+=H4D) 5k='n4)?Q̈́fYLl&?@)oZD&jckp2ᓿ j=&__'{|Y 8/nʽ cw/~e@$v N rnM)z>#/~Ḇ"t+V$=~%4}n;whW."u˃kE2CxmE^R$.t/T5auVZzzxz%+X=?Ca Dї3D44W\ # 2rWo=ϑKsrW›'PT )MͲl|.@2n3t+x:2Eϲ}'=B@,0• uisJC1;p|luR=]G14YX:Ltx("J*ܹn u7Ui]cl]R:Z:>cNF*b466=IMI?Fwg;c!<'q:ee9,jZAQxQuI.J>/G{¾5u՟[A l&U8wo ty4>,-A k)y{ϼGiSt5洞ua͔V-YA NpgJՔsʺ[iY(ιaYWʕqß|v%v,a\Pb`EG~o?+~wY&V1L\laj`ʫeGl}~l6>kSZ^c/̘\]K,׻x)& =J3E Fdb$>3i/}BMKv[Ad \tsW6lܒq$#uFBOMX'B%v[nf_f0HNpͽLm2&XvsɩCC(.v=#ZB8UZhY=NVY w(4-*G.E(*g~vɿ bSG2Ed%:]*-zJ[ems_hnsۨl\H]3 >$ܦBq SxmW3_*4Hu/>2[cOOlL9-46O>>`0H8jYa !S͜)e_WN>I sөnvKJzE*RpW3]s߻H|DQv),vf!vkɩZR,t7{O}IXGczݐ=HQLt 6~/`o)%B(Lj`';Lf ͊"@ 37v"gƎ7s2N8t&p,$jǪF*JKmZ}`VD'9w ^īPTNZxN2j2cV4/iϧ4ߕ%Bay iNʄ##Ώej3c83Nf 2B1)3G ݅w!QL8N7A4latKCnn-d2.8Ќ!c8[|AWܿ#{8v=q/O֣T{- >ɳ{Vg`%#@JI?E;*#Ps8ׯkR4]ԯd} S-4EQUqbYsj ةToOKbByV@$X HPOJ6r.P!Wo#di0/ۊ .8J0UyŲ &VU!w4IaAia6*ŋSSiԙD@URc It>˥h>ׯ aFO$IӸ+S9rcQN2'iD$L3YH3掵ĺOzpnV2 $IMirvs1pP3)F: Qs{wq-²M(:^d[ܹ2g}`B')u ) aC@Q!thƺxVmvU5rӄz޷Øongt4#/c;jQUIaNjq "UB)\Ķbu++PU |/3Dd+#?%xd֓رSٳ~">ghSk9{#W5>¡xkw,Gav9v+j<\zc7W1b)º-[Y w BYR۸r8ELNN1>ϙcYn9`3/1V.®Dph/{NuSj奔>{=G`h`[NeY9>Ʌw}C c/[Dľu9̚5ٶu $?yIw1yf T|WcR+XXYsvzZz훼t>LIYhAqN7v˴(@y{ F/*ƪ D4Lw^[ok aKkYQWbFg$RSZB^A!LedTORV4ɥ0E,)nsRRȚUXPOmYhI^uK-͜5[6QgϪ%1$ +--Ƥ@xbxR66vŘPXMXIxʖczdObsv[^ϊґ0x wRݾ" avS:6ݹB(QZĊX<4,]FjXln.&N2BDղ o*,ʧvq%^EزiVSXIqQ1^oWDӊ;LAy-+/aqce9[ o``F b4>)J6?JZ,*#Sģ u䕗-+[VNn$v'j(.*m%(,B\j0QSQ~Klc)9sQ)/+t)v>_v2<_HZͺ}Pf}H>/%uMG-WJ2)" 5hiXv)>ӌ៾{uEhtrrUYx'lsEevΫ? +ۣZ6anϫum>:`aO(JVI0{]Ju$EϞe;^z?Bd0]6(oεNz{-^ݒ5dO*crzQ9AeK]w$Dfִ3oqsמkHYRGә7뺖nd yȎk,7ׯM#]Srw6=Wv&ucih0W+aՒr,Bœ,?Gה׍Ohn\y9weEQfd / ]^+膵MhkZK>.FUf%t6Rec )untЅ_8K\,OTf!Ǵ/L7yG7fG(Dtw p]Yۮeq7KN y8m``Bf9ᩤrY&Rf;BG6h6k'5̹x||}uc{7_gZzR;[BkNㄹcPʋ/eʒB/e0uqo(7dvoRyX. 7 >ܖK4-j8GeVԕ`#N.}UN47KəQ> "r;5nҡQN|p#V񾧁700000!qQ~sg?KEe5 +P@*0HL*>ʱh9~Rk:,|N ȠXQݝI7m,00000000S\ǃOgӪNOҰ0CD!~}a) ?LDwG[)O/L '"yʻ)Z( n l;B@2fr"HW/ Fhj`$i "wPk~(:FRdQ?ljFxj`,뮬5$H@].X S1&$7BAUߟ0_DLo!n/T{\!nP=\ܨ1 VP={̤24 -[L~u}:B2̏u' Q.xq(R1,x EC_s3M+fրwd:6D\_z:̚zV!13! ?!^|o2@r/ǿvL" iKO$+h \>·~pI6tp} S 9uupqF#"S)Z<$)a# Y(S( hI"Q z ZA:<ġ.59yS!x@],2{!A:\sOJT,^Қ"9-Ut"BB7a‚N4$MfV]Z[hc?3]n 1馬"05&Xyl[[=Q9-{-XU@"vKK=4=0KЂ =~"j)_ 9YT,0;Q9?-%!3z Bar;hUDfdPU:H$J`6 (GxO!QnYMՋ400000x'nCٌ#?}g[OoģNO:>LVo}NcB|{XQM5w`C{OX:58|Nf\2sy#ۉ_wڜ@ā{1/}75b%1Ǝ3?; Y`arq/<=(ԉ}Օȩ6wo'qiڏa*Cc((:?wDEX(ra[c``8ݯ r5% 7b5-2# \/RZf7sh%.!l)s!7r]$ 6w`5-t{ogaв{g'GܷG9loDJb)*fb~қx7cOo%u|n{?xU @J\*KKpvd SWRb?˼hw66xUұ;{pw+*,\՞CuU+.)ZvToH( ^~w8oaE=K|fCf````s[I*Z'|bS>kJϚj|]{rv8| ;cRΞc8o((bSE\30L s{_:>i@ I7QxnjWI2=K%R3/e[ f-E|_~/|~~Em Ӊrcu9;,V-)$3}ʜ`c,x'Wg*@ɺ(zu)Ƴ"S]W)_UƌPJ3e\;qb``𛇢ne9XlܹCA" }lgV C}\}%z1U۶Qsgïqeo kf'A&.`QyRB1d%\NE} S ˉ(UQWDǑ=tLfZ),-'ePJר*P eM<.v;R|)شUKYFu++̬dĜ{TՄ4{=b3@bv O7q2ep9za;eymN~3ܬ7'2Le|3z+Tzw,atnS+PTAYI:n[_E=r]9zxw}=Ȓj,֯GZ[6sO*gdt棴(Svw3Q_)Z<8xbvx%in%eɊulLB=I8fᎢ\]x,٩[JK;(t2{lvTEA!afi)hsW/㫍D OAJL'bb$NJW)(-#eA:a)INa E>xD@#' ri:ΧI '# H(VeE,JFfRGGHY}XSFI+9-$gl2H<RVhV^T Œ-''BJW%k|FN13:<@_%O.¢Hd^EupaBw"=HVT=]Iu8?EY~r>Wj[46rIB7"Ĵ2W!Pvjv-LPc.јcxu&2{N<&Á)Z/7sk kwrR'1Amy!nK̒+xW '^™~`:$0ɓ On獟<AZ9xA&:x8g1bKrr?dTx?. k|~͗i>~|SD 7pyDY+#qk-} 3(aqu^e2&4M!2'39ͮW^Q գ;ٛ .K0_^ H`kfw&UiZ.]?|31E cCt1y7~O-@Evɹ8K* (qf[_ H'oCy <7#i]U; Id\UB/}Lq^>C W`*='iZ 4˶yYԈGH]$&Oqk-#\8uKZ~yۅmyua5MM$4I"g":w"u;-t'h(c̥^$Px%MyYXWzo{ ]%[s_8qݹB9/9N; hontk;eO>3QgG{.}rX TxҒP+-<'O*_E)k_{'H0ֲ#0r QZʸ,;h)+=|EJ z NqދŊE*DCqtutىOɼ|Cst)^['#o|g~?7״U-RR]K7?&cUmm #H(t Z;PpqP^Qtx ."lVc'xѫS<@&Ir2KC Hg,etby#:x|u;PT eK R$bʬI%NzCĦB H_ZHˑt?<">ƉgQ>Cְ݄y)*;sm."44]!4Ez KV|gTl.8$%&|P^lVWRp3ba3000pqԪ"k#l( toTU)F:{Xȧ||S~׸9w떗y"urUU>C=1?*uad']#tO^1x04 sl rxe+WR5!Ow ԥ!I'b D 2#gi4),fe;[BS*#Jb1G%Il<3d6" R0AFfLlUt7)Zks&})lcL L iKY'qz-n[M͔* 8UQlZd܂-?Nj!"%xqx7EEUM؜>VnU0a(1g.APq] 跫NN9',ElYvo{ܙfnivnr,+[ŜANUq@d,wګVx(=ַǾFMAnjW֐i:~]+DQbBR&*OUF y}LPb9 cIEsN'699T&<8U ~&/- 2ie뎕).oHZ9W?e8.Z4S>=H)B'eg@xA#1E_)lcI}_]lwBW*HN(&N79K'm~⼊%4 6\pn:paPPUI0F^Zϒ3m$4,w0 0_gmmI1_QuJ/ƻ!Mvt'<r tY ,CQtJ  iξ)pdPwE.f>\XՐ(lŸ:~7~8=Lש=:-Ăff"qaB}bM???}b.cUE^v?E\_A)kX}>~ԗ|YV Qti!  Db10 vCKWiIx+Ca6륞&Rgv}O:]K~-Evv<Ⱦɺˉs?]#'hfӚ*3c|VUKYQ7Ooajs 3X(B!f{+So?/&&$gC>8b" Pg:VCӬH pgQ6 >O$a۱Mㇿރ7&h랦fvV[!N>LՄLf쑨>q7i3M H=L L,SXT3>E|TJ#?'Tl2ɣ{x۷yw?d%q}(:{8!bbbjF<6K*ɱhafv֖g&Et'gζ2908)ddbQa4ܿy)d(M雌Xpf͙ƒ2FFl-(TO+}v yggRZUCIz*1qN%50;kC]q"2fB1TJJ=4 UfSFVqKK=vw?̆`]u|=q"KSH9RZUMeٱ! EU,-l|␊NtsLNZkp8.wR 2xi X;>Och٫yn\Ns#.'-ӉL'2p7S#%Tl߀өTfkeilU)[W2Di1N43+q&GfFbSOqw}1f-@Gs`rQZ7^bԬB : I̮4JF9ri WB,)T֭ {b:ȊB&^a5]W[Ztibojqu>RW~plǜ'Gs3a`` GP2)r,7`*rJ옭jZb]~+ yxa>U/"z;y=T<<\N\&(wG71)[=kɇi_Iyܹ|YOJtM#i@:! Nlho 5%)9lY:xx$JT3 n?Bbq8>Dܺra2+W/j`35OM"L=if-d9O>c````q0$Jg{/\ )((gˊ"RpG1͡#MlZAd(:+t !e`DbN?ɮM'mRPP@ecP} n=7#-- k7D$JF"Qtjbɡc'&ީ&cDEd2cF^)ˁ!E;~"SM˳H -@8Lm6>L&600000sCv ;[BrC(bdl60000H=QU˓N(RZ\G d H]CGauHVjtPofl8ЮQ6U$ƃԍ;sep5MO'J^s ג.j|[DUUQ'ܔfu_׹kUMŸS "b~g@Uot%UE!(k!jr5O&ʺalxI Ow1#d _H$!g@W~/T#tmNE WxhcB1:iRn܆n{8{'GA|^|Ή{2p^/}~ȩf``pM>biHL&ҬRcqt[:K*tHS ч) ]ªCn>ƻgxh}fXg"l|@#_ӔZ"`[6=õRu-4MM՘Ĺp$o?'sd_&@&xtS=W`V!2xoĽznMQ̗ɺ̸ف=>˿>/ **_~(}I٠KYŬȾm\,]A {想SԬ^MqAv-4Cp)_sWQUMMi&vU /,^SJIjJx[\\(h3'?FCX-9XGKVP!Qm[H]E5\VȠcZ}7D]ԭZIλg uPr!a6z_1{x㵽xjײހ>n'~Չ\6K{,b"ߘK5B$~^dS\)B [s~(C۽h+YS܅(/j&*d7V,IF[\.\.v5J iXn[bSTZFzf*5g̎:O+G7ʾHfGk-i'!izwBT]OTݻT2EdrawYciX*q^";mh(h!.%%EK)۶-]&ٳ{l&o:Q<7~pMdū߰\ͯ/sjqQR^'=ܚe^<ȪL^x6ob`m,I?VyB T n ^|= º+_Vˊ5x駨/ ALBY0g޼j^r6qqwn5۶m&m:z"kއЙә:Ƒ \_| 7B@p!"_;)pdQ^V5=r21`@(w2Qj&7O~|($ĞYʆrLf4>JLKA+_)@gf15ei SՐe^DR* .SIe4Ӈxd5jsSl‰^2x2sqZT@2pj7lY}0+誉vY9˕@i:(f+ I-K_ # 3d)~w(~U`3@Ƣ&;גP#="(lv! wnFEG(I ^]O#} XVVΞ>#M=) < 3:-qNV<6OaEZ|,CJė*(dAv"I!$X ӍY)x$L0E*&;&# n = 0>rmE $#Bab1!Q‘(qMbpXH) Ph\Gq,biRbwY@Ģ1UI, (R1C f/o2R&up`$j>׮上kU hRt`Qļ|B' KXXrhyC4PGHtyq|QQH݁դ$p(B<A>VU(ă x-S,IScݤ8 w 33zkd|#wbV-Oݕ[H: B Ǘڊ僗gU&+RbAq8Niy!s7ovP= *79K.\dg:q;("Isٓ|ZF SSPT1,= %&G*TM׉{8rn-fS8D췈h9׎'UQmM "z=;Wm;K6'NFYyUأzeYətz++)Qln2*_0Wbqg/t!c k¶ti&.E(a/:e?HV )!8E\͙BXl#8F/ǼLw֤͢bV%R%=t=CWXT' Ņ5afgѫͅX$(Bm2BՖ4!8 {_U7m.=OxTq{O$Ex#! OWaS""C:>N) DXgyv[ 6I:/3N0UX>s"2Pbsbqr:(z xw~-@9Q08͞n>Iw~+RgyMdLJ8&X-WBK ,\|uY~^;b=̩/ݍLbEAvk%8ML9|K灵Uz 1Ɔ&Z?/s̊pkNHh}sn`5r/3%UEm< r=URSQHaY Րzvtsj%ny#ȥ\c+gw=~f5}GUc%Txuܳ~r5S\t aIaY]J=3hcj\&Piz7N_@fldr1יYBMeYE-0U6Q31EC`X1T,6;=qGJTg>;AMq6%%LtR˩!+J ٴi-8SD<ȉMbYY&(*ʻJ&9Ǜ#RE^kSؿ'QJ*)*$6pCP݃픯YMӄfJp{_>Ė`rPX[K Nk/x )sP a&Źȥh'}}wǫTaد͗ ׹U*LP$Јu+(\l@1yeXD"xAfp8HFFJV 1/YNu[PdPRgyޓ<L&SLjV (*,,\IYP@"udy&k100#"ujV}zL1O5wRX}IP,Pr)px\bK%D!{,cqړ'HNFqRPXHQa!Ed 9DH̿^B8Mob&_`]9{fU:X^]D mn#ѽXj??Ͽ ǰvwmp!f #M0G_`-u8ScCL۝Nǝb{h ,O9WJ⚺D*V냒77RJ\8sS纘i ns URAQEMxC , E2}λO3y-yf ΗX]Gf'c$dzYCf$fwŹnN'Pȫ(#-cلalOjr1zd5xw/H<|;GnϿ 6uQEPQt:!iJ$AI/8o`M@cbl¼%]VV^x wqXe/9tC^h՘Y+nɤ /Ǎ۝F59 L *hq š@U!OF.)&ad\,&(͘QxGe"uYhoARvh C@Ƃ#&;?HOIaQ>f7ZG(){{ j15Wqmrc# ż^Hxp/?b%jwYZFх2oKwC400&ʀx?WT!<=ȘZKKIZ 6qPSQ>ujܗU HJ<|Javy$QI̠|- tK !Ld/h[SغFMAʢB[1rOlc,ǏchęWkhi8H@'6~EdVe8HX\BO]Te[o{5]ch8Ll}<Ż?^?NDx|_Xs'8؎/'!w$)54]7pXlNt=Ho0ӓxNOӾ,ᘎP 2OUB,蠇޷Hz +R./$yH;3ccnT`ɭr]O0fP(ܾ'8c= dߵgx=Brh9uy,BIGȘs=mBFcM!C!#2J_Nٸ~#]u~q:zLk!u=Y1B"S{N1wٶ6ǁb-~l͜?)>$c=o+MD4ȂLkqt]bM4?yu/m]o:͹1xž/>L[G'8=tM#AN6gμ?됨TH=/ttMK22ʩ^-O>{Ud9͋- Nr9DhL\Ò]4:Ox$غyw/NGhE\-eiqtMP(eモL%v !rX*iY9s\'#`*& '*!6`N\ѵNcPL}CLMO25=1D̴)ڜE~x':i:#(v2 03>„?uFRu#,NVnz_w?3cyB1$=9u]C؎΃>?T"5M{u$i:XBWRSX˦%}%344"Z泘'{?@2Aχj13Ҳ>%5 sd#8ju嘅|}iweضۂJpBL_?K]TAQ^f@a:N7p݃\*J N0t$'[`i_PPP@a~&x y=>ǩݳǛ )e`IO>C=KOkGᣜlgY!HQ7,=8Pdf$kϮv?rihF8{7;M䖖R̠88ԍpQf5YVzOp\ADvqVzFjRq(* qRwx2;!P=PyFζ^J 1 FZQ}X.oAwe`{8vtK7`Q%B.* 6xӽ7RIP#%k/MJd ӓP}Gn!(íx؋Xr&frd.Nrl#͝Tn}O?4%D;AؑOݒL3]k/#TTSҴw7tP[ULKهxl^A,dext/47Ύvg+_ށ3b-#9s7':GpVP]ZDiy9mSOpaK4J+J08v'1{^ZeݻvqGNa6c7ei~MR\Me-R}T0yÜm>ˑCٽg?ۆe䒓X";LjYՄّN4{@²jj. Ut giV+*))ȣgd#83aIeyyTV젣v|f6=3QS3nL4GIa&6v{voZ3t7CMdY%9i.38TXO~z, 3><Ŭ`/M'`jaƍTXn߇'3t,*-(!ڥ:ub߉Nt[˖RTRJ3ML$0K̜NyQ!.9ߣc2SPZA#N ֍t=O<,NW~v<̈́OGNz*|m=̘?ͤ16#3+,6 nRJqݗ{õ/5(CCCt:񏴱safKJ(낼gBb!?PT .r{ I&oF'ХdsvG4v' XV֋aX'cE @w8z,wO,Y<j&5= j#|(&.x$L юb;pح( 8)Pq>B8ӍnI.kS#:6O0a9p9l(h~fj`UtQb'D DP.|{-$25Fݘ랣2YQ^NJnX'{2;+pQLBHH ۅ))ߥ' XUA@#˄sÅx/bQMD'YxͰ(B`qsk1ɆĤGMY6Dhv@$jq@]8\n1D( B H* fÆU|(f76U7xfˁI~$Yb!GCAbf-b'ÅeGh!&'hh HXӱ]Ydqc&쬏H

    g}ŘGCY600iD+h"C\*c+d3Oq ~͝wӉun70,2.6]z+˕#̟ >-<5?.~ͱZ`7^|OD)bEh p 7BY: u[Owjۮ C$k}^\+Ww\~I%ѱ|e^Y^zO?GO>ŀ!,ʝnL\u¸?'-@Ӝ69x" ˂0;vk/F'k/ʯu\x7m_t?c100H wAHJz]!{yZ孮"{7Ԭowi{>&kO~78^<*sKGPZMUgk)lXJˌ5xmWߏEuwFǥ,l\T^W߾N__n9\ I_> $Æ۹a,(&7ݍb n$s305H$ʯW[J ㅁH%}#e"I=܉\׀!p$%`Xk&YܐF<'gI; P$!H|`) 7?@W*$r &>F蒁|[ ʍt;nd:R7zC(,,z#UUQU5y6G d &BQ7x^1ܹa9%!yXIN]R35CxcI7A񣴏t$ǂgA9xOwi^%;S kRGӴg\nGZf5wRcvC'2{DӴ=;k-```pCGʁ!UQ@Jt] +Db2X t>?8m|PPTH;XpigaU|(@^r*R[2Ee:FGAU@Ffz m)A/rb @Zj(&+Bdxo}c|$q`||8B$m~zp,{[j2 ޘ,|V,+W;C7uD.ƾLB\|B(v351D6=/,ӆh6''Skm%F~? +W"ysMGLc۪"R[8QNٙQδz:_bE;oӕ?޾xǷ@Ow"8IZOvQ_󕼌go,VS€E|/siԭ^N;U'+~#E|qCͩ"Z$@\c5};z3*W,ZYBysﴢZM v jd?Wf:ALטjx6} gXz} oVnߌ{)o)T> A$o _LߡW7_'ӣ3vz;ݬڣ[οf,O!bŚe9FFf|b DoMׯRb)E6Ч76kta{yo ^}4RS̱xyigKb76ǰ'|t (s1s o E'"H^ʈ˃ZE]u5_b_V 4|*\V\ڼWs(+#O 344JT5 ffCrf7#L ;UŨ)N"(QfPϻh'.A.eۅ 6;wdz3l(#k+jQTҪב {ٲOp{EA} [1[ȿ{;6ϷIϴ9G4_ªEJ#+c]0G^9VӲUI]):Ԃ}×pU=u1_G^+:LMkXZÁ(uRd&t^MJ_"!oBwMXz`#fh)ÙX- y]%e ť.U.IϹJb=ĥ'wOZ1*~w/Y+^MXrcv>(51BGixd\~|D &E\DZy[D^_.3"E#qek^wn}>DqH7 0T֦%'8A3ȰL'HՕJqF:t0((WL33+;%[9z_NJ ^;I,-떁#{vrxSO><'3=Nsmnr+rV*3 =RJ=%H)J:_$M Y).A8).OgP7.V7ˮ+RSrOMLDJ붐6#[si& IL *0IGejO j~Uy)Dg8w-l Ym;++ <Ł7^ɿ04> + ]F,0۱*MU%^H V潿1F{:Pu!uaub 1baH[L'H6 NR3&0%%o.o}q̅0%RSVX_ 3ޞ8{"1/ Jbft'W&&D2 0eyTh=ױ,LrF 7odIxA#PDq+yvêbAJ., I -qN763ua=(@A1M8>?8rYz3R2>Ņ'ˆ-wQ@e o/6QlC\蜠lf\ !ZгjDi:ʴ{ 55p nZzưfQt5neWx`-[%KM !"&*c]M1bLґ͚s Nql S⚎#d9-D}#9dwᎍx}v]OqouVzuR=D,g} .qo/w1'?]KF# Gq]xhojǔW#&glma8h~=lY?@dے}Lظe9?'/c2"2N]|Lin <6N;.y0elX]L-eܵ JB!8dj%鬼9y~M(kJ-c{X-$;s ׬eֵ8xb l\S7lH>JX=4.459BQnzy~4L^TN2K?v@1cl};zcU!:a֖CEƻFQ8˯~ֳ֕mS3c'PJjI5)&{av,c}'98ūs@Յ.Tǃ#F'tOglQ96V-c!bV6r 70mY}?2RGtHFt]hrQ!4'ȴ޺ւDX7+2_6 4fŪl&3˖QfۃVVIIVyfn'R;&NFJsfV_,ۼ2|K], v3?Ax-O K/BJ=QD$*^fK^׹̧?ol[ RƑH-yՄb5R' &(\zf8rR&?LʣΌuک=kኆL9D"d#!B%MWa18f{y7A<9FmXnNeI#2P7(ut I)!5&30ǟ0EJP)bυKQTbJTd7M78yV<{Iu)9+3iqBB6\Zl gyx])iЃ<\UMmBy;yoO#}LyrxW_MQvƶmk9~ۧW'[Kp;U&Aqz<T%ԝWE]y:zX~#Ne*'~HG84IV#U[AؗPdP 4{obԱz+㥷ayS[YC~^*l>B]Gx,-P[ 1=0E2r\w .5>aM/_Wxm,Kex`Uk6-$ILB6n9;|5Ǐd:*Xibo:2rXA:~saV\eR&'|+b"袠KL„g>Ϛ>} Ϣi`d GXÊپrIE jha3{*T7hh ?& SJqb {EbzJ%3Ś,CmBck~U=[Y7j @jhʒM,kv6 @$t5c,C:i|+,{$!>;M$I(pFEcuxšGIvw60 !|3tY}?>NUm~?:E!<)4+:RP|9?A E1ae" 059E0Xp#6߻҂R>$)Ţ,AdCAQ n4C=t yqsW΅smu?Hz2/HMCgֱ(YW,aܑH!uL<3yy_qwaMny9=SLB^GĴ3PĤPUFǣnq9/O>IdQP@E RbЙi:W/.09UI& %RXGAL4T{z=BtW^fsMkaiDX\9䮯w@ K c,s]9x@8ݏeJmz\YtKX'K*l-of$0;IW jjU/FC0Ph?#^rײ\ r(*fU2>؍?ɶe8~bӓS14-_Xeh"H.DM1q;(P dd2a6t6;@=ճdT- ʼnD4=)3D"-iIz,.j3~$  4 Mי{]SZ!wj;IDچ*וRɤK'Hed[h?w٘>[GUL&. ˁIx{t Қ22ܙj'gH.{pC18Cqn S=MQ+p >`>k)*b\8LK ;T 2ن:h9e[갚S}{";yX"C CILSG"]ݪ &ϵKB o=B~*T`IA1=µf9([VfghAwK_t "?428ў67Xg>%I#:pxRVV9Nu\]GABש>ЈZXCmY*{qn|a՛7R|"\j2Q''gtgN3Kc͊%Lr{9Gfr* (,LcdiYEQe{pYRI^ ~jͫOSi>le6Zk "լXR5>}{9ZZ ,&8{Ay/87v<~cgxB:hn<λ{.QUKyH=H>^v@UKɰBك{,jF+6ޣxQb[3I%xL~NsTV-(|ct{G6K2Xv9`MME#tsQM71<9eTea$'| /őR255VſۿZsL{g+.ވ`ph4v;amyRfj N1PYҌE:'4 |_LaE5鉌2HWD =B,EahxWzYYiA^xKӊ 09#z3g_eU-lK\Dvjr*H~(dU6N`rAF{ f`QD%ol]ho܋4;)$' U=꣭ 3KGlԜJ rqhFgts޶z'xrKYVY]kȋ+<fewD`v`s'U+DC=!rkZx)`qZ~͙GJq4ҫq-o!5B̎bUXmM\:8t r=H4b% 8# exp)?,X& rpZ\AdL[ xCVR]$O7H@)(.!?Í@" =}ÄU'9ƹzq %e9h3:FܙMuES=] dWQUto()y,.-ocd&BVqey̶kBf%Q$${ I&J,\jUjU{fho`<EP4;ݽP^MЙoQ\VA~+~4GEGMQ^&%Eg4';l;C]dgAp֖Nf4ŠsL vr{Ŗ*\&ýbJɡ#浿-O` vChlV!ѠRQ&`rpP#]bI-o^Ec3LMfg2h=Ȍ$\ eوbSXDۆ5&i!rJr3HCt L2(u3>H%'+0`|v;ʇ _4N/7` KػJ.="9gɅ]٪y,Hw3'WIVÒTUM_KTROTR.iH[(ɪhs$A&5seBPs:2Jr\MT%q}No j(j", 9_KMci>NϤu 0 Z3; v5RLHLmKm aѵ]'̷q ͍g_V,R$+dO:]LP]݉J:$K<_|FhH}5s!Iyq9Q.j}'d"KC/:1@/|w000ipfZBAy $b4&qd06];iz}c/b KI-sG_})u^%~6R׸Ht-~~?+ k ,UO}ɔrB`r͝hH^*%r쪳ԑ7p_K>_J*K<4}3>-zմshed4 :; LKI~>n'n^1zE۸p{v]rwgFcEڵh,|FR.Gy޽'xfJ+`:WN,]:4͐b~Tr`{.YQS33IJaYv2|! n+ #o;ҜTMJek)7DbcՃ*ls}Rj3٩30000000DԟgFh6R߽ dX/ 8nȀq(g$,nMڹIyXd?\$`O+dӎb6'H]&Q r;2`&f37{ &P`````a%T?*5`j`Y o?ddN$kJiT 100 %60و"7w ~6WۓC4J"}l=⧿1obSTH)8? *gl``p t'NZ6K̗6M)t߼ fHaQ00000 sokBkQ|^/qK*.N ztX\b6a.Hgses6E=''nEEd2ycoo SLaOSf2E!}jVc2)ɹE ʗtLdIH7aQT3\֬_GrSas5|nr,6⫏=E!fQ.0^!ęjh#Ch]pm#%d} Š#; rNs]#Q9H˰C3}=pl V4_}~rsʚ@(gơ.6Ͻ%U,!4:?~5cՒ8nZ&B`껟=@Q0'vE|ŷ!5զ#%H-DwI}k' {j1 ?bB BnG+}!i2ogy:-1w7^y}R>)ca.j P-T ŕd-G˭k!4v%%XOkIEh} "T% Y1l`ӿ(uY.zWAl_Eʽf~ uNq_ zǾ#fg54kw>kVW7`_ ?$kUo*I=n#BtI~7tVr^VB<Hz$G|!2jW&eFx;7βmm9nǯ@3Qs6d-}yex1$B߯eKFtML滰 M'\+\ չ5̶ez&&b&՛.*/FtL&6b¶B7 W`c{ CPu5m۩>Ry)YFtqg>@99HDqĝٝgNɶqeIVb9#3  AZ%[sx@8L*S, pbqرV|7f{Nkq.PL3DٹB )~ߋ')qu4d5At|\/I= 5 ؆] "HP75]󙸚(؜m[` A"+ 2揃{ӂQURepd8}cXqQ-,t0gl*b18{3umFky AKK_Ú9|ܹ%a۰X-(Bn^?=zLjB,F?d|LBxgJ^1Ko_xՇIia6?Bs]!'kV mEQݽC} *f4/YJv%61JpbU*VER͉Ç@0~ܙAHR(_glt'eV"8ګ+:&OwjBEdXy 73Ny `ת9ƋR$.g]6:]t L% JrpZ.N4rzڎA ^1YD'# aI΢0)v^G& T\ya6< >"3O~ ņ3)fO\|+[1M1T;yTܵyS@ nٍ)QTFb-F.1ma30)Jij'-- x0W 0#7F& T\bF'8͂dKrUe(Q:z!Ey)D&kd$ۖ0kF{D*0q}.0U N*g'RBA#0MDE:BFh8*エ t\oqQXHo'ۼW=b6żhܶk-W6!#:A?&o*ֲy`Ҽ.G뇐2ȥ}/{ J:u_4{/b"mo}GjGQ~o=}ΞnμOTE@`rQ"ZH$ˉc````k.*RD-l_oo[~/gg$z;. -A'ҫcw:rwqOER{b*NOH6WeSE-'yL/|Y"ю4Oђ*,7t2JoK#d'V䣠>OYU72:ŅSH\dG^D Lh:?FP ^ϾC/X;}y^Jw_I^~6l0 ȉV:N\sO=%4ʫ?~K,/b*v e[oҟ*5T5\IN"^Q2?pJĒuϰ4-tPP|u)R`ua5^†ŭFJ9[ )P,v "0R[d7z!bfbR)"!ܔ#>ttuNз ²4قcڍ"UZvw}q9E8D?/?w?aՇyQ+F8GYu?fjP;ǃDQwd\y ][rY+fE0NwǴŶSlZ"WbmHg2s2Ǫ?͆8Ma-NM"`šYΖ;0m$C x Olcy֯Uѭ.Fϟ/ܶ@7H xuEqy gCEsv9[Yz3U)6n_Οr%)( 75wS병f10005ვQU=8ӡs};v* tz$O׿|/Eirlz'ٻh%Գ'9ueq9'jx_3 "YEE1Yvn[iD;~Bw 3CT&ŋ:Vl 5ΟKsQ~ I.%;\t j$Y~cCi tyVgT3u2zxrk?%\:CXrL0ͼ2V5~%M'"| _,ϰ͗ٿ%RANrGG/;VV n9lDm!,KB0.[||,]C4u]7m8Md%ɕ2q%8x<$ح99Y$i=0X1T^J=!jT,):ڃ4ˊ8}8L8s kqLh9M0|sc89>Lv0 tm1BH ݖ \g]a`p M(ʮ azegFGxM(fw<Ɗ662ΆzL7o(Ř/%%l3~!b$N%gzl] -G j0=N-,7g'2 ~P;Q\5"bSDGD?WݧR$)VmsYC(H!$5N,5cy}O205Єw6r{n@q$d8xm*7'˼ɹY$H;`Ǚ5t41\Z |D@ħ?'zg_nR";ۉ&z$Ąoq3n+R"~mCLIw:VE#!T9;P$zk蜼3J-fhٶD#$gN28U#45BARW%Y DJ0't&L-9Qۅ˽a_`U$D#a"s j$JrZ l Sq:M ?QgN\–eXI$glbOJ&hi&$ЃSh-ɦnj2HSAIy[{*,&RbIfb{=&mcYj o x)i."PoEEi9nYh[b!Bt5ǚ^DS㞸!|oFl``Q N"xN ΢Smj['2G 1.]b|4Uژ ui[Kq&咽!V!N*HKA\)[3JP50tRStvz)=g98cD>%O@ :EL|4(H$BTιMX֠'͛og fۈyvw-8@H3* 24Gi " ?t'DKh9#!{;Dl=$™O|JH% <\D S L;y 箥 W!lv1,HCt4L n3i9'[GbGLMaN$+cw>Ld$? K(7?79uUXdV Gbj$Lh޻&i?U)Q4b```׿bʟ#)ɅjEqgG\!yN:λ{4ƻ' P GwXW2o">.{Un_23rtrE%.6G؈NQs,^<×_vwR*#eF'8֏kg}_:ϩ'8p8ጥ,-&ArR7ȑzԇv.J=6$5`Bguy66 BMyw8M\亠jqܱs{yxb-t]8‘ald+S9xS/,C?Α,vLxkN`˶ux1(j- WAdEQjIDc yt 䑗jacdhw %ZwMx5QS cdg9{0Iky m&T\`J5i̙~˖$r.Xyho}Hz(Ħp4-SN2![q' c/)%\koܒczSg[DB0P%M떒䢨r1bF:U`˲|q!D,64J!7+3 --L'AAڒ)˥ [Q? E,[\B^Ziq5jWp!}m^{mS e$cF (G;8}9!  G$a2mdURiw`U'y)t&:k 崑rjj:̥PW1 3"֬[C~^ Xv+Rma"B{p'eiN"Ak{PnT igoe1LI%=52V-* +W`ee.6,-$$(-_| y}M $D79EydB`dEQa>nW= ~ ٣&&W A?y9$$$b/.0+#$q=\0szW?RJ t5Ho)yru6'Ror^ ~zn3eQsm]9gq/B%˚y6:KH100-$?]%$RE`cZPDse\9z|y|>/}͜r<ܜ'ݳ"n0g+EAHl"54KW!Ba&dߙʼ9?{,3!+ 3Y'Es)tמty98L snU/S6V_BAQ47N7;f8u珵Pxxy9c{!rf#k ~%hFKk9990^$έU!fa[&RGjRӘ?۲n֭dEY ]/Iass?H1q|LD1I]wͮƃHMQ,W`w$sL]wɰ[qR7?B\ha9vd fYhScyP2w x3/K=GeqFZ5[pHyMy`_;ލqn```ɭW!8"@jjOTC/ aj(ްuI`0^6#,v,,EA !s'Ht%; 꾃}\H˦el/!l60000000)_ {\vOQa1$  @BBf|ݪ@QLM&u[/ބj  I2`RD^|&l\>.|$`2_*4C20000W6\vW700000000000000XÎ|)6whwױwQǽ-H˅cے{wƍ5!>ZD"Qe*fn9GmۧېӬ09X ڹG:p7F]ʆ$9혅Xw=.|K3~AA*Pb``"ԕtԍ.&{ʓ :q>?I+Rqmܖ<#$EwM/RXKC-DileBr^\"mC${%Nx;YvZfu]:OPXZIIN# HlIY,[Z\pLH)I)YϓOTRjhR(D'xƑE GyF rol*Y^'.'?KYQ9e%bʺI鲥n yH,,[w JN!NN%iau#Ņ9&Y: 4:.y*ٸIyE),]\JLluCg60x !@ Nt k9M~svWƽ(=O@-tӠ$=QrtV0_X2_bkk\, MP_Wp _Ŀޕh;O-m,شi;h>ϿˊYFdvZbQ{fb6cn"txԝ m3%RhҢsC̋[ZHhφ\h_$ l``#24AsPOJ/ RSE͠Gv3 yZS4?="O܆E"LOplv=8BۋM^K\Oy?⭥(sL-*`eN6Sp~zWcL=J뻇(}N{(B^|<}1 W<*/I5EW#C̖!~{=o\ <΁f>gcq*3$^n"5)b &VJY3`"->L-`u" -oz/nx\ E茍@t gF)ZB.7 =,?͵EBm,ۘfߐ! :ɑ, #H (BY` c}OH>tg.9$3cN_ ._ }]{\z7+s/(PM'sy4KKɴdf*v1zhQ/"1sRDqv@0$f$= > n-d#z`Q$˲ٹ$ .AdO#-%+J9xB2 T"{Q3j `t: "$-$-qb&{NNiQ N5,INf,u?~v]MtX^fsyRh"!9ʪEd%[ݯ3]|Wrt;Hu% |h:=~Fk pj6)N&n[ !P|A4 [I)?BhUXq'* ZCR'F+$,Fr"_iDLvuhqJݓMԣK).tc֔sn#9|c8 %M#uIuÔe N `9Yy/vkp;g9>UHڈmBj\-x.2 ]pf uY%uj`b`rh3 Bhw^}ܝ͋I0YRrQ<1o!U>QIt%a7 Vz9wȆB4R3_c>TŊ۝4 Q 5!MfuII83K97s?l$'˿EW}5?g}I煊ZܹlܐbVs<4GSl$]XLb3-j:{"K $%&`2"MOTrN 1X N5DZ$'%Ά|̽h$BT-]MDR܉,U/!F ~.r׊]}^!4ŊayJ-ٖĢļV#A?@͙akQ& (zw($IZ] J,A#&a3[K?yؾ8$O nW=n2a/BCƦtL`Nd݆ rS 1Flur91 ZTl{I$ō EHIfGnsa"(.pb}D Ma"1M4Slv쐚J(b}":$ " 7TE5i:#,  9%yD Mrnϋpσwv'IHp(>0nӣt33Fow6)i&03׋+`#9- Q100-U!1YxRH Nw W"ɉd"r9Kt)onqRIJ?l؊#.8㝼/gg ߹Gl/uF\>~I+Yi6ݖBmm[Pj+Nk$(vx{RUc3d 5 aM™͔y&iac,+$bבA¡†#Fmt92L;yQfE"uPi$*!B^1dE*-i'O_ͅ!xO#j(l)3bvhIt߅ҩGIr9O5e)N1Ss=.I"=*<}+lt;t:HG] խcTnyg_MP=ɞC^}C֊4:\׉>r]Vh;E>[̎m)Q_;|-;* _sÉD whnc;;0AhjvQalbꛙw4ʦfsIRN7~̰w`uc{90ͮ}%Y{Zu4Yi߲I3Ij^?p ܾy 6,!rmFA$0R}< [؅YTkA:kiObm>MfvWc:g1"f{ӣ8qiYgrl k ܴDur|;39laJ-@o[\ӛO?˲13FS(h~de15MNv.@7$nںit!v<9vA qz4Yu 3*O=D#ApIYDvJW/}? =̮MHMlaC\NRTo;?\C+>NwȮ?CRw1OڊIJ:yE %$E"OIF;1UqY.Rr=%T&|gEliAhS N8f7KJs|l<+m0pry%fUE'v~_y}05}}ܳ [4;vn4~hLvreBg7:x[؝.Q|JlLްbg TQpuRȐG$ vMGIh>^ \]n6+sfrjQ:tzAV%8"U̒bR7~}vRE"MNv<ΒVmߡb3ClnzL'{z7Txi|-hqg{[N)8=0H{;)0!qU  Uر&iDC^i"@fstۀBJVvMZܨFxn_ y]ܽc+o1Rh $ǽ+]G KRqOqWS{ߠmByƩf,QlR(xq߱op}?|$TN5;FI7x"b%"8.@>H2VOrG#/-ȥƦ*CmF0h ryɧx`Z2\9$z1_x͋Z-TbB&LWRd=$3#y0AE4|WxV|VgxHJ[=[/`L4MN \@ gqOr?+oGaYQfiJdy'xpzrL6_fU{{wRjoK=SXS#XXj9I& $^sr[w?'[CŃG&Rx)E.x|+3>ƋX{h)BŒfr!/_!~GQλ}n6/IKdrRxS_>˲19ab6~Q "9|)ՌW_TCS!T5H˅S4Ww bne Cx8 %j8Z4Ť0ȕ6tG6O>PI^?ӎ.V^c?%ܵkŚCbK/~"OO7b:Ŭ,uSt_?l%ӓ5:N Xj9RC[D;>OQFN~%O=DK1S(Sݜ<̖]L!eƙ{8gzqi'#g|]{/g_n,BhSۈ B1c*WcЈFf Bd*rBjjbb_Xi̝6=̹KTsKrH]b9tIDUi! } kY[M|#s0۝dL F[Ns}ʕ+X@Woa.0ul6XQ;)p. YA1X,X̦To9RbPx":jMkl[č=\y#0n?8HO_alkY{_}'8Rp&a`}:V' VJ 8Ǩ@}wr>,F N9) ʼnCJAkpJ'%$@*Nʗ*/+8<Ȫ84Xah-oG&1?x*9Iɦ4ʗdj‡&&E˜|&C$`2ۑ>K seK2 yְ8޽gJ,f3BlFV"VV a"WBk׭e·ӿpϾFøYJź;XKRrY6d(5!,<锔J%TfBG$ՓVbA\\7k%[w/BHdlV0X&PجMA1;ĜT{d+)+[!f`0`%ܱ  29hSimII:;h[2Iݟ_,_g?}4sY|ڜ>iNJ؂h +wnU] zܽX"ARrtw$'8p'!P)Ο!aRJ<_g 1ʼn55%uo|UWItHJ9tadԹjz'4Cq a,[/d}Da[cx4һ6^3Ie/'I 636/Y2Ly!8-'`Mđ(PZ\Ԁk; )@7.cߑ0ƞ䜟,R*st\B{B>a̎fKHI)$L/4e dMs'2]PPLW=TVIWs'Iɮ"G\◎DZXTYD棾pe)I)mKEbKc2HDJjJ ).~z|L V]ga/ qJSYuHKz/cߋ}KbRb"A**l'+:Ak!u6-Ƶ@ (p/|/~|K_+܃s,Fb޵A?}CLDyjLO0#_󌺎wb͎b$.#h3%5LSLD ˵4LC)(&Inw1(~7HԂaiRXl=q|~76LJ1㭫rBjJ ))3YUɧw:_@ H-T8sA_8v=1oD,B` {&FJ+0׹F-)gBrv9#lhF:Q7yCA60(EFHwezB޾݌Um|W[-GciwXFinc۱$&e\J02nB'Ē )1a6ɀĜkp5qE-|I-첥tSyFҝ@DI.X ;L44mdhJr<<Wa 6.+"~9KJ{ 끻+{UJ"B`HJì ǑJlB,dgbSxGb_ee$ƑI|'28`h\Vp-!$Ղe1A(;vBQ@)U$ ] Sd}'P*Q&?dY 'VLښlS&UP7F@"RC.A-WFUꐘU=nsW5Y01d G)żxJFD͊tBZr.Φ4'X3bQپԢ*j4Iޗ%}.n$ZޔPÜ#J/+usJkKtV\3oۈ POÕЈH++s}\ih3\#wVvD9~<#hB$i5-$)u7sr===T׵09"&逎(3vKiDT -IZ-:] 129(sRWB~̞sLړ=zbA*aU%Ut+swWF4Rc1^OՄՙ~ 0GTE1*jTQUɼyyi[8c4^'HNr6.(Ӎy_N_XP'bg7DF5T56Iӈ*jTEDO捗ަkɉQ{B櫥&'量׋.%ZhARͺRg>z'*xR3sjj NOQ%RWU԰_Qh4H4qX&t/p8X,L܏^{ζ&TP} 5CfZms\$ޡN:|n[}r9BTO5/-}^be&2;S zzm:al㖝4qՙ`J=uWųD&;4*̄wHMJÝac^';ei2dOҭp-aQp56AGr6.I.8?b2 tMGguܻ}iv|:i9tiidǎQɣ<''8WGؖNeI>zĸDAi)Yɂs'9[GОFeYp?{39u8+L"/;`q$gdR2Qۚ4bqSLHM$1#'ǞQ@iAťd4ɤ$KKH^B뀗Č|*Q]=v)X"ʩG Rԟ:OWV1ř _:ι^4* pD8q#r(Mg,9ƹ8~(|c/,S\WE8{=^KTqQ\VfFwK=<ɸ?Bfa9e%0RNB$J++HT+WhǙV@eY!iiVAG[;c\7B+%u+mLRS]!AFF9)D[8v"(=ñ-""2RPB~ ҳsII=ImI,^DVjkjhj(E+YVP9'RXVBfj2yd(>[lk8H]l[QU#mڦ";-NqKR:e#;zBz~19baJJN1G9{]DJٹe5) Z60u( řYHyG>>;L7#-8|BAY y91@ucl8]MF6+Ajh즻Hbwn(Bknw ;4RS=(c\mçYIIKB $dbͱh En~& ]!bܲG \.׵m^ۿ5Ixp8hj`0<NW.7j..e|ul|_?䡥i.*!++3q˳FY4B#c7NH ,o¿}={^Ԍ7ͫϽI'{efS=u6H/㨩*IB]`@Rb)&&&m5!ѱz8&'&uilZ¢4 Q?!CB")=0 VBmrj MUى3)caԍѕBQHv1~6 nc}5@ ~Z _Wĭ$3Àa```````a"`20LaUBǢ̼ (RB1a6ocR>~Et-J$ ok'Pnzoc-RG/^}ޤQ8m猍fG&ƄKلr )cLXݖ@Т*2XHO r (ʓ2?!z$ ctIT2q;,E*-^?ުc-U?#B(( wsAbdrCVrP$M[J= IETa5oK.QtfrJ^R(N%59{tW_.(FcH1ȔH]^5*̴H$%n^G#d`g~=:M߀t,{VΝkTqRB'5G E{Nn/BBjFrL )ؙwDtu3AX--''\) PjkpM1MIa֏ʸ#?Ku>Y_IQTѬ;"eq 0gΑPQKfYяsW-./"+ D bh܇ɞDVVkd1kx?rB(\7yF]y0`|!N ?j|";vflB _Bl.x/-MͤOsB|=BO%'hf͔g⊳FOiεLa0ZZs9[X Jeل9z,2 zFs}~֛Hdϕcӣm,*D|R>͹V&u/dIdvW(_O /e 23,S, 8å˵cZ QxO~ DMl]]Z޶zWj:ʳ7y!C\6ݔِR O[/.'7qO Z$D=|x#Vv~班2{ ?Hr>/Q\a7m$2=goS kJWo<͏݇ >+ߏlĹOxxc;Kwngya22-Ty'E2xp?ZFE@3k##3SuͱBg5Dk)JB N`rn?%qY޴ '9Ї3own^MF|~͗y.3Gc=??ұ&¿l]!Ђ4%1a;+ ݽ b #=LoW.>5L}4.:^9h!Ot+ٲy q潟qe򖮯Ql? yI:Úw>9~+auiRoz.Po+qgZVVޏ[0kwH..gђ%ܶuKQTuޝhaN˅tS }g{`߁ôL zhFvpcitc[?\ pm!vTO8Yr!9b?Ǐ0%龼~0*6ok :kuh8{7ɗ#5N >ktz|?z*'Uk ZIMrz˜niV4<0 ~@Co'*H)-dUnG/OTwg-N ! Y1o/w@?2ea(LΠ29}[r~x?dsRq)1ΔYEYlkC:¡0p)$j% gNղr+֢X(Y{'\bltN83x0YfS P"ccDA ]%WAz`z?ýe(RGZ=XF Чi#ZL ڴ)O0IKPLfttK+7,1@Ζ<Hsr=Dk˯.V<EӯVdW =|d:躎[X~ct1) E}r2,B~z 8ڍ8wMgOq %% _P@3}>]=̄T\cwQ&[D8<,Z :=dT!n!8f*)#nݿ8ˎKɌZ) 7z_/'ζs)vbcêLiF77zWvq=HIA:ĥck.Q;I4O3)uPl$;Spșa7^-LKJE1W=bN}g¡^&38?Z|q*f$B\c(Oy}1yc) ꥽yK)._kRa}((~sF&iƚSFrl\ \6\,R'x%/se/c֙Gm+8yf.,Il$8#|&B!t5;80GWkD(Q]` a00000000 \Tu+jb* - 9Kֳ2muWL +R ir6\wp|ijn[e݃X `M \gc0=䥫VBZ'8w2}vVm;W'8ڏGN_x=˘嵐l]_@Ϲ=wz܂?Ϧ8M u c2~_97i1O=} GXwH$>Ŗ kIw2B[)ӄ:–FQNs_ ;HpBX,̉- E"ANb֯ZB`qp+LߩNgӽO=9V.4݋^ޏ'[zu[JÝ!^ɫ~̒L 3IaU7q@`3{358-WM1q&XPK-.IAHᦨ_)Wx ` u%$#t3JϬK~HD~z,n)x׊L&Z.s u}Tl)8~wNf*7;W-^=@抻y桵DzP%u[ngIA A:Zh' iy9t6sz=w"٪Gt_V&&'#XHNbOPgk#brVf0s_=(wm}%%8qk<ܛl}U?bS XI,19cOp>,dWᲙf⤤j W"=4zTf)8C:v\q8}9w\_!Qw;7M'6ěH'01C-;_GbMYŴuC54%x;g^^F78*>$XI77=EŒ@ҕDZT-!putp;H)1\ԴFJDE;3 XX8% )t:&`v)( 89ɋش IGނx0BH >00= qHq' hw)*J@F\na @A~שłINqxͳ s]WV$?[?;WDƻx㟾^s Cԟzo};m(eD72Zj2*y]$8^9|hlA)6j{T\ۦ.po螮;g4;6~^9PGM$c#lV.|A(P+\hz'9x0zjv1^DۤUPneu2 ZHB^>Xd]d,XXfN_aڞBJbk*7߾"U<|.9t_9?ӿg_ͽo>y)i.NK&Z>r'b6Vi<7}w{O[}7}9FTx^"K*yݸ}0PE]rc:r^:GC$(ˌW(h ЃT{wߥEއ5ɳ7 xo%9x28©=?} Nr-殭qg}:Cz9ٷCDZwg.3m" WZP7^z7y-#׼$6=R~^~MS̕63`?-0@`rXXcCM {wDW cӑLD{O~dFFC7_՗"ũ7NL| /DU5t],)AQ,$$y@JPݚLN 1wgRfdbhM;uVvBT(~]]UȨ$|-<$gse6~_c(i859 JȩXڲ\LfIt0/)|ܳd; - D\˹c] |^WyUW ,ZMHtE>*=Ja: D'dݶloMENxCpdD)*cQE)i >N}VڹbT( s {>c<yHTn~?ORo|A>=у:3PG#Fe|*t]H)IȨ'|BN^?DDԅO 381TypU: mTmuCѮSOC#?NYV=8ӝ^I]|Б=aq(,i>wI0[̝דյtFXYprϫ>^x0:z Sj=Y ;_߾0 *xٹk';E>'(zjWɲd4 ;{Oü>z$/+vO򩇶]HΒm_$%~k|cͯ )/'*)BP`5]']- -Xu4AN&ܒ׾" + ֝M,½n#+)4MG" o3lpMf,K7qꭷ9^;Lv*VfO=͗> 0<lM #3YteQ9a vlǟw>(Un#LL*&dVr=Hu46G.E$p'̤wj'_\zG~JMKr :TpgN?2IX 36[}?TMsnu&E3)4xo#r!$JJf2I0 2 !h$4)X3H4BKP{,Tn܉:j/tl<~eP 6L蘬\$w/fbfsl10{Iy<dWgۺ=%]@j Ɍ$eVlZ0C1'Pt-+ױ2pfgWN3$`tI$!i3#0B?K0ʒz^k/gZ+j9"ctNM0븭UMkBz1} wN垍%*($e)V¿8ȝWRQi8OW\+a㡨b)k=ܾfs,[WJ :x$mN[CV{ޠrr|+b59Yn#4dl^q/vz0A xQ ݆˕HrF2.]*>P7T,ddn(a5/## 7?B] Kw>b2tqٳysKA1YPdTٻ9^;)RT/d[N;qM86fwd7qK۱U,ɖU(Q{H9q/@E(ʄۼeΜ<eM<%V_ro+!%3#!69kJ\\$I dOJ"1tN; p x xC$鳼c"m gf;wՆ9ÎuIDAT0UZ*d5_IJml,&{S$wc6z0PT/]$Vkp9 {KK t^ҝzG #M$dKv=mxXA2 \v|7f *R?}[XπNε_"TwO%1ylٶ/=TI w=VsfpI K 2[h R^M?AuPXQNxQgz06]XMF>^uop'K:`c%mI- gh>:IͬLDn@y󇙛 &83sѥ#϶{h<$6?^ZfVӘ<7Ij0mƑNeCȥmaz^ u#?,-uiV!.(CgۃOLpyH=B.3vzYv?ol+^a#o??=ho5uٶ/ʳ?'t=- @؉۫d+)6JFJIl~ ܹMFSVX~ofȈ~>U1N>FN6]ڦ-Stu"2 (@}bb|_n.%qرGg:~iyXq:Dҵf b{ 7vV%A2aN?$^;V6ooҐLư6Njngu^5a=fBӲ-p<8]x2F4a"D*׊iH݅A_BK%WyR 7;xs*~F>^y9Jy2 2h_C1eexXLNL>~rv2'4$I&15DI 1 lҪ$3J˅˰50Xj9U.5q80 St28'2ʥ(!t?~//ybOeQ#aT].G $4:lܴvcHBld$ZvYkg.2eB| cײyE NNFf`d.^y9^<ց/ $aZ$'aʷ%/_)rtbI;&t!l"a5uԖdeG~~>d2Cdg;vf` B2=N*G', WL73 2M__/-Nax?7A'r)˵QZ4+6Nߠŋ`9 cYY] ^DP|!?@`V>k6l&m'{Kqf 9FEd8N7l5xot M9q} 4t.~O<`*id"@?0s6Zo|s|]KmR_;Ŧ9uα|i:Wiⴝ;0a [UŢTUcm&&R.fsh koDIZ?y8lRJ{&,t4uSl=#+u{"O8 h[6/Gu0FExu9;R,fZ$-l\P/'5nLW~E9N$voL~tk"5Vv;,&&zbxt-lfˤ_Kӑв) Ds/7 kO&}gbQ!Ҟc NK2+X\Y@У1΅6:Z|}80+e% 5IK*sP`5UP^.@6P?Hm )!iYu;sH pI:zXH"A^ڸk3Ɖw /D~a/ŷ;_}%7R%Lpd75۶Sp \<HfkǨEOw4ߵ2©W,]+:ņ3۷Edf"<|Q3́S=,^Tv\~W^33gl|O|c EQEQ1!c47:e"dK]q`31CX2BK5ay ^sOYi!%T]YCdtp壠0!n X Z;&>J*RarCdS5@H{r|Zn )( oލϧ0t0v;exp3퉱PW仲/M1ܠ;6IC<}l}^l?b r(*4.&smR‚|*( !Ix}i:'Ҋ1AX8=H#TTNUa&`Rˤ$/ CTM C~^6N v3ƒ塰ý] Lva3)*b~KpCאiIŋ/ƊM3XėCA^nCÌM |~m ̅6A RItۻH7]CSHʊ wu04t2J( wO /_GșYN2pIiy >eï\|v6-/5Fڄ'f2p.((ˏMyĿ7xpu)bf Q{ ^{-PCqtN3<ĞAaI199VR;ҖdzNAQ>dAGƈ[:\ Qo4 UXJIaeT23rͤ((;$3g_lo+uw}c,. b& gj\3S0RK'tb6GAjzFv*3̔ )k ̰i;}MK Rb۩z~ҶIfqqZg^cNGe26x<(q8qhW.4tyn$y7{fE+1s{5i_c~@un#ӯ395kW.#i1m0.\Nc^LL'Br0K3@1K];󮿙I!}r\ν4MHG`ϩs~Bݙk>qi!6c4xg^nj N$gr&1.][=#-^d3sB,6x%So.ITEzݟϳ;(fW;;ԍm{dcWK^֥c:s/N}oDf^K_3I#g6zMF8x+I]_sckQOv*#;0ŚkGIlb3'[(XlRNu4m%8].+caܛ@&x8.NcvU\3x*(,25Zӝd,_G/GmK beRLОI9"1R/ն/[Cb]m5˷{9w9M˞Ch8sʿoV?  IgK-WqEM%t:드a fy] n ^Jx1 '^989l2hGR^}3]ڶŵN*|ZWm_cY!Ov>G̖ $kT`ݒ4 jK\wjnYWӵ~_uI)8W FSV/E0zҾߣ?si?k,ϒe{+U^樂}WJ/I&[9s|+I__W´Ԭ9yC.^JqEWuMi1o/} =gލ^7*((.R/{_ټr6qzMܬ6IϙWvQ}ﲴ0;+\o,jSo퓀ΤfN>?}OvI9-Js<_ΚM^}?2I;sL׼@v(p74@M!QEQEy7 4c6և(f:r߾@x .[EEm+u tlKN^>e|)R-&lW%VX CQEQVs}-RTރ=bBz@P90EQEQn%i[76+|<+u )(((ڨ(((( `(((((((( u%Re}?BB}EQEQEQnoH$b;ҶyWNF0UQEQEQEQě0 7PKD"&,B[]wm۸n4MͨREQEQEYrm[.t]_}7B`'c,D蚆m[,]E.׻@b"O98](((uWQ\7/is{ݨ@&ŒLLaZrBDO=?G [B@rzsgN^g%R:㚦ߍ}3dn{K(ēOBwz?EQEQEQJו ICz$;#TC2ظ//A=SHi ;XoA:F䗔%O><d{0uo~`0 !b4+GI L)Z'L}7+f7%g؄' kV νe|;k΋oQ(((r `h:yY~8O89_Ԋ%A^y %=o򲂛HNq`#ŕN?m 'TdG8s(2üQ$RYNGH US 3!i1hN%4 be'wIdb=ml||'ò'd#Ea* ÛEEyI !)(((Wsc ._6.|EmOP@Jp2(nMvꈦX!fge!9HH4TMHۋxdg4 Ӱe3wr)xZ"@ edirf v7vUP,7t|!<~iېOAa)ڡٖ6Կ I~ľ,b̥y?NY}}\T~?>N^A6YAAN&"s*,# e:8$ L2-$SӃeIzH(((n0D meǟ|;@!4 vO0>%iٸY|:c}} O&p2 Atq,\.cB2.,CDzAh1鎸4Ĥ HwjccD&v2tԂ fNæG/qudw?(Dz`bo.M ?/b9d%I F'"8Y"(I |Yd] %VV-䡃tMdLwq4"@d|0oD|0[0a㽏p\u)ml)8`REl7y?{ѐγK\qiN=JG6Ubmh`ja}Z(/>3pq%X]>uaW폳ʫ)jb`gm&'Ib4w& قn+;+\*x(((rx RO |w;ηрTuj<`iȅpC;\8;/h躏 2jn>*WLLP*7pi6 힇Y+vO!%9׏W|\iaCyKᥨ1L:Yv&gl[l5>z?3N_cNև[?G~H>F ed)(.%/+##rf8O}1}[ }D;NIYi!7eE2%,*5cʃ]|kyu T$>YlGuΛ4SJpYu+># !&%r/[UCt]jQlĦ-rBn. H)yEQEQEQw!`nG)m\YU|w~; ?3[9 `zy|:Qf+eaNN[G 쥔u7鄞;x~UYQYSi]J9S{sդr: h J2鼔)@ӵT [Sw'_[_D7462^n7sM3xR9\¾3G3'5F(dD"Nx{^~`;;^oV:DSLH)I&DITP hHgOcMz+eڜfx8dD"@)^sјI郜r~}|5{I;J"f2IfƣIAhbC/+]c9ݧvq?DHM<g:'ae%I#q$1.8BC(V**P<}O'ȩ9ps]ț0CI1sp-4I&f"iVI$$  ˃[u?ϸauC/s"gp}3 L%f(((cv˯|?LQSSx^Kˇ C-}Abzeyx3AF~9.,=Ȣŕ %56^wHg`fUc4661i{(.)"=Vl3R=eCyKϾƤKCong(Bq"{d,BNыhXKGG^jxiIaE-Ir F%EeTk8=5e5d&8zZ:y+wj2n+j)ljk8JfQKjJ]eѡaD:/[h=Ǚ]$XNFv>Wj\lA~I ^k'/0I S!t3e9/\7= MȣS\8yΑt"s_tMq3'((((7yM!%';;/o6irЯ2"HQhZz@ga M7 یIj=y[-˖s>_[h@ HL3%AS 0-3U@$Mkk!/|fc6B1 lӲ x_us~ccRn蚘!ҶS#U RSWL+]Mеc!躎.uCO2\nRpMual z*a:eM ]fis^ZR3q)S{0().(((.zx;i&7eAEQEQEQeRo1)mlTf((((5-d''pqiVyEQEQEQ j-$4uw<Ο{4fPEQEQEQ[0T#t3N']h?#)%Z{UQEQEQFW|F4oێB^8N˲nu55eˮ*(((iB!<u-ar{]H(((X,0EnuT -ОyEQEQEQˉ|S*$(((,x*((((ʂ(((,x*~N(?!ph*c{흳JQEy/+os~bwM2QEQw՚,y:`%Iju-EQeBvM)O0%oj/^M5?EQ[NQKQJ}6A [ݠD"A_mQ(ʂa.|;?b>Rq'\(u\ " H4 @Ey(̊'3xITcRCEQEQ H=sEQ5 )M7݆ yGH4qy$5-Íx{$!(r}d?7x!V#~EQRS MtNg:i[@&SHq`F&$d$f#H:Y2]7"믛i]NpOͳVEyOI=DAN{ߕf&ر΍djѸl5VQEBX tO$|~?nCǛCiE%x(4b}7~Β}X|CAMC|kKvք'-[@f0j#[,C#lòa(l8%FC t>臯]hd<S(ʛaA8ٔWPRwDr\!-Fhmmoh[\ J)-Ż@NIN]^/K_ J|R=PEyKݗn^y7RßMO3_m-+° 4/tpC,) "~38 2U %+g ('0tT`p؄dC V;g^!C: !P EQ+XQ{ϓdy\+NO1~.љt217^fש~nbIb1v|u=)> [ܥЩ(ޛShEQw;B"fdQT3bŪU, a[6QWUȷ WG[,/|lx=dgK79B }]dn @"3[3L(Ydx5l[nK90]˫4w|\pkLۗ޿8iY7p5^]^ϔM,CQEy/4{0~ضZΙ1wb2Wk"=]h0ϔpQPf3W[2oZ{*rY?6qCqjZ" #pd$po/ۨ@Pg[lH?HÓLE8^'` Oj:2|7LI$-l @ LƘI& K(ah؉(Q,)ѝt#4Hb8n`D-CDb&pqi&l <.#ޱdZri 4;Y[ܻ۶|A-&-4KI`8,ЇC$caLJ3V LO%pgaXH@Iw٘.L n -%bm~ɱ XcM|GXVb .>؀׺-pWN ]ňB(iX5sq5֑ҐҾsˋVZ[;9~`?ݲXzb//9wzx{6r΁i==hxո">&]ٸy8*ֲ}vc V?ELF&Ȩ\΍u'郭T.l=Z照%\dqp=O /}"$嵕 #gĬ˞pi$nl;Otp˅Ҍt ^{<kiǿE`N4!}8iLVoaòy5ô^hsh!{[GY9Is{ ~l}n]S|W{a¶{G%9mi'O29p϶{3}ᬾl 1(r{Dc12y#''t l `Hpyra4l8jgd8,[i|=Ț:=+W~?xffvE9Ǻ88Gpt# ؝(zjsMjCrӧN_Z#;J>?,xlqkW /R2d}}m?>ŝzr9~r/V$2p?_#EI} sHLIlE>I#YDKĤ Qjh RU240yf:&x@$cPʬwTEQn!-&F4׵?9˯4GpHir*V&p?gX#'{\d'ۦYb сaO>Ph .n-~v VQt* Gx~AV͡STQY#xGOW- rXI'ƘA+U9m [^2^"Husa;"7}'?_GF8[>~:ދ&>|:!v),.4]Z9qRgՊp.ASt791!zQH]iJr|?%bo+Gr#ȅ9:FQviSSӼ{֭! 6n؀jW7qZR7d2(­rl ~{7aK [ WC'R2]pԏpoMpظ oE5šŬ\öh gRdWP^K" M?gZ:NC-Hyey`/!ciEirksK _~Κrr򕳨֬"ճ OD2`Q BuןRe dfH\άԪ$^ihR9a8{uJQ;81`HmG&m60aMN'm:zj8]*:%őF+*sr4VXj ɮ>xRj$tG d IQye*(7ǃ$+NI)qf JCĬ|2&x@w8u pr:ѓ1.?D8ww-Nˆx@35Nw4rh A?Id^{m~9^֨ZڜKGG("n)Vnlں0>=EQm+l*Wl惮if R"i' g?'Dg=%TXͫ) 'Ee2VE͙(<۶w Mw?f>,K2KI瑐RǡضeM̟wRb䝩wV>!O1CxKN!2:ITGXF[0;HSQW:Bh ޜjXMu>6NqPXH ᰤ?KBIz޳ҹ2$8DM9JJLr2P8."}S$-I8H6Kk2=gbr; *uAqK)5DQe1+*s |` ^qՑ RJ\lrbr8I=s_m1AD%kNhIꝔ7R-JwDc4I(CljDw{ d`5 3mلl躆,lQ|9rDSӱFm-_%^J5m.Ed9Hbgsu0mb9t ۴z ̄[K]l4_|ISӅ c,fٶu"LKKv<7aKJ'֒3y$`1=>xgݟAN۾tSO|jϦF>JQEhƲeKRʫa[6+V,c 1$;X}EH0m9Ko QD9=P0HKи?I4M J&1IE[+wFl=ٖa`JDҚ;rf 2'FqUnqi1N5oe )L2L3ԱNM`dE\i%#^H{&+C\S K-O´2G`vj.0L$a" 59:TPKKm!AH&R :[)9*@À_՛J.[`SEQ+I Yx^I͙ i0AZ>r(!ë{o@din8FC8BVܽsE~O߿o(|$}ÓvlL0, _zN?^-m vn(˼z,B]u~*pO*4;οm -K8 N/S.%Ny8nN'9Ė B}HjT;f<&+;DžoqI'h&$ 3‘D-dىmy /#WH"} ĭ8X|LJwYWN0T EQ_˖-e;زe7mDލQ7QJd"=<4VX/^|'_,*Fӳzd8zs'8~j g㶭,).!z},wxa)Ο?ǡHLIsޓ2,5'˶e1@8IZϜa*6U!xc`xX˶0&m#ym裧9p&z9~w`iQif׸kIB0zgې=,Sb #ͥ>^QHS)qgzjM \bnB04*5lΆƝ:}LAτűQ$Z( ?Z™_||h)9ϋϿ@1t $%DƘ3daxd(52v> 8z<$ ?>w}!vΎH),]pn4EX41ч64eLIyE Ƙ e3/"H˃1[,\bϾ & D#IİHL$4:C{062A㌕ֱ}b@ֿ·9G6r n;7e'x457sIZ0-3$iy6ebU ++hjiԉStxm,ZɖK QE ![TU+O$]-|+`gg2SSS^ at{08a|d֋<~LX>6=lY ,]gor"kp(5vN6,ǗOMU.fg0 E)tt O73)\dG8E,*& 9r` ]8m ly'K .ε'Dġ"PXFuyŕTeikxލz)vt6Gp{q)㹢\Yt9E1X8=> \W񔄕}q-Q "/{1t[2b WiɚWy]lؗqYrFEQZJs9.ot2}}݉wNKDxyeJRSs({^KƏh_vɸ뻢<;@Cm* %/}eVf@Jkqt_N=&r)%Bw:i { ~滞瑩p32^曩g$?ǘ(rs g$AIJJ*"(f8{Gpw, HF'vuVJ278L aqt',Zb6 4ujo w#ߕoS(PWiniiwP{A`A& {}UEQ(7ǡˊɬκ:|ۍ%!fdW!lut0\ZVQEQwwd' 9{9"C61G $T EQ48ek  / 5%B»\c:MVQEQn}O@vQ:i7@PRBHP EQ$hN J.H΀NnBs]P޼ W((6`HVyDQEYhnCX@i::5(`[6ccdggp8nuuR2:6ĤJ(,ߔ %/ RJ5(jD"TI!SLLL*(r A4Ғ<;.R0 ˧ڶjx(( NeÁVPEQp?i!CPEQD*6BFҶըQEQRw˨ns~݇GQEQn ! 21Lg&x?v_qz~$щ!]`$jwEQֹ)#0`zzhi:.ۉPCNEQۚ@C;csG2n~Ib kNĶk9~2ƚ-Imoy7gjb%Zc,-D$;佹OKk .?B":&#Mt5 ]Mx$K.mn2F!=<_Wz0r򟨫Ne97=ʝPĵrK)9|޻wzw),dZ(^}|=NƌqEq >"o4m9x.!`= :{.Jqgܵ%)(wc]9I0ӏA晢(n^#B0}ogW<|nr\`٩ p &h O y 2t_{1MKEQC&hl#@x2k#J(d]T:?:{d%d/᡺|Ͼ‰ <nB@4*YOr+h`/6 ^].A8]}Wf$/,Бןg<|)%WR;\~7DX~-vj 4MӐN@Zz-':2~m+o ܩ3WsҶ/K:]~?]TtHO3B6ҖitԔԶ5M`gʕR>ϧh2*xh[5[sLOaMwRw>Ȳ\eV)ќԮQ_iCbKYhl5@Zm΃)~ȷ<(B"ЈqnMK5u?UٗS?x4%\V/8t^hktZoFBu|yu,ƃ(* /WyUM[BrW2ska1\!-_E[(5G4172D!mW^5;t=5">Qn#ա rB#bmq)N19a6yJK(,W_ChW!Ry4MCDN6A#PG}ӂ9^OF&6--$΅N Sx)Y^@b&io fd29W̔n\i!r%[V5UdFh9_O} ױqin-^",vbY/R#F`'h@}S/l]UаaZ/>0N‘ɪի(v͖F'ȩ^x FSEyRrc7WKD|}HOQNM#+B{cG9I 柞=xF3dt<DZaИkݟqp1rpetE;L,W(:(c d|g`6c21ELM pA@X=Qo޿5_ ^mbGsC*`Ȫ⳿ =~r;jʒ׮+)f%l)GiB?oK+]f`_|زv!8dPݧ__~ҥ)//c[ Dvj <.'u|O$L Wrr*#KǣSD\ǗVel v~C<9"(v buOr>XS[ 9??/_LI !@w[@v CI un ٴe eAU>inb\r f][#ma:: Oa!RW/%Q?2Lx"u~嵮&[i:]a /'h*gNn-ŲR#{L̆B/ji[N | (m0hko`ÇikkOߏ?7~pc#0DTdbFE^ifdg 2- hQ19wXRyG%>)fڶʿ\*뵢(r YƝQ+y'O2L-jx(_?w]g>,V(*$i\)@&0\ey42 2ܔ́^u2qW[qDq+Hlu;泿)9@822^.'rcuؖNќ.<.'.PDžBt yT#ȫ#wbM1<:Nblņ8u g('݉d`h6oxxf6R~DDQE}I)w݄avo죵ܜb ..Z;6POppA"67-FG&B#Hfz*1Tj '=5oOiJ'1g-{'3Ғ<\jayEQSS1K/>q'&BwdlvVf'cT7Pwz dUezrQ#NRDγlVw\Y')meNNzG\-a6c$َh,n|HƲ,L 2 ;̙(3硃@`L&gk6CPpd/^}G zV0]]9V@"%nwMCDrM44ϫdYƪl饨,#O{s`M,|x_O3Fr]1`XlS.1Cut}#k-K5:ڇ_bwLX-iw8>pmUEQwIFM  rBt"Hx_DeY>N!SI/̈Cx4teYz^|y?]ԓ}+‰C4挾H UWbY6}1MMӈzu7'OM5:ނ4-$3rf% P9떺iiȴnh؉0]}_Jqs)H[h. n~Vmfii6L4Mlw.$n٘ݽ8 (p'y88e[ĦSP[G~ɩs$upKpnQ#ql"&/K1sv4i趍O`WHNgnƯ9u.ixxc(ϾJx|i$9}t7'&i;i n`EU$I:;ɭ~wYg`h[\jBFWwAPEI) *xt7eR29y0mCQDɉ Ɔz8~`/͓^֯[CMYz. &aXGT܋4LD۴E>b#ݜq @Pد~~y)˸4 )޵'(%$'^TE|Ɠ VxA[h ":xeR\B،74b !6Ʃ+ֲceVt]s &&'{c|TB0>1ty0S4KoEQS]Lו)$щA% jSTIﹳ $q$g{]<ᇩv1s_`)VU#\8X<Ӄͼ i[[Cϩda^?݆mx&ilH؝KeY5y 67=@_w;VEuuLN';8DG[b**+$?s!?Lfi>:';'1cSpgauEAKNYz%~Pg=/b?ɢV/;u3Chk_ړLkXD1`p&t0gjraA֮3~]uvd!*=49L%I'5oB+{8x~ʵ)y7} %lY^wPEQn_a\=^@;2:F(I O/Ye_QGƈ-*VsZr|:KW.%CD$&ں хǧ162dTRv;ksPRmdPE(f9Kk qOG_0EQ{"95Lgg^Q6դ^'spbk#>s9F r wţhxٔU/b*nvز80J!lNS/odarm^EM\8|ude挢zCHFQXUCEQ_&yt!Bb"᧸̀,]hqF'9l.valʋr/(C rss)! Q^K^~~ל%U,Y5KȢ8PN1+W2?GUl\Y tWTbzf ,-dzlp _rs=^i |OVWR2(S0ES\CAAAOb.Πl XL#=hdWf #ÌOEblJu`n\?+ֱvq0td,) 1hs:Gao <,ʃٳVfSh:|g-:x1o+ :ɉԖPM4fNv]:N=JAl[qc"'B㦤z#Rm&Lb;,Xl׵>[re۸~GV_1!ƮhR)^yq)JYh!>4810\Sj]TO}V|C!\D#|u^vM噧~IGI`o iOwa9~?poUJ)ٶ}'CCC%\kpz^yv,X@2R^CʎgxiWՔcfGC?%vJjMo6B  ;ͯ]67{wrqu,[y zr3D+IuFe}!˧֙eZ,ecQ1&躯؅B\{:Ega<~9 }e$*u"zuN^y}t*V-eճg_=@\^+e /CC]:*P2/q6{-ɯ!dj#Ȣ训oeTW6f 4J۰=c= /BYi {_˯0\T` 0P-ley]l; L;H޾>C$6$2O_8B"Jc 18a,<' 2<4`dxj| 41%y7(Qz?zRVT"( hzak2Z[ V4H);R ;$LNFWxd"%ߟiatѡA% &>:DԔフJHe708DŤGzfvHENr1o<Ʋ" {x-y{Pn)om~^-kj21a*sgM -UՕ&^)W̲MWՒ3/ !3Q*ч<J)^zXDZ+r K1\ ",[bfw(7ga\t{QZR]r{ooA}#q:JYD(/&=Clu{>?/N`}i7؞XΣoa,bta}7KJ 6sD2Im<`D[Duy捜@+Ͽ=g>~sqAh*O<]KlZMo>~oӿ1?A`[+W@g۞ckc4IO6=@<;o1g ަ;vȦ#n6.\NU(ΑQXgt0{ǙNhol8[6۠~EԥO=a?Sgϋ{b~m }7c+%,˧֏''|#+:؀?֑S/Ǻ ش 3jezɩfwO֗ oXH!nb&>)HFHp:2LJVG@6tJ`(ְq:ض{a>4CkR8='~6k;{\чo7`pK$ fQ{ᅮP^|Wwc)N;IuSϰH;$v*ʱoik|γ0P14l~F`:\4rJWƓ@f&X{C| ymS8x*L,&eso (GΞMxjأ'Qb,I[×~÷ŧ;&=aV??7Z! !.I:#2G)Y3 MLG6~4 &6 M~}7yenzcqR&,b~M - Q4!pޢ?B p;8LvPw~15$S4\n\NT7nϳxu+=Xz!n(Zx<F~~{?jIDAT#љNtON4 Lp2Z|Zk|>/>gS$XfjBNMۨ-'/hSZXHec4tQMo{wRThVr dcn~Fsp~!&~?7ܼ)~Oǘ-ttN3NnzsYЮRZAo߼]0Z' iڵI ~sDrjCS, S:P[WKI\:f`x4_SUpU5cz+WF@T`Cm.JYd#_ f 21n6˃SYyB̦ `ha޳v{J.̛@? o\x:Sf eErb?#Ix?=fJM62p*AtdrӋГ56֮bukع;., 麵 Ba;@ XD2TP""6b08z<3[\ n^r[ FkEAI = l?6LS ɼP&K7ܵ]G(HWHnE0)*R>Hdg(1@6ZrCN+ǍLg.N_.ky||ϳm8ԅD[6tzYE!ćQw|>"SϼFs6 t{x~7r m-g}cFFHĢ6#=l۶QG饻w˶ƞqa[, +eair8=Ooxt"mO(׃AKW=aR`Pb# F+jP âyǫ|{|,B#3SC""ON&V4m~q]kQ’BނEK'v}8M26[?B7g͢`&cQ^zU:;0 Ʀf^}}3Tx*T; >4FjN 1HD &kpsb @umY~olo$ZgECIK@{sI7 b4.wc,Q u4isP9sپ}MBeN6(}'OaGSmi +:]efi,-4XVeaM|QE:&mY(4#`E"<"H'R؜~eT/]:C~jXe܏˿޵Sctsy=uξ>z#e!&_ fddχasEeKPc}8|ݻw[9V^e Ag'+C(}JŒQRZBAvpv` ,ۏBsoo=7d$zaE!:Iӡ4G ㍵]t(OY~6~@a6x#e۸gtcZa'bWDry%xjnECiu5+iœ]D]m9`յ娡6?BPPA9p#ܽXUKR$ l&+1#8zSvR}G{]\ ~O; T;yef{j= oC3% wyE :ʞ % RU6^vX_A 8q|7E k坷x[ZW9o|pQWEK)1h:L}OydzUeDvyaF62*C0{-IXrkӺMAnM|dr)v9DW$Av/Npv4#'#n.acp}(?N"t1I&bD)4 &KQχ4c(ik|=T4x!|*]P+q{O7 C14h<"/zJ7Ae:3@B!p+yRi ʁg&tO\l`KJީL'ss?<7ݍK 򹘚 Dkٿ9t&L|xFW^|zƙAΨhǜ d2B᛹Np8LxsNҰk+5S\\۸K=;2ÜŜO.w6ڹ{K.B!Yq&5`w~pqdεZ@)Tj-/=k=׃wB!ćB/fŽv?^(2=:ܡɡ.'î;ξUi> !tjL#Hp3cFss_#,\jBqИyƟg̬|}zsd__opB]B!ĵ|{D9)*Ei-'!az(,+Ck ^U+@Eb*sSh۞:!-8nNU2B9Lzr/1;R<Hcֵ.B_S~t !۶ϚLJ)lۖ$bNIӳŐb`Sm^!mZkNnCN).K,YB! [dgeZ$9&++ +8B p\\yyyR3$V! P =kf !`&i^B!y"B!B9OB!B!dB!u@w !f30 i!kd/F[%b0M`00k%1$I,ZBdYY!>qdÔ!B!T* yyy? `!mv4hB!9XEo_?OsRx{;;Ƀ9MZc$qpqt2*MwR7= Bv .9<}G?%[RN17ŏy;G,ws~)hqj58M@[i+^@ygbK/}VTq(#|S[_~lZGHRNYɌ8'n]GhjD _}xLV^xW$n:)'W0/El[_̧WbiH 7w0MNBu_%ْHN!1OqRC( Jr_~ Q6?u: Li!+́p8]םyT&%|FE ^W0 ̴xfxQsC5)+3 Ãk&}7l@4 G6uxLҜ-B=|积PUFk+XĦO~ɷ7̘}RL 1:+{Gr)l˚3dVWo/=Ų ky|e>GwI{QfT?ym{=+a9~N7Ce/ +Pzoa{k.,)Fi$ה2㽼>XWǶ32ծ óvzFMն 9{楇=e aYogyofZ;"]&W?8^?/3t|;㮹kRil=.H!,$ Y6+ﺟoo^ze'wTA FÝ=|Sk׳<)^x{<3̪^敔r=wSKL{OxPiKq(<+˜cU)13ox"w ]CDavフ|am5&{XhmylGxryܲ:5~i%f(uķ -n:ڎS߽.ެRV/ m1h A'h?I'Bmk܁<*xH_M'J['x`0vqf7SB1[s,_24R?J sJh:=Ʃ ciE%+9 f>*:u~y%fk?eź,(6ɱAN55`gWkҡ n^@zG|jV/,md  ( vr<#7 $±'AnZ,H gwR^8rJV\DdeB!n4ƕbfPAU5;FHxsW3N=wy..FQ?Uu *g8c3oD;\0s?.oCWm u?GcٽD2zxkh'HPwrf dW.dI6jl"<"s_yag> Ԡco# lO .dAE.=f5]ΊyyNc< #st@t 0b٨ɷ_̘s:I Բ<[B1 RkGRS:|$y(;M_G ե8[!+t"»_no%G^)|k7/孇<_ۿxC}~YN(;ɱ-|hcxky6M?=C`$"mfS8l?~xoOW91iZyI_:0]6ҪZVc OM]M@qa6/w2w\!6 =0γsLJHmSP5 s:;;(ϧ4o,X^z0+V0@K-$;1ʩStOroa0ܲ]-N|L_1G$HAg;I [`OH'kml+NEq>Axm8 9],aVNHOBkx.q9H)EGXr}Q !84e=<+m2C1KJ&kx2y5t{_CQ/F -מͺZxVŴ:C|FPz?SUujWpm p6~w߽9^W9Rݛy0 ,`¶.XB֍ wD#PQ^B ū7p FWOE6:,Cu$y$lT!\W-P$1FxrPu׃h;`pt%6ZO3:9#3ֶ1qGH1 ؾ2ۅӟ5)()NpE9gPb[15uyx8H'?˲1.L~f(C;i+y 8Cc$,0@kҶ!uRvûw(Z ZB1+L ,_~˗o֮YŪ+.V&:-NvKpPUdrYٴͰKyay ~ |<n ǃ?HϨߋal4Tt{p]^LC 7١,>/^  $Riāfuc°33Z>G/B+qՆ(eve$DB٢od:z=֬^ͺk.hLJꖳvEÞɡ(?R ˲H[}5ab:P g'13EL&OQ11^Q1zٙD5-gtzqroڇȟxڶ{ܒ !B!vE\FS64MҌ7^7S?1oejrl#H[IVFN /?m <@[[7blzҕQ2 9mizxmVÛGMU)_&e٤#ttOL&Dd307,E^R=􏦩Z`'QJ=ٸv1~xk@gzՙYRsmC0 6z 5W^t[6Z>g3yWhxc1yt': ӀvzƪX9 :(]G4&ZWM|6F2B,zbi+d8Xz|sC}ǏkVR#zwPVQ=JV+gZ]f演"{7y9MNvT{en^';+ͮحpU=aj[ -M z0i=~>f>.0*q8Lgxky~?y[V/0'k>y7E;y{{ȱ(95=]+ʱCtutOhA]$(qk;De)ݝqwu1(ŧ# {".F"ς;cGמWf~YOv 7'JJ ())!h!JJr-›]DM<=}ܶi!'&+EKR[q,J)m ]믋B1֚ABgZ3< J)O"Kc|j'Hض-Ja&Hin+δL#S_X2L 3Mϲ-4*3L=b:kow_Ee'c2IxʬidUǴm{~3 PR3uazmCCCR)*/Bq-&** `XE[[;eeeg.{x4';],$ڶI_ŒgoYԥؖuVjsÞt6sιxXjۜka\^B\ `Ņ>ZcYifjVՊ3ĝufn{XߙDŽLpdq6;_(BwL!B!B_cB!B!Ĝ' !B!By.1QBqI$Bk튒x٥dO&n'^!5t:eg͐%%/AB!]+Ic1 lZe 4!sBx{s%WJ= ^T3)c쾠A:Qb; +f3ˆF.y"k#lyy^݀ɡtW@,)8O@klޠXw'κY^+lHdB!B\sPz/=w~"{/0=;XLuES8AN+ϙ &)N~ ^Hjֻh\*+pFUf8|q]8nK_"_c|[I'F *sq7Rr`!B!uc!R$[YQv=p2$ # 5yS) `•\ \ɱa" XS>u8dP0 @ę S4a!=~d5M3όg}ޞ'Vqdx)ǝ/޿] OQ &z(N)`6gV1iLVwf !B!B9)\*w?xaodm hm:řuHmۈ%Wg90 !ь 3Vأz;8=Nl$@$I0M_{;A*Js2B[Ir"uTWpb HWGNv`!ͯ8ˤ8aEd2&rh /KxƳ†5*Swt10#6((+'?7LĆzꏐpgR^g~Gl wWPʥ\Hw7c$RSTFQ=#$B!BIJct%5u1owxwo +KbfVB۴%*"5αv8›#TYEq%%~>Ú"N΢TUk+se??m.n{`=H+;c$0`u潯Ŀc&n˦>vG#vqc}l9\̟J }'Q,r8ܧmm wWi8yn#f[[n'XTt9)g| h^;>Gt? aIZq Ef$4+ajVB"B!ڔ7<#fd;ݝ'i 89-],p+׬d¬! _n-7cڛtB/f ;cC{9M4ݻ9AָuD%X4p3d;/ %+bպx7OZd0?֐[߿ {ej  w}>/po8}+Gsp P 01F1q~ҠQ"cS3`¼+8Jww#aP) k+-z];+nXk]= mT:0,vB!Bq]vpw=]Q 3(vSG2t'y.tl/* c] gM: 53] ])ja0=X EQDxgo#kƉt"R.^婖GmV9Y~%b>vo?ޓ]|lq!vPn#%}YϠrLmah7+r.:w0>y.{bPJ` @tbll 4Je}8Tl|L>#t#P+6B!B\s禰Z[ gXFjdf}ܽ\G8@5f| DoxlXlxʼ=WS?NKy@rOƶs1"|1F-NYM⬒_R@']C 0љD\V\ϖXj"ƶd:(MQ:o9~5 I  IjǧN2BkDzoA5mG -DžNY<3hmYcI,T&h4[leWTuw3VDԞ> OAys+J)$b. #lztfDh,q5L# !B!5%ҧg0/!yMxL{5xϰHm- 4 •W=k -4Dd8e畤Rc"x-)o4ܡ7r)Fi;T%߿,s<9~-=aÝwrV<c̃ʸHxo~ǼV}o ڇM8;OQ0Kp5| ǿ-[ywN:S<.^,siDFFF|8Y<B!BK寰8ǺH[NJ(+>Hf./ULE,_PC4wFPYCNQEBT/:Ϥ"* v\\)lfp`ndt:gF`8Jr-0酐tpcFʪ|`s u1;X\BavnAG_R6m\I`#ǻLbeI/JU,ȹ`k99g} <띱JAbCNp:t@Cs[ﺟMt) PׄX-_FEHI-*87ŠZ'g0)Y’b\`n^iƛWLEY)u 2/`_qOT3¶mf(;dz  ۯ~u_3vtvR݆B!F<ef0`<3m;C*.0NDmm5`pڹ7$?/e?g'Ϗ~#:?JM$=PϿbg|e L~ uugKR﹨gtڢ*Bд74$/SoyǴm.p|'81νXFj}bY[[;eeeg0:kS!B!~͝w3םi]~JpecfTB!B9zBrRmN|'c |6Lrv/u{g{\ !B!Bk,|=#ZzS NZٍaH !B!L p:f5X Ә!4 bN.LA /u]=~~9$!B!א֧֚sUA^^.NspLikF-{[;}4 0r0 `!B!5 &N_Sj\.nσ 5U}].enز_ `!B!5^f~/e1~9$!B!su;]> d!B!ByB!B!Ĝw!$$HZ !B!B8yi}*ZC8<`d7B!B!>,a{I L/pRTXx&B!BȥξrQ\S!B!b$B!B!&N'$B!Bc<>q?<ܳIENDB`Eqonomize-1.5.3/doc/html/C/figures/exportqif.png000066400000000000000000000607301416454732000215700ustar00rootroot00000000000000PNG  IHDR6:jSgAMA a cHRMz&u0`:pQ<bKGD`IDATxwyvUOF`%ܙ7sg;ɳfؖlIdI$A$ rnttXU{?H`jڵSU}o{pk#fkg^Wr_x^~+p tRx,1A]Nhtn6`sppp#8pax%R Kl(Tp%K=9]uvuw-&;eOa-qpQ㴆0;nq-%iKCw G>d(3MkI;FZ@T)P4]-IA35JRX9uܐ`BQ(+,jkwTsL AZńnڀ6lSjQihlH5v; KlIj, ~ҤõPjM)4( .N6mxN1nC/Rrh&y vn && L |Igl=TxyE!k~߉% 6إ~E'l@B4[55usiW<$,jFH)8=XT3cқoIX󝗱%yERs!`MV ~z⍔ GӜO_ζ4fxΜ#? uD$T׃~ P7)6%.3m~es.0ħz*2B*n`X Kή쾅mlY$K ]\.$SFQ LZfad'HJ'蹇 >B{Q֐(~ftv mx|=+9B1rmx3ɧ>q/~f Eq >dB?Md 0`8eD\SiJ!匡(ꩩ^͹Sk~s_ȩkS\zx mW#Q ~m|r[>Z4BJB %ͭH{tQ݂MXx-mCV 7p3@StbzR[ٳc#ALbsxNиz5Q9zp%мz=˪vgr+w< om/~j~i2sSg/_<˱3{q遳 ~1 F@S\xeTk:+Za2F)N YJ+tCj?ѓt^]%&?Q)1*:-AA>#MťbEi2@XwWU-7p\ZQ%t_NвxZnq\'f7=ˑu;Ɍt3 ]٧_&jgCrŅ󏏽Ae#{vF{ G>e~zBsQ܈@iN8?CU59OH+TG>#w'"y o fJ(~R F3{zSCDz4adbRh|n=!Ҡ4T늱4b\hΗ u繜?5huxbߠŨX_nf+<4!4t /ia_^bKH@珗6,~DNxBr2ms|[4ʄ*|bm>͐M+銲WtIgg5~Oz7[5l\ɘWy' %ywWT ۖIڄBuF{J4d֦/k|F@1H0mMVx(p_AC@LuQ&/K46a_c;80<{4oGh3xd/ *Tt3_^ +$zXS?ݏooqoO~u>K0@54Mp^\P cD^ض:R >ͯtwGCxG445Qӑaq́JǑB`Zl5)*RC4*]lũēyNڊ_•q`h<\aTY<3j1Rge'aq.&xd؂Sn]MIj":.xiҦ{N"*RAsP-ft r!5J)lq~uZt7p&tlR+35:]Y'l2^γϧ %$LE^z2/.Yg͉1:G<5F$Ɛ9I2SԦY׹y3OoZ`C/;i!u 6Mt_jjpjE?<ۤ"=)/kƶg`܂e&Ȏ\l`[Y)n]"-_`Ƥૡ]7uBinBAfʳRJJ1znCo&jɔͨ"E^J*2Al\իVn6ٸї9ޗB+#IS}Js2Dhb<ȓdTN P .= bN EB(I_"ϛ6qE$uAI*\qb BgR)iӓShE!ٜ %K`z׾gPRuB&Ȏc?ṓԷ6/hbvѾv^}-u *kbŪeT%'kN7XVPLKc-T#:vGhlistgOr F]|c{(>/ '9xé4(h^@eq}x`ZV5ıENhݰxRÜy-&MX=뉺>XMX♎Iڜ h5j:[\I:zXeK[ٜKX;l, \Ҧ3%]v5nԱ2糰e٬y:,~]͆* 9is6i146WzSn:S*-M؄{l9S6SƘ&R›Y^.^DkB3\yl/k$MU-h!ΞL42'log`RPY@]iNF0 |r MG<Ea-fu@§e+R69ϫ1j )EUĠ֧a[h  شOڤ#G% 8ickr4m.$)1ГQհL6SR.M\AsĠʫaqI-$ M9T#K AeР5%,:a[X3B)Rg'%Rhz)*j!NsH'C2csq&[T^Ơ lEWbdGNPi h`+&m|P lJ3؜Oނt @RZ, 븕w¢;8BC3BSe'Ģ'ޝ`Eh^H{Ki~$Җ(VThØ(%{0Nkhza9rD)Q5bBC Ii# 僔)mۋXUoR rQeUy!ĴSƧhBֹ׫ArCc@cYCi:Ƈš0 >`QSQwp3MNǘeZm#@S}1wه,Kl(.]2CYy>4Kt-T_a1,y 8&x1DIȷO#nQtMeeiC۳v ~냮cce-wpqVp888q8ޢ(O$H$86P(H4EӮ_r-L6K2]wVJ:|0M~t]'\`EgC|~Im֞o#jBv7'B nf=_=1y^RB`gƹp,zěV4jVNm9}3<@K۲e4=$]k 4% ´?뙳) ynNwMYݛ飅izӿ׼OI2$ *4i: Cx ~@+ oy;XB4<Ԇ;b+ ^ egI$S4 vA S{k֪BS9ړ|g/@[Mt/]-&Ldm4 (cI, B7t S th$ץlɉTÃI:g!4(J8.DL2 4AT C$AZ&$&hn?x6'#"2$cIlK4L&HAb0B##E(!u_y$U(kh?$cO5® MC3\!B/t&%^@}46so|#A@}Ycc߶M{ e~d?{+ن H;CM-k7fL 1Et g+!{)ʆ&J:rU<桱,Y folAG͕\-7PPD!7õ~>{O='=ɓN\ Un2#>#N~S\ 5> Ir$?`y7p-ǟ?e/)d>=qbOqvcݣ/\ 2쑶ɹ?j}sP/wz-lYVi/Cʍ='9ϟgl{ַ z@ژ'Nsq<27YCQOrErm\&ݶWeq$Y>m雩CiiStfQŶ L> MBDNjrloS_$ W)]'8>TGDP/PѺFy}0/<{%Uy7\b|+&2-gJ)all[yl#.=7 i ˥ @(+w~}$ ˌHr9Mz&c hK~_mrϽwQ}4wS&CW9v#{S_%y|pYwR\XT[W66G a gz{ȼUIxp}5vN_!k(W֕++ )E>X5y^ʲ(gū.s|7Z;ĉ\1iٸMm3 g$uv}e5"7+o=y֞F܏m+Y]H5YoP 0 >FJCn 8:hp8-[{*<Ν+6{2.\;F'0uzNV72>ΞmgQo^ŷŀFc*/A=|~[ouD.Ra QO1[fK|_g^w>\<7C4oZEוNL0!%m ~qj07Oy}/e+ٶy*oi:VZN(uo[z~M_ ?y%N^҅+$SI{f$"dLϿ9t#$yMcGx`l[[?=a<>\f6e p'{Ma~]-O/vhx#!2aXL$S&vli7K7`4'xꗿb([gR/;x{_xkc=Vהj24Oڹ>9h6Yuvϗ?{]@"1"\ڍ;x5v/5ٲҀdbAR9 Sjz/ѿ᧶:'H[`I&6l2:VYE}vIltʚWpU+;`C$JOq^Աc2**i[RRdR ,B,_{﹛8\C*(i&ʄOoŧ%WM+eTWF 1di&!|¡زgdM+MQ`R]ɮmX V.'bYCGw;wRJ0j҇r^^`2ڰu9q7XKWnlps-P =K388Hb2YR8Š=O '>ktBM5MuqxE1-~^~=cyJ. 6 41n`4n_={eٸ4 0ţ=. Fz ,U.RFqF[- uphTp1DJ+^wE*]Ghl7amV%&4̼Bw%~CmXzOGTWMOsQZ0t紖?U >mZ#RtٙQ:`EU0 f;)TlmX8Cç. Z'ڊ>+֧8ytFXg~Y̌NR J[j@W#m %m{W>3:MTE\$ ;!PIƶJ\Ãw5^"Є34_hD)p"x!WVBhX8s`j)g/Bhǻ9znMo.E%eɛA<ƬIwrg.^}'NԴodPzCѢW49%u0LϿſr!@Y>zB aRӼ 5mA]@C#S^S]7 ay'Yy MA̓7 k6J(e1p0e/=cym5^d̓3MPK|ױay nM˛Sѻ_gGUPUʱӕ!簬cbr 32!t#JlpYX9uU\IY!@DӺ|9m˗RS[0siR+a}`\z_Iz),>1Lc".?vKc4O>6ºBh:[h",_4V5DHP5OrxK}%=Wؖ$"Vf7{qǨmJ199LuN I|466 ^cS&C=]t9/N:29ωc)y>=z5򆇐q9sپږU?w-e&Z𕏷_bMk `9v̭grF+ O"/3TCUI}1zZGedޡ ʽ^!16FoW!<#O4ءLgy崶qKy %i WqjW0"?a=qu)xXRt{Ovs/<).:e%ٽ &v3[08(?k; SyDj \~"2?^ʙc\C>D0fzi.䁏?=wgz&2l4e W2x%dh$Ah 1/"5˥~3c\teM3=9əmTE\w6Znlsd.\h! gia/'< +=ʥ=e|/X4I.b,zt1wF9^04^c\S CÈP-ַ6\T:+TֻxuR8˚ַcFbVRSRD}#J` qrIҹ) PW40-ӤVQ؞~ɣ0п)QpUF*ЗjN; [i'g)C A^z Z:(SCTySuݶV̋wK5wȫ]hTVxnzݵ)93foڤ}ܦԅ&f2ű^?o"8허b]-gbх]䁒6u Q ዳvul [a{:|xQ{8-έÌWhl2t!BB%}v "d29Fƈ8:|x`&CPp--4M':JfsB,fd{/թAmYkFa+_ 6;?ɕQr#D$.;=qZ77ƻ s5޵`I&E"ťw۔LVh3oxʍ?Mc>b7W !;{)DΖ/)\_qi=}Uw3~ T|)1x}-u;X=~ۨRm!0K2ɚm[v6Zde|m m;R.DO p f6Mn5;7.ǿ,E3mc |ssy8KEع}%>5K|ȸw]9*% W/#쥜qEʨo$X +5Rr`a"/"VRJepZA[8Mwh]PY@Y}tlEڌ#WE{SH;?<нq] _8Kݦx 26 K^lٽ"K199 ,9~o6Ѓw;?)z]t}y-[=?}8t49[O}ۛ=<jBhLgOۼ؍ H4x7^vm͜ ~y,~Xx+uܳsop7=; 뺎a! y6`Cbptcv:m:UJgLzy< TLE]e*btpeQ *#gh]4m9P&q\s8_gUd<گpYN$ML.=dոAn߁ bY|uh+7sC/?,ыFU+R3(]M :#@yt L3?;OXnaPmiO1GzR =OdRL``|sf9u drΊ..wt޴CIh#\_aWHN,҈GO} l[G/]!)rH$T& `i%ue1 v_Gތۥ(k Ⲱlpi3to8L-wuAɹ}ɷ{ʿ*ZB({$SP=i)<-}[ RJIry!mb^eZ_qx'o!=Etкl8֏3ZYJu]x ;yhw-RA N?Ao5l-D/3'y!"gp<29,e_an@#Βsg>3ۋidst Ӯ&7TMdy+C>!daB-Mwgfs&!.4clN*hmbs:.R,|۶kQ:sbH|>ݜ9{zP(ą k޽kνmKcsѲu7M}O"!ڽ@dɌUU$ 3bHus?z,[M /BJ5Cg@mYXԶ|[Ǟ+1JA|6aZ~~/?ǭ+E!q}Vۖ6z,lwV`@ƈVᰬXpKi@lA_c"LJ !?# |Mqg V ^"Bcp" 6 pp$# R6  X>cd` z.^L0 $T&7]6.C'Xڦ7.Ë/sy֖>|[6eK.R\kxSO.*|%!53|WԤEI̞~`6GB\m5>#;̩ȼU)ksO3at' WVԢQgj%XZQuMIY Gz\XVL:OCm`4NoS5MO)uaBF5z4 T %av U5%zIa/(3E2"VYF84y BOO)GG͢JiJfJi4OIC}dmg0Ɗ(w`2L1|T~z{yŗ<~V\hqE'̺ͫ''X`;I~zع-NW}&ךn`[66 <\(. < M\0u/"H!tM(WԳCi#f 1%? (8V=Mti)]M+T! RiS9}e yUῨwj,h,3Ey& rD|,_v.F&9H6Ʀ xcUl[^g.A/YźUl\>AZh*Õ16Sձ,y[j*.:ShNnwu*X Id%Zq9gM58Aö{ ̉'exry< #}Llj[Ď(g2b t͢HVTv 0c;VheL?x\a .?Є@F9k\ _>1ʫ* 1r ?pYU傾#Gxt'ӌVo\FY,F<(8˼~2ɉWQU#Q,ot[Hxe I ٱnضȶVG_]YoXKE؃)y}L,cӚf*ţy(oOz"Á:6oh%}<&8s,)-H]c=>3o\__'1?Uu xf A>'ND>Vl޸ϋ˥w)/K`ղZb09ZT\:yZܵ"^Qu5cks)+@ěxceCy䮇)jS= m*'+!y#¬[[pD>.=„4zM to6 =>]Cmq.! 1y n*6GmލMu7Ι'zKx5׿K{a 2:6%\-YѿX`S{ƫXfUoGwra<Kjj  )ũ-Z]TemoEN19r#^vn(/jmn}n:M(u<˷lM9> kj x4/vُz;+בFx|!ڶB0`Źu=o:9IPԉ+p ߻B`6e788|xm%Ւ:D)vq:?.rGݢAUeT:p"x<~w-|ppp7w`sppp8KrpY\ˏ~>[l6'm0a,rZH$7}nK/Ix:4M&&&BPi266FIIJ!i}(@p-4]Ra@J>lx,F<QLlwsp@Hp:7ܲ6 t^N; 5M~ 6! ;.V⦓Rʢ0iDG*uaN4,sfbx$6#$b 5ӝgn__P+:gpǡ5!ύMqaнCH}|RV$LJܞbϗ] t @*V*tYp2(*`tdU`0ȦMN4\M݈ 6nJj#o~\ Oeۋ̫L@f'#G1J lJ"[DF҈m}TM>!c9>o>YږRضdݺuYp8̖-[# LNBAIH-A)e}^jTLM pF4>e'{|XRl(|etq1nbRڬX/~񋘦- jٍv\ˬӁFC$BV-W3tRMN"۶Ė ml @6iJ-??|\yi\` Jڨ-ٍ1?!Pdo_i k2<_q\IlgxrQ&ʙOR)fL$'-F>?zS梲u 5Nm)н4F:sqoM:1 XUjZ0-,SռjTZ[5*$p!~pkRzYq 7"kVTI2G6s'?$"L kKw[iǶ%55oߕ\hu(g 3g<:&u'O{Rq46آ3upp Ps{ ;8|βdL&M䒟G݂(0\rR244n?gfSK-L?##7b|@ [R`Eq܄aɤ:Xln}>՘y ax<%][׋߷/ZB.MH#nqmVV|F?6;G988q8CQY}DtM˃#M#] `sm1M!rw 르5m$'&,ܺP)up(azG9ܖ!H&' : ms g9T R*RIR4H亯wmBӴ;rHfeYU3ew^ (qʫ65mg]rjgᾱouni`sp@$\ap7pK%6ۖ 6wM͊i=}<{6ɽMQlWmTTٌ93W[Ms7_Z5@H._o{p\465QWY}$]͡~҆kSo>h\:E29IβR}~TM6n_RAzlxUݸh9w(3?o$f[vkv6o;~ǜ? aD;kݽ!uqny:zG0ڤ% `^|. ff$h7^TCfʸ>[B=[gB?U$XUy ב<+}7=?Rsb_ !hQ UsuzK ty;:Nt@7TQ >Cup%$ UQ ͅ0tTbF]sq{n8*!tǟ~=Q6,W՛ƅ /xfbD$( Ku8Y['^bi1'ʠt/X4%qDC^Bŧ0Vf޾dҰw[a) >~gPJݗ83II*}׼1¦+;fն=|>165! zq~YFdryz/֙+8] 7ojRtɇ0)l ӠE.o"(k 28² ǍhlwJ e+# WOH={?ZG" <>ټ jJ YU4Uw봴6 <2?}0.A[*bmąF0J㷿Ȗ*/J]=fx0Ļ|sq3B@r|Ѧ8{:#% EH/];0Z) o\zFLLRkn&8wCYU0фRJlKi)yC.Z3E QHD)ЋKz$,!mT8C~&Mp(H($ nڵ_Sz42Y[.$΂KA>/Jidֺ,V6Y!m(o#mdez@/lc 98!@JIyYg@l$oYEY\8i+ Å.$ue(a`4rhZ޲L,[.\Fq+%QX>eEJژI!b]~KDQ*=Ldx<7OdXt,4m$JM ufE_AQl'''sgbȂάÝ*x  M3=~љٰ=:G7\L% {VPt,tb(LuNW"e !uWqur7,G9ܾܹ&^SݩFqbީt_6G9Cѫ78ުnLunK"ib@ĝp46ے<2XmͲ,"7&%Pw Jѥ8% H&xTܔRx<>sn %%t53tM[(6>* ^ςS/d?Jg.um?ϏwgFQ;G988q8lw`spp?+z%`}sppppj'5ٟt'෿*4@E%tEXtdate:create2017-10-09T14:11:41+02:00\r%tEXtdate:modify2017-10-09T14:04:10+02:00$tEXtSoftwaregnome-screenshot>IENDB`Eqonomize-1.5.3/doc/html/C/figures/filter.png000066400000000000000000001326161416454732000210370ustar00rootroot00000000000000PNG  IHDRʓ cHRMz&u0`:pQ<bKGDjtEXtRaw profile type iptc iptc 34 3842494d04040000000000161c02410007646967694b616d1c02460005352e372e30 b^bIDATxw}9n-DeD%Jrر:_׹I~׹yݛ[r,YIbXPby-S-Oڦ}$I57Q>Qj߳HXQQEQOY; Ξ* i6{3_N2$ɥ$s JU#⊵YHq;.EQEU 9 xqU\bD8 5,fڥTiy43?Ѵ Nr /DeȋMYM$IH&zOq-[_pR?5$.8DXpe%~ XeKBp+b A>1=;xX?`%Al8e-7nw%.6oEhpW/((sچ\I^sTK \A=TMh늅 ;qUTt+Vs lZՂ lhm̈́cRO;zj/\0Ʈwkglش^R8D6A_8auv=i?6m殻k#m*Z +NmR:/,REQE)aᤲ%KhHvS pF $NiGCUMNOd(vH9Y!DyY*R"(`2<.ҡA@yU8tn#'R)ŲI-T 4j,>>}²g~.OtS%EQEQ_kLRu zW~,؉pwxq9x\DjNZ!X$/"'&H%.o+'K!:/D+-{FReZ8>Z)B&A<x撊 I!!ci.8x ۼP(DUYy6I4m Ru!@bnIO^ϱ.Ԃ,fޮNƓXYF*Ɏ;ce<'{/wx΅&.wPy#Շc,]:'[{%с3lk7շk.'=Á'kyO$h]ζphW/eq21zzi\[}?Hm܅eor!c٢6g8qnЂxu,4CWq&F]G뗳(du}In|.M95c:}6Mr r#ʟeRbYz%`#K<AzI8[DR`[c#>PޚU4h +|chlV>i- j}Y2.ǛxG +\z5x xilOSctb&Z>*2o /[BK?a]YyZva.,Jd(%vշSJWKp|XScH ZZy Wzyغv~Qv-ѩm&:q)J's02$h6XLRS+~iZ59qMۺ2x>~?>Z9ՇOJV4rY+_9`,]ٓhʚ*&f.G"5B4kХUR!Jeq%RJ[lϑ6_b3?CˉS 9n^MNՄ3I G0iU`Ͳ)˿[$ƇHFml[bi;Vm΂(]PuPJltB8˲-8+죀@Wp(bˢXfӲ˗(w; hY,;v .`%87baSE`Q1!0b4N`fqq7 TU6-K'´ LK'`I /}8UN%f,b @&tj?eA3)MBa,/2Fp=Kw Qp#KXGU\95E9tow B:ԍ%w'Wgl(((yR#CDcI 9Gypu\)Asоr3f/=;=E,_&*qYVGjhw]~bB{Zecsd yGIgsIc0o@y KZ~U':1F_(Ld"iKLrf\eKx;8ysfr)-\.Gex,A>ob Q Q:Q;oy/v2,QLd,J[gT$N/39yY`&Y$[0Kö  fӴ9Һym-$ Ҿr5c3NN}3iVX"F.5&_ȓL$`9r|.UnG/-u6}=v22-|.K&P0U(( ?m_)t83Ld,eTSyRTnOu+PIKS zQ(Oh.NpUgY[%::^cyxdam4Ux&ǟJqQyBa;qa@m[hnGK p|)I(**C^}g8~rRXOYȇ$1Eh O K@%aK 8w\`&bM P=0,c^Cp;SXL26!+.Lbÿ́]6gp'nilYpIp ͕>F:OrB1X|zׄpʙTB0OüyԄ^Ay*+*p:W !Fطk'4!*q b}\Hj)Lߑ;=H飥J  x9O୨K[peG9u<1ͼh3q=jajp_ål6i|)(1#&mvBYjT%59q(u꺤RlB0>6~؀&.߷e&ϣ.=,*<9(,Vڶ-,'imS39Fqq}A7iUh*}6 Bб-[ t]GUJp/~_,Unn@6o6v1DceRMC5U\G!4 `Yv(vRm2d2ͩ1cmic}m!0 cj?f0- Ba$ebYrϻ^&Q,UUUmͷ((xaP~ILq&9D#OwI˧X'+4\.,",%Cii:et,n?Y73mƺJsjt(&\qQJ4m~m4tCyBt}jYW<QCq_cp>5KiӪEQEQ~ YhH8jTEQExQ$$n:F8z SЊ((pOOM N7nCu((0WLUG_"T>Y-KUZ]}eqm۶?۩((GB1oY fOt:дOfUܔW.(T àyPulhƆ^OeIlO+M((2D"A2v ũUqdͥmvEQEQj8.,8'󾼢((|d.6(YQEQEQJEQEQqoz>|ج(k9fY'(3~zm R\(7aTVTt:^[X,ᠩaWGQĶmzzfx^պyBJ,mmGQn h,x$B}]UJe[xt]W'PEE躎kjBm躁PIQnB.ekUM@fEQjP[ǵYi&95; mVCMhLe[7~j!Є@mFQhLKBbYY،Ķ 6#4Q:JlERgM\[6[^ ȧ'=H"prX tP|/Q${TA!X2i |e45s~3FEx3# ?L֩"河h0BL^X]BN47x+ %-.k$n804Q,6ږQs\{3SDW(Χ`<`I܁ryqB)6 ƶgffh`XV&C\MF #-[u穦29Og}nmJJFNݝm 6)F8v2B]g5T!d Ky2ɬbP3"JhGgج2+y8?es1$7y+˯.p'\J/i:IM t%0H+@~}x^] !8Yq=+t6n7oUW= tm.kXuw7sy_z/mq<Ƕ*~Az'˘Rۤct_/h+=*&XLYX;蚪W>$NZ?e8\pKnXƶ%hwT rX?(8K||7D{1#B !uc\k>LH!vFQnJS5#YIk2Ceۖ^佑*?C;OY,v=U]< sQszo+-FbfQXٻ=XGh ؄X~?|5v{/.#!HE&3Xa[1Z蚆ⵗ$N*=:RHBWNà+)֙e )Z5.vlB5]0t@s y4-yc?w}}0gưl) ae{-.M}DZMԻ'8x8w/m$7P֐I<q- V&u58B:c$XAu/bےPB[zuv4O$q \CZW~?hs{-~VՕE$Rijo)]M_PBq͉>NDLU0* q LU"kFp.(.gL^h9~$~  UpVnnRJ cmcej~=Ev!ukQp"md< ܪu##I8ղjAM<&#Pˢ%Mh4& 1‰Eeqpm3>iqkkuʫsE#Ɩ%)¦1Ɯl]XPQ\`"83 4MCׯN m?X\af9y;v3?W,@vן?z~;lk $'o?[yS*Ox ?>ɫNֳaZ7ͮp[{w!/D:S|3Ar7/_ ў ĥ"S\R yuVS=Xq}Y$|-)Eul~ ~Oy~euҖS(mkpiQbtL}<'IbP2˦ >pC9֬[GLݝ9rP(fK;?|Koso{6/chOPJ7 {;ԯ$qRQ =C1F,aL IT.-:HE]C3$. a){{% _x>9AvC5,o}V7\V1?L12gS & Y.'~h^GcJwoFgFMh7|*ªrBǫA"{dd_uO4< N7^@M@v+*a{M-^{װd^.k`UuN4_UKYz ҆i]{Xp=LAP]@mR!&DKY$:1#vd}3WxnBT]E^`s&޲(ض$g^< VC÷peǁᠶp ,b:|+Vpr|yB'څ|yM>9pi2x!CHtGٺ@㩿~ٮ4e]&i¶=Ip;qM'{vpj xK9rWR_[C !;B>sb)![0%4= 4ڽ|*TlVnzRJ*+I$WIҌK/rݰ17]$HE~"ln'@J)^O&Ύme844phlh BUhF1 \^/*jpt&, ۶TonؕRuw_ [Kczm@,8e,WЩIWth pB>Q=mb ۂT<-BJ|Ṁ_I`W7cnȲ%1tcI$<k-Orwka,%ke-ަy𫿇- ʞ?RRoXbx,3`xS$ !_6#VI)(o.c,#mbF"1# dp9&K2.N5|%Bf{~ӬbKS;D(H;u!\O7Fh:n[WU|>ȃ+ɧ ;/+s\ecizpLon!-G2’kd fx͚?PA7`oɫ?Yֶ76pnwO m4GΞ%6 9ٞBקut1[frxClZPYCe ٌ ecP*O;u:IPXE wضC$ DžDIe)BCqhkWR+PNK{u͏58#VI[X؅=1ɩА'šaxGύ'+MfZ!P "yӞ叔XW(mB- 5q 4X]wp>rNvb]߻zkjP-ti|b7ur4Ӆ+!dHgLt#0Sü,왓8z[1q,Z| }Y$66Ҵy{4<OnYU͐e_>DںUⵟ?CzBK'~'zy홧w~Kc3fS_/MXxc u$g`8X&  Tv]5֔rzhhc`gΜŬXcle}=^|}w%KWǝ7^aխXTc^x=Xbt//?l^ՌBJq>ospvwuQS[CU3k 7j ]]t;G}<W!c^C{xk!#x;D'S d#oWNx7o]]:ϙ1b#]tE6Z.bC;;vwPMEy9Na<<eMO:+kWqBp:8Y^V.]ysqxiYFMGFc1pv>W`%FSIpxTuBmP0xsq<ȯ~1Vyxvx+Yr)t?NuÅ.wP {W5FV`~vQR[)x fe,<2*+;ÁWğ<{w+kS^S'~l>J #7VQ]Ue`gx~\XfT>tFAP L  @1 dY(MM]ak]8ũ _isKf&P La8 WR[(uld: jq rIFF$Ceu^ Ɔ75%PY`eU~2 GB.([Nu3'pdtMuU-mqFF#$3յTmV&awN)mRa2k8aa>x"t| *Co6!>ɋ`pO_ڀcZ L06:CEU5e>nj)dtBK? PWWC=ے]`HZ<eTJѡ1xCԔKs0I52jjtdvgkOP 'd* M3s`!tѱq/y0m;yN{$Թ^1Y8+Z=KVpr"99ٌ^\!uJON"jy'35h*sp<_/@"kY6a.O3^i)%,RJY.kBO?3.ݿxq"8ݴTOkIg-VN^V쬫2dYd6| ԔLD#)bUW͗>>/3Υϣ}GMK*6+`ד<_h&ɝ5u:MЋc|BJlyI)WZUNR|1Yȕ_s󆁫+뚷I6-ttR(=y ΊtQ rѫ|hR"\!, bL+g6\fW̘jq[\G*U+ECID7yרEQFEP< ((J@((rfA2;(_B5ZDŽ͊r_J$'P1ZQn˲m 0TMadbxi&EQ>.}_9$$c (r!OJŲ,GGԄ rpToJ2zUET/ ?Eظج盀:*ܜT|VRj EQEQEF*yVEQEQk6n֠Zh*6+ʭZbJm$I \(7$&%$JzUEAt]'cWOU<d2Y- TnEURH$q88^B@6/ "T}s2<1۶u MAEEVePoNiK4MCuual!,\S (7)4+ʭ~Y4MS((2'n|,c&'FOڜ}(MH1'f3׵9'n`:5Y]|,LJ]ۂ{/~΍ݾTl6mu}@6>]p+Iۚ;g4 fN^s_ڸꐋ/7G55EIr$d- 7 N] mdAӮ|2u˗QWW;`Tys1:3/2b Af_~m|A%Ջ@C ouRO6H?}U q/^ |Ć9 ,D]^ߑy-4UѰI?;>BGG6bHRסav#UTxlz;(o."h,וO*hM8y4`֣i:W=>|cFceZޥ} ʦ g  &.Ř)ڒZgәY/]ƥYh( 6WcتBQn.a&R!xr&328@QKe87Qz vK%'IQ;Pȍ[d>P(Lkc%aPQ={dR2:6D4&4,_gͳ S^^F0p81 2rǥdHgw (9ۅߧcQfNE$c_H  r")B*B$'ylG 'nr zhokaD'BrTWWxgi qpfZ\()4(]ZZiִl2T)c|da&Y,3ã$s,[ ؤQFGF-?D#lj&Hbd'zxW?x4]?@(sN#I\>#ΐ )"<^]A<@>#yLJRqR Rp9 Dq ,( $@e,eal8')55R[S]? e lPټ|7unYVR9Zu=u|!($G~WY(q-^~seh'8ug$[UЎ!.!ǎ%0>K_DtǞB2XNͯN۾WsWxz7ʙ1[PtEHTdCb|AYu~L6|$pˤN` yJ$r4t:O^dØlz]&¶LLDz=TWUi5 ŨNBkWY iQt#G{^ȃRf<Ċ9;F@`e줫<{Ͱ _'hsƏd×߹wty=*ڍ$O3'oeO-]Gh<8ܽ~)!gC1$ҝN+o$];Fzew{ 9_#BZE3bx`,ch0􄨭+63d O];邉d RMЌ2t]$f:dr9 @CLe.Pә LZ<7ny][GpAJZ&iϚ;IDM M8sH!ɛNGNc+9#GHiEV"ӷ-X<,D镵qC|+_;PwnG>{|G9r>ͪrJ/OC]-矱Mߡ_AjQ W:qiioe~{ ڛEBL7alYH*˲,{F]'0) sFѷmӴ(SIʼn6j C7pmȺ*zVnv9EFj l*KLiDԭ/>c{nW<yljx&OU|Kzz\* 9ȗ aDn~CvlCXZ(r%L*A:gbD#36#3AЅfz1xlF-a4e[^[_qvbnjQ/JC#i8:S뺆:; ~XUE[x`}:2Uh,G74licZHW|}Z(Lhryl)-+_,MoSz=-a%Vn]®OS [jT-M{̑QW֧aKX8o#$#~I\M膁ah膁@5Z~3ݴ8:K !n4'%|sfYC@ W\D*K6%QltKĴ@]8KIaNnZ=dr:q8ض`^\2- C@7d=l}yDQ@phX&oZ $L{pt7)f렍FMܹ#gfX('LlZ6dbcDqbCpSVUii`4kOK]elzxL!QQnB௨@% 4WtkdЏ K*]/Y kxA\l$c%vO$ȗ8rhB~Ntb)dx<ˇvbs:x2S>\6E`bIټˮ< M8膆iL M xs$u,hk"X@x2>K`<ܚɟyYhMQJp^& ӚpQg x'$)pk_R~2ξ,G2ɯ@iiKG2$;@]C#t5u46S[@ B21lۉ6|i qҤ@`KLV pz\|>d]/leAkdLDg`ӴL{?P|\q''d"ōvλ̞L$F?Ҳ,|$̔&C1 * aYL@aJ,f!7mS޾ײ'{nS}w''z,.V4A9YsxQ垵M {bT4/VYpyXV{!1p׎ gEI5 ș&f$#'oK28YTрhNc4MUu9d&Ovh<[GwX4TTWeXd lfphL&d2 o\ͳIK#=wNa8cVUnl²,r>N"`|Dy>Mm|"ϼ?xazpW;Ȝ|q˞Cv%_pj ÝG8le߾C(q6LO{[8B،wWv=_D}ypEQ0Xs睴tN֎p~[ ; `VjFՕ.5֬\N#MÜ8?B Vګ>Ƒ=X -YDmE ) :ΞBWwhi&8}=8OHfm[%ÅۙSGrS铜?v|B-n?Kber(׏#HDc$)4G0"D4N2w⬰VX4a/݁&OHe,5uTpyhD"E5'†q{ 'RR_[3϶m 3 b"eY(MMb4~N=GyYgoS[z$)2ضDwp9 `&iBra'.F!7Yhv9Ѱf[te_lPЊtBXBt4PPE>Ô`=Ygypv9"_ΫN) H,#:I˲;b-,[]*1Բ=5]|8icZ,]ׯsLMMPhsB8>!8O__qV1|>+W,1MdLq̡#XfbU +`K:N CB>G˅&Ma 2Z{TEX~@}*\nEQ_8{&VQEQŜ U(((G*yVEQEQk繦(ܤTɌZ79&ͭ(۶Kö(W"(ʭ W |$.$јꀩ( )KɑnFt|r͊riE*yca mպ( 4nb ,{WEQɶD%7Ts(tű?|MQEQEQJEQEQ{T[bz%.yI)d2^EQn>߯X"$Lj(rA(HH*yCBb8x>uU[e[ bYpxWGT*^M GERiҙ uƕS˞Q7oL:륺JU[td*T.C jUlV[d2IwOVuՌpY>o1RJlB @Y E1Ri߿Jnj&6SBJաWҏs2\u|C.! F" L$D]~<|VgiId4 #͹*EQfsX\zm,*%iYivlAzjGJIbqi8y{M_M_Zh{<J-Ҋ4ן< unFHp)ndTzU_%&+'pf׻lݰS-pqut.HeR@WS*ͦXfuB@65=մ+gh$n#E-R;@X:*6uҝW<Шج(7_N˳\KX^zh!!MFO55I~rv -%_KV=g?N"NYIO9%X^llFip;P+kd!%vS?mH$(7YB{W SʦjLC дbi)mlX>0bG1YV''_'Kwſk(]Utk-,[^\)N1\ӊ[3֭xX!mo&Gqm*ns%.ZŶ5!:MW6 MlChV?%hwJ d\&{>(25%ל<  d̛8C1[:lbý\BjYڈ)>t9qx uYctpHFoHЭ12<'0)i `:-XHcHpi"6틗XGDn dv3#!>2ݧyܳ6u/]DOKUkz=~"%rRAz" ?^]0ݒ xjh/L?D:o445VI+y͇ݽC ֳt0ImlB {MRFkm9 34yili6A+b|wi@e ?6P5Ut i9imǫ褫?A⥴Մ"d"o 0ym4U1~F _0]ZG_=ȳϽ>~Ѱ4F[[ӜcӜ9bqӻ^ep_b=n5+)3CkakrO#ts8Mc??(i IsŖx itNy1F,Y -Op jCdȳ+4ZX1 ,MSp,MoWH˅!c|0w.܆_HSY{x_Һ%Uن B2,oƒ%,C>0ym?kN%S넮1r9Fh6Ȏkɑ&R9qhp9G(+b}FOY eY#ٽ/_o'`ᯜNJ%| |n A`c#5h `oyU!ǃ[SmkS+.ۇCDq 9/6p+,GQ0t6l;^gݺ55Yzu-`}|ѥ`**io:i}Ӵ5ry ~bY lE9?CYY9&d BN[ߪxb %&%(vǵeek:'wl/~ KjUנ;o+0i jbxc ]J5b_Iu3^uu /dݪj~v`/GH@*#y4#8paȘJKM01**aM-~dcfTћrѭy r,)[^lix>y[" *'g{߰ xy~CϣĖoE몛LX"1m6i-Id\Z$yKά&JJTWE0b4 [QzHUZu΃uL!կl&dW&rsI`eO-4ج(7΂A^}u|^>p?u5 qmy})%`=K\lqSMNCԭxrV:8kN1Ll/bwN ҌOnG0tt4- ő4i2]u@!7}Yo#^ɗ> d1b$qŝ$bm, Aԩ IIW}f t].s+CnIKK\ 5՜}\!O2'J'(X6LXsmzs/ɹ86{йu&ν o{Ġ1~kw{;p&O2!11si8DD&&O'b 6csh/?5ϽA^h0$9p׶#_(XҠj>o;K*W HL3&MH$Hs*V9RUUI8,.iwޏdif C8hhcԸ twOJWoeFB5T:!MR޺LIUS ua*M245SSU͢KiiDF'*VZAcNx7ٱc;xe^z}C[Nz=laϯB+<}mWS_ʇ5݅eE-mۉ (g٪eT( H׃L#{қhn?Mx1c]N{5~F/t1a;q45Ԑ8CPOu}!jP9rh,0fZ! lOGGwP!l9E8x\jq_@za6,Eu+#S܌ϞnrZy5mu!ƻImj2螖T֢$ ׬gQSxL}S+ GRsE^,eqsDXΠ}VrzhY2.z[y{h _QKCсa0 /6LUmU!H/#D +TChd,@Xba8}=ΎN/ :RJ2#s6e5eLk!ř(+@YuTpV|@<0f2Oy;w߱m~bm7_'8eO8y;o\14MiK*++g^r OK8Y>PV6%MSSϋɘuY29yY</|jj+Əb}gONrr/_qqg\|%h獏Gb4_g.c6d'sQΊr3BJct:8 9= j=k`$Q&֝f/w$l3 M9Xx=o`yfzg+\ZU{Ubڕ덃}^t_=_?sSyud׳-_YJiYQnRJ^<8LCȂ0k('όb,LMz];LspyŃ_\S)&'|EP?TYQnBjnY"<_E{]^~kinlu5khXH V4: En~(ʭbop gK(Lha>rsn*~7?!f nbӥOC{4MKmW@Q9~7QձR[ǵޯkg壧 i(۶m{۲fl('S4).,Z?~(_FW@J0zs*x=$N!%ea'@%sHJ磱T*j}VORE Qf19zcC=d[J?+' ]p8Z<1!@@DEQn2>7׫(MF<+((5Rɳ((\#UqEqfEQn,Qn^j4E\˸*y Zt'YTQn%aP݄obLT*fU[ J.D84B(tZC&6Tj(ᛋl6K4hEEdYl[:F͚ٲh7GO'1u`aSz鳰 tpޚlܰ*l| SdmVʇpw4{ lw F'm_ɂ dcC;C$ +<,Zy^o,:.](WIb-Fb^ r:G-Vl^μ7^WmoֈVqw@8TWBsÇ~|yiS^kWvո2i'_l]C8plZRMwxco2F_ sa{gpz8>~^/y#L~v YSEȇ5phƴ Lt}^L*԰aK5^qP'6^{-R oo7cS״i}&K?ȪtLtv~zLt_ W#Yj-n"O]1PG]֭m%vp1nCvqs3GYk=oxKX|Yv6-E䗐;³He7w$#%\d 6kزIY`Z.|9 x-a|lQ{YH73~9>ʻ9~ϳfѐ8 o]4xMu,ل9)KҒT/XfY9i]zBfLtb*\eĞ_o$M)I@?I%ٲexJp*ʥ$BgeAX$ng͢ 8–||I`o%mZ'G_l*Z6*;+vӶT2 :6m.ңaG"$|q ų*r ȓᥦa |mSaHIһۚ9I0ɎQ6=DTk7;H(DH 0 tr:d݆;iX[h۲X384 dx9[h{8ģKq8\N\.9(ĭp}z۬+8(+s\[r(%"P΂r/H"X|);5*a~&ԁ!wkؖ1mƋ9{qB.lF 0̩=}?fZpq!P^Чju@ 2ƙ=Vܷj&y߻⫿56.V-Zr)A{Gu\޿zsy3L` RDe֟z^{wφimV0%ٖ,KV )Ib s<ݯ{= DF3[Uuo%@ 7G]6 F13)L%Vq|/ý#D'UGp&^6Ks+1)l9 /O(}{~8w/5*daC7vquc}Nc00t0:x?~_<7_8@Z3 b cRZ[^:C1;5\X$ygw4U@[mO=Ş1"$#R,Gz(i6"9ق@9jV9-U[Ji)Զz(JfN|j se%Q@Wyvyℝw}_e92@0 d Q~!(=_Oko[ NeQTpvm3楺} 1sLK31իH}vd062NV7Ks=Zl[r +70pE\qRQΜKRn+?Ɠ9t(򘓅Q~缋Rp`44]/E?rGٴiw(Gmsax_䕟>Ñ4H&9DXkQc="}Fjz}y襰䢆 O?ׅN>' \tg9^DR:=GoO7GcqnyenODZ*}e%\Am؋&Ls"dUT$ϝgt;MJkE>qC΁ R8QCיX~Օ5Ԅ$'&:#V>u-ԁr{իh'FxwƵ]ٸjmʭ*tmTsj*8Gn 浑KΠkXL$  Pѵv6T 6uk*JILڶUlXHhM7DsċdŚul%Z:34fQ"~7IhkU"aVYǪZ0˺ظC%IHgJW_-RƳкr˚aba/ꡡhF6nmTVR P̄̎'AukWP հrZڪay9ڨ T7njjB.fV^MCXyg bsU\{!,^1 =Ģ)4IR!_Wp:oyXXQ,7UHVT̅Cra#)KgcvV͎?e.Bo?;Fy*< uY b]myyl_od$E%5  !Li_l !fLLNQW[{6$c|qHib撟K\/V);i`,B&BI\t1%/e)}dpZZ̭2&IDATu^JL%0K6Djs3-,>Hꯅc97C~…W̰Kضr0y'0:6NF3M-qnXX\73ǷeOJi? xb.䑛:(2RY\[Zol&nDG񲰰xW,)_r2ye3N'xbI7 A"\3泰x'g2-,*|4"&= @%n!:ɤQ rz)\ȡY#8vrSSS(bXX|Hg2]+^g!5aC̿űx Rm{?"vc&3$lat 2c*7Ǭ( 2|>|>{] w kIwb)n8 laaaaaaaaaqXnWa7KU4x"33 &1mR\HEPq-H)^!H26>p\:x,pܰ7N^rKB\=2o=ܠS >Ko-iޞ~vBF]caaq )@c=TCDB`|M9!H|.qCOhϡ뿋yM-I!xB "vVdeѯ8\31u2 .*7ʔwNg z>OAJ^xEA)Օdj(ɗ]_!O*ze0/'Eo6=͉7^௟.;{5 FN⟾<:;DJJA-F>_}_8yHo! =Ͽ$nu |!Scx|ޕqFw{IF}'8?.oYXX\,Jvٛj ~'rhC}S)ܜu%ޒۆ"`f."\ r3>3-[.Qa7Io^H|fz͌mM+bBl662͹oiOM Gr`^r 7~Ѻ15BAKgh{˨]Ѵeo$t.z )n{'Q}V)LΤ{فÅ";ƛunB\BP,)WNr^c}ev&⡐a"a9쯪E^bo/Wn!MFzk݈xz7M?|rOQ(m\Fiaa9Ӂ饲f*j N?0BUUR[S,v%TՒ;_}4lhi Î0X%ce']=ږU:sA.#LNN蒢tP9ZJ+߻-'lINqw)Cֳ(9c)%6O孄-vd2yn;Zl%[n^^^}Y~.:~=x.YoB?e2RU)LL&M^sWJIQ9Dqb1.B7r˓ 1)%f/b , Bi.Vs[(r\tD"ɉ'xVUjj.064MJ\|.,yf EJqqge#6\or!$'Hhz3/,#ʏJ՗WK( Cܿv%gj0Rl‘npu UUä҃Pg)6̏{$_cy0%ƽxq@͎٭?WY4}zc{̏[Yb40.|gnNZܯ.09Yay9U#QRF|[XX"Ǔ]ƏSUD|=*a`Y$VY7`yaNJHߕKϱKW5;^d*gz'GgL~muVTڙ)2/6;rs.7ٙ)"`X؇¼L9 0b[N$ɚvlN eOjH .2dn=W\)];~$ 4u8M(#GqeKi YTt]Gڝ\v )FƦхp1:6aRUUס 4L^" |NbaI\:E* V%L#D]m[Ɋ@LN%LS|a(![(b**"mt]z1K;>EƳ,6/ 2>KB^`&9Ua)&Y<EMM39DBTłzKřI E9ouZny[:kV_# ҩ ؜bxSYa䘜"U0WTRwT(to8F$BO;3*|"DS#>9M2H1ߏ LO(J4乪ŢN0v_m?qsJjvNҤP( QdsL5 H%! tx` _S{ci8̤&Вcz#<~ o2~z'O>|jClOV 6A!q];R|\0wCEn*7Գ?HF9v uÛ ^^a2K=)i3L]Q9{S`7j>{;}ϒH6p۽ 8ߊFWj[ˊJ92P`=[YY-8ϡ9:#|gzdLuZyzf3Ժ 7džLL$=D/B1C5|MM+j{U-3kHV"4bJ"C/4r(}gz|ݖl {l ~EcgƲ0\6ȃ=Hϳ PLYq? ia>䚆`Ͼab+Q\"q]fޣ`#ZG،WF{n_{G3 ^< Y[ihjW蚌gE@o b$s:Y} qc:B6٠q{Pr#Hne7kxSlZ~n~= ww!rq->x'8>܊xzu[>[6W {yv'o'nj3TD. Vfi1Ȱş?>w/U^n7_6M=ս?+zU 0zFBwa*(F}}$~N[>c|>tϮeU'Os^ڶ~OV0׎#F)^zy/$*("-<^(ERq$C6oM/o~^7/,{x?@k ϟ{;G>ʲQ:VPu61>;zM t뿶Marcx7h1^YGYYGvw06VS8\r  GytN ~Y%n ?z:SYv'~LII 7-VRރ][Yi-W4$?N0}GÏqK{33[/`fӨ7VȚe-&MNz=sMU5޳tF-3?}cp]kh9=,i [C1/qzzeN {no}/a 8I6r BU)L'O=QV`1'nێ?y[J k qU.B`/8m69/Θd,[Nģ'8{4wB9SUp6R:͋B;MKl/HG.)h PC @$b;YYH<.LF(X* LWҊW‚*l6m|fQ;u)4tdE!7n{ln M}z\> iJ~faIӗlDG2{!j=01>JnOC~my ̙!^~GRT0LI%VmՆΆ eYɹ2!vPvv=43蝞۾9< GɛGIK`jT.AȜ?\ ewC9/1|XQ( mrhϋ;9;nUK!bzt0׾x),U N!@˃'TQuΊIfgJF4\&V4;&KjY? ܁64) 9si4Y]J_`J|MqS/?~|%Հwev*kj 4FsӤGS癦D>}'s ua 4ɾ ϋSCWnĉ# O'9?punrLeH 2{w0L [$a7&a׾x ݅oAJ{/| /586;xs+WYxNNb.8=z-ыFi~\xƽX J34vǍD*3&g;6Y}0Ѝ_g \icT6E)#Re/ixs0ϙiB%PQZaB)hkwLLrw39~$AoW_T(/hwB0`brƳ|@.'XR"5ݜBjD=C7=YLLa` &uTUA| hV ˢ`JIAK f)&KpT/Ym\5ࡺȉ{vz. ߵvR`^F2G Zm)/F ߥ׬deT]D#݇stSQQ欄k ;Qsv3|i\ΪzyHs7poByeZ'2% d`I$(d7?C?k&J(ZCq8CQ~H.](: E Y."͒ q O`B̛ pbD\Cl۾,V}rs]o!)( S-ӘS>s|? Hli. R$5퇆1ɒ0dfxNٵ֚J %b#XÙ;˻ϐ7ʑE"Tݴ-_P#1Zo'h;0~ZkBhƓc6>E!6M\M)OdQQǫ(r@PYq?\S-!0?1^fpF+EE(h>^}|q>isS 1e; /={t4Ui>l2ɫ4zqMnF=IO8p*7' -F;`0B04ESb&BQt$*Qih`D 2ywnmWo%`k)A&|MsK} 4 1s=4d>&;8\~TYps˽_ߐOQ7n#ZYQϭΝG&$WPhtЧ% dIhh{o⯟_oc F:j]mU0|u╫Ykxl%ZwW^EVO20P"KwIJ MsGFi ':XYgf:G}]O2PI|<$GhD\?5-];oj?6#OSչZ,? |7U*J i U?>]Ok{`58tλVK};%W )R ZbjV­ww5Z$Z7s,UnheM2Fد,,,~RPy;E~wm|CwQW]zg݊k EbmѾ|&&ykWVs,CLQ@K&d[@AHyqVO]l`0!(ȓ VR1EV{5B.ly|.݌p8 uxctև=Gzɪ*5Mm4ұ̩3eZVtQ_ؙ=>ԝԷPDĉRZ<A0ZGUehu#MQ83T++Umi9jc CSY5-t.)p`SUl60I3tiZz4n{|L2s{vm^F썬)s0g]G"7@w9b+X/g8=8+Ě2Ł=o?^OdVSs"oSǏ3Fny -!?۷ep=DںXVef!2@UD1z'.!H&!BSc3+W6cOpd7qͲUi 2ũ3dP[_K=; D1é{988eY jj7wf4jEAؽ4.k2vA}*=EyMTF*pqچf;:Y`,gpDYՁg x E=Ⱦc}躛f*KƊ066\/i=}475v{|ݯ|ZC'97飇v8=IN=w9`j޾a Vwuzu=Ωϫ좣>B|(B˫T5P[ TQI8S}dj|JXPErE{hh‚g97uxŽeCl7sTLΞ8xZRUWOQSUI[#>LdyF&4oۺpeyg'OvלbyK A`#UWE[c5 ?0gzΣ467by'Q5MNb8 l響s/--6X/?pW&ٺGa(;&U(UF8 FN#l.ڨ1͙}$ۗZ[659{GZ>t*W_-,,}ɩiU-Y݉_&?sO?0JEnXEĩq^@qili"VYKG[0gF!:Q rH0ZӲ|⧱6=t ĪbxbH2$\`f9~?">Xt|> frEˑ2m8ӔhE !sɄW+("$QN0(1룩-Vik)H (tm&QJQle6vFr,J"DٗUUQwR200H |@ d(?0JB]4K6vtD( ,KJՆ*% U)ØM!M3 Cǔ6DB LKʳ_d&BQQ+ KA<>Gp:b'*֯])Kub>l IY٩*,W MrST\yn/ K0@e,Va\()y\xV'5KƬ \bC/u)Z^Aԍ>Ǖi KQ.f#`|bNv.rP(r9Yv c^ Em`doˣ J㹜,fSKsҸ7R_C^n%SNsQ_7 }+,Йf,rl6_~Q7 wG e1;J)GL-^NU؋0uOSܟ(%a2tKu=R{iH,E{.RY9l\ʰx0M3ghlhtKPJU!l:żhT.kWג=\#迅dк&A-,,.j< 2+x5[΃:w /tYnnr5ђ{U8Rβѱr*6nB}uA8J ~GmXXXXX#k'~)4'^M!W,,,n8We<[XXX|R\#EYeAĵg ,rJ>jjievei/zu P.ux,B" sZQ"p)e,DnEyGPۍnulaaaaaaaaqETU%xϹc`We<[XXXXXXXXX\%laaaaaaaaaqXƳUbWe<[XXXXXXXXX\%?g_eXIfII* V  d1pi~digiKam-5.7.0filter.pngdigiKam-5.7.0i9q%tEXtdate:create2017-10-09T14:55:23+02:00m%tEXtdate:modify2017-10-09T14:55:23+02:00&tEXtexif:DocumentNamefilter.pngvrtEXtexif:ExifImageLength272d=tEXtexif:ExifImageWidth1027ܰ/tEXtexif:ExifOffset126F<tEXtexif:ImageLength272ސ`tEXtexif:ImageWidth1027D+tEXtexif:SoftwaredigiKam-5.7.0yEBtEXtSoftwaredigiKam 5.7.0 ( libpng version 1.6.32 - August 24, 2017 )tEXtunknowndigiKam-5.7.0IENDB`Eqonomize-1.5.3/doc/html/C/figures/importcsv.png000066400000000000000000001542561416454732000216040ustar00rootroot00000000000000PNG  IHDR!^gAMA a cHRMz&u0`:pQ<bKGDIDATxw|\}νwJ$N%JlIdȲcDZdS6>n}v_ɖdc'XR{'A@ށ 0{?A(6e_/H̽V9s((((s˿+/D;_(s8|Ol2 XwzEQE RR{Ӹ{((ƫB{C{((o&((rG DQEQ;B!(*Q% qe)(*Ӥ;Hi Q( };7QcWhBi[X>@d:Rn≇6s1ZJ˴>RiB.W^Hic6&w\nFlCuA2f M"M'v:җlב(|A@A;H@3D2^]+*I0~ӫvwy{p뤨f-NiUr}@bF>+W.'G2B`Etw04:Ƅ?N 5#b27Ye0D]S?zb:מc8TV6,W?(/`k9K%:ɳ;Yz# Z? |pRR>g_6+"Gbv YɎ;wN0g1:dQ"ac,6XPA?/0VMvr2`}.f,o%1Zh?UD'FV*ۼ] B60PJJ$?; ޼lғ4(ʯ_9F"Y|oi8j?ds*e Eq– Bh~}݄@9ENbR_3?3Ҽ;V.a;}5 DVF')Yl~+Lb?|$јE|Dޏ! |`oΓ uA40?!#DB 6kVP إS_sj *87T)psiFnI9I n$: ^HC׍/Y&HA Ėih-g3[bGJiYrYBCh߯-or5 ]̍rD|{3 % !y:6BʳtLk&'R`ϓ+3w_J|m#hڕl~9ێrne5i^7@$z8Ntr+RJlȫ/fϻmǿ7})Vu.t\}~oHZyC8ֲdq)I'-IH/b&GvkMWxhȨo?s{&]IImϜG\!`>{FHyy{^Qłi#<4\oc^~:!(v..$%7B e2ÙHFf&)^fbtqpT.0x?*ڛ.b h Hr - |At<=MH OG1\RRggF&p%e1<8T͝HVVInW|(o_&D"\IdmiD}c3i>֤^^~c }S,y?9s'8/0 ZO<9>uw :}K$/{KA/u1M | 񎳼滴Ep;a:0>HH+@k=pO!/ɘ SíٹSM}Q|Hg" l K<»t,` ??qՆI :9BySYwNZv.@8<Ǝ ST\P`hv=A$--Kl߶L/CMHk[6{,8Rs]u7_xa*otEQn[MK3{_w5rFlF2B"Cɶe2^yEΝ? Vy rjϼ} MUU.^SM}i/U NEk~Fʟؾ8Ӽx!t&mra&j6nӟ/t3;_xŋybM1L 4o5yDF;s4mz*1 |wIJ<H$˫Sq{^ Q rvӯ%K}>@Ou4\)j "x JM҅,]yumzegZş߂Wܠ[>i$b=_8`-!W 7r3/|E>ϫϿLxoj#r, rd=g=;/oQ&S3x7y?`rt<-tJmeC)dsߣq?l\JV#L+wQKg"oO~ F0ٞ[!#?,)po2aR,O$w?7'E6/!|xS*`ʴ(s,)%r|nŝRŗ}kl=Ȏud>'lߺX5\>Ӭw,FD4 *ů>BS'ۀ^>G( R]LOrP8^µZ[ē``/{n{Ra/8Hh!R9ᷞ~O$ )*b,dc&%;R*V<_e䮝yijah'wޢibCo2y~)=-#w|A׾ s{/Ko:S4韎"dçi{? B Cy5 SyW GpQ?` ε~%^}7c%ٰE.rEf8AH {smpIz{&N;阌R<~! .>H=u:s'7Ptl9ٶ鬺q ks/G72J#WWW@=ܝ%AI.*0#Dži4g9ye${$enWZIYN 蝸l'nIXmOBduy! pqGcH ۅEJ]{rf4XWXmuƝZLJM$wOŦ*8xSpU2AT {:yMrEQWܼU3Ɂ?xY%)?:Hɳtp&>spnBn\/ƝY4}軴6;NeDm>GkG]X9G|CtOĐRgr:|7}e7,&ƆHJt-Z&)0R (i:Bg.+mAnFyC=L]=䷜a2m!+vqyMKPsz& 0ŚaҖ'pOPb[ļ́N4R+S\ן7504=$U]<κ|؄&#׭/tL| al;7n.ŒNb%!HJp]YJJIidDL%>t eU (\c `+?gL̦ LJm?Lb]gG|v 2u|G`i:6?o ݔr^=tǿiƢt_HX2w!%ʺCĴ#s֕mYO[:{ݓ͆{7LptRb5^&FMGwh8xɸLMq} 4mŜ:)MH} O# ȯZo}l\-%i(no"7>BS[?UۉÝ@B :5Ekc+[^ B6{>2~<;`$zU/msGӽ*P!r#v}/ 'ly(LBșoaf$$zG,_FK'26ؔD!F|/},Ř|{'Dtۤ^?piKut]#󇐚@35ӎ?glk@ KRёC\!$q|1lIEIykj?gsQ$P8MeÊVɹ Idz!tK5H/4 8Η_|躎&,Uh8Ay%$eRQfI23JK%+7~v;&@7u] .Ĵ\ Jpl#J|?u]#&UL~f&0i9G/g8S )XjumBJjI:-^BFb E ŵ']lN| TE}n[ĶW9&ěa1Qc,IƆ#&bjQRƚ)ˎ\Cb|KÖkGyGlI,]lC' ] @LMF R288D g˃P3޳w;^H]nҼ@puX$9SHt ױ}"F9<h<}joLvB<_@3^abx!<[!j~ƌ lIĴ.ĕQ̦kr[OɭeAw& M#01IwԐ)H%|$kܻe1 "ʥoM~{=q^=55Pͻg [Gаo9{Te{I+]MH4LN?7p v2Ͽue<%֙Z=[S {3ϿťFF9o[G 2s&{W_|$)5 Lz9[=L ,; K qK8: I?Ő|5ؖ6&ć}/O$WҺ}(K1W[g~>H`G{ SWJQN:^'qZC 8$ 3I$2RC I:[if|_ `?v:.NfLD-<TTu019=%$EYP9›/Mmw^˧I6T"77>@OM=T^&BؔVTQUQJ ~:G:_hR8eke$88qZ tٔV睝GM#47%5 )HKMWtNZ: 4˛{`W'֔6Kl**Kra Nư\,(%73BO!&h;wd(%f 3(*&$$A3>YZr%Bz>NN`G wxc_%<կmI饰 h/c>[8s<vvf\p"Ҝix(,%6Gߨ6ΜB>7SS#{x QKUʢ d('ergQw"-,܆b-}LN q9_home9nM|#7_|<&γ{~FXd*(IItA8=\'8['wؾ0upp{4% rK*mi?;N1bx(YXI~j"ƇaYQM{,IÖ.#lн,^mh<=kJ4pYa6-?  BF95OY[|1-uY~>sk3:ŗz;ן{F]{n5l9z>=(rcr u}I.ÉZey݇F78|ͷM~of+|xB4]cRu|% ,aKn.Eum=s EQn_8!lj.N}Y|7rgb+p^( DE g^ ?$;\E43 n(ʯ`eʯ˩#u۷*M^T &ǚ0 H/?c^{QEjBO_nO[?Bᡴz-_X>3Te۸Sͧ(N=_ϢLfz?p&SU+ xmPOQE&e}Rؖ?EQ먜EQEQ((rG DQEQ;B!(*QEQPA((w BEQE#>h6;:j:OEQEغmA >"f̎a&3?7JFpzMaGMSE^1p(Z-A1Ʌqv$-I)Nr ~EIFVygl9["ӣ9?Ȅ?Dnr*EQEQ>.n9Xf_ ta zm[, Y'ILM'#=KYI1yD)y.'RbE"r1+b-gNe2S̻sxyR9'{+%Ws6y:7,KQEQL$b,LiIq9:!e{ D.?\Jlic7C'3$Q|,EZjnC;$$A DCSLX6xIpYQ" K'IRHJpL\ O0HLNB`FLØęD 7 j;1dN_gEQEȹ D&]F>k}bk] Q%bM3:< hr3> M@ˠo|!Poo2?}|7i[42W=L1~: X.o~l_OWǎsp= V͓R*c;_C "sioFK.⋏nbA>Ӄ&$ y˷~ħX_jQEQkRMiKFKR ^imtOKihr7.c-d9, !].HQlO=ɿ},,H'}-6=K'yn>((n)qrJ6[rtbvL=Bej$YykS 3i!?AS" Ӭ(yLYszrAfhXr6yY餤᜺Db[Lk'p/yH"!>#2AE,#b n'1Qa(\햚c`qΩq uRaNEHamƧ 6^aRh\#-h$L(n7RDwܻ'm,m yvU"" %#w_L˧t IϾS DEQ; J&[ zZZ }APCEQEqǂ[Š U3g;K%MQEQ;@ѫPEQW[u((ǚ BEQE#T((qGsBkBHlƶmՍUQEQ~ dpB+7cֲlQ95(|ݖ DA4c`p Azz*E$''`M[h/j M (!PLrsHJN"12:ʹTTvna[HAn&| spj7EQEMpKAp8Bcc3)ilK^^>@~~5%șgb6,3- 4;F8EjJjױGQEQo7f# $aK7MFFGIHva~YPQNzz:_$<  aK%)у # )ɸt`N$9ɋCf@PLIL&) R" b٠;$'%ML26ќRѬ>L d*Ԕ$\cLEm\ $y]`[LM$99 UQEQ.{x<-57nK 8233r\ܺ˃suR̼zH׹e/h!weEQEqr&4̌ 2gė{gu4Nq⢏* 9ͩ]yTu*w4lϟɗ*'S+bajXvEQE% DDc455"'7X,8gX쬬W6Zy$, 3@]lJ`ٚO$1_Asct\dڹC"- C((/-!hK86_!RRR\(mmm kN "$lmضD7\ 3f'Q(۶B`[RtM׾hvH6R 6e0tM*uM,4]C4lkIX4JLjXOSt ]CJ?F!m )2_hjEQE-!BB^]בR^|M,d\.M2MR*L\מڈ9n]y~`#Yup9Ü?[Oͪmq dS[ CĒ*xUȾFhx=CUs?#4$cj^G*DQEQqK i?@A~>p ᑑ.[{YRAIA:S'ye9ҪVqq ~S>4M[?=' {ظnʜgpI˺ӗXQEQ>n&IJ,)7*tp87]fR]SIi.Ȗb/RJ{XŅLdT0M&y  5,_ [ OwrAKe* MCn<.$33HwځF2j4/ d?SftPSjVp\,f#w6Sȃ@Ղ((|n9RAb^&2hZml[Z\]Gв箂 4]! Bö-IlQRw¡&BL*l ĝ]FubS[[KMiM"%ہmlأ+߿.GP9!(2[ Bt]I`rrM(!hi nrx B2~?IbJ* bvzA?C._y49Dw rE1{&ƴ+˹#J0Yo[N'oc,$$*(2떂0͡4oeIۄd&6⃺jEQ_w<">u?7fz>6}I$ô;^̷c6Xr>!)3EQ~un`eׯ<s>?F'I ˉc!HfQy^Ps|+?G;D>ii~p|x2;A$= RHMI ϛGQ_LLL?04trssp87XC}r{4Lc4<(59aiT%m!l]}$B|Of<:Uwa)fݙ@vvG}jù.LN'=~ ײ6GQXťVGHKK%#=v}pQPQEIA*v}' Pt7Epq9 HO i-;:AӅ~J7>D;Z "ӈI,\?? BI^ @JAZ~%EM4]'weB5(rn9'rXn Kjk(gaUk׬Kϳl mc&1K# "Ҿ2sm{~9o^ۄt~31ZG̓d:OoY&tCp,>y_{ogB#8D,[g{q| zyQ!$."֜5 qc_⃯lO,(JgtD-EQn-Մ!d8@4M4illf͚U7nc84&FE%^:KJGKo]^{Suxs 9u -{@Q;Ii<\RWjj7Bɢl9Bul߲4,G $k7< N@ XL/ \\c'pUl[Uq'e'O4$YAVeYQFzZoj'kvJ7%i.;"mXh_=$A5M*crbVesiܙ\^ES&G%ڻZ{7Ւl،tpecZ:y,,ĭ׻x ~B1/n$;s?:5ǟB\"#9xs(n&4Mz(,t[\NNB_xgO==iE Y^HK9ǂHYĺ5tGi;=քw蟶L?'y=] 1 O vP5IvE56<}^?ۏUke`(MC-X7^ɷk' 5Z[V6cWջ Q@sZc.F"26ȡ]82KYRMg aNsWf]lټPFb4?kMc׋?/BoTFxA4MÜdΝt[l~]UNhp7f.f˖-(vΏg70?!/})j |[cm83K)O?Mtfpcۋ3KO?ٮ zʑnj6ncSM.V,-55TOD0m'_l泴og2aiCoa 7g9<͟| ް:-~*KMﱯGY\yw ܩfdT΃O|YGrnKi.$CedCMZV9%p]׋p&`Lsϰ_}~X&﹟{֔154Tda? 9l{ Kty|o1ۤ[[`=$ 3ƓKaR 95<'xNxtU(ʭ IJ,IIIa"tt:aY6F#Q@1SGY :GY~},ID3TXF#EKXt  _}t ǎS5da>)e{I(aIU)9X5K۩Js3M(0AF[HXbD+uǶc,)8u3-k֯X,rr֮&" ,"9-װrI mgkU.zqWPLRZ&U0AAu  lIbN9K+sHc嚵,]S; ¦ g5TWBqF>'w8֫$DJjֱþm"Jfy-Յ^2 *Yj%K$Kkp߃l*L` SpVǞT)1L5,+A皜3F0NuIT/&))ڕ^^êksn:4aG$UF{xq|Yl F4/ rfQ[ʅX2hx08\^Rq)(*(?oR65 p;5L-`7qi8m[+Dmd]7ixތrzj81b R)>w]ϳKI&Rd#h6-aÜkHSOU˨*œFQqyi8.š$op%4)S%`e_2-놅83KX.rtĶe<9 |_rȄ>\T\Ee[JضD74t݉&rd8&:RsW(_$?gMJ&כI`kx`~56/ե\h,Dj֮%49FW0#ؤ̞Mu C[DmDJ`'A=9Wp5h;ҊĨ#?t #}k&&ᦰQ,J ]wxpbH)\$&HBZ&#}] tZE^%FJIһdh|{(Hu_u\u Cǡ %$'B!m.z|f**Rv!6?U_/…)4-&::1[[K-! <*uLOa7(9+;F[F۟+VP]^PC/i{g!ɊYM”sχF˛z UE5 1C>V]ޮ]TdV0^z =LOed2Hxڴ%Ul!ѡcx՟qfQNI$&``8g*% !ޔ.m@wF)IB,bigۇ 0X x3CZy~n:' }53,شlV). LMTU.*۠EJx)6-J'!q8!3ƏaO1"F #(ʭW[g~n7IOK+q{(,, -5 MDk:Ǟ=i ý4_#9Pš^*fxcxM.N:\${Co#&I0$ýGXs%b$O^``l_r pF8nNQR47x{1|2%:Np|?SCFYf5%3rG5٩|o ;9yDvBNq%L w=tPVYךoəd%xe}D JI g*&q'eRTT$Sc Lϣ(Pw?$琟dمT Gimf+]@QV22:G$Δ,\&1HK57&ݴtS),#Ť)-^@Iɡ.Z{F2.0C 20EiqfD.rIOrOԑ@I$}I(<?LK[/!ᤰth2@#~t Iv ' 5;̤y~m+bmY2v4@wxRsYPQ#棣dR!b7'C+Ҷ%h3ٶ ɧN??ዛľ6aQf9>gaHeAf1M^{ߦfG']WUhdMێ&Ҷl;={l4 ۾د:Rb:vka7s<9pe}YuԄGˆy2{bs=yevkhW+\wi[X5sxϙX~)Fmvyto+@?qRZKV&/e g[(J-u/&V`ݬ\qg',"_ߵ(1nkrٯCJ (!+wVAܞ{ЖWH}S']]s)[ OF~U/%ՐHdњ{^;fn8W@Q~!(Z1P(8v6TQE=~jEQEhPA((w BEQE#T1gP1EIsSEUAQOAL= gҽq3 v"R9EQnB٩ߟE`lN:;֖K` 2 Ϲ4d&-!/k"*> ]N[fl77xH+!L3?EQnm+ 050`aJVf53en駿˙b}x=iZ~:BDB4CGyK)m;>7H6:;^LRR< 7ŋj(O䌻O< :yOb nCZJ#{el1R c~.$wd~=FU uƯTwxHL4 Hwf9idCUTضMGg'~V._NB0m4bS.$))隵(@8tIpPjv2]g%av&˳^wi_=dw\΍_:/u^L~$a3^.nʕYV/~y+oxLvyV'>c}A)fs3[2z6uuwWV 7"x4/ibN qwm=k'?ٕFz Fjvۣ%٘=|a[&+ 1TwXkϽs/~<BChܯB03i>]?++_o_`pEnE D(CCìZ=qy22lbcW (),Obh}!7/IeӶp s Zn\Ebl=3r05^H) J$a +,Ev:䗥@kkU^C+Lok Cb V(͎2AgS8KXd7qb;Iz26Ƨ{{LuSw,>PSMý\j&9@#Z{3+{j}mMa}LDn\ hkn#ʥ=b)t7\m @~Z.{>FbհjiINp7;cHEт* 140:Z^S, 9Y.2m 4]Ȗ+HvtVLMrʫYTuƮ¦X|UU,F:{ȭԹ6nײ,zzzZA~>e12::A-x g!Iم8ٿA#LY Hux ݧn=3 &}}]n s7~4᭟|o%^őIB~/]?pa^]G΢&l֑V, ON#-.̜-bzlصqj. w0ӐIxo~ivm`ZO&+! a.NSe I!:&7fo0Rww~ ǚqevΆQ4MC8k'>W('^deexx_WNc]gɷŏ^I4iY^9xHkbjD&8-Nwp=8ca/ozu|WF^tO  _a<>SMdogzl9?zP 73/IMs; ND}w7}r!v3:7dy~ovp~Ft޺!2r{8%xҲY.-_L7wa͝#2k?[Ʈ2Rr s Zڌ4O?e˗Qo`]JНN= ;)N5d_=?ws;Tī {b|{< S Aw6lo:7~/v ޳!ʗ,h^twR&#ȏb([ 1- `7 @\N\N'>$99.gMOɸkOyn<7?ezz;v|W)~eiS5PXk*WԒ^Oݖul𶱳UC!Ha <Ԕgpaڍ,J5XQDcӷih^sm,cۊ͔dmQh(z+6EJXY{/ 31mPZ%e. BLjpjZ6,JF, |~ `#oifKUQ.B,]7[U-qPXn, H74\d^.4+;,zr+RUfǛ/Ц  M꺣dž*7mq={֡)Ķm)NB@JU,!6}S LGM/zt]-cE`tbd쵒r`'ロ2w+fJ@´]_E3ޤ!0t~s85my()EkvEis.E(-5h& h2IJp)m,Œn/) )RqDf~N< xhuK>L{f5a.)㚝›ɟ"N}~1\hƴeZeYh 9<Onw-.FWw"I v>DS(p9R]]=-Yù WKL3BgWS+!t E8}^ 4'x\Yx-t\+˒$.kybMG^.hƔܾ$&b R g̥ Ì2|)3>KeaY|MwJH&)!Ԟ?QϠ?Cӯ?6)!MO{h-nlN"f'/]X 4#tt2^Lc8-Bu ox\Nj' |e9RJx_RZ?|0sf`&h1=*Q[ B ##o@Ә#ddd\rr膁h2@9zlbS4ᓋ$&cBRхhw'VBSTNn(.mSbQc#Bș땇}6nc:Ok|jm>c>K)v9=F̌a7`?7 _{t :d/?i^QCW4DcLEgįt *trX! M4!g{]+~^- m(]Pw@X$P?h"K6TL4a AzzqUbAVB:`nϞ23ĒI^YyыA|!b0#|~{:V:XoMmCVv_hˊ0S,("' yZYXa[d(J4dlhX a:ĒN&(gUM[ p 1#=JgI<=) WՐhb1BDci^RMWv6gC\#|A5^sH~2%kljd`2n}$.YMy+a^)E 0dˌ1d*þEhfl.[f,-_iH!4pG,xw¶JD2V,JxzEQ>6fs/ `MBM``p4IKMꁩiutCFF5hb]4wLBlr6NbqJ+9˜mR!v:dV`s]ti.|\hYYӛJ;s-N?$=7{ws'Ă)JqȎsX4 ;YB ]=¡ M008Abv. \؉fD kjVV^#4՟lN$0>¥Q<:]g:ɨXIua 1w,Zœ>pKVfF^XIqn9tiGNgٲra͹U˗Sd;=ʔ+K*kqdN7v08XPWV"̾&ZDkk&/P;{wNcŤrj)I#<iy^VCI~.)iN.G͠!Nv OYf5ޫqK ZCT6tB×8xa#skٴ|9yyFGx(*a8w-Nd& pB Kq"ݜ9~0hfv'mˊI o~&4*LL Hә34!A:ڇIȥ gt'.06(S*)OqANԷ021xJo ̄${#g޵ރ 4C7t̎9Z}ZyowfH#i%p8z$;.}e7YAwUfĽ(+W_>FN6XCY'S8t˝g0jr>23 elhiڜ|0g{HfKV6P5s^x-(r|A{}12 n،pWx-;P_Gd"/"=l@ҫ0A*a2F6bHr$vmdsX BN'yyy2::5&wޞ>**ʨ•3Nq7cz ,X$B,aV a&jRPOUI!N&J(o)۾r/6nZekSY&M9(_M,--[7S[% W4nh|Poi +)K4vdۺ @^E#[RS^Lqi6oߋAh,Ea]{:i WjJ(jdǞ=VR^]CYI$i@ueر0)O1-(+ gx JYߺ0_2ܮEx6J*pY1f!Mپ义*jY_WIyy)y4vо*7k{> m9Db p[TW-k( i3hlhh;PA˺Liicc3eE4u& |^XeN67Nlj6SqH$lcbhٴ m&N;ثcWolEǭJRWHƭJey(:-SZɣʲ|+ٹg7UPY 2uTPѰ(.6SU]1aiiZٵ"+I"W[n*D 47USQVNυuuWֳysm׳<V,_u5TP$MEFj*˨,-DälXWy&lhjm< f^5k(( QIu8)jeîA9mz&ۥ+H&&D"8N ,/۽{ \x$8ei[6&adnY/'oֈNK +ͷ01Ւ,۞/d`^&.ZQ\)p^HT sn'UG 0j|QL*ؙdG33udV s+ߗ5vn6ee;TuťU3,)h"s+0Я+eSiFν.w7E.#Lجb\V +< k{quml\m6V6!c~g3}iՏ5:mgQ^L?TKڪF۫жr^mg"s,,HNulZWLB|d=|`/ޟh?׭>I:2$N ώ;ZW\~:(ζHg_?_aQg/^-~:F̢f/WfMz{G[i쥍Z l;-J[n F߭,Vݪ ?=+*kجg4mCO(jWn jiֲn^؎Zjc13f}v>ُU+kVkٯV:X[3 i޺R @$z`=MrOv٩IAjw׿\1Q|Z۶gihp1fcT ж&(b࿵(t:T;,S|3TlZIaF|$} isᙇvI\B+OA䒶m*Wך"oB! BB!"'>VAZVk?)B||hp2X<uB.AHu/?XTx{?yt/<_Cz]B!ȭ-QJR7}LOOҐRwM,<6xJ-Pc׻זMB!Hyׇa.lmw@O[F^9:O<"nPg᧸8ˑA^A> zqB!ȸ DkM ##n$?/˅eY ._szW_R$AfS>c ox̹ٿe^PI:f2P]-i+TQpOԋFS=瞆jfjRܓr'^ B! D)$l߶?6M?3 rΞ=[WPhS}Lg9Љ^:>CE/xn34PErAKvwT>G)i޶*B#= D=tG4U棴F)͌?D0wQu Op|'c3Q<%lXO!B!Vs]seOeE@`36(#399rN1;Fͦ:wqGG3[2HϤ/R9~E"6Ӂӑ%_o?5G. rlۏ9982 w88g^|QNKu{E&3RNPٺ;lLkjskLRIn%4u~ND*ٹge>Mew<^:˩`; 'aSҸ"T|/lD;ijـew(y!wu!Zk,v_901 xu:PʠjP34? jIav\>#X/l"1B!k:0 n7pu:ReFRtDXnng| "܅l߽ ?˰B*F. ~>7Fct]#jekghϞ#w?o~ƹɤTsB!p]Ai22:fb(E8&SRRwPĦ, ۶<6okőGzH嫹;S?SjM3PitfTDklKQq;ʓ (; x4 0I Ytl_O _J%%2=X}?~_tљ$!zWIDAT0CCKUODcQUYI Xdx/=ϛF GXH@8xaxI>?J4233㌌ϒJ'fzfQ)kI u3_758AJk@ 7hƴ,kp+{8p}9|GM< spqj ^nZȆJ!b5םqz.\drr*lH$SLNN122JYi 558V &bѱM48UT e' =/K9ML*]!IQ &$,Nc!CkrLnq Cir6nLh.ua/(=I~& &)h?W>u 5\aW/&!< 9geA`q8(++lBeJf%όQMƶ5i.yamcY[:A›/]@Aᰂ<ob@K/+:ivmsO u !XTX[B:bdndzftmjbtzɿmj7XR$&{qcYB(6ma[ے+ZSlB!} B֙*>>JǟGOBױI:c6!%-B!wnپq5$\C:M$]7B!~[NljRRbL!x<9!s#!D!0N!B!= BBr*9~>ZcCU;?>nJ(e`f'k0d"SĜcY>x#SOI'ē+Ti;M< m:Jua0q8e+e`:8Ǧ^y!h&H]g#m7^d#,;cqVkW,%“:r>eB4!Ny8s&V:cJ)tr ry6-~)DfF);ΉS9s#S!98L!o$; +OWZve({7E^{wm1w83J2{1T&8ˑ[Ǹ<^ 4|/_⏾8JeRA:ɗqοO?=SE~^x8?w&wTIaċ\m(slO_{}PsJk _)[Rz~4 J)$o?=sCON33=S祇_8I(avEqz:j0?QpPZH}e>) S/\lAH67@AquՅ׿[h(g[+jf6m<6˦VJ&Q Q0 '~{_V8]nk pz<(k0<^-+_[*:(4d8?JF0ܩP:I0x48IM77}Md.Np pmC^u+~5̧pRq;_bmV8,ᠤh-ĶW9&n} ;CD"Y6".DKL6Jt: AmW 2vq䬵X6Y}ݲX`'=GʶE˹0׭V_$ӥQ f_?KD4۟7{W̝/޿}%p>˚{x}W8~ɛ/?l@e\x]WWN+Gϳwcn,+Mڲc۸Fm-8¶V82<&S1kM˷ɵ[{o&# m[medŪ}j~bl*a,z哯3320܃)~/-,w^k|\u,/jߊW.W^ d2bT}ӽ 4PY:.bj6uXmVC0L,_Gh<{X}% _~nZe/k|d5zsicn/zyc6~K~c^_9y޷g: e4p8&Rln={gHԋsOS״Σv-sf ]ZA24Ι'M) [XNy( ˼y5bzpiy-Ǐ7&v{X_L)xgN;i&.f:2w)dzǎq8n ٌ_߼=AW%7BPy>JO{~#LǸx4!UV򜤣8z qaKe08ݗz _avu>9Oi7t"QnڄH331ĥK D5;\Jh#3b5q;)+7RgG8!bl-G8k JZSvTI&e+*Vi qq&ff-R>C?%oOx]|徛H ѳD" ۸gw>׏(޺ȱgvTpקcK] H'C ^#G?0%;ClAzg;Wl/ݽ {AfBaB1m;TW䄗f"O[L'GNvaVm޻o@*:ɹSgc68hݾ|L,&qtux96Cܻ 9:<o:͡tܾQK}2~.AK O b5wG;E^K~+g;v8#ý~vf0?3oׯ١ n=$.Oz?֗XL?L(D8`ÎݴVֺ\kniG97t/1&J$):|p}^*SazO跸pe~ }oֆXhK]}Lg (j`wG#%}f9qQoҊ;;'xgh?5G&ts'ߕ>í'.9(T:gKo{u~n8ޣ!F Og +f]s>_@/>qv9CgE.R$'/ԓ/[ϮR>Mכ(7w?o%L/_vt~z8^QC s G;N4p*h)Gd0ufJR=_}}GԌ}G~:SI}?=z,IҜ7O-H&h/`owtȣ/b4sDy F& ^ʫc~ o?4gyAs<),_[73OL{xWc=*|~/3]yᗘHXKGu$O\S-+|aG/0 =c~s|޻o$?xGdt>DƻyчxL?65Em|[w qx7)7lgdߏrc;K{ ˃׈0TyS3Nfğ_BaQ1>o_y h-*ߔnɥ#/r?W^j?] 'm /10r$ oo=7lk̑~Vdwjpݤ'/s3Rei޸#OX&5No3ǯ NŖxᱟ>)C1u=w=w66j-R}7ЉqV 1MoqLS<#0ф;ѕν _d2"i&T46 I= ~zzMjyx18768?Ӝ$ά[6SdD8u03R*  h~(0-f8|03NvDYs鎹 +&)$o)"eپKݦܴ1GO0FtfSoqe;Zt xq((e%;ǙT@{ H7mgV칉wn"ryP6ٹe7mPjqs̎NQ}3Lμ* z|3;񙋏jrֱ͛x`;c̉0yZ嵐47PŽ[,|'xX<f8֭;Lj6)T'@߉ǗOEeEyERY80tT97n@MS4%笠/}k/X2rqPi'{sD'a&W}[j؎|Z;6pOȚ.>1? L','_~DI3u% |ޭxr&mEic6Ts\M19CBKdʠf&74Ӻm-~3!Vmayq9ӕ NM#sosr˺ >?n_,K5*7 C)d,uVnh&/ߏRټoζVtwl,%28DTd NFk'?ৼq_Tgi:Ls=̗B u{;1:,0q~lxӜKF3!0umcغ_a6~EAg@iUn7 6>/)L[fW_N}+|狷Q_ʰ`tAAk4 cBm8iشXh "íMc زu1:;G FЮU.Z)ocL LiJm9x˧|KwSV*X Hnl:mcz׃t˓o\ƻǩcp2"fzx&8B08`w/{d붍5G[+JaCesL<^7N"X[gƏ1~<׸I@mlݺ WJp}'" x͕Z7s UCH'btjjpMe`n7pn]5 u_?`?Neci0]lޓG2qxKsv^|$]w&SW7ෂt L5m[ǢƶVGG6ZyX M&Sn hZ+&gIoo ׿?ǗՈ켸Z--u|^v/C *$x$Mm[h/t.|o6FvooszfzF2S 2p +p*6C$[ٶm-S(7 ?>['/4>@ca׳ hÓ}Sީ$nluVʌEg#{᜻mskmE]|wxͅ3w"kdsxxidD߄,GOZ{Mv9; tp(;F+Eaug<2eWLi81lM$^[MwoĮ<#.bA5(Ǚ駕fdYڷlд淟\Fb vHeyZNG;3tNḩm6epqt1va4Y TL]%@yʠ8 J-жEJ0k.I|Tdɯw;w5s깇x3p# O+-E߉y8婴u*ЩY?8OD;x=XE|gSw/WƷ_ix`ϒi0p{Nrv0hLhΞ>h(>޴eayO*c+@6Yk֛o&e߾Cˊ)NH(H3 gd_N[h_wi賿蹱lD&};_`8>:1́.N|~BMgkGM8)č)Fֲ}'eeuy)/D 칛/NSaxh Gl>)k˥Z9X-JvyoY ̔C<1EjZ;hܾ3_]ͺrhx!{j=1>.ZԮ,$*bey4նJZoV_(fhGHy'y0ˋ̮ZV˪Νw8b!brmL~/]/'Y\b 2u Xg s/0'g%%k+EJx=syQ[=:RTyKF\:!tvf0 [K˗6(W :p-.;XlѱP ptπ BTo6T'f{>:sDg^3NWĘ 0gعF <ԶmeS,_ feɍvw2ms-mxGdz~ (ffē \;z_ |%w8kBg_>Ƙ Nx8Nn"tk?z Pdp\c:Lb]tOбmï?/ct: =N'֠ fޡsfo&_\:6o?:L;eν3F>@K&mNLΣJ/)|? ~G_8D$2M8+u*uvFΟs8a:Б)Sz-l̋q|7&>_bRNH0D8#29pw,6tiٓ>E0 #gɓ0㩦NDm՜zb%(hlG1;v'taA&L=Ht+R@kb*6LL|e-{ސOQNr)t(G pRtR.{)m9ꅻE A82K$'t&c6fNZ!r-:O8"2 /|VniFF{dhdD*E*^z^f٠E]8< \$UPÞJz_C]㤬4 xT*V쟫S63x}*#xF7əï`'fZU+ϿiZ7Q[eϼq4tlDR*p0SC=8F{wW#>xyBTW/Q* 2|!qd#}MzJ|h3PDu89L<&<9DX4TЩnIa37 G Lτ0J8um+{[$y'ع<碁4+5>{ARg/RвM-T4 rw$:3aW!siё,O-޲;Gb;xI|Sc O$iݺsvc͓ٲgtW^zAۨ+u3x${n,')ӍWO7nإИWKqN] 8,pqJ$[  vq9ֻăSHc} #252 gnބ9sE #c3o* /gSF* <,dh* ./^8+v2%7Rxnf.kZ2Z*p7``bPܠI;rBȑҸ\&SC#Lhn,cz(`)x DQfg&7S]YBEM L0΢*j _IMWVRn\FQ'|6j \hqVt(Mc '-Z6QU`b,o:t(B2bhl b]}啵T9->uI姾ϢjrJtgdȧ}s r''G}^+V/NæYNw x.Ml^_IjW}SiiGyYF'ᢪ(Y/w9`gK >^%NFm렡x1~[XEtt4 ]f97is5E 4._NT^nRJL_C]˩ _XN?͙CorL7SAlW>5uTUVM恣MO=wf=޻ ۃC\' 34mtiw1Oۖx#%M_HmYnܱ̱xi`0 jkJ=[G2MOskwQ9M{]y/be(1 vmĂ Nj|TaD'%fx"gx*JNroN*j.pq_ o! GYe9~•8Sal b*J qDxqE^q UCDfhʙOuuFlpRT^Ei a'øŔ8 Ep (AF"j* pPUQ# O'/40ca%$ K#LոS3SUV`&VN+)+^I['F QUYOP7 EIM# e}xjo>JRY^sRXYFǘMh K+(ǰ^fx*( r3q: LIjyETW2@+NEa*"PTFey1N`|xHDIFF9 ,_P06:lȬEyYBeRƆGZ䗔SQZ^f8]_ʆ/ܽ!e(,-(^WVM1:>CJ+\|*+Jq`%c qx󨪪(Lj^(` _g&ef 31 2\Bs^Ԅgv ZxW &/-ed^"f.#95Œ奪 cAZ }NdѡAPT^A;t_^~"36IDSRYIX}b@3> Ce&?4U1<5KoqAyM=Llӣ L<TUMCaa~$MqS]Yw2ʳ#OOM}exxQU$]|LO 1<W\AU OP_ɜIy\' ueIv2`?8@!UUh'a<ÓWLUeY3V<031(-puJF&ApɨMaY%Ş43q||fF6}בgDRˎr*J3$C$MEfCX7H:<|`DƻB2DaYٶ fhsdsQs\:_+ \abY+i,[4]EޫmB=s?[F6Y6B4ٿߋdd362*Qxz@O6IU6Z+ 33 s~1^ޟ?oF#,b[LZTn ,' t %E2dZ3$DsBfױbe#j:7Z/=>ؐ`~˶ϒcdcDe+z!;e8Ͽs'~ok|Z:Osd.1x[;~\`g -lʂQKU mՒh=,sŪsS5z_||U۩>m0 T}ޖs矅bV esya|s\.*FUW^jqV`,>}Y|NN^;{voI| -ݢsm00? Deϒm[c!so*Zr,^!Gk!i39 K~hGy+ޗ ,n':`ƶV^&kѶd/>Y/+ud/^J^jc3e]JgB5*XUUOW;٭}\넺t+WY:V9kWscDwOa`NڶZe;k|FVml_-ӊqvXk[_K_gZ՞+tUm};"V;?^S?Xx_hj X5|W?/H6 OvmCp\5յ~vq0%,X'|_/?ָ]s;]QNq .^%=w&:5i36O`c 39"c1>N(?>g}M1J}8ɡt0=2)RrJ]CZNt _/($J"mu>>]&hsNThw}IFO6i2wE9Dyŧxd?)!wMNfA~sosB!'RnFB '/B!靖!Zk e`:HjBSR)+S-pdJ+6t:fT\e9󅓲it OLE$mi:0 èʚ <`XB!>x(l#}ansncp! &Tty. #p+޹=KO'mv kqWT8w6;N.9ʼn3J?ͺg❾$1v4/ײ/f]Y@} EO\V412Ohq8ݸM3CF5X|f*e2I|lB- 'Xyܴmx|LLbG'u.ٿ8Xx䰚bkO6o_,^nN-+B|tF;ucju~87`O#V۷2~ƣNukEcM3B I .G'w`h*E*&2ؙ @kRR(Je_ _2LK<rLTp[!B!ć=II~~sl:_)~r}VhxI#Q;o~4~n9GHQ=#{i͏sES?{/rqxP']S&y(] NN:OX5vNfܒ*B|)Jdfj`$;PDYqlM;gzrxZc8qhmgb:RV^FׁR'Ǚ wl(w M36r)) i191F0ƓWDEi>V4 iAQi3$1KWTNicS!ᥴfy<'B!' BP,HevdMBesy0PtYs9#JM0KߣmEdJa,y0^2O\B! Bb*`;WJ:\mYZ_= BjW[rBaB;O!B!B! BB!"'$B!DNH"B D!9!AB!rB!B!B! BB!"'$B!DNH"B D!9!AB!rB!B!B! BB!"'$B!DNH"B D!9!AB!rB!B!B! BB!"'$B!DNH"B D!9!AB!rB!B!B! BB!"'$B!DNH"B D!9!AB!rB!B!B! BB!"'$B!DNH"B D!9!AB!rB!B!B! BB!"'$B!DNH"B D!9!AB!rB!B!B! BB!"'$B!DNH"B D!9!AB!rB!B!B! BB!"'$B!DNH"B D!9!AB!rB!B!B! BB!"'$B!DNH"B D!9!AB!rB!B!B! BB!"'$B!DNH"B D!9!AB!rB!B!B! BB!"'$B!DNH"B D!9!AB!rB!B!B! BB!"'$B!DNH"B D!9!AB!rB!B!B! BB!"'$B!DNH"B D!9!AB!rB!B!B! BB!"'$B!DNH"B D!9!AB!rB!B!B! BB!"'$B!DNH"B D!9!AB!rB!B!B! BB!"'$B!DNH"B D!9!AB!rB!B!B! BB!"'$B!DNH"B D!9!AB!rB!B!B! BB!"'$B!DNH"B D!9!AB!rB!B!B! BB!"'$B!DNH"B D!9!AB!rB!B!B! BB!"'$B!DNH"B D!9!AB!rB!B!B! BB!"'$B!DNH"B D!9!AB!rB!B!B! ǵв,,u{B8kB$X !#4MJIR),G纷B!H6S.clB!FSB!"'$B!DNH"B D!9qw!>Zk:PJդl[cV0+~Ϸ~f߯F!XE(&JiZi(8%KLMMJP頸hEߓcc$O`3}z<!L)E2"|[G֚p8L8pB"r:ijhx% ().YYn"Nۇ;]_!P!OT^9`Ӂii Ӂ &8N DN9~T!B!dF |5F: LKF3}7_G$BGbd6i\ɕ_:|)yJǓ'NV!̷-Q4%M48 j+ 1i/zQVY%dS C4(hԕt]rw|Жd^wAv7`+۳^&!ćA>Df&aơpx(,.q\׷oۊ199C|+ٯEwNorJ\|c4gw?2*WWQ e%&n\N'R*(6ӗϰh=0嶢}GH2!K_#c!<E`GL49wxR5JlƤaͥ7{rb`6{eנ%uMsaƦ's%[w\{צS|'O2.dƽںYCtNZz1܅n@+!܈k}gÅpy{<+K;t^&&He_4KG&<Irҫox JX׶ރ|G|b7ָl]MYCeҪ#Zk22]%3u20 # 95Msw/۰ZPVCO4?垎Jn߮,/_z;DK5Di=g5ӋRj~ o=6eb*(۫ţGBR9 BC=HXR`J0EK c+T ץI4tv9KKRilp8]8iRd nkdի//6Y>1kw?MGeo>~Fo^!>Qfi<JKfƙ/.#_ gnsWY;l4P^^A+{Q~ϸmS%؋_ оv,X6g8|1=M;9,fffM KQN1!ME]&JA*f6#eٸ|y1Y5bz$B͵tphH›_@A.4@ʮ$PVGFΩ'Ե4Qm 0x$L M5xEa1;8Tuԇ-լ1`N)?*.q/LD JifG8i$g0Ş{n%vi{8Oxq/ 4^}mNG*(0BTDWBYQ.hHSմuuMFF572Nw,6؈XP8nNf``Ӈߤ3T7^gvO).]ny.,O14"ǽ|v>ߏ 63ƥ0[4{[EH"q2iT2A4"Mx W\3 1>2̴#(4A+,#URwd0Jq&Ҁ+#M4cx|/Jz9 ?ZE{ez_u)S# \J%ԥgW. NaToB;hb u3O~"Ofs3_c8Ϟum#u%`۫_kzÓ^6MF! NǕx,_r'y~m5-Lh7RMl۹U~[ݼ-x<| wP7`s϶rKÝdG \n7_/}B1Tf4E)41oͭ[oZϝ%545QuZ{K/0$A4k7Z,l4PR p{ē)QuUe4Vsllf)8o| ߥ5Eu)V#8|nlֻp21pLk$w!ć`!KC}\M|vbJ8jj_(Á&[Ig螎 8Ѷr\6& /OXRRR ƫ &2w+|Qb[kn:±ӌdz[ضqyxTpl(x.$mgL=zCq~-##Sv Eբ^F]!8ƯS+,$1;3(t&pYH/5]7 0S)/n q;er$3L]ڲH[̏cz2cXz,nZo+%2lhM_G?}$pVPN02m$(2]ݳ7owO`g VaL sq^yMFT-_h)b[z_9[>-hgv2Jp6D61MO1I—W@QA+b:ǵjb2a|%}Fy*]WD.oro奺snŠR!UZN7M${/p0iݴflB||R/JkR3]w}2~ D!>,sErݎʏ\}2* BC]=ED_/?_'tW$B֚n7Y]e(m n HSQt:_+ BԨùn4.k>tv^x(Z0UkY.庙?~Wo D!>N"b'[\R-)r'J)n>ҊZk^/55UDOpWzE!ć@))=>oE@)_ yB!rB!B!B! BB!"'s uÄBZ%UcO-L&sh!B|9Nx|uSB!B!B!B!B!'Q,|Ԧ/?9%tEXtdate:create2017-10-09T14:11:41+02:00\r%tEXtdate:modify2017-10-09T14:04:45+02:00.tEXtSoftwaregnome-screenshot>IENDB`Eqonomize-1.5.3/doc/html/C/figures/importeqz.png000066400000000000000000000613671416454732000216100ustar00rootroot00000000000000PNG  IHDR{7gAMA a cHRMz&u0`:pQ<bKGDaIDATxwysԓs AHL$R,ɒe˾9gks={}Dzd[, H$rarαsu< "H_>tWZkUWk}[ҤI&M4i>-I&ͧ ﲯfk]4iҤYK˿om#P8B<덮m4i>bX>tؗ]4i|Rb U&M4˒6&iҤ.I4i ic&MBژI源6&׀PE\{A (u.5M:11s[- zC׫%ZGufէ佗sD2?jɺ4OLđFw#F/v$nwo?"2c$dz y-`O=^T꘮`!~a øqAγkٽLkoʱϒMDnUkX=y;;fPdX֢K>S}i#2=Bb:BL>>|dc" p Ip&Mk! 34\K?-?5vf0>_^z=fqrQRϜ_FUb6c2 (PWXM Fz:g4$t5wl,'6O4ٹw]}`l^SӔ*Ljz?.q UAJIdbK s\^hd^]0kӴwt35T(˱"'hmд x c\܍]|=?rᘇ;EKAdBdN|WSa_@$ȥ,?y8ýw3揓UR˺U觹<}A37mMt<^8ᶩmtL G攱I}=_ml!r{}!]-:"nj#v6WetMBͬ(@Hm=8\l@dy|NɁv.׬euy&t<ݓ7S[!$ڻDqӰnHad9uud]!*q&GY.Jh`qSYSCQ DLZ@V&47l@Ǧt"c~+ukWPnoo;R(s&Υ8[[iR^Cx?OxE Al"O^_m J)/s|g{8 ?Giș~"ym:"f&Zߟ ~}sN^zq5220ӱdS͗coR,N/|m" :/r4o/O,2`?.lPFs-@^Y%%^ӇO30|g{Q z9x\`Q:&ᦼ\&IqPQ4?oGr ](/&S]]IA@3?%n -~FZOx;Dso0%ԛxc 5D|#~IB%! :GXD9eeg" -5I(u?^{^> }@T]؄@H03)(i)!mCUqaU6Qp{n?,gP$`"Bs5`8oo: e%mֱQN mdÊ 7+6mJE%1Ư8EI0TדT1 9Ϙd嗐aV Y^XhQ_"M-/U+sQG'(eP_WAb_%پ#y9&c۱r|wc j1J7އ2qhN>C{ ;LCm1 U7  Vkb_j؆CרbBU1ƒ tXs\<<שO_ DA-;ݎbPig2Bנ9,m厲JtCEF%pÍ HńƞIH 0p8Q1@vvPmr :ZxnrJ(|J,3OY.,V+"Qۅ H·l(އq)lvlKfgRB"sYņjcQ*k6P}b;K@5B0rSMib] 1q$3zH0#0Mc_ͅNc'}aa DUMX-l>2V,J,w>F8RRgXmvV  芃;F4A^qܿ#;f~LLH 6;y/BJ )1[m0Ղ"iݝWCpPSbYqM*˛GHhBxXueW~q .l0}/3n6Zz^'1q .p~"u: Ű:s\!@׈c~LXIXdXmX JFN #EE ٖAl"@\)"崍:3Ɇ<-v@+/`veITG|g}~U札֬rzW4v5NTW |l*πMf#gSLf*k)ed\pt1CrS5NDVL6ʫV=׏\"00SڼRY]vQROчU* "㓄tchDD1DTה1>fl[g#@Z)+7{30t0؄-[6PiAIG( z M3L_~A b|:n+Ohщ̷B~ ү^3ݾlɕ#T-1wM xct`h`oYrJhsK)x׸8mC4!PTьDJ\Wgv1++8wј}(9%(˶̌梐>PqbTl~?ӯSr+,> >8P88e і; CVVRcoxh&6בkI+?VEHgBq'}짺a96“=l֮ ?l{(.7FpNo ǡ|P_oVL΁ô L01Ey^[VXS̻qj` hM>7Ŭ1>n=k4?ƅqlNnZڇqgQV A:}Qz;Q2(ᦋDk- m~G Pe9A3TG˵2;3fa jcerm&3O6 "weF|vf]ۿ]Uh4F@?yyZ ~"(==eFa,T䒑/'}8~S'Opݷw|lLM䗐ˡ(EhlMaܼSd\a93~\7'f(uRqn א\P*}l ZmâaH)w=\7tC&QUDݺ(?o^>U9`UUne%be$C].ײQ3*Ax^9Ħ)5> ]"t9ݸi ah |Fl)ue\PBJ]wSZ+KRkڂ6HCG[R9-z}q, ,\E#4C . )\b\o8 AK?Տc|%e(\.~t)LV7GiYvbӃL{-dMK 㶙oE?]OtiX{f9_?Ӝ8_>eUlܱ,5,q2A0yEU!.vr34-* \Z74f%%A7vvlLK$R,\ɵ>[a70͍2ݔD*4i~܊ӜOԘI&ƭS:M4$M4ׅ1vgt9[tJ |0g:'A18vF~DV\vV@R`F>FB(X*7lfq9hB |cl*|B/mud ]'/(_VH4 WmLGЯCU+]k=ſX7orkv縙nKʆUduS\Ϛr/R, vt(WmUՄCA4[PPM&LBg|dfael&f5ma(]U>Ӄ4564QtʆpBLS4q79A`'. rL zf;wm*׵FIhϷb.ZǎH$/ϰ?N~Zؼ2‰ )0}~ N=]>M~fw^iJ6kVT%g[Un]ȴ% [Zd, )]s;Ub&pO;- 3g;/qQaаf56aNy.vmţs>82ɝ ?O1-(/s,z&(l֐i|y~Vq`&"+-4>C$1ianV8nc b'H7gO獗?s gK^|U:tN3[{bRȎ=km aB'Ι!ACCӗ᧯&j+B'|/5#{_s(V7 4 !e%^y0= P£-Z>z'n$=O Pf+߿"sk7ذvn[Gқc*jcO̤KOE@D<›\PTڬ(/)j"Y|y16Vxh}^l r]ws"GoYnЌX&D'9eN ԯm@qZK Ӆb.6< +vgWMҰn+ܷ=1D4kdʕԬM}@X",nV"'IŪ lZ;wsr!7gUF{'Ŗ:BH=JwSalqQAݽMuo12Wm +udggV%#"@5[q:XM]TdY(]5 lQĝT(r1+qBv~kWTxX{'_|d9V%#U hXǺ£S$Xnnvw&%%2 \A [̸}5|GXU\I$y+ֱ6RJ@);j)k p3Y~rlD5d'ع6C8m Å;];h{Wv"6\N{r*6͜'%._5kٴi pR/b Px^6+YT w继ɯ̆2OzTOD_ɖwSL^2- "gxZ6mڄYa`&UA5()^݅PT4]G k7NNt2[LVTzCIMU ńr-vV4Fq 6JfO&,\w(LPԹtW쓅@3&ThC.SH-BGG ӦXL HmU}Ҵ)@{ ypzVR: ?&?(q׳=/Xo=#6Ʌ˽$V2J@颳Z-UL=#`ocz6y<%L_%t_9 Մ92TJ0pI\2`H u;fÅ[?89L7j4tA麻xlg%>ou[UsbYr.S^;/}f UKW(d 36yz*@uR[xV,2X>i`4uF>{y&&cՆʼ;V]]\&aԵX^<4/Q E̥L$mXY]2xۆ1I`0?"xs 3>+G4)h _UƉW G1#J|d61.[6y%q^Ӽyeպ:oާoO`z>q=L8yC xg+Zxp(.Z=bI?'%fQQL4l[IFLOOPJ)qUP[ˉ7si(~8nHLffAwwp#4]7f" 19@$4;[|X";`Ūu8/K1::j`ԔϊBB'1d2  bD Eu4O/rc`P_/C-$hye^yz3lZp8LT` /{14?9Bۥv Vgq_q@..LSR1n'.L`%oŎfwb`|H8(SD3ɩ 4fyra`$H rG5!ߐ/g3FEykW]#OC; ‘Gyw!YE7"Kġ9sILJLv6ھ#L2YPGDx|?o]Pl;8~(R{GyC?r᫧29@kWQ:>owxf- 5%b q#4w315|J!$MQދ9qPB#:5Ů\9eTIq?ᐟѡ!Q ՕeG¸l0E@]Ch{2_feI13œ|̤ϼ9!;;Z]'͙ҧQ+y֟3ׇ hfR?<4%Z-RԔMʑ1ճ\l4fsMR@}ɕ라ҐWyKi!sf[VZJQa!ĕ܅X,eV0{}oK%G.Y\i,Y߲إ*|ru\ZF"]9(1g|f N:@^Q .-*kg>Hf5K(LKRsYǚLesmq"D^M!&oih$p'^P6&i>O%u;ޘoz47ic)%JO|veUIKژI源6&iҤ.I4i ic 0?::1+|yn%PZDOx5'2(IlH6N=Z{|~+EU"|':1t+s|,cQYwC z=C$R)lL@H3ILRy_龃w'&hN~/sWݵאD2~d V^ʘH)ꦽBPYYAEy"T V9bб?=ا8ꓼ`Y֛(D7w*%_K\tŞövc)A\S'6}] & AbvfD3 1 ˼Ÿ*ݜiZYf5W !D:}ۍϗ3)*/''Kp׮#VL%^8UInUE(=%iD"lx89YYXB#4G2648;9av=d'ULZBA~vlR |9aVAM&r 8UayH.AlR;@ő„f4BԉFhF*2S.zZX\C5[Y`hĢ14$˛t8n T3Vey'DX#g+1t M&3fUDc jn$ 5 )T:يb .>2] SJ=K'0Hɬ& #TD/FMۊfEUz"NNwGgO/Ν_*`_x,[y;_~a;FOQضv<E RK  CN_|l;\8}Sqv~KPL`{#C&l6KK PɱQ owH͠ NMk<6m1/ׯg{iSh9{ f3pYɶ֒6ѧ9̫ﷰΜ q s{=VLt;B8f|t sJvmmFXrJnn4>[{_/o1;k2g3ޗ돑 r4%z-1^9.&08GХ kw=|@2T>-! wa:ǸŖslNN//CTiR 7,2B;/vKM;sjU1ᰛh;hP+ceY6SS?5ENzzp7|2I&Yt]"q(= UQ_5pcwSlyn^~!ȯfem. wGcyoqycMWGCUi gqPn\f;ǘx+YYTDyVo~<^~ o#aHLqxk4_! Zth(r}j/?y;xg*y|1N?esS 29w1A( ѱ%zQCC^Z'\~o/ow(y|nF[{T7JBl֔2xpbVD2paUl]55++9.vg LֲuxQ(Q s]+P/IAeM-ծ܇n6Vve yVMwC ™Gj7ו뒚zTlBl.P-HWT뜕p0-X,RYT%Q,׮1$x,,YRbA*-!:E/ 0 .ŌIXq:8m Уy0Y~Ό,gB~.J&x 븻H ~JACq962'$4`AN'N:)ݾfKvdb2Y+*>~p|kkjrP1ԱkKokFvURcUɺͷH qW-e>K2VG<> `BRS]wdfYg¾|suN-=*kX`dQZ\/_ϿDˌ006θFQI1yKҐTye&@5Y@(@ L xIy9R&W0$"0+<9QQL(&CJ`m 6/)A5g܅Sg5/-Y*_Ɠs#TJC#.87d ,'S'e%=f|,' ]8SAE,Ɯn$<9BG@/< 3 ޤ'@o"+שcL.+- rz*DXRmOo$#0"B2/& UIpQ+(qA(_dvKO<V_JtCS/>} d!aqZ"+_j#w7ϠsbRS:(N+F[ z&(I0?; Rb:1!ںG02/ADbvGil,e%]cGa 93nGnjwSmb ,nܲ|%hƛieM=9s]C5w1?u/ʱN[HCGq-Uuyhc&>S^>JTYu#YF~E_W+uDI]"gn4LBK0SMΏ$BaB0D5=5I%N~C0̈GǐeDZ'|t_ܥnB|g~5VTryP$0`h$B\ӱ؜8.4ghGDcD?}D5F 0WbK%R'4fE ( G?}#hԙ^׭,LM0:D 6Opbk_3#NmdyǿйV8sݭAV6LO&NA(4r7Q㙟<;/f U=mؽg7몒*a7DPBc46upVVy0;pC, ajV LC<_p\}4(Ϟg,aӊr Jc挎RYQ9B::;fxi{g[UJK)`udPVIo!İrZ*}V/Ls'$;Oơ3S 졤CКQʚ"g/0PR2,v~ <Ŭ*kc;RLrT{!uեQim:McK/!Dnq9َ䠸m㧚 ı(:CSQ2 ()T O-())ėAF8v-ڦbRd;ȱ1{}:A~e -6eSihH'|VζY221?5B C( K(Fmsz},|ٳ 9hmةfF VtE^Q̙ETiHK$&Vf3̉ ưgPQ7p:Ǥf N[Cn%t7?p + Jƣ}~K&PbS-LDt9Ŕp[XonG7'rirlˎbUrw5B~±R(]\vkj`#3dd0E5v'nh(t( ׃Mӄc:&׉O0Lv+R_$>sa9{y9rNLq'|kGiJ\}޽vv,&WhEx뢛#%>2E(^~㗹xK[ŝAa֋m[&H[}ι51.4qj6+BOE+@CmUЎ+|90}6zMQ#\w|gi͡s;@b(v쩟Q[YJ~kjrlL7tvO!̒5) to!ȯηbq{2c37@ӈ0+!BI}iݜH<"V'-e* /G71n9>qO[ba)J]boei>='"e81۹,&O.PEI7&3ѱ3~ntWkl|{n$X'?$O>x2Ԃ?Gh03짩ؕ =Bs NJ5zi0 b !ZKBꍄx2aCQaBqdz:(7e t?GՏ%\cNp޼ϥ _CE."t/й~#8/I8@ +Y9Y Hp D3c||ۢE%dړ͕F(d|* ߗ166N(#iIUG Q&`vEY:mBǂOct651pX& fRYAh* `|*%'+F%5A4ՎaIEgr:HLddeᲣ*D A^^6B"8́fGݎ/'|6L#h:83XFU' پ\VB@,4T LB3{ )q'L7FԏuYCy)aU&+FhɘBnnVbQl^76U2t?doZlj '@)B8:f2qZBScLL1L6r|98\aripT3-<ӌT<1УwXco$qg^:@$c[j]_̹6=}i7VAlzK}qx_Mp^~89kY.l^*l 9uYr')r"S4730!A[0Wl]!LtsYv/Nd)FLudi~o|/xry5/_m~r?Ͼx ozj%NeTa#O:6m #Fwx&w~m-c^hH5ǿpڻn=}lj=?qˑ5jeooc}t ܃ʟ/[Xrɩ r ;ʦfS4cHp7]#:w= wRJ?sh?;y Wo?#Of _/k|[(py eN"y}xQ#toBDV㓀޳9b?8*1<ԕfC"@7ì y{ח"~;px8ё1U\B7όpM"e}_be\PLpv&䤺RW'>P0$/ۆ֒zJ;kw[EC\w|3{9=T_~ i;Qلs?>z?k@AVG؈ n  U@T~EyX pC:)ߴ Mq ? pRPTJn!EERTb܌W 04?gO6 YF}b, rlk5t'3>~EQ1(29 مg /Rװz"mƑ*Gh=EQPPTE2} #Ty@plFNw=<;L˅nɞo?JOE7{&p37)$ut$V3ɳglOTU tjp*cE2d6,!OמR-0h> 1O9_RɝX7''?83rZ2+b))/ Hҁε[1YpZ0#(XŢd $9".=$N9%^;1~˽}W?b 'ÄӉ2@ Ѹ"l2XŢy)ty7{̻gs"ϖc$P8mFΕ?< dzx2'z 4=`SɃ욄DnOzZ/hA}:IY}%YԊ£?R⦨HpA.PTEXXXݝæqYYTP@ш%O CXɅxO 9WJlqs)> wC ֮(ӍbKS{2_$l$G.R׈ 7f??R* G2 c%ps"2UđBA ≤L27-?٦eE:F+5*|[Or2kh1bև?f!!>,cL>b-wcbPP,x/wo2CY};U''#I`"jaJZ;mTca6JP48JPGmM>N ;+V3gRV .j+ 1y%d9FswݞIeY ԕt=ΣeQ("K 5sf9>rp{3`2~gp<璝N˰$==:ڹSa"GO0 2 )Pii<ƥqL+K/nETZ: )VQQT⧣k.bu}$J }di‘OIa!U+ȱDhmc4 T" 2ɳhYݷ)ȥt_i +q8APsǂ EEUH) XH&]!,lk7JV꺞٨&TUMI]/|mW5!QTUgɮXuCTD*͡UIPf7.e ֒2) lSKZ*Wj"u~^yTe!YOgJZ4Ֆ:2OJT;UU tbv*DRuRTʹݤPG$tȵJ]H)]@pdFaa^{ѻtS&3'f4dL3g^fJ~RRٲ`2-,pggZ&elu,7I l}$N9ι_X0ioYQEe ʚqhʝ颥o^_ ^خ\aEXC,jl]~C`AHH)q\ tM}Iig}'#AjA_`(rqεVzҤNiDب|?φ=8nNO=iciD(=8RH0g1rka 5WӤIsI4i\$M4ׅ$UchЛ!PSBC2Ygf!mL\D t]#+vcRT23X㌌7e )Y-|92WGژ!جV otu~+hF[{`mX̔\>hFGg¶T$Ua՜0)odJѴ%Id2/Mu`2%)lژjI>_|˵m6G\yK54+mL| LFB N(Eذ$eqܼŸV\%sx3ceYVAހIN ?^?2u0yFdW4tG&i1+L#X- aXflʪj.I?BdgLR}Aɾy#1Fhkb&аgSdI%z].)}n$Do!^zjq5aEkQ]C#4W\Bzh/l!51IX`q} gv"{7DI!.$81x+\#ƯuF &TrrYg, R39>d :ᵛ i&4+_ Hoȼv >t`r-_Z!6^M_asED 5fx߰+<'K'88ڻae y"rgdh>n$U1#^p#taɣeOJU5c mA|Om^3r m(fj 1*2IΟ:pDAF'h܊Zwz`=nΜAM 6ʪa<N}%:-\hrO1u +yin`cEqH1f_ZNL\53?BטOYD pV+_|{C6ZG׭/.xv&Ή 0h?6iݶ>y'PMs1~HK۱hN9`? bL$KAS29@ӓ5#UDǯ˲?p_G&ieCx\n2N$R\;iH5?IF΍1f3 5+(͂O31b1 DBl!bx]7w멛q)0S$k,d r&"~Ƃ ;v ͊բp1);tn|'!+uqCDJyR&[HUY&٨ | ď~ CI0*I5ciccxUb _|`oһʂ5!6t8m5r6㰠V4-D'c[$ؽ .<őHRIO." ("k '\m>fHyxx' 9Y,AtcӎXW4 44P.P?y]wMӜ4(W#H 7K^4O'W岢JI6|~%..R76J6Bh:tw'[DbQ( (hh4a*a;x/?k]PCqۖjٽs|-+)+PK<&Sj~s~g;k߈ko=˫Gsm9 2ϻoz_}l;f'bD b~]Ÿ|a*s(70#k Iԛ#\)ZTZ ^56rnP6UxY^ǪB'8e(Shl%3SPVN~&<΅`Rʲ vrkSf ks9-geYŕהbpqcܹTV`SV`||ٌ\@0U0;(86.AHڍs n3RL \ VB[q8.hHrӒ\fu҉ Ҙֆk~iBi煢bVT> Ifz+[`a[,^o6&i,۾؟rZmL4W\͇%,o1IsȕǸ s2\1IY Int>IBQx"&i4D&W]h4 iȏM6&i I 0喖]ݶuM淋4HRic##fG$h?U̴b1c;nSTTD4)}&B!M46puIN&u!mLҤIs]H4i\$M4ׅ1I&u!mLҤIs]5&fe^K&MePSb q&/"=P3LJiҤI^|eX819u]\IDJIVfƍF4iҤI&M4iҤI&M4iZҞ^nU%tEXtdate:create2017-10-09T14:11:41+02:00\r%tEXtdate:modify2017-10-09T14:05:35+02:00LtEXtSoftwaregnome-screenshot>IENDB`Eqonomize-1.5.3/doc/html/C/figures/incomes.png000066400000000000000000005211061416454732000212030ustar00rootroot00000000000000PNG  IHDR0XemgAMA a cHRMz&u0`:pQ<bKGDIDATxw$uMwUu=`0xO$ZV]i(魴z{vϮ'GR Ih x`m._{z|w̈a2ƽ7@P( BP( BP( BP( Bqu$Sw;? BP( BP(~ \sc??oGP( BP( Fs菿g|1c(* BP( BI mr `9U( BP( Bs9m7B4M;7؆BP(Hݫ U( B+0K\ |˪x"I=sTnp~_!;ib$)BP(?P`H*"|bHXP(fd d~-?ͮ3I&O__ƫ+ m%!mSW()KJj] Je='7!-y8H7K3\srBlBTmOe*4qySg>+PƷ!)ynW I,oGg*fn-O=þ^mI(NS/rrP )mScrXbٳŬb c@Xy/=/v BP(~0~io'~x XEHH%&xacM}v-疮~X,7` $=pW^=G?ʪ:fxU k_ѫTpC.Ѿ-VЙL!GSzkHLbwf 7"`.f>Wo= Q~<uwE"{(#(ĩ{΃}#+B >ދ{ѭ,/yNÙ[6t7.B@!9ā$,Ȗh]{-G^b}[ܺc@9ch,gUgqO`?ξ}Oy׽,mb_,ZǢMI(l{G"F} BP(n sW`KWH>Q8v}h|7~)1"a<(agΏPFV<^YWuTJ&+m>O<~66J8iH)ΚD '-Vny)^Y~5=m]NMkBȏ?xG>Ã$ot:z65=w< LC^$aܿyi%4?#Ny6L@3=#cq*+qj?[>i#Hw㊝RJ<%<'fsIHFhcxOxd];z%[! |\17.HU+)!عո5țlF֭ϽAe5k{rj0<)m7k.Am}]) BP@5tӍ w:us&Vuԡ H"Bhh,v\,YaxѼ)4t0ts.hn~٭Z~}կZVk0yL0S!t0 ^~K30ttϼ%

    ӧ]t1\.78W/t'^ӁӘ5ډK8W^Q( Bx B&DuTB!bA@o&31x|7BwGΫC L&&F!t{u?O}50K,.3>8FCG7q̙>F'X-9G"5Gp%qtupJ>rٽ#8a,G-#4p=SMhfvdF' Բ{wQrӲh9uGsz 9c.@bfAaؙchzJ#'tzjBXF jy7@&ɉQ9 Ofg*xm,_ڂkN nS[h}<8 d &(˸B-֫B%b"Yifvbh˚k'I3VrjXfAL_Z#e[KHd/9%OP麛QVƺV?#d-mn2Ls+Ǝn#tY!q*E4V˷&q|Yvֲ;a8H̉4Cvֱxm,o C9˙S93c˻<~5osAWHc H'zGW{9!ɮ7ˢͣogM{O4W-" U4w/9f=}xa< .Z(O=*Ϳ/NϬ$?8FPwE=mx4o>1VݟaQC+9wћlOem)No>¶JG]xMN,t,[IWCpJ/I&eNjBe 'O*؄Y]K\YTt ?!300JPw6 +iWHN;,zO!C˗T| BP(.΂d\$Js~%/LnBHFO卝GɔLʹηx~U*E wѳN6bl}\ez'rWy:JW1('>}ouI~ou&qzI;2 dhsf0cUwJ,[C^ُ똙Q^W/OnMh_[5P5sJYJ0n#y1 ^q^|~:U`?o[x-yxQ\BP8/L;_'^?Z XJ <_(i{_o/O401>?:_޳d%ͧ~ʾ>``qsD޻??x+6P]xNë;-2co~l!?/o;JYʫHcfɿ| NooXB`q_5ًOp&Y>=^?CFx?dFǣw&lJIb8xOllN!i^}mV9˞~ķM:CI;|Kv> '%'CP( {yo ^og8ӟpK[[v%C"b*?Kw5 lP}Z!OpMJ^vIV1jxc;!$c>+Ybղ%l̙Ey ɲ)IQS8Mne nMαck]ʓU]CH@WiWn ֦Ed_|NjZhZÇ>^+cӬClڰ\^]ތe>棏?cA?NlKN|[eAVr]. 'ur;:[8G"!g90ѣqZ+o]Lț9}{OxM kk`RVݚH] 7clI;iǎď~㷹8uA7PтQJc5wу vӏl]myvݲ/gM=VFE.I1qgAßbݪFt{+e Ӯj+_նj[pkGxq` o#9i覮EᱻۑM)NmHliwx]-^Uԩ/u`s 8; l@7W/"WXxlY/G|Oӯ{}_dm[--4~> AݻHV۶ɗ[EJD$ye+X3qz<,i#XW7ejA$5{^9sK5Zw.>ZXFR$O<*_V_]/ +up _8B H lװ$QGdŽ0Kk$U!VGSXB #˄7ʆMwXj:mp7uZ2w'~'.zt=GY 7gE..6@+f*@92nתc块_`ψ87,*Y'"D#J+¬u3 ͬ g3~e58n B BP(2o\M>N L̙[p?a>w0VʪkBNBLE8cԷ/>dCK0dc{3XG,݄ju*K6$eh#G8x/t66na1-!)mfFh ^O@´=Jg 6mcY%tw? >|*4SlDy456]?]dcLd^zA~7.RK8i]32G?I\߅pDcРIQSl;hċ,$5Ai1ɪN>jnٌLoj 6 % :عg/6z}\>ڀpeX8we&?/=!) A9С6u4LOPJq3׬_m7hhm6~M-B$Jll"lKjjjBâ`?I{ B˞ )d,O TsG?Uk͏&uM-|n'X[[ڇ1:%ܪmdvl[|4zx#ЅMM}#uBR`#:Q¬jԐH ]Cp;kڝ<&9Q>iW)${ܧ *@1^1m2;ct7y|s9rh 8х}fnm¡#'R' BPYWS9!/}i2K10ǞZHy6B yq>wu9M ݮ#SI,g쳊XIEKÁ( |~乿IΉ?[Ԇ`zw6ׯ}~0km{N䟩T`ѓ{ym˛8=vx*r?q4ϱ^/A>[py)Kq\:OoyV>Rޥdئes NiSV;%U%TD8#<Ͽ N=@־&.$mas-qzheKJ{7v; 6k2}\a_KCWBR!-V9h]~;泿z}#JJffg M1'7dq=\EGϽK1)1 }sTRP>U7__>%:d)Eү5aFY@)@'9g;[ID9RkXίEg|=&R"1<8F:+ \|So~s(`iŪ܅AMg[kӜP6)8?>U^(.l9:~Im'z{ؾΜ A;3!D[~V7'V.$tr:qN\۲(9?6ee=OR">BnN]( Bx0ٸm0)ąHD|zQwE8*gU[\d2[a &O@mcxtKwut 駳 <E&Svhie/p`0UYEbI|.ե8|z]=顒M1~bju 0(%ryF@L-Ξ:2[rU?o ˤIMGS&S&U3s)L׾#uܶv15N-Em_K:Y&HYq?-%]qjma-#SLkJhsX64 5e!4 01Ƅi]~BHT+?G޴ф5e}!˩?uX!e^?@U4xT*E2gO_B=ĩ bKw[o1^Փ<om0^~=}ɩL*Ŵ%ز2S7DU6{fsbf@`S*=`Ⱥ6 a'y|#,X#fZ}V u5ҞVI ^}wUeRq3cJbXS'ع8#yK ( BP(BbIƈF834A3Q]pHd2g2#HP2p3Rd&Tv>8Wߤ{Ң~--Wp,ʏiSԆʋϿO ^2vd#+ZTZ6ߵ>GȦ[RORX^~uZfYIߞw(/>tvO~JXL12uE< 3!jKKfHgK}k)oūۛYr36Khg"75uӃ[jeBrR"39cldLυYʑew% %po1K#e LdD}A6' b z{BVڄֱbi :E2!7Me4b^dyC|o#XYY.B0nmmZ"&yiWTHg>؃-l[\ÊFwPj]G?]f" O(AOHBѱ$wN~9vFWn_&ڊV[^DZnB3;xc뛘Koh"H0$"r),ig2_!L&%#os=|WQաat$\&3wb/AֳlCM{ef8, R2iLi1ȓҌRturo/o l^!$KPA>5 N\GƸ 7NBP(aG pE(3|$y'm蚛H 4飤 ܀$&!rqXQm+a8ơq4P}M!/ -eGfմ:(䋸lܸƠN֮6KVae>h3>8X ;GWăw$+WHKW#PG%ə8?BM$JGc ~2 V5Ax"ɬE]['ma ]r ҃|'DEzOQrD𺜄"ux)-anV\q7e'`-2(ҹn[ֈ'%\Y(hYk jZiigj Hwo!V_K%lN3#D ص>Ƈc:x`WP ҄PMp]#QJjoo,lr/Vi'OazhKı-ӵu6f"(Cc$|;W6,],[uN?mQr#*Njµ49NB FjLy{ﻝkᢾr|14|6Ԉ-ftH=+ְ#pѺh%+;Rg,k`Z e&s&umYF5>3I[A5P;L(7BMNoZ\>:)M 1ji544 Yz?b#ukh1"C rZ`}3>k!&I XiRI)A;:h!P˒XVUC[[#pH-T9DbtS B#l}vL1m˔{)9SfR",L{Vh9^fYyIllL}Z~` yv lN6_.uz緳sl3e9GW+SζϮVt;sӞc:ƅ]Mם9iegV.Fj#¾>wnlL;]^ /sgpN&O َWG%\obm{V? Ǚ1{gձtg`y积2cٶp *{2qRc۞#L[1]X imcZ3uy [ $w_C\BP( ŵ'B5|1SH ?pm/rCu1q]<]L/yE8WVr5ƘRv_lkRH>2Vn˖>X%4A٬7+ͪ k1tqͪ]}C1e‘)~?91L`Y&uu H$m7o$A֏5iBp0'5>#;McS3N{Z)%qn7`-IRpͩ,MyB=J6cuU_7lKCo/v>_0Mth۷c/^?  BP(S[!䩓ܾvBs]ٿo199ɇ?Vbh8/%4~1>EB B455000@P`ɒ%ضi:u;wzj',ΎR"!ˌ`ƕ!d?]]]W%^Yrui9}ӧNyTim3::Çصk\+/eٰa=m#*rzjll-ivmM\̺AR:z؁WX(V ,b$6cgHdFK QrB2L94[ZD]hڛ "abtHWBbrbXzW\5J9OfrR篟_!1 dq:8!4<^%)*l;")qDz(.~֮ F6t` _FY R.bƲ{1-kA,,jlۡL 7c-5iI>?`[J]!={Nq)YnuK"2wodnjFKC#z^P( BaA3AKk+Ht]gtdRs>>t BhqIe@\'^ͶmVXիaRgccc3tvvqA@yUJJ'XԳ+ !xWbtww_򨡡9+0 tfYgΰc9͛[ :tm۶o|z6߶+WxaSi΍km)bW(>~Mh`Iӵ!6|K4vW,7|yoN &b47?㫇,A^_'\s686Ahe edK$Y*qYHƍi&>cN_r1{>|>R wTF8ס9 ! s2NMSJLSE. p]ĸsE=.(-l[q-|!kheS,U%ضX6q*P6Z AX4+L˦LRUFbR,SEXA8%UVTFDEsu݈Cď[`cgkfaB zgn> BP(7 N88iZugK">,G>}$b:[\4 4_֬]:d $|r9@~U;뚦v:!fҞJ5k#Gӟrشiݸ\.;Q0رc2,0w}5sk޴/BG-$VL SP}Iʥ*4dyn _jU E! }TvL+ rܷ CP، >` U@w8B'^0q<ΚZv8cE| e8}IC,^NٜM߉ Do^9ˍ>ARBzTSFP8B]dLP,RDbY1 ˘{6/|c?, W%QЉP}g ЄɍXuj}ҥӊ7E4q*v4IR ضe?nW#4ȹٝa΋?pTqId̎rzq;}9aQ9"'&b[<g_lVc+!N:|1ƶs<q"$֎?YpP( BQ\seYX'z6W^!])Ru]g㭷Oާi~\u~ٳgih"Ԝؽ Wr(0f+W<!H&/RH)vrf|˕ |@ţ|].VlpG1S9EPK0X[~ 11ߍB#^COiSȣ>|ήW1Bmtqziei鼛h:t1[V~ea.A.}}? ܶI,[^$nZB3* mh\E lfQZ/Eht{?. s59-F*ߣ!bQ_E FF?#δ’T,[ \Œ4qSq/l[θtRbOnc>}N6[ 8rio64ok))}1}:ɏ=c X6 | S"Oek>ėv<5G?ç6OD;uĎq|w ;+_*5>9H/$k"Z{Tǫ>ZSARgOϐ``>~:DP( Muq!1 sx= 0?mNVa/_F4Zy_3)%uuu{ݥFiFq‘ '¢EfDz,&&&BЀQN'w}<Ғ?pB}ރbl{RgNqLf+-.DT*1>>F__?444r Hw^#$VKlK24|SΊ5hQULh(Y4IƲVK$vx\9tJ3v?4 ';ʥ hitAZV1/qEAYjXS ܰϠ)A `!q8/8'#otI&ƩFq-ӱ$3F š%p@*uNnlSK)>Y&qaO bM0o'b$oM-!$mun| H444i3mfpp}Q(D"|Ux,$Wvy--$m B088H]]@`\)I p&8Ie@FQp? j߀_ZO$;P_;Q41GGK%drL;e 5ŘmfP*Qe~BBP(wߧ-[J-[>Ȍ²w-}7"dllT*秡4Zts>ϲrJOL&X,/O )%뮻ioosJbr^x%^۲;︝{=8g O+&&''%Z[Zxkۛx<^{zhoo' .\!uٶ(b[L, aJTԆ>]OIsˬ{ gꙜ` K@>#etY;F_z,OPt`P*e5pL7No7nMNb&-u^p:;-Ws-}ұ=Xf$YgTH0teXRj|!z'ƒcbۍnpFq蚠T 4yKH-t@I[ăXpgz2QkiTr˲cllv~jkkI$Baʥ2ÔenVN863nzB흉$P0.РPwںJ0M(\ʖd|wkڒ%gbJ +W.|1_fHU,nT;\T2YD uNiH$cuއ) ʋ_KLK GP( :޲-LӼf[!dϞ=l{ A\fʕ(7ze{mvo&NH& äͅ頦L8R7zC>C{d)%pq-C{ٻ{dSg2\L!s7Dz?@:~9c)멘m2<##xnΝ+;/OYBK: C .ưmv =nf * u5^_aCcHi#ĕ}4 P©CQSA}b,F-uR9#Wpr(C2W!P_{X*VBgg'K,ʗ&Boo/5kL)%NӅ^ |ٳp8̲e&ul2ZZZf()%WI8:-sh%*#m0dy/miogSy:H Ky/ /-~ٰyCvc6bZQri#*bbөΙBM+ BP,f@JI:tc|=HRu wy'+VddxzN/^L]]5S!fvPoǻfq2{=?T[#xd9)/u:tS縛LK)پ-VX=V=vxE{{;> d2=y4C5^ "a/!JS8p:1!0( hncaxm#L/37{ 465{fFF3˿yB Je~Gzt,zcO&+qϐό z.݄1(qt#5-%N u|uF]4/#]RCr\./gKV=N~.f6˃. 8Q˨⌌᭭򢊤e ;9r""Qj&D~xœ:'(n&X?Ĕkxݸ)1?IӴ',7ٹs'֭ U,5ltwrhNַ>ʭbL/f4& j67.p,(2`]{%n},{~W?擎Áhl,%.S2 .kJ8bκQNg@CpxAU( B(<)Jl۶eCZE.S̄ p8X~N%4660<<=R gnwy׻ĸH) B}ם30hkkBf||b9G!3Zk^Xf]rAuu?C⍘4P)TH&k)/Jb.:vcWxQN<`|lPh1 wc#뚣B܏3Իt6/֮Ե`VJ3\Hb?MKC-g߶?sYCP BP.8T1/i풌O8~gJ'Bs6p})^:%u}SG_"1qMsSvw8d+_< U}Ià%kQ Ng"H`i蠱:>[oEKK ~|>/^޽H$46^9zg>$ [}SO=Cw^b7"Jоjフ/ ur9r=Q`T\``LĮ$Sm!x"͋ZߗcBP(J1Ol& rm]rZTضmuP*8s4=qYj\'.P.( w/o>x?r5\ ! _9?rJy^Ld׮] yRQ,d0MX< &~-f9IvrP˯ېeUH '8nݸӧp~.IJ &F F0ZBih@RpqB!M1֮YACd >~pt 9-lBk"艓I1I&3A:?ַއn߆ma8Y!y[@!VBۖ=U7 !lh>Oec2Lva6L M8~8x0  GYf w歷blذ0viWLWڒ>&&&!'ODeYLRܱk ű z3bb2[$iټ(Oc5x+r-B\Eyxc@:Zt89Qɰiإ<+xsW( BP(p>7$)%H7P#O02:JXF_SJICOcM^ z~ 5՞>eg8ƶB<^RK222$~;?ٰaBo\| Qj"-ij HLT\HӶxl Vm͕ʚ!o9^)/ BPgXcz16 ahvQuMQ^^ Mܵ\Ũs>C Wpw,.';~ ^K)% ՝ܝ;v:ljF\A?<S.3gXd eqQl{mN8}8dӦM$/sbʕU,IuV5&&b8cqq}Ҷi{!o dMq{!=M>'T,BL&]]]ScXdɌT*3s,dYs"tUQ8!*4ǿE̝;qڌmbL_K#mpͿyx-B=R+'~ti.{op:#/#HX$lY˰LMl}%\wBP( ōb!r|KiN䮻^P&%k{!eAuхE<~8ccceb%mx<ݻu zzzVv)x<^x֭[GCCJ$dH$XfTƶm6_]x'qJQ{f";9gKBCk-b}kXvѦe8) BPܬ04+4"1_fJn3A"axZ4_MR~cê-;\u.4ضƴntKYtyдk2\mkǵA1B@<+nsi?v~?~BH"ŋ3o\1m!ez}=/}q4qӞzr-Kif2)Wrdc#N7P#a]S1/ BPD/P( 'NS(.0Ș *!XBL[qP( JP(whB?No 2FOD BmCbilm [x^^Z4 $ "Ҷ)H NMh\.jC!t]WuP(CӴꮁmcwLs]6Bc8uE"&չo 4bIbE'%RT[&!֐ n"ڔLJwpBdzM@(AJ9?ݟNO2ey!39|T:MXE:.Fini% 0הmz޵΃BP(;\iT*8v(de˖A0T 5CӴwg T*Hr4ۭ7!4tN 0X ݁&t$6m/(Vl)i><^$P1m*űXd.B~}MX%1&pg+!Fg?Va̵&xw WOxiwY$dxhar,t@ @gg'M(J 3<<%o-d+:*۵@Re(5AϜJ9AߋI+ L1=)>uÇJ&ꢧsYbuuuʇsAƶ% ][ڸCƶll9eL05fǏdE{v0}ʱz: tWXD,ضЪA9v@|?R *O÷+Bl>gyFj_~Bf–ce%C(&1^7$/NhЁ:)+!nL[hS Qbd8u<}G?zaD5Ŋ"d~4M {mWk擜`R-д\U>cr<0y:ܺ}JP(DaYt'OpAlbڵ_e:::pLLLp!l=;:X~ \yYJ}_6ыo5@`%)cְܳw~Kl&'Fd, W\4 ӽd)͵7yC! EòU9iM#{$OX@&bwx761=F D2Gxi ~.%l{WՁ/ :8{S i> 9_~ϰ7MϦGԣ4! 8:M{āA*Wf0Bw8(PM ['6YFZr),_ʡ ?,0:4  `dMX}ׇCc94侇dnXT4M4flٲF Tu֝cz tOIs%˦Tc5|+Q34ED 7M@3na 1FGF477C؈˲躎7QWWG$[rQrhimrbdb4㘖EG۸e/28=~*&68 A|t56K>1@ BsU+08p' SWWǺuHR<3ɏ¶-{^ߺ︃?1 cYX ?y8wt6,FM39g+;|uS}9/}NZu~zyPKzf:6oߍ&$%rwejHӏ.n`^2+h2B@41j,`xi쏈,{ XO S)%B")E5lqx(C,kbB#YE6/ c(ytt4ȏFO' :\ٚcfcSl}oeYce8U۶9qD6:;;|sNs^dz !(LӺl azgzv-gׅ}~>X,2<4D2$r=ĵRi=Kf^$B|Jܺ)>ȠBbLPLAVeWJ sf$Ce(PYY8nF~V; NsU66:p>^\JY/i*Nd3@ڶK͸,)w%( nrtz֬ БtZv۶}:FTڴϑjy:#??BqBH-/ѯ{f5:t60c[OT7+` g{ʝ j>撦w8y=h))Hf-ߴYzùrv{8f'H9eM6G޹3ۼ߶kl݌ӤdW vPjtsxI` 'R$L/y W 8[zVv{p^/n `ъ[.4wf|g]' c8u SZض[4j#umcFMŲ,$RJ,rZJY O{RH97P۩aQVo9/8-]zsmj_QOhd)JFZ`Z.>gݏ`|l\6 ߏ?)v===3J =e%sw022d:M<^,aP#86F[ `;Y<:{M[{_ 4vKWӮbv=W'Si۳\n B>\FyyYR$IB!Φ88|vמ)36'S4Finåk`I3, UQiM᡾KG&T`}aNfb `3+;X<ɉ4FM;g4Fikiұ v$/ΰ$M utw3 L+Yh9Ϫ@bm"W%zkxuU K29otlް>>#d);^6.­Y,laRz LQ iko&1(x韰{ŭIt-28!*+ 4EK`.iVq2Щk[dnm#7OPkVv5x^&W" "M!ƓYLCsK3eҲ._Aӟ&>1>h{5T/Mcn.TbZTUUyF1=Ʃ3mmDePqNaHa;<$#)t_֖S&BHTr!@r>C*Y%.4ơU]*  J B}MHʹ$IJ /Dc}fqq2%Om=m 隃M]t(KbvNxM9#ll0ISg54+L&(S8m8ιHSYiiIAh衭>6},fd,K? MpZ8d>6Cc6:T)GXN{.+f1K2QN1DhǥW+K2<#_ 5Rgrtxױ!Ljt1R.k4Fʅ 'J{KRrXmmn..U!KRJt]?gbZIp=Ω;L}>^C[9D ɧJeom uAtd8boM͍u|,phC!9Aewv|2d^N0@<_ ~> ߊjo:7ى 'X\>ih$sV'cC'j< NI)E:::hiipyfnJ"[n+Vk.hni|Lp&;P;?O06#SFhijs31džN[ۨ -DrD\Խ44sU R reQI*V6$\X-%$UгZ%"%)P5P(3[G pPyJ%_BB5룯ޙ?g޽kVSCs?3AGџfY31}DC: {Ӽzwc221Cе;v_NZx`~Wgv~ӗqv#좜~.^ӅGz'~U2t[l#gqkQJr`hb8݄:oeYJ0njƣ[Dbˤ9gfk:N%5Qy~7`Qd듯k_/!eMTe8p}q&N w5-gכ[(p<4Där/:&ΰm!h~ሏݯkG T_(w+-SpSL ]duD=ÁolݏЉ+u?$NFVSG04l? N} IUe)[l>4Bw{:Vogm4SadRPZaVnus t]x~ƇTawoib0z(/ Gh.2'C~qUgj;_gב-c-ι#hK 9r>L6^|qc Ca(o쿄rX4Cx㗯q; FёQ+n\AS '8(=I9F.e^*,8k` l%mSY@$<FuTUSCo)H]r2ƇO!l8~rdp*xtF:_em BÜ:x\2V`U$^|vEMqF&3N|=of yA%4~OXKLvNTHLlq *BG:{Sϩ Hqc Fu, !]m<7BYCY>؍=djt~Jߟ̍BǙO1yf*++ABQr=eeeif&L{{;P1V B3xc4,)/$S9uiT !N8ZH⸁Ǯ0=wHz|v-sLkKugt*Pw ͆*wqBe[T|=Υ#o˗[2 r).9̴ c4)āx hSj>&&&&&(ڀ˟5o| )%"TʟswSUUŁbÆ hѣG1 6*(b͚Lx<2%V9]XZb>9KXEV዇9ޡT-,nYTzA/nfՒe$)*8ɲŠe y o~Q}iڇr\J!z.E2.%zehQw`k G9u-B54Tx- Yu2~vKj0M LI Ѳt95)2_գc|;cOʋSR-pT}}ܱJ#at~Gty~,% 8TRE5D&/X)kZŠE9R9òA>-al:YV,[ۥaQ\pȘPՃ "{G@zH%wg{}ɧlŔ72:tl$A3o2ꇤ pTIt(Jc`#GЫ`͊ňvv\$KJ8bee 355wj]F4{ԮעŇxKzbt#QU1إ[h)$2:ʇ>:wփ&EHhivZ m@ |;vdwc+8GÈl *HLHF8||Ah4ׁ%EIʩ)Na%T^>8I1ֱZx}v:.YM1NeC=%v}$i$2p9Kh?1,Fh"cXV-ʑI<GBvD;ج6***xx?s*++ټy3d2di틼gt0SRs'J6QZY r +IDATdbBK4ǁ$H,"[SYACmZO}=E"-XT.I9[w/'谠W9}H.ȑzCT^ HOvk64M`%M$&31111h`XN;ٰaLNNGGqN:i|tr!ywpxɰFVt1-$+wsfL_s V`B T FgΑo%Ru楤X!7rcmcT.3YOYaoL4=}>N~݊bPVRm8K(H9 da[J/Ǯ}ܳn1)?„#wQBϞ/恕%XKYPj*tLivBP=,>lF:D' NzR~mun0Mͪ{0Ģ&"D>Mu٢TH]F\^\.7)š^ P\k!PE{FWUGۿ8Ãei}#} %6ݍn 8x' "r r!nU()%څs}mQfSFڋy-ӻy]~uv ;]>Nd"C,N5mMs}v> \N@j`e>4 UQ;?W4G:hGΜS(56v{gr6A1Auh! T܃.359@*v;V.aE&(~1}׶^^MpYl|4_n"^'6)%(i"˨z9K ."AEիQ L5!_~ _YRq1c'$Bqbs5P;y.r[H:x\"`p[ 6rGjsq( 04o Za/bt:؋yH3+Ɵdϟ$v}ܽ* 6g>:'{h gcf<7^O|Wkp'O+!V%Kxٿ{{{9}4Dkײlٲ$ ױ_acʛx%ܡz陴r׷؂>G#d.,-".?T @:1E8PpxKUqc+[IA_FJpyp9 Pҁݿ!Oƪ0Oe{XP!lMPUl.C[yj(+-0  8N9s ---m*oGe}L&ib ̜&48iƌTwӵ,YøBtJ&ih3 ͻ.%w%|klirgxͣDwG` Fjza~P` _~d Kq*+ yq`wм9 \d) &9{'wWVUѳILE(:O^`uWޥ.?L%kXQǐ:LzH)Xm:٬Vtx+e"ӣ3J Vh+pO㉟EE/ ə':>5bSLF'Ig QQԲ$u#/8spduQ^v "`}"lzil(yP|Jp/;;O"|ՌG鏒V:;0:-G[jx'CI}&y3r 2?N8͙_-9}Mu {_~:IBh ϔ"-CW_1̋?{N}Q !n^/~t:Mww7uuuTVV26662OYMO:U' ˷! twrcLEy9v&0~M}U\緹u'fYy'(?)kʯ|~C0K冹4&2OKoD1󟮑HgD c?#!IxnW̥$N+}jLLLLL>)|zdt{ Ѽt A(JpDq-?AвiIZ81,8҉F2cr,BUY!0Aȑfgm_ yo-dbӈ@j;NszH"SOTZʘt'󎙂V/+7mcm xm3RD,ϋ?sq?+-DE!q ObCGN)Zd*@)u5EDFCKңQVQT;uMGB'>!C%~W0>TJ_>r2?}ӲIR1w-(a ]hŠnLLͤL:m^b N q%<4 .f$ "#c5$}#,(>FCȂ!"("(a*eۘ%ɯPߴxREqV.᫿ܷI{G/-@I.LJtd*f)e[/!xJ"O* h=MgMrY$V:XleH,d3i ΣN %z (jz~t D5V$e>cblWk=~',x޲†97B̥>zgf$ii=Ŀ7UQt  %noEw?=*.\B8VȋvLV'0g 0O|]pr-S0c~gtB+2L\ÜtI&#_֯ t_!/-R|g"wH=C"C5GۿklOZlO]I&LMMvٲe Vu΢- F|cm}BpC%|xec>|1TOI;G4Ws4RQQ,Lp\=i7O?9G+TUӽdO4joַXNA)qݳL/0+$,  /PRRElrCnb$ v*Xg|VB%ʋx+qF9x l xꚭxb/cgqw8+D:z= ^xJ/d2L&d*Nyt ?֌#WPTQK$u $Ǔ>CBqg;H[nQ)~w9Fkݔ,Ugx_ E֕lK/ϟftR*|*Yc٪EszƱsi >O{4=w "MGvޱ8g:J$H&|h!HJhY ?AdF9kKWl +ӈ.oĉ੟Y%KVƆFjBdbi).C~Xė vx^~4Ta(h)NˀV璌M,$C+ 1usm y( 6m}/2,o*d)o^Fm<@`Cm(gɥH%NUw59Chs+v-KCԭ%.rQ kx"eO"RIR4Fz{{Z4~dJDd|}*,7,KT2J,15=H8ounK;=!+ove|ޕ8(XVJ™.l`iaJ޹'0U!9BuXP)HēR ,kAO'Slx):E#kJYd,e \|~/O?a͊f2Ru 6ѸJaPC~4fǺfX,eT2K4-\THe5&~n1i8Dɩir %N$HD H$Dd֍wmNFXq }A:>;GrJRg93h/CG%1LDItlBFH$DcItiEKƉ$$"QYIM<o<}#CFxy+G@.fEW`UygRZ>tC_TE0TfC(dͭe\hg h$kqj44(xd,F2ᶠgIR1 DŃL`h2C<2EO E$qR4D C0r)tT:Kns>V/-` UK%Gqkٲ~9OO>ŵ( EuhP$)"ZЅJiRVsNƕR4jeÆ "Fb\LD"Eܕ{+غ;Ng9 X/ 6;EeyZu+YT[KW7`raJ1k֭+߂e!ar9 Cٰ~vK~" SS e,&lnq]d1.R>Nbs9(gYcvdB Tz Ne,[XAlAlZ\,CNr('")ݸ%4V si<夤r.YL&'U˨.rh;NH[ؼodEQpBKڬ爄%exÔ)*,._3V|&ɴtr9(.rch ]A{|ґiKV %^R҉,@6yg jQ&|F A.s _ Es>{97k\=N ^ښy(*yEU(+iCi pTG-R12e5o&)U̽n&oh?׶{Q8׬ l6f :=DbasUIS<%Z=3E%ˑr׻ϵow{Wk񍟣q3[%`|l8&LssС Okk+CCCttvQ\Rr2]g;|߻RV Gٟx}^TZ{L&8w p m6\.$3sXiݻ#GP\\–E6 1=ދaa1:Rt:W||96#D4u^{SNqE?CQzZ,!nUUF4\.B~]q: w~whksgٺmiB"e^N]ĆⅬ[\SA T~o~MN>t8LyE-KxlvuL#ˑdѤ:ɯ|!B_^>łEx}e|il݈:_EQ7ߋ5H#D?z\ٴ&>v}VsFQQQjtU|TVUΤ1FG9}4p7RRRb(l$Gx^BbjxLLLLLL>M|`atO$2Dy&:|,C[>0!%/G8r/^ P^^JyE+XH6~7|ͯ}޽ BQ , eU)ۆ|eГwX0.p0WJIQ\8ʱO26ˎӀdʯQ^ yq X]5݅]BnzXJ*Pհ EL*Ieł"b&뜟p96k`TUUQahh{ښjjkq8!b`` S\RB}C㼷䚘|ZP40LOl6**+2B4r9t#?pV-TE|WޏU_]׈Nt|z|&,3Bk:z~+˭> v'PUXmNLƍ0400|QE(Kck #X-*eH)),gt ?W!0RQY۟Tn1)%##IRh0EQp\JJ8aj`|h50BP}o>,V QUU |w @J֯n%CUA cGXQdÇDI&^FnMCWM>zTTVR "NDH&rp:]N?511111fibrknf(BX혎 4Rp:q| RJv;躎i)TgZ6s97aLr͉ˌsBzv Ӂabb!O2\0 'Mi|<-fMoDQrW^r\~U3vv!$M!)DUTV}1Oa0<2rabbbEJl6EEE> )%E >v5 o,V+9y-H)@us"fbbnj"3111෌mvsmpVmc<ۍMn7f411,03PsmqEZxOa 0WCMLB.ɇ ŬSۄiWLn7f`P1giHo:B4D)lh,NI0d Wr9H$FiWLnG) |!l].3!NLsnΖJ缃{o4 !Kc DCH*8, 51A8U, U8-Id#iE"ۆ&!}g!)l fgDWh V$ߝ|˰ sݧ) `br5#¬Oۍ&&7Lkbb@e*}!&/Vabbbbbbbbbbb"G rv_J0h'r($ay3I:6M\yowLL0EUQ?aڬB( B!;bƦ3]wPf i" 1G_b}fBAQ {R af|6y_ '8u #uP,V\;`Ii>8 '<} =CtPT+.b#XRN]] >ZG ??_>b!{qʬf(aΟ>Md WQKW*`E3"2<EXlX,V|R*fɇ@fc=}I͎Eds:ŊEdY5[ԙ 6_Ne`:mn\@cUi>[zz '5l6+J*JC8fgժbŢ/΢CC];^FBCG(VF]/x %XDqq>no9O\Jō+پyENujBVRgAZY66{DNf$xo}|r8g?Nx΃g~PBpltBfpy# br!8?sfoq1AB$sm E!'o')t E| KB"PR${SKFF_$䓍gOyiJ $F?Ch5+&Wר]N). ;7`H%a${8LT@OZ( Qa T;u;7T!eK){i[܁S{ށqEG@OM1RQAX].ʙ voZ>j(ڐ9v}#z#>ɏw w~WZ6CԗIsOItxﲛ&D"`͖/Q؄KL*]YZY}r, eHb"Nv=4Q Q0RdҤRir,D:td2EN7 Wɇk$t]J\&M&o+3$Z.f^WKNO瘎Ifr@zNu^d6&63:%L)B;E-g,m6&9\>4H$)rlT*E:`NtYꆁ4t2tC#\TJ8s=CˑNI3㋚ TAz]>U8Ta躎aHEl޺j \Ps<8=J,$(A >P sf2$LH$HevSWU1VȤS$TCϑL&H2I )y|4c344]G("0t̀ (sZ/ۈU6zA6%෿=3r.ӉDUH%$Rp }oj}ɗ0tr9-o ]#J~PsfH -K*,fk?O mS)4tH (`QQU("Z`x2F2|]IuN`wfڅt("?m6f`d83ڡs#܇D}Db^ٌUx8?I|{tB\9^fCsu˜&"Y 1M0Ѯ(=ʷ4.74i^x,9s=_d:c:>'|(qs^) TO%7.ᅣ8|MwE9@~k,)wzb'Q/xLL308,nM3G׹cc*S)l֯_EFj}v2@95zΞ\_cCs8yE{G/Irk=0vä*W];ϰ+#ktd|>j# QKT@,iI;JdEOf)iXº-x,xg;*WSq)zV6=pl'u|{ IG9{'ݙ ? %u鳌e|+$p,IdjM[SD8]j,^Sd9NQ>:o1a>6zF:bYT0g BIe-v`rlD^Eh ݻT8яeTYvѿicHE,ϼѤܵ+k1r).͛N3sryBN^7}c3;@T\2};sUA?}=&ZG {x魣 21/<޶QrRq u۾ @R MNFG6@kqR?'wą T9kxW~?C0߹/wOf"mOeDrF~e61Ϋ;t$ز:{Յ,0{Y~w%[?/$'=[k[ݏ!TwҶR60w/rSO!J[V#: gKϳ YCW8tiMOq:pɜ[ i{%^>֏*Z+bG?CyGsI>8ݷ"b.|Ȕ ]CJbE{Xn+U pB"|h;YtǃHra<nfb\5J!ccS߇|!X$8u>̲/mgQ.Yx3njtx_'l55̞]PVb7Bi\&)A h] N hA{ahq+-XPW^S2)?DMՂ qUֲ!#_}z ;?}60$7^^z[ʆT_o^}3gkE-!E=K[)87;(obAC2bÒgx}r.H^:Ѩݹ"@65t}`+[@~8 -x$8KgI#Wlh#6Bp`Q-8]n7295meU45-Dq𒤯[` wY55Vɑ0j{OJ~ۭx "6lKYhE\ͦZV ^S@y4_ƐSm}K¶Uʰ`-oލa;kaϩ] C?yޓvZDF!ɞclhZ]QfQ/ⷫR6S"}e7]7T`Uu5KFyWs+lwnho3j8*YE@a j( ) y1 j0d [soᰡV\n7t^|,$v0Ͳ᫿Ŋ%M,5-kh\H'EcEd_{i_`8r'嬯)"ڻ݂{Ġw܃;RcPְfFz>mY+.U07pl E!=Λ_  U7MvkR۸ j"/âӰ FW4!4KZ6S4m^O/6Xش9 '94!#wPV4x]xql,jP͒es j|iyccatVUV3ڔ,P>j౻Wct}HBH&F,vB, bYjc$ c}]hT6.LiBFFGy7ijld;λ<};qL VjƻhP皳GUbxVoɏyt__cceWY;"%RJŁBa?(oe(u|R`!.b#3Re8q -Ky Ѯa"A˙CHܴ)[ w&RXq)zAƒ\6_ÐdqGz 1r?* M&6@A qX,UT"ja$$#<:AQU5^lg@bX45.t\YS\(Ua)dcO@.d{G)Z!#)scL9,ée# jRJbJ-V{Hɼ=nV0 .VlY_pbXB[}:7RaBD'Ex E2ً;e+Eip=/VBxdс(b =`/zl,ع6~<[ ```u8ry@&D^GfŘu5&aj2 ,VK~|$540>ʼn)'c3I,ǻI:T&JTPj %2Ð`Y>a}HdESG/=@,j >2BQ1b=pOj\S6~~ 'u;f;@ P+$Ii蟣d8v lڸɽwES<3&Hu(>ľqTu\^ԑ>N$UH)ѵDl_gK8kaOp"UQP\^|L,֠"/ʬB ^"_"LF3\{e\"Sq4w|N3Շ z$FbUͯDJBLNft*);ݗ^=q YhF^2aqVl qvʜg[ݝ0pj?za1GYivk!*V!;˱ͤ躆. v$Mqd&il UQRv%k zn!)N)Bα-nJRq]. 9(ZqJ(/ WvD}ЅDF8vaC(("$隈(e J&BdY TS P 6.K*vmnQ0ⓏXԼ sӼPP %~/) "kee;ߦ-!(+ǂrbfhNM Ql!6=~ie^h@n#';p36sٓq,cAi27;O184H (Dm\R2#*ł]11Ih駮5}aOA:vϾ&{ط-Nwauymlݝ9;n! ʜ ͷV4P[]Cm8zp wi5UTVRIx;Y9[o'faa ,';'hi&;z];ޡ=Pݸj\3L'zK)i|9N&NgpUtB\x^zSUqIΟ8H,KQi zxZB>;KRWUPO3řG85DJR^]GOpn/stvqa8Bp i4֔hk`'aY\x{vs0`ee;.T\V$k"} 0 u۠ q]8pQ@IjAoWCtwvs4wRNd}3:2bBAcO>iօ #mNuORҰ*?;E4;ص:-.hΫs;>֎/cQK-d'oCۄUW# 'x-GFz;\OPָbmyDsn[(QSӜ;~ Nm/׏o殍(r[owՙ!D)Jv xٟ]{/ G'4*E61'Z#>!W+e~6 ϋêYi7H":.#pUltp,C#O9=.T3@Ozp(Q:ud+N%Ѕ߇ӪD1:؜g>T2D1RY׏mȥGIk: ϋݦgLOG .A}'[E訸>Ve62ȥDd{Q4h]xl6I$@`9yݨB"ux4B4bsIkW54SaJKKx]ϦDd4b`'tmd1$V| .! R(dau{KD4J*yqZU4ȥ# 4T^ &a \tTp]6L2F4σ4K6%RZZr)(C#OfBAU%:!+ldaucS P^VUAYb붣`0pm~!pxkmݸMʼnlN7>#mL9=1u)qmr)-)F.C4!?nQ(ɌPT\^nzࡑKIkK.8%DX0Pm.A?vB.'K +`{@f 19쪾M˦ił_1)ȥLGSX|.x4H;o3ɦ^ Th,Tmx>$LGhRv^}6B05f EgS(ۃۑ"3D#1DQJ~+P*!O#-?vqΏ׳X C)‘899TcERwQDOߋ"2Icd py$Lǒ l\v FaŊbdƓ)iB89'[W^ =n 3{VEJ-Nl3smf^G.7y-"s5 {]V?DhɟN,/΋^Sǜ\٫ȹΙk˓-oF M\Ӯfr3H9o$lWOQR,~weN0m\nz쮶 3cwL>B_GY {kYҮrkۄh\:ySíp=r{$ f\n l煆 pci{\9H97_*=o UqmwbVDݬ[;0f?y-M=36rf 3gL3uc붣ٶ;Gжf4;g56ޯ}g!^|_U58~0keynTwS*5#Iu^2<*ˍ37ku }6YZqe[ݳ_6! 9;pD*&S*]5fv6 z:JOwz#,U^)lf<߰\}ηo5mDžuDl[*d_3#o/&9Waj^%n~.:fԼmBg_DxrJa?|r1w- p蕧_aC?Ձa%wY}PG# GLLL>R 3qۧ[) :0|O,;#TB-[wۏU-|ґ`2Q\ZFi}k6Ii\ʯe 9011{_?[^]0MHԷB&0MLL>5H иTqaiqߴ;&&&x3`hӧԦ3(s0a? \Ov#DQ!%n6O"mP~\W v6M-I.#kN>4l6kLL !4 l6g>.ש4mJbA!#ȷA.y'립1L2ن@uKTU Ӂ % "|"Qm6졢] n&eljiWLn7`nw1L>~?'EEAlr&C!z=s!Pe111b&.ȧ(׭018BAa1oۄPA611̓%J4LN,٫>\]QD;q_N</s [~ƭPTUEUUL!P 﫪ܸ2p)"4s}u#G,&`;c2^O'"ID#a&Sٛq#_}N&2y;nj Q\2aNtEz>֭E~碴3ؕJ.:&m!6R3Ӻsn` 6cGPF8uὬ* ]'A8r9\&j`5V52uh"Fjw74bז]_K"`|tM_Rn+T5 p"Z rd26Ed)gJjpZ43oᯤGR\L|!b!> Gv=ේG ì.TM3dk#KTJQ“$25wo4g89_ƝK;U3304fׁStwwrc5:|g:?͏ͯ-_)AV&xݬ}q)Bs}$2i ڄLk^9wKj~O~u>μo(){? ,a:s~?ʒr.2G!vbp36}y. !/w[y|fj}XUM~u^=}EV%v8KCR~p=8\b.{, >W_n*Gz 54,':HPT̪Qu?++RgAb9 l?Ab7eh-}6[F|zڞɼ=2ᔃ;4μǟkwh@fGCª\i=":åI6z(Bb(nw9aɧT^OJ@ЌXA,|bl4ɲ{}~;Cɟrj\u2zEM>3)ʬa\>M]HsU;M_,1Rdݸ~0 ѰQwfρ*\=qճYwof$=njr>ΞGВ}5"upgK ǖ4T a*``&0~wC svxu*m7'(WMEQubanDcEQklt~%UZ*vTY;.o\nӎ|"C"C,^?Ba͖->F,@,BMMri|w/:x nz'_AL'`/=D)lE5X܀ .)--!{ Wfi.qP],X:oz{"&$nڨkg*N?@͒Uxט2KZĆm[Q`,vĿNWy>fA= _ @n~\3T]l9Fz/rd)w57} 0pF2.nBS QJ=t=AVITG+or~vO,##AvER;x|j! EQ(E Q%,..8yTW%kP ՍYpf7SlcH7+-T+ 1\m{wZ{UT"MD !z蜄FuI#@_j H;Ri"}!\`b96DJR",* \ZMtYC&:ӧhp&,(n'@KGh?S6MT21z/qgz9z!NC3RBlܺ n: Ӭ{1-g"2-olu^"%⤡9#?NOq k6,U`k`h<-PͲMx >.^bh"5P5qK A6:o'd ^PFjΞq*­IL} Wr;JYq- %d1{(zz4-gۚVk[I0fc?3{2ʜ-\rK&j8i^% eXx?m;`˩ _Y-[ Νej*$@oUw=Ɔz.h:Unzϝ{,E͒[VHsz3߿kqgjBA7!0|4(LΕy0BYUimd v1rQqyFvmHKHvsXKerBN bC1Ӵ|++-MtG GQ Z;$EuyVr|gmu߽gxx"-8Nx *g$[uрE\N~wb8&v<hYU D!0Q/;LLPߺe͕n0\t0PH"%T%uQւʱy?xqU.iZ6goe"-8 μ+o#-؉⩽]hqxӿ^{&o[H_Gm.%h4+ IE†n?I9q9(DspHgFl!ΐVmxgͿyz.ʑopj4gw_"w@,#\pէg@%Fx'gϟtO+[$vx{9ʛ|8HPlYvx:22w)2O\`繓Է~MyAHI6DXE%4өcoW3?>}?&FpU5 2FWNR0a8,j!C'JDJX\8fVT!D*;%x{/~:c݆ɮS89ozbkDFd7;^}qĘ8pw _ٟsm8F &!(;J75y-ZCc4Z%gzu!8v$䝧o]D{yEܕM61vg#sx%ԗ0#ӿ/R!\{?~icl,GLf io%MvN O׹'pfw|y+; N(겊mN:mo7nI6l'vl+dV%v B dkiwf̜9wh%Ig斳4_A?/W^Muig_ 5L&AΟI3׶rk![?}^Lm|ñ(B($'zt'a;DHjo`Q (zGSf!+֬>GS&|i|,WJ-[{䖾ϟy/8rׯK/bfꚚpUgT״u>V-]~Vn\Z˂˜[]Phq}z%bd}74n]r9v[륔s>ϞS^'4JoNF*Ŝ{ h隍@Ƃ&[ƛtk'IIyqi7I*61ƽM7M(b6dyMI #o~ _MR'h>c딹8}X.5;7>?}~Q,/ίFJGVO(&L& D|VU%LyZ0IT=IRik*V D/`Cyn)??s${_r7ÈZȱ=`(AMl[ | zºF*-{p=I6 5ɛ9pv+qV;L&la^}Wl ~itH2ALO'X)T59A'K.c~m+ݾedǐ%x+„D ;5zr jj^=ɮ^uuXx#S N~x-5-~CCE٘Bи|0-\&h}'زY d^LneJ@t{ KQd@5E~%>A)v5xSKl#, 5.D6WcbE0.qlyT5,H]SChqb·:5LBnU-N'rVBԢeCS6by%#mm9J:<,*ᵓ!V)*+}zs@H~~_(Ǔ?9ϕ;4pǖM~F榻֑7W7>9Y<+X2XX]G^޾lTȩbRʪ7k1ѐ+z3*4svϛWl eX-F)VCQ`Q5dZ.|d /ym66,;;pjOfbnhٟ|G^ O,X`|6֕گ&uX6+vXv9O|}!s-W] Vb͖Ȱ ѱ:xBQD:CJֵ ȒjN bbM:S7x5T/@fh<@2%2)!jUKbc WvUT3f  Q(_‚7ط,,D(ڇ5|`H 'e9YXm=C]sZE*D`s: OdcJ[51 &!Njab2bBU&IfłnO%T,ddyqTbPT9T-AD{\_tBP.jJrokW/8F֔ łN, Ɍbt`3 noX"L8w8 tMń|bBman;^JWΖ;6 28]WGI: Y CLrk3̅>4iZ~E'v ńC"C=z ]OG^(~4 _L2 ϰ}VeGٵ(w>ljTTJiZPwx-‘lݾ]^#4$=o^9]g>҆54ؽ 9eؕ``G Z*)MMrS֑z4`8؝r汶b>B6\d;XaO%m::\Sb-edl@2 (X\LJ*[*)ӑOsމi6@$?ÇYtLKb8d*(d I%bn~ܾL!8poξc-dO!ؾ$}Wd:Mj<ͧ P6ƋO]qUTxk'TIMzWONH#\DJ>$cFF6ONJLy,ɡe3<4QN|瞟bϱ>'ƾ8~{h>NfM%^K*POБSͿ^9됩: }]LDCF%500yW !v>t1<$b1&{!z%/ 6 Y.BAp~&4T5eWM< qW _x]~4]#38@'%tXh< BAq:{]lLP aa$ƆSɢlΝj%8ݗ-]|t6d:!lKV-idߛ' W22 +*i?Dzq-3$ɤ(Oea^|nX<MLS9-R2V/[piIes*G(w (ՒGCNfEA F4㫣n$ZZB? grgH$R 8- UECiفP YU\YI}a(TX͹VBWDMi" !Nv+ DFiH.]BD8]5^5a)WG%'c~oXEMI$+DL!"7NRt5yeDRC%BSfu0SFTVayKS.ə_-ο_=XTKUQUTU!9[w6%ts2U&_kVM v":Hpq%Vxhi(}cB D7{Y}W5l};x2P0]*">ӯIc,,šYɃ_ys-KB\fTz 28gmcITwuet~׎Ij$azQEx9G4L_NN]')R\ \]TYQXLǘǑzp @(VJbǩ{2"(H O"gWȒD(e<UUPpZzѹLL뇩-3z8BDKU :)^wD8vH.ڥ$eehxDlTj\\ ѱKIzUdr)~i1@8k<088D(f^} #T? !H\Y%晇Ƕ"{w䭷ȯFV=8ȑ#UbMCL7/!0'H8UcblOY}7/RS9;cpdnB2z܋,] g8ޖ`]1?1Ӄ3g?[A@bxļU,ZPNBch'/zڑa?-'xLR26LBlϾ|J ! WTP{8~[ٲ}`a:Zh'/ s+Ƃ+(i>&'4fK . g`gs QsՊ LB%le[QNgo#14k)-\Ml_1k5>>4nɗL[_:NYRd??o21ta;N,dX(e60\>whw nAlj<ӏb#<͹2K,yW_ۃ,i`BGxyby̙T#x7rR_SF2>[^B퇸l]0Sjv'/H23:K󾝜PY|}'C27UbS"ݷm;(YڢB lgrb qwocs ps~yGv炬X ktUDLmWGsS[UAuifؾ~;Nڨ7NuIDATL`ǁt ySF9|AlVo⁍8LE w~.Gl!rjA8k4W,eb/MO7nHNDƇ9:Ё#3 @O7ZN0VS`南ޤ#UdtڏսgȪ n&FmX@cl~- s'h͔xMt|ɳF8qlN  Yn_ה2=.DWTa݋/Cy[i0]XrJ޵'G^ZGA :Zm卭8=cҥF;xmG<,_Lo;)'{7َ> )p󍟞f }OXMBD"2[Ξ~wW. h`$EeeCFV51pb;ϽuQ?##(ܸj!nw]NqI1dh6޸,oAq`dSߴ&ݧxuxL ͒Q_*tv*)8?//ªZ-kcÕSJ}e.X :R[ÝAn*2bEÕj&<1a ([K+7+ ]Dnb\zŠrsr).,͂֬4?"mI't+Jp{iWX֭X40xo`s12å^<K}Z VdGgGF #duIq*E%8ւD-J_\R[Fׇ#ۓKUBT2ϝ=PhznSI&7Յ h8WƚU𸲩[@C~6ERK8iLy83)+Hk!kVS\m*Yel:#ㄣ1Tw17n\Ke!Wqx ,."3+|1,PXPDIyE9ꖬdycYESTsMMNfIMՙ|h1B_K0!Ng,u+)p+ 8s)#(eh4Nvy y)`qc=l,-Zla"|>jv۰{ri\%Y$ %5%R\RJ \,ш <GFdSCQAV=Ġ?InUe&طm+C| ^ݾAS.MXH%} #?3|2a" Jh\HE~6&V6⶚ײ\;YXIR2FF .ᵊT 2*r1&2ijj`~eydfCc'W@7\ Q^RK1s(+5gЏBHBc -oOK%p Sa +QK/$æ3<$#Leɴ2pZ,ZY)CsYuZ*`|`3< t;)gA1&BQMܺa>2= a-u9T"ha"tKspdpRj  Oپ,%jf^]L9^e PKaA<.ZDuI6vZVO͌˛C:4:{/bmlM82dal.: ZhB p3y0kgB(W2g>]u]J]źr']\W)n}ʵpsMi1h頼T:y19JNHRq}~WKM %-e:XMq2)XzgiUzp^cm<ˆ70x?BEQB;u{|pxMiOU&I>YÜKj"`(0FT8\TeWr/NOB(bo䭜%oEQlkNv^Ҳ<.u]G(J:QDL++r^z:$u鐜in-2]y+a43{<Œ1952gL$l}dN]e2uZbvEU9A'œ= ayq~֖oR1n1y|>6}f^DSa =vCJgarU\=֩zNr{ttZr̼?}<_L[bOx&1qM;,uvg23W󮪐Hin((qO^/L%9ut]2:v=޹&Zm~N`3fF?mFL~Hh7*|*RCl4-Beә˙*p'3I=Bw%ԜdeԮ/-ڒs(q9yB\Ol_9%8ϴr?U͒rߵ99ː^UOo7\s9utmڮ_w #-<4~.͞< m"M4M\y/ѫ]WW:f9S>'m̔nh6F_]jqZΒ,m"{z%NZף{Ouuǜ{2*q?>X`QbICaH GPJg&ӫZDɝGcQIN[ZJ2Ğg(|Tc ~T S/?ρ3mu4vne>{&2D1 /"%zd|k(u-񽁁ǗFûAz&Ll+f}UHT ]وפӒG!L8l PTY,_y.9O/ me뎃Xa# ʯ3d"DdžM :]`$ BV~57c3Ħhuᳫ!!*4Yonwftl)?1,eO"bZ +WҘ?5t iS}[t."c |]]C MВF w'h``````` }Q M w X4>W8wBI.+W{4g 6 >wˁa!2e'nT10~jBHO 0 B@<`,}k 9 #&ate`` 0Č9bڟwc2o~^o~~x,]\w( :ˏxe"G9LW \BfJVOG2L{V_Y{+2Υ#6O Þo"y1nEg{d7t(a!tp1g;;,RU&ǝkhz փ[3;NGO+kX >BF@v035t0Yp-\O%ƒ\9*tɋo'hamܾG/˻2`ۻ0dZR92l江BAh/?2"lijQHF Ͽ|W.,8'LL*Kp\ۻBM|=o5|+PbCy'k*g>^A!>6R*x)Ɉ~C֘u rPߗ+x)/cB)^pm54޹M\1.]S?Yn(NTbɭ[nf˭7scC&:!G=,q|L}REAlCU4;sj?5]U_^=]GruQRaC+! :v7 "/R~0FaUܱ LVV&x?=}#H{%9L xh"(.-mMX(>sra {Fe%yteRY^dT10xoa\>YJ6`ufa%PaRLD 9dX\J%lV+(&ƹ @p&(XV RR8{O֑e6KA"O9w 9S@q?lLB"L+?xˑ1leR䱣jm[0leOP&9{k2ہ&?;mh(\cn4+lOZIVL ?130ɥЇ%mHFfE9dϐ3FIh 6 Lhu;).)gӸPDl 3+L d4H ס0ۏΣ,{Y^J2}ဟ@܄ۖdoPB%\mjL  24'⁁Gwn&l&TPYt >=džy :嚾[E9%W+`XG)@/;ی5+W6d㕗0'?J qYqR:4#LTƇ{хi`|0"8qU.Y:V_ Ѹ"WMJe,x0?q;g:*s\)).c4HCl;5_Oܽ1!4F:/7s<|_%4f۱o)cF+T÷Kݖ}9%1ʮ?Ah|?oS5%ٺeVYZOEHiDI}l,*DAJ )tB"Pz9rIvϰ4ׇ"z2hg5jvqz8>1KLH‘F5 N9Z,Tε\b?mn~v3?Q?0qj6ƫ cZ>b ;Npi}lo31r's|,hJϹ %TH}TUMp9g<O~~vNBq:H8sʍp}9z$2Ź>e6N;՟=Id1XS>M3%ʓ/&k;ˑ3]o|tr&9sW ~v2nM7PV>] 籶 l}g:6??+) 1#GHZjA.#ZiP6"cmg{ٲ$%HEEdomŻ`﹇i_2y"?kkJ= ?{3Vm\} H _7XUɗelXVDoV+qQiB]vIaC@`U9e^5xUQ7.$BlNGtހE\[*B2y'"K^Sy?K׌L9|ް"t]<τ~n3>4DGwoT2jj k惞zls8w2z ܾcAJn֔`j<&0 $DE/֩F7a*o}!Úf׫1r=|YRxG3=֊Ŭ_w#6mdY7/ cvp)03#nI'kd8EՋ|n!ugzb|Jrܬ>~_`YeGbx rp+mR*b|럾/m\eDH\jO8ρYV`J+ UZO'UTD,LBلfC|X"H]$89;gA`{H0Dd`aYLhEM(KG99a2L)[[wc?{~Ņ@N=<*vg&lpc~VEKKP,Nrr|x]A*K(N{H'WO1AJQiBOnU"y Il-n꯳NRؒwd0[ZZ@!&zXr} xLMQ3'cXT2|ydf8uv**Jp!A*"!5ZpMĢQ\[ c|hCmxs}O-KeE sQy_ iFKj3(Wqe7bSu4M%U&8>$hXiXL+o66.A\ؚ|>ifG&yy^ܡlpZVVAA4A%FAJ+o:( !R`z撟.TJ'3; Tpa 7Q2`RO*fU`v4ŹAWT#:9v2QLĴk܊D&LzS%$TB:)t]OW1QѴW3$lp$Cz*WX5<ױU(Ȧ)Pr ۧMR`h1N&VRyp5Ww'r;96+^G.CA?q]4=A<8+u2%md~at $LÍY`< I$d-c­HtBgyo 3g53 Y96#0GN:aB$Bħmi#"COcTzA O5m[ٔey >HtC]c-p)ƚ0]`L$@1cvJl@ czƃØ(iCPCQ4oQwp-HzLr7ԕO]t)LYNj.dK1-9ٴE:L4q#6@䯾LQI]︺ȤS3hqƇ/7MHmzk(eԒ edL8p:&&ܫ))i4Wj pBe lyiXnA'喬H<@O&H^*j"gζv~x0Et0CJ6meQ8`tCA}cU.84L S峇XZ_ LR' BaE%E<{{Nesi هɞnMK(9qoA-+}~stJ Wj!t;rv(Q`wM˜ (Lܮ"||Rצ d2D ZP<ʳSUۚY`vQ_}](B"q/K ʰ(`^"I]NmJ@7qd?`>e,:4OQQ,e@A=MhRس%+;9~[[)m\J}Y.V MM,WkrRIӚXOk()a2R}ZBٲwc-[͝hC@INp!.QcT<yqCw !u("\!v:HL( RO SZ( -hT`EQD( RKĬkCણO~~؃ Ryē$ڔ>.ah".i )ɴ&+zѱ0y9MSc@rˋuM  %XaM= [yP\L]D^2#hIؕow2蘿b_͹86<5&#FdKi$w!2OnH=HE[nЉ(,h$vԢ\q/R~wLqyfh!Ξi#ofVxN:]*ÃwRg&Ē~.w^bGW \h K8! F2̩rVR",^W$9VHah'Π" ]$qK<"N jqb3HFhOh ,*R s+ȩx#(c8 5,3BTqX@SUb&*JVt'tZ:zϣV47E8r1Pbuvks8=R|(CBEf/b]AgM-El<{W:v2V@Y:\nm5JL{@|VG#BI]c1.tvt0PKP(B0 Mb5_Y.bY޳ }(\wDsۗ<5 xf6vU$aP(:ph4D(C)f]+矾ʷgy,u,\Ƚ[?#YX qV4% IpWȿ|}qP& GHi! D_bԼ &58Wl @Q-KÝ>vZɕj#eNckouk7lo?VP`٬ZRæV(kW"A44Kq`J5QKs2WRYھUUn[1Nc"F(% kHJ"!Ē:]S\̎bsfQs|-z"A  935s73 b0Pp$D,WW6Z#9&6*utE (}r7C,gN-o?~n\XL2"j VB0`pe$a&"a1`eGc#QzhRm" єBNݡ~ޛn ! h8XUEJTr? !HY-{:V ~FbqG맷Ǫe|g\@kc )p3N!` [wa<]HQ~&f@QϜkBC&$QTT5Kݓ,$m.dlSOq"qG lfAV&;y4Pc7keRzC83{9Ee^xd~z'*nV,<֍Y\3ɱHV9L^p7!5k(dB,:FԔ͢yxf2)$~?7pciV!ҼJl^Z;鏚Y6YW%ғ\;9r^FqȤL&;8} ;!Xryv79EuRTQGsY|ʊ )x jYP]jl ݝMh[HCu1x'GO#Sf0Bj]IXU/4BjvRTQJnvv OZ)*)&a:-mYGS9p0-+/Dȱ>0+-'\ z`dSUKGZ9e8j9}8|{韀6:=Orcj|_UȷzήnBbnmչΩEJ4'kJ)jr>> ]DE5/%1S$&/7lR&:w#N+fL]9֋4+)'NP -" KYX_ |ϰ Ac4_P+"Itd(Ea_};}QZ,DX܌xV꯫(ԤN7$@vFF|SI( TC70x8{$LO}c ::0gPUNY˔3"? 5gf+MD'; I+9b* SW"cEugW1{?Lo@"'/R^p"f#S+R癔re}*M)ڗ CZǢqi%=R9R߄@CFTbr!&s?0CFN3׶oS3/u? Ec8ځ';Ip|vNMJꌰ2+WHGLI}dꝟy3ڕ)1M[WdNZ= |Li[5Nb7k9~Ŀש 9u}}Ndx{OPf#NܜcfNꮘCVͽO>cRV s:I2*g23W.xΜ f wN)+Sg:5ˍΘfodq6"|Y\K1IBlYYImk%8VuW.< bnۧ~o>W 2Hg!rzTWC1¢RhzM׮AKEeշW:cy'=N|ZN;NXd2Q3o\Kd|}Iy$$x{G d|c۟ɝ]TVa8 >29Reyv+Rn,#*E r;n"[]~E(,]g0I.[Vqwaw >1H̙U<ٺ<P`9%Ey1JJ~H"C]G!k&ƥ{̿J=M,6UW1O B5aS?=ola7"ڝXvOdz+f100D Ļ7݆æ LDQwu;y UJGoO|2000$幬ic``d=0^j"u/EQR5uL Ƨ*UW Im%e('!!9gRۧ02Υeގz#-2ei|UIХ(WD{q]M|3sT/gj>ln(2燞5>L#w/1SveQq)z:lڰ'T?600H _(YAjJ"EdN:}m &WGZO]LўR[B^Y%^Um|\@>HVu5+d!~u -M|茏sidMRQPAݚ\=CmtBO+)HFiog$9YTVQTH;#C/Ud[MSmI-L@}vwչ8* *Hǹx('Ɔ -d4%;g :LsQZ㘭4-2Ë$졹 Ng++LsVRuQSMmN> ZN:{ DHJ^I%585:g~0ē;FN;N_Ýn8b,w~(z;RVRU1'!t?r.2-[B'Nl+Ʀ&j3[ dt[懝,]al1ޝӆH-'ر-^{2ׯ(S( 3ǿ}r?~vI'm=ϾM_#vN! _#l}!z"ض0c1!@:oO_?ɟ?=&CQ#4T0^zos3xO[(aSLeKH@8-׿7^qNEBHvt7}ǎh B GN=ϛ=8lfΝ9?: -]u)rW>ù ?>/u ձO6#.&zw]J< N>]øl&Nz5!35ZqC<vSYHLOyF5P#xt5jjG5;q&xS\*f@.'P(E?ï-?U f+em΅b. S2nk%6}K$qbx*VTģaф>)DH$L0$ &fe.MwgfsYGev5_WYM* VoʼnPJі Ug[RR5LԬ?o3ʝoMKp~D"F>SG9H]Ctt-A$%iw'}O%OՆ ƓSnI<! &HcDa‘4V? >32>Fnf}__|yn40QjQtElZ//}7Cj]*9ю"ck;WIEE*VK07IAgh4Gǡ*;Y΢:N0 r~J ]W(ʭ϶v_c :S:N*:)ތB<=S.5"% ߒ,'C,]GP%%I7xbG+uk7R_]CRy%"ēˬtMCez솈 +$ '>9:|8JdqwM}`6"$R:%vw4HSG E<^%/lZHGE"HGSWJ5O_nF×NX;vֽoq'¦%x˝sJ3ٹ\h,& ea'[+dy;z*7ydfqȮΘ j& SQN^qQB9O_(P/&sRC5P捰h( /Q?vrVoīq-{n+A_ݧҰٰ\PTW6^Lh0t1˺Sm٠Lw/m?t>EQ=吗wn̉;uO: KY3<'hW(US<,{˸ aE4}`U +Bt ^%3J2JUsbzPJ̎ L^%!Aeиt1.c}^M-V2lp9SE^c) {WkGϮ>77v;} =<ﰫutΗS(K]>76e+ y"J*ü97C_䳷mAhʞ$6ynY^$]чL,[+y ˿hR2olQg7e {`H /ϊ5kqv(˥0˅"%3921Ɖ'8:q=fa!<ΖEx@LSY  KVc6Vr# "u 9Hr]S PTBQS{*Sa! 6-5lcF~DJ '|0]Ѯ[ʍ.2K1(+o S`2;\tm})o>Y^ɭfL*pTr'Ot.C|ebWMdd_b`qAG|3-=PGl,ȚF!A L DS.iń*TTŌ$I14]0N*T*fLjx29XAQ̘*kId?&D$rIQPUE)MdzXXڈ/'2]Hrxv2 0Ji~y< <+lMUq$QBp}VPMfbb1cYQ鰣KINikʰHV?NdOX-eِKn򰠮n`UC 6eu,*sRVOW55,V+&GH_j)T+Z(Ěkկ2/ (=<5ؑH]GGlN7 JY\(~?<~k< _Q>N6_fHZ94/_"XFnQ)9\x|<|aWhu>LČDQGR^f^3I,Ţztx\*" &hDI2lYmxa"4 zDLӃRnW@"$Q./6>āВu ' T٨x\TU␒8lAEL7%`d T(aQi_?ſ' jꂚDeӁ#^yu($ c#Cxn8Ô/sʘ+XHlAQcQ^"D"uIU0 蚱iDJ8/-:YUMCD݅Y㍘k/{b"C(7!@K?Ƿ7c@b#QF" =Qg/R: ]kXQÉǾcO;4Dۥt5{s=N"~|(%2<Ȇ}.[yɟVL +("}O;AXZP'7a{P]]]K+]:ѣG8t C~2s}ϟWc:| s&,kj3VpϮm2Vbq?āc <|JJT3]<ջeY𓟽@{@X2}ӜdOI9J^~SPFeP0UN!(,-c3gt !£< ] hvkPQZ^d4a2n+Gs"^ UP[`oc:]\E]e!7`VˑD_~3%ZAH8-M{(+(&2ACØ6reєGDH145"e.2d<`];8yu+XlTzJMu5=B،UTMt_a7B/Ϊ]+.BYS'HŦ9Ӷ=AiG.p_>t,aCu Farc6Z/qvީILy+yn@⟹Kh04T2ϫPNs08%y:{s8š;5Us!*L9q}4QcMMU-Ff8u$W K*h^DUNۙW8q_@EM=Uear+#4Q^RNSc>zJc%%(L ^N Y0VPS^>/k"BeTpǯbYEnz"ȹ ıSﺾrQL6Bkq6c9xIUUW'N;DP1:wsGqeU6NbV4{ZQe.&)]JssGxF+)xW\9u֡iтDy}ylfL;' g3]#G ` u^Ͽ/^|?"LbVx`'1b:(rh%|D:&_|5CON2/3՘qi):8,9kN&RH+NE} NG))-nb3%p_0ppZ.Z@0@4FӅEM FхfW[%h@(jvڮ DSɊ $"ĈDj*Nt4H @LxB7zkV嫴xb.V^rsF꛺E5\7{Zk츙7躼b 7/>^];~ͫ X󷉬Bv5lɹuWW9szv8O߻Iϫk}nfȑ=1`|U^PA=˛,F`="4&zZ9z[PN,Z{]Ǿ<^ȶWQx}_05_ύ-fy59de^m^Տ<7zboWׯ1msEk^ϳ^zyMy79rz2}J[r<p|Lhr\9ne &7e%͑#G9rȑ#ǫ oR+W?/g`pPRp))+#i/r઻m9rȑ#G9^?7ezD`"tٺ9rȑ#G9rȑ#Gwo oM0$qrȑ#G9rȑ#Gao! 4)EP`Aio Y\Nᖭ 7M3[A]n΂s9r:HMkj2 !PUUPn$ 'ו{ו{w WQFr%|ɷȑC D~|$,˄(Mk1oKt[NQMɯTOts/ǛBv\+ʢ󯖌0yoLq|hzqHJt]-Fw~u+}YOElȥ!&_+ʞ}P}N̑#7Sddx?+<֖Ѯ[׉}LNIi`9)*)ELxӃ}|b˻H]G%d hJp1-B."Dӵ[cO~b) ]q 2c~2mˏ#ǭ=rY X Y9H&yB9X{ I}B.U/ G|i7&N= &<<1'oD܏/C1:ȷ91?a?P M O~>V(2N֣OBеx#1$@QQT6 ӎI?i컾Rޜb'x)Sh_(L{#by߅@OF %.-~O#$i/4(U@*'* mƷp%Ž|[RvQX1eL¤̣$ߍQ 9M~L1R~}:XdENpB/Z" N .!&T9r:AҮ,eyq>MP}I#ZbiwTf,cH/0&cH)B8#_Х-+~*Byl,8q3{4;|34k;/;O1&xshU504v1k^Zlzۗa@c,)^]V܋U4^Of5m@On= L7S``7'lvB[T5pv>] !Np+Vc{{w^ SqҀx+DR*KjiYV~^eU%H]?6XR \vg*##Kװ%:6mi#Guɳd+Y~SHp/ ]<_cS} ?Vt6OpivJaDb5&5. ׭TLToE:Ѐ/qWy5ɏZOXlơj\l _9Go '7,f VlzR}5q_>'YϬχxh}}AAuԱt}-X'p+-(Tƶ]W^!Ђc\Ꞡn$3O@AZvV,4tdD^&k%rܚ?u1[iE(NmQ`ʄkij΃MpԹ8L׌kr,mc6yo1;k[1` -EVגׂӫ=GBO015IÎ"Nf#fϿi[ Dr^ٵ(=Ed<: / B'yY rHx DQ !ѵ4&qW`/e>tvΜLR];oRO Elu]%3DoDĕIJmwg .mrkUɑ㝉JE  |~B6υ6OpװU\b-Q-,H$B1XBebtVTCD"p=ocVUEJRB3Ε1R $0v;BHFJ1ḢezGEEJaqSgX7^};C`DSerGt}7b7)ssQ(sKRbOHgrq5md8MdKǥnR>] dI>]3)uݬktqx{/zxXIw1Ei;v6Ƕ/PDYy|'# V&S.6v+3Eot`(zr bz~F(eӶ]UPHyO8Y}K3M͆-T:"q:Z/.bk~mdi;h1:7!uɂ~w:>qPW"iL;غ:I(8,[φZ,I9n!^wXЏ((eY%SjISC+_}M; &m^xaPpWIs\;23 )[rB2"8`6Pf;vO@xl:̆Js$-o 7dMhܸߵΗ~krˑ^3b$']e[s^+e~ B@:6͡'{: 'TWypf5csIU29r9HPlmyKU?'^ "ܴt3QOr-;q]VYΏ~`UX 2 #~3~|t Øq=5iǨZf4E$޻!P!zIb4uKNRm{3Kg@쁋 vg/"M0Jز 5%|LTbHd?D4gv>SN2Q]UgTBC:Cw'`XU5t_fJfLD!:njhgچЄ2o.v>DY;hK7DBpN Pd-m[94FXTl}^h t6n`S0Jc4=/BTnj˜;Gt UDgzy'Gl jQwy4L~a 4}bIbD.?y(BE~݇{LPZUAz$7xe|*^١1^z|Opc[~ p7xX7iȤ1Oaz6i&ں/kWV#/JÂjaQ5tK1y ˧F6c=?{ ?;?.vGV!$߿ǏEUmsz$C)ogE>"ȑZ`H@h!.qls#o>Aѓ?_g]YF鮬ϣ(d6FǎhXHch^U~rx %l:6}#Ώm5Xx?'tkL2GUse]r5|y̿czeK]ײLP1(FRZc)3YTŀAM26)Q0T Iz1+1P}_ ]m1w.'(_AKK%VN/FFV,eRi>3((lj~xqP *9ryz&"+5Hk,c'.ܼ]̄$xBa] [7ìjC|LD5J$wbS誋Y!1Þgih(sB>;HEAI&``xxe(HPhYVɾI[(CqZmlĠ2OSfǘK*-ܮS!n'\,$$s\鑄.GS>y7Ԓg=T7qߒ,இXesI*A/݀P'^~<n C"@(Fn7 E(βFZ߼:J#g.)ueⲙ(gistwq )KyfqQ*/ M[6gP(\zEؼ2ZmkpV/gztFYa=-VV.$2=ݛ(z`¶6eH U|Vp睷q^FCIllߵK/c_sBK!,wEVLyylco[fuM 0R|z6mDq?g,*+:MGU1w?G o`H&:Б,ၻ647,ō|ӟc>t@uv cӜ8I{YWBс#?F89H]CK $M 3ݜ0Ê kq7qj/dֻ8kE+s:I?Ã#x;YJ0ٸs+Lb̭ n#U(FoH C )..'& ˑFIW((jb]|jDǞ牮6Rzf(g;?<ɾs鏧nhBgl,*XMi#>*zѤQ1cOD6RGilN 11"\ۺF=lv\&Dl6tZbPq"/L%M% 2z'~yJͪlmv3=2褏 ]UܵãSD \v'F(H)(]j3_26i\ָRԖ& @י/h6ÆٔF!D՛mvvlɽÖ5$G;irU  5?>Ҕ2[jiYՀj0`12PBciҚRPR1%K"SqBiE +] X஭Dh1FE̅% ]!lNk&h3hͣcCH&UHwNɸz L KV;R~V] G"ܴxQUلAɄP[l,f1?F.C* ;l¨fSʚ-J~A%L[i- RfWm9sD:N4jq=5KJPDQ N7N!3.nFgb20XL9,6TZCOErщ3qK B"ݜ鍳h(\:G1܁-M1d;^,zL7n'I%BHT Uyiɝ͢ 5ki)2k'>&f(Ԭ}z*-/GK9x0ɤ͡ue tϋN?F5P1 }Iʗlduc(sΕ:G7 N$&L:R8Y>vT2g U5c5;+YSވSFH& y8UwSo7s]1تq-f}o\C5Z)sWMR 4c`JకR3 d\щƃhrJJ=E0켡''j[.2䴏DJZpZ^CrfXZ^riȍ  6šy60Frvl^δjxxH$6Vl tEY`\bȯdL~v@2芑;?ĝpaN|+}` E|E2?V†Xz5VλSdd* :; ס:AXxFC,N"]sٔUh+/^*j ii4Tq{ .c^Vf3Ò1tF9l f)DHтt ۗW0p(g.PXèF#ώ N滆W] ;؏?! vsq B^j)U.L2 #:WZBuI!y2|7njha4cKMLGx1i=SDl9VI6Ƶ!dSh6R w`fMPpzJVH}.DGlkȄ.rjTunsprI0dQSiUKXRSD=<⥬ZRd*A21V_g ֬leRq뷔U~6UqڎD_8"KΕ:G7|S\'%2%u-T YSRQUP2p"O)\AhCyHYt]pPj>F ٶƯUnG=Y^X"j6Wa)#8s@Zq'(]CAE*m). ztި`mC k^ Zl?hHږ}tXf.3 Hr.>B 4SXLD"I:5_ŖԮNeS[U 6x'"S|XGN3 $@Q1*cC 5 ʬn!U(@) G_|qiƽت_s}1|S ̠g(MjG{8NddAf^6Y W+;̫'@4Cmf6mn%}(w\B# 9q3/zZQNk*YʦfN>ӇĈ|zhh~4g'cFPd=-p}$*G mMEbO1폐J|SKA c1+'9)"8&ָDi`@U+N0k}9꼓!B̓z$D$Su=e6c .~-T._EY]$P1 ^ V]SЅ7 %(~^\!ᛚ`r&TxvZԼ^ 1 " s,iY>o8F,gph@8xqx Q#G#ȤѨNYfȼ;×mCؿQr9b.1Μ$v64.j)H.ܴ;vġ 6<ϸ?Fctɴڦ%ءA^>с"̆V$~Ϳ} s1<ȋe(fͺMv>C}RHSa;pQ:T6Qq`6 /m*Po!Bzj?mQCS^vD'x] B?=BLZANùu-ktBW8Ghp ,ET\:zcxjPYb'Ō -jdo*e"odũ{93J .Ndsr,(ّoxoC8y}m{Fy& stDE;ɚ<bJr~|9ڇl';0ԅ_x Uv(9TR fD5SdHpeщb^ z⨨DG/qlxwv&U;(*Lإ20GZB]o9^wtq+ѽ]?ߊ71٩,%5/bҐO]u%.ܼf8I2emm-XԜ{O!.eE+hajjɱA.=xͺUKI _}ǘlj&"\:z)Zr**;i&dh`qoÅ&b T*:1xhm}9#Nh #6%Dch6]92~Naމ0zV6VBhmD4 KS_aS?+Cf 'UUxlLꥵkC{4 Ѕ,2ة0'FkuÂ4a&H]TQ걒 t(M^Y-MusR;I[8Ѵ u|C\'e+31{!FO%-ɳIE}3.Mme9r$u83bskm~+77o0 P0W)cHkh$HDZbp:(I{m㯿euk[}<_v PU%;E1CS?/MY]|ܫ yLNͰxԅcUlץiq1;jG2$oΑ]1`>Io2L<ٝoYFьVJH+qWAJ)Ѵyed~iJki Y 6Ƌ̥hr MW}-ugHw+0)0#ǻ )5ҚeW_F;& R3>5d5.Hhejm/vWJ:ž.tӽq3oޒdԴk抅s6Jm2-drv:CLRRv]5}\ ׵׌k9oA/w7Sɦ9pPYF͌j' Egz}zآ8ۍou׵zV}uk|U&2ξ_kLz}Q:PkVu3MZ_~./Wȑ7˛Ꙍ sG9Nb[ceE\9c g)a6ې  GwƫHIF&%kfϑIZxWe3Mrxs0 Ƀc Wb%nd@wocʍw7-bbj?4R5kRG&y_Dr |q#Go8O"뙼d]w-a) $&g)[5˱+eEP1Ur#Hbi-+cI57x!Qm@ t_!-;0r֋w=d8_ǝ$LN./4C0hXu+)sr3ǴoR4UWŇ^{";95rȑݍSx9ލ1#rcD|D#{.93~s`0 ʛold9](#G,ǻ*j07JƘfK9r䐺DחdBH,&JskBe9!5s>BQTyS27K-GoE|}_9$AGLjjrq xkQQdNM u BonCcDYLYշrg&ʑ# ސ/<ys5uAҤ̟Tp;[W]և:T M7k7-yVn5s&J]ӫ :c*_{YFc|9r]*BA}9`o!P"nionymf<4RZF$"i R_E_Vޥkχ2A'U^4.r1 9cZ:E2S(h ^W|Ph4Cc7hʑ#o1xS0FƸh`-Ի\O0a2*6AҼ f2D; &ozo(@B dv90vpf`24YӸZM@wW5 UDs( L4l`UqBrebi҉(HcK]72 ńcO(!3ۜ " q V+`کn^Śe5xLEL)ơ.jC?p -Tʰ`zs86^G_[ cDu/aM+WRo"83H|h}-0dHy$Fj o Gn>z*<\|&nހ!@HL%<ƹNXsoM5Z }g7@/W݆yޛF*׳gׯaxK@c4{+ ,l'72Iv?ew{wz?C֔ZѥDKh=s=O}_WuM 1k_'T-5&WOEIlWD`+2D.|$G[AP[e 2 Rr }9{ xcC{35y/u =QɺsvRhv!O/d]eͧCS.mp7Ӯ((H4O|rpNe">܀G2o3~Xoe۵l"E=\A]ޫtJJ 9y?8~4>]U٨tyE +%E{jvPYY}qÈ%eۅ+z EG^rVm^ɺ"[e^ЅTȫ\²38;硵e$#Ƣ ˂+(0&nRԭXKůi;k׵ˑ]M0xd!?cmwr'i9QDx#qV=9r%T7aZdE_QMVl6 vЯ):[r@ײnY7gjy/]_,q {FaݮqwO}\ʽn{ΰ-'[`;(z+Esbseޟu?Be8F,G ټ& iڣQI&Xݷc4s"1ϥ|_Y\kW!P@JL-:}ItMG Z}89r!@lD)0=lXuqalRJ{l.i-CA[ЖӗdŲرrG> KڲIƼwmn)cWLZYj`-̳2זy e_N:6S'fB 4VmGf9@_v?_DtC4SӔ4mE`KE^k˂, ?%@EBDVo\L\G)X˺ϼm.PZll6+f M5Rl Jv0)u:dALvlrX5>_w.ʫ%Xge{jzc?ٱيhjɶ{kNNg q9riDbѲe;F E@gtx$c)lrf|cpdFpj1KiCVʚup  0>>Sod UΊ8ugnpWus 欇ă08A49o;ôMRbvV\VȚϪ )b]*t k*>Rɘ9\j{ oCd2xV㱨ι*]=äŬXր˴ẍG@Ҽb9# I}EpX!b`զ*euK$wnU3.1rx3 hqNwEu-N!0ZuDʋPH2bW N"aR2FB+X !g|6,Š"\vgri><x\uTG9521fU!$`m)vmGZ/k$H+S]f.1;Jhvl%7T,AL3}96|Uylh = $X t^zG|+YZSI'$icLL50QIӲԗZ|+#QZVT&'("My}hg2@ 5c}t n-e$BH"1F&fĒX<הbRsr`aQRkɷ;)!HEt1UK\O::We-ft* sl1R.miDt OgPFmj>b@KFg>:Ş#GD 2cxpb*\iE0hh%nB)&WaETH v0v1Ѱb %&43tPS`f`4U$='_2XL㪍,ϲ)bw/H=orD=I_ e˨p@3 YT͘YLPPhaj< 7 I14$KlyeW`V4&{.qc(dيT:\9wkVQg&09tX<| s)v+w7xa[u\n%RK㟜7QL3/Pd)u% 2<>M\mԓ+#-g:c"u MϮy֖`2;:{?~Nnz9oBO^;['2B/xJ* ʳ?/資O#|k^LjT(Z%RJ̎JH]75ld0 %F}B1`11wj4aP4MC40.bY]0ItayNԤ7?|㧜AgROL#'WS ]W[ r:n?}PHy'y>< oקEĸK\䲂!Ag˲x^OfETJhd}/,j*T]Ht Z=!bq.B 쪝㏌c7[Q$LFNoAbQ!%nf0fVƄӖ;57d:$acͶ% VvHSσ{i97O@dcGO24>ơ̗,uAOrF'|)rq,P4__O͞/ϞmdS? L4Eicߋ' jJNT+W+ o2:?]8yK_ُ/c ňyHs4i?歀gjq<0"HxoO_!!~/?_^DQ{y>~{Dp1lw\Bi^ٿKA<&[yi)c2su)c\x& >?|9|}RLEQ6WW~K3DZ_& PLO$Fc$Ӌ{ܒib0`+ȄG4<'>.| ]Aŀaƅ熝]NňKyqM;neN1ןxO"ȳlZ E&:|!"Q^z~7ƍdjT5k A$GXOy]3vhzA?cT͔N07 [(_盻O0䩂KGT9r-?T>+[juPH[O33$#v=q;W`S2ypڎ<27RhUYr59SOEz͛`"u^t#|ѣlf:ҸbC|_UG2lj2edU%K( VPjrT+`,+0}y~̡#_NM* A~gS9RT$gDUedxX=<@r)G>̪Ҝ|?}+CLí|hs-W+8+׳ŦU|Kʏ~y< }'ϟ wliBETL7_{[qs+_DS(&Eܻ$?~&Y"5 LB]VLyi>iR;ʔ/*p$MVmIĺj 7Li)*^u?NukV oΑ#o7dBx<'z5))Wj~=Uiaߣ!n*SU˾zpŀ;/J~~V|1 FI蒹:.pɛǃߎh 6gL#뺎nl."MCWp}[&| ^(/[v5Ta2$I"BK %}D*EwR]PM.*+3eSv RT]CWaqxLOa6cSu4Ռd dB鴑jBUT+JqiC3nHI0f6瘪(芾 GՋT .&Q#3ti#t}h;kJᕓ0\۬ib'E \(8y$E.D::jP5EW8dŎ~ޡ;pxs`2JT,~5qH]fw˫,c+HD QE^. U\GIIb!d4QT6/2y"tz/ghRr8-Yx"Yq+{+,Y "67xso-VV4.{>:AhCsr?1g*A?9| XzAHF 2;H0P6+g.PXQ]M&3͑ݎ$t)$s-YjI]"XyxJ̃K֠{k( Lw˗?Ȧbw!mlץd[-tjP,g2%eNk $ Bd `Rh2ˌN"E9Q)‰&{9㵓F4'eUwܷ d*L=t C2<)ZOwچhwcGRJc*lu ;ƕv&{YrQ$bզՔB>|8ו*BF' ~K?``hld+Y܉|LsbPB<Tڗg9ƛ!I5wtspE $ OO~'/T?8 />$ d* OPI&Y F FX"5ʅ߶cnxfVђGSc)Es&{aM^ǹa=TLYE^"tRZ $Uli,StvtakТ Mx "TuA\cϜk/s'vRK 1& %͑#3`dcμrt:\[Q@*I ' =6,0&1ҙdk2b_s 8V`T D,@cltN] eH]#0"WPkWRz۬B@xWtfG/.<'ֿ~ g3;6nȮ~^gI?~qmFj ly? aq4u}Gv@W6zCQ$N]+X<:*ipcfQٜ?BX28TjDrod{M5$dưik7Pi-j`tR H EDclèf:9;M0%qY^imBO163z%v-Z\EHM)P{`\:vBQ@J|* (cro,۲"BCZY&F#)\ ˫";V؁#ϟLMS9VCN} uA{72ʳᣇ霈Av _ǘW[/LLIB:S~q#L- ]}yq~CsƎ9{;+,_$foҢ  da|ŵ˩ =C'"1qY5F!P xDRʵ uDDMY/xd* (ٜ )(Ck`K5CHzC-DU+)g`*h@SI6Ꚛp%X|_\]A؋kIÌ(5_A<2fr QlT.QPE}mAC F0'ONr- BǼxрɠ\eϸÔ\&t0 Qc{ t'J:"0,.h?G+16s~DKDK+l[;rq6TYHԀQHS3A&' ǝ!>Ù>ɮOªJoX`T$'#RTW9{|ͅ:N1Et xvemLP|8eF…s0rKy3LNI 02xҥ&"1`Lp< ehy)\1b2od@Ox/YVXyg%ev$;}Mi/a5R=wʆT[Tt)^9C ƒB䙟QΒRv'xe^;[Shp-֟t<:sQ5`AL_晗yM 2`F?(p"j$$.w̳t?ODSqr PS>y_ D`f 0N8gpUfkٗPQ-㽁s~O19s=OcMyv }z/;R|bxL0'԰|B^Q\}womq7gSJ>ۯ˱1iSܲN|x(1S_Wo}3l_$ D >0^DZǢ"~|μ3N,np943CW}(5#2kьy4Uxr^8O߳{3_W:vl I{wlY?p3|ٱi=VXQr?e$Oǽ|p}5PjZC|+عo"$2Lz7L(#N"MFbA?p'Ұ8q,>v ԖufHNyrUKz9MwSlM I/x Y%Eu;CC>$LeNdMёKtF=|;7I">?^K(hm|.v͙RC`Z߹̔-k&N.7n|JNqzTͬ| &Aj `/A/S dj&LB %|b)p(̌OB~[Jۨ3 ٶu~W㯹 ϑ#p2ܑd1b Qt= ő\+󽗈k)fJp) usϝwRdT; ըQ/ae,/Bܦ$=DpbR_]J4<+UTyJ; ! \a & Z2N4#O.eUYm6/ţ7BPz;i,fc]mMJ)8Ph?Ol#,*`qQXhf1&7m;1X]Y "׬`fT 5S̠:x*h4?)m[2KtNIi!.lR<Yg !m ۲b (5li4o`d/ wC֣l)ީ!|-X_g /-FD'glb޻Y]"#caŚ-[/"yVx`2evS]]G]mb Mk7]RSSBp0pPZK*ɤ|5@<ulXQq&&]H675U WHXK(v +! T^Սef*d``̒XPJ?Lk0vOA)M˖S1AQI4OQUvFژY򨭮ĚciSXFME $/> Ǟ=/3De,-͖H rIz'Xv*p Щ!zF=n),5kqcU-뗓Qְ Ť~ ƕX\am z{R=peNpRLNzQ%4S^XB]ynR31VQgfNEEmŅ%8c5G[HSK QR!&GlVbo^s:eBK."QWYLbj mLJ@ʬ{Ű@]775-ż b`6sw dl8}a6lc crJNϑ@E9z%usfSL{N" NpU̹ʷt4BrNF"cN]T8]Lj1EL3`p̄99|yn$7L'fٖ%X[ݒ,˶ff_6tUWm]{}ZEĹc&ϿOզ?n/ףa=<5'331]BXBӇH1 xYVhS5+GLk 릻ɱS4v ^p|N}>:g~'i>' >vG M_offzo׈C.N?s/'(QuifV^z}8 =uqX*<5['Cb[2[̜{>Smi7պO?^=oy':̚߅=>{߼^f(!#'jq݋k+X(L歺81ͬ'tOYz׸ՌD02O=/>(a"A quLL/]ȋZy?otA1z*rN'" """""""y 0DDDDDDD`)S!"""""""CDDDDDDD&?϶6!.e uxsvct}FR9X_&h=ȹ8>6J糫86&ί7{)c8n&Ϸ8O?uzg_q4k,\+]x鍃1M+!"""dpKtdF ^ wYÜZg?r U9k3cMsu;2k8>bqSrF0WmC[F{8q$Ǐ5Rq\Ǻot=΁(&3t18&6:HK&@* K83ܬO68i akIMg1g2Iu8>N;7cC B0λmƇ7eҾ(`C9xb‹"W?BM.nZp2:X`f9o28yDPj!>6D(&A~~.c^#@r|ΎnS`r3c,'x;_a{sZpSe@rI:{CW{ ,v-1P7͝1gUh,]gXEqk(_!ڍ pp6:R9䅒tQt=kL,p)X EU̟[Cıbٿ^sȸܤn֓{i쉁"ϫ'/#Pq^~`^#]m$ r+ w~8gODtއ_YOx! 90` vV|9SOʵݷ̓^ʚ II sh>v{'MGU,=GOЍh fh8-ddhrՍ\ f#޺X:HEKYPWPam$3+VR˸edb#}G|=& LƁN?YO~pq.+(}1XFʖS^7'(Gx/=Op7򖧓+0ݻ9vLKÁcFUg03mh' Q1k>YoƁϱH]qK_Aj%`G Uܾa1>BLr 3b AIۉ;E8BS,>Sg?rkxh H w3_?rY~Zxo/ >>};Pg ddTbW`㖢BWe! &9āW姯%|S[`1 7ܢ&%PTG~YU gvl!r/Np8? ]# ɗw3;1|8D[xanP'cD|o=(=c!"(Yo~5v緲䶥|[|㡇)(}mC|{}>0`1unRw10.~㖥}Coe%WvlX Y%xl>z8:n[Buęh@@>H"A]<_,_:f=B^e)a sVvA kq"Ev<WƉ1ozSY{bz<a…eܽL0<7^w7/2/;/^n+#XǤh;ixSRݷ&Ov5Ƥ_vvZrĕ{-M0XOaѧIWe3ZCb}+I%>z'ZŒϛt6v 1k-ݿIɈbCp}Y8H&'H؇`kHZBiwvw n[uwb[Mnc3br/`dW˅ }$nn#5A#)(O(2JHČNatPf6!`h,vmtl>9bRp0ߨ(º cqS9o9gOϟ}Sݤ)y3NGjrӍ@L?}w3%̯|ͯed_WǛ}ccA7fv]W=quv ?COӟ.xl89x4&]^Xpleu RGݼT&t#([U0O44v\WCMq#'j pփo+k3~/?n}627g^)Qu% ֬#omZ8cul?7 8ƥfv+fBzQ>v_ AWglqW6zaX릇sʈyv';OGp-ƍqZϏ6T%Ϧ+gbk>/xGV4.n*}2Y ifsXac1}\x N4~Nn% 0{t k8$:Wg dIAvaUE'>j}hqu _3l۶ '1BskIc!;G6?ʃ[3cb;m; 1/W_Scp-S=ˮ .^߼>˚[P릀t#%?uӻ&~M=yst:r444Bx)OM9t]1Wm䆕s\Fiij-Aݒr:hC755T>o~[zj78\͵w~yIZN2g՚u%[x wv/UU;ʙsC67ʍKܳicɍwqmE/oũY-&wAi\Z}g?w^LyI.ƾZ b29И"ē p -f,UFȉq7p. S;{>u'uY-;r#ɨZ-_CYN.ǶST6#+?3 q6. 'Zڅq,*>?ʫvRbD"<|駯=(g3)_u=kfyc2g<eO~Aw[naFCaN nG!u.XȚK(u9wZfQaӳϳXd`4q^WypG76Ȝ` ;2u~2?|a~싼y+'[{h<_ h>C{t;ևk+_}`'ca /=V+gI oWe;x y!@3+b-w$Ʈ^b789xɭkfYuW&{`4MOxuPrw¹K)`Q;|aq8YF'f5ċ粠,r# ttGNv.3{z] 7jnn5ڻ0ABY=Krȯ1N( kſ?G'^`&Oſ}A~nX4JN,n\Ϫ%5Dv('ogFO|Ӵ f9|W3zfO? 9Yf{YG#6b憷c}2cKz*LK5"̻v#w}wYHVb}*_=3'!qEv= ~U^vĥC'E+ٸvnq^~yzq'fӿķKMH2>g:ǫOG^HR r'?- x:-KʺԴD@؏㏓Lvۨ8&IÌfQ ~1K.ew&ZpwݺX}z+]ͼf6 odfI5 *^o?ᮕwvRx=w!>~zJBCt;h0~3s˼IDATa9J#>Gii!C^gWph/f0Rͷ]w *X yV?c>"|9:<5!:gm䡗1̽n=CX gfc,+`łra n%59[Iu@M 9cD|>"1} SI17IZז0xO st_ +Sq@jb[=(gb6|离ncnvrJ325n3[?mieSY]FF!UkWta5g4dO2/VzG\`!f9{$gOA| ܴj6{wv+j0mp/+Wd\סj-~e|cWC?͆poqI(c$RIF%q)H&Sf5zk8|s=v6G|OEx]$ۋ$4DDDDdk-\20 ϸ6$I R s3obÏlKtD=;H@|}AF8>E!O]4 BPQwp]l:6ݯyA3yBɼu(=%[q3_9WvdYZ~pHHq2U#r*]ZihaIZXG*>0 '65};CKL! Yr#T+gX2XX̚{<Ӈd˃⁇OŬY|ty-7K_[~oIBCFa-~ǞDÍKXZC8knU6w<+Y%H>ka;l W撕IdŒ0 m r /58I~;׶| )[ĵ+v>FŬyYZΓ4+׳fN!^í:2 ]H^Q)5EŸKM`] '8M5DLB0MA~6M^Rq&BBgN+uذԪU#?R͟M6  \bJ_6e7F_S3s唱{Xs?^f5 YQu/~=*1$;}jOmaǎ\QCñ9Eh|DL\kIƓdd 8KLqpnlf`]8dfDON&d2I(obN fsurb3;^]sHs F ƁTLSk% )M0s:~?O(#rrp]R2vrMA2acQB2A 2wͬyu^߿9ǜQ(}]p)W1X ųq5wS Ͼ$?ۺc w0_mX=k/ Co/;0>AP'OBOR_XSD3/</nd-ӷ&+`|X1K܅,Y R[UHи 3@,yxtqgh=ܹ&^X|p-_J^,N,8|̌8x}m+Q5h=c;XY_a*b`4>q' ʪ\B17a߹Ct kUR1Exz Tarj xx M0 Ȳ='GW^OeAǙ0\kd*NƂlVr'@ s4v388@OOne|lxO=A)fjB&=oh"acg^D _tȀ?D21FOO#ÌRӳ8~p 0088ɔ%\4[Excz"~cR4~䟾-`gj‘"J ct9 YkA-fb^zz;~j9KSqcQ1zq>} %fNqlncχ)I?gSF);1SƴG@'1 Fr)2FCsdzp$H`~r"&/U8c39ہuU*e89D*('\l Jf/bnuN7>lWES|{S8ƥYbKV-$>ˮ׶9gt:)6&*XVGE%)6?}x~'m4xc ;.& ^cH췿ϓۨY0M2>6pnNdm5Xs'o9VPhs??z upn/ #/oŝjdߞFcpS Rbfדbb7( fQ6P9Z:N AM- aa4NbRrO_~Ekho#]rVGrd= m#g0ͶWR|55iC,g&HcͪE+>8ģēYv qq fbƒ))KAVdr3M8M-'g"r8 322Jnna>ǯ߻jS9ݴ/GXq;{M-a~6xڅK˷zmw"fTر3i`,: f0xr/m;0YY@}Y;Ɖ9/BIi1A '7:>q:r`HvbϼxN9nXGQLMIdϾDyG gq۰k 4u˼qPP3|r gٻs?Cz>kdum>z;9z4-ĢQo=vIC8ed^}n:FȮgRw˻OY +_@GafGXw,( 'kg ݜn8}(Esr}Q^B+/03HxO3GNXUK=SXd/Yǚ9؞, c6Vz*08CT.[GYϑUTHȎqr:3p}'Ki68xq㣻$N)޴56I{azr"8X8Ϟ{"̝UNf$ ƹab2)p}hS5w>Ku Kyy%%Yl39D[158N(T~az2+(02K[k+cr/n}Q;D8o.޼|3MdRdqngMw*76 ,cne6 ?wݻcY%d'9tc=zܲcϦxCԯ|{7F[;nj_$,';ΆZn džt7幧yX3JjfUSݾdi'%Byy fNmsmjehûwC,7,)c0Ͽm#frNWsnRR3u%d47FzI)|(;^ġsdձt^}v]tGjgϥ(]ynQm&ϧ4B8/D! g}e,<ǖ'_Hµ׳"{4m~i8v2*ru+ȲyQz9ź믥*?~5˯&?;Gm[|s4=5t6sa5UNGCQ~&=M:tkcqM%^qxoo.?0gqNb}4vƆYw-\z1D9u, 5Fi<"ͧNpn0Iil29 ٥V{g;qCaVep_,+Ŏpz}TVSU{p E5sY6 G,(cV]5-O|uN?)Y%8$x'iPW]I^v&uyG'281D Xp6y3%[Dum y黠X{qL31_6Te2.EU̮ʧ=5u9vq.bђEd9zy*p},ѡ[Z9}8mʍLYHL{G7Q7HQU-sj*M \L*ȋnγx-OܸIFzhju|dQ]V@IrfS<%յ]X΂y HE{y呟'H]}-ŹYVf~4ΙO{_q5udd1gJV=IOk#m}@&fʸ Ν9nl BY|7&hb(k el >8~vygjmyRaG00׳p^a{[9~U 2RQWOOFR&ݻŵpN)SDSkP.յ5gal3ippMJkK v޸̠X7);|Ϣ4/Ši'ܓYv+g>w暹}lj{_Ž qH߸K(+J"~1fΛE^Х!)gt!ЋMD[(PUd^ cj)™,Y|3̑YPpG#O4"Xj.Mv!6CsS }#򩬮(9}rJYx6k%:dUllr.-g9҃/YUG:8rK %m?ʼn^\WVǂY:Js8?Y8`zsӸ3)MtK8wF_4 @7No9;ؽ,u7\ƕs gygOrj4Ĭ s(Ü"|B*N=ܻ̋3Q#hĩ.,4+0yli??EU]-!b);hl=GBfͪ8Iv! eA+$j/>k$?ϩ"rZK˽WF 91ɾ-O?OsӲjBMO58Q=3%.֚.֝s]w׵S] Dtx7ݝ0&]2ׇ3Q+u݉ ^{'O_aG>`5$c:22/Qh1I/gzb'{jD7{cT1RwFMoKLĶ6|C'R)spK`76`Ѫ*Lrzĉϝp~Cy֕`Zg`jl*Ѥ%H (F Dl1Rdek\0s[n a4 EgfuYS#m@4&ݧ/H%SA-\xǑE'cx0Y2ʦ=d K=My-$˯0/=<Φ@˙^wȩS/ O'EVdJ98,[)2Eoo'ҟN?Ft&]~hX~ƴc`hIFz';QsbH1z:^s&DLa>X;u\sy^k 1v?#N¯p1s8, )ɝIaIG$3H`981[٥9349ʹϓ(z~Lo[Ht]w1swfj?M>71:2J5"dg0M(y71(_z/):ޏ{oB-IjZ֍[8iV#b-\KqϜaeVmśݍy{ɻog(@NZq>~k7Oܻ c!w^Mt_nQZ61d3.ݓ䃷ދ,c:M{>; w.2njܩ3e2o=44""""WZ LVIKNcŌ72rw#?v_Ce~ކ#\ϯ=yll2 &36ǿ?~Cj#3}.s'HKՕ%:#y[ !ÂkX:{`~7717^+2Vϻ;s61A~ 69N[q>EJcά*r|#oqr';XayaCo\UӦ&9;U@nֵϴxKx !M~K{sE~^uy~Ńt<:: <"""""""y 0DDDDDDD` GDDDDDD-g!I$L&Ϲ*[Duo >\?Ȉ]^V::%3#}#c<\?쁑J%O61h1`]>ccpu]<2"`{0ض㦒b{BKJ3u\ܚ7\k̴ǝ`xhkq~78Λ{ '^w1LI>};7CAzcm88>'HEikic8cl;O>뇚HJ|@)qI6E۱(knճ M7 M~(۶b隍[PjG8gAy#>$,Z1Fz83H(w(+#/;@]}=|J|oc'`n9k֖cmzajGvA% QYZHXRS4:f\-<>1Qc0\𜋶;dA fSTRIuM!TUR^;~K RĂEZki03Tl+Yܩ;<2kXuyzg醤5G[?{oGH6~XhȻ(ãQ)( Gbl6)#3;̰Sd摛h1뫳qc0kq]7"dSXb1.#Ìǒg4\7h4/"7taF>< Bl13jfXu;)FFH';'HЙ&g) ;;pЏcl*(Idgg7xǤb ?Bnn6 3wd _R KOVN6AW``ppN ep M&kT|#[_dgu7]GIv%#HZHf&!)Fb"Dw""""""i8H8n7Iǿs{VXod==zx:Xzw_{x-*gɶb?u91~J;|e^MNv 3{8>m94fќz"7Fӑl# g3P6&8 q695߼Pm2p\SsAƠcl=3Lwe 9w5S>[(aSQOtcC=4['Hhn ;2׏p>7߸ˆNx|Y ]d9y[㬹h=u}3^_GYXuc;u!q:ZڰŋUUu%=F+2+#ɉ}vhk?t Js.#if%v.7l\3Hc0TNlܰslݲ@1)l;?+q/ɻ/`-NF w|5ofV7rxI>{X^_J 5֧~Ywsܺ=~m:FMp|vvǩ\Ӭ-'=Ϲdn~:wla&~C{ygp.vnIs8W<[^^zy<b)0D:9~h\T %̯Φb2>pMɈma, 쑽`n>ľS;ocQU.FHDDDDDDޗe4k-:>ۿ7Ʒ(C;4ew>9n f GxZjVrrle3/{hגOpq2kgSbfz er,/% #RqnDG`! g`$N82L#`-&Mݬc~?~ Hξ5dQ_p^-s3.+)yqLr[^eꊳn3 M{TI+XW<= 7/z65YkU]F-dy<6J]]%a 2Viqr|v%+uL ֮.d愧 !@I\V/6No9~̠lghy9G wi?sT~59X,Y}! RYIS9sQJrݫVCDDDDDD]2U@. cH5NhhZhZ}}0T@&>'r?}"6Tgnhg5||Ŕ:Sc,M~7xZqP8 =}d+*SֺX\0> MEG9Nnr. t _@l`pR퟈mlz[8t H\"En~>ir _ZȦ`ʥa-o/$w3>?#Bŵ9DxqVDDDDDDD<] !I%$Gƙ*i!j~ zl?Ӵ$X#I՝\`%H{pdWnN|퇚)_גj=̳/$g|&ȥ*3=MJ[ >!2es(q&j5 B Lܼt/ݒɱm;978x@F> Z:aR Grk)2oΦEywIժy\ډm.=}yט!'?>Օmp$v柈޻ 0Ƈm`(NI]ס||2CWl7eqjszv<7 ]<ӉkB[#R`JV|bcGS 7'FL^7"9}Dd25 ꡷캕,Kټg9|8=IT2AbkԜO&~#ddd8{:+/lh9j+KN!uTf[&Ef(,39O 9sȋC8$6 ֬cvq@Zymϒ떓H)O2MKiΦM[8gņWUR[n ft$yVe[88@nA%sgeIp1:F\+(̍L>ph;:E!3|`qTϞOy$ᝯX+HsϢY9t:ľ#g3^0BjP9ghjl̹Af;'b޻f,Ȉkru²Zvx[vgn\SS` k` Q9k6Ź3zIcgpp`0G1G9w7:H`(<} RXJuy]'X c5gt6s`V>U̪-!5ΉS F!,[Og) 33o# ?""""""2q聩k >1QTXHFFƌn*A4'e-/@$13MOnX,F҅`(LL{]K2|k$8|6gh8Av^挮#Dh<`-^. Ȉs ƺcQb K X)|%LYp(c XO8ZLjƓ!+P%I(qá .hx2/" }))NcC3DP|.A!?8a>_zN,F<  8T0KSs YYYWTӺ)8I7}eSbqRnX 8dz`(I!Ib$\|Ƥ{I'8x ~$RXXH~^~xˣr/zt|22yFB0+;ѠՌ3Er]+qYu1ӟ꛶xHEf˭ u"]by fsI_b\11\(x ^ls6 E""^p-5sb0Ųᯮ!{z:{̠tCRX)#W""srIW Co_?EGDDEQ&;;kV""ޣo'k-~]_"~\^aap.nMLDDD~]^d),cwFDDﮫ]q9dbź./.M7D(N*>Bw8YD4CDD*I 0jb-u/6qi]$ Gپ8%kofx;0LSwgd-"B>h|D;?΂OxGC:OmK_m鏹qvVs+C57#ʧ<`&t c nb{%0L*jUULw&h9?:=e522>_3tljj,/&W?}=c~!\vǝ,*Ɯm].˝U"""<C;7 QQ^NYq>#;_cG[^2A0y1r~ݍ1KۈSQ^Foɋ fl;3l/ZMDD{CH ʨ)#Xdײ~n>n%X7-=?4"?TZ9l+#j0q:z-!;l2gqm][`cƤh;/} n qj 2!֒WOaӴYy3wέ>fƷ8Y#U9AuP_ŗ;K0Sbt*!7ÙD A3ȈUejxW50`H%S'@ |cg|nX,F2DA%'pq!"Ƥ1ƣq\kÄ>T"ul2N, H$ ҸII8D!,֍Ӱ% K"`K,%rG8M%IG8&k8K""" gC<4d Çu]ROgpTŃR xh, 1@bM=JK">| !2"Dʂ)%' SaX, u]2eqK, y 2y0rL\BbkXZ8;7Uԅ:Ikc#tvR:6,.n^?B" a{ˆjR9n~;Bz|=tǯ>+;Pin6m'ؼi m٬-7ܳ>zw]3>SIz{;)ﺑk?u˲q#ۻ F ֯,7H*MRV>Iժԇ7RvHFh>EkӋxc\[cwuYLYVk݋ fX2̩Sgٻm+M>cIe[x-j>nXN7u36>FOWEzr {FhX /x<֮[]7o{FS}ёqWpʹdRt3[S9=prx : W5TX?}?7,KpsJrE1L\;ÐS{>k]Wعy.O0}2c-g޿љ(ஏKYX+'Μct,@o#nqEN;l`l?*~޽M}zLj|qY3~?::}nHf>D{I~~b8 gv?ˏ?I{">+Uu5/\=OUeav ᶛVQg(^I_Ԧ wXy~߽,o|N)ej,7~OOEMA6vҴiv }Ý/yo0gٱ7W韰ig9G[⪓|Xh7m1C~V2+,}gyWI޻#yl!IEKSª>/LJouQ7p vg9+|_}uq(Dyto/+ow/eģ;Β0kOnbϱv Vj lXXLP,x3˫38c_ou%҅ `QR3,]1|W8ply[_C8 #dz c!. !"&E{)泓[`.+o٥8}G}`ddfk7$ӵY܂-O3ldR]\LtG%/cFc@`mzjU~l0ϗ" MŬy ][?Ǫk$ 4c׹5 0en%#PVx=VIJ嫙k]ys]:<ߩ9F΁ @9"iɒl9ȳ;ڞ]kgƶ$KXdE( r 49wߜ{эDp9uSO 浴ʫCx񥗩~F̕"gd`ŏpgIikznw+/۟GIזv5m@Y 5^ 5>?k2SZshFmbacq /l<d;LzcY[K&B v4x8p{h\셌;\C=郻c4 O5\hFzNɭZ{ڃ14,Dqtczrx5!?*lZڀmrʹ4(%kX5wcAF# P1аt3lfJ:iLU xaNuiRNL^⌞!ܩSam ^q Dlt9'Fvp4]v) !Gm۬_0ŗsfAcI)RX&[8nx)Ʈ#:y;v3GaЎLqQ5t1ʡ xX( ّ's0qS aہ^)ٽhL0aEmlŷ_xfBqk3W;Mj &rչdǺx㹟q(0v}^~­$R9FGGЖ@(P/cMhY n~w?=8޽N9%vhw="d߱rxhhm!gm8AgoykfӲF"zښ <;7QMN26PS8{yzMT[Q\=s }UbXJq[So@][b~-m,H}K;AMꡣbJ|l3a{x m˖P0*o<׳|1Txo[.*1}o 70uLqoo'ݻ_ϿdXrS@]XMj4}fUyf$^"u0 7cMozkcO` O?{}SYLmB!nsjիKtnv D)ɗP4U9Ϲ_~ B!.8w}/|/&ȏgnV-!SX@k iuk`aMp*Ek]Gػ(5ov_{aZ\h,zrʹ kB\R9G'*SGbv!$B!neF|{& ^<c TC:?Oz<,lMК&!7ٻy2szP `)(BOS VTRWWϾ@1X ½**biodԃBl߳n"Z;meW| !#RNKc4F_׳eki+2eC!G-(uVG_{A""3^Uf~”3UXi$B!n*yߺ7U#|B!.C[j^~1r썮Bqr<>eR0X4[B!n6lC{8c]!ٶMMM5>,1.9VpwMkHwle.kR4lS~o) 0ƀrf-kϸJa)q d2YE]9l>/ =R[B_znBqf;~ ƻ=/r|>Ma[ !WDa)v3;?B;sM#1:ٶ )!Sv6G]``yp;Nх 9wEk'=ޝ;/RH'-;\%1./ؠt}/4T:5kae*3ʃQ䀺R# u`)R9ߋ2\͸^W1MGKҪҹBqf3qկ:i[Ռd\ ߄B+,Cxni޻ ?̫CgxYW':M5QbVԮ'ܑƏ&7X7/%c<~~VC;v{m<|oُ݁aB>ϗ;|c #ЉPU5\'E_<'=@={,_ O0FUKq !3 (p(FQ,ɀeY9, KY(eZOmWJM{S6ceUOQXUJu鸳G͐g !7"͉=*.ފ \[s  'vxr)AEom3ie)b0z#x]ac%o|E>~'wxCT>oh!ͭ̋ov}f?ple%ر ܶ~RśPx><pmm e?A_Yeuf&X4²J+8ZOj(Sn12m 88/Sl&2Zh]n(}y]:rLRю|7ܓvMS p>EL[1r;vL&]jdI6IWi&Rd6M 0:1#B!n8_f؈el,#d*1FTb w.͔3>IJEM|žcG9| 'h ʠ !o.L!3׾_ٺ4l~W{I`Y:;»¡aC]cI^ٺDA3rbS PKo77S(e*w~}ȦGw`"|k⍃KM,h{ݷDQ]]8T!ćΠeeUt{w<]zk&R c`%Nk IL# >6xQD+H8Zx{Yt Zy(hz. gO"\SOMO{=MP8a{u: d.ox_׶b,IW%aGhldv=CQ93s;!RC}uS[_s$ Xk/O_e0m\<۞96._m~'w7<cٸ9>rS/2>rR58WE"I;7Vj?)GOr[{m/fWWQsh+A~inZ*?x 4_Le@n!wu7AFj?دͭl\9}c< kYcA.jr5qmqq%Bkg!2oD ~__`cMXvlAƊ:#p٘ۃeIs'b):L.^lb53vcXF[Ny1zp'ϰzI%VMɍp:jq{gC;_Փ^E}ܞ78/%&c ıdv^ R*5̻_?l^>XK(KMS ?. F6d^:3,_-~ 1:œwR40x` sPȶ}_rΘBRȓt)R(:`ĉJ89Li=wva, BANf-.9\)VhhMhZ~ziZoIW!seY>|>nn7;v|G1Ɯ+90.` @?~K9* U!ORpl/᠋d/S 5vqMȧ rUضPY3_kS2F#};X=>/Bʢj |WpywuX8gN`[1>5 HgJ/T鍈P  &́)o}Ѡ<ϯ!>p qʢi *[8'a9Bɗv$x.1<6= 鬎q,MwG QT6-`^Uێ0R(-;C,` @|H:ta ڥο`5]<,ڊ tQ `L|DQ>6[㳟z~ >FV]zW &`! ⋯o 8~8= uu-} sʓ=uwL2tv/n$*JBkMql٠35s )3J5Nı-h_┎P \Q"-!byE`` qv Yڦj^gCR,Ig2kaL9q̄ˍײ8i.8g A )Oef`L1|t4gkΡU Z):LGaZ.E[M̌M3}4-臜]ṿ~sG=m339EFF3B>RC{ Qi*y3g(ßghpMt,̌jB!>1b1}a^x%:OR~~s'ХE_JU~RN9=`/O}{ɂh(ɼb;[8=~BA)Hqp1V,P y[a, He䭷p cE8's&`)H_Rn_Pqw7{8}(񢅥rtuиhj< 1ص7||Zkn97%;Yhоd!QJwXx7q3f C?LhFn_1qfQ[郯).210@_ɼ([~ v'SѴ#?K(l";>@&ϢKZ &L0P̦I˜ls5mRR`(ŊLn}۶ 3a*w>g[7~Ϋ{:ҐɟH/^~ïvnʏ1EvH&FS_? #(F]n!85Xԓ|FcCunۓ??@FH$s5#ogU,h‰q$S˦u+;sp/\%45T2vj//>zsZ-faCA"^C;vF'?z?yW /cӊVd8s `_&=t^z6ZLccz8#Lrj K}K33[}ܭ[ٌN"|UUYyݒ![0a}y.F+6?KC4uU ÉL?v5Ul&L]ر0kޕ]~vkpM)~Qλ ZJعk7c446mv;] VQQn"(%|lEOWa̩嶍KyDzsxpe'ûo¿^>yy!=^ GbHiiicɢR=xd4[*/vwxIY-YDm(͞]DZ1oƠ{1PNCñ$8%x {7Xv#U^]kYa1ésbpEN{gN[p"B#1lOeKfwpڀΓN7^˩aj|]9b<=FP]DŽF0umlZ=[|okW/!l:?~Y0Bn7>ی1UzljD">~g_y]}C=9oo"Lm]-zZj )(FcTHEe-+֬*֊XRm9PM kVL 28ϴ:@L q>e[% 08Zâ 9BRp|^v493,* iz;3Ly{x\=P)0ee456XJӃmTTT\tTڙQ/e\je[X:FDPgV3?D̬eAn1:ؖ]JYgm쏔azr?UJq $*P9F$SGp8s4.Rj'0B|q8A{[+HdFqijj:7 XE)1x |Vꠜw0q.} Fk3 3,ܧB!>,hGѺr0#)9w/gJgч,4ʠ@L޻1fqc\tM&_L{8+'*cf?r!+Lܺ%h}/tE=^ T!8k6P밌B!e^urv y~CB!n2KSB!$n!5{71!Bq0 !7پo !B9n2,R&f31 1)UK!7d}}Y"y0!CV C]LLLFB1im þ][1JzzzB!.RPQvt `!eQUU(ڑʄBDDai**\6BaV !׏A) 7k/%1x^ot5B+&G)E8B!n( `AB!B!fUHB!B1IC!B!sL!B!I4S!7%˨޺1y!nl۾ո% G( 7*B!emJ|Yf]stK!7c .Mee%.t/fR(шD"daVFbHcZH$ikB!.1&Fd$,+~n[BF qY+Os vID!MŲ,,}rBlߵdœ$!7 !:JYضUb.hpʲ52FLBeV>P{B!.U0r:ΝOP? DhJkS5^ےA)ÿRX^hwOw3sp`-u]jRK),uN:Oe6>k:wj6 !3|Gў ѐږ6-Ok!B|`B{o7gA#.g/)֮ӟ|5ZUzWeQd9~0Cqڢi!'V]Z =t_<2c66OIƏ+WO=Jk2 ⢣6Rdzy|h>|clXT (e@׵pݟ6`aP(aCmbӂڀ6$l B)=OкyXZZ !Ĝfr;<]iomD /.xg_!t 90,BuoS̆Mظ~5k׭G⋟ycCޖ3w|!U)qg{㬸X~` En~k=RǟxV-gUla>H17Ή%'EO kA,jfx/[bY}+u ( Oб/<-cX:e! v1IXXM%. !MviiG2Jݒe]~'64ҁAԴҹH_A!蹦$Px\X hP.>u]ӓdR E (0:OWh Bt*E2"_<mY6u^R 1X"5x}a҅Rap-KQgu+4ѿ7?'_k7$B|ꂟ_d@r[88 *p{PFM'H(8LSqƓ)II&SdN)QX,!J0|D@Bu[FbYSޏoŎq$'d˞V=~՘ӼOy@TVg=>M*e|d {h(;Ovhnẅ Ji q{҇.UJGi S0g- r^yߊ͢;f_Chf8y C 3dǸ5O~,[C)*7?|jԴ 墦H8L$'G__V1/HCu/!Qt[;*%w]6m 3v˃jǃB!0'|xbt:M(²}RDX&<~c#I~5ys6/X^Q`ˏK"*=X*Mj|bݽ7_@_˸W L<FB(!7붌1 VPY[Gvd.zInoL[H TviMUZ<#k{ΐ;('ˁ-/N[y 1*Fxmt{]Ir.kFP%BB]-jElݯ>l||MGDX?*=31S#!,Utus*(H$(R .!_IGt5緾R8?Dղ4G<B1vo,֚wǖwF^^Y8"=xukK7~GWrb r4m?ƽK[0,p/w.ךH8/ᅬeu. ?{c/Jin/>_B;zM˚;_|=$BqSn#0vpEˏeQt3M-ԄZ5ua\~~Co팗~g3> XƺBS|7 {n6T7)Nqݷ1һ{`jA:l7^>Enxؙ!^}i;_Cۚ;i3v /qe8ƻG <ԯ2/bCv)Nea{rP) }w1q>B|8lbe< {l߱cǎ9g}q5\ڀݲ-o˼&|o-Qjy~]}A~O-+cMXr[Caź;K6+jmڐW)B܊[C)E&5 U1`)7l >(zcGpc xNx /Jd_`(N{? cԮ@W`93㬭,NA15DW͊Z 4=]0Z0s۾{U#1`cxG$ G-䡡mMΊ ;4-}!"cO<?yyilh% ;ut ض]JUa 5Mmfǎ1z)P?K`CwU0@ƚ az,W\q6n <岰B;O}7VH!7YBbѥeJYX&DZ]ph?*;_#pM# [l9SV1:MqTŢ Ltz(|(o^%{e̜La00{5M)^ya+y3-QRΝm&O{I;ضm)3;-%o@ALSZ)aނvꓧ9=ZZ3 LXls~R]oqQB1*|q/[ʓO\ETRiYUƶK1(rx'3+i)6ݹSeGGń,w I޻{'Bѹxlhقs/B!50 b32D,L|_:6OnhN1 ,$8CdH%GbttOZlgͩ3ٿ{iLgW|ǯ3QYvU)($3=PoYT80j/{=|y[wP,+:Ӛl>ʫX{T$՚B(jjyijB8t>O>&8xgݤq2 GHgԤ~b0Ѹ؆vNgor GPNqoc|/w_;H^:B!ĭc_J7D"A0v8P"ګ[316J޹};HXy o5ۍJ q!MJr,hk"aA{4[%NvGhoF$6] ܶz1!׭1C" (~7Ó +/æzVU;8t(Goaym0y߾:a,ZH}u@];=ʿ0|m7fNŻncw?nsǦ4T3c8ͩ n;7Ezn7OUm5 6n}f>w~V֤"H`Y>o(yy ټrcG9| 7M{I,ho!wP~6(R?>a=]83Fi[8;q^y| zm A} ˹}q#MPJljDDŽBLhK+ʼnDvџ}+7_ڨ=TWyb(d3$SJ'\n zօ,d>t xdIRy?HRbtc x\hr4ss=.5===,Z`jI:ab$۷ nbU4V.͗²J/HQԥD@Z (Nd2I`C'3vT2A&oCιlD¤\'c 7@,eϥEK8]bgp* IDATR29]x](4cCd( [;[B,m***fܧ.'P 7@8蟱q$)%QȤ(&a) }QݱyURbT*MA[!Hk%L:ry+m FB4CGIZZ `8CWW7MMMn{T"z^yאS/9rS pt`GOKA"/i7XZ|,aB\RPry& ƀ"gjP$Fhs/\xaO˘5ĸ6 !&dӟwVh[j P?ҶK1rbTVJ%'K2e{G[?د|"iB!ۮy+{a9 u GaMEm r6yb]ˬ%KVw96&d>~Gzi\~!dWw_B!\5 }^N!▧, ~>mb Q !Y<C!0|uj*=B!( `!b<Եcd4B'f2ǘUVBuBn[cx!T+9R .桵P VܒR8SK!7jCsRJ&&&H&7:B!eS "(>OVe(C ,!:ZDfm0EuuBqU$xq}BAn!Ͳ,^ﬕ'9H:B!8YB!n*l+ !BBQf !B!B|!Bq#B!nF9zPB!s1d2EXEHB4,& bY3CB!s\<'q{,B!nLB@Ue嬔' !B9L)E"p(S!@)r<'O2B! XJaHBM B!MCB!n}גB!>|J!j!J!B|8RPfHgs8,ea<^\wB!IC!ןR8qÉQR4p"`5w{/-LB!IC!חR=<6㡥-.F?e<( ے2B!ĵB!#*&;< .MԴ擟Еs=ʲf.7ٸRS+r(eaY c4Ѡ,,B)v4zjNBY e F>hCߖRqQRSKiLMsQ`9I;j7sBm( P!י0Bq( Gy-6*A|h[r:Gߩ:(hYx!10z'wc4,58=:r%k׳)P%9ulpa#GOְnj]iN>DGo+Y0Jq:;O3<"[ iv/˱{Y65U`R}'?Lde'ZX~ǃG3cļ CiB!.NV!B!u0LXm]rāv4>< 4Ն8֏DoRcrl_v;#~/?ώg3zׯ?D S;_~/ġq 1o_}^ztS}wa, f/rh >p&cV~YvPq/c.6HWd#'K:PL<&c9-!!#0BqC!#er"R bsn'klXَ2OOy#X `C;c./]zmi^hghFin[LEjZ=wooF0_<7@o}M6,k2{p/ q]®hfσ.(ۗq;6C۰vMy-DcQV3=05|ⱻXFr8āT^SKB!ąHC!׏Rji: ,; jQ1hRUHWy=~lBԄJDb1|~\p]6vSQ#'`+ ?BE|L'c(tG (4bFQ,1$5Z;hwuͿ1xOiI˪/ !,%+B\BqhcQټ;nofp[j ͑(R '18Qʲq{/g^BC=?/(c4:gqE05Zs *go~|&ۻSXM~>UB!.HB!~i_kCDw*j J9o+o:A֑B!!B\WX4 3c޴(>"9o >sf7Ƿ$)>~bB~ omI;6Ƙ5P>Ac^# `,U`=XϏa|jR3g4>`BX=>Ŏ^5ԸgUD3жb3kE)fGyB[ԃy$B!yɿ &!H pW\B!DE@$S) vuw=*,C,i 260hB4CGIZZ `8CWW7MMMn{T"z^y2D!*5c4w* fH8}] S<^8~3k̅[nD!$B!B!$!B!B9OB!B!$!B!B9Ox !B4$qB!پeIC!bN3x≄,* vgH `!Ba@Ue%##%B\'.EuujJC!bm] !⊙Y>( !BlvBB"B!B9OB!B!d B!Bp1fB!B9 ˡFW㺰, ǃe]x@Xs(lے `!B! 6>>hyƭ5 CdǓ7׍1E49Lhۯ0B!RJ1:6FmM PFWf$vg8H3xڞvvot5?_[7D!B!n"l۾eضSpy](hsnzVʓB!BƘPjA(%1.vly\|Wc j>eTB!#J)M2:6NA_(BIGKd7W8E ĉ>v d3yw!B!7A ?ɳ  ~gf= ³o/MMW}7ȓ(xrR88݌}J#[?X`/a{)t8=]`q3#dfwl0B!b.)$ɾClÒї(?I=x v2?h]##cSPqȦ3 (>ZLXȐp. ]04:HL\y]I !B!d,)6W7wwqk)t"̫ws8zTA$zۇ5'7t;h<Z\Ab#".PF.%PgltX]:C1LcEem K166DJ"9~TStN3i9st!M$tEwdPoRZ/e (GE4@ϙtʠErdd<";y^3r|*HE<%ɡ#X,7&m(ݽb9 h1{Dn2ioƚ lA K PSWG$_rdN3U=EE\bA,%`r8IGs 2Of2r9p}a[hi*$'ʒf):t\pb CF`!B! v6eU>ic P_Kr!vuS8 \Z8"X>1?j,R'ydkE/2 f]]NʐO&(/^MRucg,>7 h5ASd=r^Kes>1  .<.E&5Fގ }vYql1fΏscT1( 'w&*]Y,gZ"GLcȦd2cdNiTqF+lݥQp4EF+4:d"UWAحfY/Nerq\84FOkc\s.{Md2{0E2YCQk.kڵe *ǘ"LlxPSϩ"\Q/VY$SHB!bNRDaNص4S{#l;sw0M!zїBY夐L=+j`#y;ה\Z?JQgHx}۶hqӘy:6mH6#x]gz*BǸήcTUR LqA^.oť/O Mu]=/4AQ8.M)-044L*q MXQӦ( kjPt5JHC!B!nb60 ,慄z7v1V,ZiO~莓I^Cw罟pO2%-\u=/>sS$16LTC K/ d3I<|l&H7{ljԵRW:aSd`hlQcmq( )z`7!B!Ⱥh؈@''X9/2BvbpXwwXz%{tORTU7UQvuXӶI'0\Ifq 8eLƂH&[$h{"%21s6rQB?m36+SҎ?x*G:gS$1:WE4r׌O)婍JKMu@@B!B1˔R;v|>2~TTj2s%>5j"'Yp8<\C¶Y3蚰Yt!a9'AW-aQC򒈢08'XQEg_c dmWJ100k3J"A qꦩiwSyIO!B!]"px&LUb#gkPʐM1ʅc_(K4bΩϭJVY`B!B(x %GoҒtv Zkm0FܬJKhGi.XdaF9*jp0Xn0B!B|5l|ldAa[[מ~qH&p&"Kp!N]Q,H95B!B#[0{SH0-  ²9e+U,+KYX\ԵQ,z^mfrzέ 0JC!B![} ɅLN(M)eϘr^R~bwȶYm2q)KB!B!(M"P\\v>_;0KF`!B! f[l|Dd2ɰM)zzǹhlR|eݚc &~2WC!B!njjkfppFW纰-JnyI ##r]B)E;(-vՐB!B`p6 ux mbxy\@Z! !B!R~usD4H>;$!B!sĭ ]>nL!B!B!HC!B!sN!q6\n֒n!B!-bW6 c XQ'uӊ!B!bYWG`njkotۄB!Bq W.k[yI!B!B}S!B!sTv7BB!B!ro3<ÓO>yxFV!B!I۞ya-F%߅B!B!nXEFWA!B!B!B!B!B!B!B!B!B!Bv+%tEXtdate:create2017-10-09T14:11:41+02:00\r%tEXtdate:modify2017-10-09T13:49:54+02:00NۧtEXtSoftwaregnome-screenshot>IENDB`Eqonomize-1.5.3/doc/html/C/figures/inputfield.png000066400000000000000000000064341416454732000217130ustar00rootroot00000000000000PNG  IHDR0] cHRMz&u0`:pQ<bKGDjtEXtRaw profile type iptc iptc 34 3842494d04040000000000161c02410007646967694b616d1c02460005352e372e30 b^b IDATxYlT9wf<= `1` $b ڴQU)mڗOU%JmTEJ.""4q!ȁqc/`{s0!!(dY3w;c?ߜ? +QÙcB! V, ;\ZkB B!< Ri6r&ls8ZjotD!ɦ1w&hX2nB!~G~ !qq/v Bǔeꢽr9"7 B)H`4x[~GԹgOƏZMxr )Za3I"=+'5GMP.$@!9RwΑ8%I{,wA+D39,FP rQ>ʹ[)CX2}Wn]({HMMug爤hJA" =P{ !O03B͎$/?O7q\Ө/сHgg|~ӟB])ZBs3?-J{ Y9_SYQ;&cܸt+hk?3]H_Zs픣!J)FFFر{/CCC|孔`y7\Y%nr8N!x(M^м5iz{!W_iYo55)z/EW.ys< Hۮ]|Wu(ǃPY?RKRϬ$IB(pHenR43ph?~|ttYbx8Ȇ;vXKQ(ı'5x3Sn$yAOB!@iˍ)A}g¦\8LSQUMm<攅p&~kgNp-3T֭`im%P5X?o&ɁIt&^zhVںz=sHA -/ЃEQY|.|E3k&~e4<ܽ۶lfTVT}.!BLKpCY~ƹvk~^zػ'.Zh8*X`SI"QIK^ ?MY6u:o&&s&>ۊkl[_(//gnׯn"(LST)5B!DT:-E;A7pMo|!JSvJ[v˛lr{(0n203j(WTwkܘѶ(79vmb`K=RiZi bBB khԷ*%s~O?lj4Wkع /f?Rܼǿ>IXJF Bf2vOݖ\eD8<5X^S &2j1/>g/#aad6ֿO2 SY)L{g1wf!^Ny+@dk X0)Ϧ]UEUELa!1T.b'rap K9l?Nib3Er|i)j ]S6 l݆lqT,`i<. &Kr^;I L\pѰx!~n{ԓ q7>؍ŋ:n!Ѱ8R- ɑN7529^/[@$7[*M%0V (W!+]Dw~8NqWK Z^c>EaQ A\j;C.k\J^H4ʲg@B3.=H`GYe53j=L&3嵔5˗1ЃAWfnE fQJlrX9FB+k7cQk` .XF+>lcL>, B!R*u|Xk"0 B!1c MMM(8 >B!Q>eBP)B'(.B"2tWU"BDŽR=$O .c:_34HxB!PVTpzE!b2c]H?ۻ^]^eXIfII* V( d1tidigiKam-5.7.0inputfield.pngdigiKam-5.7.0(53,%tEXtdate:create2017-10-09T14:53:55+02:00л!%tEXtdate:modify2017-10-09T14:53:55+02:00B tEXtexif:DocumentNameinputfield.pngtEXtexif:ExifImageLength40ŽGtEXtexif:ExifImageWidth754etEXtexif:ExifOffset130aHtEXtexif:ImageLength400tEXtexif:ImageWidth754ruftEXtexif:SoftwaredigiKam-5.7.0yEBtEXtSoftwaredigiKam 5.7.0 ( libpng version 1.6.32 - August 24, 2017 )tEXtunknowndigiKam-5.7.0IENDB`Eqonomize-1.5.3/doc/html/C/figures/ledger.png000066400000000000000000013432141416454732000210130ustar00rootroot00000000000000PNG  IHDRG?]DgAMA a cHRMz&u0`:pQ<bKGDIDATxwyss@@ERlY^k{{l׻^۲HIHQLbA0L= Ht^鮪S'|w@P( BP( BP( BP( Bqg"f~Q( BP( BXHOKwɏBP( BP( ę”H0&ucP( BP( Bq6G,0otL BP( BP(>2k HP( BP( B G BP( BP(BP( BP(;%Q( BP( BqGcA9!>z ;)G~~v+( BP(,J8rH) G"H˺QQܢ躎s; 2:: Ht]'-5s1GF}#MVfvFGFP( B#P‘dxd@MotT(iOI!==Mh,Q p\J@"A 6g##߶˲bxdܜBP( @ G)%cct:ott ?K8]n4MSr㗙H@Jp:ܮ'6 n#( BP(w J8rHiDŽHX5g$I$s6o&( BP(,J8r HeBL @Z&6]=BH,^P܈;rNGp 7^j@J6cP( BP(ޏ$wȂ⃒(ČDZKJ0#o<̶S_0k1B ;Ͼ={/+Cl(ft:pgԋkE9#BC׵@N+u d?ג1>pD 0mh{Vsi!az;/Hcw-,0q^˿Z#h~$2|X FCdTd:\7:QWqa^|AuqtAZؽzlX* qWDz~ϯ-ƟH0QBP( BPiOny`;7~)q$mqJXY^gyqiDJ.UUTVaLG:#DC\D'+*ԭy'YL]~ !4wۼ [ny'č )n2]Q6UvWloc$.}Ĥru+T\6^x TW)xGso"`^ACJl%BR?0i!_'%3Û̈mq S$/C\o3s"/p)*.AqM- |&{oƂ[ӜMwg쮬Du0qGi׹$$EP( BĸvD*3N#nhaҚ-0c0qnnMDCABRzpÌ3 axnt!E<#fXn6EB1tϙTcQ Ebh)^gbhi?3O=L^TN ĴփTZ+|ʧ. ?V.G BP(Ok )j%^2,x}a}#jq!hTS;ct_aLSOpz8 Q ]01:`O=V>_fA~ }C4}'^EN8AW$':tw:"6x_{y(1\dRK,7mcEZ32]m}9~~QgyVU#vںz Ecv :qEGGӃOoD_IO~Z#6:>Ľc^tr'TaI!MZX^ZmfW{E˖澇YSuyRŞ\\-fyuMEgϜo$P7=q? wWg0Jcs't^$,=D3#8s%aݫ)Iw2q~|V89oW_m9o@+<ݢ)&XГ|z"l}Mv2h9_̣O=MEJA^tmq.7ǤwzdQ443΅Ǡ'G域{5g{v3O,ma~Y =M;Ԅp<8 > Ӱ]N\D Wsr!́QVsf;q^g+)݌v~wYk8;OD:iG݁64d3qMd@+bI9OGkICڽwv&cX~(Տ=ښg4'xDP( B$ƍ^-mQ2ĵ ,/&axsxorWӟsy4t#7džYa>Ggq>^1y%eEؐ9(jXD}X$ cc5>s~FMf|?hKI#0LG(ĦkSZ%?eMr[N|tM' yxeƱ1oEc6n݇?x/>K*skrfgHp3_z^vO-;NhcEk Oދٴ6!iX=ʯ93qPfOL}+o --{o!pzzVF>>y6]HFlケxN=~|󏳢f~h#|9KֱGp"O_PLznf(i,-"`ɄIU<4‰h b?4c& qg.Z~%Py;edddJB0D3ib7^}g_=xzyx }(SU50v0jYn{|~^F/sO<(/}l=Ӈ%CGش#)} [^KiBx w!nĺB:}sLmin>>(D8th;[)hXcCFtO1ΒqN9ȩsyO4 G/)T7P}O}?7dUef.y]> BP( 4Gsiİ[u c,p?]SH,V@p7T>K$tIdTQC/4X|/kb<E.vMq88*֨RJhoo睍xb=k%~ %jҁ`GZ6 jY. zH ecc_|??{|U ʠ=a*j(sQϵ۶qn!Jzڙ_ܰL\.[G[cS)jH;ab*cZx7M`9p:1ۍɓ|Y ceJlS: XoPUnQ\EaGy-GL2\gb2*231˨,|/kgh,vlJW%Q( BP(>YI8…y%?n=@ߺzJ<&CtM4HiZ2Sn(ea A<0DODFE9Fb,j0ƗS,K&ٴ0g-P?HXLݛXhh`}#3B‘F; aϡfBI3ia%4|ěs#C41,x$g'5eFr %Ȟw7_~|)כO2%B\3c17f#4SXn#߽T/034cQN(xddbrÛ>MZ`XTMu2uZ"QL\1cr) Nq{M&f&i!vjM ؤh2LLE2 skXl ׯrҖumBHdY)L E(!n 0ݣ)- [/g0g9x̓;Ogin<ÍD=JsE:/|X4J(MfC~»G@y-?ǁsàiM#2o~[Ga# BP( 'A gBhw7Kr=?ʼ44M 6-cCGN9!ʒB )wt#'1a((/jrmAZε~m]-kܩ[cʀEڻMrav]8?#ܝDZy8GJf%EY$fu8GδroOYY%55xaN=JS0vedgPYMGO(8R]\lmBWmȼCzM ]TS/G FPb,QG„ ݉ƦOUCj<6-)lx4B8C4&ꌖ,ۘadZt1넒H8LۍCŭ"ަ&f`&PiahB MlNw\twwSUUn[EGG'Jԛa%`$iXRa1BQ˃ǩ'bNJΝ?~r/mʦ1'4b, ݉D 1`-=Gi!h6lG.c*eƱ9]صib<v۬|B0<2BOO\<vJg*SD Y~PHHjM֛hDuNr{p [=6M$̏Q9hNt'3q8h;NgM:@BP( B Iei>6aYo AM3>'e=$j5؜#"vץBP( BQ\i50?G/՟F{is>}3^]8sq|pfECm9ǂ $02Vfwt\1?3{9gא׉;dڇIɤW~]YkgGͫ+>}s>19OrUP( BPŵ Gd$,Spw7ƻ/b r8l4uGB땷Bz9(%.$7u eqɩ0Ӥϛۖ BP( %FnwONO7@0nLym#dӂ_Jˢ'Ûש" X^ɜFGOP( BPv(U2iVs' %8p~Bi@Ӵ,^&H5 C{{m="DhGP( BP|R(Uv)))v,]BŘma(m6|>e$Metl 6+EJFGCP( BcP‘k@+>.v;YYY7: BP( BqV BP( BP(hpDP( BP( 5@? BP( BP|H0WÇzLq&FpǟP( BP(1.]$C1-eYc M<.qK›]QSSB"'ScK<'QiC!))7:*[`ݎQĢ1|>c0MBUf2vx!8NFGB\sW-1!V M)gJ8 34β!UkV(>qKc* !CC&. G  Rcmb1898l:ng%}0MLn5˒4 >^$wCJ!+ 9CK#.BkF0GBm'nV@C^tDz;F8~V>lYZBP( Ch59Mhwk7>7!erBNJyG F&Q$B1F"gG䶮#I25qi]S/2"kguhƃtoƶ i2n歽HmEZ{i9X\M37*%}ٕ5jBq h@l<^n'ZLĂcbY KZHKv|)OɝĈ L14-vؐi c;PA 8qCbwo@c4_&t=a` NL 44MqNi8&FbXH,S&v5 Ӎ'lo$gf4w9!o>/L8M1A1@,D(s'DM 77wwzCTe/۽i?:.@Anz=/*r|7dWX>gm?G`"LL1, $݉ŮTAh`o39*4^(nuQ^N DM#BҌ2 N|)>n%GiI8""#zWhi,\XAב%ղjB;NqlslR-6#'Y=^Ȧ.cm΋C,s]N^Eۄ9gʲbDoD[L_H(v& a11[~vjWgbH YŔe8mK¼}|@4o͟0?ϛ08w>˗XO^I8"%8S X7pNᥗ#|&:ʆz!-7s_L߿`F O|IqnQ6CR'uYpO-Gq/rhۛ#VIH gN_z9}V!Ǥ%&0ie_R:[jf㖭7kX.2 F铼7͑BZV6u+S-"0;5s2f^ ۝ҽ~ TRU $4{v={"IIay̸Qo#Гmfp3tcCQia 9G7l K_}hB\1Xul6}vIv8}iO_{)/#}?Kzҗ'2/]$Gʇ84f9so]i!;nfK|tmv_339' B<K # {sU</bQJJYwZ2-VF |NAeHx L8)ʒ46=jQh9*sDhe<%+;wM1pw yN1ճ ^Z[7Habs|+`Zw20ė[utaZ韈!FVI5598hDAgb32?6jpp! Wcye&BJ:0L767~o. kyHx^Tg9}Ŭ_[9~,zߊ &/r02WMf -t念?륰r>+a.o|0q iyUґ$ qډ8#u14 R]:F5,]ytE9y kYo҇ri*3bJ} \lez Nnb4-`,N2\l:ʙӭY,]Lw(N !lHVŴˆCZ#M}Ԭ\'#fE 6? 1z5p[f(3g?fBrAF)47~`k4|n/Ͱp t#t'}[7u ӎmc[_ ݟ< !cCٸSv½^lh&ŭ(*\ [INov0Ɨ8&:Y`Lpl{iQXYMiC#\8owyM=S- 9%{q'&`e??ߦc sdݷفݍ'N" #4Mk?%GTTU~a<ο|;|s6~c=afDHt?y] [Lxظ1_եzN)cʮS}dTQUܡ\o_ ;LJ**)L5Nz<_cX>?p/_AD !e/?atN硷?xBǜV2+14bA9.3B{K#,rҽhM\O_qn9+I/7H 6nH\i78Kw_X_Ékk{Æ 8M_ĉ[kvE^{8mg-3]ƻLTX&Gndomw_/oo!>6l>Њx~/o#/=^޼&vk}|vHzqUE~ڏu0 gFNtN`s: _BqB|QzCNͣWL붃]%|+@i,^\g0n3CŹ~k*pQTW䣋/3 y-b :'E]y *~%a FF"h,gf$E ť\H}pfw 4hlF(M;XF"i%54Ltg}?bW?B?t'RZ\n\N'nMݛ5K?2h9j~!v9nT!Nc&Fqd,'`oErVnчjJI,3_amCG苖b2L.gffn󑒖inj lv6]ڨN'..d^{i",l!-²@j6&~S=t&YLo%N>rjIhm=\Ǫd.}!3*x$6>(QmfKbSGz6,ƴjRJ#Q"1) "$5ՃfY \8MX~:6ibXR47'1B ˍ#8SXt1۟mgbqPOIiYX2)7^<ױj^ /\l{/?y?eNtaNbO},<0$|1j3xZ.6` RPOmZ ޚ{qawر͡=&qu: Ʊ$Fkg%F;unaGd7<028hH|֮fϛ9u%> G}m'Q_28恇 Yxnt|,,J͒Բ|s_]#D"75aq&`Mtt]hHObd4Mz2~.M-G"MZ9Z)C ˒7?~IZ‘r_ᑇ! NϳkY7'ӻ Xj)o?uΫ'5jYn-۷dQZRB㙳{ eu2sX>N$@wogF(I|PIJ,LĴnaeDSe8pKW.WGۉnCJ6z22UG}s٩B2{( -k#rcq9셓/ N>1]J^޽ODÉs͒N:D\8lcִCG]a"G1$c/s=p}ۈJ iDbX$ÈNBӈa̘݆MK8'9&tx9 W^>;[z/uclۺ9Gp7#Qx;cSwOې'B4_ dʩ>ʲ,N< 2&ػΜU;̧AXV1>MǦi6_ 9/0n1 pdpkкؼy -Cy|&7ǁi,ͻ.ɶ,4 baeüu7b:+Nٲ[wNɊ`U{vrqܚqbN>L@%fYJa .7ui;-;5 ܁Kƺϲm6>τeΜ/m[3ÊGC=8pX!z{"TmP8Z'MB#%BA~WhO9P5bqZϴ25L00,KJ˂Bp=Gf#Tzٿ {bTV%7ѯp8X~i:zuR]]5 u:gwm'bZÃGR1_B}Q'y F>ǢӞk=K,$`"m>zbN.Lcq⦙-I&sX0F#6! /\S[AUA:br!IkɟU|LQOSSJL´ 5E=H/faMosmô VހwFx4=ngrd @y(ȧ*;]!lXF`0HIJK1:ih3RbY&}mlT丱|96a4j89EØc[E87Jb^i66 ż4t$7䲠ʼnmoe%n_\cEH]@'@h?Y]0 #Fʨ` o|nW!yiyX[ORGS[Su8m$2Qv"v+0]G"04h4,y̪gjv089J*cfK?ds;,[,7'nXS{̪,'?[oos$wO ?nF1|i 26t[ 8 6ڳeiׯ_ z!vǰL#<ǻ6,xa" ?{wC^%yY,_Mo㬠gP$e*ˮ”?ܛ\X!R1cAڎaӎ#Ln2݌~w8{]P1U\3B TF8s#]ēWw-ܲQW`q:DG0C= [)xlw@T  ,0wvq.+) w2^J]y>a:MO)]Ƃ,2}8rf qI%|jMn` U|Cb@ѲT_K,xFfO"p7m܄+IwhGrXV0Q(>$e GzSI+F׉<ݸJSU3v`E8{82J)-N=l~:򨭭&!Ρ6$@c(@o {]ǸwA61 L{wuehc{JY>#NC4aQC`&mǎh It'ETgkطcQc rrXham%&hnm!`Ϡ4/\ؿ06 #\Oe۾AБIq}K*rCC8<^"?q'$Z0O+2?gq9;;~%m!}B06 cgضu ]Q 0AClz%>2u }V@~ю3lߴPz..I4v{A*2=x3 H9yCl{'g1f7'b>Kke[{xa^p{O! OjOX0!A<㹒шrai֑825UV$@㡭l<1 )MA#F}Htpv+pN¦QϟOEi98n1~k+$2p[vdim>4D: :;h8AFN Ei82y>Jݸ\:-[)Ys?˪JϱcQB  ŸCغ#,#縩eoH`{7@δl2Fvl 't:6Djo}4Fvq99Ƕǡ5KQh:MCx\nΞ/0lsorfBl#۶q-H%Te8F_//)(W[wP݃1 Eǂ\9Ys))k|I`$ooǨ;ʢ,[Rxg#",\ 9L\<Ŷif,B`s1:hGt4:38Ү:Nvn9 7=LJ0#-2(GdIuv!NZN!y~n?U rIMMnbeQZGfN! 6PQV3Eno; G0}CxK!-=T_j[p&+WԓNd0ȻhWK-N/VIyԕq((gyd{s+ GL 1P7t'CAƈ ՋW5dxTW{hX04./U ,+ಢ Y.JҜWu8H+c%`Q@^Ni 2ҽ388NJV9YfB9nG1JR G׳v<Ozy)H[H^0eegחEz0C#DkeYu.6L&F}琓GWcxpOz!EgsH\8"F!%Tr8Z 0c*n2).bz ҽ8ܩT_ʒ|6U ,-!ėYȒ(;TϛOdxxp\r:.(!@ ť䧢ivrY4HRK^^.irM2&p(Q[W]ղ|Q8CL"DcE_l2 2Sq.^҆2RS3(*K">?<2s`E>n?e YXCwMpp;GcV6:LЕCmUԗf|"YFF<2NH"rReew%'B t5cx?nc_HC}1x`0x?U>Ƚ+O),H˫`.\),XL]a:#N(5˫'Yz-5y)I3NQbtxH0dɒsѓSZ' Yv;T]AZ B2a Mvi8{츉tȤC3MѴdbZSfSZ Ue- |)a$Ɯ&ډ##dU:0>`FL:̴D}"+DKșmM&Ú}m%cTlCbF.j4'izrvHZ̎;&Ѵ}Ф=̚CN!foj1G!a^e6ft-MJS'dMm6L:d9;8B044T"drV7+I34ZR$m_o|?d]>2.%ѥ7YN0l//BB0Pp 0' g.757˴]?ԘLz\鹙scm1.yky]]V}xqnk=fL8ՄHcެqFFGΞfwd^%]kr/EҔJ̜$TY'ޗhhSe2sm*?w*8ր?纬 ¹f'Kߖ9xe%qyrܽRzd_g TzZe>QJL4qIC2M,.K+Hǚqa[5yV|$2UC9g>\9J91M~ڌ(qh|ԕ)a̎㊏eU-窓Oھ_QhrVkNKtsM /o˘7gHi~}믨(II=3-^D)ijWdh`R:V'}d5Hvz0mrl~x")g0JsK-eufMs]ӗ]QG)g?ոytf(/{~2̩32_Μ$n4?)#j.|pclA+W/o2֝ЈٟQx_YL9g|l@^ōC  C#dxB}EaXmJk coNuK#1Fƈfǡ+ fgi5w7(_ŭfPXV]w-!14Aau-d؍FH^Rr*Y|7QSP(iaϨ[*9LׄM]~ʇ>]Fwz)iX݋pO0!; +rk;GxLҥP( wP:iaK+3+R1H=%{ qJ7 u$ks#P(n)$i 0NVS&32,˺QB`}:pCj,7sVO)4ttގiU\7B0yȩ62~y I>;s14)MCĴj>[hg#]!"H%syYgyQ -cӤl2\vc#bх#׆KzZrͪkY-'s9u fݑJ %?pDJ #9ydy! 2>ȹ&uĐv/UW] !Ѩfr9H!cn=%y ;g_iӈc1S G#M@0N)pYh{=M3?|gxfUBMPI /v IV^!UUm\8c(_ Gj>-(݊yf/om9HoF݊ذT +6}6pς2ڭS(>>jfۻ8% C}5`8kco) b#?}?GգPBC8F!=WRX[M ҈46!4&i!t k񝴝Q}x9Be`DcH4t]4B`1NDǍBCݜ<íTVͧ" 2Fcn6 .. M`xq:z4Y"Rr:еL.p`&1RrY46-M@f"njGMN"牛H w^ jpnQ Fd ˕A]M.%MZ):|G.!dW?VxgG+Jgqd,o| RkH'{ogc\ {YI>~!N!MO.XVGZ¼H/-`<79[[OƣI1NbǙ<.%hi0:xXJ5KrZyՅ8ti//nXC#!<#7?/w_>ˁ5%ӦT0mjJqLk0)N|x /7F?Y]co x^{l9߻+4D3> ?:K0{Squ4sSY.%7^4@9O!#<$cK&RZXo)DGw_>=}9/t';Na%LrR}dQ=;Oz{7+&;5CvF 6]I+!r nP dfeH/ ?7 )%9dz'Nvʔm DCUA&LϞ5R9z˚:^^_>JB4h?6NW1o11\v HVj cHZrs\`?DO<&^!}t;H{^9u cw84c6ɟ}9==KH3(WŭKgחа2N8ެ7/!4@IF2k(\K, d,b_dQfٷٲ`9߼k-z VZĺR7vΜib/`<@b-vys Q>)GC,XJ*1͙0&;8j%15ّ| c+e=`b|"pi㵟&_{j=iYeTx6w:Cj Isc56]Ϧ4Å%%i9H:V㲹)j9+G3XJ\Y |ONNer:qSMQIHGc#4Fxd'b|iegp6FDhlet|2ɭ]Gߙ=[o9H]p9nmJc2,4,JGtyq9`aQ.R>l2$-g+'xlQuũ"5r9±號"3E`YPP7>vepxө_P6X,F`b\;t ~ͷ8WbUM.0'O";_Rd*c|SG8zQh?]/{kq,6oVftN?^R MSHKI'? Fށ~¾x򐛞xGp%r\fi)2M&lÉ,>}_>/#gFKs;s//*?C{4'lz7uLf,7ftS'kQ^mW;q,d^38xמXKà{lo  ĸQt8agO>]J!b}w˕NuI0/Kv9Lwer7b#}t+IsO^r{4]S3bNdR²wqkﮟ@O 'bJAp֮ +6|U_lPc'g!suαx́~^w WScv>guilܼ7 +G^GxM8!i[ZWr`/zO(C\8sy!ga]ǟ:MRB"]@v8_˔-Y1ÿ":Ј/Gz )-L8F$z˙x1bFYv 1bLC&^dp71%nMoW,iv>;<^*V&W_jBgaq^(bmy Ah ?|1Ξ'xh~^Bbs24K?܌4LDRQ@qM_Z R.␱Qz"8Sn,eS "^ǁۮ_`OmUE0D G-aW{ ٳ$0AƆ^9&w{3)̵h`tCogʮ;]U 96cneɊmigl3y>{<ײ-+Zؑ9s*r:g?LRzA?UN{^E|ai%TcŒj.OxLiܫۜׄ"tP|;s ' ΅lj8Vaԫ9OQnl*]5r Bă4O&N01I%kWb}v:1<緰C28@dd/Cl^/~U>{񳧛YQ*=m+paXkyF~o|l۲ y~=2c?gZKhE=˯~2%)qIĂtv{f mH o  "+-(|MwbS0#|#q)-Qd qhϓmۯ;P^yI.EriXT4w2/ {`[q޴-ύǼڒg)S]KPFhd<Y&J^n~SVv7E6W~WXUMB~GhXn[KO~{n_IGä&mLq@QӼJ;[c)uu0#9SϿB`ݗC+2l%;4Ptn(y6G=(e@%iH;'z¬{ 65}sEN騚27GNXd PMnK(oب^G BB*zSk#5wZUο7/>OK,hlɆ@`:.+1 p# GshNA (rO(0};N  VTT2y8o]IAID1;jxwvRbԮAN̼œ˝,|˶r.1rYTZw0"V ߎX#O<'qx#cv߁XlFq%y.̥0cа&Bh6 |N#|[ ;o.9yӹGw%R!`X; Vl"AFCPs˱.Gp_>\ClUGfFd. pܹKxfyYf/sb05EVtaLV3^#̗,Ì9_BsgR!SPB~^TװMt+pOB@%V3>v<'eUxQe&AX+.#ϭV-Ip^,BCױxJYS 1NK;6RhGdyǐg&})JgO0|$~\ n >*}W^sq^`DFhc OIΜJv6 30.b}tyFkv./i;x!~qS<;x#we]GSz?&oC7/9Fj+7BJ]|?H_@\tG΍񡏲$ߒ^͢pp-KJzH0qJ = Ɋzp[[y.1B|wvkc4"~%L3;&:Paͬ.Lw&&DF˹K@sl jOzg2s{ 2xup"Våނ${98HZny- v'9n7r6[ۦ͉Yjصu)3MϤs4(/*c$R}"aTӁa͊fN"3( ie~+ $ N +}NÎY> Hf"(/׷2뺞흗[;ヌS"HL=:b }A"m|Y.PM؜. JiMUZ$ 2'&U.NӁͤg"BlnDbNf>ȸLj@ Mǰ[-HP 4"Aڣ2퉙5K (p"<&1{C7Z.wyp m,YYA|d&w=0:8D T 6a"@S/7w(wFdb4  cȌ02]Ʀ+vWe6rkHA'q)bmKPQsw|v,ۑZO_L̥0M^Vtšzjt kQ (!\<|ܷ{GIDAT.990H Dbtfb )W!21Ӎ$*pZ,MQc4U 2zUӕ"wrsE+XYh)|!%F2Az*RQR(DF;5+_sm9\eʘ#8$޺m9h;sAUET"FҸdHPr*5d>N)./ǛTx]\Y$ +z78ӜD̟Iб a5 #yM NBb):zG1fHHR]dr z>P p,j~HSWՃIt)vo?JPP$XCzA1 yyx.z{H&%4LCA~N5&4WS^1`JA['(Pͻ6\_ eɒm@" =x,]l1]963Pv,./<ϵscI唳e×ҧ(#aڌì N03<\w(%B53t=,ɲ-,ݵbU&Rmpܻ>Fem~S}N<:EgK?L楾< ۬>NbGNa"BVAz6NƑuL%'4 'H$ ];qINUWRS6[Wr)=dz&kR>·C?~KLc$I?g=&3F"F$ 2^7I"\w[-/9pPD+uY\d2HI34Ks9|usk.|/pT#e(bf7Jo3$ɴ}$JJ7x985AJO2ȅ"Н%DD"A,H KHI$RH)I%$qb=,R^:̩ƣv<#=yin*+k)Z?dy'QTt"ѣ3Luؼd"F2Lo|(PqK59oDD(F2!EIo~* * ( 0O}(!HM'gBbˏ>Cn>|6M5@$4ɮq)Xp֞[wkccSyB7ދ #Ɗ$1vlBԣ\>,?x0C#ze<?/9= ?ƥP[VWΛ*d_/O 325sD^pk|(D3[B2fl.{ήf"׳$cC_D6zƂMw2[k0$l*`UR4x҄ 2kwA]3rfy ΝV:zzln(CC"FAE e:.=%Vm4NaQQzZ'225EoW-m\ʤ)mאhQ9ѡvZ:Qظ.VTxRzc:qiU(Qౣq.8 1KwB@x#1L34K3߷C)_VO/~5չ&z:h%hgy]cOr &di`c]! {n9 v9agiRgNpyZr =FhŹ 7qau汴pRSt _ ֭%h̙sh졳qF[>{C-d:7Z!ho34w#<޽ ~,Y53tBqz:9wO-M?JT*TPK:ʜ):._f`:A~E-KKp9=,^\rSeuYݎäu3i%3pRd2SZ Attu;b]se%rε‘術8 +XTꤳgƑ\jWSXTNC] MXT`Μog<Śwnqs͒%C3cRt.eyƺ&qnd1?"g*sL8 BV|Hd2nY5 Β*J d&\3ajXL&0R1qqe\ʼgT C̸8yu$"ϊ+:PT%:n (TAf<=? TLq@R (t_DMU2cj~TMC7f4>rrY{A8m8Zrj3NJ*ȯ%'׹+43E~ZRa*:=ہRr)J=#t%q,g|Fgr#+0N'0@su 5dWwmg8'x^\BZFI {Mلb(6/NZBQx=Br|{N ]shjiD ~|9WkFʉ)L&r }k~)@xJG3Yh`QUKѮHf̍xbYeϷ`(l'z=9|H)p.b׽5̂:1 ||֥S9(!-&ͿPTL|u!QprwiyA#P5SƝH H; I":DdAYVuu弯W?Y~3j\[xf2-hg K,"\7y7Wtw {>g _y泫kq?\5.dɒE(*,Jj^EwU ":k\tP*P2}D(r;*WjS3>pTBiMrm6*\ Qdz6yvS1ed>ff㴢eX{}*W217J_,joJa.I-)T΍&y#l~$+!JsIPQ0MؔGY7WGST2-ĐzBNOdɒ%K,Y>H5Hۘ# L.f^נh}9IB(R1H$q"eM;]W=-ZԓLONcŚmLD@UAO0K' RL0<2櫠2Ntf ?@fp )A27oFIp=#;|7 סe8dɒ%K,Y>HLg=Ei _ӷFŘ6H6*SiưWR䱣8"$2={-L% fp%ˋ2Wb/1 G ? 8r)]b9ȱim(j,Ydɒ%K,YC4qe7gJ$*/>2 Jd}tӓt .kZWHѰZ-B XW B((B EZK跖-X_n8"L' fW\/2NQ,Ydɒ%K,Y| $%Q&ٰ׳̉Ȭ I㤰3p\]1+$sm9^D^S,8ύ>U{xk>@lEnۛRɒ%K,Ydɒ%K,YɸtrX͜$bdlP: #!VFC:)F L%fJM[dd&;y^ 3]I0iSPXE9 f2~[tiw=鴢v%K,Ydɒިcy?c1)3L>̳Ib!QDJiI^x7#h4H4 jNg@U‘0јUn)'aSI?Lpj6`$w<r+e-U̳ue7sw~@ɣY(13 $!.^@WQmVbFV]E( ^R F;&[yJٺ}k2gfNx{f Lw?rzгp,YP1K jj1ۚF(JfjyHϬ kLid(09褙kQR3E@2L_o:UyE!:k|@ 1yAzM~' 7nvy a4F?Fo2A*$`qx,ght899nS'kp0@P36f~u| PB}OfsDs2,2s[ ayή2J7g!@O014d LJ)Aonbޤ`/#!L6r co"'HDE3cj LVRYEz$3{hm!9-̪B @y ?l~8B@<4@afBUMP\ݢ5}dɈ˭ NPmn*jPUVY~Dc&4̈́ۗOqa>PQ?ͭ d꽼ꂜlgɒZ 6͐ ')-•As|㚵ݕ]kF`&_!9ŹPP`z`e8\yG{)+lN.?d넘9JIA1PnQ,@%h8YR} z$zV-G.f߉L72appp W^ b$#Drݖ[l ^n⠨Š5HvOܹ8(d Hgn)K}%s0/ginz}1i_PQC~1b$!>Dhvk"p+ [k0 *"F2BǙ<8|u/Hؿq:B}4O@yE vӭu7V*2Eө? ļbU 8ׇmaP8{l/-Eo\/(~nS GxٗM.˄zב}[|חVWQsI&[>ڦ87R\rW/Mq} $nx+KɽPn!Sc&& IÈi9ST2I'82_җ*f:zϒ%U1Ocmf2h$*,fL<=/1ƴ{P 6=LjX]0(]L; kp8!v1z՟BlsW$+!WǾxɄf!-posDH F,[xF4=H*+$<[|a'Jz`/y|c8S5"a{9s?5P >Ém` 10U>;+<%y,YKnŇ^S˪x'?k_Kl͝v^dBQ0)*70bLb8n,#%͔/_˶ 7~(Uu(G 9nfJ*mg]wģAw#'GSɳJTU#3qŦ,X- @&1B/G8!ԧs"V 0βJj'IQ`} E f%qzNSR@mQJ}f@μ(?~3ܽvN)!n,)ފ2K]} . -d=K, *Ktz,I;ekG5 d"FF;`LzlRR"5=HS)>M/X$}!vA,=U8;8x*K)t =K3%ֱazLbOo.Xwbu^,w|uD]NtV-f ۼYޏ(dǺl_@2f\Rgr gZTB;25^SbQ}[5MJȋ$g9-3,WQ0'O42c1j&O*B i*ˆ}{ۉjdZbºM.$FNuO?`)t]ݶTU) )P5 MUҮqi3&MiJTmat=Dy3 BP))29{/rX]fC&ޫYUP3aHTMԒ:3#V$BU2hS$SikUH Gݛj1 0Bbڱ/987|l-A5BT;RSؾp3\:zg%y&tVa78uj? 5ys|x;73\p7-4G&E$C#(bX#LZjYQea5Il*;ɡ3ܳau3<}[3޴G~z>ُR3ŦS,V8z,T9wD;﹓*sK9|4?GgPuPN|YJ3NtuwoX)K;*aY+/LCKlf{9i^GdIf K6lfy7T.qbja~h'5:NO2~NyY!޸xn$T?Olly7;VWbQ 3'gYg~/tQ^8]<3Q{p3FvXRSE2g/`X=WsE%゚k02iB?AꍛXr[ms[*Mh2ٯ;hfz29k;'4wM!Pd^ j\#~.dHřN`|8TɾVN;mru:c z,}SQ:IC~k0+=faqE(}g9OqR.^l%hcE;[YˑRb+b= x`7%cp>Ec#(($&8cOi kQ$Inƅ݉ctժkY _I)b'1?w| 6RWTN.mh4a 4>EBAc)oaJo鳛s2IoEV.88eY<%,ƗMeUn0zm ڋUKy%T& /K08*X@A"_Q NY]xݒ*7o͎j$ȓ?yW_sB  06<98L^RV_)U*CqʉnWm+J$ j*KƗ|1_+=!R QP*z"I @gs(KfmN2Yo,*iTӍM."kzBRR#0dT7O PLDtgi]gjll}E6osmG^%KkԮ糿G|ȷ) `HIp-}?[jܴy-AoEm@XtZʬ1kv֯, < ԇ)]8 &$5k!S/WBj_=OD bCSO=O?Ex}[H:Jٺk7KcO6,gb󇟺<02|r w1G=D 63Gx2=Hѩ%6s UQPa>,g, 6͞MĬElڶT?w89e{1UczbM/ұ\ܶ{laxpشa Z' hSj37VҴCly;G,]:Hzdz.XLt|]"H{ ?*/^Ý%Ҵ=HH+2r62_~h;^}g~53W !PaƧH +^(LWϐS >N{T! ‘K$E,k`_%P8/4QvCl2Ᵽdq`ݶ)_24DB1&~̟PLXlh"2Nm8NaаN@حfLq;^vcې Imq9*2'Ss!u^u{յR TLAٓ $ܽt1͠%ZIJz-BŔx^͂jL{E`$GhrU VXmJʋ]xmO$nز6_z=3[%Rm\lƾ6D;mAԺ59|4]S`rcZ%Wb >JJC]r7UY^E1ÇŠĎnC3Gp{xfRG\;ԜbBS{XREJf6R:,iXN"7FU{\.rb19szp;Dr E5ZVY9t[rWQpUW(tGBtpCyVJUYZ.X{0 VRW Qdfspа|)cڱ`"@W9GT "L5&wVkg5,u e.ێaBx6+& ׋Ǣ"c6J*kY/j(Td2?EM#yPFMU9)})֗ ǑEK))e;7t72h!^ʒTy}ܾӸV2Һ OKp dJk"n_s/3UyiIūdg`"H|6LHF5v~x'dUTCSH{`if ^U:kka#9kYr-]4-CEfJ]ax,\]UqeX}mr{Bz˧NcZ:&F3+HDEAq=E\B7ov#:ɩxWKyzmNH2>؋)|;kXT[wNTYbH~Q'I!-bySDyr/deU,^MIU.]J`bM}t͠u )(_9qLƊ\@I!(El40ұ ]7Fv -) ^ڨc$HN>lƬu}^*B!?SxGő,]ZٙKW6tU[%u˩g`6!9mWq9$i'#O11ΪVlƓ_{>y*Hl 7 MEUԌǘd!#btpTdi2BjUn.l^l4ee+M&%좮ˡ>Z{/[k2Ӻ)Y#짷@ qE[BjoJnSHbq{ *vUa,?y+/32SݰAgfo9W,wQ$KB1(.OR~_c8|)IΟ"bmv241/iO6XҚo43|0R7VcQ҃9TgTx8y%2нX=N,.'Jhx|DlT6pzWƶ XQ`Ɛd;G/LѰk;nV'R$ShXa]W{ĥrg-00P|F\QI))Ί1W/W75lJY0\>"GU6YDUcN@؋v[ 'xj73oayuPHBThoHf-@\DEGBKsgs(S ZNg +;4W:"ǗΞ<ݚ7_^&޲$-4ȋ/L*9.3BJA^ UFlK]T)Aׯ+7hf&eǖBycB0'luͰCZYeԾWiXR>{U$.j}T\Cǃɔ,kې R'0PLN3- A{n[S躞 tE5^787LDc#2_xQ)^wEqITȴdQ eydMc |fbR(~5Gfsa̭*7yP(]]D..HHTUE:yh?w.ŖSĺU+{q}8c vq`4 &B ExyD?\/^[8~}q*V83B!0hK} H:sF77'],$:D'MUF< mEJUTZ:Ol 㣃t0H&#b4&;J}rB`6[Ca F:A$`vY8^yKS %E>H%F#L$ ШZh3\RSCνDG&JĜs:.2׺d=\atֶNcȴcƱ J"f?M(&H^%U"f&d$34{'^?͇VZ ټm1Cgod.Z;t3HEEB_lûn+k}BC 0PF$%]m*Eܹp)z( G9&8PP(.%V0|5zTL2$bPdm bֺ"cH[n9W, ľ 3FG8)9QA\ f̈́d2&LrȯOʅÖ4s9/$z'HJD9^:xx֓{y0E4d,4D+CJI23P\RX IECSәho@Ss$aTM%11šiI^=lȃ $ R+")3 lE?r_ uW=x!F1x#! 0$Xix*)ӞK↞!:wqރ?y c{Nbh&*L57⋏ܞWi Z(+"t$ c&zϒ]Ag񃪀Lܰ:3;W15dGg d#/Ǟ d%\ T[  vQU?48q̾2J658w@0Hwi#n gj66@!51L@dJTY^!0!{:T$ VRKk}F9q9Mkp63G9t]!t i \Xxz<UӅjFqڎqy.&iomL.6ja6,S=\Ch6X_UV2x"} Xg Eۍfn~`;n]4NU$mgri_'NR~'[ω,@Ph)5y}tvMWg݃S.ƇwNkVJ&F8q[ *(.bNh?w 栠ȇ%3&:o..o<#:ׯ0Rt [Vcb^ $^E/m+NӈW9C "0=F{%]DkGzn9M 0߇uNW s~_!\r}> 0g϶6T\N#yTa3XV}hغ"y0/HTȊ 0G^˹>?T;|W!(siXҲr)ZNTs`"7##2eKkjaϡXKXR]=LBe{kXL[I1~{98E8b|Ks΁oZ*R#Gr3'N5L8SRAA*4A f 2iέXJbb/2Iau(:B=~L>nMK 1aT+IzTRVBń˖cuwIǜi#; .ORR^CmEx 'uK0ïpjTPQQ Mi1G9w]RXDz<}Qʗ.,σu(; l܀QANa+0MWW'ݽt9ŷ˪1'g<{8V?h@`i^;tɈ"r=._JF95_d&!D#t<-c *pFhfrlֶn|M*n.]l%(,m*S}Wyf.TQ_SHl/I(YFe3T@.dEC5rn;;>LEiXKLFtn'QR.Uz<'ॢ~UJv9/.t0 MD|,wW/cQƇhS54 =\B3noYHE֓{{*K4nPVlg%og%]mLv"A^.z;|CG?p}x6@y38}>Nۏ?dx:X)&;L3=4w.JjQ1yl}-SYOׁc B}DEջ7㴫`vwhm&0g{mՠo4[ L]Z\[(uAѸE&6qך'Fb6Ԓ_PK]4lgj,b >33]nʒbC^+δt}Mkm=X{^>i:VW{ )~Zz{(ši(q+*DNt?P~;PTAB8g 6]Ejb?pe.k h봨 !%-I~քKk:G.!yTTSQUEuYf^Exxɩ#NjeGs{BLN '$n_^-Ǚ'r8 &Xc3s&|,*A?I0D5;`m  Kh+_.nE ,vD Boۃϛ91[?AP "SDc1"фiX9x6L' Mj#ab|@4*._ m^MFO&k'<5ERsu*%hXȝz:q&g"\,2ᤁ[@^0R_j=pCύNhz f `rlqy>̊NpjPۇ/ǹY;DӌON4n6r>rd*ӑf<ăM79v?9N nBdO+ ]@*δP  UU]xNLHƘ'ED RI&a ae&FUOF OEUQ$OR,2= R1&'Sdb5J22d!m!05aPc&RX cSDBNn>yn[vS:: PSXݹ8-jz"?9E$BR :N)1)x)OzrMG@Zc@7$BI^+6s}f5fMkIRvV eG2YtĜ6q>58/oF3UZsa6cif5=1^XS/󾇛5tYRǺ8ynU;[#~Y!= 1`~ֽPg*:(o1]ݔhL%WeH{ŕG~K;1)_ϐ+h;qI{%*QQ7\~]?f=/|޹v1{uݘ-;uͼ6z:nPBfrћ\]\?\OJ\ܰor;e~;Pɫ~ջ:}l{,ڂz`SRdԫ󑆱` bB(siP Jfc}mXc>@0S3sW{xK-,_V6;om7mK*2L4Y-kg榥d#oGB @Q5 7`,u/]Pn>nz - k&ozp?WRgf|-xM kY^AϵW{7@zk{wTQ*#^eѯgg"tu>46w׫k ^i=ڶUFo|yrK7qd(B^ޯ.y]/z1z}[{,}b<׬~י;IJ_Y)1tpL47ÄApjK~9%Ř{܉7^۴Hx}[{ Y>xG2?*FL7-eKˈj#x$%&ʖK@4%^WCS}=L LaPN4U;O7nWbjr5ZƓ [͒%-h=Cϱ L`fWM[[3FV!3[3b-i%%$ƱTfsf tI:A`\I iB)I˨c3ngz~jDҪc^G%u0-gNs&DSw-E8D% ̢ek(:[S bMMc+i`ZlSovY~-N[^9U-u]0b=I@`lZ;XU@xcqT-M8`/SqF@Z]rT)ut]bn~IbpX3)#{.rl#]>$Y< Ѓ|<~:½I.+Ţ q+~?ӻa7 D MӸ^#<đsmvq';>ş}*L'O[?*iy|?~M.SA]<8ykD$.\KȝwiI)icRCjTج,Hh*Õz*ܘTuU;sk [~%f#cE6,Y"BAl-:EK j&OU=IxgdpXe՟5vOSbC^x"/X%.>y=wIlYswA}OѕǦ/?56C _~ ZNē1Ks,-yX'˖:qSߢyڄIh$X+7_*kce~ٽS_>FNٟ܉4@3r8Op wpz&#ܱ}C_eZlxly]A4s'?d[dwƏ~ߣ‘ҁgx岋/ȋ06b-/QO $LN*cÌP0i*}smaPL_JLrGƧ6;hm>?&1X(AW/S>n_QY݌L|?;|W|FsEQPUUUDvgFRI>|DDUin~Ү!Q,nV|ܾݍ(zm\`]ݨN )(:x֩8UЮE\:~[ YY_*u{1wvi&.;otǟ?xĸ=v^;N?i*5;"s+ϼ~+S.l̕\6]{ShEB!:|GS&=,-/ S3CauQPSLH!`|'}ܷ}9NSzs<2=J2wv? Ů1.<^;3qc-$#o2&yٺc;mɴeJ!0D&\"J 8BgԕΉfEUv q%g?KF  N#2׵ygjtTaΥ~j|֫★@Ƨ9qh/E|eum) )-/6~<&Idz6GI<,_e}4d<ު5| xʜq)cͺxauH^1L !L\NtOFi7H͸0q,k_[\fJy;q @@2⧹/ jٱuE.R cw?IRיLPʹ ͝iԈݷS v]f"*vڀ;1k{^eZan_G{k8Bޒ|h L^^y0z>|&\4quغc}4Fxs)C.TT._1ϝR4Mxp WH7z)uf;|5kqY$K,W!=c2͏NMW4XTXҶ3fIaƞL횇Z--&63y)`)!8H{Zf%'z2XTE(?=jk[DŽË'?S }q>sv~E`wjzlۖoG لPRP&&^6lXM $8|E1y%~nB=FCiZ:!6ںOq:w԰ زy)/]>B rPHMq08KU#t1U#ŦyPD EX(]c3^pJz E繑R`s(56d )B x.8xyk5hP8FJAPS{IM`+,ĮDBA"$\x[\{k[:<=V&:=M8JNI1̥ ln#^߾c.OIR~s1l\⣿gb.w6Ut66~ͯO2dᰙ-Z ˫qU$ǣ4_8hTéygw^BKC$M\î5LO0L5hp ANzJW  29o$4=E?ͤ4ah Do]rd -Ep`$#LED.&ɫN>Ilf?: *S=L# MHft`BgzlQ$-P1L]Gڂ-Gd"@ǥnjc/;fe)RēnpêANJ<&9+|^>/;V(.,d _REN(.NYQh HmEŪP#qXBP+X{JIT([\*b}]T Bq 6nULt  L<;hشm['~ۗ ζK`+;/3VYz+֖|vKV0Op @^VckX()m<_۪dN\Oؠˆ315wrEDfڙ C*:C{[#- DY}%lٺw|c"ٳZӜE8r*'>1L[ҥ~א0 pV8H86ib\+0Y]};n#w,+BC8\rʫjٰq-juCSz9Eq|+jqBQ KV]wN8b#7N)Մʧ09LJAq^ǎ5$Ǒ\{݅wT x" z"HP!SLOp-b۸՘TF. {vo"׊4 r6ns1Bs~ϒ% &?Uიp'g^9tSD:ּbHSɹgjǓK= tHGO0t#5_PAkDѓdHO_'[Go™~R*^(ɮ\aJ$BSz3wm_yL qC@t#{pVO\=O{ya tE#ڭ]mNR7zca0H⤒)6?,D51$z bA0${q頻izzr 0@`ɒeym_7^^ۻ^9Ȳr$%QH1 r &9T{3 ˧INwթ|#1"IR`q&^eAe:8ItxrxlBaY,6|9<4ca T ZroǭzМ,o}s'yp<|QPR>P0f(#%8))/ǖn^?VT  /4'tŰnn&$h=%1;!Ka |+tC{A\&B,vr<\ ͂eX2>k%^9:G޽D Vq׺:.\`s: ӇK%I>n[ƽ-#% JbpXCERT\LYY ~ŦJ 2QZVJq^&YG"$ @K mW<ͭFVn.o.-њ"aȅe3$ #:d.V,g3H93LJXx[ݛc[ _`ISRTD l* &cQŸyU"/]T^Xظ Wz1wn{5u q9sVdGq_g6w^xM)'aA^LXD*;K*(lu`Bf\9'c(|XAd#jo~ VV-A~\tT[}59yll ]3Y_=Q)&.["ora?Si&j }L^v>K:-188L8Y*FěKdž+bYDOߜu|pj 0uG]A,b`p`$Il}A˒Mˈ s8PBL+Xei?z鄁i.YJ}Li2ŀa$b<*(,-mU{2TF&u OYpDMcztp]J$x̚02 ):XEa44H%Ē{9g' 0$월)aS O1ǟ$It njơ[棡o]ډ$DS qp.FM|S椸]n$eSUOj;2Z0o~ۅw3;;sW_}/>ӇGhZڊ\19q,ŭRgz#_=5Q[fE:{_~޵Qibtz߼Qu* j:FCX, C]wSUMWxig5+QWKb^|#S^6gr.LJE Sn3]g6RU($dkD7c ̐W^5ϠʊZr,{EsPF?] b|۶1糦qlUd[=[BptkE5OvSәaيZRt~_qš6]B8(x|6zNt`ƒkq t0XgY}^  n\BIzf#v1+qxU^{% ),[R(oAt i$o? U T{?{_?#R| ۶b4F F:;MS][A~Í􄗻<1>u~+3Gر͎v"r~kL9JXPԵRj& 3=5vmԘʪwhJ<8Ω3$lT9NT~2!=GVĥ0rzܺM%XMdLO! 㽣ăiPZD B} ý!mxhp?Ԏpva"VJpTlfl`1XGz,"BN_~SVȩ;Tufp9ʌ(鶵8v"BOprL饻wCaͭwVA n5F>rK+ t/[%K+`(`g8qT ͸lNt8F":ā픬ۖ7_xh]ʫ⳿a{+>ǟ2]uxNpj8˚ؾ-͋JP5;70.~{h)rpZrx<ɪ}<fEWq]i ƃ$4A*'19>T8MEHT +I&Ƙ Lj؝N=03I׋fnU'"Ɛ;.1&&gH:c{pY 'ƘDcIl'VD"Ţp8.u)౿˿SCosdjz |Uly9|TEKid:#6dϥs啳tYU<? KV/)4EuPRUIQk @Q  ՔR\\DqI.ci}9v&|P05MTG3L&]44Pﲡ4SRG@jh)$($DSUY'?jR\IC^i6<¢R \AY}E Ori(r4A٢ i)AIIQZMAN@EI]+KZx]U|2J}6"qj%rs\:;/bFJ4)]PҸ-k{ݔUQw-(gź,,!bS!457"ߥ (b6UP\BDXݔL Zښ)xCӄT7esWLuubt@i#e"b3jK),("?Oy} PtE,iC#85"?>"<eٰz XA Jll؋euhǦ$yeThY5K , S[UDQa9.:&$FV/_D 8$HNKlٴ'ep Yz=+ RY^m0=5a/` mħ' 㣪<36<SS3 +.*8Y]F*V%EXEp73*zI9+q=Axp*& ׉#/MT\J$apPyZ9|4M8m)8fj.®B^P@n" JKpah&*Fv3!MkלbqPTRN1T-ec?LT/U %>L IDATsoB œxZٲi)~{&+"3AbIAij6-îJBcCDy4VAK+Xtx>JkXӂjR܈OĘ-g:J6,2pni&V2rEQPSJ=E"i`:mH#C~A~Y]vbX]spXTT]Xq9XmL\>׃fjsfs[Q݉n˔qbXڝspڮl3P+G$Ω ~|]xpi=cjrpRt{(mELP\ˌMK%zQr^D`* }ܣa0[}1Yقz=v{("SzK浑R l^{-K1]nz&Ȃv϶B y퓉Xd )a?2m±_}Eyn EAAbs@ + y-#2cAsuFL `n!j֤P{ss\0:wF%;e.:3b~}3G.66U;nv5111Y@v.Jwؠ/F!kYgSy|"unwoqnʮΝd]v]oLY2O^p-zW{A#]utMb^:hC7;4r2Edq3+^V͖`v޵tx(5= ~x26\`vtl M\d^ZHb]Uc6'%. !)F Ӱ' .BJraWPx2.}]Y/UO? 6%KbK{:}+/.Klɥ΅#/ۏ3 \82y_?y /|Eywy}V^n^qhbb!$;)TyB(<ު]ʏ]y"/av{11}@1M" H9hZڈSdjos-1111111111111AՊ\HF#WTHi&ɍb,@s޸0 I,@I_G6111111e.{ü> #w$f6Kʇ yiLBAU8.[HD='bMLL>d*J")8HUjbrGI$.+j\{a iY9r82FdS2 .Fƞu5 k=[v޹nȹؙGVT |dM-|EQ.&&&2.;R(z8ur S ކV>U(=lv ^abEQۓ|Jy%Yc3ÙfSv[W" y` BG#aEQ$c=g췳&[qϝ2ȌXhBQHdb2C@ɩ)b{ nt8kR4Hu!IDCD)ˁr 3$JFQ\5le ^⅀TAt&ʣhb<>E83&8+)n*GS2)Ə'8P.!$\~L vqhhʚ6$CAiBqZ JB' KX.NE7ӱ =gOs/BuRsBBDXn|'%[ɳLŒX%,[JKCJF8=D4 &6gnwPolPM:5U+GL3qc"|7T%R&>v!N4f6ny~ t~~^7WxIL[-ش&$87wqoݳMKcGgɿeVVxg/m;y3lA`$'xj2Dl~Wh*%8|%4V{'XcD5$-c [RNhvUss䃍@F|R~/e "9BQEeCqPߣiU1ȡcv?!/DMz.Nq*Lʉa?~7#w<%WW3?KFRʹ޻Opߎ/QX4-Hn`8S/W%T'i't^ƑQbNA(jkﱲ9{d*ĩ3=$q Zʰfd7< S:ܼ"Hwjvȉ3,Opj, !扟ohlZ*~;ʧc5?*6Iyx} Ly 3՜$'P6>OlG?GC(BkUԊl| kjԣqf&AmSUQn[X-ЦγSPUUPB͟UUU>B$#tw׸O|R/eaT#gxyYj/qZJD8tBqyL#F28hCsRRZ۪bIG&n,Hi++^1;L;@EyvM`|x`$FJZ)()!Y\ %;gjÉzn"0M0 HJ| i&:99&S^Hfw@[ Q\ZA}U1:j!**5Ƭe*6t (#ah<,2Hi:/bőeVE4=ԆnHOmky-H)qTVTDڂ+xnN&R*5V`/&'gSԴήG$>E(:R:Epb Dfr8DSKLj݆v7y!da7Xlx0 V&;"`?OYj5~8' Hٿg-xA?W:qKJ!{1h{דP0_58mB#Ǝs}Mis{_ >]XKC@M?2gB/JQXOt)1yF, @Q5<<(2E,#H@ Is)QZz /}ǾwuGL}/k3~Q<+Ny1-8-~ӟskٽ Q>ܛ ̔E(*V4tt TCIi#Eprġ)Dj6r|XF,8\.TvAEP3u"I_v=ZJJH$HGFu`2;(E/~ Å|x'pǭm0=GmnұI8HHa'FױCOQ5yvOBJpFxΦ~EIkmXS;HY[Cdj&sv"~j*KMLLiNHĂڽsjIjfﱬD}KgM!Bp赗8rPS쳚&&&FZ)ʙ'}Ô,Z-`)Qv@i>qɈڢ1TS'I.h $a<4Pm.l9MauNJ3Vl?` `#[\XlV́灣fFQ1Jiݯ?ɦ>Hyvb9gKླ =M4aƈ VŚdl:Ayt bAAh6l(@U5ܾ sm?ad2IWhiSL-8V)\9I&fbHr/[795*G$8GڛXT V`=xi˫ z V#Hl_?s?|ⳟ5u0Ë f4z* ˚x,q&5.p K}m[p\2lvSF̓ Z)A ;Xz9QW=ܶe=yzm'#VCh]0~v?Of'-;5iHGIR궛w !v<{Otܽ -k%g%@M #FG )&J[Zeuk׏:@~e3%.&g> ;)4D9~z&K43IX^Td^X%>y 'AMLL.w)_*Gy)vOLG(o,@`DF8ҁwɽJ6cN1vhm'* 4)М#EЬRh&mH##- 5 &&k낊@&dAS{~C>B|\욗5I!>z',{0D8,_ƣOY]OzzA@'QF|~6Xq}ܵ۬Lg w.TTL&z6{h6KE "YIhV;6gH4ywx"$ UUWsS*)I CP.Eoc08HE8p~ԮKX7G?}}{cG QRpĤPE.\NFejn^=d|#nv9Ξ31nٱdnExĜ[ <} /4a\RbX]4O^ĥeL%f|{Oů~|gFcPxTeˢ7yqFb98ޥcw5# yie㓤Ry\Xz]XISVU7ux*5q>~fj|G/XG>n g7n"%" CG~=GZB]Lgϧ>u>. EbIQi,(H4> \f41ML.D"]Vo\nǾ?)~ΥƼ\yKu;C<|zʬڇzG `+j68oSg#B'xl!QKk}s5e~~[ȂN$Ҙ+hN;P?)'Z4I:> ӎfGP4@(n40#78Rh6ࡏE/qx|[_}"Ra<ְ"CY|Gk.;Pj6TF86QWϗ;̏y?$?™I+$'I%wߺBFJ͆ #@ZY:hD"dCEHt[.1i]PV) ‘j4{_ST6!S=99ix_Wk u ^–ť2iz)%kGc$3 X,4MEU9MNJ5+y<ܗre#>ɡ#g]~+3,rspQ&:H-Ŀ oDw VSzBjahled)b`'OdS]iLTe3EF#I(, ϴM^2/™~G93 cjbHJbTUQCB(ʖl#6q_$QH҉(=LGh9#ٱ Λf(jSTͷm=v6ؑR"l~|| {ͷ/2]5Rf\ų7-,=h}A BAke݃͝bތL350ڰNe\B'pQL0dUct$[rqx(ѰҤ")_vRs##A:g֠?[DW)M<:qX/NJ4gk8͍9gjT "^\JSmU5v:8MX7GNOۨR#D6) 23F,_^Obr:adU*%9/Z2tZtQmNJGg'u@b"<&y(*ѡv>K\f0)4KNQ%^޶(B`DL3J!-5-$B?pgj xNQ}#EaNvb?lu IYA4ӣ59ɪ(:D #;`P&&H0Qb yl=6\[&6'cl:N~k#.: d4L¸hNi"z,B\q#ß~^R99l?MNF&?|y[6L",^1n*Oc}Cx ɟ>LeFTX,q)z^ !2 ȨQMdRLg^٭QC70۲"_*(/! P̈́{"111$B@b"\bY\,ݕqFݻI6RX濈UhfDhV.?|/X6-:t  P\I}%{^6;!u#(Mrijbs"&"<dzv.u#M~d:Y8))+ȗבe|}k^Ce6@iJlA3;͡\zV D&j OY @"8ȁ')\y3kP$Oct9X(,ZWX'CSI"HL 3̣ܜ2!aFꊼȘ2ea\-Weg# 93̫geCLM9 h^ w}{WU0`D6VveỸ?_cn*&Sh%N+Acgmc]|o%nm<]mԴ2ֹi$IP-[yf]oz.[ַ`WAF")\ SrxwmolY)f$:d)niN8oj9y}AVŚܳ_1_fy$:r#:D^=i|7 Ï[ߺ$.XǰF$uUD_cqR%U/MYmTy߈lA4aa8;$ IPY?Q|?ϰh/oFYTD*yMvA8!NN xh4J(&q6|9<}c'<cpY\t*N0$5>BOA^&jӭܹH FqtFFS6 DbI">vm`K/e0'SK#A@QF%e1R3&𬿅/BJ<Kj%l Յit3x6PTA 58ỈPBf7rX)fƞPW+=aJ7ߎ!PKQo2p7IZ1իFCTàKZ ef2t:Ʀ7Q7?c|>8' {Ϟd靏pj4@^橝CO!/N^y0GZX'9tśY^!6?1{lL8K0{|O_@[ilC%g"zUxdM[8At,fY^Ӭn-r\ 0is 9???؜\7XPycO;Id||iҁZ6Ǟq~I٪;gCs(/vI_) 2<2l1o^EKNEC +CCu;5-mԕS{kajlU7oܷ`SMv+ II88 BVj릸\9EdW"dFk7G:H*N$AUtOe\)cêF1=$40283'طwdžS/j$ya(jLN09=Cꧡ&cğoarxɔU7m4+{j r/j$ס{ghn7eUx)=I(_UrYgVnƖFrqǐ|ZR07:H3qcc\.7%8-* J=048،AIm#,*6K$'z9p/,#t `)('Gb4%]˔ɇ! &9tDžada4UrSGB6P UHPjk$ǘ!P|f J}\wXl*OrI$oK3uY\]pb=,nkAp^eqs[9>[ZKeϜhKQ+o^MS0xbLON0>>DOa5+R u)84?Kg06$P0|z)hYM˫e͑4 S/X4(W*< ?T"b(h1L$PUqCN_0?SA?b%%_.o&(H8s$CAll"ߋ[kfZ̿5=fa)IvC>**F6HZmw.@sL.rs$ vG&y=!25,.jqv|_A/~Rzy!/W˂jF#7ȴq-ms611yKDv̘z= X UDC8Xw]$zo%eXqS^ͪ,.>EJp6&tw(].ڀ1G(v;VB+ȩ鍳b]C3N M8.ڇvX]✴%'/U׫>/ 0<ޓ덖 ?>1jͤʾFqf"‚ F}+}gF89HNY#yp Bجrs/ # B2ҚVj. W`jsae[/ /8m΅yϻ(KٱS[BUܑXW_oyZ>y;*mkb0Ca6S M_PmnԋP[A5E $ҐHøHHoMV&7P(n_8(ݮKIdl)9,X[Wq!&\X%{PҺ%ۧЭFQۭDڙSTlE./V~w< ۂݏG*%Th2EZ7^w NJ$Iڒ|́osi`f0}boC '%x6@XFJĆͪbٱY-W!T9~{6{xg|פF{$tr;`<*BHf89D02M1?LLLLLLLL>tH۵nVps: 7lE\Qv9.ciDDZ?\I:$mˌc:n$qbDv=Vs Mx#OM3O} aa g~gDlV|/0ʐ?oˊB?)F&f@p䑟E) M)g! 148D(m%7F"&*iy.V!.!4 roĬ[.kV+H'* ݍQ! BY!G„n J lcyTF W( .@cbbbbbbbbbbbbbr!0"}N(wg>8S4%>,DJwn>&Jp:hj0sniN9؄b Lwkz#rzdc:R+ϥ~҄i*>ٱ&o&͟aLʾl_]j#wi 1e닔R ܽxW+Hy.5IUQ‚ di^##1f&bn-]Crc/õ+(f?W]e>_>*Ě@q>sqEԣtx N^FB@tןy>|D721y/{9&C?5ywq)[YLLLndCc GOx9Z ;\b2`L Bcl)i'{dfIpo̥ć!HE&8uhՕTy^:HHj |ŒrD;1k!mkp 3R 9pd8ttFB)|EU4VaSXD&8sn/W~d `g4v_ c6\Adz$E!1dYg3ZD'k*e8)@OD$n/M Mp53rw:6ٳʩ,_={V3D'z6vh:.T"Bc8upꢶ %K؛7x;_G~M 5.;6 !H9oo<6y77-ƪH:^I?B߆Eltzmdr!_x$ќ !P4+mh"ޛRŞ'?{%ߺ2N>-Eߓ1y"H7]SԴp|[[ vrfnn.<_sX| E/f3)y5,,aJV#&.$KM#|.K~yW\_2>qչ6 Cu1eTdJXVŮk3111j =$Tq ǏѕpԄ]&eyk+VfzgQf593[۸ccC 96j45PTVabbhiU`*eUlTP!T w.CD1fBqn+ *8Bh*&31Y!, V# 65ġ=R62qocqE!6zt%lܼ*w;_XHz+P[S͢VW":W[YhANCwP7īS(B:ӿ~o 57aٗ՛gH#zSGx7?/eIF<pjiFǣaUۉY)(SRf,[w=̃2j:WeoU so&]w=kжR fZ;x%.DxvSwo>&S@uU "Ѷh9w?p+}<.fHssՔxF  &&&}2OEշEiy.BJԉ tнEvn  ֽyqFX,cA2w!) OKZ(]w9mR )N>גՔ5Pq9nQ;*ܴKEb۳/g/gIc SK*~>JVoaV s(2WtZn^]W~.Okq¶B x1;_ $=KWy*nnh%=gaVΪ,[{ n{5&W!ޖ[MCfӘO(VESXXDII1~=Sj!EQS*hN?5 -,j%mCO~9-m4V㰨Fjb rqYbϡ}V#[XGI~_NqwEElqjZ7N+z) 04l8UMyQ<" Å"0$XTq8X5M%Mh),JVWGz9G8o!qU\obV8467|SAk*`н 尾!V9ytM$m'GFyaIb6`'%aHc6u#JYEG#D-,bVP BH#lbM! #cyb %έ?_Ɏ3ĥxY{Cܽ.ƢqO'R(vSEl!_[' ~>c!#l}({^)5xO$O,I8[x~{3|ܽ Gpq ol}q3{c{գLE}p/o?M|j?zj;1$0uO0mgߤc4IM<;q?|qN&2WR VsCn=SQwETࡻ7b}ONv^9p5 w>'Yٗ==HE0| ~6S<F):# 2o7~*+6rӒ ,d޻{y}f&)#ܺ^\[oes{%Iv-v<Bt '2g="(ڬE:h 0H:/gIDw72/>BY>Gu[?W^ɧsxyɡX#/yqYbi_H_p0}=ta >jd-#BoOEwZl_o0V\TT^_h$H8&(h:-'gpb.1L dDWXC{8ϵpMj2>ʾvCAK0oyόy噟0vv[g(j0bm7._=?_tz<[tH$m,Icu Zp|4RPr>yGw,ԥ^؁g6@F$<EUP ʬ/媄JFjf^׵fm5P-E}XJ4w)| t?R-m^k)sh}'y᥽]DZH둆d7 +Efm3_?y^$<5JV?q7qy. qL;rGE7{GV/|><X}AQU<牢TqN#ɳ[Fհ&uuESQU ͢`I&s}^EP+@ʪkHfjQuVd'ػykdcC\Ӽc_ϯZ~ K& TW<%ƾsN5116Ն:L3o0uR o"%ւ:?9Gi /]LYs Fv <98dx($H$0d.G5:F/d;/z?ʊr&!"=$ sYv%n 2ŮC N*0$ A<_UL! 9H{{DCC:I]0gf2V8!r7QdWepa;=ȺHi}ގuB" 5A0ry3̢@:~3_>ሙcz ̮5^.&wIGzwPu=93.(pC*mL23g֣qjrr꫱z"Mxfdbl5kXPU}fc]TaWTꗱfyS3̦lQ4+y^D=ۉm/W3C]TNʉD5wnLO9wz5wmh 0$HH -@<&&: (@M0aR\A A:iǨwajKpej<s-\rD@:‘ן7NΝyW&Rp&:/!x_?q%PS#ɦ9Hqj6^]~me?](*a)}:rShzz/h'{N%tOS 8}7 I|IM[㱜.#$JgM2+~kpk\O! J"aÓe6m/iݧ&Cݹr1iN<`h6ğ$>Cx;ű ޷۶`7{qwJHD&RCIy*[h-)!ev4~+Ny4c,bkw)!N")i[+8qlx8`:锎`+bK:ç8|8xl&}}t `fV恮6t>7v ]G72Hhvt?N^s!)866VNl?36:cX|]kw~g9{vIJ\G$T95TA:2΁-e5h09f fZ6RBh=oA-a˭im` ][w11!'%n7-z:yWA|Gǚim EKشЁ݌O0S঍,WPZ{!1dE%XLÑ!(v>ϱp614QVZK߂ʣ,A$b"jaM[.d^~'99Xb%աvO0`(uh"sM!~Nq>Ϫ*_f y}*yy;gvj(v6FL{Oas8ԭ`]Sw!oZὴE1ANqFjK0}4tdNU' +W¾Iɚ"vՠk|[Xo`ܹ#S>n۲\dzy R>[)Dd|b#4͑#8KWwF-wAK⦲9Þ蛈PW]KKbQ &{쟢|ܼۼ QAx(t7gNaܵIV_MuaB}8OWֱyy-v5>ΫɱYJ4Š6x5W.׌^H c9v5[rˌO-%`syב''Uuzo76y+Cfc;7> ZsK)oNٱ"A\ Ǫ]ۺT{~wY4pN&WBifZfwO?&&&&&&&&&lܨj_^:sil͛;@Sk~nMNQeU.rI+0 ETlVU)ޖrDJI,@1󩚘 kZ8FQޥ(GHCF .ʕ# ,tE zߏ{mO !vʫ9]w_i}8MLLn2ML/!.F@iVةTՊ) wY92+FȦ<= Ιg~AoY$Rة2#.M vsQzkiCMI@1:?eՎE#eE OB9-M(9[(ʹl:^bD;><ЅSU: g @ shsk_z{aײW%(Ki&'@9ht  AN̯g]էNU ctuv`)[NJboi sseT53ϪX^O1~Hx)e&@7ꚛ[L1-BR#{rY_ϕXm,}&!}ͫ6hPr%[Mn(y7sDQT\ B d!Ff2Vp4XI09:E,F7 *BQPXɥ`ƹq1AZL u32D(2Wd@(.c{B@Ũ*}OQOEQH#O0K*fu)3 !:嗈UPӴ~!')| *cCc2PogjhP Jp賌N֜W3zI>ɯ}RET<%W29OO*,t!to 'w{FJ>pEHgz6PTUyIQ(H }9^Ml7&&&oB@&LRQ,z@M ukL)FVp$&HDShN q9Fdrى:VlʅLdta P?DnH0~]*-8,٣BID EH?aY2-P%\Q4uc5dɿUi'&I8 #el|$V n$o,/Dv\H*)LGh=Ùl ֭oc]T+!8Ge,QQ/HLq= >6!z)@$]9E`TxH0] 4pǍļՅS UTnNFsV A l/CD+T;leE>vx Mt]=Jta'ٺ,oF(cϳѶê[Aܰ4 LxT?voVUnbb ;T_{`^)˚XYd˝k93\>Cj{̶ʻ݂js*g$HXj=ym%# XC"5B&*mH7cgD d9|bl;dL VrWE4S*Æ-B !d}YD4F1ȍ=QHɖu&axDt+]wUk*Pt\wq2JtYnߊD>Il^M_>ɕ 't[''м|Jb׊k2Dx5W@c{D!C #(ܪO)YUPtO<͈;oFvM<"O?Az"'IF8pN<dz{)t`$Fo}ib. KA Tif&G8w%~, "tH'ox7ES$j6Y3*6BŊXz3%NѮ6no\+%vMwdSJ4$+ix/uxdq,vSIrfEH TܵՒmݒՕ(spU 3łj5dX2ܳ\nd"SL'ѴOk}s`~P[_L];w! C _uqk UG.Xf0{W 7b]0 f =ܳM%+}!taYF{ڑUi,q`hXlB@$2-w@yӋ٢+bKc'-ʼvKt/f B!wqXii Dh7l6 da%mB@%C$vp/4{m${XUa`-l*h Dհ[|^TU=ϒЋ+%4@7z; 'XpAd?qu6@VPï"rz=ϗH,k"P /feE^3y"0G`tUT@Ig&\ Նê.Xxe2 ˷ww-n"N_Ig28$3eѦҎ%b6i\~Sˆsf"5ԔBҼex)R"t~V U q켺ĥǥdj|XF`D⤼vmC`@|a\0g-J}EO`)N57\gUҰz5g9sT?u{,1ZB~Y%сgO+2?ȬefdhbH gQ AӜ2/gOp~#4D󦫨C#9J)L2J_{ Co\#? M{_J>yMD1#;AWM7]MUB4LP):Ħ9~ e$5nvji[8|Z9q=O?+l6nm.urn\.=@KiTQ0!o_^K![o}:= ^~@sqy`o4.Org AVi6 "mp&u^v*Buzcԯ9q_qb_=ʨBT&w p!(]-GH~- +)H2dei>y\~Jk宏p wZNEUŠ|v?|)HG8:eզؾbALY[.~3:8/? ]{\pLfilyW,SK~D{EBplknڀPqF$liG7Gh$>?"\c{?}Ѹ9"PE;ン6*WVzKYa-k7l_ Jfyj1eBDfSG;X&6V{1y{Z_`$l*A7xMPHz96U-o)H uM4pW㆏{aM+׬eJSu͕OSS~OӦM[kn]t @|zӜ'PmkJQ;ϋ梸ښ2#:;I(&UwBς奤ml;ϭͦۉD:I,B`I /+_M!"lls?ʌg&9E lڸqH&]BoXt)Nt #mN<Ük@ף=?FeM >G6vUXjs{9󨨪dL͛ظv5o+".%<{6R/PHcSuS6\SPč,{8iZuYVeh" n$۩ F{ڙJ@r*cE#kJ0R:%+Y7L$EK& RJzHTdwPێ'Z[6/C)Fq%[XnQ9?{g_|ό23@N-l۲[qõYY-T ECiHbV'?J8Yr@Tp:RanvG"Dv&# ^ڞLv1_#+|oo&7Ŋjɺ(Vk6'Q̦͢p:0(ikm<?~p.ldCiZ'3"hް[6uvnf+ˋ= .AN"̅ۅH 4݃),߰"n"F6[7\Gۿ/"34Պbsфn\>T4f(ePm5 V rQ,q_`մfGKg0$L g0:!W4 EDpz\h .eUF'<[ek珞`p|ΰƍ7]G,-]PTXCYώ"&%aZN}梺K:JG˩@ Y[eLe y` }.MvWUjsb,ebbhb ׮ #h󁗈q'3=^%PT+Vod4gϕ=YJ Tk2N:}' 2Þr̐̍gz@тXK&qgmϰ90cO>CO(jD9 ?sߺx$ZEHZmX_[%v7AE^R ;.W<yX#X022^5&:`9D!/XDQNhs M̐)T. "=HVsn5z*H_ (X*.O@NʼY\MG.~Hz:$edQ|+u#oN9SNJsTv fv[qPTEӓO1c4rR3lc}vY-] 6</%" !Xom7BMЖF~Y n0q9S1UU/J)|9MBtQoY[y炰:տ7S;04fgs+WS'G7лa~q(,bS좽w*.{% uVbϮ} EK% )3xv/=2=c6+bOW]{}*`(/Y3'ӱ]t ˅QY&ٴtQ AYzb?í$j_[jNn8z&Y:C~IJk˰`nGd(Ŋ]QfDbH۶Pp䥗8?DE:#CLbLu7O@kXlX4%8Afٟ>[gy{h_E~3rLLLL^?B c3c\<2kf]evT:; RLzd^3%5y 4Վd: 3'5/+Fνwi) C0zA nWEmD%HUW4|dΩrm$f =GAM=>?k73H2m,XtdCǺZB4^棪t?3ZHD㠸^QƦ iR@-IDATbJVMzj+Ra[ 1P.|nB SPXL:ccǘ+Sx9c`uر(*Nϋ͢.V@3/ <7(((z.ScLGSst#o¯ +G<4Le8Ymme(bPb%.uB0!c+fcG TMC`/cݲ"UiN#qoht'cYə)UHL1eݶfmB? N)ȞbrbtΒ_ĊJ;'')TcIV_ՌߪY`F6̼$z/^B{hd.!A@YYsErCjG~2AVTP%xx2K,<"Y5AO[72>e>vU9X=&sy jx'i F`l:{,HLEJ(\q_p%|r/3Ii* }yv&B88rrvT*I<`:4HggMF5A"c)sx:ekxYy3T/iM)fYs-YD]fRUMH%Sd 9oqIPf5({vdd6gFf2L+ )$!w_ˊBTI:jV\iQUa]=/?ǐ 9“f +WRpR$qzy|OMS/}䇎#3C~d=f9/x5+)h3Ib(-Η V3Rz[f۫"6C@lm*` UY` }瓔n]u^ꐠ: Y'Ho c}DJʚQEб8 LO+(PCY EO23k:n k)@WTdxp w:Ӏ=C&lP#C,PW]O B,ϭ$RuRSRUSHΌx$] ]1`c㊂f}02HEB((Rk6{AuMi&nQ5N"ذ uj>}b$:j ܯin#G²*V4Q&gH"?HjqHҙ˼ *d.SquWQd"4yhN"ZSeެ/\\0XT0y|>Gص{;_xlܱ2J:-O1=ێshn'2ynny>d'3tf= eTZz5ENT Гڎ}I>1MNEE%~'Lw'{GЅw{I3w++ ` /:yM-s9|$ ;v̙+s{eEEA}?31IIe92Ů/pj`yM9A6\VJkWXᦻFedtnN8C] 8t0Iz8(q'8CcSְye%6^xj')+VQ`Mqn:A^rV-+rhRp-7o(`G]uMMŗ8;a}%~7"!:C ]^<ЊV5ӽ|%ZFtWRYZN'}i I?JYM5.r(%a$i9t0 ɩTUR`9&s-Zqv ĩAi&{ TV9SgZrr|\P#7F~r 8ٮ!&Gcd3N1i\OfG#P 3"@eJˮ}F^^(v?"g'tjẈvO9 y4חᰚkG(fbhho+8qyy6ܳ$ Qfk?bm#eGT@1Fy{݄/ߋ#G 3iRcB*7_G^aJ&N#t'㯣5i@A^NtL2Mw87\OmV7nAgGT '|5t#Z9W-C?cϵۨϷ_"z3߳a%5ZI:[{>.*J4o;?Er=argL*L[ ˶eAb0@,}$~z&$W|=Z4/b(([HAS35>͟ d2f%oĦ q(&Hi^|NxdPD(`SdYxlKZ SC`SLM`wq4TY\yY+ 3>u,F*¢i8 $gn]6'Й`4DQ-JAJbSq?'q8ޯi9.kI=cDSSYUߙJEÌ 2<&((*EM?B5kaoٌͧ4 1KlzI2"[+MH KŒ=!IaiuՉL3KŊ:]Vf6fy#nCO1NX R[UM~55E'4Mא:m-(9; a(9P1'VV*賣h"PlFh7]jk2.9#.-J*K42;b>:$F e)P9Ȧ@2.:Y(JNQ!%h'}|~JnHqXBAUKMe62%u$؆a\RE]p?zahwa2A 4 tș)\rԌll"̅ȶs|\p.C(B(1lJ9ߎD}-~kgzڣ p_J~k"ۦ_zϏW…qBnl1 'nA.#~ ł)s5{{>Ogֳd?پsm듗s\P5׆&&&&!Px:J=_dss\ R r Y!; >,!PU@!M%2\ۑzL^6,r׾r.fk,skҐd-7!.*6}qY ++G'h2=g! pʧ8߃& 2ərNDp ]%|gqk!+pizשnD&fno'( xq{Ko=1 Ip4&KSgFt-=KhFp8=PDAr#YRhAay () W9Uq]\YQ! ̫[t,yQ9!j{\fK\Ee\r{mBJ y,24\>jWE *?sʎz\6wU0e/rב_2y~x6r~xq\6111yHg(,y9YA\2-ݢaDJI&#W+7) c$~ꫫ_bd˵aL$;炟ΡXܔT%ɤ3( ݊\TfbZ02)-saӲJua!)Ye'J'XEvQ(%KZ,9WܔOuEsPXRU̇ j6AR9R# Ccb_WM}%|@w~)TM%9y,:oQ Bws*6"odFqQY gP4\^?EU xo.x+G$DOzUHEB3%U3>hlbf#Z'˝/DWfxrWRʏW˦ΝːHi\TK |Ï (G.~B.jnHmֽ0gAk&&&&&&&&&&&&&&ĶC0N"&I$V{.޻x#A2uJ&26TE\No]92kXhBOX2B\) S$$'ģ$]VW(#4 qb)~,GmVQ刉ɻhM#3"?r 69Cn꠨*\˻_Az uzU~wUA&&&{d&X#8=rgbBchb&ocSc2|&&&bXdR|WS5#mv":ziPTUEglekVӗIH$$IۗK\U$J&It!.zj]I&qņf.fF:9z. ([ܗ^;ym21y?# ǎf2e |'5]~EdIJ 8g{rt $G,\v;.0Q'{Mz/&0f82b P+)e$<4 Eyc71Rth9{Y;>wf+PCO>hRAX]?.[4 !o{?|56WxH L%2[o+wd>JPUo}N*dfO_OnXqz?=m$-8<\:$Ú'>woKJpټa9y(X]D1\@ /޶LvE:P+e"^3ɛC@f='[Onã 4rEvq__Ơw&$*,# qυշa_v}cYVA>E9uv~cǎ4WF&&[0uG?MyU#ˊhi%&k^|z ݁/O>f-mkИ(FWo=xݢ"@|_sڸk_emή*Ÿm<kKB~فwxUT'T9>QXYߠ+taQ$J^[,RJc>؎ Hi_!G4]{7r;ǟxה4w_^88ȶ?2~5[}}mo :u,7w~$?w[P 2r}X[;"6+V8s@RJļ+NPr.>u[KXd&Ӳ.IݐEeHkk/~Mf$sj*mU1t nRy-7#ceb% 'uVᅃ/&n/HgtΧo#TB%vbmE+-my8z;' V*7Aݎ(ȺoJ84mيfB~a`0xS H)Q]~KxeiFp5Q #+lZvj8{ko>h}WV+ףV;;w6^ ^`5 lXYʅ/%g `r:Qz k ݇عZ>(57oU1BQM>3N(,$`݈R_u%gh96_s-q6ܖ&$(*ÃGh S'Ffް)UaH N,(:"0xG׿˭w%ej ?!RFv1(dcd/N|#vIN/?- ?>[b ;JVIcHL?ں4RD-NZi[V>QBq@XPKacHsyFzfmͣ;;2Aϩ|_!@˼xbקsc/~gFqha~о(DGG?乃 =t 2w_lj!PN߉ux:C,˯>/3yH=ܹÏwcLFdNIzΰg f9/yɗJEU tbx5`x*#W#/345bc]#3ZK_7Y<7~,cIUQI ph)ru ff⃻x%gzp=47m* U! zڀ7{A|f37O~gIRf-qgbxl+m/}ТPl,D;NU*j<WzhXʼn-Gj. V2Q"iLg41QٴM)ya^j9T4wTb>v}7l_)ܳ"~!4MC:aoȉ)׭­j|]<ق;aj0:v[+(N IfCL8@ gfpTMHpen CbPP<ﲿ3t^)q7{ܽcpǘ@|~"}S!FǘI[(.%˨.v1trfnS~!~fLvr]SQ6C@*Ijy*VE'6 fWȥGDP["+ԭč7W+D98/l:֯]˵|Ӭ)pzC$¦Wv*츎_ড় P/ +^nƭw|.^dۮO|᷸Y̑&N$6VE <_Α0 igP/bX[ŹdbuΪM|΁P V/H ,y {2aZ냞Kh|ݗH~&@nIgs$bAS$,RHI:dWE)4.#2ԎY*9˿o/'>v;|}S$S 8 SUl)j'ac}O?+gzN{~ٙSd:E6 Td k?5l9Kg?cԻ%sLts94 իz uD<)A$λخt8gH6VD~\~݋ gO1_Q"w8׋") A':#m'|2C@śC&i9oB:hnVjď89ɦ^. ˉ(vpy8P\1$S휟vuMl>ȹTWvn ygjⷯ[Xj(T \rPE+ӫ5ThEJEHFO-mSL(Tug.7wx^6܋WazN&r;s;ɢBnsJʼnr9Xl((ED7,E31y#|e rGGSg_ҭӾ^/i~~7ZuaqҸ BTa5_w+7p '(%/3qҀLچ' 5CvZf7e9" 2Wu;֜[ PrܸfE-EIĉ%Yw_2ʙ L>Ǣ& EJ k^Tq2!eٵwqn!PKb4̞*3Dge[2fxp [Pd7]:WfLvM0A<:KjLC^XK 34K|24>fsu;L j>;_jmS G_KO2*6Fjsvt^\)[Q#ׯ->Zη1S*;&&R'd \ůpφZ&Z2g=雊q9_l̫8]'K{ia1YJ-kd>Nma[Caʍ$L =:m_dKPvG R][5`DJ-m;" 6ѾQZw'I,!%DMH,V7bFB$lttZD"_Aq෌3:ũӉ%cH{ <^dfx2I$gX411ybAb(V^uM t3NCǟ|l kW6qM^:zXzK@r{Oװ{N. cz e Wr=762|}̫ I-GYBdzhR D6Uz$m'X\//@itUꦢ]f7sDӽ|W\4t1B }># `U7VUY4 E!1S-Dl/$,fyY@E=3Lx0zlLͤjʽwOlasc)H+`箎/u(όϳM*bbbi?31*\3L$Y-=xt+Pj(Ԯ*\ݨS(vln~v"H r>ȷHN%C#$qT ͅP& EHL34H'"OrA2qf8gZ]D6 ÌMFS;zEOY)-*Dj"b\yz&cc-5-g׈Lvr˺UL|^{vW}Zev;O ǩ=%}q[ e'1@ ial;&3}=T-R??f}[ngr`*9Hom6Q d98细 n.CHs11y"Є`E(324̸λn-F%7\m'ha`(]=m=_f/ܼ %ˮ*=d"7^Źsg3i~n DO 22aRad|O`e?Ư_gvl;r՜?F57܉\}]obCA nnJʻ_.C‘)ɖb6U2ހunI/_Îy{G8wq<#6#h,E 3t34_} [Q$a<)k &iKsUޒeYc4i;7nmd8V8N k {^k֬8ώ ظ t [nE ]T*?L'xW*C%+f$''Rl VV_r`Jv?nrK;K)FCc,,Їz)h gWK4bBɺdeUR7c~'*Z 'Ra̦%^p8k-ƅz&!,X 0t(jRf/| e=WXxZ|ʚ/9u4WKg#P1ZI]0ʾw=g mEQmlͿq@ À!x,FL>dVEK柹uQ?%!. `r|KhnbmBPQD=[XָRW^ ?3<K)td2H}C_Ĺ}Bd.SM4:F( =Ŕ89fцWva,Fκp:"Μ;n61]tr]-Ehv*B2t(g2l~;.$ G\, q X3;7//rќ|[#q̨>]r g@/wT,l\UVX _e1 .wICJt@sR_⋮%/[D^ U^~wr{|Qa44[/; ^^ڷ.C.3 Al<}2n)0#VѥPUB;\$z6Ԣ9y,qKX)]|6k,uJ.VٮML>pdשPX`D1$<@Xb:܊rWJ,/;[zPJXu*\{2y[ȶwU~,YD>wdb6 bA?D6d}襖7ÈqC.$H͌I8asɇEE8Oߙ6Һ rk*w\E,x=e|PTxyNǰ婘;l>/o* ="Q4 VNNFr`v"d͛TA$SbZQӇ 0 t58nͣnE#A碘BQz`} N͂ES߱rt.taRwL3IRvZ_if$0avOL݁8}TT/ MCJTGSwݸUyML>!z~;A4 y"j- I<@r[sn1rdvSym,Uɶ=c|wtsÃ#> "9:wYEuh!z=ECZ-Tt"ڱ,ˎh=O$(]̐ffa[H~\v-zVB#! X0c}HOr' &#Ԭ*2%z&sI(hWͤa/oUCUن&iGl(!$fhomgl6UVmꡭYCf1/\\0XT*ٗnWzt`SZk x/{eB*ԻH Xgm}G5x +  vC~'v%(+Ħ MO붮F=O%{_R'4]sQSCHLy'ȿ7< < Qw+ ƬXdF]y~-ՕUzc5ˋc1y"ZT_}k74RUVg+):bqPT]C]m>M/=v%M+ꨩ8dn?Ce:**mO1[ɭYrPVZc;ٱϒB`Yu- yZML>DH})B1URPlewOY56B&4@h}!:v'e + HIjjߊZV/ ct=ӖjV1v7TahV(= -Ϝ#o< u =(2ini$}~/ǻb;9ɕB!9O̬0PI?IgWؤD( 3/˯qTWe{4m?5;_yb/"Hp<#<.|WaU N{C]!Jʫqhrz R>SD qr_sbI2l*LσOy=e2{@4TįV_r !N s\U|vl#}h EZ_+/pqz,~yG^(R^[\OS BEjM s9r:-RBUIMu܋'(i^G]Y9k7o;}':{û>Pj&$v&m¶m[X#2;S-6ARKJ(d͆ke벬ِn}=g;IעwszRd+F`wQZTBZ(aշ/ދgp7ieߗC]**]ES;]2pi{k3f0 ! 9#:8͍7mibkcu)z2QZbl?!S w0][W٩ij_/dF(C6_AwVSiKjhVxw͛3K$[n,"2 NG#9'u4A*CƘ:$fMsB:A4c+DB!⺆/ zpxD*?x$adLOG5`EdRg&4E$F h@ 33i L',*ȶZ˽\Ǚo<į^Z_|j3V ǐN$͢"/eg.s2#4PlLPxT::lӉY‘8ddG&&&e=#:D{1ւ2PxKl5\EpfynULݷ뙠jA5HX-q'cqRy͸689gʆyv! 1ؙ *&_% RmtԜv%z0RqƇll,qn/ WIdz|bΜ :JYNâJ2+ Bμlt?B6H}Ρo&793}4ْ:bٗJBqQ}-tP\ٙI8\X/Ǖ;"4>W)R\'}g﹗;Hd`{ƑB23>@ﴕ*8QL8f]=сs:݁kU|P\ Q4<;хuzdҍۦiuPb*aP/($_Z\id$1vmq6ݵ"=GycC=6@F|]廿xm߻/8Iv?ڹvr"}-<ٍk>; St;h HEF5jCZb m->?JÍ3l&Ϛv "QM} -M$FnŽZ*6SAN#(_C}ţ{Ȝï;>m[IMtcs:dc5$G;8u fTbg>"61ygz(\s3_MZ;ud~ Wsjȓ`VCuh&w96VUapM"]E%n㥗O"=~<aDnf-LrlQ rmwS!d`N1~ו#gKsƺ"{xCت7Ozݳ|& 6sB)B;O%ش뮾8L Rdy#/Fϰ1e`Q}}YzM4WW&𣭌&g荛.Tm,>=LׄڀiH$ N*2fh8%-/r҄FƙX㶡R(xE‡ Ő5w yj䂼2M_W?6"oBBJc^cw$e[?cqM=Ɂq%~CDb)AN=G(b5b+ᦏJ\|J0v-Rqp 7s-rMs1w5OО3OӶ?M<νGI+( 9;!t s\i;u><;><ſl_.zAwR$ջ-ْINⴓS߹9wrN$Nb;mIV %R{I轷vmf.@IT(yvfyާ@#Jy1uP$_í|A-,,>&(ߠ!sO3?tf)\ *0v-NMg1%FDh* j7`}s6Lb.K DuD1J44bxDby|v&V&+z'o]:pf-;m̶(%dWe[;E8gIѮPx f#3Df(U!4 L|EBOs_Jzn  ?||w%1hv'6IyI>1?Eydmdl[O3~< HdNNc*Q6;(񅃲PPm{BXY5nZ]=j."%bV'KM*#{}Y/(iJ, QRGS#۹)^-cؗo]iJ-E0Kb/((/4[RP3XT'>7o⾭+qI>T`r&܆{ɕ/5]GQ~\NEEdRH,JE(+-$#M] OHW@qz:"J sq!X\_sW+S2ĉ wTزp JSZQCMMBi)G,>H\.d|iDgXHα{ou\G[A7$E5++ܦ4ݪLnR8tڧ$t\~rJ>[TLfzRr20ɢaq!;:E%«395EQK4 Q%ŧZo1~#p<g}}~SP} ;L*$aeSqWԿ |)LPnx%I@i:[88zܸ aCPBQ E  kL#AqR6)M{Qfd%|a K?A|Bl_WOyח*~eK9L(@Kcֻɳ|_|dp8|S ́i& !b}9,?n9BR`G8vқngYQkyBDJpeq~+[094lh:N4Ҽ^Ҽ^\v-)B_$5u&0w$NҴ=3gPj6qB$i~ٹM88Kq-$'!z  V) OFN kW."ͩ%SFJgV6T3D`hG^+*[iRÌ7"LLŰ%ݓ47tS2Y&i"t<YGwyޙB c^{Y|<BQF(X\.$gJ>K=%[S]J*󰩺Yv3 gGe$ϊK kӄLN{igO26LZFc'Q6SPLU@YyPmh/c](v@L@0M=ŝ_TTǩX51 qp(qb35v wNeeF{*h6u~k)gO3M)$ |Lt5"`ý_fkIӹ +T;E/?ϊI|2Ib)Sqfx>ҵY |=#Nt 1!#ԵgNA)\ͫ*q $DL Eavs]=$P.ˢŵdeaty"2^:z.Y,JCg:!tvٽB8A*sJ 8WU=Ak$RD" 9+X$ļː&gr>ZE(HZ*ǘ͠bĶo޵cd *8pe94 TO\_EQQ01>?_Hw8& oEEQ'eYGBܸdEr|zsi Ry{:ɋS?tdf $DÔsC O-T)[{+)yk=7@/P,gN} 4Ttyf015[]H@S1P /4R(dÊ|F[Oqkܿ -,, ! 6do7єw-"-ׅ6gƘ8}mp:d콨bI{6:ԾnCQ}vHInM)FhItC*%}1Lv`2 gtgd_T7do00UuxlqNٚr͕NEd8ZXHWUK+9'Bjnn%6w6W͐(pMK0ßJ_=tArYF5kd4((udWi#iJ*r}3F !0cS,/mcz=o_ᙧw3A"Dc1bQWYI6ݵS$ Dt =.MI+Y= ~?~;9wÇ=IebDi$av72[_-6c|'_:tp#{vp{oq=t8t\ܴwJ(I`{gp͗Aae5 ÃYZ:'VέDIEsSR]Z.0TRUS1k><6^ԭ55*I=Jxws3mA;׭(3@aY1Tm] \sj Tvg L) ihAߙyR<:GCOFN1Cs)˾#k(ZL]mw3cϢ*ѳ9x%o`mE,*"4AS3jr}y(G9WT39r0C3x *Kg '^k$ XYӛEMuf ,! 4bf" ]-㨚 rT#g9|fn[_ߖW6\>mlV*YQڎ܋o0D:K;a.4;xlX73CSdM} +P5J)M)k+i0}[U0L΁TO|ʕ#εaq)<WֲC"$4əf {dxTKciaaaaqU }`oRTOnV,)/&,Ոŧi[T3O-n>=P~r.xb@JJx['ӋסX wAjӳq͎%D, ђyޤ3MʗZx}49VZXXXX/CҚC,,,,,,>č'~E\N6*,,,,,,,,,,,,,,~OQ>SO*`$#E_gTZҹFߩ'zA^jv-b>5ZXXXXX|~{((sz"P[#MO(" "RObRQ42MnB upq,t[Y" VJ3\/iF mZOyq`%irri"@S\,фvrU=4t9joeu3ѦbQM'rqc5X/78~xI tQmȶ[,,,bN?*ɫƮ(HF PWdMVswKX_C//B1wR!$0Pr}l8x[‡Vʌ+Rg0v%Y8kL#:MO ēOyI6bNMdf 3@qqiW Fzd((\kSClM0A( $qLnU-9ޏ,`^Xj;fblXFAGcl:bi2IeS$Sy\VnZߐ̌txi2 *ȱxTQXAmi}M L *kc4tudаᷟ6~~Rriμ,)7LGZQI=XJ]!| 0jϿlT{>{!'cx"4T͎?#,<}-"kg=\7xF,H,,,gݍSEy(b "R,傟cP0=#@~$zh!8I[5B2a+4KLy$[1{¼|..6"nkfIyyӹ2orզ?F>rDH'8{0GTuF*DwrUh;6 7VBzm@5U9nf'z8{uж@d6}}hYZzzY|mIΣA|>j7𥖕B?z ؊ز@3ۯ2 ;A7q.7ա+w4o?Zwb zbOVq KYFQ־qLO Z+qɤqbzv9a o2Z_s~(Pq;y"Y߱O~L[L?24^sJvq=>UB cSMȦ,Kgߎ(sܽU@dW_?O7vBc)GCڿ(>O?UY?bL >'(ΚK-kl?t|*2QG G\2}@;ϰ9Oͥi3]쫘19? ~0cwxM3lɲcbsK Z>/rY9qƊ(Z0n_-W5u-D;pU!f?Fζ|sRl?tɐNXqI@As?z*34A}8t/eKF1 @Ŝdg`p2 @Fν N%0f..%]8ٷ;(+ ]`S?'?QRD z^}Qs 7-`y~V~ue}gh.bR~A pOE6awkmkY>ޮ1TRDy}A]AHIuZ%, !Ν>ġx\Fch4eq(I+(;7?yVW"A&i=gvݒYHϾ#|dyD=Gpa~/}5K9q-G$$FbQ鸛չt;DlWn)m5/M;WFA*VN-)`t Aj*IBɸBH @U͆u]Ǔ$,5dC2F[Osk)T͛OśHG'4[aX`2%4[je.n"$gV%y;bI`b*(͆rR`dzS+X[Wc0GT0^DE`&XJ!u vNBWs3MIzI=[Wȑ]꿙-rr}wcRS4uZ#7(ۖDM dy??y{xnA"wG7LbA`?rK[Dl41%(j*҂k?Se>ޏPPURA(h LI/] "}<2n]ߴ4Ĝ%-Fs' Cǔ9qa?4zn +%gwUWP _z3ģ`Ϥ>J FtCiļDkSGA.xcrD!P O. K9*h7}G |mcL=G F,S)%@gi-i)?t&։4ęb_2e.1u96tSBC\:Ί[Ư屣(Ӽj fo=ã'x7U4gQyt qf{o8ǁ+1_ygZ|4,Vş)tE)GOFR@qQZ]Cc4%(2Xϑ .2t{sp1RXUwGWb]]nM`JC㴵12dr2eJbGqtDeUUgp'D[{2ҝ 9TRU*)H`SU %_4;F:^勗š*,4lOP0B=?1@-adĂM"}si{6f_/m>rƾ[2,#BGavi?ӆ\IM36ři`&jRn^):x}r,2hkng$djr{N [79}h7lEyk~o&_P1aLpdAƵ+qKHL ' eSri[qֳ9tdo_KNz-ǎ2a-s:ܗKi`sq΃wqT#đ]Cryu<[FYyĎLepȨqdEQ0a=% RbfV2=/EIe$~TrI dh w%89QsB?A8nr*EYXy?5=>x=6W$EޝkK_oDJ:2 =ęHLyFR:ϝ`M5Y TW)TG{iBת \DGN!e8LT{PHE%@zǦY]3֣J0BYKi(˄Dp帨}Q ((4)%+z;F[g|hMZ(&x'qSs|ilgs BLoi<]54!~*8PJxbo3fS#y^A\3O]MiFφ'V۶bcDM v=4lN>w[ZI_b@-M˘82?߂-k*FݸU294t̎$(fڕ_1B/p}̄ۤJyYA9LϢ[w`&Ă#hv|$EcsLN_iFbD զo/v$љ0Ӂ:'`;'i ׾x מ=g ]?{weq?sw+sZgMQ/_LAv6E 6pf Wf1+V4n)7V='WoBAF8reU7BAD򢟣fSU$BnH4+&_$H%ȯf;կed.b%TTPV19C̔hL.&ǙETj66Ȥgx Ts79V%((8nv;Lr2tx7/%?;҆-|,-F aϲPB$6T8 i8ظv%U,_Zc4L"vyG+VԒ%MEZڥyafz<ܱSiP\ii#8N"t8S٤rKh(/&J́Bs$+MI$dѲ5,fMl^\AwLv3c4^EǁEIj(s)Yƶ;>ǯ=t7nkWE))Hg,B e78™s- Thfp 4<{Q5(tVoZGMi Kug@SH!zP]kZJWk*)eJ܎ f"XlCx{%)p{ rV^AMMvA5f _vn} F9; G#1+6pQ'UC @(*f¸A((vk("B(I,(v1lZB~v`ÿ_oS̚ITSd JK`{ #IΏ( :xp/NUPPMK,9|j%>m^C ,mLJT>éÇPˋPDڜdx$_. lE|}?sDĸҥn4M4 MwMo-F+bt6]`&w.p`>71QSSڵw 4)$K8 m %i. (*_op91L͓˒eUDZ9L4!oZFtrp}a=ڇ˫&!H/Y|ijc֐Xi>HQS^SqTZI%F~b*LZh%'Mm?x(S13="4Z9j*"KZKmɌYq嵹)Q4;@|L/i ?@ Bz8aZgizBVWm 8E]{*Fa_׻v˓l;Ħ_8шoZ:i>2YfBQ̔/0I9-Ϗ(t5O'ۘMi]>Є 36ȭ+'@ 26H8&4q嶛(̴K<&;9܋I)u*-%Vٮ@ =g9={ngGCj 3O41»\)/^[!sC 7./.!C]^ߖ ^Ͽ}M ͛tz xȷ$w]Esy ur}(y:X$RY7ޢs2 :@!J&fp% Ӧ@mMj[J"{?y7Iٰ0'Rb6Ҏ%6h7S\hatu$ o67Gh甕}" !<>L5-m[ILHW^@('nH]+1D F1t=Bˠ!.©b8Ȅ⡤ ŕGH~vrD^%ikc*GB&:W_Nh )5prD+"K[7]F(፷5CUU3>:IV6X?`dt 楅8BQg-ktXxՓxrӃqQȬ^t:MSC\1Xw*6%u qHfngn*qc%5 `HdN)sBv>J2iBfcJ# 䢤&S:\8quw=В3ROڵ cO|7#C\"B2$aeX̪-C<+\ b UUQziN* "04c#99DN:~;Q]MI,Uד s/NEm)UXQxc H fC`l:Dx&L0D]KS"Av*8x"L'b2l4T/0qr_@n#c&8lÄ@y=k+80j^[;UQQ;ÃIbYB ḑTCJie%!M<ME?,';HdF(Uw海a0[v %A$ajj`З`y-i`,PYNe3T:) +)1hrd0/IeI! 韕( v=*ғ1)r70L*0yG_xnmي}3E0DK p ذy='O7c^o*sG|$?olK\)؄d]*<@S;|k{Tܼ\ MNO6@PvI$JΞtst=*Ys۽Lf)`${w$|v974UfhmU6/c[p'!:Ͽ?ڑ4=of׮l?6uk.̣(7Fzǃtt6pdþc{l LtXsQŖSJ9GvU 5پM.٨_Rid 1-l& {w(Y咝KI~珱Ǧ1mi<Ǜo\|rpjcEh.bYmS-4]褣^:Z8ڏuED8r7! p۲|.'U|ns5sI603ߢi(BŲz؉}&0qNvjAdU*c׶y0FebʋK)ɳzǛIĦGRXVBQS{x坓D8=pyqNWVNAƩ1dq+Hxl1z[t53xħzը,f8/yIFEdyY7>^+VvrB;ttFSs_ΚU(=&88ĸC=4 ;JVJ6&1r7^ɹ8eRPh;Wt4  C&:.0>Pr-HDS|c!lyxq:U&}Nݴi1tQ{X{ŵ(Dٽ3dYG Ë'?}}cE͝7hq3y, m]*VR5}FNpT'-ʹȯ۷P GcgOvsXoaUeO?g@+dj|W'kRYNqWKd1&hY{=,MG~z(1;ٹd &:NKѪײ< OFsɩazYy,/#|{bTp۝[)LK cqdZ I3__^q`^✜ ?v݄k5eix5O;8E )%ZZ6EYNpl`DGszJǮ\( 1:6Ah6^i$1ms:TcϟSa |CVVU^"{Giq>i(<9t4Yxbޤ*bt|p$bs&'Fɾ.F.**nGb"Eh2rJs0;5$bßEnU@tfi5G&Pd#CCLxc#*d⌎N @bj6#7'ێ F'4rrpqLj*idgfxq->8BQ0㳌 jdh AǑN?Y^fF|dL2=s2qi0;5Fj';tL 06͠0? n/8#@ۆ ,]d\$f%+d1&Fgffgjx7,x1Bfn>Yԙct"--4`ǃe#41d"=;,! džů'w3LF2Uel:/]IF  6f!gǙdgg "7?ۆg (Ggrzhh##= *УaFrĦI'iDƘ 6Y9x $DJFN>>c O̢:d[ťH=FdbtrYtiƉ 1Lisq8Tbc}LR5`KW*gvdX@ufZg&2T7)BALaÙmPHbDB1dgb +n/z,(Μg<{L{Rn{!Ҳ).*<)4NNiTRSQ*Ӣ|dn.ggj&!4|\el<+ϥH=(:8<3l)t&cOYPѦ~F7?]<|!=Rx4ϺzNc/P|S&x¤O]*xz2S%ξ8οoQO7潄@QNdڥwϚ o"DBpK!R"Re1W7s1={$;J.(ϋłK]S,|1]W[o iŞeDJ 9sT@lcI,/$" Ibw{Ȃ;R&zwzddO :9D[W/46-,,,,,,,,,>eF}+?`qOrDbhAK7 1I? \9"6\@L _$l TFy_ip$W똉8;1<']JEXhZ Ƭ%_b-,,n@Ύ294a*9]O_:(}H壘}H/zE)t %0D9hG_BEA0Mg0 T<^/v *Wꔤ41K[cL&i`J*( ۃ@&^:m$ߡ8=S\] Ǚ!'Ӭ !@Qq{8mx$L(4L `;x=8m{3<®g3$ߣ0D#"1=5y8\n<.#qL#N(8CL7AQq5r{x&l, JP h ߉f(BEI[R& "u\@j|A!3P\8,&6m],H asaw;?Ӏ@:Ýh궳.݉]S.='% MkAB@<"7PlzY3bV᦭OӸ$Óyhךl|(TRJ\*n4B@,<7_%e4)1M(]̆5 d{lje*vJJ):Q@g[MK͌JxXV~`!o,^@ea%'<ԮXBʻo)Q],!x ii?ɾl"Չu.'4E"ʖeR.g'8O'ɬ׾rV_DH/pDSDޝNLbY% lYY$G_yl?f _E Bg;rrj%Mkq9$RDt(s7#Lt0=ɞ>kc DS/?rGr?ʔ*q@ ym+K5a%V9tz ͘P-W? :\ls!{o?| tx'vhRt]7I$S*| O@|t~nY:J|L&ȡ4o_L}gFY~#=`| tHWB2pn<*3Jny׮aq*p8A~22]n~dx@e-Uh֖'ї_RUxC?JN2nִ9d'qȗnfջB9NW*l"wyY54U!1ts?ۅgT#qm&si=n[qFw=GGJ";O̓LQHNu>JlbƷmUK d?钴` /kZ,cz|̲H">/>¡G %% fx kඵx}d-ogNzu"&A\[#a?O8:h-x#TlW2xe^9> uww7K 5I4`MA5Y@3__^qBL34p]SkB Eh{ˍ&$&7n`iY64SL;z4"s qF\'Cx&Np`)2ٰ5EQLF[ K_(|҈m?_g}+w߼tۍ#[JNMJL OKo~y_/c*q}S(JKt7!u<>`f,>B0`ԫg+Mq:@J\Elܸ(g:1S&9u(hvgs'6%'^$۔ʥDw~ Mhqh`Hȯ⮇ *?#vhꏊ&'0'|U] d;yqUbcshvg_2\.I/BCM!Cʻ.ӌn"' 5OYs+z>Us5rL$E#l64 c{ #xO1mKAeoޅM[-TԬy _ZI3v!qDUm(6v\jvI_J]e̞|9.7:B(DZ™C_JڕfxPO/%stD"HLcfֳ+`C*}/=HA[bsv=#Ǽl,1;{Q {vEK3wS 6G^^h$kyt󃗁ō"t[W !ȔKg*e7_?߹o .ҙO( 6p{(Bŗ2;D(HZO2IWTEv(:tmg8@-c;{1Qlݴm'fFUu츳*Y"C;b|L|`)2C795.$849 Oo<Ҳ,l!)Ipaf³oKWw('iKb %Y vSd(I*PE @2;O[[D*8KprQPɱw34Gcuɘ#B'Waiƍ|Y0d۸n;OMӶUl`Dfhg$f6EudkѤe ZsXz9Yi̎^zT:Zɫkr+J \Bg@ٱq$29g0]b?-ع,Qw>7o:O荳斛tvvwAԑǺ+IS4?O4VvI%yo}vΎ&CDM;dc35rinna,f,*@Gybwz9T\ȦPi(=~ N,Mŕm޿7O>:f1-YDO"!lY2r7RA8-pb =_H*.TIbv ghh:,C%*ډ.$! l!ߣ\YPq{ny2]DϑT |c#S* kױ0!ZzFg壏qc5 khBYXX||H$; 9sL6'T6OKLE%{It&칕& GjzE v\@ߌͮ?0+{2)%>Urfzb{[h: )M7/+u#~%H~V(^&v`m>1AA$+J)0/SE>e;ʖcԮ_G] MйɄrUOrzw6MPW@mY>.M\bI&RcvM%7*uv}uc >C @$c:~FǑ? ?}u/]1Z#=Owb'2xGtL!T/o86=  ;}%/5C:%QzԔw*I!4g2ЬtYo?xB4 g|>~Q8,vN@Cм~k ̂HF.gbW}Q}Htï??xeIƢ*}7?z 1p*ҕCݒz+ pSä.('">C[qf5X;;wb7秏>±YTa/.ob,l{!$w^cƕGuu%f_~1&xd?.?G/dL bS| LU8<)"XP3u1gޣ!{{Owj;ģ"\}4^hN:}AKKPJ*%}c !I߹:ދs]G"O!/}SNGxD2XX&o\8p[!/]I 0c٥٩U aGrs8ѩa4!T GZى p̒3SDͮn3E$8Cl*pw(i7aLSh:68 v8ʅ yjLyLƌγ4q.KwЗ(M4d=|qCd:o#߾ozf8a4m)4 BSLHY8~|bx3$K_'=^|9}|!1 ARPdj4Wtr֯c͊z_Ȯ_5FV@{3aW5nņ4tDΗRj6lD\_3Jc@ui~l fH0xMԮd*G C$MҤP*cjJ_s^}g=QBVYKKb2H=Fw1z{{;Y4KVA= nc2 %5u&=y./oHqFE5H/[¦r=(M2,oj?syUf N+>)/0S0ZXL ]!N;*3lkXoC7hhٱٝzx|S;ߠ5VF $I~2 :Ɛk;%6RlD&Gq1Xrdidgph6P?HK:8g㞂llaH\yr~e#Kލ4=3_6-@n22P ZYX|jPYd=),NS"vadG㲋KցB;vD*VHڰ{ӉGbHSgEQ8dx#QD]>>76 5&p=Eb3t33mS/NMQW0~Qbo5gٓ{R³;<z-<G?۬,2|~Ͽͦ/.t='E˵k2V *ˊRL]s]odsS$yH* Ul]OWaΞ@< v1COoDRAz\M}>##U_`aVTF"^h''dH6߅iΒW)|' Mrr/;}` HZ8֭goGN=5CFq.e*}o ;W/y5?+le7}L%I_`:'13=YFf\5u|.swBщ?UQP* F;ϰ=n#.4)*"1k'8{/]A*n291L,]>TLˮz];XWoRdl-3A99x bŜ13)B M&sv|6ݞ-FP*X)5lW>&TJ-mwތ;4td~JnՠAJ/v5_}䎶68$̉aULme K4n:`h5C'n-@q`pP43fp]CM^ C2k44C<- /VxEL)1M)\/?A9sqTEQqh,U\/xccA<2O%"u{zV.(y?arzk(Ac'AI+b":Z 㮫*/S'CJLS&c̽"j>FL:q#"uʼnbG&9K IQ 3O>1/.'?  ݄AS`Eٷf)=j8KexA@ZNV#%:9x"]gi!kj.У!f42leth*' 9,.CSuB-'hsPYBβ&ϷOH3Aw~fkT5M2= cCN# Lt AC*Uy)/!@"PyKI'jŒ 1{Ylސŗq_c~9HKs1A,)D&z.g%{8z7Rgwo*sV[='ؖ8:f2SŞ{3{1`ɒrnTŠQƦIBqZϝeU##-,7ݧh#A0Yf*26&[92ͺ;{rΘoF`Ϟݼ}?Z˗w҅:;!rd MgCQ?u%NlVUfܸ4-ws#1!ç11Owg;'P]_.+FY8C}{g;dp2ANa!^ԙ̐tl5wnu\73+IWeEv\8N&͛u/}כ).qmVBQHWIvpzHPEQ83g̞gg?ED9~P4n< YښF"* q9iTjnƆi)4Ip2v@F\EkLt55l+FItp?;fٰR^~(!{[/(BL31:xH$Hcj6¥l:[^\ `?A|nlCv.p׽4PD i4٢}N.g(g̅ rs!=gd9YQE rө@F|cT32![}Gܘ`m Z(Z<N}$D2!0=>L\4a}= 9zB"( -zmA|0c ׮${&b1HX ,9kձ,r JKj<̫o%mcv|N%ر">2n)eUM)~@'cq3=Hky ܵɂ׫I 5ٖaoMU9(ýO]u%>I2&?6:wVO$pY\8s]/B5Y;w-m㬻VSSp1)g?Un@9"AG&z XQY&fR,SbL̈́Hē8qێ 9MH R4Qwcw_Êsit._Jvo@ۆ?/V5شlŅăXTpeeqrTt*'DCA&&&۲Yb GV1PcHG>w6f%dmsٸuu>KLF)),(7|?zh`GqYyyZ6]ϒbzjP4N")cUPwbjfVWɥ(MhjGNYYx]f" 06j9U%>{$fj}%~*V//&a6ŒU۷S"MN**Jp由q& UD)Y)f^ț{Ƌ70XpaÄzU(q/ek0+'x+o W-!RjYec9]@NE>&om-6SlKr6c5„5;VaRbfgHhr7 ̏Pq2̂[x-܍LaWPb鄇],TR; dx*U¶-+?E5!#SPKuM) D⸊صMɬYK."R,Dt yTq:cQ.7UYYaFYf&_uؕ:UNٰlD&y\S92?- K$_1_N[+D:tƜ\sX̹sP)+mY'1%;;jRjE勞19RϕqQ_-HA+~楲/HI-O_\o.zWݏ=t%;h TnCS[)MUUEt=B(*s$dX.xs̹iEdⓤ#K[BQ+faP].2T{{7\殗~Wd 0?CcWo$^ HJFu]Cʴ\[V>wT[b2yת9G|dN.mJtȰX {K EQ[办wy/s2fu=JzFҮ_ ĕ~\..@nOHQE 潋LQ.]cp\${,xl|hF38S|%f5Q9Ӧ絜sLKEe9)RGN̘zyLð0r+]fnguVW Ffs)"-efjPBbwz{0+=`k3=3&omv\sz9.k3=Rk֬IMͿk[>UnA1ds :[~JvzZ!P_./]㝦oYhZmHJ]d]K2>N^MSY4O/|K]#kW^pt_#uuV{M/޺~\``!.oqEr 1!*F{Rt]B.]t;lo^Yz뼃vy,yz\vu>b{:{Q}ko;^{xrD(Y(J|LGOX./Դ/$uުHk"#:$dTU̼b@5;)tKF'lp?q+kjBm֭l1M[z-e7Z:t($ća)jp]OcvQ #g 2=5L(cN YܴFYdj`D˙./#/[x_~7V0Fph3:;VV& #T3elٽj#A. iNjuS|7k,p`V1_4UNK:g ed>!ĂX5WN1000000000`!ޛ#BLV0 >bP`!LDS޹rD#v XCWO0@oi`Q2M V>T\C/b``pB 6KBL̄ާF(0IlAE(:oL)AfsF S1Č %= MxA7@2!!zU)*n< k&E.ٻVϱ`GNµułrGJ~c躎iR)F:Om_ɿH ן>F4ueVd"W_85M+ۡޅFǻ8xc! !t/;g~R qU!> ?7_(DPIwR.=~9[_L_+,A#Jƺ[9}P+XhPmJ]:!efz߁e~.kĴ1db\xx &'ˋEa (h8$XmUK?3šM[ȶ䅼2XxNL"B q"AYny.eEIk+SŠ՜9I,єnZR`sq73ü3rwAEbIFCZB$o9sϽȅq(&ϩǚM[XUE>Hfʄe+`5ț= H&+"2x1 Bcya *)ɲ nb2 Sӝ| z[FTh<ঢhx#q9vPR$ݍejb$-W.Qqf/0=D2ப>fmnfz~DFy7;~9"ZFⵧ؈m;5{Gigv2A~oq+L}~ G?Ow~y 'ۺ%yO2 E^RHiz%1j=|P?pu}+*cYAbPQH"*+*%˩ʉpi|:MR^|ENtM+)A(1ͮ\U=MD@g s(z:#]n`z>)&>޿k^˿⥿F%P4OBZNY}'BAAzK:;w9?fd$lBx'OUƆ[h(u3KdTD)}I.sضm#>R%0_yun!` ?{ٶρǾ:A'8+pҎ %3L:kٽ#OH EgU~YWmcr;/-|$BC*X_ %k{("4{ͧ(1us@駥?Dź=|+jۏ8B(mP߰څ")ddgp._Adr[._j mf B1r{:xn<s,XX7B(/oZs:W -GEQeQ Eb{REåP1n2& Nj97l"ޱ9n%+r='fx Y+)ŭ4ɐᕲl!tY֯zZn TLJ9GN7"6ȡçI'C\~U!W? XF nd3lr+1]䬿eJQG;co?+L~tj~Q"3&>qVXgvϫP++ƻ|e)I(st%g:<, ih;; @a"R;I{²B6'U }g ֌"$-/^|7߽lu @Ʀh:{W/f2eR3ʳ)XmN= =k=Oc\S~u.[S?;vq^N >WD`yi5ٶL 6R{)U(($(b(:BѲ5OdH&pog|!~Fngg=Q L061_DAlf~V-+iNăSNEͥyNbryk .ct A|] u ¼r+ɶyYz=d?)=wb 09ʦIgbd@(J E&0&"2\PTllɸ $Ndo[n^H!K!T+y˾Zс~& (S`! t6d$~rBA<8IAFIi H-bp`NAY>G:j~*dÉL282pdQ^^ۢ0ax<@ t #-B(Դ. IlfDt@/U}@Ob:ɥ8H-L$CX“`ήjr6P|8EY$;JR͑D:9<E"Ŀu)l ؑĜU@VQ4&𒎫%>*(flK:4O²|jW=vEFf%0_O7BbcT+DW]ԕW-$H p06И:÷0ɵ_Gㅡ|R':y?А݀>s_k\S4:M@`#t%zh3gßǾb=kwrEv?]\8Tf[;s8tIc| RT M#mJ&iw?9ͷ+$`u73Pd` <@!eva1+@f;N$yÊ.͔\GU~/!ZKU s>Y_ݱK*FB1a6,9f\.!i5p`P4H+$xUdÅ4e"Ds3>ΦؔbflL2d|&$VWȑN'?ʁhc6_$ź 2><@߬rFӉL УRx X2Z}W<n5[P5˖mkȲ)WӼm ̃p mҟKP6PxJ/Z9Wv*4ʉV#ϮR!P!Z/~s\S/IP]3|7Dtoϲ2׃=ft Fuo'_m/?~Qsf/=K0cpS1oh'Qk.U5C$&9A|n>>=:'/18єFxj@vg9^<{bʚ"jz0)\?QF+?vamq=w=Ʒ~+'86a=gj@PANwsguًi%˲ys_O>^Ϝ$kt5B{>oYOשf1j%+ԥi=7f$$]Eںw__:υILv9x^8*wroÛ<~nD K֣iEJ*G߅% ˖}Dn*x''&9xh>;qi:P1%MDJ_1[ouVZyj/i&'CeY .I*֭>DЃɗk8*1t1?)t4bwt{Eve吟nl62Tox*D1Y0kM Lq-, DVՔRu7s[+_+„n7<9 n:8shضWo==՟6ܜ,,w6ח桲ɏ"9>ǵCw7I侟sBOƖJИn>Ŵ{ב1- 'oֱ7b݁9 O]b3ilFI.(J1[y?RB0Qr+_02"g?O~&ԗ'<ƷcR;qO$Xl.p,~c)QUvո|qZJՊG )2ȂJ&S-)}8lf0fpC+aqRX\BEM==I3NW8d RYFCӼ~@\r=+. [g3:0@ml#ǴIdpӧ:Ycl( e:?L`4 4(ᰘ9FD;L5xMdb1cudQ͜־K-VT; T D: n`11L& -2n]=~u4?#si*N,0 Ōl¤=DT FAuܵXk2Ĝ}nZMHL(Nl"D$aja#c􅞈2J.`˷hQ2褨 #0{ly9NZq?>3"klT'B`2Xldrw:˧:H\RC"Q~Ÿ;yo I5t=A:)zrBNd 1@,K RNXtb&P)Qa!<Kh)ϋ#Nj!2}[d(-n3\?HqH0{tϗڧVBT]K<VbU kp m b3u'|ܺX,E5Q~Y% aR 8dZ%">t0TXEH c ôE1Ypf吟4J/5)RXnG(uXiCޠq( XbTr>}0{Xb -l=1/5 챓붱{]NŊ 1<.RYu֯kg~A e@N>L?)s 2>$IfZϾx_~WPZc1V |S869o_i8p:_a,?'@ F.n4H%Dgdp}H)! 0NX!,حf9$&Kի 1N!)&'He/2̅}O?[/' sw@)%$R$S|p rmƜzs&b>௿z'Oqٻ >{Ft2Ş<{QVsz.y<&!$pTB[IMֲ*LvG&V$>9Xg?r+k2~dJ"Fth~%9Ydկds)ݾٰ0Nr\뇚IHCKzHƣH =0F 8`Y?CΖOrBdP0D0f6EimɎfB3c 0<>EԒŊ|ƚNpu oA&vq Y)iXY%6I$2֮#ǡsMEe5^}gxTWDSK;fM3)a9nXMq dylDg&g5g^B*o?g}m>`=( #b/\Eϙ13HIʼnzkvBYxQ=JLq?oZ/c32AW^w zI nkUb$-~}{AY-[/ܿu?> B&DS^AVa6MCM:}G Eiisͮ{W`ҴK)x\*0r8vxm>nkn3u;\.z.3.˼F:?jM2xV#rض<d,Xh\!TO ABc G`U^2d]'Z0UYY׻:{[|O݃mö<ʅ[\[ϙ7r_h]P]ek/y?K(poh7ksm:ZKTky|UMqU^(W"IDAT[Q ǣk%dxɾv4 1=T WtVs\ws2]_Qăx,ju-t]z%e -r^ewR|F|Ȕ#G*Y-L,D Ōj*yodf5#/ nH:p⭾GPVfA ӽF(&s&V:/|bfΕ#"g$!LF8! FtK#A!-N CHE1, T:"HGF;200x?:```py89t#d{λH?~@Q>HPTUE5h Ed6a20A\[꜌,K˽b;c?{Kc!H st(L ۞zbC ! uҁU-6c/F;200XqfzsB TEUTA12,~PT褥q,\E-I"yS EA$S׺VzݫJ!PT5=7o7 Dһ"e~>Q-6M4yEe`-$HӐo4ŝCUu9QºtL]C͎sYGxMMx{Օc`!p7g &<&,-(ۉȌQ{^n#8ʳ=O_.!bS,YsaX$hIƛ2FL஬wpyF į"mu"3s$$%+f;//SA8Wcw>Ri:ZrC3TPB,^`0EVQ.]5v׍iKNZO ww=br }-Z,@wW7RK(d,C!2=LWaJQE.!7yi˿+3?W''tgX2X-}<=хB}~JHxKc"ܾۚ?9L*s]7uV' >;73/p _>~'1.ovŨ,˥^_P]SӔ1_F'89DӉCLX#C|3sER* ܋MxO_D_örN'">EߘtEׁPTf8~dn| ֱSb 6⾢V;$p6|>TJٳ뭮  hI.~y5h3ܴ6._NR"T.>8-f\YVz5+\uHˠ`mXiM@~$Ta _b<&$CC̜?HoG~&eG҉1xk;ӃzśiL%嘃x xn A<;ȹtW[jX|Th_=ଆm'Ay]1:RA*4¡}<.$׃*kkjxjs'2,(eַ"{YDʞMQӂb rWh1QYSMAg9_/,KЋ/ҝʢ< ' 0VSp .t6\cՁw[!'d-vb8yܱguԫ#$C_Ss(.;KDŽNYu97DZ *V~Id1߾eyW]K o>07n~Fv,w0@Ղ2"64an|S cvx׆R&LNk<5C[h)dvR 42^Ah ~4yzri~g|ɂŤDcqtŌnK+f=E,@Kt ݎfV`Kڛdut<|:Ys=@x2L4ŞOnUfn ł| shQƏcѓ>X19YggnU5!}T,cѸ1~8>_|^Mqvr]&#GU+џ| ?_XNeh((g2'<<&*21 Ëffh]_>] Ǐ2Q౥QTlyEXF:0FRҋ^asOIU?HLUT>?; .x{~?Eǂ"좬‹5pU]|LX<祳RONݚ[)4xnvR~ŵ25C_O/V$|ʴ$cL'PY7_^Ce[]JnL1zG~0g& fZRw #„fY|ǎ1$PTNAvI- #h2݁7ʏ_m"~;~{09q\U{V368t7k=H]#4;I!Sdj9`J9KM"HsS U,7jda*0O'wa]Lt2K8yࡇ^WYi;uCG.6yܵ.G\"Lvѧ3A*ѱvrNlv^\$|쓟b},= A[}3ܹ"^G\4I9^.n$P<73M:=gH;+-„NWyţALu73̦4cx0#1Jn:|>,=3 !R'>BxKc:+{8"<2zqcu|(C~k:D._6ńo:@,3|ˬ/b6OzlF [%ԭ\jr2)_YG*JPJ Bh'83AM)"J+ ֯8ֶXWJݲBk\QKGJ/EKr9غUYM!c8(,bu˷mPKmM)֎QYB$&xg),Vc7 cbe``pHK_b8\޿'=5;(Tyڱxg̮\On9F+K/, %BKj9 EI'dPMCuw}?=dz?.?m$Fzx>+/!߃n4g-<^j H) sfvB !rI~8?dY h  BA5)jc)RiWTqCꡪn5װ?*\_$U14bC_cCAlЩVoۻ (;{1j`+2_+@œ?qW.v*Btzb?D!Ү5x< ׾=:c(q "뚛D&<TT#R* 6j2N BUV0YV"3h˭c^RH)u9=0c_w>bKV.IzSI:T޳s(h⒒R .3IOM J)d6G32E5sKе8#\+T@c>d)sL`tRX-hwRTTy[]&+|J+r()+>s+2 w6RGurCO;Z  "%6T|/dۯʒYYH ff%"tܼLW|XP<38sa8Q#:E55XH~IǖtVqCxͰI`o!歑Y:,(WK"ZX,ۍ&당x83AФD(!t9$ZY_hH֏[~ ň Aoi&]˸oOKZI'#@KŘQSQۮ\!dvЯ"Rt7cTΆ|ĭ=c2TH$($gG࡭zCxRQ\i>Nx|K˂@jgvo5g?0Y.z931 i> )-Rby lN$p$Cm^sB)h8'l7RX '3ʷtp֔ﺦ[|(-ʹW$ZJ{W#MʺD cw!tIvVßgp[>G"F{wcLͦ 9µ˰XpLb%χ>vw.ѓ1(.dૉ330]pSeexTav "(љU58F3,SHC͛4(؜n.IB#mZ\V,jz-8Cx$mo3{wL84 G.MO{%Ō/;Պ٬"pi35tPG(-4ŔMEM Y"*%:I2s=fM]+GAFs+ƆHdMm6Hfp52RCUwŤ+V8ξ]$bsv۹L(}HĉHq%N ٹc'wL׶O8mv/4sq^;xE7$‰ӗhm/Q̎+qY5!J-X Algݰlx_;g!@FfH05FZrtd'1_Jxb#=S]Q"saRe}[ȲYsmSϞz:[i:E(nĺGh;!$&z8~wΊ|@@ѽs0>/hzBM!3Lv}+nGZ|?K,^fvJn[0"2}EBAvJɁi .YɮR̦@N5úeo;Oi+ߎ7ٶ!  l^ŕǖk9Md6DmTd޿1c_홟Ё:Ul"c{y ,/ɩ^NzlZ26>BRRŕCau"5/'_oJ++;P  p1 +MIZ'ffRRVJJ0u'_>֋9qo>;,B0~=Kδ~'Nq1:&Rݺl/E~Zohٺ Sy /6qI.NYfu>.oJlc:䗕NNx r$Gxӝ8XVYBaI9y8pkbv3Ē*fG^&=Etlgq!RZN3:#wz;" cмTZ*SESLOZF_!F nΞmdծ]u(`qQZOh!{IzL 6w~8JW/Ǧikt4"+ClgqK8~Ǐ}m,?,-{LCevc/YU%>< ]I:Zb0`b۝Y@b"Gd} ps dNŀΦ#Wu <W.gR%$|5Wk̸M:#8BTPR^β*|DQBɔBbw[ؙ$!fC1Pq=8P(RO%5ÍiCI¡؝.,FO:ࣀx$D8B1[p)ID#qRq8ج&B~k:K|ˋ=]PlՉ/N<3pu.sbǟ}^nd-Df9%c:=>ӟ͛*]~?h|Ye.r. U2)3Rm2sن?۾ Ã͹ )8^nȘD`ɲ98vY>z΂PQgsY1d=C>+X|1̒M,>+ߒt\3]Q}Tc2se++ HɊo{w$vFg@f\,V&̌]!zAJğ .7j(aEJf ))svDd8FͅU۲8aP/ϙOZ-x% (0@cץ-37AC"sz;EYh/)࣊"-+,nwnn`k(BjR"]KUEZ~ȾZSA|LW:rF600$1ĥR3bv+RE[b$Hu"E&&ѱ`dQ.'@ MƚE1VBhRpⰙ>O@lvI,Ym.UQR&hyžR*  QQy兔]_*$89I(adu.B &H`ƛêcMƔ#2hIHXu3^+i47Xܶ 4{KrM%2a<_)+VדM&Йh;ΙKFF{:2pǃ,X]D$f97y{5n{:k-6#˄•(%"AH5Uy?o``pc$ `XPeVϔݷc50u NbDZbD*BY[ٲ Rj:P CıV\q gӤDxXG=wxo#c{1I AZwiY.9NfZO`;%(=-'hSXE]y@Ořm'8ɕPs(SQ\=>IkEfb @ίdYMq0m';-SOl}4,K'H9u$q5:p{o5Ļ) {֞Qt=ȩ=DPKq$>ls' ͛- ~$sb)ysU2kI^cBQHNwW_ŶdrG~]SE$0Ñg~-ZG" ^{I^|)^y)^yi^/xטJ͖P~w> ovH@ɭZEmM>xrvo~G=@ GfxTc`)YY_tӰ>g{*_y5C)-3TupL;TB9,FS300xW}aųv{nǝ끔b_2 =C>W )"]BOL09t]"H4ҿ4)s'(=Ep&sڵԯʶ۶J3r$2>ù~'(iMZHNsW?_&f μ<V"A,/>?(=4g[ѮX ӝG< ؾg>^zB:&|XNނ޶_=EDW>@F޽.UJly\T,E:yp|#tlD_<.Yt h'^z'wnqcL\I]YeK \`qtu [g͢Zd=g}lJ|~;5ٌ^:IYY o6*ŋ=e{gF5 S3T$;fa1v:ç_l1 UkyV!ԴՊ*Z&19Ty絨 }3/8+djO\QWލFÕ\#gzkWHE1݂I %y`,Ϻ@~ws-qtd;wm.RAA)%B1#L&]oEe]D۱Yb-Z ."cx,"rPH\|Ϩ*(dIs#16Oβ,c-^NAzbb~tUƘ={(a+ [qEA>&wbXl %=F N3#)BثyC}7($fdTez3ɨQPN}V1 X rWs,/t_#`d 0DՊGji".ճx*# O:̟ y>'Rlӣ9Bȱ"RܲY+PUGxL9+GAAtmjfZ-$9=@dD1a-*G:Idf swKE:dK;,ȇ++hӼ7w#(sSWF_l_.`|mvr#Dg ?ͅ4;I𓟟c5@צ8me.6Djk^)8C r JVqރ MRoUz "8ñ~Ii9[7aUd@0_Ԫ6<^Tdh|BA3)-tvjs fSBE44m@[LSѤD0q=ߴ&;i׶,YњQI59pa A@7:W 0Lz3 ޻Z{z^J<-%K&Osh;INȫ_E}U!L7~#~87C{_yhR(Ć[xgCvOm}G~^|i7i7kH~(3:9~əX!뮹rO٤DS6!O/~ADֺd,DS*?{᳋LTOݍS /~ʾS#݃Opc _"1;l?>* riqri56a!C" eӇ_GŶfna5.EG'8C<˄M db=€,gÖ4d*~_D+[A-0N1 n%4/ daLb\3Er TN3+Q'IO:٨ePlN4oJ&%lsGզHDH#'DQc 8!5F:.aLSx5\wu#Gco#%322>wo A=Me5 AbjV6y"&l;O~#2/00P\sKЛ" a ]ڔǏG $ō+;rT.Ʀ# ~ 4U_TlN)Ҙ& vyd<+Utkx6{(v|%j2rf/Ir+T$Eu-fl3x5ylza+{+͎aoGiIR{m Jd43 S)fS?Yr'//ڍ+9mxiXTYBڵ4_ + by~?a=AǡIu+Rl \y)NɒUTjԭb嚵,_[oHthHaD !C Zv29 ګa&v+wcφh,Ͻte,dĉ<]srQ\}ǭT9qUP_[YL4X˵I]Y1LSdTv|T-(?*jaS'`˩ncb:v9M( CJ09|3gژ\q^5x$(^n _4X ]~~4:Bog#Jpu0݈M3Eb2Ddbx7i"ysbEAh6~RftNΥ 8t)-PP*BՑo^gFJO)}Oܧ%~_Ww H'W0r/w'#irxA@%sPh0=o1wruG<ɌTi4uLML?z'YZ۹P |Ń u*5xb:ry@]˹as6a"7PHt4E:CV OO' <8lx]@Z^w=7TyWHM l4YlN5"Adܺ+TwHS"UMPv4E M#kh?t|!\M׳zj9L쩸ji"{?n0 ^KCh|kaӳ/ͬ%-m$WD-Ԭ.dY\MzH" Ľ\f#uyZiJLJN %͉aF郯S@3@Uj7`$Ü|'SĽWף(!73 Ui|۸ _d*los`k\B&u c{3/u#Ծ=(WwK!:63i{i7nj/t,4 &Hc PǖSٿI#l6%Fs)as kq#y]~57 x}5ÓvjXk_xY[,Pس$TAjv8'~S~ohf+#_fp2jv(NAU0%- uI.ww@ǟL'1i1>dBEt`sx(iXAMRiLc=L-=F8j௩§^SC:K7i K|/ws|gS&@R"(Yy7,-m:ptwܷe+Lwk5_OG(*yeu)BLtfv&JYqnƫv Ld+׼O14!q^ilyM,+NDDo\K4 {0]E3c9ج4ML4y@띕&˃<sb f06F+4Pܥz=>8ӳYZe33&"]WQX6$qsJ(",G dnL*:C_MUU!TX\m3gAH3Ya OBt)zR "cp&+U8|fU`dpXāS8V :EA( shryHōo\B*'zIJ֢Ƕf*YUC)Ia& XOwJ<  IWbW-G!0ӴdR*:FUU=~'ZJʜvb 86S쳓Ih6}>i3vH PR^AIE%U ("s [POOEGˉ)a:NzQ4H_'ѼE47ѴSb5TCʏ*-uٟ0& 9v`(m}y9('ƶ6ņ+$pt:iϴaYՋ&}'x_P_ׁ@b FqzM).Ȯ}"" hT/%?mh.; x\u;?}};^e+quUWSURߙtk'f45\a N@gzSvqxZbJr(`Mmftt{^)MM1N޶WOt⥛hc8(\Lme8p/%>Eozn-> GCv=@hrGY#zi@% ue_f> 뚩̍s`>&"&Mj y)N~m]LMNM;)(ibLshKPhŅ8^JJˎHr\Hec;9tq#)c-ݳT\NqzuF1Kpۈrpt  KIt#۟xK?8\(izZrxe[>M[&hB׭C;^ɴCzq"'{f(Yu/d,ejtORV4zGmBD{ S-&􎠧6HnmqPz58b^"!#Üc|qo!AG5&nBQ"]`Yzw Ļr8gL,*p jn۹rcM)eA_! "tM EeT 0;M[EMKuH?ȡ\oy4R^Cl!Ҷ\j)8ǏMBSV]Ce-`[X]iP8vQZRCcS=x$X^G]Ett! zNJU5PUe3@iU%>ZXXXbQ|}6x!bԐynжG>1ga> uUh2=KTD)+AU$^bwu56!'Ob*v%s]5}$# Xk?q-E^<};^FC1A7 Opd&SkObxhp͛KiUyQ=:Ao z 6z>CCURKں*\n?@E~:80084!l*(f % 1A[q`ޖsĭ &%6 ۅ".,i+ I)楫KAf <&UAɦdd'2af͌`P2҈ӱ}2V^]}/ k3[ S[U.2Τ32!Re#4Ms^g)}ާ=2t0A((4 L NDC?6/)v(~"9f䜘Ð=~T2]i{gcS9o r@U2as}uad\9^K"Å#uiyq?TUE09.>﫵P B0'j*˿\~+z44@qN 'esy J+s2 f}i9F>&dޟb|IR]2sWqn!\1 >dϒUKcηa/YP#k\i)#c\Ne;*w %7<,;ΑT+Tnn @KL217'?gFo)ӥ c~%[` 3bWRMs|s@*Di\,۽}zݫ T-&!/񲎤q}ͶR{फ़eڼ e+M%xS#yq¾f!%RO#5fm Վ-8#07Ǿ$Zo]#@ j%晙0q-HM"٢ozz $n7sT/.e3]ƎmV9wq[g.;^zjь(#u7BGyK~xIN361Ndrqr [okmAF ye,*w'g[>brl\6O(8qn ˪Xi >$Ij6f%'Iᰩ-#l%a˼)d[YL\eտi$,{3vY쪅e%[|R+$ "?ZXXXXXXXXXXX1aZٻ[tHJb=  Bl_F-oq*qo )`aDdA_RIEfj[[(o OYXXXXX+4L1<2aխ;E 3̆f0LkD`"ggE,?ZnwL]iuDmIRqՔ~o]Gf J&22r7/(QQx71 D84Ým>tx+ذm)dfӧ +׬x_B23AIZ6T[LS m;9`j4D0A#'C,0nh*aeT8R (N5"J*cFv~x3EAv?m ]ljH3C93Ey.&IU?Pi9cADjjl.<{rl3ko_*v3>KO>Tu|jk~OeV0DOLvdv?ekc]uMjj(M@U+fpJ `9˖玱>}a+A+$㎔6QW;hq[fc??jmBjP8np;a}1o+|4~/i\$FLn%4dS= S4H#?/'YSd!tOvڵuV}%x[i'y4Eq-[xcr:T\;X8E0$yՋО6n[U. Mvj=֣8:x=7T{^zGpQ] :KkkR^ՈߑۉN?" 16OA9+w*)\ 7ް}~Taz;{iG)%vo)uU:Ξa&|W.֬#a8y.P&eQMC 21]g 9W@0MhFcG9=8UK*npf 14iPggFT2)9B`gff6y!ǥa1F=A4]݃$4? LEbl:WDCC ^Ld*%i(8|oǖ3JSjYL 12&0)$ŬF4(,p0T4VaW%݇yGgFV.X5,, k| RI)vE#c O UQ߸t0I`)ci]Պ޲x}jCnUdĶ&-Ci tQ~|)\Jc()FUZ9Wp2y'inuŹ!$&Ϧ(#7&:.| SS8ڈGs9D ,ʣc {WYGj1ryv.GQ5^opA~諔ܸ 48<>T}W_=ȒOn`zhd 5nn͖YLM,HזyF9?ɢ[X8enaxL@!Z^ :fqI$Xqc*Q^W|aX>o[U(*" |Q։'E􌐌a!q="StFԖѴ~=U&NfK~GB Owd@h+q3l{6=-^6:L]DuiLO a۰U+`d:L"F(*v UXXѴ=2 L3IɣPD}e{[v4IDgf|EE&&x7?g0zGfp8l$&ݏ?}׼v^{P4B(QEDt:=OGv09"o=>F:y?{}$8)vaW8Ь ɩt;yO1>hH#l0G_4n!ߙ o>-=Ēi_+Dr'+{?2JGZ*Ahr@-,.IĢLshNbu4I*2KcM7CB#9trmbj6mYXX>F_z]'a6 bQ"z>5Rbg=rd-K.CSLHFV ݍ#$:9\U*#!Ӗ= ]= h~̌HZU>ʘRi +JS>H(T iv?F)'d&%&M_ *:?fw{>sA{U0 i<}xb2­pΣN,m"/):Dž=ȡ"<3Tچi?"[dZ ,gNYZ4\4lXMïϽ'M%Pn:hk9i$-Gv5D(@sܹ%TҴlA&Iї7K]c3 Kةkg[B@:!*6ƊR/RQ{S2vXo~YS<(3(ZXJwj[~-7n?77qIBqD:}GѨ]7o+9{^9xhIҪ\ &W rlk_~;ڦ$B;xW 16:F8ƱRs ۨ_kΗ ʴ*9uTl;ヒ K[Q# 'ʋϳe;љiSHUP$Kb8dMsZd*F*$S4;N,WwT@(3LWr (ӄ?pu$)fqI;!b@⥨/~ 2ձCf18_!`S4IB2y624y87%Dc5qK+v/ o⁛#QfRH[WO?CJLSڝ}^^/ M([Kky c՜>ApKdS2uaplhR!>MJCSS ;oLrzF9.@pS[t*ζmY>ʼ o?˗8p@U|^\^'a䑓`4 2McE,,.@"y,[[Fx?]对׃FZ4wM?[S|꾭,@#ZꛮgVژ:txn)B'tl7qO#R"T'%XoEvlDifRftl^7;Pl$z2}Lix{]؜Np }D!># l.y>/>:9L(͊bjdm%O=}~4@T!#vo7m?_Lc+' NfQϵ5P5n<^eC)s[t:;q:8}Xd2 q٭+;B`WDM9WHqh|si=A2/+DJ  31e}}4ٹSqsoO\W@h\Wa#tw1jBة1| .EQ-,g6a&h\mqwi3O( VvNfdfT@qQYUˡe%+HFjg65$a)/* (/[ܮKq/l!r9rj<f|y^E !q3}5W73mf`x,_}x(rJpDNTֺas}7[CG>BtҪeaaF:fiHg9x$֯(GגdR*w;2v?XߌoRmpv9'.@+DfFe*cqfNr rF g3&$X#{+1;G `NJndyeNFbfAjȫl?ONu~b{\ |gيeLű錰"L4M$4勩 *.%[ 7&! fgDu*WQ}p SQѓ OcQ fTԹ#QL}=]CZG*ftR(zN3Z7?_2BGY&㔮XJ3@mc.]GP&4M3 .rfILd$ ztۿqORx1Clw Hdl٤U]bwhnt7-qңjP WQmgG:gv6q1 \\qYDfՔDnd+I(IMߓ^X-l;߄Dr-[QzNXaGD*D{Y3b,wguzM2vO &iαB1Pd%M5I|m$G~L%BĆFЖ6!иwn1BMeC4}'v+\/qӊ2&IQv-UܑH!]6@b \x[(QS]3@M&fҹ<{_^AG4bIN"K_=KI pe^nėXW6d(%wF&&& cD"qqPd'nll{3>6F"4I_k gWaJFi?|_=W7x~a]s/ XN)i"\s>ưnYGutݝ\uGcTj*gz/p,]I GfMϒtqdƦ5P⣬Fn[~~cf6,2}$iƧHOMHq,/<@Ͽ'lk䶻>·gT0+31=Cd&N(e#  b6&`s_TS(@Ia>Ÿ4Z|ܑb'HM qL;&_O`]ܱnB  G,  1035I$c1&'„#:S31 Am6?K77Sj,,,.aWIt1֟pxTn $}6cS`pxiNXw%LC߼%m u*˜h]룣ײ:I8Sl <|$<6DDɡL~zj6PL}W7Яط8NkYYFڜlfN=rXt_o"H\\88a:OšLqkw aWĆehIZ)ƍ+SJ4nD4`QA7={|E`RQZBUU^bLGM *Ӵb =8o {v>VNzuJrz)x˨.M@q"6"=ŰhXɩaڇCr<RerB2if \!$3=tE//n&M1<xf:*r$£tLs R]e4s|NO;= WLUI. ]DeӵPz/TSLicz4AU7R&HW+Fj*^0M0#~T4Mk1M HCaUy"HfK'!30#Xr^l#/om;/ǻ_jmem$BnW=/*a*%7SNr{uHeh}x |'$dFYXXXXXXX|Pf xY4嫰xPT dH Ҹ ]}QcIfV->\g1wvKNQ)U,Z\bg{P=Qܜj%w2maaaaaaaaaa!G\$=`m8Gk?(V-/4as: X - %oٿd(`X-9G hP>Α ^Ve儼EE~C>y̨].<6aEXXX!o䏴 >qXX\1>NLpcHߧ-51Wcf-,>!H'ƒׅ2K!lv=U7SQa;|K`nAQ%#m Xwb4x H&mԮ@(b޻}-8[XUIHMMf0I/~IDATDx-Zބ~H!""ӤBӰk L} ]h-;2Z:4Y$zZϬ=)/ʹυ0_1B s\$!&")7ɽk*7& usP Á9/)gѢ7l3B($cԭmK7@W/\"dvl{)뚸D_/P9-,,>4G$e+{UL] E ]ĢIl^R& sFPi&< 6$G9ux?M&a-ZBCUiuLH͎vY-M&<ՎdEIx>")ҺF* v&1tIy"UU/jB1Ξnc$_\ò*<\6l/M4TXo+v$3Cgٹ5>C_y"t]g(mZϺ\z" cp2F! <^cV"rn^n\UM}}>t nmoCWҧb"fѮQk*pc՟ N y \UiWIE}E#+=K};>K~a"Br,O>cQmEZT`? 'F@2W^ _?a]H :`1l̲EeTt~T~4U^]Fr= Ԩ_3{˵) &OIq!\JJ9.3}龣QT卥.~on V.5}>3klxC@&۾#2Oy7FA3':=o *ZYو P[sf$Ͼ^TOYC57SٝD X+m/ x: +ܼowbZ#G Ac}-,p ׬+G:!w k֭e5j55N\yT/J,@rG+]4x8f/@s 뛫Yr= S<6fi25ɧZ*Kp򂣘tzC*.rrn\[p%=^d6o+k_So +j}&/1 R)oN 1ױ}$"S")<9ݠ'&LAdz2^x!HGHtJx(fG1Ω#\يGBC!"GnMdrfgē) lrc"ٝ؉ ˿`iLsƈę_ǖ l fzjDN0'KS0xd^f i:zU_Pf2;&L#3v"^k HENz X|ԑzNqX2F 'MAJI:%υ}N¤ ۟KF%un;LNA  iQ ǖ†?ĥY # tv.#PlT p2ZKўèy#ԬCe {b3n.͔/(XVωNGqS~}HS( O׎nZ 0Ib|ՃRRFדtfd eMRV.ҦBcSvnڟ>?7)T.v*\Z*~s`7'·LsfBwv0+1ͱ-OqD/ k8TP<4.o?8ّ0%H#RAfB 撛#FF|g~pn؀1z.+(P0m}&uj(c>],{ q9C=N篭'>G,ʵ^!.%_Ĩ\-7^W%sV>PU~@'4Fs5e榰q \B/)}OJ쾜=2 LE0yǦ\|u%OȳLOsPM+JqfS|Oa[yxǧe$>{]pbNh76׉$C3{&]w;-DIm uzngG[ "qɦ>IO8 FxksXwtG. 5l%Qq2ÅW;( O9\wV \Ǻ``z/'{0$2ӏZ݈m4]S)d*po7e{D8{cI=soܹe Ab1G$gZ陜4uq_`ʳ}z|1^۾ {jd>C۸-n5Ѻxth:&H_}LB*p71_#ܱ\9-,,!Aq)X3?|}M,/,D6\yJÄ}{NjO`5IƘ ۨf \)T%8N Ї&H~_NhT>RQnOTDlga}b#F).*$#D2;o}5_L္XhP4ȤbIzf~~a^8ϗeKT8J_f~kJl9Tbbp#3+}N2m>PPBFCQLHA+4T<MKkz1g~NFc%ۄcXO"$iO9ͅ d0bfgvDFU'UM5Ȥ ;,NͪkscS%ng޼|z's!2A0[XSGJhxUQJFZG(#py~21šcׯwEfXк9~o7~ gWw" ._Jq: ɩC8z|U0=wtLόplAFMIua]O+ܾœϾBd `1O~oXC.?o~4FOzt?㉷]B2 1`$T56"4H$=C/мFnv޺_T %-|=_%Dޢe|ɟ.7sop4A2:ũ'8"xz'#SSĦ9I X##<Ӝc&'#\0t4c1T3'y㔮> 67ڜy#L,+#lbNa0>m0?s2MMr`/=Slaaq!8)35qjW9{4;duSf9 T3% =[:]h0əXCS66J~&֮+<؏/g`&DŽBziXj^4Uir'?ӷݶDҒdE,mktCƒmt͔zT./P8/q,n{f0hKgO-/C1{-%Mqcg8U,|+>O*7/5e95o ǶNӔp͵(cCPQVQKUivLZwO+DT'^'At|{[K[r=[&kKQpRI.؝9bMGIew!(|jJC0qsrsޭlPUh(BA4TU]T(n_svxͧo(†aX|($h;x2>ǍBqJ 0*2o6w`,?уM5f9c| fCEu9.Y #w\EvZ)#%!ao} _;2E 1E S\9"x#mdxdiGQ"Iy$QBaUH#AuѸvwg#?b:J]"@ NCb)+J7,g; Ԓ&,ay~Fd@S\vBJTw>*Uz/n)6;ԼmP4l66+&1eBXJj `Dkoem?0ϦB5b*n>ΡIX`&"LEſ?}|O`cpW"ʤռq3P]^ֳ=̆VS`q%f2ı}')_{33E!Wt$F48`LI"8Ǐˮ #4lZE}H *No KjzR. !RyK'.,s5D&<#G N  }^lJSȔwԲB(*W};V:x? #icD"a4W>~KtGJ3˫3l$!K.$qd{N0߃a"ɋWISabcq@g MGѬi3B';^+@I)4? %3W[2"sܱ$HS"Ȍę Piaaq 45?>$,BbAJkVq"-/&1gr|r(qq3;1gu;x9-WotO$2BAxӬ]لR40 8zqMKײfj^Vu'f$>d2MQ(k[=GW(}.cp(A|zTIbq'`.`\mp #dV0cPP$95N $:Ne%bsPjޓ mtANgA5͒A =#味d13J*T UKڬӏ2xCd,N]Ksqزn:̡=jXYY,,`sP?#afw5OߍAF:H"$Scøis^D"% .9g|tلPXɉƧuEg :H!MFaQu%A9GLNylY^{e{/=rst=K̔q6eM (JF3vЪ SfWOMn?yű3]tdx849I۹~lZ@r!Y=^y}E kQgq:-Sui$IDʝ0;t]'C,߰$qHɁQ")CS1:fbugUwӬ>FT\H;`a7޵U7LIyy1N;#Dui褓iRtf &z:M2&mHR]l?xdڵ4U.8v-v'ɣwU %¥|/ '<+G'RFFgy@97t;xh/I$:S! dT:aJ4II4R:Xe+{?qav8IkM)=IxjaAFJd"19hn:4G_fy$}<ZNaLt0 R4z"GxZ֮XNsE.M-&/fk;9ͩch2O#SIR4d*Q|!xՃ:yO0:B>:;@d6 I|YW-U[f 5 n{ r#Uy"A'~ʫ FKڲĉ}#cSz5}*UT60s/N,TkѬ.B IZ<) CakεcJX~ ڹf *!GZaԥ86nl%r˚ZlBi zAvcc==A׳(hCO&2 ЙSd 5mɿobi͔&wIKֳaq.Be?-aR Z |5T?-U-uٟ0%/vTMN/~މq:ϜĩVN:EQ-)+ںzRF_U|E|<aZJ<'}tɩiyUSg8g;qJˊ)i?Wxپ4sB0޶:'m?ÉS-8quWo$OUMсe`"ɊkofmM}'sQz'S|ri; fnT=tvYizi9vWmcۉ!JI}QѴ|c9ueŌ?}(.x}i6ƦR4 T2SgA74Pt˞=$>0&ؽs'mrY\C>~K7oe]}._ 蓽h$b:^@U+zJ!Wr IzϞѓuv͔e՚,.#j/gE{(K7qkڒî#=DUul߾$6 JYX''Z)^(bqEɞ3FXܰBhEV8D͉.f Tzo?+[ "ٳBj)7mDY 'bG3'O7$P\'?<9}tuXW>Nf vV`d+ YBM[/BUڏMQsu}_$tFɚxUiFZ2;VqR󐳨cB#Q 6@Uc;jv>C9vQjoᶫpϰؚcsCbacmO2$sYr)T:j=MWO/Cao㪺!Pr,ܶe%~ɣN#%$ib z 6M= [g׏x+;TeDΕd!iҺٰsQ"iD(͎*$T _M42 Tiiڰ۵>%cHmJHUMas՗iC"ݎ*@J#>yNFwMnϔW鴉PyxMHՖ9->ꘆN:^3l ̌٨6NǼ&1٦!zn Csc)Q5vۼqTfnCEQBf޽f|feS-/귶7eaaE:Ft}#?Em3#@&DwЏ\ !F*DʼH= 4TA@J #A#t 8\י_Jl`tŸL@N&2! 4&ftNHIIE5Qw,xꆉjY̜wXf~n͹6JedHg#|^Z[q`vUzoKN=䃻쾄v~hvǼhB%7+O=c'l>unC= !P5f7n!˕E~Iš7_]pm-Yd8NsIrsl;f_}dcC0~O2jxc^^&M3 ٿUPmv\ pj8V_9.WzyEcvT4 :1H( cu~ LxctuɡxK0d:o|Z0=MNch6UؤL|Ĝ#&[Ɲ#v\9~C=>U~BH"C]`:4='c}3yzYXXXXXXXXi4N,,ހ,R*sxOG9q K EOzˇ)%CG/8A$xh%e&|X o9DK$}?x.|xK#Ra細!0ZlcaaaaaaaaaQB)4]ކ{(@q EAbz=EEQĹSBJFn{n$0t,]˰*s i\(LӼURO#˸yBôkEhfe])*؛N%N3[#PDm+1wVAJdKIJ ;E)1/>!0R1vS[_[玙1.pQ] 8#Lt|yŔPΟzlQNaI)y^yyF|sj6m^Ge&B:#$(K׳nqenό~Mu9pW#>C#iATqU@J:v'Euy>Cwp-l]_%ba:Z1VЕA ^}ΌJfyk,D\kTS{˾ Sk/Ž.*ᰂq|ox1>_?i ܒB!=O ٟ~cDdVɥ*.jbqU'/8'P ){zx+XcϮfYX ~lj\$h陛]v(v?uMK XR3'yۿ|A+cL2yp躋x)&_!E(={=Cj)Lf}r _e9pc_b4#Юm8R~1x<=N+'**"to{Ѝd>MX\Dz4ݱ r|}t Ӷ[\ l*!PQlo%K6! <Ʈ=y44TEf*Mb3#tvh-e~q.2??;Ptr0'Hppv 9_N۹aE9d/|gY%X?zb>8k ĞD/?~ +tekٷcy>O"|YzIE!>ɋYkְaY%''@U c۟%_6SRS!Hݹ” #t-f֮vm }?h?bǸ+Z;Ͻp8}=W'TYCuXGq፣$t9K ;ՋZL~üGEϾI2q!6o`^];88gηs\;m;XBgA~-lZ\@M}||1,: q~IN|Lk=d};Ҵb-km`IQ{ΐ*x·sXz 7;3??TZ`Hޗ@Jj[ł-Xs6ꖔ$qOߞ!$(BK(DF/5n!3tBj/OY2} .S3!9zR"*s*@O%ȩY$ KW~=-`1.(@:uKhv'αiA)tzPR .Tn-SJѵ N$jXZ復PN݂N*FٌbS4i]R8~?s‹ttM<9T6$4=R(*bv\:qhTH¡IB8ROJi(ծc8#ujRSʲMf]T)xm }j4L dޣs_-fjgEUTr2]}[ԙ  d-sU]z2ne`/@t9GOe.s멸ykf{n:ϖ}H֕2pa駸| ?*@,PW* [g.ۙx&@״f걼\s*] TE劖%2nUVLtPe#2oG?=ydac'%vEFLӵ ?&5s+x~\;_;\ ZDjv`5XO39bIU Qicc I-Xh)=Mh>eWx1+ BDSdǀ9 :e?=뚱*rVk/IL?2nSiJlbMUzVr G98TХd%h_X-q{qYA5dY=r{ײԁ}G73PF;Pdr}B-nz' B)*-[^qjV.H|'ys V>m+8ǫ/qgr-ҙth~y4-\=WS4+1KhrXNj(=c*ܶL|jΡ!"4n  2WA ig$h''F4nm|PWaN:͔B(;XE;ƅQ=̆"b_8s[ ^nD~3޷B'29Źcd:!] ]t9KP//~_8[ݏGsNϥn&BS؊Y[:N{aʷ|VTq7 )IIܶQJlg%YD%Μ" T{q=+40L~(V6s,}nWJ}xA7pܿԋґ )%[f+'9BO+'}4O߿1?9-|꾵xb`'=q Dw1-fO¸ʖbi`O҉Q7 Vy)eٲjXPS"KL|ZZShge46l&V/?6AR `v JQibOQhz5(z(/|qZKjii*G)e<ϲHIZO촬K?o:G$ @?ñB+=*lk;.e:f3-ܱ{vq;@Ny +VlifÅjPXPaͼkjfŒe* W_< (hXŝtw\" _{MHGsNnHGOo#6G_(W+YQ_p@IG؁_ƣ0 y|;_ʷ8T EԈ`}[)]sIM%ҳ{5ҍP)LxVdA";M2ʺs*D,wϗ:xĵ4$# LN|xE+16f„bǤf=L/X'1N{{ÓSs:1 2.$T,6#u۸e)?Q2ٳJH#݌ju .b٢TAϸfۜv,c@JZ-Z߷ CzojcVQ͂%"1E$Y6Ӷ+kpC H+dʄlF5[twk?IAȌ~blոQRa5:rip8e 45e[sE+??%_ŔüEiɨ?<㔉0|j=9G/LQq=֙: s%Yu&=8XlƊ#Q5<þ8Z*LpZTSݢ-m|~&8oMcPTBKƉeۂDt8t#|J ܗS ^lPY)%ՎC )͗ @j&G%< SNw ZEQذGsO|7/c4D39Kd I4$ugړ wa ;%F/UU#} HΓEQ0) RH6 &]h$BᮨǙWv068AF?ϙ>W y5 c+&JNd=>%h8ˍ%x8Y$ =ug._+k2J"m2B׼<.,n'tdrf4s!Va#D:)[C*ݎ ' 5@ BqU#IƧH!е$@ \vJ=`E2r0V6E<ӬnAK s|˼<1JӉ*Jߜ}:{ߺ< "\jU6.{Nu MmA?8$d"\V_O:Ww˥,ɤԴal%f&$ܬTÊm骷yA"{MpFRѴo=xZ*-9?|[~l2qFj uPx56bNФX~{~;:766O+V4`/F)m~T{'$~ni^v?F`)_&6.UϿ?dcIg)W0U2*˩kbŘ{rk2#k2Ҁ](RJTzǃ]1Taŝ'H3!RI4a&<7#=+ "-SƇ]W >(̑.|Fr Rq{&/,||*yڕո1OGBԈMqUw.E!OeQӒRӜ,RaF&zf- Kq{K19fħbkq 3Tiwq۶@R$әJB&xS:ZkS-fE&66)1YlT"l;#;s,e3ȈkNK]@P$+ Pז)6ਏʨwĬ68"2`>n=tDI3j+q[ Wd$))2RG{hm]u`?oDWL6JWg7c~LO״mleUw4\f>G:ȩ(%99B_o7Ϟw"A,Nr*@?}Ldr HM 3qxBRSNP]В$#aBi}NDl6E1'k$œjlBq9K8ziޮ.FAMʌwuj20J3 +}q1GM]LA%;x@,"i`c%kA&=ƅ(\(Y/L2u2ٔ@h4J$@J&e3yy`7ZP%ۿIUZ%b;)x{aR@uv2B5e^H%#QҚ-g&zd2RȔw3JbvawyͶ""IDZ=ty`j/_˽NC<~"T#:MNLYf8'vt9]EыG9kd2`R#Q<?z3WB(D'.4/cCR*u,-ӟ<þ^| z/^kthH^a|t_`dm \t&HLqb'5h-Emx]  GHI9r&+0-(S!&#D#Qi#-G?})0@DpKBK=Xnyy|7j’nV4c/T1%kV`.YAp8p7Qk5"o߫LX+)[L)‘4"%5BΪx_nex;)O n\4chi:iJ7KV/'|L+#f'[)c" #L%mƤ@&3ȴ%\Z(H}-n!;8~ Bgx[ :h]s(&_gl)ŞSʊ ?ss+3I0 Maև?l\,W ׿ǡ=?y{[)X1S3{}IVl\Oer<ʏ3.M46ԑcGВaNtȯātDB&jk*)w3ru~P 9u}\yxS8!vo1v[;wq+@˪Q1~ (DO?lYVEj;?9붣NNqmKq_Hǃ(q>͎HTPR$$6Nv6#C*)wINxg(op;;woeAg/1<:”trzMS|{OuSV\HAANڏs9FSe$/k.ڇSTP͈iҌvWd8b|wNi3oBSg];rq8IAQ9UWPdՃ/dސm͂2#6ƒԵP2ض{N0p~5^(G%1;s~"N-hkqz[=م\O`ǞDݥ47ՓkHa!RWNKe<޺NpTcLlظ2Kd.(,قCWxF*Nlh.LCIRBcKNr|vj7vʞLt]3g40S &sF|G{\ML"4MKv !~M]u63V0EY[DrsG XJPBeXwL%c{qּJZ˙@Ξ9˹!t}ep|kXRyNzX`?ͫV5PWL*4 8x~t{ ̣2K's8C$U;5Qga9xlTVSYUKR ?=]{;/8sa. H$ubS#S&ʪ)Q<]/Paߎ8d~ %yXH0x(mhL^aNJg`B L ɡ^FϜ'߉{ݔG٦^* 59^r׬'ȉbv,tHxr.dj6cV[g|7e[(o*Fq|{v6N湰o4HtpC*Xspc:4Mju+a2*$'96@_W݃~LEUlݺ\ hsF Wq+$ }X"r #L&;ohv}snx W^)Eyl&Fǹٽg/I_l Y^~en9Kqx|\ ?ͷ""ct3p3HC:+ _ޒ\`v+!-RNI 302I:*E48oG&PVVJMmEׄtqFaY)n[fKK01YYH/"0qh/7U0m8&q0Y+*0J48x0- U@lji9OQy9##i\"Ja?Cu+%䘒LLHIBGE tЏorauQTT"M VqSjGn": E%xftPG}H`w{)--fRz})ʈq$"G&Hh yeO#-9c72;).*@' vK$aʊr ݔfEB| m1D$ȸ/DZf7P'`Ɩ[@[?>Χ@A SQ|SI<mT,ᴂR4&R"0SHyqskAl:$e[ [ &VyLlKZ2IAqQɐiJQaVS<x0᥼5O.Gc7O3:4|9˿C4&M/Ã#LWLEU!uc OL$V"&%Ux&}a-Bfӓ|>bib"'c$DCqنeFN :1A2:sp{P~b "@C蘰bsZ\$19N<Ga>f0[t",||d LRЃRi;V}a -z:Ęf|/e:E7?&ᦨD?HtvȒ-S*̄/[DݔOP]/ !HF3sV 9yx]#0/3y'ޗqiʸ*:.ARhdlRnsaB^aSf3Bq %n1#)D&E9 F}uwR_X^\#7)e&d5f.C"+=@2qϳ)>~9Fy.u9Y*P}΄蒬@J={7'x\+j{]N}|2EɆeK+"ZV'1B޸fF.ۙ1TH~U!׾kyC^^y;֏kum }1ʒ|n&3grMU]=Jt=+ $sU,<4X\^ZVͧ!(4\3]G\k-׌2#wc8r`/RLf VZE͂4YѴwN{7{n4^o.ƙ9_=\1mdsSs>7[oHqnpv.-RiSXNn!+~:SITO)M&qsܿz۹޹jEIjxe86@cU1U#8mg(c|PoM s~Hc-c 3L%Ԗb }!9& ŋ[yv#%b͡aJ_5l|Wf``psX]GCW/9"b1cG n3Yl& _ f2*B2]%A!ց})+>J!~npsӞ hI%koF~Z'h;S1:5*Crv>ӻ\uoP#* _ g~Pd2&pBd`0t,- 9~sPn~cӵ$S?L'&5!   #E89}m`F3ʴ`hPžqz]!ctONN$'P5uMGQo0D-o݋ow /KaC_Xx]8;Ű) ˦[w;@:9"iʋ_P e [ ExWN=NN/&0ƧQIJ,i‚:$x&ǧP=l\H8ӃH8kY_Yj48gNrIL((_ƶ͍XtHNpY1#R"Ͳիڮ 2 $uVUy/ۄt , <Z 8C=X[ˢ\2AN"HXi3 sc~N:H8E:>M^m[VS2M}G2ұ=>q \M;o^g" .rjKjQN:oރy5Qntۇs Zn_)HOs/-:W?jFl=oO !|ϑ &SfDi:?ueܴ-%<^_$/>/Q:~ Ȇ|ooOwJa"7')bq #BLONqC_aEܳ !G%_&)(qmhd7So>'74Rd_& ˊ?k q˔̤|BRQ|J9>aS_/Vy^8=Qd~&j+>xk9w 8,cP[>{|UEX^n~B9%Ɍ0P5)e&2+ 's핟gfJsK)Q.3iJd]f+'13|H9>., HiuI.OE}k u5:>Jl="8ۮE|L}jgȿ߅ͤ uU!ym]O^(2JW] `O ||QqNwcm]+H fVRߘGtzYQ˕FtA*:2] ֡_+y*$zH>_z/3HL8 ata<^T3j\kƑ!%vv0ocx-&,/zᮺZ90{[j(Z֒Ţ lLafyzy]D&yl(H •pYTL&.G}t0 :J~ժl^g8xq+++M9L`~rTB40L=G~c8?WsOv6TZ Q ͈|Td<th{I<~\ F6(vM4X>G}GJU!@o^ϓ0I S.`у+pH6"ҌPl9~ǃ͞w$Kw[΢/pu^7x{{3%[~||+tgf`2ƌPc׆Y?3~N%vj#6A()ﯿ“?}sEb {xz9YPU3Z`nh"Hg%<~SK^TFXR@h<Jϙ_ID2ٶOC?_?bW tq({vn瑄9{b/Gpb5%3)CXs(+)aVg5zOO+܈> K-!IδӸA:R'PX)5|yBr?4 %Mh'+ֲy`M.\֑!@[s// 鵌~ieml[RL8?AA6 ۚЦ&C$!& |ov͂DU{c8thʂyuB@Z/_~~d$U7:I&So%˰DMK rfgb)`ZQBqb48,D~ɢ22@ +!ilՋ.Ec>ÿn>)E +U 3Zf+w\A^?_, C(ԑRB"G•ӴٌNfJ{POسO?=o.gV.ɳ jε[h"J*e-ܻ iMdd"ᦨd!1% o% 4yS#aF5)%xyh7duS.clr1$SR)h+@Ad5\W1y1C)EjDa"233=N(ch|$ph]rZ|z܇f!յgkg;%v%& &lj6R"F{ڪE|Ezx 4۸}yk_0DOg8P 8M+O?ϲ YQ{|"l w`I(C}.}!*6|CCNp3Ş248E$xA,oeuѼ| y9đׂVu!޴O? ' LVyl1t1cml?8d!K1[?zߢ4tD9s4CL0u34QGE#+2Ewr&2;@b-xuJVb y{gR0Ya|7MEzS:qEE+#CB8 Fc2+DxkN"%14ƥSt.(a' ;{ TlHJxޟKyq!9n|H8o^TP?}xK7qg}-$0by.$x`B:63oW^ 72D?OR":Z:BT7!¶rGhٴ.JLI wu> .r <.6Ot,/SGxJ1ʈVKTt(\#αk'\H&t=*K| ~}Uxmg:cn3<|N^=zqNe S-߾Yҹog_ZA͊y};}m%U9=h?}>tuP,m79_9tPwBꤣ!҅6c2wʘ_B9{/5ta]wԆZp'h:pŅ)3EvaGn `Kt &%KXTIh| _PD嬪wqb8v`q_ŬYT(!u#}D,y/.!?׎%L"TϧčSHYq15 T@Sٸh8\Mԁ7yC;vݻ;җt:%^# #UU_,]Pba>9?pWyjJ]j D#02xDPLIn^,X^@B@*dxtj+VbL5k(**0as5RR=!ȱ[pWjJj \-ĖN_MKj*Xh@NyE%E%%1SY\HYy DBiE5EEEx):<+j 2'Dq<*\ `X\\!',\HMc<\4PVnM!c}L^js+,m3ç,'?K^Z.:'eA0 Gj T o2C 4J4B e %}IV^ k>]{!JH//v4LHuW]ӈGBL$o' s˒>GkB勔l %5+z ̺7I]GIzĐ`Ak-Nt/Q3VU82\u5mVCQf\"_s5O+ν1~uvs.7)t!L6+}=gԛ/Iϊ-k})ze9̹wzstM= du}{DQ11^~u]Vf' BСTZ0F nA[o2|El s3 )jv>g=;dr^v' ,F;ȄKT5RlHpDds]!=soF{rO%3u411 !U܎<.QrU\rU3yd0NekkWeh ?I_e8БsP:Ǘ˽bsչDЯN,Gc:OOMy'WX 5~*T2ʹi~2k{\7g_uϟ\[5{=>\+w9ס(7,C(&ArspߤԹwv=N&#of?}R{;s)oPo4p+ajWwgYF{aDK eKry$TrrJ)]?ԃ| u9.xaC͛= Rhܐ5 kvŽ,5oEOpԞ@ ~j!Pm, cQ ~uP~OH-&a {78 ZÿG;=;*(u[)8yPLxXU¼|B > 3ZYTA-DQ8mac"9Z13R,G긋+5PQ ~͐Hw?0 >$taeÃ,`þ""aG2V~AH&&J ~@/{7uI4@|M >R٬ܮW[e75QOo>81000000/.*DpȝLHDcךt"F$@x%F_X~L#"S޹B&HkW$c&)->y=/.DJtWd&Aw:]{աWy=f;|(d) _@# oPnvᱠ%Bi|?ۨ7_*@FHD R,6\.uE2rn/O|m;]B@žc,YNz݅d,L8@q9D s|aŋwIs(P2-,XL ԈLGHٚq^Xl6MXhC_A\UTOE\OGYAz:`<bfr kOM=h400x! tǨojìpyihqglX/|.EEI8wHW@Q~RORr[1FNfB(&[0@ODIFb`bq:QTʈgEՒ]Oaݘw|Bt8SƢbjJt^a^ 9^2gKi[4YKf}?zDp_ɸMVPu×NNuWrÏrDzkB^xza]S][7k>ggw3?~mA}ٝoU7O=D?)gÈ&5DGBJ {HZ^un((9TUEU<ǩ*Is |u<#4YFx;?p}gy6Y~=ޣ9KZQ1?gOݼ9&cO=Χ?8nYLi|Z Qn$S(&\,NϏ4묀5B͢Zjټorz(H8~dp,4))-aH&4D:0ÌIcW3%!0R^ZU'Ic\r }ğnkAL:&w9(I[jdtH2 "r: 7ʄORfe9H#uLô}!y; Ο>Jd}=LRE x7V;ILSlGomDZdt:_$1x"*rtףXlx-k-!$-.1u`eٙEUP3{HXY\oIK-Sqb֣-\-c.~>lMXXD%||ɷtd;^ ~Y;f;s Ҍvg@+IPբ ~NAz)G׺I& 55̞;0RS 8~{M:2S߽>ޕ`KTO)yv# -@ѦtFCU ѯs+B(d>Gne yV]\xbc8: i:Na9_[헞a |sȲ"GlXR=7BӖ'Oe6^z88|'y,[7RSiG >H[E |g|KZ,yjY b6cr.tSBabs則)k(̬44HM3Œɖbj2KYvI:4I4nb KDəvnh!M](:[<rYk$ϒ@B rbekmn}; 5i-<ım%Q1xzxK)I4&HT i*X,8s*(X9L%1783c;2SЄP(/ffݒ= .o!A|(?J\ Z ghl]HCz~de$jʫs~CY|EdPUE ~~vz=l[PM/dxm5aVZa ɒʌu; (N#*cLۺhYDCB@IFxh'<4w>RBd܃zI.7?0Kj q]bӌ F)nheO'^;E\Jodpd _`D:@L!:ETpFo2=Dd%v'ޱb{_C(c d#^F8P2Np8xd6aFܶqL$t|8ܭӺv>yZRO96 \6W> VyTH8 & էKi&6mM!?ݎn/uA=޲*o[OS-㕩+Vb>2w?d*)0Ys1E#\+,Y~ܿݻ Isf^Y| 65qz+X|~ #ܕҸ8fs<7$==Pb::j~=M݁:M:3;3ojA6#g0tD n&+"@XQ$cq+TL.3(!Rq c%95ҷoKLXB2Ĺq,qٛFb$MC注Iu5t|kg^;E2;IA2@GO5w3rOd2e3͜ӂ#'E,&`X:„ICF&Ke`8'c/?>3~G7}&1B&f>T$iO18yqU#sѥ'cbVR1ZH$:w,9=n6R`ȴݑC"&iRnŢ mG @D8iZ}nGOLiʄؠG \̡7Ey8*s[!^ϦRTՈU#b`4s]P8GZE*sliL*V/` oqn64,&9fقUв(7Nf`p #%l%(48޳@g;m>UtOy r A)Q%Yr^o{v]^{mɶLbA< 0z:э `Io]SuB=?4KT-;[֦bTRFAQ!N;XJΦm&DBj'??q,}19dg9-("@'LF$BjD"QtHŌ,G"p8!g ҅4<1;L<ȩ_&pd/Ý!*yː ^Px#D]L:ǔ@NbU2}NX 䥠҆f`2$( Łax;)6/E?ΙC/}Lzco{ݔLy.v[a}alɴm8Ǫ3!%8nVoyG?&/YWnCHiܿzOJɌSQ94b6058X)@fb53鏉9"B7qnКJH(mdE}96 ńQŀdDW h[~ok;v%sl<__y<ζu212Pm+ɽKdhSiXeYHsFS^  (va5` OOͰp"\O`|шlbϡ٘Ξcrjy=T7&뗟鬆)fEC1c!c3$f&Fј|R<_TI|ju~jN{q' l41Qc@GrY\98Ω3]%xx,J$dҀ=ˌPIf#v;Ĺ)\X!ç:X\C-gĹZ2$2FhT0\2K0Ȳ%\~륔 ȫ.[.Lovu7';eZVv2\F=3d %RSskV~~Ǝa[)sVbͥ/E zQyE("X~¾p*)-A3`u;f$'$I(YX,;)u4MO ]E; :i^DÌbNaEJJ(י D2ĩQ++7+2$zj/{caþ& L˼\*IA6}D%3&dBSLD#Ĕr\V2CGZd':pԬe]c)F!HFMO~ 'y~%ܷyEvqņ``MU5l%,Yf$K]'dJ)ݸE 걅8=G“tK 챓ذXp\R^2(^t%Ok,jh 35WmN9BEe_r*2'5Bd< #7-wXMW1>!-ʴ/Nn<-.ʪ,\lɋ340\%w3-&aeۯm8LqU99|zMh0D&eǁF7>#::'WdP 6ž-LmW33?[cx&˜UT9޳/cq]vU4_Zk iP|7Oll[{$s\EJQ.fl{8ʨq$&gZ,t @NSFu6L7s %7/Uοّ˒U$&.1eW}ͥ{ 2|D1?ދ25)fKܘq'[@zL#I0UYNi_AQ$ST}~n#R$fFO9EFf.RjѱqDC= 󱺧Τ6 !OǪ؍@O) #Hj 85o'y'ضs^9n({L$gCńӜYdԗ(j6䌏Hz'%{<1Zۼ 0I4!Т~{zj6Mk*a|&g)k.Mʨ_bDόΛOm+5j$yuAhQ#$f<&6ar"WXzKdC{8/!ӣZ(~=I߅榰}{wqrg"|!,γ6;[2dM1]G=`Ac 'afb >%lZ|ít;˸Wb C!,@;-QV~~1vD%丹$y`_]jhZlXfS-+ H.^Y6+}y dy itD;:S;D2J#QAXeO#~q . ?Α 3ke;14c65LX4la&#fo¢XKh_؃]JS|lm97G؜TTUzPb 6maQ =y8300Jœ͂f2u#,]F]QR֮ZAyWAM xXꕛٺz>6Հ+7g .\BEfl(CZ(C;ͼEKi?O{[;ݽ  TYz twP\YI~v%Ս)uwt{&09qi>zGH)5~`3Rh=;H y}n='fWLM􏇰]TՔasDq#bjO뵷رg/v[ohRj2!CO @mx|d5f266z!L'<2Fhdfhm3sp?¤LFŦ8쩌3ZxVZ.}#ԮaVXAfH.jb1b)$˥鼀ot[ZkRQjk0DƘOPq3Eٙ;`fioL[I6Ö:Uv1yQ9VH'dg;w3?Rc(7^S~_ޅk)BIsӟG%/'V1N=^vo^Eɹn}a+o*+GtUaY.]eqNs \k L,̟gt,!W=K"s岐M&ss3!.18fSnkk Wݕ뷫;C sOn6ܰ k޶ƿO2g)y.׸M(BcN&#!g )1.2Gb2hklP^ٷMՔn]wWR򲜨cu s97 *HRT@v\rSG-iƩX2ݬ\6QHwNEmsujsϛIgqs) FGh=q ?dgMUiN/p#:I-I2 #C 2Г1}h9Ld2o3w߻,n/--q `ZE(C 2dȐ!C 2d%#"I=Gt*ϯ4SJLᆤV 3$eȐ!C >c\Ά!ç9utrf PL4 N(L#rD2}rt#=>Bp5_X[і6ʒA$z*-֎${OlVV8١<rRˏh_JgS@3dAQ'?S/Rw/m;1ㅢƗR./ En&,,]]r;k(B)}HUsLX#]AQQ[ԴqIX˨*R )GB\1 $F+6*jk)r[tg%ݘs$>4)0-FeTUn$3}x)~fH&h9Jנl#nB #Uh)f~dLEXm6;**s0*}ڊ@ô|MPּ%`T*^F DvA1%Xp'btѰd6#>)Bfex(/!-'ȥ~q39zϐ!õ$#x:0pfLJrKQɕ3l9 $CLD0嗒WUQA9=#L\յs/{-JVCf+ u.I@RU^MY6^>Lxqo WQKMI d]z]y>-bJUsIB̌3HP7SV]KY##"12;_נKhHV1gOZGۡi so!j%+J1|,0N_}lJ1);u<9z=ENMc BкIIQAвEϱs~v=ػ0; 1~Rʹq;タ\˚Uϲ#>N{7RPNi2P8z Wyȍ>#yl\Z> y,jl̅P?~c=nVH`;|q*p[7=bOIݵoj+'wEL/nA:),t~-XHCdH'w<6]@՘1l}8uy(#ut;﵍Q`!.Ӈ,L/Գy}#9VS&.C s6Ct[6Y(+kXzh{e_@: w b}&g_|^/֢RNsˤ^dc%Wɯ-@+g_=Z\I1ǕmAdU[H{tLPŬ|YA(ha}g78s6ve5eDw/?Ûqq|WabW@ }E΅]T_#MCu!FEE=^xG;gͶY!z<㜼8ENa)VuB'x鉹(s'&iC^x0jQ9P7/zSB23܋PĖP{g3Sn$PdIL$Ncț'c)tw{ '/zɯ(G;?Ͽ孓节{;Lf5fyk75ʳo "BO0>w_;{n )RzKw_7 L39'''duSSW='yֳu*V\-WDwqf S.72zCgǕnkj(Xk\̊cfOӹL059LH6* ʨ,T\͆YrWe#ko`t|^o}U^j);T &78NCapp&o$)9l޻WlbVZc?BCJ0pE`W#Mq]=Uyb!d/z n}1 s$,YU㦨K 2d DXHUy6maeSl@cz]x3L pE ë4Z΢e+Y۔_m$qm1`^=())>?.7X?)HNbw%Wy-w՛ :j1b&jd^L58FJpW,U'Աg$Ԕ$OOgRz꼺F"b4@׈E$bLxdS!ԉDhRl`Gƒ($bb6*h$PZh͊ {*}A(U٘G\z7_}^%G`"7c14]LXFf}AD0F$f Oӟņ|P$@jIR`@##t{ؖ%/u MX,& r BHꨪ K!قd@O.k1_ Zh,.%ьd2v$ j@Lj%4TɘjZotK>Vv+FU!qtu4O&Smz'bDzϐ᳄IB=kjBY9RcHD]I( Tfjh6\yv"K}d8ONJ *(܋x=[0w♰S]R\K^YEO1$~ %Q,3.d&Qf<1%T5ڗzhJHSG 4fX+kñlAJ$ uT]7^8={3tj.ܿrvˢ?>J񗫰AQ,l٧O=~Oߑ|hDQAfD%n.K;s1ˊ+g,) 蠴؁%bJl,3}$f]2R\Y@'#a:)!b\ڧRZ9 ^pRQ_:پG^VgSS {c3:AZsQ.ΘXs#<}},̌R`_y>Jʵ*I(%j+$ω{8:Ă_22h[ʟXYm?SqߤZc#hKhx9q$~~[sgi9uk:P4"8cC"01UW':ƻ sgZ t|XBlE88Jϸ<YRlS\3󗮥M8ضE;; LLŘfk닸=2{=g/pD<,tpv~nESʡi<ev yw}j֖8}(SΝne=71uvlZ9.#?)p\! #:Ft8+YA!{!]gFi~+|ncf=H8GER^ZN1A +_2|Rb)a|3s2+RH76Db-(ƞkd1`p&%",cYE bp5cPS'F{b Ãc蚎:kАgFO(uYSzn3,cĥ UAJ8A;G(c*BZHiO'y/N*{_}Ncγ_"h~50* R=+ЍT}TqSgf1!DdUEǽLxʍY4)dQ^CINlgg,@Q/׏R!Uh_D0>o^ׯ0oB*ri~O<+,1~=PjGXOG;d5bx:HsYsf*bit[Ľ[Ph8ƫ36h6r{~ sߣ< /J'BsO$QTSxYB | = jœO܋e? Y,j!w:O?VrI^F/O! fpzbep]J /]g(ZG7r( wf.,eMlݴR6'Epr>nc=݋rwɮse;^=/dHGI&{Zyea.N'i? S~{>MJW !*̸ֻ@u/ۏ Q>Y;/1@ŁQ Wqfr'>X}C>LGYVu5cgc:_0^7-X߰{ 6LF3EE ' EMTuu&Ef40 !M71-w7P]V@,\r@8 "Zk1|TBD+p6d}}~'UMa:*Jjς2BQI 妱W R[ظ^!X?cLJUj2%"zܰޥ8KcIt~ʫ!5gSJ&kh(,0UtcуDBQ"c1t=[ˁ"6dXC1`ew>T2۸}]?/H~9ɷ@KL eh؂ӕM;A#PQZ6.kFDcC7,-b lX,6<d2rݸ.rr+Xe) g9q~]q")EA.ىJg#3~& NuI+`f3C ~f!H&8Q%`H z&&˭r9wY|)'+z]DjWU]'ܸ\3Z8=4tMCTxQT;$&LVRMU5]ҡIZl?)YMa-bF&.a6rkp*W_Y:]jfw5]UZM qgF'+<~PPdVpqc$޷HZ>s!@ѳ).BEtӶ$L))(.!eT5 r1k+y %5%;73-&Oم^2SR|BYQ"W]Of&-vq9'L? &ҒBƫm޷hӯ'He C(f791Ʀ$ӕ,dP8j+%`kOnlES!Ĭ7Tf [793szy/ƿ%Ң<,t+~M i:rlB& G¨3KLKG0AotW'֜BӧWgj;Cb!c 0)Q^;9sLFY;Ht cǏ#kVQn>F5*`8JaM@&Qt]`-'g~8&R'Fs0( cY<I͌Bw0񘏡i$KKv974cWZJT-]AA'$ԆbuRWYGX2B:#4%w+G6Rh7^ڵ}$proaӋ' Q0epP3w) zLjk4Zy%UYld44M/\IJb WUP3쟖g٘] AI*Q":B1pyڻ\W/hX$&^~GcƻvVk ɉ*w^Ό)p7'ٿ]Ŕ[=yAqbe6Q~I3#$В^3edZ?U"G=@Gh;ȏ*J6~wm2Sl_.9u@D<$Bga[ ݳ-6MM:WM#LD)bip;Da T5ob^<+IR^q]'隑D׵&fubq6 &N{8u<3RWדWH]GOjioj'3<6%aӪ~$qi1PBOptNjƛ;qѯ}~g%Ssz /Lf<.!u,y S<㟱}z9w7wg:8'+J""31>E8L{vcA,cDzgwh)_™C蝌*0IG֑{TLMOKJ{=]J r("c D* k(*s#d~ i`d {c _c`4Cr~~3wz]H} g-jI*aF~3"˩ذcx1dd(rq_NI'jXK1e2޹8{h&(BAܼ\320Wd$JIUU@23pW^{33h%kR]`(Rh ]$^u JPI2~:L`'[سg3Vjn&I&E G_ beƭdy8q~)tۑ5ͬm,,fU:Nty~ ͳ^! ÇgV/6]BGȌE$h?o&;7C/Rs}/’%'xߞ`(%Ta e9} \j)u3^š$ $).)+oS9ssYҒ0{!vNeSlk)/Dٓ?ۍ7*-Cs = g rt.M!5U:S]EEdY?T'V wc>&xgdK /0mO8)ܲjM!Zq{&Jk(v>=>|c#LLO27@Vɽa?ɩVFIد%UZd$Fcdiew)4CUd)QL,-$6qwGLF [8=00(3q~9]ׄG^K.|'tvsAum3]GuOXlFenC?;9~n_ЏgjγۻahfeS) q{ẅ́6=Lv|,CCȬb >gFqU4yv(kЙKc+c8~tM[*zgJHzN8Φ~§9)+-"b'D8s':L=ykXZl:zk`ex`|l&#gm`EhhYLuw ֗ݷv1SRHma֝q!Հ`$wP{fDN?L[+3l܊Go9=?| pl7.no">p5fQZ^yuTesiK[xb-?9rM:$hRbq9,)ICxf$m^\,@KcIPX8 H-N0hu6HR2Yd9,5@GBhYj:sEt~z.7d2Du8b_ }`Mz~IWi $Rg8/=,CwNG߹MW\IlXszI\?}§ճz7&sճ{WG_"\ksc.kw\q;ϡ޶*X_]k2RIønr*fi5o|o7ݵmzƑߊQț\C"M&@U87U +Q_]ste\eY]E^_ +[pxx+}VQ+~nJ~E\te񘝩  $"T:ūtg/0g~o2\[2E⟞4QZ*֬ɰ9U,j(ƻ\z- V7_]1$c8!cqJ^+fx/Mt9z&q-A8v~4U|ՇAax=P?ZQkmq7 2][g[#q~#IRY_KOp(J0wr]ߨ{kN۹~uGRu2eZZ^7řzϐ@:\޽7--ntu?C)$+g`*4ٕ(,07{Mf=t̻g,@I+6DU>{m;bCPk4>iXXqRg &Νs&n^çeXIY1Bɐ!C >,R9BX1*2*J (E9G K D;gV 33p߁Hirs ,"3xH$J~w4eEd-YŸErL7Iߛ!C 2dȐWpO >|#ʖ.,'"LF\#~{ AYU,/Rro%Mݼe2dȐ!C 2yd?n8"$2!C 2dȐ!C 2b.GͭGҢdDT#P!$g ~U']$6x=O췞&CY>0C wЄOWH$3Z@5 1M@TߴԧXTy BHig(Ұt95U;K}aGC(cLE-ŮO%])ٔ:(J|l5x:UQ˒D`(Zļ-I7Ag$5? 1Kb >ZlgL 0Łw#V<¢e,o$e #1;NpT?Պ",V32azj׼5l[rFR rg]Ʉ0;cWo,Ы?˿=^ǡ␿~1r?DWC#fU.D,hm[򄓨\-E9։  H55RGBhqyIƻ[9pъAjAhqSEܷe[=:dΧI߸Y,dȐ#CƼg0!Ө63Ye%G{`# Ӓ6ę9s8 0<{ݔ7p%}-vDxP,mqH 2@Ka(ZL݆E>'2:ζpS~+Nanޭ u-⣳@jeέ`RLy)=C=DDP1! U:L(HE?Ԗ^^O fԯS\VMzGa5$~7<Q?IdCL1b˶Tf2l=ܱt15t]cTo<SbSn"I3i=IfZ \&;mx'h;s; fC2Bˮ7h7;_قi%kE׈\<{ۏa:"؞xnF#*[^Q8Z}F 6xJfBw{q.Ƕ9M̞>~se!CϰrO#B(g{ò{ uQ@ز=۹-b0cnmA&9UK=IZR~ٴB U(&5+ܺD(&l#'}2dc8L߉0+cs"{QA0cbt<BOPXj'o ߠz^#o;dH<^,2ȁc/k6dQ\/D(G=)}Šu% y+XKs^ 1bC'adVo@t0ulD7‹3jsa@lfP"9$P_0ZFE!4;FXz&ɍŪF}j PU#لj5"$I]y R()͏4. ]y<\k>7SlPdJ躖^^Ҽ\kHo}([t)E 71u(]|d?YCsB8deiL_@VԆIՈ Q޷2+G&qY:zC{LjveD,)/M">0WKf1(Bhe # ibq b4i뷑k  !C{Vc0AꘋRB3TQX_^feb_sr#(bQi6(*Va{긇70 bE܃Ū*(YZLˡ^_@Ahrkv39L14fXD(9H{;'x u0-Xԫ܌ވ`)ɶ:׿c׾m ϬK#t(y $5#R#yyдt 9;Oh7&!$S9,k©a_EԮ$'F8yk1G8{$[zՕ.t]'8~ ]rVߵ7[IDAT"[EJ0N](-&cqT0M. JYM޶^&TWY^i+0Q94-IMLE ?HeTX ҏ5b; E@p8xlE[: ENheob֭,,u`z3^k wvaKI#ZNӄԢ;ù1IkipYzyg焻-nHeEF=^89 ,/àFI5#(\[Jn}?-"zScP:ydB슎6וK芍R{z!̉Ҹn D?Og27-qJdg8x4~6AH`c͚eѺ'zYPKVtߏy-+>6=6ɹ3̻kvZu$q!q悪[i%' x9- gN.g %6m T$ lQZ!rIRpf1%44+4$/IV*k炜&η/ELc0袹L UNsebn]c thvI^ꪙWhM2ˆϋy]5g] &#}dĥdϡBS xc(B!?'|Y,[LiS]WPc&Dn$,bH=t9ÑK8 RsxO5nc* |]O_+?cC " vd'TV0ٶ^;J( 2Л?Ǟb*U<n#t~{浬XPLD8 y,n-~]0g?[vǒC34<׍cf(Bc>v [Y ӯ3< ÆrZ'O/djŕȑ?d6RW([*'dЧST LN]ZQ鷕T 嵟FD5\7jVnuɵr1"?~:i2ڽ-^Qct=>'c?ӏxyafC)NwFM;~G.bpSqh͈椬铭z436_kۏ"s)2N32࿮s;Jb1A¨$-`f"9y+-\k?w0q9Ŧ&x/%o%=׋XOsi_˒2D<}PlµZ d4TDC58^^?30TDJ= L E*@ Opm [.tK y ϞySjEgfɎ&H90p\M&>ǩQ++(bҥdy7ɼ"v-l\\"u0ьCRňn! 6#]/]FM4W>H uXPhĜS][vDMS `u}%)"GS|ܸXj5˛GXdxBCtsa8@Q/)AnlfU4/GQd2)m6RPq01wo}ypYYkBR'%n!@ONgl\SE2:?z,PgKش~196cZU!tVd|u {(UilڲӜ<7Qwa::(!۪"%8K*i,+˜jqȦn󫊰`fޒj^ʦ`2KI` onJr-(aEJ*ybvBJF}7*Ki\R[T+ k>?Jo01a@9  ^/&7DɮGc}#ZCn8̴/|_E MRFxMJZ`$~eHLP\Yςƥܵ3CL5d2p;g.٬[LYe6<ҙ[իh^݊gwMc 2/Rf[⇗<6.j)NE:DZ81Z\ӹb0'g@Ȥ> a0$9oբG2|H,ᡯ>Z'#o%VW|[מ7B2uelЀȾݕdo$$no2I ɥ0n&DӓZ*>+FKd2c"\8y_r_]Α|=ֲyE pL#Gbr˞K, xJa>ٶ+ E½mЪ u;sP FDH&,FK~BgJ1+ oS@QM8l.&!TeP348Ą7x0 Bl,ZTtk+w0f ;`cJl`ulkܳ%Y `w9U`C#%榮(GTZSZ),ԯ\GSF'hzJ*f㦵Lyﲿkm'+ fT%uM͉AQnjM,vX;}=Lgױ\rqz Ij*0Z % [L- VPh$`ibL$`'Cq<#nikTQPMYNjJ,eͦ5 gu{,^S{[7k|0> ɵ)V/gr| L3zed(c"Ł9}JHai%+r 0<%՛b˛'%PU3Cc1L$>ɴ2d 0K)Z<>.b7]ITnXC+k"i1#x8rI]GXΫ<%݉)!>kN{1Cؽ04?mz|Ӽsyr %j'G$|!ڧHm.n'hp8ֻԓII.3@f@|(:g8c۶ YXf(mknfْ,Yy ?I[4)B&x-!5%y>#' x3/z]Wd!qX^gq)cVvScs䜓ru%Z? ~Ǹв=JTьz}Ĝ[ǯ6ҹY~R `rqȃ.e{GK{ [QLaFU(B1(c]Gyc>. y_{GNq|ygsNyݒI*c|W^j ?Sx㽣$5QOu$~)7iI#mLsr24.[M,8KLd,uOqזbD'8͎׶sk4`V̦Dbc54A˞=t{JQ8oλT  J<jW?ʿakg!K^2dHh$|ݴ;A,3 [L<'_@yfŕ$'i񠆻EU]ď|]NC-v(+`&0ڔ@G1TVb3)FӢxa@ +xB~LHZrYy#ٱ `4uZsv*zt3-,]Ũ楹+?Sw~omܙͺR05 GŠ" (. 12ARhG<\gf36!8TדDz= ww3L\yp|DI)S0tPh ^R <0XP2^$QLcuTGxhCV:MQ O8|+6pWf zj*j=O((ۓ2kI.<̄c}9?"epB$g\2&)!Bo"% kqhh}a}(AB =U穎3ۃ6tIc+W殮KZ=cCT-rIK1C$N*"&OH$t917N rq R׈BD5 MS="  {籨ЉDc$I4 rY\ndCJ JXl]3VP2Qξ/jbDX,J"u3wR*W>Fx Ͽ!ofBt вg}OŔhXpx ]n⛿$Qd7+&jiu8!CDdh D TdAB2ԱKR1"U+9u31E*!BҦjT5~:܃ϟĜ[N g(z@(eqU^4ŀO_!8}" q8Z\HR)h,?ݼ+A([NbA7؋?RY%,[QEO[L07L%82>&>X*_uHahcEs#z5'iXgq:VpXjrdlWĶZoy]~ӟ\F#1|{heBșD0(GMY.9dp~C^Iv( h_̫(cc2z 2ð^B OB[;tPWEUfߩ:^ H"vl'I7&:y[rc;ʼn[,b7R") cݙcU(453s<ϪGkpr*@hm:$fXAǐ^E,*BQ8px;6,vj[C{WcttӐW6KOG&I4VJ $q۲qv0<ϩ&3WO^~N],$;;ekV29IW #vNvd^1Nls`rϑQ6 E9xLDjjDwpc^^{ӌ/ĖSd-P9V Ї,w|&7ޑ IWG1:ں xH)ȭY̲:R5awbBS ,ȝ ,hb|TON*J u u0:6E{GS= 1>hϒE'7׷+#7A%vFEk:M\rܘ]!l{T9H[#';Y:#+8sBY)/a~c%HTY‡x,ɍh9ql܁:'Lju_HHv 2 x<||n'%`Yƣee:k&:QjVQe&M6&ؒb`X!+?G?Fw n,T5HDsy,rgcek H2_.+F1d1\wݭ'i 1lsKj qZa7^zjO=3)\x;6rr"ώ2)fVQ:~va~Ng#̍I,OL:1)M PmeLqLIôO%Upf!4+TP]%js2kq(-tF,(8D7,Q^<{p 0^̕ި$>})~ND,X"p/]`[TF^FEGH"Qzzz EqI)%ETAp,GUV,~X-\3]#EZsL vr\/QNQI9Xq\yeenŚSBO\c1rJQ[UHÙ6VCtv*Ŕe!4757+ }t:)(#ibjsL䗕QQRh(G~E>F'(+f/LX?-=(T ȣpW'Gdݜi"bvP5b mA\9ז4_iW'Hw'1W!%nt>|TSJi* |( ]+4`Y喲 SxSg͔_@y~aIم̌pdgag1L/%ՔzfWN;INi%X`I%Y$!pR8ZTVw3PYYLbm`͠z rfCA2)P-X&, spL#kn'fˢ<`'~Tfdp2bqQR^FBhgژM̫2pYDZx [PIP$a&8IZl\m1 9V[uA\>L"QYd`VSedžx++ZR~&ЅGa)9Yd`w'(SZ>HQ{{i9s\6LrM^AfIE^ܙ,_"B#&\}Lsl6j*{ʅ˨&Dpsͽ*Sxpnz$TE4+Ccw )GA5V OTRR^6"Hyj!),dPBTסٮ$_o6+ds qK&\vf @T}NѩL4:/Npе@ nk PPM0%tp^%BD͎iGs]gN3sxEE>-~筙S.\WNpZs[5&.yOn5fP-Dd9g#JOi<\*ax#ܝۜL5|p rH)7bs/U>5o)~A:)EJʋy.]GRGKXg RJ%ex~f=%ɥLB 2yمϖ]t]w|}=y ٽK|4-9so|>CJtq"c̿Cyvx /#Wѓ:[ L'@/5K]!ŀDJd| `DIf\^ԙ3Y Su& j+I Mj!Z#Jyyοһ]\3Y9rBaY)Wwl-m uwPv},+v_00000000000c ? ^*ά[0)F_;Dfjo8_ΙnΜWPLUj3] 500000000000008b ňAI⽎Ekd]>PK^9g60ōe%'(Fs!a$y?yW#Bl6l!D**4"R\Omp:3tvw N3cWHAҘ\G B!@z?MůE2d`Ɉk5fC' 0IwH`1 nTҩg0h"A- 0O0)'"8e, B@$`|$\Y9"9#ђ 8xDR{ @/?~B˸vyϚth5S~K *WUTNke6FדĢQb8XX,F4! 3rL#u8XX,F< HX,F4lԣlqƙ;+#d0y엇Wk3`,#Kg`^6${|;ڿ7Wco=Go> sDp:ZВ"Z@~{*XO$ВZ{ uD]ӍC@Q$M9NT+Gz^֖+ֿ3kIz:縪u5eBt!>J py(EQ%Tܷi ^bR:2ɴL9CB!rt[gCkaZOyO$_x)BQca$  D&Jw"naPY~+CxIBfE=&`'{Q 73)턆hQRSEC096/ɾ ܐjua!Z]>6ʀC> >1 OMA*Rg'5 A4wwY  D*5$6Ao500q&Zq$C1?'%QQ 5X]n1= I"~bӍ#}@&F`1H7XTRhKg8WynbNB\8B2k 6_6%jÅ* ,q<2so? }wǬ-+9tpSv2V^ 7_200n=᫮0VMt!"@On핗\GiѐR@<@߾]\*nҕԬ]EV"Wh} ^DomۅeR*o`m];^@(@8'ϝGg\wZR_77_~oYƵK +XL6+6لb!x>@TErR2!RgB.2/eN3fkuyTչ>l:znY,ق۝vv;-x*pjTe]|<=0#>άy娗Kɭ\\Epx=V7k7P-G9|9&//g&8E[\+BJ{ D3zPL27R!$B&hiݻS @(:G3d-ZEm(vӟ:v~JvkM9.K(_`mnBhq:z!vvvEqE$9} e٘3 icv J.]ğї읋__pU৿_}$g2-R /_ocME"%Jy JsUyuoJ`P@4ӺgxU9ug|ԗapEBy*L4>n{y/'z PgXtW. ).~ynr+]'ߤwPT+{:?۸>qdHa#D酆43Ã9wg&pWS4G(]Hux`$Y;)4Ǔ2/-2IWIyU>=agӋ-9A{{/u{ Ahoeɣv~.s*go_!b5/;HYjRe8Kފ46̪ㅐ??$'B) OG IdBHMӑnqWU$ ',8T'T\>6#( 0XL0ӄbB.yWWR'299h o?K D( ɩ~^%}wuլ9Ͼ/[[~=@DAAh3;{O?k|%m,=϶0('?˛!>ɱ};81J$6t4@^z"?pIv=x0JdWC^:M:ڜsNv08^9?y8Dc[79[ׯ3?xA-U,7ytM%BNP$'y{ ZI9Ǔ3_$= ﰻŏ(hS}ؾ) ;_3\oHCo T[ @??>EǤ~Vu {ΎaR460NׄD[zٖ^~cg (f+Ix(uDh, BkŜ$ $IZ0RR32 MHXxR"M6.$5vDiJygdd=6ʱ;'~HRGB_kǺ{8g'Z2p{#'|3PaA <ي5q%d,Mq(&3`[2fK36֚7U4[:. ɻk5`PmJE<*WQUf.Ba[Cw.Ǝd$'%HbG1 ѫ-E8yj 3%^52IuWbև x8;ג]޽,z\a&7Ql5 |VVԗ}z'݇6>?CؽePDnijVkoYG@sy(\?w>lKHMx/k nUN<$S«JEG󜢊Ez!2h)F@F8lr\% 6J* )a:nY|z,aC@J]P0QPUh?9ȗ3Ȁdўɻqi:rKn lbѱv;lGNrN=+s rDo<|d8\x|8f5uwK>Ck82@>|.;&U!'K#ב"{ eYłdϋ"b!h$Dc+9K>ţ-BյvЍEW6K ل?p7&5tuR3[Pc>'}#BӆI>wC3 39b%!q e "TU6{pb I uX\,6dDQ"5d` C1r#2x oh|쳔bV/sxYTg\[Y4,9;nes??(8ÃLK׽10:A(z:)p |8m]$QMglR`d5(2R^&flՈ% fdX(s 3@\g40"˙U†;79qmI+D",^n'/eoTX`vA#%YS.[K|PRqP0{qzLO˔՜yq0~4T&OQ q؄2I,$`᭏GWJDlTʯGB=P:O<oT-\`"r\r Y}˝,=NtL1⥰@ 'Lmd"`xlM &!f&ŶA$< A@%UMfT&LH,qb}v^.?udY8'ۖa Sr*YXYI۩s5$^$$#豱q|,F :yRDd$L/VPC Gq!Rwѵ9^>ԅ6ǜQI}#6gQUlO?IH`;S>B24Dº?G`5{"$LrnVR\5% oJX4#gj2DE8s˷Ҹ5uN @I&$n"I2Й [IMi֬%%c!@1۩]B ( b ˳}S9 V,n*Ji߹̓hISSē\Gc*D*@k=٠L7J@Ҥ$>%K"[=}!s}$T#,Ny>EحbfNM3k!Sz]/ޓIVS{HTb˩ o3$!z0/l 3ۇgfs"I&ǢnYӤ3@@,4Ιc̈́@ T Y9dJcn(s pⰦ 0S@vYR60SUPiM%"jrQWVynaR ħF8y= L;A( >F],YTAFF) gpP\"Ho?ֺzj uCלV# e{0mgZp-y=6) 1:4D 94Tl:ŌII,qTP9/>7kdֱ^d|l@ Dw~a2Fy۱̧RG(^1>}bnv<ĎXd[<:Z"J`hPã!6TEA ֶ- Ɗ5h(#DG<}UYHB48ȸk>y̓+KrYNyg ;B?cjRĥZYtXu[[N)TmŬ_WO4?21N$cQbL LOvEKqX}T׮dA{ypi6z6P!!Xհ G%dddH">u7¿|c;Wmg28$ɲ6< {M?dݿGbǻXxgXU%b|l@*t[ON#{Yw1~oй* + z %6G!{p(][HF 2>D3br|X36 01'zؽ{3Xxke>!ׄ؎$ )BCgm- Q"GD<#AYWAQFlԞAj~sT.!z_|bWʡ{a:OQ1@O{6ಃR 4{j'\Ԭ*ݴL@OܰƈswQL 2)!A)Zy$_:ʪ'֕ckS w6p]h`$;'HD"cƔ3-%0:hqSxsM:goבcMDVb||$-pedPRR[Nr\'Xdr),BHκn6ωɖE dLLalb YojЙl,'xKx~ J4@0an QcnDRROv^a&:u,eQzxc%ش CcA m+ݭ pWTJC0^˥aB<1:: RV߸Y\fBʲ 3STTƢ 0% (fZ2Aq0%Ì =0A~í|ỨȲea󑑝Ge#I>7%8#4z=dPQMIs[7z&y;YHō+Ca3Ru=/@)kƳĤ׍bu }Ooja _X$0RPժb+ Axh(J]XTwI(vr]"&G183Ly!nm(* ?{0D^"n6ܾ|gʁ")FVzxg_j7pJld蚈g(Bíw4!SS#4<È&fͤa" 3옝Y,-#1Cgzm ro,LMܺd&M0)91ge5'<~3$:WƟ,v2 "Q:;GJpZ!nX”sΓQ~N|6hp<_i3+HŤH.]J̉2{c:}$1[-מaL=6J=*4aw)3༢3GEIrROTҖDwqjo,9mvn]t^\!S{?}e3r'g#PH e&}b:%tB )Q!%;]Fn 3y^{w|K)/qE500xH?0h^I \z$ztD-YT^Ęt0g~%B(i ~%HzNdը ]=Giq>7E39gͦD#^ )tτqТz:;eSRRB|ɵqqzN&'%eT Ft~|v/՘ Qw<<^t=H͡~i^"Ww^pH]Մp|Mq]$+Я"u̥rnjf7p:w>p~~/#T9s|Kֳ:Nyg7"ׁ+KKTZ颧/4}SSR"/FC!bpqU2yqX/qok!jnBX.a!/@.]j]f<+SJ"%y .(gsg`qyY$0M.[l[dJU^*R:.2kKmͼNмBt-A"&L&uN~sLFlot ivP\1L'0'i&%+X|>.ʩʥn./=dz-d2*)hn!4S\9"꜂RDt#RH^*NP0u`! 29ȱݻ95ՓEF,8X0Nʻoq{@d4f`JCQ^*-ê`ě10Bg}>Õid1 !Mo//~[ă~s!zûW-^7300Fd,ؙS':<܊"TEG&5zf~L*#* @&hT&Y̯jZ':h[ ݊j>u-JA?2ɪY#48̱6ɸ6Lyy U>9qq;H ,V+fU\$FRgdRngivS %PA,8J[s+2ꪋR^v-UΧ050`顾ؔ84,KŢLWV;;/~;u`PF (Gľ^K4vg$\:`" >r-eQӦZ]XkrF\)?sMOH9aOvW`)/˩25]QNsWa4w=lݶ7ng붝0QWS|}{B vշr߆  CUMi nfNzos˃&@A~feԕeffB)d2w%9o KJhϞߋ<'H3ݰM/B~5.1:&[VCi;`ݛhg]u;"\:"a(DGyg7v{^lUap+ wf rzDRVY:}@3<vqhx-'Y{/l=C~u-9 ׿dמ}1g%Vnj`Vv_rܺEB"g.JI7&}xO!agNCdWaOsf$($l} 򩩯6̑QP!Lx2uM~Nf!fQbI-/;AjWeQ!&bd-jY:VQ2$=M>6?y:9LKKSXYM}}]o~6U'Mjl';7Cvq %WV|ܻYo*@s]yDŽ{1qߙ˹yU^#?7 KnUTT-bp(y~ϭq~Y BQO?D<XN/9X(([ヘ&}drіYud9TLe;o0aQ״eZK(z>:Af]%,2|B,fI|tɁoA=y דUAWxKQ ̥˩XƎs$4d~:,iWQCZ73>>3+~zN" %5D{$fڷĽt9YeYҽ#HcyS(855*cu]VdH= )|xdѦyjۧf\"0NSXHAAEx nl;r ,[q^q8g:]H,YVOyU.Wi&ݺ)_WRx q^ڲ({RJ$ÂUQE"i,.tOI`Y`pRalPQgsR#Ih.lf`vzyi+i |% . Y%(SD[Y-N7SH1!ꦦW~zѻ*cue1 .I/%h3aIMvᵽ5_U띘8'=C)/K χI& DX.|$pۇm-F(cB1݄nIM`XBՊ,Rr U %0BWmddxRiH$DFx*H$@DŽ婢IA ѥl&9g6(Sq4 nNDj1BQU!< 8^<+ M噟rTǃ-#!3Í*50H)50)O]bX%Z a:\&օV &IL6n1200""oaSf>(6$eVQy8eD:.g=6qVͨ2bbJ >fqO. %xml%59hdqU(0ȪSLߎ)b7Rӱd+н58N4eB|jw_@QFYoC%$X-^3&(zu΀)d J>ȧWARCJ] v්rPu ܥ,TyaYBkڻF IAA[A%u~vz_q~#'<ӴE~ٙI8XIЅ#-g"S,YpCRyut#Mnb?~G$~~|;wFHi(Y^7Lv$89LඦRc&#ׇEh} \XMw(p-&o!6αc=oy<,K>~ t8AgϖW9geÚJ8؃f-~nJ3]g$bA{U[jh> /\YǼAǙӜGxex='6$skv45BOF&V T$h֐4#DD'݃4;2.T3D H ϸgmer8fԫ\`ܲn9$?Ǣ<䕊A Grc%H"]O|- n\Ա֐y=E=xq%OupRC:FFL(CɴFdj7,ìd4Fxou*69.F5uF!IL )tZSqEŒu c$ Kٰ:qfxMD:NfE& jȎlG?~IEfNKCh*2uyfS}RKo:ǣ̫^"<ºR"a"(mBnQ>#-c㔻gc}}+X@sF%$f2ЄJˆH'!{?M{# UIz:{(ZR/:G>ǗenJ\-b#í7BT+%5YPl!zi!BWbŸh8L,h¤Ab5&)k yE}"q#6@iڷ~n#@=c|Z]哿(kj u:Z8uSv9{OUG_mCM{x꥝t  30=~>ͼ-:(1vn~Ak5~ܷa wy3=LE$#~N;@ḧA"r=[_}o<'7tɩNu31&Eioxn]fb0#*(va.(Lpq=CLEZ-lywH):s25yVR!uiPZ%" 3 Hb|22z\٘'鮄bԑL6~Sܹ@'L 8e2z adh<}/>Ŷ}HbS~:&bT|٘#HPۤv}j>sc``p! ۃ/+s:boV 3RJ{w=;l, o+F#ag``Hn#󶏰8~Pzv[mՙwM`c lKtb =Z,=ӋP9;"̔bhgy]1Q=BI{Vå&'e$gCg6q!:ǣ)EHL7o~| #g ^&@'na>cMM b3J;)S?&Nw OFXp$9x֔b/@Xd :'DZq{}3 Sa4R$Q2 ͈q )NoD_+b5tT(@`a^RLcWA E ,:H-u5Ts4pTe9PN4]BYQ.m%("8d-b^cNE߅lB!:c,YIހ]GK&ej,T8p x7~;',4 rl.r'p?z'$ef'X? S+i?#ari=ʱs3ى x_" RGr:S?APpr7x Q]'HfŐ{Ap5"4}fpa7ig$$|oy$100,B@,D_Djf':96t@A)ʻLŚ#,2jQ{ @hI"A+yե&BhUV9 Ԉ@U,5XC{Ri&RJ̎l֑ac1_R(̦l4t2!rn!q, xY'_s2='D;K4MڸUNv;n))Ξ:m%Iē$ҊhD.uh#!S& ˗3\w:=NFnd<.R׈"d*;|}XwO_m,t!/SlY:LH$$x~tM#s)%jE_ c$k{v)uѱq]':1%-'HvAjI$xY#KHHX'>C™ǒeYPn1̷ ${d4QL >Zس_3'_@'~.N>éSh<3BQ2+r*,!S~L ܶn!^K:%<á9KTH, BMjdM{ogf{"`pؽc;ɫ!޺WuS\l3M:Ɣ%\FNaߩnIF1FVb,x9N7{ dj<졹wWVʽ>Ʊstj#˫s'6I64+ŕ(ڑ!5g":Ex#=z>Nz7Ǚ dUPU6{7!<MPIż r}.lfγ . ?eԫ!4F;ϰsFCQ z;hw/.eL_#`X2&tPLAĢQ1`[1)F$XlbRg'? Ō 1eIu ux,lf!Syub[8 ,V+&8 MGf?zq?XT=Z͈,@$qIlb6g~b$$X,U_ ńL&'5PTV jZ- j7B|k (bIM&@OD LXmvkIRڥL'dbVq$Ś %ui0f-@*{Cf9({Em±(f3:J2fa9I/V\UK,ON{|NJPVrB4w^.?.LfL3}h f:2KTR"(ŵ328%%65PPzR|Yk~-3˴HBQI)bRY9s89fsRY >895i>qxWϪbT]G $=)1R">v] $RÝ}A XLRTSOϓWP@H~#&0xZ3r<|e Yx}4߈p?t! t  9TCci```````aB Bw <<\7 lge ŕIi%A"?室(bՠfȞ2q0tW4I300000000000005#E[qj`G"Dz?MŻ8!bB\fX|1ް4x?Bd``Ez,0]B)Lok/A(jZ* W~ZF${2gw :] >̶CUEF'0ɞ7p˟jd``pMwsD&8֛8K ~-lYU>gQ\FL.bNYhe`ps!wtja#v, %='V.㊢\>B(kwl^X5B!%_\OB7KŮ uw3L\),<r x_U¼˥M !H'"[+,\DH!K hu H'nkdPVUMρ0Z%hL 24&LX൩Hpb3OOճT!Hzvl$Gw_QQC0rwD3[oΦ U0f78sN* !MDxKushY軤 xk_EӗB sl[n 'سtNji Jۉ-*E(v\U,ĥ^ݳ-6rא:#GٶÁ GO5ߍq0[s8F3LMTCN{ysi>qQ>ټy; nGHrXGV#@Q*rꕬ۰{D;2JɌɘ]\#=+|:6]Śu(v?-AQ-F;4RK9(wj6q׼*D"i"i-ħKTʸv`x7}紇s}6[w(]"z_p:6m=/_`Ʈ l?r6,Xmu+u3MKX /ہh ʭ%?sv M\BEj'oa^b,oLRU$l}gaMY\rR(0rf7vnٸy΍D:l#!WduLo3!^{uZnݰ;64г%^ێ\h"8t16l/ik2-/pr[6 xӗ0Wc^xn5X4A5||DXs;\^:$&ƈ,,Oɔ}Axf28Ң#eJSjIf/$y. S=_ovU1CM1&Py,_T,ɱx3$4?t$+>7>^Nˊ"-8\SY!RU%m#4AL[S5BS&2$^u9't0N1LҥL5 9'qy !;GpNN dֳze]L\ڝlnt-e>U^ ,SmDLrm4-u#V!1uc 83u{ f\Ey"͹1C$2zB̴a~xȤdf 訔W,I:BuQ;oKlB.PҒQ\9+̂"Ï7TUR8 G&lJ˵ srC S"a޼ҙ &Ǜ=ɺ{ʱ P\,)MTCf`~&R.&o5eS: Z__IVB2rԚ8[o{_|ٶK -ȱ{RD +z[=lexG4X!zRC]яcATʢoyژ]aN<@س<RJV-'?OeC{;x`2|<^yBǻRW{RH |\Y"T. 26Pdl/c3_^wfGh='ǹX^j^~?~& SvkjmdVO8sC,dGt`.Z R,m N`ʮ;7R31̡m:'vIF>s&h$},xW|nYD9R16у9)XCӎxjk>YYRrX7 aQ=Px-Bl^QLحft&C\育L8Hm(s+ɳdfV"&by5L A2:I oიEeqfxtֿ ,-5^lQOt231ORTLl. 3!ב'_W$&2 Iv'~1}? Lom_Cc<_6'TB;z)Z8HgO;[%+WL >%s4b6gQh>G@t;@JpRR.F&٧Z 8M~K$Rr(mc8FwlPHE%o6GXV|*xJR9f:CCd-< t)%ՁyMjÚfێ# F>{Ѯ2θIh1ES%`EIӉbl25T,dϟ1{宵hCuA3~vơv:xo׎Cf-!| ~vƒ J2Wᕃ`b7h'0|>x$oo;}$y@?VLJw8qQIBX!}YZxh :̔GAAKb壤%C1b@"l[*[жOʭfi]!RVXF]]wIÌWJfI=3|frehmi}`ZqVe*mts>'>#4bq{3<9p ޫWRڡWCoLϋOn;,ɯ^bʹvp#% 泦>ںL0c9Iu? C M1aIuh*$ RY miE*X!ts[=Ƿs1ĬJ Oxw2Gqs:9"rN$H0'IDJdْ%۲wVd~ϖk[V)(J DaL9vOXutc0H3[obGjzgpzQJ{dD3YrAǏjGIoYR\b70x#DY}!>K_0M"2G"`qt xpc'xPj~*ن[L$8_ŤxGMro>GVg0Nt.L־;hQff3tO.?QUN@Q烩 t He5g5Z])pٮSu^,2dQ9=F>hkF (C$32cd۸=Gӳ{= 1Ģ惧^ęc'NbsYxEQDQ=uQ3fcjAA dq"q-'KҰ~;^9#+%xgq׎V/D/3Ca7.??_iejxeidm %v? 2Tjɺ2‰ĥKń(%,+^3aW"t&FOӗqXܝ ҤjbGS HTڂjfFB@*&$@>]TQa x2RK3P\RObX(fbLMFtbw߹%&ֱlXldf3cjh2?nuUڊ:"2B񘉥Dΐ,nAqe ~f:E5x F,^R'8b%AG"QL4,wCUT5&"dJ*.noQ9"d>gRUSF:8@N1I_:.օ5Vyf wlaf&FIɤdu \|kmr1^|"JYFi?adA;֬d1B3B4\ (YttBB#2jf.hwJ4 ͝qE|Z%h<юafgkocp.ʭwmh( (]zQ*wٟ}/qqS|) w!v)-L?敳ah:̛32x_y]芊9b+GcXChQB8-:gw?S76Rh3q"ɌP.XQ3Ѹj k  E>vCȈ\?&"lD=ɱeo[Hgb"qR- L"@si~J'&fhD*28[Ϥ.XIx o1{!3!*d]b{u-ʏUɸFuZ*, b`džE茏N j Mqv,sE\\QItip)EV4a9NMPd|s5[*Pdg~7h\p k9w`H隞e&,VPgMp|M$ d}X1wl"DWf1*hIB:˗g[Ls~R@6X kXNsIfc&77m2ƉBP/Qr-DfPxVɴNac3ojni;upV'Ym e {ڦ@uS}F( ݝ˗yE%6o[`i"uSi3M%NõB˗;?WK8l*bS%&z9{‹/foܴY(ٙ8ϱwD}Zփb=W4@ CgH&IKihǣ83k_e5~L L7OWw_y={̳ǰ֮`Z**Iw92X?i/;ojo.24٣y 5 JKXM*vʊ[fiR4'^yǺ6ւy(nhayyz/I+Z#|$c$U'5uS>@(`5^3%+/T9}'FU52̫=ѡU+X\_E]r$CSIJfʫ9vUDz'/0>5(=݃65 B:M$`1[MngKiiÜV&4v!&NkJ1k."#Xv£=ص f`kE!< cu/Cna" LG$J`jY饩Σ<aW+-#g9u4}Iv &;3OpBEe5eEni:у̘k*ʍ3Ө8zO73…NWoEGƧX޸hZ(wͶqtxuoeہԦ932L<>ILKncmEp/xi: Q}U47Rv29+-M =)2uZH}QdH‚ *T6/tj@j1&S5ͯ#%R;GF+~o)Vӥs+% ʠݔa3\j d'lme8P̽oئ^ʘ%$IB)%ȹ|!J,:z6$]HYqAL΄хwsDSL2\E-eb2 B q&'&e.;sQA*`b*Hťݶ|/H=.2cٛ A_ oI94M+e.e>^F&AٌŤ^{wSW/Z|J8qMCG"}Đ:U8*t̐\2/~#|(X3HL/^b?|}^WY]puph+oR4F >bk) B2\|y  Y]ύJ.aΛ&\cN->Ł='vꜪ?}T^`,l),& &EYDCyUN׉R'MI0,Xk.y\].\6\7@r:R76@U 0>ƥMK{{=Vj,u.w_u`pxtE}>{#Zކrmq][&RGӮ](*kLfEcϢY r>UY@Z//uhW퍋D׵?N'K\.[_Q_ڕ_Y\^M״ԐWua*p]gզN4, Y TrJW柫\XZI2bf9L[&RjhƢ5E1a{颖1SSr-7FBb]o[]k y |׻n``EJ4 kr/tB33o9Kk̏+.?Xs}kb5LMŠoTn5.ÜTU^l/\"%30"PG s̟1_n.AubLj, R*xJ)PM(OwU9"V?;x lm& O 0XGiVR4Soo?ZeIiPPōnQk```p9 g\*Gaeu-0ݮ hX!%nD800x7By ˜ nxL[oJ9"$` iȼ/```````@:m*yʑd*tC)Grф ׂX]' _8]* ^팁f> 1Qs$,u|Ikb^n ͕mDϦo24ZoH=C`bnWKGe"700!2>Khj: 521B*zoFMނrrLrպJNDI_xIT"J0$%_?PȄGxG_㟾8!!bR9/HĢc 4y⪿ddR/QhZ6E8  L319E(iO\|F BD 4s)Ώw(t``pPD*DsU~x)Jp7N$*SL\oMf8ZVUEQk(RBQQL&mQ<dL,J:@r.2"Nyۧ!1=œdH,ܳ^iBM'Ec$RyKוK{+ڙE)$u(-BN Gc}H٧x[Y2=<O1u- H:7@FщDԮEe(9d~Ҧɇ-\#u̮2K<zIHEg&Q)7RLp,D Qk(qMdb!,BkxNդDIk>B@&.Px뗔 ƻ~p TɀيLE h!6P^UEȜh6Ixgڙ$H$Xl6$Z6mWR^YEPr][$=ã,Ndj50@hch+)Jhز5#aW=?NВDLG0SP]tq҈25Yq )-D\9L8qp4LƐZjȭf3$#$HGjV֡`zs?u)Eikf]094d \f:YުekG'MQs DH9uPJqծbfhBl;") ncQ @O9w cZ*FQmk)vZ-*GRK{t2EߌƆSl*Fy0ns???"ˋ V:i^q*Y͆Kx]Z0׾. 6|w\{gZ]|kcL{wŒM23O%g?>tY.}9-+YV[]wJ vo%V֑~굷}KQ4Xp()$Ne <'Z>'o]Y?*v䔊F10xGB2u=v~̪@K=ݭG_r̛z\RAQ*UUg+x٭Y}Ӂ6 \=Oƶ"wMMej"fI£L9i͇pti%E4l#͊;Wa2)d'^ܷe^-Zc×> @au:YF8O?"Yy zH.Vݻ_qGPLMC}#ك46,ŋ]AR`9}gVO[m|ŲV(g:yTܳѓoO<)w z,񧟹rD8tXJsJܽ BCgSYoNw4TسtyL|Ÿ{"kw^MX ޒ.U(X`;>I^i幧`E?q +VbQ߀#ŞhX b[̨ g\sэE}*`=bz:@]|ğ>< ¨8ӴJWiZ9AFi:O2D E@MKc/^/ݱnZj̨J>5kBUsA%o"6_B(_SʙU9*,M}EQ/e/,Ӱ!{h*Ll_Z L# [GfqEf5T%n۶Qh;/]@OstdZL( .Et cducV.ݬ,ۯ;((j~7m``#BrH{Ek~:N)shśna~V:uh82qE,y3l?:?gj:BCL'(o,E(ٴSQFЯp-c?}2\n ֲT(`ta,E)^ӌYkYOsmd=Edng8 yrDfIZʸOܷL'u8Pkh׍𕔢F 'EnC3J"AtWZg_JMt8I+kd0Uޏjyj&r7xR*nbb8\C%(B[wlg@IwZK[Au̅e4:=M%\S'DN/S2xoq.hOǎulX Kp>ۂu\ֹi]o$ Hj {陊RڸQ.t7 brPM:7{M"V 4cA<~V-ƹ8;MArnZTQ %Xv-5ĦҨ,2hXe%kP!HGga.#8h\Rl"p Ye庵;Dv1 VZת"  2ȪT5-n_‡XPI5cWh9K{G/ k k֭)M ?F"+Q,ē3Y 7͋)stvt0X~ ݮE:*dž#T˭4DW/ *E#0K$yQE.+Zb}1MG9SUƆ;)OkZ*Jôc׳~2kDfGv)enT,0WjA"nXCU-Y 14ls^ƎM،%7<js{<*͗:TKA Ir AjFGZI5H'@vb@Oialǔץ !I Ө~ЋT3x@kw/D3RoqS':?sޯHl3mxk6t6JY^*{Ϗ K]>ڽ~lL},Dխ QTPE젡Gi~;;ƘfʵCSMnvog2t; l3c؛6J&qUQ{!4=iSH0SV׀ LiU,H$$H஭܇39X.ovP6LKB!6zgńbs9E cH z:EBuPN<&`@HTqx\XfC\OǮQ2*RGP{5yCy=K$0yXєPx&:_9OJ(z֝Htؿ _֣l'JsY_g_4( {_|PEa |'/20xEE:BHϏP((=}#$u%oPs|dݥV~O阊Jbrּ;Mjs̥b=Ib"Gſ>QP$_蝈B6̡~ĿeYPW!,'8E&j*m`@ױVvc#s JdCOXs1@$ybPl  fl6"Px#N W~ =…q6켍%eFJˢ &.&dO f%*%̪9Hf.(^]7-ł͒KKbEQ\d7=ٓg0U.yc5V!m=v}5ʙ+ 35nw? 3<(aj&*}NܥU4aҼlĎ]-E?O<}H6C苐1(odQ -ky %$lݲ߳nFC D&DF"+~ԹG{|t:l`bYS)>Tk ?Ǫ$O~~؂%-lۺ;x/fl,zt'{w)-n?u>sp*raxX4l(d"Lg.p4T{l_o !@HfӤ,̛$g#ϣԬdÊ7-a1?E䡦 رq5en3: ְuoq ]DS`qT&{:hjnDUM[ضm ?E$&-NÜNXP˒u7}LFYc`AOߎDZ\UH-M,N0z_H`*vPãL).|n2^BUPVd Mk6Wȋ{ bؓh z6/\+(8Z#)u?w\Bޟoꅉ+B9d mSl6ؐWYKҍ7qۖ%$.#y+j=D98c<蜈d2)t][Dj#ɒf@jYRB4ҙTt_,L5[0ے$S u~me6iaFwrlHي2#5/9-`1`E>m`H)~IlxuH)XQ H vi(:molt6# yCy %I[͐M21c ̢p_W'|b7_?mF%Ɍf㰚  uC/ȝ܁[/ż_~&6ş4,eՓ?{O>ϊm8ic2Lׇ3%+!1ÉkwU:&8X.09A \*J=ɪ5+xOc}-KJ*10!%b_e`|}͉R|P,D]YY4pVX]/w0s=قiäjWF drrY*{͎jcQtl.̦PCQq:]3i,D8n`^CuSys3/)lʅ&5-,L /q[QiO"UPБt2K'zǙO{iP.,܆1DR`80(҉̀د}QTͦ -\Q~D տMGAEhd¹/5,B:Sx۪Ͼ~N+˝ U +£> ΀-eZ.=OJՁL$ArR'ⰻqxx)Ln*%R57n0~x[7BHF95r]R1!8(GD$PɼL 3aZOQ[VբR ^?B9 IbdJ*7XvNb]f*Mut]C&JJX-iDlT/<}gMFjHłccQAŘa6׈|5 la~1pz<Ƙa"ι-˼AL3rGWI<0713BPPZ Fr'R )-s粵|aRYm"'D4 EG#|*%*h oY9" 1Եlo#Ng&иv%.1CG dBb(ie%>VGdlФ$i NЮ}&zǘ%lZ׈EfIO1ֲeAi&F&p7l8d!rH5 Luܜ+kQoE D`*ZxaR(L'^=#=dTOAQUH14v m4(g^^>O*+ѲiqmE$*W E!e"b4sYj,'{_=K$kY Ͱ#D9C3q˚Xq9T64R`H!XC  $&`6%0*Z&+5QZRDS]-G_C\@0Dd.t-_$U c]1QEw|_tPZeh)Ol UH/FZj\'J::lK[\Y̛ 1_җΥ -,)ZXT@+ӟ`CC{!Z^YXXp:sk;EJZ}Sl$nǿq3N&1Sز{٩BUȄ&eXVIkebq kQ ūHDzϋw2If:ǐ bsi|[Z _-9:N_ T%7YjJ(X@lhXB tI ̑']Ѕ;*N2\itigE}&E[:O!@04cQZ (G{2Pl]Nl8I%>1BSj;Ot7q8%p9%ܱy%NuѮI24SCt#b`ɒ&jΣ/-@C:J\ogw?7~<3Ӝ?yٽU,_@yӄL^̱1NwOr.WxI6er_:ȴZ%8ld9HѺ[YPxcHM=#PZd#<3P/_>hM!#<8e-Y3{yf%4:k=cmX*q+Iҟ,䮻S-)&`x*01+U>y~ɒŬZZ]9sGGhX:G=ΒTRYζ+,+4+{56Mpf4e8hfrx}Y! 1~^{￙ry^ڻDa Tcôǁs,ݸrjKt;O;VR ^8ƹ"~8C!fGM[(qf9yh/ltZ+;l50T+KiùG虌#ib$ܨu}LP x}~JLt@œ}8r--b&)1):j"8x_nÿh WoNy%^ie EVfWNa.Yʆe(ZΣ{6Im4$w,i"494=@QO`wRSGgH8Wl0s!*If%)M8l ƿ39A<2nFB>pK8Jd- cVGxʍJgΒ "#wNQ~9PX9&zg.]@ӭq؍!Z/$gf.eXU!JS{IfIjN*n緃$HexK{" IEXD06Se6aR]*& ]14JsGg]3n 1DQ} ^bQRRB*8@"T179TLEU)^wnRӲuX'K),]j2s"ql%عc-ENt6Vo1q Q)nte㶭4A ,'jV._iAyhZ܄-b&S/¡暭_ɒBIAmi,ߧʑu#˓\/V Y ڑf( iJ]/EU!e.nĵ =1Ï3wㇶ`(B((=BA ѥD**`>~_O5C …k{|9 ɛO]L{1VBΥ[G+ E~A}*@4tsQ@HNTY:_PTT%oRL59w"2qy3". u(j\e}OC/%ic,h+~JG60rO* bH9Z/sPTKKi9AUPM W9j=5VbQ@KG8c<]}Z-m`@jF8Nj.$LQ^~,fe~r9RUYZQ㢸X߈\M#^!TLv0 r_Fvu;0ٱĐ MwɌrƧ׮yY\~!^~cp@NGSk׿u:TquwWA&!!N .pkB1GF9r! @KEg0Նd[XBâ%4VaoQ?4{,_-wŦ2ԷQ[G2CWO?yf<9Wc~rqy &v}[Ur700ZdS$1:i)5-MU BcI0Y8(*ut(db2R@64ع8jAkVr ӄ{;!U4P\N.@L?GprdJ<@ÜL&ih^ɪťR" 0؜x\kmg" 2\dR) )r'6;&U :)6VfQqv(Dht4.S u*5,gբJ7=z//vBp" TfŢ4!}_H_M5 Gj?<ζ>ζU ŌCD9z %+dm/AzW?aT](B!9ɣ<ȶEx⇼2fa:lJ^ܑIOF. 2/B(a.D}+hZWޟњ " ~3Q~N Z8f*(z~B]둽8SxvY4xB|?UFM"+%}UcC/gO 4UB!@O2q~fK  ~o>=/sMkW7g8ݥ㖭ئp C!ən~nd[|#fV,fҙh#t증4fy?cܻG3i6 mɛxo.$)Jm _CM{J*\˒dqRr;՜((7 B*S(9y6v`去Gn!_s'u2t{֨-M7rMg7B(Bl'x>2wBcz:AˆbPPP륤b?bjVO7zxG_i'ť:BEh:)rR.V '8M4\&ËՂfa! +p>idRQTTUoB(LI&S(J-ĥ{;ۙ(W5NPW].hByw[o栠KY)u5 )*)g]|ዟ6~qz4rY(uwQ!$ w!v #K]Vr ]l;"rrY_B}߅ %6.Ʌ#L8u&7&w|?-k)/)WP@qE> ،\ %ƅȿPՌۅWGר] z|'[{gB,ZEND_lk"DUݮ%o3H=9lyh׭Y$/oMXN6课ͳ=>7V‚DtTUjQPf"Lp:1 bS\drfv\×Lv6/BGN-kąLRa:~ڇfXQVJ Gu,x'2>=Ԋ\ ( OR~>p'9s,S>ZO`i9U,!=e,飵kX7/>oGEzᬺS6{y;;;_q[*U;rs7J S#>rb>NJRz*L۹L'LXd :ɏL{?z$jǻɧğzs3ϝ"YRKS] Th\΢z'b;ѧ9})=lUw[A:Zϐ5pQz^osf9 )4E4z7BH>{V2~#F_.J쒱V"?ȞS1>_U^O=_>߻ gj] x'=֍(Nq e}vD'v3CbcF1ͤ#\~iz/U9ΝCZO&2SrI|U+1|Z[7,>?Ow:XT_*u+/ɔD mf'9%hK'?Cne?{N?ܱxBbSݼRj*=*C=Ldʸ#S쥵sD'9F8co)Ό*#1W56™B);rrr(w!8: LWT2tzGy7<͡N3_?cUMOBHyzO+V."S/W蜌`ze5M|3_>E7|/!fHG& ǓIs1RCD oi-[o?)ƥ+.bծ{ܵ%$83PD|_ӻ8թQ9~ya9:9v;?ĮBMl·L׍Ssa < `kO}wLQy=G&ML38JJ8XRcײ{k!<}9\%XҀq)yWJ-3LXP0k.!>io>x3s !n;cctNfX}?"koκId:ǿNjnVv޲{nYG|Gj1ο)S%=q^ੳN-ÅiElu/ϳ>+e.yb$r0x8u!>qR;=A(fN3cc9'i@qhϔq۸eܾe];?AV&o/J{{rYflghB-f˭=6yuaiC7Fo:] :蜊]ftwcddlXFF &'o0[A~O^8K\ Dt.wAE,&J_*Fd*IH`Pl80HE|af+B$l5,GWbT G~㷰/sr^߲B*E]#Iy+d<{޹ U+O@:{qn͚墀l3O`jb d,$ "|.A$ VmDŽ@5[ PT exTTV8[ҚbuIJrnmrc;]V%Z(@b=5Lx,NRJ 6z n͎d,oa >k] 55(HߴHtv.PG)v4w"67Uo/cicxfwu4]G씗 R`Yͪ]ʡ'ȷ-eZQ*Kvqֶ4ދ!GIe r.HY- ;R"VR&ɲ`Jf,6+!ʢsѢA"p`FvwVcqQYF(cO N]] , [xNN v};U\Ma)t3ಂH$|yW)[c {kQu>_e{ObW0wbMQLb\a`K R8Ԗ82[LNI@1Yn -yͬ E~9t)$tw*61/bϔ' ]fTsIR#6;B@%wEkܿy-6z4ƙ Q}5c8f[;͹rDG*.¥ Β*]e/:=g`asI >D㺝>-N@w(,],./_ RrvI'M3հlHeyߋf.nhλ.nҲz 9{,vWfbYp,D&Hc )뼹qNB@6#.MR1q9QS*vF#DyX ˅uS;FnZ39v ^GT9NNI1"/w:n⚟)@&!+yYI f J BBYuZ02#l\ε\R400؏EQme8G QRs1z ջhXV /}AzzYj"$(f+6_9V]˒M&pP.x<8!bsܼ-tDM(`QӃcedw)vb9cѥ@U%cݟa/c ʎbuSUA(-aWzɮ(zAk>Sb+ޏ?̩o60 D$RvQpT\6,J}017C2+p*%%mx~< masQt)PN& /Po;$ j.S\TjUd)4ɝj.ZRroTt8YŲU 2I"$CzZbg\Z]*\AvWooF6axF:.}=,,:LeD6$.(JX03i++Q%R -R"܉GGXv}(BϛnJ0M/z%w~=~]b381Tr&Tk-(L~%D&3dlօ<Ml\Zr)*X&Tn^>vsNpsX*F0%1$x"ٺt7~;c{yg~r/+6J" y;XPo9-\8'柣ad9VTǂJ% `*#KǎOVc*ku9<'p!^9txnk.\`0#~|EPx EdԳ$Q$3$RdLGgxFCCAzt&V:-SI&$DID$TD*'ȵX *K:y}9r}G/H$DxFFbh,@bz!iT2WD ]Ib$1i ({s9;tIf/ݼtYetqG"G $LH$ G׮_kĢQWȽA^=؅=c{9;E2I<)_ *'"I+ҩ>"(  30<|GHk픹rn#z:Ĺc8;B⠸ӊ rqJj{S8z4C}ol[ ͷ˽;̻?K/ŝ ?BeqK 5nT]1048 {nAB-@ 92_AMY!B pqFSfTcq{)-)oņ`vhZʵdd4՗c3)&4MY(gMu(]sX^kG9vNAY-unێ?YuSPGee5˗7`O;0t|rʽ*Nr{M]}~sGO2a/(BiG~jpS a ZQ&BStqYzFpU.`rB"xXXJbjβzV.kk7!x.# 1:hn۴ 8(vb<*(k<ġCCĬf mX>8Ó*YD8NaUU.*.蔋oHC!HG9~:rsFU" rq4<2nX7CiY\5 %Rוn?eԕ ̀+]#2gu,. 83t280DDظy+!ekXWU0sD\EŔ},<@YӍrIfCt]hvV)^DKNzX}ܺEYYf9T᭤Ppq&*$QCCGHmT؊ֵh(CÄPZs5.fzH"︅œA&4MkZp8LwŹ|͛s܈eМrmT1ԼQV ]g[9}Zn7.9yd:;%Lh.֭^Ӕf#ڙI b/m/GwF62E[ofm!%BRЌW$Yv4R)Vĉ]"f:!a;R4!zFW{'}#.훗ȯYٙ4ǻL~+W]_B յJnʍ!ZuH)BZ,!ģsXR\^gEοbB˂ E`~Kr\f t]\ @^G{ 5(Ӌ]}e>wTT|<˿"~H@>:L2g=_{\ WsQT26c'w|y?g~{;{)QYVlYvbvbqlIvl&d8,]"+@$z^Rde̙3=o!km,5Ϙk'<;{LJ[+~9SEESqKW.EQWfPPwN7aN杻@ۛ}o15hnɸ:H]b9sblEItWFg l]2}tuԃ~% בAWb(oL{XB,7u_zB H6na2W|!]3ĊaN9L*vY`UCi"EGYg9fM$C_hf"irdqNGqT 5B24ʥ.c.L;Tjrv6jYm^ Fu~͌tO}yQ@VW-wTe~WbG\d"A8Rb#Y}BdNoqfFh[p7O-υ,0(-/gyegAaxf&U"&gm\E{-?s]Xs?\,̺RK 3t yMA[=HM XxD3rpghQd) [IDATxv7sWws.g7(Շ5ʞz(fΞtx~=9}C}FtYeS#p9U`5U_|3 e ]Ym&_VF_,4E5.SQumf#[P΢IWY%>$׮k{Wn 1;sXy3.bש9XV}syjh}H~(|ךH:C4^}hTsGr{?]H|: -E4cn !HLtkRgC-DX\8 o| `S)udk73MtPJ{<J,c`5x{Z ,/p1x{r0ɶ?B$uVIM p_2 h+i|m \.x1G7S "(bsw "IbY}|I#D $͎jRO'1[혌T1#\̑70Ypy2%Ƨ3xG,6;`t~0[x_/<vi:Í+GDg+"ކ刁oDb ,G]uC9bN䫤ӀߏcD\I)b: s:ܒS!n7000a3WuNƼdyM(J$Ѕ :EQ3tZ$]{?p闦_4"NCZQެ1zۛp]? )59LGWBaY%YÕ&2~ַ`W{4@ x3_`VAinbqڦY)A۱V,d9ns <~|kEKY\o@&B~W^E/YٍB(ćǿ;vذy+eߜ[WBy<ܵbX 3.B㸖`͌>!+M|ht}WNWVǪ2vlfH8) c{'Z[T![q >J# x14%PJYg*&U+7[A1y~gzpi:Hǹ!, yQ3,^bdIVE5$.pS(y(fZ^=ך^}CJ ~m%VCh#Zx{5d`gH7xgwOa^I6^i|~/ eeM $Fyx8t(#9HV@UrB&ʩ>JjjiGFGҫtDzUz\jJP 2p^8.jWc-0 iRgCmr __; ħ9}396.{'hHd9ᖓ[-eG%ma\ש?xpChdxhpBcn`pkeVTPJՠ]Qq Ar΃Gjz55C+G1hJ*%~n/mGۑB8'[k)+D̑"5E+/Sz[5rS*ZaYUn#q%Z rCH.dw%K(aYMi Do5-[ג_>. 1I[(Kֱ~Jb& :Gqgy~^yz ֭cD¡RW{ކh |V*? McIT=_G~jmFY2Ot$|txn53嫶./ȗzc,)Bk?{y8p Hf9i) MJTՄ@*$PMf,@'(B*'ILf+VD*6nl'"5EG2%).?Cг] j(JK-]tL|횚QI)?IυIU 5_&\R={S-6JjkARdFX"Kt ]Aj5[0"O ̴kv}kbbRR$O`Z:QQb0Ն$ВI) jŤH M;b`Vf!u .`eԷ^*o@2-h *FCf!$DlbVD $ 49HۖYqN.)bRX8:Wz@Jx,jb1$H!Ӝ2ϴSiϳ"N<D2]͊*B(*HOX2">9g-HMǔ{XmC!2`K ^"YY;m)MbZ1)T2N"!bA:xM cm*L;5 [X"D*`޽4MGf$$x߫f z g` Ŭ@ H0Yn#fd;hHG!ͬ_l5n&pvH兘"5咗ϝdxRW>p<~)V쓜Ϣg p9DQ},_U3O1'ow,t2X-酴_a[m^nYvrOa'> ;]؏A]_;pƹp ZGZx_#I,gq6#p pκCII6.GE% ?Ѕ#o3fUAJݕEVaRR,\5к $:CO, ypQ[w{ Ih{OP7YcsNq#ĦUTKaeIs>V"#>|X{Ƌt tc?䴧E8m]L#Lٹc'M+`7{Pv֪+ K,Rjw܁:38k(q )zP]Oih3#{oT4.aӦm}}O~~yU?͗ބj} n>VLThO10#P.v-#s'8ו`ßa{CO_b7]' |tDž'Rp8X92gs t+l^_U@*2©#'IYF/&ܥXv+wܹ&BJO!k ?  3R1Υ=y똸 $W˳4=^YS9[nc|Bmx(x`]:F†r;NE۷xE^$[H"<ɽp|;wǶ*yATUa?e՛{R!h/λXŧ_"RO}A6\C/Pde.[>Vtީټpx4l>FT{^˸|GEN?{FܶC1WMt573Ŭ 0-zy}~{dW0r~ѤSe5 W/[ ň.a٣u~9d<+ "=;)4PV]QeW`vyIFb$!1TM< ~pkfnd$6&YͳDMc$"F(kh3>r/ީ^zq~ ye|~3BJsaNy?s oa1xr2 Q.?)oUt) M";Bp ֥0VL?xD“'TӌebsO1n7wod&b-mNq=SRh^@X:Dy_ݐfêgҩTL&%:&WWfTtVzWP`"B~o >t:S3djFB**ܰoB3[*XVvM@!A*d-bQm}fiڵl_ !&KTEKkudn9Ue%, L(BgϼxI͊E(,6+& Ӊm'^O㰃 [Q[]ɲw?=6qfR[]5u6rǽ:װtZg]dL%!<`EnNJ9ʼnW0/g}]1fjn۾ƣ9:edgRWҒr6lDIBdU6;. ŔB/ejJ+ijrcG t5wXD'ߏsЬ Iayʳ@(/Ž5RVG0CKiKVs,:/e0"08FVU%Un"S! ŋPS\eU.疭ˉ'& (!v[r)-q00:FR3H?H  O&:8ؾs3TT#D)kn߆2Q(}+/YDY,*[RÊ%Ue&P$}],f;1[]15eFK%K)QV$"oTZNe h)8:hH)rp֟}_KOD]RI=D\$ +&:xϤ嚾.A(BA& 6IJAAM1D"ch,HղE:G A 7򵳄3L|˟s~WB8A0@'0Kxb֎oB=p_1"sd=b1LQI38]5!J]31ML⊹tRgeߧY~*˹ l'?9Ebz>ĢV?n&fִ- mzûP=A{9+sJf M79PT ]sIv~V)-Ü^Lkʙk@ -D}Gd2ㅣسy0e,v>{7w^WfH*W(̞}7SV 3PLM+-sh<~.S|zrB7Q:{ХB^J,.">?l&2%o1|[U2%‹}K%+}jF/gߡS(;'4MRb',4 P.!!zGp.(ˋ'+ukVa<ΑK 4Xvh`}c2B`jX"'$b1jYkZӊ|(sOo 73>)} >.HD ba#DTu;Y?f7 <9֧XtpH &SDF'Vq.>"t -"TȮ(F5b t)VŘAC/-SU`4֓`]VaKnvH&@ _ʖ-+ʬfPpQcb5#Lg?ˎ^59(,)m`6ۑ"$OefG*[D^$Bxf}1>:AqAy^3"uOM@D(-`䢬$]}$tZQ 'ǀwh>*/Rkm9=JW Eي #46+*^:Vm__פ*3 qӇ?>ŋDxBOGȖZz'6CzJF\b̞6ê~"N汳 ,[j9~q)tZVyY1관HF*`1ݕ9%ظa'2]א) А"$$Rt dzHzx &\f0L6ͭ[F"(ͧ,rwn-㱥3:z,$ؚ539{O7 MDӻNBӌ=BJX]b5w+IlyGc R͸9EJ%J׬g]mBVEZ(s3>1[C&' :t~_TJ]׮XeQJ_ʖ55:ȤrBh!蚴ٽӊo=N9Ub)&&Hh1t0jWS_MOOWߤ@!NW9䡻we-ܾs3^ 'I0R'h( 1 +wm "ccDbItag56w+Tz?)ѵ`cm:nt2sP%Qrwu6} <(B!-}KWp=RbsB@hK1I&J-qC իش(ɳ/i2n+̝'z;?WOߔwKhAWT8-dI]$ϚQ:i#H3H)ʬՆ)0I"\ n>1Fϝau(' a]"_urau98l̓v;& [JJ @,!HMv3:bp:V+Y77u؇pO QRJP2Ư9_1:ÜUBіUϟar*)[ڲ׆f5yN' LmliCcw4KX EQ!\,k2A$S#hYQ*%}x=4M!ŕrA" DYr%y.HNsDek6P6L}R]˭\8Sx\ pimȵKFN?R?v tqu&:6..` 6s"-}TnLeݰIL[s]?Ё:kUlA~99z8젝[v"?"JwezU۷,E-F㱗.M+qlwaIrD=TTt#b(tZxH*T,^B~EyNljg_nΜJ\:'|Ԕi`ϛP^\ug.MRcoɉ, ɣ$`OO728ɥp_#{} NN~yM^B4t\[!pm6 )ZαgqGx|yTTWTNDo{ =t53*TXk>tbV b vRN_`8F3tI-YgXc jK}t9ě.qdMA 3nknwB^(PF_s=N7CVʭ;֒kR1<,%`V8Lqߺ1΁7ޤq0EA"jr̴;k.Y{b_d8JV={8Js{+NԷa7Ibc=-==r5w\j  hdd 2tPUYמ`֖yI6م,-$q7gPRx 8 tfwK:  rqN7gpIZZ;Rv;kkDF;xOzr1'hѓ'dhbThӴO`QQQF~n>e~FZ9zޱB*K((̝~ڈX˹v(MgOrk  r݂8x5%>qrSQݬ3rsC;y8|B5:&ڇPE!8̙s4_joO2vD]±7S?LVx'tQu7jrP wɠZ+^xAgt]H[y6iγ{8==̕2<&zZkzn[_S-8tG:V{ȳEh=:o<R)(R{}=D,zFr4Ml1椷%WW5=_,TBJ?]J{f\&I,l&B$ٹktjHL#h2Ljd4H +&C Ò,$Ñ)⚂4 NQM6~/RL&$$,H9~˗V8͂hpNw[ ײR'$@QǍY@ &$"A ۉYIOp,[zd`,w#c!&& Ϗ H_%sz f|v3L9j1QB1 buc*T21 N7Yg?Z MEt0YdeyD$d(&|^lf"=ƄCQe @HppH\C(*EQz``h n6%I4cXY"VY>&=D`xJbsy(& E ;h Wqɘ]t@E:`\Z\-?9U@}Alݐ2poW*E1tcF\)su̪yڷ[ί_ìq"tdeNjm)cŸ.J߄72:cuceqF+,ŵ/[ȇP9f#upgfe&1\ MWWiZq>+vm:Cg4wydrCfS%eQ>ьUAGѯV?Hcm ^= ?DEq> nqM[)/"m#wCY``qP:|o7T[[|,x#aa#cpWn EYfi``vwK-.E?p5k`;gSâ.l,_YCPiPP, ňGE1H#R[jrKE&M, &W6?4RXT/@"˟4xX-!l:I:5> >ܸrD"6V=GI!w_ orDffC9b``av& vl``p3(t'ݞ k! >`J~0}Q}(( }GK"JP{´C÷n2XhN<8M|釐MrhF?4xWdB{e2!Dz>q+ݷlg``B:ZGɌYdZwYଟ?wUQԙ*s7/[Dcl"''Nj5jNhP`H ۇm[ B*B* 뛤Z2XaiyOà N0:ن￾ ?⟟C.b50x!H'FHi:f|,א_;/  3[wTbM')DRp`g:-2)BE(]. '2WvrZ^RL'%u^b<DWl]>2  az;FF!\͌]IˍzekeAWir:.B +˃Y\K:z%dI8,awyw-JGE.a*e%:W>ƻil",+*D $Cm?#ǓlbQoRL$-i]T5xJ:ԬL~ {x:TmmK Q3O#@Ŗ<@ Gc4!2}cŚU8߳4B@*6Ņ=?(_{ӊ0D]< sxnJv<Kמ@.Xi FgVlY]8W?'֕]{V** M'c7x hh '\leYu!$"w9hJ( &=M4!%,YB r 95a#4B@1 ll,A,ajͦzI<4@VŽuɵ uOs{mYSYÍd'8uC;8Wrϝ˰)S6DC(r[?|sM}$UEμEl^KѳHJ颕%!2C2g9ހǴskOP-Aw;dcMdJ! ų[)[y&Δ#BǧxlGzj\Kn{o|>] ^~^5/)JirPj#+Ujټn @ -2ʱo6D_E{"lW#[qOm5N?O?|%9Vd?kŸ.Lv_~3F5cGpTZEwR[Ć +>}ҥX^G4/\ 9OkjQeǹť Vg`!E CSW}?޽":R Vb(( )8~i:YUDzD{II$=bI:!z{')0Mm9d;g($Yՙ܇]׈:sߣ6?#<}~M>+~{?G]%O }g]_/gl9|i2-}\RG??-e60(0|Ouf٬\i5@\XX[=/ ӯpi|wvQ9"ާދ1YMi/6GyɟsuEMhq"W*>=KOnzf_/W\ڎ+\4JU$|W ;?/ǏnåFnH9"D&'1..C__}-;6Q*tЦz7 #9\'$H)P-f)efkWkue&ss|}H~ Ul _ԋOr뮍l-Ҹpj P[>=7EôNArL)%ҜW Ӱ%[XV`! EbV:` !;'fi8)bU׋Y~W\=ͥ!WHwseBQfRSw>injL3q\J>4|l=8K}x+ҋF]Jְ@2cf޸p L=NO> dƭ!>j29Jc_/`QBHae-86RNUvV8+/=AgUqb>s'zvܴ>`o}6(NZS-f&<{IAIE^!M\fn[$PcOZ9r"i|#l^} 7H2Jאm-ĢOqsr=ۊW0kDZ/3}4 w7~B(Ćyq3w֡=?E帬*"<=v.ck.NqE8Un`CS}(y<գq y@lܾՋk%QH_#שbvTuCma:o_G]$h>\%,K MbcudrX"QlHC=tRSµ,1iyMyۦXy+ ,t^8+s=Nb w7s{j[6r5߲2g5)<*yXRx֎fl˱T m$Wc*eKn ֮=XG戣ٵU24B!sXo>θLׁ`K#U3і3W*e9v5TS~Kqײm \&>_b, %S IAOFnncRP CQj_̅"bnr hc``05˫q ';e~]ˮU8 &NxNbٶٺhDM t,zɫ0A<8B6 {f`!%̙'JU.c5a63.;ùCɭk-$#4VlUkj|6A2هGq05K8wdm+h;ع?H"ٳ1D r%pX(B ';g+sdYZg8+]Aㄓ)Bl&PVEe5-yOXEڿ*&5I,/( X;FivZS ]$D~kZnrPcwq\G0, >HT~?SM s[F Pՙ8^" 1fed[\RJTkz3';֬fq^æ+z7¬۴,BKEQ eME'N0<$?o:f@ƹ\?cE.Dj{ae{/ѡ%ۃ*$RUh=H$+ HlgR -bIi6BJ/+HsYŌ6/Cg P,䖔nB w{O )ryG{I-MgfG #0$l 5VRSC8.v.?c2AǮHe|bG.hՂ>mdh=O T3‹??s ġneǚJƺ/7'2/4=ݸUnS'ji#ѓh[X}>XNIW?Ȥ(A9<Rs0/nWRJ$ ES(zv)d7?c"Dos{icdl {v1T Nvc816,&)1r >&H{1ΧXl{?SC2cgxSpo?Υ3{8 (rNwƁKE2r?'^{ѱ 9x t`R8*lT#.PsؽAJ|.?c6K*0_ȒwxjW%p,ű<dJL$D&?K~t׃fhnh59\{[d )ѱIMM ΎA秥l5O qyL8dN߂$i0( c[vwL`qɦpS-:YY8Vt6u>@6͚O!me,>[ -1޽ЯOObJ͛˖M$fѳO_tqd{ Wj~I==&1%%&U)$2I_7]'(+.yTPO|!Y':}oB"ǘvXބ$rg廞d<$nfWz9hV $ py8r3J5,8= 8=G%L#Dmu^猦DawyjOʂ{4oG _HGO`yW R;~Bcc dBQʑL_;߅12qI%_Zk6P^ZgSj, !3.]sإ~B|i ʼnaٸd !:b'qt`!4#.B!ķtB!B0`!B!N 0B!'B!B 6M0_:{Qq4l2t@ @UULc)D{ BDQ"H{gE a&>B h!Np88I 0N')))XV(A^Bp/!:@`0xҏu i2C>{Qil:U 5WS:v؋nCkPK"-\ϲ5%d AX0hܷy}%!{_Z̰fPsOu !:*=HU>+vgw=_30(\˺WoK' }Ϟ*Yvæ_i=0(jHJ­w|`Y>Z21wяn˼2 ӺcA[?@z+ϸ?SS=Y 蓍-~C' =t&==g=6cO% &rޤAZő܉nyYl<DXVG{gESFjN=lX ;.>cI صu%[4M 1Cjf.zYψ Ɠjٲu;^@#,[4Յ:g~{Ly̚}\ 1$'Նې뒆UL-3/<)ikmL Ih_{V: 'f4%vq౧1D.o^{p p VLKn# @jj*V =~ '%MZovWҽvp f鷹t`b{_!aLӤA|||{gGSΨW9hJڃM;x"}g 9^ `zXQ_%kVl&N>IH#~?)))_&zzL\b, !Cqk !⛦#;B!B$`!B!N 0B!'B!B u`0j4>O!:$`p8L0{Qq@$9g~J)B)OZFX,2) D|!7iB!t]G)TZ" aNqNZp8HNNjphO~`0Hrrr{gE a&it:k!N@ ?Ǒ1B!D%]'B/ԩ/?`sys{F!L 6& dKBt4AcnMC$9zvkRf^?<ClV!iҰw++n&;5\[AyUVO i8m2#V)͓DVV*k{2 ˨iƖFnV6MF$HUy)~Č2֒ -Bt@>> jtkp- ;>iʠP!Z F Ww1M͕]uI`yWg[ ho~ֻ^{g^Jcvl<]]儌cKg꙼4se}6 ,uf,bF\_N{H!DG4R a2R7z( /טisذ%B)RS[&0ʹcRL P %yfOq yg aLϼb ;;ѣ2~p:+J%oҺ=䣧X<zaʔLg`jJWK2x4&y6]x(j9vO& 0bvǀib&74BM)aR %2fPԶXIMC}Nwu]4z> .tK po!"l(hɋO>M0(#uXu/RXwxas6;;.O1XGuM4;(c&#c.s7UuCD(ۺ'7T&U;p/n⇿~aVo__S64#]xbFSi"B=%p! J0f-WR'B~F RNAɶU4EJ|k/G=Tn_IU;#/a(,`ny5xiΖE$i'[8|;ΓL3M{V~kWJkaVm.ݤ$B6f=*[+ZEz~ٶ`4p`԰|Dp*Yi$%dО8"ƚ֟[~Ck6[ l ԗuN=ijgp~_-{5QŵמEld<:˖9`H䰗n4LYc-iǾE eO-uM }Ļy5ZJu"^1vaY98z.nٰͬ0RYNֹg7'%Bg+C=<|TNaX퉘h]-ĥ3UgG+h9}‹Ƿ>]Ǟ]$7yԣ5Gu԰[Xt0Lbå膴`!>9ay쮫f.+bqB!4z`ҏ gfl'Q Q-Ĺs*w.Co 6z,/c/)Ͼ48gDvnDΙzX%NV| 6Z^2q thi>0@܌;,x:%r'tb/q;S vȌ ܌~9MpbSMIhSB!dk  [Bg]y%}Do>#[s(f=UϚ>jJۤh| 횉''W|F:׳eu׋}Ӱe.˳gՁVtG"JZ (i ӣOW⓲%薝Զz*q .} 0JZ?Y]l)zB(hk !AGrL›N'=JB/شh [wՂECi}`HCv5 ڦMԱyb6`Cdle ڝ,MsEIIfi xDB:ɝ:-;푨:^_d>ƣ䅙s ȩb7{i;u8K/8U5;(.،se˥>t}'֟#@y$?щ V FAn7&1)Fq6Fٹh2 t+4On>h>TAϐ>dęo|o ӪŭWeWCCG cZq8ǟ,ײpFJJvtCt3vyESmsf t֋nsZi*^/;8㼱$jeۚuԇul݄w LˢHAk`Gi5r6;bյun}[ }#̣ ;y(4s2~0qI䥚Z@ώ-;H>&i|#N 0/<ܪ ΛkLwl(?}t3wdBo1'>ұZe|C49]8{b?_93 BJXe/I !:؊=sI'(MEJL&Bo ĄB!'B!BF !B! #B!ℑCo94; B!@N,Rp8L4ms2M@ j% wvil qҏs MӈD"'rF B!7iX,LӔgH$AN~&"%ķR B|(X,(;+BSH)uJ`j B!(4 OS`(Mb|I L@S ۶P\!BMA{EOx褍8HEX Æ 1 +NB^rfшR{5V4Wr[~Z!B|(M#Ҹ_[ΥWjv-V h$nnâESA$$Yơ+զXh(ٰ۬GmYQJaQebZ)tӤ<RFv9t: ΥlٓרwI=l_=儧 Ǿ H4  R1.]Q{ٲӁ?B!H:V1',[2pr/o#¦E )3lsD2<#˦Fm3ou!SFbv҂ZL?h_ʛ/T ډءcJ>zA{yUaaF6hƋo}aa(pN^x瓝( lnL)McIX&nYl(݂a824RaDTUWQI$--ӊiv~jEΤx?4øSHOGkn!Bѱ)QUO7mgs٬szwX0M\r%!\ĺP8|PFK_{%?:xOGo/qɴ! NSU汷o L&;/i ~ ޚ&ӊE;J(D8<ƟOl% 5#( JEٻ?ߎmFj''8]NA (͂`JAS~ ZtJXUL֙˯)^7*YoWaΒU[(S}J(s$NvEC!Btd&NO2j|_= M`k1&R@m-! /KGwGѦ4DUԖU8]nVϰ(erCGr~n`&-l1Yy;RD$:QSYIFɜs%0LPQ?VʬV'YᶚS6A(GW/.˸ǷpY?Ϗ$`\h}x!;v՜?(϶֤B!Bi9<gC1k>o︋n#+=dεYVEN$7!զiOeش$dƳ<,Y@$jaB 7_}HL4B̟/݅A^Ww4& ážG~ q P틶[7c  EyE{fd\l'0fX6_aֆ2.M,V.7n˨ oI :$TQM!_!BL,l?[^;~͌(j՛;3p7?=63A9vm<\{2ӓP{ ZRg?Dgfl$,jϙ9`"f(+S|8EҭV$;'ƍ?϶frrɿ.Mx-T?%]͵uێբ0MēJ19?}qtJfg])Pm[K$B!L064\f]Kyet ƕ+i:t[¬reә 6gaX\Lz&^aR|n*<)]ߐ`Y>c:g sW3x3 ؼ~nsF<4&&z=Ki- bCѓo=^-~7g-纩IK.a9{TzI95Ma#~Z꫰g0s:J)4fD0Pf:zϠnM3bwfB!Nidٺ T &Μ\3 :-iыL;aĖIPVdM}>w'{=/6ӌ[a`Os.bT^`Pb,[W.O糩4)۹۫h.ख़K h*Vn\z AV+ |4g*ο}DL]Oy iM| C͗Oxv,uk?ayAW(d՛9w5'j2̝A/bO@T'K!BXdgwo&PWƆb\ʵ` [IIâTQר1 ag_#q`%g'/qϮ$kAkS)t`id%yqcL>/EY3%m:%3_Oj]J޽PV-U*(%x&%DUS$*Vs2q)v &~rwLj9 LX`t4%Ҡt 3:D(.=saKKy!Vd$'ΆfuROC 9 }'/ՊƓލǐoM^ ^+6NT AڊhJ)V+h"ur ?´gצ,^4U>(z=Zln˟_ID;vقl\@ϱSp52WxwnF]3~vtIvPW0%AnU>1k?\LLJ~0[}Ĝ.ߝpP{e}FKYIuz뺎R kOc;؏]~=7h)&әF0a@bQ(&Ma۱(@)QbfźEYDFMXX,:ѨՂĺPY4hnnEDt?1!ķJ8nw68bk5Z_+!k4 v㣏>`_ )4l$ e=P 5=/sh5h]ӻY)qXEs糽zG]IhAW%%t!t,h#~ȧ+ 9g #GGV"],;ӫO?JC;XpMHII+5p !ĩ#X$ֳ>Jl5Jih0 4Mh3ul4Lц%/2-1qѾ ͢*M㰴[`eXZ40Tl,ƁA)$; >*to`zBF+vwI:z2 a`0޻dVrM0Օ7"nߵa̎З*@!B|h`%!pĵp/% isu*bu{ux\*| H!B!>Y4^9JˬA#B!K#qŕp-B!XC!Bh$B!B, 0B!F !FfBH7d)5B@ i׿A!5+ 8C8ٻ"Z<`0xwGZMSJBq@O80.@Q( S ۲|9 0 s8;Zz 3qQWEWJ195t2I0BH)LJx7{W/1KϻS)R u1UBGB)P9g[ .s/)0||a.=U'bB45Th@r* (ɥ'Iy>*A>:i(<5N.Mb%b]7!9'TQ1֗.mS(m(sm0>*iJaud֡z1Smۗ<7:}\@md zJ^`XKDqV)[mYzx qʗz)v+9]vE8&|̵_ڀO]nf𼹖UGiƹikj֢),ſA 5t}#%?}jqsqFz6,mdr8ӏ=L;>G>:>yƇ_Lk]/;I_O/ "tCqsz9k)yXԚ1G0MH^.'%clm$`]EL$&(a*ʂ>bgY[=ycy,ur}RG9z0N.C,r/kBA{-6+2.يgkP/lb&^[E`^W(24*^ 77MJfnn~}~,@0m?rʣ!l・7vIN ;e.VerqH$`(ϐ"x=NA**oLe8iҺ/@?ph{)e$Ie1G֚EM;ÅI^yW? 9Nyӽil[C9x&1Zg] wUB&Uq5;J)}{޷U_b6jvSxXkPT4X[l0=ī~7OtϽܳq;aFKi8IDATv2tz?$ΗQgUS^evbE . w}>۹eOg#?*>4˫h%x rՈX@Ζj^md]x=w\@Ğ׭J MO8G/9e(/O>XCkK+a <'Obb3TROTAkeRQL `^G`L[AbcT[Š#b Mr᧡ a-rp`D~\ŵ}\Gȏ]gY;_,XqMjQ65޼T+J4;\^@RkJ(c7ЛzPcw^ 7$ YW{L<@247wcHgf=m\ʘ;sv=p|"ߩm˸YBg&k.ނ]F{hڸr(}.Q١A®n>srϊybØ).@WP2YʦxNq<@)K< 8X+nS_7f2S[jݻ<`9 <-syTX{ NR{cwaOLW7P(~G +`Miϛݏlͦk;̾^zŤ{heRQHl뺥.~F4w y:ZǻC)uܥ0"JaSSLLM0fӔ>ϫ0, 0~~eQUB69v(5҃P|>4Et],rn_)ȦxEe]y i~SEaOrTF:|\[ a4]*}`wǟ=,;WX0&OMpcD0?Ey݃>@r]u2J}5}/JMه.$uQU@<NL22VX&>rf]:X9Y&'0"edGhh&bi'g:Q^]Gcm i _Fc} AK>,nX4{/Ty#̤Iy>"8`*0A ެ@1 h Y CkR#N1 (ZQRhS9JqXsĠʧ012.hcF}1U  KkSy$7T)Ko0҃#_Hf91ZCmeܷxͣlm߂kֳ=oߔ:.?}a˪gNp|:(D}& U6Pz[VKC2Zkʠfphl QPKo|j  &`-DlC\+PF}} !b<ccxr C hh%&TQC@+fh&Eih&dxN~ƒ9PF[*ѝ/>1"F0M GY240D2[GUmYR,'.6j"~GXښkjA̙rMMԔ xQ^xCvdڡ"cbxdFj+hxFhʺ`b:6r L> keysBH]cu؅44Vzs/+uRJ 먟 a@dd ?@o(OgrxZ +:d3Y `(2 6Ȧ3`x,YB:deE[~#̓a b:{v F̳y~A6uUw>e41ϝ+S}Q{mo3pxoþs)ʣ6y_/C0QHrs~_os{ynܾ1W&4ghȘ4Ă[6WY|)OqiqGbߐc,4 98)e(41:+lOUX~M8q$ ,LON`Mgbp8i2uy) k*-V`Q% L~bxtښG\WA#ٺ`qř7]I+?>r;vo'>˓>Ӱ?_nᅨ ѳ'_Mi)Q9*M|8޸;i{2#W{+_&4䧇xo1<әCڽ+91h 2Y|_H:؉ct4_ lVY2ȫO=ϐrR#gydcGO5u[zFzܺso_<{Mdƺٻz oTt bcKC'Xs۰OK}w޺3}91]oep.>>3Gx: _}p}drD oEyDˋ-J)$Sa]"@"p alKl[_4-3ߪL*1J($ǘH9ؖK3_r;O0*r2L4M5}^)xM&C݌5ecFj cRXوv7*NdVbA i, $ \?:ZC{K=~ɥ F ښTba3BCc-AS3ZC$ :+1u~*@pȥ2uug`)t!D".1h_1WH1?D SI j,21{Q)&&Jj8AcG'uAfBB68n6DqZۚ'93/@{K%:Aɑ$ttR+09>N30 M69aZ Ɔv-7bj: e3זbqWC8B@ P f1 ޥkw]U__S%(]+?瑽cz;o㞻&oS&=*e84Y6V-#+6;++De$z?OyT_*i k,/ށ!FƓx(Bs{7fyHg[JhXJh`)MLˣ's81+@E~r:;cg61Ljڀ@c mxC~㍁9=.m]b ƆjS@s4|Ţ5 (J,EVZ ɑ??gԼ Qj{,lUo |G_=E\K̺Mr0ٱqN_SC;S*Tk4m LO{}R݇8xb[7>wI+He4WEt;c ϼ69Ȥ:Ͼx-T|~T!K)WHC Q[[Muu-5FĶlBm ?SC/dht ( ,ݫgq(bgF; 2<gI9,[ -**iji(93LM]#mmi\ Hy% mt5@rsc ^.wܰ}!x*kh#dt"Uc 0ΐqg L20'VUCuu555T-37]9::liqg-nt]]ol-<Ǿ}=&98dú5<_pC4֘X`{s}j5ʰ,@KK+uq0\?(Gs>_EڊR^v?G۶P>J)LSuۧ$mgq{z& DXUn0V(̕L ]>^>)-hW1vk=^G &]+ 9Y t(h̬@eB)i GO3>Vs5h ۦ,,ԅ.upyu7T9,YvOw8 MKTWE(2h(*`=QN&ɹ@if_E%2q6}]z&d]4FEYޘ5Օ8_U p.W>?Ac23=[ : ai2 [3Lsϳ}Vy=l͛0͹gyƅ}޵璙Ns Gg3g*SMu؂o.~\XYo l[3I&>c˦RT?9u\c(&Є]d+> g c( wI?m ؖ V8gLB)ř6ȕ6J0R\4e aprLm!eL2ciQV1p$^l4,A*8pJsiƦP3a[yeW$#٘VE0oN - >S܇qX&RQIMg&j¶4KEôm?òf(D\]RSxJkg+=c'3<LlvfG7HeUÀƶmFƈK 1-]Q3`iX~h  4dr.Nѥfv0aq"}yj˘Ѕ<Dqf?5Dڠ\皺=\Yh,5F< Gރ}cە|U~ "gW FQf*žB"n)ڣ+7 VصV( |7Ê=!`)Pfz`;9ej~*@hG\ 2C@xl/Z; H.CWK`0<ԏ~u=C-?x=Rra2WvlBmD1M|D Rii 8< 3Pj 2>n,cg~C? gK+VxCܵv"¥ N'!0 s$ULAklӺ.,bMki-PP]öKֽٙ)AJsT 5aImRfLa`8y&SdBL 3[}aA#Bkuʫ?ae{]uT>.{ )nZf($9xPcs~ؘdR)\3Hy4^'#j" CuCd ]D |ͼE8V(zv>b:wyy,n:c`Y /'-bjC4c0x\3͵QfXy$2AuA.aϽDzҽii6C3iQ?~?_;3oj%q<|Rq<|JNz6.n` @Mu5CCøCuu5e5Vk"P$9A'rŇzkWQѶ^&>XkZo2ePN |tKϴGe*Kg+ YP6B |7ejxTx(Ko\q.YVgTPۛg!f-}MkҚONe4oy)/[9zOJHQMm>Njo!=y/x |sw}_Mҙ? =9xr3{?%ٰ(K;vzyNKe3Y ehYha'YqVakhU35;MVf:q )jکX Q`ƪ_}S<2,TQ}G)pl0`;|ݱL;l6+X-{xz(@d =&xh 1M2}I^y؎8ǮClC,J 9^l62;9@:_T '%&05$D- c> ɚ 6oa]wmVp#[ַps7%݀Vyy-K XRckPdf]3ㅑ1Ow8ryz4um.npxXXlK@#5a\<7S7ψYT,ETD, o90c07=r.cA<'R  5/'2tq.əBb'(`<z R^ kvC.IWWQ(#8?TU;AKTVle)=o?|;h*%<|~<ʭcFxN.i,SS%uHRd3YR,U;?;;C ,Nӹvb5\OSܿLi#g`◼SH~+[lp2|E^9bl~ݧyĶ/d7sbiu7?Jj:CL{&NfNepuqFtLfLX:D$px"A tT|%hHR$ҊtX3]gHI5Mw}<ÿ%?t+"$S6o`͎wG{BINŘLQ c|[gV.%ꂿ 7{1bdt /V1[_h1|WVIkCs'V ص +ZazcGsT7}}elVouc &cU]\ޤxX8ȹ3L~obŊ}CZʨ_x'^x_z~g_ͤWAgGKj2pg{Y N3aQQYEe,Ba3U^_IYu˗6#&WjE'H =@d;YpPײ9Fb,tw}l޶ X#k7 'h^{'m]F=w'q~Z 8=)P8N[[ 3;6@gm! E 184xm% :ȱ /LCs 0{u,bG9u#gꛚa銥TZipq\Nc,LeK wso rUTUU0բ>o M$|ndKZ;$Fg7f*Aal4F`O1̢>oJU351A3LeRL'$]hڪ}P&hMqRmSɩIiEm|lFǢO1H[ m(i(e`6N64m䳤j+[\6KBld2L `8J8`N&Id]:x&0^i\U\<MNH(ՄuQX-Ȥ$Les2+v LY$&JɺDģh2S$  3&Pp0N0c(;$h(6LL&C5N4PLwTP=~bu{e{M~3»/(:䗳/qBFk5ۍhfz@(uhɥ8uYu?;oϒ]Ev.8'+ yׂ3L)Eo_ZkZ[ZlIu~LJR W.*GCKkM2$VQNYYٕ(Ɵ;="|s%HFk4 y;^y~`]pG}%6}mʾ6$BZ\ Fu1w=_.x{{*olsQzQi koܵ(bK{6 .H"u}}tKqY9H~~`cZDzϕ<<}> yI9Wq.|v^OǰdzL,|jnf!E\*"yY|(ОKjaӲ*+Kp=wYn߸rejx^i#Xd_HqC,RpbmA1GO}}+$ qv5F{8//iliw6-RRC_zt!T"\& DRl7b{r.)y~x`hȹ%9~ tv-o!+>>C}|[|˽ !|QNUCq|aւ↸4WKEV,xvT"*ćE 85=-=Oćka,\ [cq,%"3J-6øX_iם[qZs=˼D_=-k) qxB>mCCLOO]H<ʢh1MT*uS !4ebtch h:lqަJT$-֚h4yR+XBf@ @YYeQQQA*)M)E0]zI4P BAB "jXX,vwSqPP(tBt`,2C!B|ɬB!BE#B!b| C^^/ 0 C^ƕw0>S*e`|B]|H^)XD`(2 y?WS Ny2'wba4.,Ԩ4KNygȻ 3׍i{sׁW:nc} N>]9&7P2:C=\jBv{h(އ a`i8s,f!ͧ>'p? 005е7%9ͮn!>ea4c$3yabh9J)μ˷dV}.ieip?D25dm+a&GKP6"D`nWLX 7S{?]0v 3zVXaDʉU3 .:ͮgcd# y##w;ueEJ sZ4IGyjj.v Lu3rWRSUuJ>Ji_~G6.5cw){Qf7'k@7- gteU(ãU:3SVv4ҵ_?ȧML+hL"q!j2\ξOƠqCw.f8X7JQH+9Uﻨ%B|r]gP:O=4(A?m lz|h ,iy}j⮖OxL\.hj |;?d~_QlCo~P_"@{hM]t4sAV4< qr,B[˽'8C!4(:ױϲ5H aلA̍?C~Q]]E8t&þټi#:!?[VEBK4eh|x?>7Uy CAy`` m!xQ,Ͳgˢ\,W@.Б#XEee" UHr{g?S޵ڀ~m @0_?Y-a=PSopT&KEdfa!KUn{{nl$nkPX;kz6,qy kRR),b՗myZs355E8MOF)eXh f#_gI箅ݴX\<= U*̿ Xe TVV^=a`YgΜca+0cu^SⅡ swh)Pk/\^^?ə*ߺ rKQVO)f8K{ gcttV.J)b zVX9`"p߾~m:X#l 4 ^R/pyǮf}x-7>##ttrc//+]Y|m$wϭD|MԪH ׺㾻hf΂+NNq~ts9֭~ 0 2~ˑQP;{ɩOšJ w~>3ZQHRس*/ugѳ2zp[3ym^l`( b+q:o^K`brsc05#g9p \WhX:W*%8w',l@#{^7zYvwK+*qzơ%̩9;k6u{0$jλo-Dp0KH;VpО#;M"Uv6lç .wq%l @Ѱ[WZlWj=˹j^N͖YN@MĤܱ /L͎ՍXS m;P uLb]wc<8;_}{V*h#gUygR 9ttσx2,i&d+|G99l̡KҸz wlZJv9޳dGߩeԺn9O|~t. 2p#xd5kQxq[6{6RS> f v[,<Z>þ>L]ֵ#}g9;Lb:4~2!d?w=1L-w޳e ΍権 ww=+CkRA!ɮW 麅O}f;^3 wP)|fuyqw86峛VQfyߥA˚۹i^}- k({N ӵnV}g^ڇy_|x=a^ѾSzo/﹗euxS;1Aݲ&NAͫ{B6V{VmsW1=p=v%|IpQ*mI=;w1n7p=ᗞI=Y6y41Mb1T8Ei^ . /őן穝GE9Ƌ<ʼn\{YΜF^_P-a>6.9Zخ=S=c['{vxCqi n~Oco q"3r_<FmNך?ʥ}~֌vT孃g(h\r޾4״T7/>Cn W.,fK<`Me{=N@8A^|q f F+S<7J ж| f.AOO?^%FU%ey^wxJ)w} &pU3o>!H477WWN]a)`79-C+ }=PU8 ct96mfmG9oo0@v4w>S#5S o5/eQVYKE OMwqB]/>a*N2X'{y'/y9$ycw4X!ZZj. >2$&Au(8ϴ6 5V@=S)~, FԹK2{y9K G~_' FE= /[Sx(eTTX[VqcM;LwK؁(ՕH3}/l_GW{;l7o c~^r*nfwΕulXE[Hy]i"A+$oҞ_g&aȮiw385Hrjtj]/<~JN$?~bpٞIF}{O8ٱꑧ9P8ԩ7w@0{jյ̞=,;@ЧTמaWw֖Jμ8^ϔi3<99â_$;!!zg;8VoXBU[G~.)O4k5Le唇X5,au[9xoMogr 6m<k;xaN*AVn[nb*!i c8pg kX.C!'\,:MZ j;ֱqwHa0e誴d3Yj۶o.n; DAf*&Z^A42ʀCZ_x w(o^wm,@4w[ufD*XrmNuAhUMt5WR`=a tB{,x;vM4Z!~?^|0iWK3`Ug5(VAxivuٶmu1n⾍̯yli j`ܲq ܧi'83 &QYh*PŮvٶel':pDt(æyݝ|zEnR;5A`f6-!]]<5_orLfjc>^ya<]Ʀ;emK:"k԰f2n# `UWBr/޻?uäs#^Sd⛹s]8=sK ðJ],"Hq[@#eĢ!lM2%kѵlk6oc{gL0iO/gVoΦ gbckGOƨctUofeKP51Kvu7gF3(%a];h,+)^s~s~gV6[Vr[ɝ:pd1رSxhP XFu ޴jrj?Y)tE,]ƶrh'16SWU[6Ӟ-(ʢoi;PV۶9G;NQ?QӠZm+me0vAiXݷO~_9sS=҆2Z6ǟ.`fZk|ܺqol'tH@=}C,=G.Q޸ًRH?ʆ.jr$Ctκ̎(!b\b= +ٶ:qj:̊%}{d, PĚWsW8T;} .`x*7ѓf*ʤkѣ=7۴>l8p 3oX~*p`rT hOM[@8A;mAvivώўlLbaƒs7NqpO4@)C;_hGXe˗9;U裼 ˥ϯl4#ԕ*e-͞,ZWʲP?KΥF0u bkAF9s<3>ٙf\- ꖬemȨGSm>F_?OY};k-^"= ߹2?3YLҔf8<ʻtLc& y<2ݭy܇7aD=qZ \WJǦ`-lڰ ֱyǝܱso‰Jk*ֲo[G,V t^i< @ϟ@@;i<Ͼ=ciL*֨H=9ī;eqnXQ hN8p7G\̤YŽ~vrv3ye}]zRXTIad'8tzW#.Rew߸..W|H dBXv#89ư,L7铣1\b`R _ HfrB &s\+*33n04P37[J3̼p9@!m-~M0i&GP} t(hp N{ᆕܾ{7Qa1pewbe{ vfs8n14wؕe,1M!ej|d)]JTl&@?Yw:ab[p~׼~Zں>bYZ]c5fˎ3iy&+/'\FতT@&9IiEՒܱ~$8PTd .B(OO`X.='Okmg:y'~S*L*@.LuJ-9ifۙ8{N[4K3V}" 5NiX_'cdr9#Lˏ~ &˺X( P~s\Vms9ADZ{D[_4V{<0- 4zUjw719F:SL28 =z_?o6~u'Q[8Y9w.(afyy (2I3g fWW4ټo6}^'X,=d:O,E{n,gƏs\@*ٲc5{_@2HCeA}:/=>]7OQgg:Ͽ3F_A Yry73у},ݺ-utr7_}x5AϊjU/0ʒM'"U-[OUc)Mf(?5~Ua lR+L^iZ~ldsҩ.4r<97I6erdLu+u0fӃGYm3O&?{t%5EB>FyExŗqWrjo?Ls`s =IPvFn }M+者f401F{!H_Y9s 5Cal|sc44ۜ=g=ϙa&NP1~=ڶCv:ŝXYv SWam=r%KviYZϱZƩ ʳO㭌Q qll7̹asbeS_[u`&!&[^qP/#ރ^Lym[k*(Ʈd>v)g#4lw7=G ZIef'/>4eeăZGr"ϩ݌&9}5K+;u]ii0\@{);ZOsx!F9jngoaygaa| '%Ɍ8=rUYr|m/RYNcO/}a=ͩ!G\LPc,#8g2\JMΥyx"be4>Mwկ0ݟ YCc[S'itHbsls0#C~9AV">p& a`r--~<|tmH+T7uwō7sS^&w|)R3o)oXS9L [h==`rn+~1fS Z|aU6{x}GObWs C>7FCa\gdUA;zG rR7!R훠=NMK'mcV7b{_}Ft(Jf8pWcwzYVǪPS[KyGQӱͫpYhzVLn2Tgsɒ2GwaC2]:Vv-Q)&^%TUUӾ|-[6Z,/]V6jj)YrjYv5V,H/HSJ-֥_XdY*J:qI& ذ`A>HϪ Ei_J**kYr5W,g6ʣWֵ8u]lu#-46SPбr)MTUDp|jpEb4455^ک! ҹPfQL0tΣu-˛"WT&U ǡr ød:zz{"^;TYN[G3UUTF*/O2i^]T#QZwDxᣡs9kV-֮]Iu"kb}g xHm]˨кͷBGs TcNN:ű#yxC+XH׊5\BMU5-KVvYܾFMukK:۩ؠ5VWUZioy3²]4RUh\NG}%b,줮`OkR_CMC k֭1̂BO? ^͝&&o+Jy/\ȧT>y 2Mcv Hbӳ֥i`@﫧1 8D{.m׀bӮ01 f0P/ե}4 Ⱥt.U!h)Ѭ 6_:]=/MCAf*ev]\,gayO̙8%Ti,6:;;[kXg?Vׅ5Wr؍yG3/i˭ŮnƓɩ)Gj:Uܯ=5b^00 u><=s~치yO;R:tgUnCQZz^˂w+0xtǩ_c| 6%ҙ {c|bJ0fJ.>]RW9sN3\<=?l^ki8}e(LwoRW~t={199ycD"YKNTۛ.9 Ǐ1]W96.m.d+hYPyŷ3yW:3yL^(/fo<(g1c~;s=7($yn氺V9vs1|aȲeKθH>9wFiDxܗ^= c&_O?ФG뇨^☰\Ǿ];¿mXgm^2E. ε17߲ _VF^+)G/*/xa 1Ӻ8.4 .>"y%c@šz_#v{2#t s!]v/Ϸ@qGnfmVP.\3ڶ¬X>7Ӱv>ǮP #xO&iY%+ٲu 1]O dokǼ}w.ha j7ih#i_K6Zv&x?frviB|=%of(E(lTˣ.} }O }o~۲,f ,\S"I(h#J>_Y6V]S??v]\;gɭ|uqs5-V| P/<}J5V wMDǺǮtm%KpNGSz>X#u ]AU6ObCRU@{rvJK !>rDQEkTraOKWK͎bKZ'!ޣH)!8oqM8""BZˎBc!B!ćB!BE#B!bH!B!X4`!B!B!BE#B!b:B!B\%> R>+B!W!_(0<_ڊnM0 ۶`!BqR$ l˦f 8gΞßLǯ`!Bq<ò, @k}wgٶR u`!Bq4 0\,RB!B|H(N6C C!BuJ)a`.^=ϷgqZû6 "%B!РtR(&8w4ȃo Fon2C^jrnVW^ 0B!.{-z'F:vl@E8exL_o]~[KPfuC!BUl RJ3tu[?!z/Jߜ}K]m-0 Z7J/(@57׊_Be5Zq}W"Q B!WmfS! >u bmh 30Lj-4(M!dlrX%RPNH)P9- ՓC!BAQ])Mb&z4FlەaP?B8֫G3λX^Ea Ͽy+7=o]ᅲ|VX#zL-@+KXQ dӶM{y<#A 6hh$B$&߷ev\-B!yk,k?|i ,#? ?bj5kְWrb̶LLN;S&B!ćR!D e(P(puq[JXi(p \O2mX(0mP1N`6RPڞmcW7:uXKQ ^ !B!n8 |~_-mپ Zki3?(e`|>.xC!B'qt=+a o!B!Pq| 8< 0B!JH)!B!ǾԵ !B!3XC!B+TVQp  q3W)uM.RB!B\h$Bb*ɓn,>U ״ 0B!BZk әe+R O8K!B!UPJ q'c0B!F !B!ĢC!Bh$B!B, 0B!Y1!B!ću)z,gC>;-B!mG}߹ٻ"B!B!B!B!B!B!B!p %tEXtdate:create2017-10-09T14:11:41+02:00\r%tEXtdate:modify2017-10-09T14:01:34+02:00\tEXtSoftwaregnome-screenshot>IENDB`Eqonomize-1.5.3/doc/html/C/figures/payedwithloan.png000066400000000000000000001516661416454732000224300ustar00rootroot00000000000000PNG  IHDRkf;gAMA a cHRMz&u0`:pQ<bKGDIDATxw|יNUunt@9(Q9ْ,r;;yww{{7yfvwqde ER9@9ntsDI`>ϧ%TUQOss((((rǣ((G}ǟ %PEQwgOK^R }(\N>R)z((WKh EQEQn*+(-HxEQE(( 㣾AJyB|BEQH>384>k4MR4ЯD#GTC(L/dph\.>knhx6~m݊1Nǣ>SEQjRڸ].t !z9۶۫5HQZ}Ӓ4 ]DeLJu3i2SNmt(ʍxz )hr'7AZ+nlnPMЊ(5ɳ$cn"2V_wŦzۂ[Q[sP6?3:s.e()wq!zݼj5}N${~|~L{2Nl/${5LC^_ )(W 4DfLS }-y!/A&P9nTx!% a|N= (T[8 L JHHnbhx4Nya|=sxddpDÓCnȏ.>̏pwB271hN;PC&OYHt\`Dthji\\|>u®乨ތrt+ٰ͖7=-tJAS4t;KK +t>{_cgC &͇\$p\ GwǑFyisDF]`[IK)gYYds$ ٓbͳ9:;%4oq*MJ=E2gɦ6d`JQ+gREQ 0GvoE NԚlb#O i['o.qfWH =ӽOjH^x~' )>Ʋ-5'Ȓ+z'|9uj67[5zq /<4e.!ԋh>mn$3yXw=o, 1ϟn|ݣ{3r݌ t:"py$C؀Tͥ(p%3AjsCT[vq 0r f3u.*!\ ׭e̛]s?9;e~Ed/v{ R4wfJkfpJc4kdѢYxt5@Q/A0wzXM:2Bg Ni{ y/sS<`]Ye PSO8]Due)y.IOq$WCJ&t<^/d)$J*(t,CG3|;/:ÛN>Fֿ٬ZUNﴴ17' ar8#ysytRte)t\n&]MEȍmKe@746_;nÕCqq>fAiKlӠ(']PάY X14XGXP``IXtÉөS\RDcQZ^JnЋpWR]fX 5hbHۑCͼ ݣn5UD,_.(54Í^_PnJmXLH /Ý?M@9ެ=)KJi``1R)vzb <``0@0LJSSƚK{s #c L<~?9>>ϝWEQ Ĵ,vH F̿/=R˞gaXH)$DEurpG!Xfe_x. '{b~2?RWX𩝼$cD$\e('4 iIkNrNOl_M4J24$- I?` 8vѴ/mҩeJ PHGNaeߟ&!t=HcihXt@QEff$KiN$'0LtjoV^0U<2[o'OJH*;dpXEԏqk 8]~Ü̏Vᔘ$f*HaJ{Y^, qy9NTz 8xzh`p2f3=kv>,EQETO'S68uPEQuwjrM|cH ;WE'$#t:}NA"폾L$e 2<<|CQ#  N?z |o7DRxXh>[+LC̴IwOncߏ=}?(r5̐[RKQEQnA*+(-HxEQEݞYs-G<EQnZS0a}2(7]6,fڥr1);|ZzVQCrbTCj 3: O@4 sr5rB5+r:H_9TrP]Qռl5x!Єw!47-1o_M .]<EQf. MC2Iif۾>ash/ H|㦠 aC7ڒl@ʩwBdn0-$$C敿O!࿮ 3S?JJtϋp+zV a M\@/[s |MXGݷ@R4"?y7cN.7%bah.TyN " IsĦ5ucsu8Д|H ҰƺeQzoxh> /5K/́ts/>Ҁy)%|j\ًޕhi-y6E \B&*tBMc*S/֕gZ=BP6heZ"}0f& pa ExYj9li`jJGM_{L "_(EM+tצQDJbsL[ΤׄL pnТ.R[5uՀ}cLWtU#%5~w7Ogj83 '#ϖ zSĤKym&%X+,cyReQ %BhfK,¶%h.jWٷᕃm٤5i2</25c lo&x5phl_/D8NA\}o)w 煀{C:8 A!09BٓT6!s]Z(K4,\WgGy|C5942O16Owɢ-}9G$jmM42 WY9HMCꤥ;Jq,BuYN 6fј\gz je.ɷL9: 7y#"q%a2蚠 $y:w ~[( pKB~FcIn?@$6]xwYFK;pϾ/<8`hlux_ ܒ &nfpo~ZBl=ǚHڙsww?E|泟"yMQP1s(_yoo>+M#8Ս3ޗ~ʯ ԧΥ{rG=i)zg/g:^c<*K4 z^N7JD4 9 ; j, c6/Zê2vuI]okSx+iLɏM،Hrgf^`sF&0 ^8g|EwBW2,(pdy46T:g9l$UHQZ`Yi,p -,ﰱڃeU1\~<=:kOܯPĂ"JܻZ,I҆BL3y|ÆS#6- (l6!xDg7MC"W3f4OgS!IH&%H.A2s鷰m$ƨ͈snfgF%щ.s2tgˈXasI6845{( %]D͟G8=DP᣸B yqf,e#ͷzDF5H$m;3$׏ea6RJaq2;?*Ķ$j* hKLj9/ σ&2upRhg$efّ6t-s\R`c+t䨫LJv)_TJaIلq4.X:$Ls@Wë j Ac+&NH@HIZf p!+ n C2:e,+M'uJEQ X(i kRTh:$ٻsR{>_P|C{џ$C Ji%w|v[:"49Lk]5m;$PI@!ql\ y.>GG 2wAv6ζƢ\F03:!WiI4*(2.,'+%t'$}iI* ,DH e@r=GPj!MI_ FӒO($0Ɨ js52;MtMgӵӂE:d=S<6>nɒb%>P70^ژ$fwcshO3o<4>_cME#ﭣa3ٷ8̩8q#>Ӆd.\OMn.@%.uGs eHS,˲l{"C_&toc4-rIB 7in P{}} 23-VIJ%lt>Gwse u4r5o@Zi6b[΍>D}&?>o v"}1脐!0 dkκ4舦l @+X,ǸE)xd'J4V5)Y]6Wk XqwF [e&Ѹh4 0mn gP5r5ViܙQxPdgE[RQ>xa{,~Ci47O6hnVpg6Rw/?7/_=ʜKXf^{hqǜFj˂$8u36ƉF/)@):N啗#`Ϯ#ly=} ֯_ϢxS](;(^ZɚO#Iq7f25spZc9ynΝ'ϣŢԟ:˺Y4eZ*!*-{&y:Wh >`tͰڰFtƖ660:+t ™xW[=6q15y\ e1~# `&1*8 CZ$&9ٛ)BU Fm2Ɨ=mc*NQK1݆RJ:::(G/%Icē1-'& '^CKf|xWSt 6 p8{Pf(^py:dgx%6)%hov&Lr#g撓pymex|&քxk M›2ÜO9& ]S?N?2 mg1^|粿0ei"<7zz''Mt6co16u 1q)a,}~teqSXEQftǚUNgx2SN);'%p%qH-x5_atS*OtӧC{9>7Ĝ0!59Yv }UQwxtn^pUs-̖d{]P6 rKg_imVwI̧Q2\~g}blE]*+.tfZOQŘ)Cag Mϒ:_g{w۪]Q)aN@tϝQ^I ~OW"i.(Pph3?Ux < ߭\lyuP^eO?(jr(8T ^e$׆ -#La(&|8/:Zffjq]pEe348H^^15I)$^ü6d  Ѵ5W^%D L;EQ sͤiDU(hbDžhNC4'.s2[2տ(7RݗkO8NrYTjUWn@Qn t۶\s&냿8YժEQbjO.(NNn)Z^޽V1^i+ 4m&4׋a\PE}MXĶKk &-2W]DX1NJk"MTj3GY$ci[|~?N=ө8hKpEI2%%^ MZƈ'MD4q=x -uIΞ4xChbf+1/"&AQ϶32A7T@EYNAɲ,$^#O!G# S?WzYvק*Ly_کQx7+;%ry ŝə[O(a9h:;kVR] a9B (!C-'}se6 ?}h>s?c^Q\9/xd7C$I UbveD[S%m+2Ÿ\DžX={w ا+ XR%eKW0+ϓm)^we6$mi?3`{ X"ce=ڋW;$trΦc }׾ĺ6_3tƷ6s?pccL;PG$#.EBdF4\,3M;ü/ÅiEQn#Rb䔰Y/=`,9WDp%桲<g0Nj+B@<c M644tnF ffKtӴ/ ;ɫϿ@w>WͧwEY_uzbiT{Zl4/0:6ne88uKv+rQ`#ܹ_zL@b{v){Y^x$qJFs+we+3/[ ?^OZNu:Y)ysxB+@K&&בIyl/{OP%Z6bByr?~p]8X@?[0Nf{;U|/%"'! G/iu]gm)UGmY_ K~k7@V;>م=>?oavfhǾ||d(ʵfx^_>cI/w=Ο|Py3\B9]‹XQ:DL+v >pyfBdӦ ̭d73M; [9y:BMu MӈvG UUv})`|>EqrʃqZZ#T.oQHMCG`'SXH-v;yw,(ʭMlE(d,cVELڒ}ISx+Rr!j=o3 3x?ZbL 4"Sɫ&.GvzŲm4M#Hͷ9v>g KjYp1zFR4t&Bs4^OgBu`8x,) 躎i`h=oc>˺YO<ɖ;7կ|ښY\K09)%@O_O3ڱyՅ.dj#^On%|] ==v?yZmvr~BV/gB.(䝝yi[̮7KuήcvP-$(ʭI`Db'6Pa6-dq˨,!̑6-y')EX4%c<[KjnNStS"DgYvff))%N˖[ф`v(7m@Ӵ+ @)qs_}rY3Kg%{, )fW5lO5PZYt՟b`8RtN&n&>5wef'NDwhxρAvttPQQuOWH;PwMZ$q8NEeTwc9˜)ќ~gϦ4vi >Χ0'3a`+gXxZgZ|v$p.PP{ܒ4;]_HE[xsXiX4G W|Q->@2^ W-$A۱U &MNn9fy80K-$k\6 !W_#RR\#=@(xRf ^w}bq.sHg;0ex(*7&2ECC3I$'2|N pqNi'!qjض 'Y5T0ĵ\ZKk8˽ypҥfg4_%k\36D7OH۾0"ۜ"+RfEb+)Q^](}D_0LA~vI>4NByyaRk61Ч鬵c3xaB8|AeK\7>Fqq {㓠I;;.Fhη$j>0e]6F]p y^' We59)m,C7¾Fm]=i^ٶ(ÓCiU -4CcV0OT/ b/B3\uMw)E<)%e%LQLU}R~xen|ؖɍ6gޟij=xEQDV5c/|F΢WEQO }[EQFfl ܸ3)( 4:!^[ZUPQn| gHӤMY[4p*+Et,nݿE뱣=rN'> WDUM U%84GEQ#ḫeZr}@`%F9p޼ ϩ $-7Ϟˬ vM4ys3~Ƶkfo h9:?$,]u~?m:F6?&n;HEQEI靼1<lh29aWS|?>Qs`yO?&v?xi03V${o"x;K !h`kg& PA1Ex+kYb)egʣkh~Nw̚_|_L^nBE_ܥ|b]X' XVRiR6$fmĊ0z*H };vV3gR^[7cQ 9ŽW^ӿKXn#z'>Km[R0o%Աo]XbP*_~Ƕ7&_k %Hi˶m w{3r{l!J124piIDpic[iF"aJT"iY$F`$G à OS$exxH;,I: eZQbmǶ>st 0l?Ӎ/( wp%Jrhr2殢mCQm$9%3:KEm5i#],]X`{4YeiίciE[Z[y,[$7Ů'4c" ? W,ql!c=Gm|nc:ڴ_?oɗr?{_?~(|u؝'|uK9ǷɁ$K6#W>ςB/lZ]A?M;y;)q顡Mx/k?U[[E~.7@wO{(F>^xʅȓ}=rd=bc'Or9 o<~7^ ;L##Q.>Qy('NLźG;zk<Ǡ7Y<(hٕ EIpY_'_YF̼$mGrxu@J`>ɕ8KAD܀DJ²rYFqtrzq;AJ4CIe!G{)q0{d񢅬[][9uU+_O 6 }D;%9i~瑇sixhE xUx8sYd.~{ ǥ)nRc)'6a߱3$]E| |G &R8 6?PWSϐ"2M{Q΃][{71uAϡ {œo?LgTn(/_NWŖ?g6U7<۴y_()&{mf0nC{sn Mق|O*oן+PĢ) ዿ|<ܐTo j(ʭM"y ?}6J0J! N I!I]c$]؃'ehhZ4!_hdMRJ̚+B`6`O=kf]Oڌ`i,pVxPjKHr+ai!nI@Y+3/,9ddR;fxg*jsBj 1glJ [ya1%xrK[UAn*+;/ԙ>Y]K8OQQ>d ӲlocgoWYh9)YX ?@ͬYji1H giobˆլX|ӯKM٬ rÔ̪9Y^f4&4 @u.'N0?&DpX "Ӟ"4ܼBC ŒYܹodp4Ǿpc8Ng(Uή" ? IIf_Ҷ 08$mEe ?GNdI4Jepm@ D;ha87ƨ ( `h١ly:y!ng2.$6jVœ⻢()%C~Z_ yeO=IKAsty!)38@NJ`sd C(C0HiaCwz8k/#I4-T6M{dkǣa(-NNl4g-`ќjܺ@ sWk vtnII'bZ6ޒZݴ7G @o7Pue~ kQ<:HKvu摗_24MzI$axd|F3m3$C4dͻxWsOX]GUp+9gz"}9rf-n*ƶ%{NFa}'Z+)?4eb'6iJ[0Q#o )$ͧpȉvtG,`x( =$,Xj5i-!ض36egtI=qf[&iJ\6_GN;|ϱD#gOЩ$L EҲHY֤KcYI,K"p\hn馿Hto<_P}ڄfgǭ̄7=DR_3Qj#<}lY^f&9G?'{0U|N졾;șQݹprY# &l=g9;Zw,'KsH$hmm#H008Dgg54MocZH`00dpAƃ{xoIc1zi>{q\)w >8 A~l*M 4?O.rn͋ 4DO'pej.'D[00Fb?yk "iΦ(dvp/N`;m[93w~A9}39*#ݍ.&p] 7wSndvﱧ g =gx=)cVHrrNv8Q7**]?uXʚZ }3wyp1on%d�Q|ŵ)/$dt#'[I>i9ř+(.DQnz(׀D<_ϡC9r4F;sM?b/gNqAaAiMZt5XdeUMws6%^iB`Zˊ(iYH)uKx'$ 244Ȉ+rӰ̍b|8V^%n󱬏 (r !p:(p\$EQnT8xEQEݨ(( D2T(75 -#L%U(7IfzߏCe+ʥq*+rs`4*+0ᰚNXQ۶ihl4i׃$TWnBZ/@Qj,z֡⺢(ʄTSHTJQEYȹ\ʼ~/>^iEƓXD39x:^MqWh.AJ(m@ ,@Z)">D B`&Dc 4߃&,w!^K3@9~ضM:$6ױ^AUb( TxWE !"tVXsLGƆIʹ{z } gNlx5lY9A7 JI^5c#}g[#>|}nJE+?}H_AL0^fW< ٭LR5yEQ[$;_?n6} {/1Vu?l˹w1~>G,-^6|b2"M?}zZ_9>]2-WR`[jq)ѱm.{Ǧ(46Ps>I!2jF#[*gy(3{( xAh`ZkN CH]Î79p~›G;i;ƏO?|t2XOeoKM3$$E Qnob Džmi8Ce,\ Gvm8=Nnvi9no޳2Q1^QF&W0;}8^ @ =ã t04$hN(1Z&zAXt wlH:&g?3Ivf1ƴm,[^T!%=9\l3=sܘD tyܙqɑ><6/ZBhC['탤eʹ)4JY~e G۳l 몱m+8JàQ54 Tc+I"=c&];M'(|0¶,l5taO1IliO8]n4i˚R54m҄6E \lODRR?8hwjJH9=ЅBEfwHw\{DG fٸ4́ĕrf>at+mb ض]TdBJۖB"e}8E^ NW>^l,~7 X (7= ^tx2q9ur>|)dafߍ阶} $;.ms:&,Οc$b tL'ۻq/f|H{ 5K Y+Y_4w⩚KȐH)(-ĥTEiLsl)]wcL4::0@^,(#Q (E}Ki bM !cxd䚜))(Tm[96"k$ع8?+*IdxX۶HEVCΣoßl[+h6ebYrJ_GBkx4D*K[e7hD SJe#D] 2{nϷb̽}v ~go^-nv).]#'K3Y%rSQRjR֭Gn0DYE QUPXTLWw~E(#h\fUaEFHRUQ@QQ1A2 npSZUIa@MbV\Da̭A ?YuYP[[G!Dx=n>EQnItU5Ts) zNNYͫ`BDMndYugͥ&wn]4^zַ9?btttPQQA;*44 [yq_ s|?<X q:46-3D6M-+M3XVY_2RXqg'Af"3fC -[օ&>wC]iVYEnOm1]o2-!]]s jq#EQ&O6nNu!mR쓌O((7ko.*+(7;[ʵ\kYQ哚2M S^%\."(V&!tMh_P^I) B {GQiFnnØprKB]sYQfrTWn*9RQa(( EQ[jr"EQn>W#TWni?@*F( Lf /^x'Ȯ쥪z(KӴq?hI؏Ex`Y. ]U3(7 ˅RIvʭCuEQ 3V&42SˉTJ!ض=hكF)rf( uvOҒ68t]ǗρA׀Wn]BѦK6eBdž%HcIpuL~в(m{RB3@J8)(.&/ BL}M\tuQQ嚛/k=;Zx-. 4^:m;V5ZBOF2Nb|9Al^669 Lvlj%XX$1QW% ;[ilyǒR 0i=GI Mdn4 *i"P[xbj+sc._u"1 $'Z̩Yğ|y^LƆh8~ gQm vl] hLdx(͖ߚݚ-P(ʍbjHh~7)1M).eˣ_bODUm,,J)-09mvjl. lMLa5%$X7xhB0t~587dY~/bdgo\|IJ,@[>仿?Ä ߽IE!ɡf}yի`Ӽ|l9yx$f/q2p"ynIYTjfT|1NհqE.o'bqP_?+e̔ !iA}篿\N~iĺ[-lcn!U_f,r ih|n\K}9Iq %O=Ģ CαgS`%>|t/ 2M7k1Tcԯ0$% R"f*VOOg tz͂O}z>!mY[6]yerP_Ocs;U˹wc5{1?y(Gx|}Q6H|Ϋ*ਕp:87 D7<-t͛~&\,#sC,(#4oynSTRb0k6m_a/vMR_ZI8䣯(>Kc+Mp+w,Ǔg`K׏i?;$zmGIH]MbLm4c8(cLП*M׹F.998.e͗K]y!h/g;IuK/f假yp|]I?+q;_xE9$ !bw-å #Dtp;g#86l/Y)8C@wEڄbqپ--{ikN:}Mڌv6Xl,eA]1=C q SVQNq~3{8nPUx:As w;^F{ "2CiR4H <9t6vsrX/~*. n2*ˊq_n]4Ǐ!h lZ6iʴ#\RbW%>Nh3:@QI)q]>^cmX]s kP&3 M'@k죱8"0vzXI&+4ضmw1 n\B Q.%dƃs>#`U]ON0ʥ8@;2WrhH%䃐MbEܱ hq5Y}z3܁0E4@"Xɐ@ZM9%+¢lW(ׂ_Mx%GdJ2c548)d Yc?ƀYw-!a[/ꮓ{2 !p5;O$mcV:-4\^/.CMʧLCh$AVn^JP>Idܳߧ?I(F#ΑʗŲ ? q4]61u],=4H0GXU(]P|2UxƆ (˹d a\N[W]Q1!kVd1>^3MlamN3 [XL$?|f+}R*°M8D é'I$R.\GH#+$2:D{K3}y^Ovrn,Pi%h{ᡴz.չiN}=30LRYU gOhp UO!Dx=n5`>^Ke!Y,[J1N獵֖Ξ=Ua+;];q$=S3C}t2%wgcݼow|on{ kYWWBQq '9?c-TLqاnCB:  'I w_0qmfg&"tuv2Mi:nbrڅ5!8]tGp ,Ԑ`w -Tq g62Mgˎw $6G[Rs[\JA=<MPKwSPRJYa>n >p#i.G5l) N%QXPAK></ya|vkM8y" %}se/iڅ("3fvb{bkp}%L~I'C3MSU 37эmcW'm{P$kҤ"H9e쓗\&Ԥ(JW۞~;i[X> R\v3}EQ(܂TWEQ[ ʭC-D(2LU(W`l,k,TEQ N1>gaimoއ(r4*+M(Ͽއ(rP}(r R^QEQnA*+(-H+55(75Wx喐$gGD}$(WNJe9\RP^i#&NM,< (WS‚S&>-N^?eR64V$<: 7?2>EQ+#'3JB Դ񋯢\ ~''+ g6&||3&HFf,i$'"BS,jN(C#Ē&B q7hQ!V7YƹE$W1s^d*Jѽu񸝘(T-f}EK;)ʹv'd;LJSuN0yug( H녟‘w?Brlhm%h9@%JP>LINl~=eZl3A_Qz8QCS)%7{>BEf$ a|%l?u Хm[z`O '2F@ Hi#%!:7SjlJt}ٽ3҅m&7^xN-WryB&V| n#xxet2G fK:l9uZG!Rbg؞D.ݽg#p:/}X"v*nT?_{*V/5$ 54hvYR"u=^? RG"#EgK-]CD"QXh6F|c'%4:M eEUpm`N}Z!:;ΌR6Cg3}ܵyA=靯ʞt6X//{nd f<ˬūSc0?O9gjUx'O%nC$?wSq)o{ {p9]}:#qXK~IRS]7 M#4v (swRLΪH7o?_9FD" zSWb {.{e?i¢JQ26mXk֞.'{=^S{pwCgϽɩ^FDS)O{c7HG:y/r'%s~ib4~dz:M^_(Yx={=f6GنפzmcaK%H-=+dy,,2%~v0 77s)5=Gyf VNѼl^%9ĻOs+~‚"\Es[ 7~w^zCڅ2俿2ֱf hg}i*bH[[7D,ܴE9]iifDt6vI˶I[i4HB7tt1I"%8=!ʫ*X:7N֖߇m8r`7V.(׀rZ+,[<0U&5%y@>|̀XgEb!x8u gϥ. /e!aakT_i?.wK$%W$0iik^оe5o̴DY~p8-7GAA>{䮾wh|p΁煹Pi`߹m %aM4opy:ܽn# }RBp!LYN2#/A9Ћ3w9a%B8(w81Yt] s o~WYIӈrQ?T Fûr.c蠥{Y]6q&^6:՚@h:!@h;~ҶA)#ot/纆jc~c1ZZaFr x˖FxBA H M˶.8[HVaFbRmp˿ǟ{VT3* 0t֭[ol..**ʯI> tH'o7;¨EII!co!|d;/>t H2ƚ8ЋeضeYX3.{yw,)tܺL.:d@L{$g tazLKIq( @n.~r+'OJHico\Ea=tYфA\> /?SO|3itC25FҔ}up:ul"o~l&%y~w4Mln!/$r'f3 ta3|C libْP~̧{vª< en{{CO{}ޟ93A-[5v&do6{y^MuM&q\"۲d[VE{'@D6s~R}09w̜rjk* ߵç/M$ᠸ8X^Zcn*T)eɮbj KzٻkG6/榢DZ={k04K4d)Kɒ6R8WoZ:5gʲA~զ=<YH_3ִR^^v)Fhnnw8p_Dq~CikLCJ 4]đWAmY.FbgUTRYƩl"o RY]Ea8 'Oެ#THGRIţ]lg8a:),/ m:9~IaUu\aueѭqf\#* ( Mb1e69 6KKK(4 RXO"1ZKXۑ19JGk31$\PJiAyWw5sQTRtjZ{r(%5prSTy8$] uitbX(mM D+K~~"2o튳oS=eYf q:[pvhʂNh(4V=>2 L@6ciƶV00 #=Hs8d:.֌G9b k0v̱tfeyu,*Nh40tz򇃡PWækL;rP\hd 0 3=ʝ-{ң[3tib<҄Ffz{鳗ߥ>c Ʋ.5>LBcOWEge4Xm,*m}6lMZYcYiƷQ*o>V@ؓs,YDvU.J(Fԛ.=ͱt]aQN:>2NN$*c#]Tk֓>=J[Vjq'nY~YBYf|IAy%=0[WV5xqA.'܎~G%.bftlۤz#iv9O\(E.\Ϫ ߅Z]G> Q-sa!5uۚ4^*mzŖ>cu7r mcP'/>.u! /k~ZU)AB!,4 ^ %mB)(&[cwIsPep;ŁM 4 Mߌ_4q6KBaߵx1O(n7w%^W>ȉlFfB!ćżf%B&)*REWW72bNLI( ;;{کox1)EkMQQNB\d2IGg'i n|HB2$+땆vB9E"}K2 0s ȜBCf.+uŪOQ{}ʦ6i}t+j+Bf xXa0m`֑Hn0:`phx a8<. /8+.{{?xBA_=ZPO~z??ɏ9ԑVQSil+fVTTcϕ)ϰ9)d##.X]3]*oq(f܅,?f&+/5+P[e+m-8$0V26Y覞(Éqh<:?uSa*R(›g|2 ҆O(H%ӛÅNVٯgg QP*]757Y0 4mc`Rhƶm4 4@k,FeF)#Kw:Rl@>vz]PcY lBL1sBgW _ux(CN6d(H ǩ}, y,kqi{kr.U)#}.VI{6a;&eٓOO9we(.gN5'+P{՟Ʋ5QN?K<Jak#}>;S9z:ӀN_/0ӽBf1cLmY8˹~ ^~ ߺ v6q| Rd9F:;iX]η8Trfn_ u7ȃ[l5JaUgOQOµܶf>B[ iSQ ,YՅJ7q1ZGl}+ śprQ[8;X} ?׊#6mر4GR,X5 p*P F;pbɊ%ćzo st=QG>nLuHo1~J +( Vp':;!tO3*;SpWc7sB d-f]hPMʵ.T69s%˨*t8y己$ƣ|}9+krjz8SK~Y>#mk]P˖ͫ(v75뛨\}Ec;}C&V( F9c; ~ۆ~i}S]>6G9cTԉtȩbd92)"8q$C뷰:sBc,#k=+Q~Ɔ͹Zڴ6)!/Ysv'8 Yd&~ʶBaN"xxdC~Y(<ä 3fw>[H8}';Ҏa(F3_t+&m^yLvv&pf/ыeѰgm<RIDATux.ү<y=~^c>cW=ݳ/gw?x1L ~^|8x&~u{^vԗyIGѝИ.7^Xlcһڒ ͿIiVoƾ(˹i7ګ$e+kwzbܻ<0 Xt19E~ѦT/>ۢLBb'xf)bD?>s|"r3x'f6pz(^xt?[GW ϙ0( \'Rض F H~gis|Y~F@)}-9ݝ!ܦrz{ƃ֚3gQWI^kp<8Ndh7;x]|k2\9o`w?|?o9zQssgxZF\Otpx=n"c:,3Om&}pK)vHr|YC8ӃhLrPx; I*ʑ\dv8,YQFSkM=ugi9]nttݵm6]G?}a  /kdQMjd^JłMweY>ýDX:.e5%`iӋ˙q9$SB|96yyg8x;︝& 3ۧzsH  ݫ ;P&L`i500f]x᱓9XBй?Cήwquvر4"Éch={# Rn%غ{("7ӰN_~"_ %k )ʘ>W-VSO0̡C\MRvk2>DO0=qJ݌GL+Pt&%KgАM`e>8 0Li!߅k-cQv9]:e`n1!2Wե [Xuw=;pOS5&7ĢgON6C*Sׯ5~ij|?KILMQOt:ٹ;G|YWP>]$ 3sW:EɚbI#nZ:R,So}x$+ޥgbZr9WBUU?39x"-m}D[O= fa% G9z M囟_7;.)&u~Q5m7\ʺ il+6LJᄕבʢ|F:C_Ħ=BuMhW;z-tƨNȡ#l ɚlO(_ϣ,ǣ+3wjGw#N\2)_Eq-,+T(-tNtU!`-w3HAΖVhB~׬ 슥l nkos+2< I_ݬ.("N^}U⫪^{-1AFq K;֟hRV-}| l.6}>OݻS>~*۷$DY۵|Sr+Xx1> JyЦ7IV|~Z[졵Xu6j."R\ҫ_ZMuw~YTCVh)/9l7 +{^Np ё(宀GDZC#DVJr W88VAf=m-Bj/J8lB_6qH Cl>t^1VWd~544D(fntV)V%I<6(f w[W^1{Yr!^k(ڝ˖{aiiRq ;KPP o0%j*+ĥ4JA"@MiMfyԖRPTH8KtpG}PJ$p+zR[]FNKvI-l`QQܢrr.k) =}#dWQVX@QaCSXXH~A_YPXO(\Ȳ+.Rh9TUIzzR]T@aq>n;JߐQ$SHEy N2ʋ8'*|U)Y֍+) SXRF^8D\\I%\Tņk) ypYz KsT,ZͦU5 w+ᷣDخ6sB\YTR^K0>E@rJ (*#jgQ[^FAQ!y~ * b. K+(%KWPSܱR~n{—HL7EՋYb!3A$2hget]{5/{,+59\鮋-Iw:O Zke_zimaMh-{'mޯB\_kw;8PĠ;2L~^V {Rh3O|qK׊0̋!r(BC݊Mt3*a  dbc%obN7n[y!]m9=rqg>7޿Y|HIs!lOOZPCMbΚ-|uB,'˲$/R$igx1/puu# !ćY4@;/<5> NB\Ӊ+^i)z|!.U(^+R.iD?x!V#9x1o(U1IW/hlf'E!ax<3o bSJDM41 !ćS|_$BA~y㻜@b84Bzz33fJd,z!\3[RP[Ԍa` -ֶ"n2adU*˷y?\.FEcޟ )z[C\+\. s)+-$mJ7;Fgk#I,+;Cqa^C^)E2?W^8_JEN4C^3³?l-嫿%^rP㕺QR &,*KI s KXt`5p9W-3﯒O)Z΅f&+7勖2z?  Ed&\R(>@tSoKl 5Bة$7`t;1Ϸ\)R!F,Ab.FvF׉i$m,pqR6*]A?9'{bgmض=X~geδ-E6Mg {%hlfu,.¶LM̶ǖgV'cǙt&Nn&avxl?ҎF9i/+@Ɵe@lsI(^ͧ>zYÙ?|3ܻ/O/ wRW!F5+ױ:NH]SCCDmm`AQV"Uw*HGvnhG ;6Wp^NXS}3Xsܽ7?8pŲYR]...'Yw|cVW/ t/*]G_9וbոFIzZ.p~cuոHx'((NT_yRXmG}q܅l\bKkX^\f(A0M8m9¯~C6^ы{y엯6N|nIGۡy] ē_-#EZQp+'4oGqc nOSD-0A/aƞ@o ?~ML^K^KGZІAWo7gy<~(Gؿ>F 'ۇapt۳OTlZ^~%^oXOaOsaAmm%6?y_fsuXšW)e|sD}|[VrJ-7H?0,gmw`)mEA Imv]/#guaXzGu >>^Ianea /HA(^b~׳+A|w(YO=+?&K\}*׋4 4PBV/Pg5֯&g(xvq^ۉm,' |ͮ<S.N>h nˋaX{zt9Oo!!Z\6'k(۲lms9GShmcndN<7R~RX^Zрm۸C:dt4ͥmcjB$pPm0>#5LO$#i .~br]*b˖u7AC{" sdy@821cr8ޟ Cm4xud9Ac.("d o>L_ FV.eŔ6s;jj'207<7OQvrf~]ᡔbhx;iNe0ûJ>ăq*⅃(~.vʩ`QE1Aك֞z~7#vΝk"f3߶ Evű6pQR;6Ͽy+CYy)yYx/|] `%KWqa0sm ު%,)a$e0e&ioj (2G4ʊH +6嶭)UM/AS8^HJ ò/cSgⲌ3oOY0}57AkMkk+e(E^Z Q^ZHd:5JGk3}&E%t[:1$y;Z 1:9Bg[;}Ir (.4Z):C 衣/I~i~̩3)hko'7CvvhRqxbt. ʣ(/1^d1FsάJ C EL99Fc{\K{$l'??5eYf q:WД33(4ڞnFJ׍jz4wXuLjTfd ec6!oIEnuW cc KeϮL3Eb kgIj~_"Vhmm=s5s8̧WTfh^k,F)#`$ N:4̺c@6ӄ-3.w)פ"#!flƶ:3؟+zr4J{iڭbV渦6H[[Wحƶi^ѷبoױm˶IS?Á}մ>_l]m.|ʶ3~L&&v4N.B&)L{whld0!>D:hj렧sMmRo!Y$46*VWݬ.K[5fѦGQIlۚՇ!fnrLvC0!RTluT~ oF,BkG/ڝMeUAlèDR+z;{a^KKz b+1MkoҚrN4Bo{GEbNp8s$͗\D;/Ql*<՟ff=E0umoYPFOv݃,Ȕ#};zAˋHt+ҧ`o_yEɋ><ėSx$gl}aB1?|`(x(+TuX 4w0l/# Ѕ.qV ӽp}OS?6n$o8;ysT\LȥHZ6ÑF 'P=Gm[<+v1HŪn!x:PςGo/kW(LI,?\_AFMMm%ɳSXoes@*e zрN9}(GLـB)pb\A7eF ėz6% !'f~/ zGG5mUge0X.>:HxʾT>! km1NwvwZ:ӾNeۀEk(U+eIByc# Zh;,p9:2Ht#\5B&Gb(3馴COģē:/;Egۈ7B!f xM|40-Էv300@$B[ ^}]z[>vS|_3bsmFadhV### GGpTs[@?˗;;u<#Mbd(Ɠh Dm1_p!ba`xB!扙)1ZIjظ/њ%gf 8 e_l~ Mq\ͺŕx5u;JrS,/ H=<68I-G>P,Ia?9;CS}+ظ~!Ags-xVk V-.`* i`'bϳFVZJyyi^}Z_&JI˯7'lߥ?Hu(hko'7CvvHB)ur,kLA~-h8;4e촢W|N/{AnB!.V!ӓ/BCByHB1Ic fM6#lr&XTBJ)d;y bZ%R#L)Evvj7 b^p88B9E)5+w/!\#ByHB1I7x^jmif{~^~$yAkM__1/\0əUy*x"16";;@ kJ0,^FcY9n0$ `3[.^yJ)"!'bQTX0)* 7'gƏO$4 ~L&gdn #gx1/qr9*'xvY<'?/oR)>ۦD"1ex@Ytg|ż/|/}g{ߕAkl۞,ݳ$Rּ[5~gJaB!f~_>f-+ma"pݘJ r`iwkfcpgb{3eaX ڛ8u%=?QB1f樯Ox>k3E/Ls+M;Jr7Bk6 eYܭD#+.7Ny$G9uٸIxrZ= b><^|RHk\n7mmu=ؽYt(++J礯z)9/U.;;;x3`x 1/⋟.G.> X"Q~R m[ 02?&֍SeRTӛhzs>I׉2c+Pc)}YRv:H_hIJƲ,,Kl{)zmm&}j)e4ȓB[2c^&Jcv9m۔vOWJ|/? `g=9+x`Q9;_=ڭxh?y]b{V2q=N70U̝EOȑcJb`1֯(Q:Ew5F$f:H#ml,sbbt5rd^5Op2R<(g(-(- \lcpp;Rr1.biކti-]c4;J]{#_~׽h;`OMk_Ȕ^JN<,[ER(ã`j_ &(;1csy65^` 0es۶'rk|ݲ,n.l˺jxY`Wh;JS0 /|^Z|(;xOWQ^I:k?>^BSS4gt|u] ~l''գCv]ۘ;Co>ͯϻT N*GGؼa3'oex"\@MI !g5}~>oku*{;_Ƙ?zdG^ {!Ǖ ›.bß+] '_KlOov5`">/~íqwqWٶ=êի `A-NkJ T3֍v"qQ-_F0@puf,FNne*hjcC|tC.E |̉{o~5E8?y>op|`k2 P|K/NtN.٥i^]C4M:zF:hka]3L]om '~Zh&vfYY֬]/I!Xc !i,>w&rwH$mkڀ}lQ<穧z]럦z;!3d[) fk*f*\;8|qWǸ]/˟PUZF d3:'ONh$a^ rD=Za iwRvs{_ׯoY(sepDF6maY6vznjff0tvsYFS6nLLn~BR&'[E2IJRW>!N~?X8G_oX;]fڌx_ HxXf%YF7w!j[7aÖGƍM md/Wi]d{pyb8mugsoex+}q1g^%q~[9u W5k?ɱ~7 j(X|R6H"̩dR ^ށZ:@b1(TAFcI4--ޭnDp(~PerYf ۟77@oG3.vOh<&?xWˠ8B[g{ChBw_W˛xRDx7ϲMT,/NwAK?4 8GB,sY*U|o=ąsux}Vvl9Ķx~$- WPBpJwxؽ%,ݸ{gtp|+օYolUF9|$ RdeOC]>ezc慟|KQS^/s_Ne5˨Pc]+l-eU~@AbrṮLoˤ 7X@U(3!ĭFvmSXXٳgضmշ5%%8.ڶMNNo=7~iEmE5eu}M]ZiS-kZL\M_mۚf6 <*;=9-\i\[[_!]م eQYY7Q}n^+޿ե^7ty͑fBL ssР5 B!=V;W7:l*S !CnVW*/[3lw'r3Y&uB\u,2:sRj|Җ鸜NgX;H`4ăd8tx>"Lg{$y!`X1Ҋ^!$ !ыy#L7B1tk0f>-^ 14B|imx gx1) ;"77f'G!eY_h x+} b^tGk-].#3zlܷ?$ !ٹyIB!/WJض 0QJ֤ 9i>ǟxN6-%t=P^vs>N?/e$OqNsḿwwjA.c>n¢a] w5+oqgȪ^/][Hhsa$ėsςlb6Е]@ŋ (mjݧɫ&@^^QAAvg֭Tz$ !U3MNНHR @)'y;﹝-[n#lb~srID;vn<կ-vU/P2. Bfm#& O=9Jðwϗ~[_1s`Ex9^B{G7);Kc㾇?~QB# ~KT,"uw}m~vj&'XS"I˱W8< *bvx^(8O( pWOϓ6H, ٺ$EC#';Xn9A?NEYYٞvryb LdmW^A7`N,/XNrvjm:͙ OQvbkP(0"e_1R 4J1ڭˆZd߅B̮6mjFft4N">J"a5r`8E:`_PtZ,<KkM?5Y֙ Xx,FX Á41MSiB:=bm(Z~7?|AG^<Ԍ"Py!nfF3{<ɶHS$]\)W 5;c )+(NlO;& _PW[eKmd25R8#8f$K²t:'oFG)0_GDwqLu&bL ?S*?y'F|u Ϋc}yô:H?%~Ml$J4:0N%FcQ%-d!(XM<:CQJ&:2P4F|޳yW{7oxڎ3<4# $GGadpѤr h?y#Sol'Tduu1Ӣnׯ!SBB5chyƟp4/ճGger: ,,Zv;s]gPG,.´㴷_mHQ$@vFDښ1sVm3@nfr*CNۻʢeei{xfRTyiimei~%w.S\hf:j\3Ңb;,*Ȉ9H,{ 7ql^GQ^UqU5V׬=TdlE!JFVZJyyxt{_^ѬKc_>= su.ef_R{y]R #fRvr9dg !攺zq\S5]l ?jsx4`烿RoSoz]:e/8` !tB!<$^!$ !x!b/^@1'k[ q8Lx,NʟIBkL&3è|/<5p^"7;9Bq͔Rdg}/AaANB\Ƚx1֗D!"id'BCByHB1]W\)R)B̮$l nnl&BL0 xRs B!50Ø ?/fBqKHӿ?F&BB!! B!<$C !ƶ훝Ycg^$ !H&"Hfi^IpLqV>k!^!(NnvrfE*M8sb-˅a󲗓DHRrIBqZjgu+{VB!nBL$HY3@LbKOGrmQ)Øs'ӉA|Ӝl4}WܯB5RiN'^)i1M>B|TLN1F];N@N>UՔdc;ECb}+ÕKܯ+9j:FH$-JYh!!LAk4ȯ\=wo$drb?u UXwIm+dڹ7 !ļc}y)giIXf=ׯcjta~_Rx0V,&tnn Oӧb4Xuش~h;c 's.ۻw SיfRBnn4( !wbjk=w?wܿDŽH^Z^8==bqlK@1V=\oWSY\ ܯqN|?Ғb|=b)_w O6E!A\z [|Ѝeߋx!21bjeӯ?宥Ehl:;wcҠ``8"'W,b``m gw9 q 0<C(;iQc$-/@(˃Kة\oz(`dٲ0lL+zϳzi9P`( GxkK}UeA w# bΛ =ʅ'm5x9rt*FZ.^4 |UE^[O /QoVqׂڛrd#Y[_,'V|':gt6|/ݽdg.Ԛ.:c#lʾn,xXvo%YUM<NogUc6,ʝ:x!47PKJ%`ہ֓OQ0~w#{|w<]eq,'[ȩ\ʃw!o=El?;ʲMwO/~!V@r}/??D,)l&3PڧK |m3Ges9eAz#l5ë&/zH^!:=5 h$airָUj:b4Dbʋ*defEd(bo%Y,[W|`[EykkpEW }x˵t߃l-?obot/B9/ &,Cem /Qmؖ 3.O720H*Δ Ͷm4T钁hAxp[kl$f AY']!uֲEsStM( :EWEyTWΤܤp|׶QFs=~ubNk'fP|+sm^CMXR w$ugr1B,bJ^':MƗ<8C@ 40 H`r&yC'P M"/=tYV}bض&P]G[4P2:͚fuUڲnk_WL@}Oz$ !vZ|˿aY6v*Nۙ MwXFGnk{p˲&RV+$%L'~rx>N&LKH eW=f"_yp _ mhOoĂ;ڣwVh">$' <vUZb7XC/!SJ14%Ō˜R 3e$[ܯx!ÔRYY7;)r2R/BCByHB1IB!t:aB!sdc<3|c;IznY!B|}r"(uL#BNB!B!B!B!B1?)oH%tEXtdate:create2017-10-09T14:11:41+02:00\r%tEXtdate:modify2017-10-09T14:00:01+02:00)ttEXtSoftwaregnome-screenshot>IENDB`Eqonomize-1.5.3/doc/html/C/figures/recurrence.png000066400000000000000000001410241416454732000217000ustar00rootroot00000000000000PNG  IHDRQ;YgAMA a cHRMz&u0`:pQ<bKGDIDATxw%u ~y[j-Ѱ$ ) F;~>iV3;Oh4"%Q$E; o^23뮆mF|?*MqΉP( BP( Gc|"|ˣP( }*y6_ @GP( _uՉ|<$7sKP( =6K&0nuI BPg }&P( # BP܁(P(  BP܁>MR[])%+(>0BT(tp8a|D 7I3Hir:A MQTTnEQ(;%0x1bL;?`I ,BhnjĦ|vED"S^VO B} x4R~TE* p8Zw8%>$B.hVEP(X> J*nެ0{>.\$Qg"y !41ʟTkEP(n(R 4\>~S=n$cڜLiY}/+<7\ Veٽi.ܐDуlҊؽE_nwBP(8>29aHQT5W9ғq V^NU`h"usϭ NeQLyGIb[S1FAYUѮoUo ϯ-A& BPi|AxON2E0#v#l^iL!,)sUb3 eޮ %?~rV>3} ޟZ]WPHQQT US?_clZVfKO: @^|YTc7s&r7[zL|%lwnٿKu?4T Bq 6x9) RbI h6,)q ےĒi 8F0iK'PP۞W*X&TJE$N=/&2,ALx6܁"JntX^' -D*a' cnA !euRgF1Jt~ۤ&Bml(RZ{'X\e/ciMyyg ?/Dmw?=7F2Lǥw}m8-i.z4G[(aHi2pǞz] &r];#}YdUb7G2>#=:}Ksѳaںz , 0|/j^`Ӭ^\3ݧiyyh8vᩨߺҽ#ʡ^ĸbt :#RCkh]Sd5?^ 啗uҠ_J 4h7kz*W0Z[9xM^}s?Ո(({pD]DFI)mX vwY@h:LqĒ.!AB82ìYPˮa MMæH r#OnbI)%k߃ft:)++ m~?؋eǁa-B  w؄'hڰM ={ɩx4!-.1۰ٴ M)I457g:i"EbB.-<ӟuXR"߄lNQUZfti3/I-2#ٶ_~LFռE43oaQ>8 xSK wBs]@ZX&Hl|N[2:@lҁKi_Cz+>ŧ]kҡ @@&'>>HʲzŤr,>l݁WDc3s,l ,(0YeE!zldLX4ދ[J 4,, hXTpL47GXr]&'']ZM&clD`ʍΒHLbcnt @߇"P(M./OQo9o?t3a,e|'pIYJ)qyx1>K$ciL֜Q'~$9Ako=KMɯiOb!r!f|ʫs~.t Ml:Tk! uٹ0)]ЄI"m,*A^<3:XFa^>P(w4ӤL0.,l6C*!kZHlX(mmHeWad1 l;gYd3q"<|!-),x6Dt6=&kZ8 X|!m/-D=TCsM F6C6kdmYRfi1Kq]58+LƨX@~vbe]}T(x02TӒ&tLFN`+d[@Ĉ"V.ofHg2dٜAJlL&6^|oIoGI|Eז'9},,R8(.-{w3˲l^q&ť#8xoa e*pz8~#I d98$BP BP([ BP܁(P( vvS\'riYjWB\eVR b= x*Ftٟ7^RrX0ޭ.BPܶA n+ȇXU(>$) ŵq8rK?R}a BQ^P(;% B `rxBP(>|M OD1 HDlj$[]\BP(>0] r?׼Sv 2sU.[]Qf{_kl;?\P(;붛Rvs^'!pbV|ˈqz^}yhXuWK!>pL N,kc!…s?|Z\P(uH7tDMvךEqM li^ JW '$A,j$x hc1]sPY[OQ( #RvkB!))gBzq (?@mSi3|V44M̝3y@q˚:+ -0eF-4mry4!}s4SHkC \²rစ& m>`Mgf[!?/!7s`(C./},ks-_+P(uSћv?g9_qiS $+R6ԋDasu8Ccq</!F8 J*ŝW zzȺBTkS[A&6Fk Ayu ~5j&2h0xQRQIk:4 `1zGTRL 0M15 *(8A"  BeȄ).E|ή^ _)-ոm`f8>C=D h0Q #4T@6I_o7CQZʋ< L3>2L;8eR[WETML?0D,3PDue)f Bqk~6֒0,5r?4d22ӗ7+=W^={ mgOp-ÿ|j<2Cߥ$t34a3A˜8"uϢլw, \Y+ɓ$n ux1' ژ v~=-5CqLCiʷn'+Ox:0{_&{X(^gѲ$.ӽ?{gl BNۋRAvoFb@'oWw7+^<u_n^7>N_g_EANc${U; B\7?)O+tMZ?/9Nvs7&h7!HNL lT֡ OУ5_U?M\> Bv@6v;vaa(+(Zyf*;n$eDʺZHrk*dՎsRJRaz ˞W9_7fƟsH%F雐9i&FzC$ҒB95rrf^j9eaIrr%-8쒎t&1Ó~3=ݦ|ˑ9%O!'w.=gB BYf$XV2ȫ2#9SDdIYͺK(ڦwNY9v+'-+XMmNIusGq,l&E:c^ 3KWXـy!iM#E* uU?žc1D>Th@hHLgjid3\EﳋkE"%| jeNF%H&'Rd6M<'8ôv꠽KPA;ЄE.v t3z0R5<#Dh3pN>+3Lbƽ9[T!iV"ɼg>W]gtn+l1K?8#2uH#g^S( Ғv.y x6TuQKk}|*bxd˴nZ( BQFhP(i_HvR222Ja(R( B.la.6unz Bޘ#Rү9٩n zawI( MKfBq`aB/Kl8\8e5 id )gnGj331Ė|~~\x(P@Kya0*D ԰7@@s::He4IƓK4S6F1nPu Q޼6>4;_5yK{fԞ PP5-e tƘף|w~OoZJ?᯿q=fwSVVFPS'à 4M{\؝^ZV} :th1cf)躎͖bBt]fBLV fnYihMϟ4riμ~344MLchWI[T8]n{>[:HWLaqj u'J]udzٷWn/RDػ2TIХy|{S|;sWK<t|3IcL2r(G:t/qMt~O(tвa~{/bYC9˅lcx+g8e3<< B%\<Ŏ|sYQ.%Az-oEd F ˄Pa+ I{ kVա%,YĕJ Nt2jA{':>yܐnDyt?&xp#iHwVHkFdX^BvP!.?CSoT=_|x!',^DVC̖7"rEx:uV֟)%ELN*( 0ks`9-f؄;T$iK>U \(P̅`%$\> oE_>#$wϰX(9Oa&% A6%fؠŔt:n/@IE`iZ~/W1UE^4+¡Sq7>³Oo.r_H~ <2'egIeLDGϣ߽S`&vO]m!5fD!+~Ǫt۷VUyVΰ!6+ek/J+s#,EWeB17ʀP̉MH-(w_] x^?L̹Y,#a;/=LĐya&3M"f]Y9|mRI2r1CNf)'3% ̦E#kN]gs]]~q]{Ϸ24Gw `O֍ڠCSP^sM%6}O(_7ua yf'olK,b;N%`u[dT0mxӒ -+̗E.ڬ+,ƺJ⧶X' `GH !(LoPS[ʱ9>+D[ZkEXW9FC2_p5M 3y4!4͐Ig'7D󕱰T79=3Kd" 529F9֧)$wήVYN}YW Gp'U TSc!r2XNME^}=ooXk._n'㩠hEv.N8SYd q_45~vlz:<躃Pq񎣼(C Cݴ),X7^E_ PA~EXPFEǑ]8t ͣ>rU(,jV*ʅ;y}'VCumKymqKp؉=)z.ɋXRǖl?{PVBI}oD;DKX~˃/u>oν\^y9<_U'W(f he.)//R^Y׮)BR*K(.g&"M,#h^Š5tW|Q~%_JAJIoo/55We$*#"DZִ: ;rlҡL -}r]P(;% BQ^P(;% BQ^P(;% BQ^P(;% BnԎO BP丙nÄ#Q=BP(w..Pa!Q Mh BEJOf,/GxCl]QXXbH+ c0Òls|SRv]ݮwbrG;) B^iM7Ao~MLG,e0K$11DO)K B~ w 3Iٞ,2 ݁ݮ_'fHgHt:un!p7ُ:Q/T@hǿ"R?OSxg* BG/ލ<̜  ;__{aQ@?O/냌3܈y'DϢk8uUi_zp!MH Bh˛즺K)q+Yrd;vsi0ЦDm$e( 8D)-+o!e^lj!BP(>"P =8!jZ?XR,ߠC^n 5 m2xNyoJ.BHKN_'-L+RFj2'Zi^s.23\*Aޙ.ji4-iaIt]iXJP(+h7͋~_RPlgN:]HstQW,gi9V&x +hcH ]a J H uqg Wq 6t$G/O֋wu QWUͺˁ{@&>ƙt(rZ@Nԃ4=# VXL'L8Yn5M} BP\MH6UP}6x{! ckdq I0V^gop$'w^hʂ8{ce$?;ΐHAbbx8v ;Ϟ@hج;_}m=6pi^FoFBP.tvu3+& qR*b˼sL,I|4Uo]Yt)RP>O{$f覅^Q= PaBP\_${h4Ɩp946Mrpn& 2F/X SWVM $D,m<\HsM!B&5̧ҫqEbBq{8l:v,79e5uv:.1El6%XxXa t7GL54ֆ6P(ϼfVZ]9} [nCu^[O~>= X&;Mk7̓k?kPӯkH$Rb&eNoBlHÜNN6r̾I:9㚼{K;^Ά8rKX)q BP|\Xt y6Ѓx<>h7/BNHRX {*vɖ3T4W@L)m?a,fذhZшO$L< S LMg :rN]5]^W(`UǙ\P]P(>,ZoȦMW )uWVHG6z&df~腍ԇdRQƉE t2R4o ~zsB8pyFlQ&aFGd,I&etlc$zܳӗ:22:x8DS$£ND!̒3<e""!%)Mf_2G:2K7@5{W( ;r'7gS_؀&%jqBP(ލ;g#gIiX: 5yW( Żqw)*?H RmݑBP\gS( b&7O2&ibBP(3d,ynRvb_~*P( Db(.*i:w8TWWBP(͆㙊r\.\.MBP(7}BP(7% BQ^P(;% BQ^P(;% B)nwzd@7AP(>J$aw&ݎQ(4J0 l;R) $( G;SBH)466t8rIA$a`p` T BQ#&uiRm6P( EP|o|nau)4 M@o Biw:f ">>HoTP_Y]/i0N[GGFJ7x'`lpᢲ])bf*J`AgS\nCZ O$#6@z!дۻ=?H),no!F\S !30G^2{D?o}N&2 ! o5^F62=Ηs/7:O~1Zbij: +aӺxl~H#``qNTipmIkDpeT}d6P[dyf46C!!t]}J C,Lt\+`^])[J) ,pznB8D+DU4 ˍ#W9eɩ]!J׆M=-{W?SS}J'01L1~08|z@ׯ/H[I.uhīOM'L7aҰӄ'@/$cdq۱@3&bze{ vv_n1-s5Nѵku|*lïD >g7+9i0r v!p`60+̺춿sof_>HCAj`Bsϋ3`-p˽K# }2X4IrR? 01:.?DLi2ݭt Ʃ] ٰUIhG- NêX] +矍G8ǰhߌm&j/d5,tv:,\5&:%H)a~SNM`BSBoEܵb>D{#k⾻pWJAj+:67NYY)ozt*+onG}uF:JO[72X33…dܥXpy:5-fiK. LV'XRRzNc CEKt D)_xl&]ǷoHb)Ӳx w-L6>ё.Z/_?Ѵd9󫋰iMFrqeaH˭\&ihZR <]4wYY/rb7Za=W':9Mxn}#߼u}:tLR_[ ݓEɳ ~E-Cfh;&d7{.d \:F?KWН$.:FHS8 +T&fLeηIAe"Zy'|㹓tvT\ŚG&:ųgҰt HRa:;„;ø%Qq2VVjyx2R 0vSz W.(tK8JXC˗bK] F =vHGh_XBvC Xb!e~o{#T4qg3x+g;G5jY ~+nnO 1QFp7~gݍ27N5C~kFaz;ޫL6o=QZ^5tN4.?z !t.8u^߆D:ض{?df !Hezih+I7ίc9sjF8p) 3?&|G}/bdr~v_b8tK/0=Mnw]A4ݎ?JaaD2M5~8=J"2[??a󁳌F?wi k0[c~sdq4;^.?z(qS wyIF /l>ՇBHpC:&z[9r2D {_o< ҉ bŔX2]t_v*ǝ5HV 7ãx͒LspNZ Dh %%Ssc SZiö-0S#n~^7ۯg==MNs6+D&+PDiI ~=wzS}$#w`0 &pNHaϿK[ɈRAz_| GENI.6+!SZ8feЗ+5¶=8/Aj$PЍ>C !t̡s]w՝2s\?[|mAJB.$ #o=#6sM~I4 N.KK).a˩=~S[]mjYbn29$6pC{z =o`2a%j/9- /< k c$سEKXq1;&ښj4MLE w=9שׁ/^ƻe-tu`}vq ]MN%Et¯uK,k C>sT4Ԓr+DE6φ{ZJj)XG[5эW#T͚6Pq?*F:NcS}4{.2ztB7-@ ҁKbQ\V!&֮bQKCkQZX@a~A\ [%CG[ۻIIQ]_O34ׄxP?!xfXB? XDU{*m{c=g(ضmzD#NIy]aC$K>}Gz6Hgp\4Rf.FS'|-B(qy4a"aKy'Ț605E!UKLs&Fq}OkF7veň5MDz.{k:T2~n6WC•ܻq%bS'b 52+J)pQI, RGUܳk|b G/4JqD[h4&*峒wuOY/%QX=+3||GTSu -Q{0Vl s)zF)߈+qn/ 0gYvWN;YU1u4X8L^O_NO_y @Z@*~)ãLIFMU|×{yU2-XӤҌ\8!ƙ3Gae9~-6oEj>O|ClX=n~ZyL =D>$%6gvoe{ BEYeAD 'LODEVȧw~?|5pبhY``z&m9.cYCk(rB2TJq;lǻ)+ޛ$sZu 0k%xvR`}lb^U: Ib|rX[cxpp2ndlq&C O$h,j{yXVcAUq=C _gppacz֗b<7w/H6:p11D L?x 3'h`00eKI8!$r/i(,0MSRHUЉf-_F}rH XBeЉ%% Yr>AW̼*V 2oR5RSAQa=5Nxn_B+?^ tb* Hl/`f|ɵBUԷ,ē0Ula#>piYEc).*ΏCvR \<D"hkLIR]루H3SZRBiIɴdY@f;DqI!U8 ( R\ZFe>bť!++) h^j07LdETP^':CP^TDYe%T0S65!+*( h v `(*.lj51JWmý} M$Y q tǠw9C`d zY\ix KcZv`ê&|UUXA"B@P2J|$ceTSY?kqKW0ld$.%%x]+Rf B*+iq"xBQ]ZLiu+5pGӢ,n,avK`b0e<~!^"*+K؃ePWGMKX~Bx Kh F(..q Q\]f6t*j( gL 1b)/QZ^I3K`%ETd0QQ^HqY%!-,k)#:<W̓yy.yW:1' RRKMMUI)ꦺ 4]W8?h(UfޫX 03dmS44]VJi!ɩrcϵʔJG!=S^}|2h/NM9娗`%%=475W65t,bhxNaa*Uc<4BsAlĴ+gZh&\Fx4eK|Ҧ@k4-0&߇0#dYM+`V9 =|׶c\#{ =g, )BL}|޽߾z%D4sT)_9:`C~0yg*;i{7'Uuɧ/m8{ 3||W~,߮P̑F.@OX²{ފ]]ݔpد:MiI vZ<*^u&{K,ĺ9ds_~0Rc 39`Fi]+_#g`Mޭ}-|4VCĸ\ٮҲWu{K#ׯfjXl quBPb%u\2v^&ifmsidzur߾\l~\hvy7ҟ,q2-yu+gCJ̫OPLM#y~=rG)y5kzK 筢Xs)x¢P(%o1AkmNW\/Ļnr'ns| KBP"- o~L/S(fB^ۍ}QqBP\O # nP(kGF8vq3DQCP(> JBP\\(cc87Aaa?+ Ň@ vʊ[]ZMP(%?٭BP( EP(  BP܁(]QQNkbY###ڌ]v/,f$N秸H$QTTH PbN b556S.A&ӁᅤEb))A<`ӉXXMq8Ԇ'ݝ070q}v 7ۍaXB[w" U"s{[ЗT 4V |6oiNZHre!@q{d!46*oXg!Є@Zuw㋯xw>^Mu=躆n{qޱHA9șG%ILsb>چp؉MFZ9㦼,75, s3 m'};2q.ñQܞda.:ā7>3iȮ#'?_{ xMMM]'3SNqYΝ?m1"+Q3?x]Hɬ`'7 py@lGFJ#߿$r>z?i9~ǿ<u-m 2#osddQ> wy,7H l#ae| vf6k:7gs~D-S kAkĠ3j2~L#Ioy6b8 هV+'- ˖/ıyg;xq{8ҼKnξ4:^Q#7s_Sqp0Þ$ܸH:m.Uʕ ;? 9̍LG"?+?rg.9Mg@Rs3g$'Jx'^F_dm Kf9+TD^;?z%<LW^7P)6oJ= p$GxiyI+sL)@kĵR2) BL+t, WgsI{{/}7/=˭6&M9Ldh;1rF*g{Am7;vcvtf#e>g;< xKŽ,u> 7g8=n6%E.6uFpU^eYn)F XT_@`7:zFI^EC!M&p~ Tp^.O8#iaN+GzYsd"'u2MAE,n! Ì9f9s]aһb 'fbm!},*)bӳ_d^EOE9O^"lGTVzF#D" UXFgoq%MŹX/]B0M+L vpd멚WMHA|G|g7'Z[)l',oOL r|(Ǧ6Pr6QؤX>ʐ p9iL+dd "̤8ρC'cA𛽭/XSOy+ح\l;zwyU̞ dr4O<}yy3 |摵n" ܙ3M3Tˊe):F8F&.Lk<:|iAb^zサ?} 95r>ȥN&1bMKR]>&G.PpܳPO=CDbQ g1+V.#m?Q*o;jk)Hf*¥3gaYzϷ5lSwòr ]g L"~ܹNvI2kP,LĔ0#˱Q%EvZcxzO2i˟y? mŗf8csl3& KyuI|+ȃ4y "—y bN?M ` M@lox~ibY@;TWyO XmJrӭ'Iۤh4ʮ{1eY8H{{{ID/? e9 [p,Y3a*3m}S:Wu5~)yd:ǎ[akgM,:Ou=qu D.]uF4I^,_7$K&s47l>dT;alX5ÿk?xc+āh.w]1LBU4 Ξ=K\xzTWxix ێpzy/sz O %H /IOm˿<}Qc4SD . (ktK]3O&e+?;?hLcNj?L/Ol]lXBI*;GFfbX,N ~T/mӈprDӂQ2I[c4#He^!Ȥj^*eՒzZ^EeE9u2B.{Xtc{~=*~.'6M ŕe\e})O/) b_мn_a k}kqJVOnhUNs vSY@C] ~ 94-[ͺذ YXBr71 '8|bl['?-ENwqb~NMPhǴ$% կ_c 4~d/&as qXSסcIb -aò"Z{H-S3t˅͛222aٳ9U^6Ҿ7d6{fVP%Xz-+K ql}D"A"`ַaY;禪9i EYK 06-G7phc%b6nh"CdFϴmLG;Sf+:M Buddv+ť 1Dx+ TL -oۋna >!3mBӰlp cXct|v: 4̼òw 4rQ@Xi.Gj-OGFB#T/ۿǹI!/DNu-]x|Xasj0q;`۹ ٳ^`0@4GxV?'FN9[@CO/#=ܵ~щq.0M rm$~[O_quETzm/0а9tl6{.`"V4$<ꥳKfƆ2'/5a'Xp|+__3!Tmǿ~S, M٦gv+)ÎFKZX{;$%1N,%5ֲg9?t?e}/ZJ6mϽ w5ܹABhNNChAut=(;;\Ys_G֔S辿-8 5<(8Eĵ5Meb;/#e1󥖘ȴDHC?7\R 2\gkah@tNw4@W;>em:{֦|^y!6oƫ1N'/?6zm֌N.f{jF/5l7>o1.[rl.^ACAs107^ ӊOҲ0#מbqOv$ez@qq5w<ÎCdXs,r`n.ۘXl6zϜk,iaH6=ù3ܹa,aj:T%O~ơ :Ff.0M"r>FS5~Z,Ûtt:yxӃx<9v xKBW$ISl&En]p_{tΌy,t`1$Xl6Mȭ7͊ 6J0 Gǣ 04kl;4@]s#.30/"6MOnsT]ǞiHKfdM+2??c&߶B7O?CQa{IcfCrɬIe?s{ o [pl"I2vqE  EA; &EXy;0R. xK=NR$h;Yس|u3 V^s_1090)Kt2\pzzsr 9Y&&^^-ۙp).p]1BHy* QLV4hjY &V'LLݳn!a8k(*dͺZNoDR)\4.\@(~~(Xޮ^&L -:_l9P$N<2Jw&gq3/Lo3}Qu/[`۱vs>bjA>sU4M.yIƓY,#C, 51 =J)z<W:.jv.tMi?wLO< B6F:ΰt,_1NQat,;G|WЙfV: J)/p3JRTθ|ҏ|\nj@ pHFlmg(.+.'cM|>VZJ*(w+$ϋ&Hyꇞ7k&MZq\G- 9!JX'7!0t04V':n#2 .ұ1::z%.>%85v:tCdd"1݆(hg!VtېB r'%p+c O ?ҢV!37ۗ[H,4X7ZIJ7uݓ3O ~6JhWx*v]pS^ZǞO7Stwv14ƟWLYq>3LK8Wt757AAU=eAґA:0RaGikj?j,4H|K-ݤ,.*jPp#}熱@7!CJRV=_NtIA~>Azx&x@J'iB4mʫv!ChbL]T#!hL%Ȍf'c],Df BJed&M=Mg!B miNQ M48Sy\Y4ffY2EiLkst\}6䚭4LCO'ХtrLiTiYL3KfV-\qe|ex= {e6ن-wbJ|z_r<12w;g=y0g7ydn&[y[ɌcF3KNF`r͓`y-ZSw.'˔dfivd朹ʍm49•_Ӳua95|yy-{͐S3+MՍrqgSݬt AImpwQՊzdIL`]Rb&1gZYDu-%%4ѯ觶`f~4fuoW~GO&7fzɾR4 d9s~xaN=+5/hsI9k{>ԶA<:#Tڔ@b< !:4b)121sQ Әle9c#^ur(+k [.8v[h;e>5;7?? iqLJR1}YXҒOIfT$Át^#+ >EA|oʁ ?U!1oH?C; sYX!.|Z+KkDSU׭Z7L'> yY`&yVa|7vM,},p*xzK6ay'x֛=&ԖMW~ҒM!WOnͼmCG0Mc^SM5#ny9Kx< Dz'?Dޕ[./2 B:&^s|e Jf{g,m})jp8KaD4jTM2/)%KWWW ~ 7I4M# \f)R"%y]w0sE92#=aTS^Yb:QojZ[tRYY/*!X6Nxԉ,"ݮ[j93kR'ʧ~T)EQEYTWEQUH+ R24x(s!:WԣlH7#|?|/?Q @IDATm֧fC_]>,x-%` ۘξBTKRD/ q1.]n"Jb#;~э wnqQu/g>&O??yy j6B` 9oۃjeӈ(o_S`LXitRX]%y#ǍYRh0xcMxKغע?gh+/SճjO#uӢ$OD;P(Ȯ;`4l\m[kםbq.5^D"6,n;Bױz ;1g=d4 M+Y٢ a~3Zw*fCܕ˹j#=sұZ9Ybu]o=$sS5`H(})rN&K?73YL:]i`-bjr|?,J:G x8,i^}'y0 &ۢͷO'g:kb_TWn KRDB#~uuS)3lz$i:NKc0eoοCX7c-Y{$_隣as2t-~DҠ=|#XD/ɯ9y!FbU!pعs1~ͯvt!j>?}׹47~ʅhA}\8=nݽﻋf7b#Ci^1{8q!2^pc7w~;P-єq 0h>?1F/ 'qzsm؊jٳ~R&VTpB0>>C s o`ݞVv0ZBg&|i@7LĨ۷PH+/{|G/qr?br~ś@h}sӰu;[7TB,24;p#MIYo=_9„pSZOߥj8p\[9vT_z3¡CWЁ(- 6Ϋ !$eb"J2oIit|4rٹ6N |n)$Vjvh!y5śT]BaI >%>͉k)_nˉUH)Ua}a.K|?wS#4d|y6ZRK(/ wa{aW~ǩBRt~:[wn8/@QY72Y"S1&\֭_˦p P'Glb *!6Q\;9w<0 FGGy7Ţ8YE*+[^DoeNQLRJ,+a|)^G5xi{z se>Ǿ3lb('ظˇ 9tzfpx푄7wqkdׅHH@R 6 ݆EhH >L"g욅aHc:4n3/024>B݂B9ӯuww~3®KX+)pٸ` Ôh0M,R+ ŵkqtC6 Î-;rul0yջ/t !L)f/lFh"aFJ~:\W!1?P8:4!0iHD%HinZH$B< ٷ}{g>MA~Ugo^#1 f{6qWk Pr#X,n6Mi{=Z#Ʀ¤ Ky kL7ErVK=Lc[/` ~\sNbqij '#[\T ,.JˊI 4r70bt\8M㘓G>1 t\^,f[C=Gy3ֱ"9uƮyy|kٺ={}3[6S]ZL_rwxe 'e! H'zHDh|G5^"h 3&ޝ8H9iR:a]#%giպJ#s|$B0cp:[[:njK{] .vǸGY0ơ9֚B $܋!$#ݗ8qam| |,EiٮLÜ.;'H0嬁hlT6=yG>{urj>t)M@Òd&̫>Lg52I/fm͒TG-w*mf&dmfFB6_yqՆ`BFG`:@&SW>=1{- QH)DyY)@`uMZq\%W~.1d1g]q| l䱒Y1u EH)в\y|2}i0tsCcV<@A8app5Wm(JGG'EEEsN v><ȝ;E/ //Dnt:aX,VO:)1 X/I X`Qـ8LYȴr.Rb.~Di ~ji3Y Mk|ﺒ?QW ÜwH:oZNfƜOܾ&c;lk_rbΌ)Iۏ<ie'ӽӨ(ݒ&gZZS)ˌjp{(: ]{wwWHpzFEYMjv#O~)6 1g^5k)-Jn?Tܾ݇k |wr]myeex4/r¾;|'i>8Vo<- %yYH32Adp EQI1^{fԱ'ρ!:x3$mG&ho`$f QbFai)n4i0>2ɟa!PPH~baG"$:6O‘N'= 682O@t[dnsk?3. ܠy|G3M۱7W Q<'\|i'_<˘o>}/Vbfy\4lf7E 4n;ǥ oi^`㺍x`?7qwԏecN?y;x]1\I%Z| 8ovG/yCO ^?ʚgp|i B3{=(sip3m{a$сiA:GxMO|}9FğKKr^Y3</(ٻ& fF~4u]O1Fh wmNv5+g7_پ?YD1Zt4=͍tɉvst;}|󍝔~G6pxH6GLx_E8F$D/¹w't?_:k UVhnF/܎[ݺjAųjpc{5 ?cc]i+( qxORIX{hw>%N< x-.jcF>EScOq}%ܵoޭU;x^)rlOq(^t,5pj$)ۛMnUedr_߿}^di;&V4yV\Np'o|{6!;1og4}";ye9wl'J!1GRXg8=q;38fҖ\rId;gq8}^Nw8W>hʁ-tJ{JB lyA*_k!ʷ=FL4w<9zm pqƁ.'X_&s3:>&8Kb}mv3I*>JS{6Թ>ʸs]l޴}㧿5LMz˂hO6Idto"ngyfnVOce/PIS]wn千wWj UBwls=7ً[Dn{0%>ă˜9=zncnz5;`ǏÒnwb(..ě3NIq75:R=I$#Lƥ%ŒFCg?fKZUD\%z/ŮRÓ.$сbR3'%0`H|4)s4 >]E™KMm.R RZf1l}oK~AWR]]Nynf?y^BZ>UM?GoC7$<8аm腅IAmE91&sOā4kǘ(Οl6wMRVLh?LC!t VRc1Jǟds qSk"gho5e6L3uIES7x򨭵 v~Y2cO"f_+|<]%Zns{t i'?SbT_㽷N t_\L0Njfة+ i'HI^71Oޭ5G7+63tzfɜv _c v~wچ1wRN734-L|ey5+]rʟuGSIs~9Y&1m'v/+G1F??}۩/6u)j6~ //Ѕi)ym޿84$i:[`J1-Drz]Ʀ~g~nib O_ !{i!<;i爙EljDev.t2čфt$JgjVrƶWYAJ c>ml{d" LPd8kH"<sL jTk;ȁ=<8d-=Du1 -re]v2O'$ h˧+7E^/1E& X3HH*["%F1]dbt{i1> uj/(5Bkz6pocSE@rbNƓJ :[:Y'Hg<'KX| ~'SNqNNzGinSI"e<'H!ɴEČ(ɴm?wVcu6;>C"Sݹw4W?_ᓄLp_W;* ј:7gw|Żb6 QYC%-Uxp/カIɱJN/E$dD,N"mcO7\}kB6N`V'،KDqxCFxD_nz|/3qy'#77q& $]8ttᴺ(*%e,"AoK3+ֳPo7gM1 g>p)F#n!5yw]^bJ*BΝ~śo*/55 몱io6BHa%k\W9Ǧm -H!f 42u[Li2<֙U(3p8:7k_T#ѱ0_3)%ݔYVj*X"̖XidвBH2u0UԐRdƩ\.d84~, <["_ލ˜O5j2,,y^[}e Kə5(HSS3@dzDg;g ”94dG3Sgیd2=%<\dM5c1 5=Βɤ7sOìqa9%BdFNЄ>tvL-4 dDJf|fxr9e/h~2rzleJO63ҍCGss3};v _0ʪ*C9Xny#t4Rt{J(,K߯JNf;iJ$J:m+<n˼QF䕯cϞX>rv{5y>Z!~m^QeG^h: -%q<&nyX\A6#fE,i77 N?~]llĖzl׿o'fd>1ȯψ=HmGc]9>NIM>5T ^Qe[_ ?+ڣuZTWEY2s1t_r?cHuܚ3;a $&r{SF:A° 'HI >.[6< 0uD)8}8BTh4A4dڳ7ZD@o4-WHT=4L=̎?^fR7hB2vnR4۽>AxEQondgi4Z\'jpe~דtʉѡ{% ]{yWhU˥'/t_}zq.?Kphx~{֢racHg?>ړ`"gXw_>`8sMuSm?ɋ=m;˨WEY2 > 1ƥÆOR"筷O⯿O=q/8)B)Z.t(9ky{i|ES8'4->ΑWÍ 4}-8p]fPe}M}~c?&c ^=+?FM342FQr)iѼ_zWEY Rq)z#@*_r+ KHm'L#*i͂2;0R?g0%5(d1;/~vL`מh'}gf)/qL* 5'.#{o },ZG]zWEYM?j i.:HJN5Yg-0$O.>GsG6 #ϛL?liDCX91Bs8d:SnJH?1@ 7`@n.~YM&yzF'7,N %+R tb SU^3rax.&_ (+Z&Hnd&1MAIn{G^͓ZfIi/B(ߒG}M9 mrz2:NKHĹa:":EC'X|0 hB 0Hv&U1MINZ~x7Fӻs)ƅBF9xd-wekuiSi7]O#r7|_^{\9TWEYi$i)x*xgmeO^'\##cWW?(2'`|b!kΓ;M Twp.6FPlYSm'DS__q5UȡF;rHJeM >x)w>k[>t XΤvι]n_EQV()%nbb8ř9#y^*+`B^/^w̨:xEQEYTWEQUHxEQEYTWEQUh*l61?((˞51K/ORJܥN(((((((((,?(V%tEXtdate:create2017-10-09T15:01:22+02:00%tEXtdate:modify2017-10-09T13:54:31+02:00 itEXtSoftwaregnome-screenshot>IENDB`Eqonomize-1.5.3/doc/html/C/figures/refund.png000066400000000000000000000601071416454732000210300ustar00rootroot00000000000000PNG  IHDRgAMA a cHRMz&u0`:pQ<bKGD_9IDATxgǕכW U(xO(DVKڞ6U3NnK3%Eʑ2m_3c?[(0E""#NF8?011111112:vcbb)0_w ~kbbT=?@8OvSkbbjZt9PR'o\LLLn#L`brc;h E ov"Ln k47C±!ô& tʄkA(:} *\8-i@O7 UUt)N˭\747oI!ҸpR\oո* fȩ#avi(\wȹ 1u weXؔiBAz%7=LCJ "2\op!1 i%%9Âa}+F"C>rwWlDiAԐxY֋M# >DHKO#i] PT%qDbN CN{IIt"/H@QJDK0 * xw#/_a͔d$%01p@amܵze]!NB*6 JTrtIAkP;# 4qZ0# NJ*7yXez =8Jmη \ĺKHqH@>Hk.2Vk O8M8R I!D|ڳv xXqeY^ĝ^?>eyRV!O}+T$0Ƈ9ޫ?s_k©~B:`@×#*d&)|;C ыD~FڽfxPx/ ŭX{ QNbQ >CU}{;I*:N+Xr7_K}NhV{^?lǐɞYW=hЇH_݈߭rYd\E n ch4wJ~L# rx2=U*쯝dGȶrk1=)8Yeq{U:' Od )b8%^>1wYFut`Dәg(?$!Eni8>{ 9 $I%}ia}lRՇӪg$֒S,h10]~0c(Wli<+)X5EF RzN~\,5I#7΁gól hr=,M`4yWRXOAI%;wGޡq&|!+XUU1HՂ͢2[P ))pG`7HlHTP]!<ƇNBҽ,/J5(Hg[xxױh#Vbf:;82k&Cy_y=d.?t$d3š5h5Mu"ԷtO.%ARLL'=Mumcfzcu#$T)/ sD9aѳRJ @U+ZYη!xhj`os]gQig^7e2"p$搝(I[>Ǝ6jtc t_?ϑI&?ܛ ױ3E% d8Tl2+꡻Kv:<E%-o;Ftd=ܿp?=$fdJ l=O}s<녅+^XqJ PE vxMXD{IT/.>ks |O|p`6T6;$4/K źG7sW98"$C-'}-O?͖TJJ×~Lw>@ $Hp8rQ]`s~?LPV[x~ j,]D9U?{X]CFV|=46QS}#'I_> Q'OQև)hk"134V14B*iy)L s~m``x )6̯{e[!IWP.+ 6ֵӖMYFpL5iVY4 ͑̒Kpp| ###$|/==,]CԷ7NBV9^=M;zDH+XzBUs'[oa'lYlܑ~N|3Iٱ"zZ}5äe呗nA!ޠ"۶r"v0K풟ja G6ڻG%BѰZ5!%+;k HW3]x2 K`O'?3470.("'-U1N{'‚\dGGczB6(@0npdDo*]2qc}%sl/VS΋wƖ1IGT,ViٹdyNZ4l,"7Ջ$q0/\0EUT-7A q?@얱L]{ r)0zro0K0B&~XC/e9UV(%f$tfScs>Ihr9\,4 WᡕNt>kzGC=% 4M#ո "1i' .WЯ?o.fn0D2⣭ fd➉m8 y}S\7# 4@/Wg]|9啩7O]i ~+ެM_ş51"@9g/=Cn=Oc?Mg{ ,<#,Hcz]U" p# ~G֗q;z; eTd`Qbωio{paqQT !atlX,+2&Q\nJ*WP^;abjv6:R_{<.zC"Tg?3\SC`D9>>Ӎ|=a9Ka+Ȇb( N^{yv,]Tg~Kǂ΃ksQ  &SWHHDdD"a"Q}&DFLfV!LuO3EQsE#X`׊`v^n}:}ĄG,$W,!AH )qgl1 H ͢GtF)FLR- R*SBޒ o3:!Xj9Yi,ٰ)xm ꗞ {\:d Gc"BOghYa\[C) v6SNOo/#alu%0էO@(:Jᒕ,/&tk9r!̩slr jp| 9U4m Fa}ej$$kovlel߱ {~?R3hPz3&s߰)T|ߤa( _˫EpG_yp 0gAoe RKկ>]=HИaɡa/JČݗR#w)ws\%+Ȝḅ(q$eѓNM8a`HARZ7pںzǟ}UQ6g[X,AnnO<(iii VP*\BI V--"mdRq콏񥖳$;5J*:x)IujNog@Nf+[XU(!e+YTuw!:0d.fui.陬$N2 6O21ou |ݧjzq=&*#~F&peC!=іKc(Gz졦щt =( \yk֓[8 Ͽ@m3m>|ғ7寧Ͽx,dg+s ДLpr]`|{ǐv77Q n(@4p3^FMvY^4ReQBAp9<8*`> nAoq6Pbu WYNDa8o&~#ZԸ$zBv!%YTUPt9ƎW$)>BA5){o>~7^[LEjZBRZ)2m+-IV'v~12` !wvDJ.@ exӀ(ӚҘx? lTBߩ{isKٲÇhi*z<ٰ,R4g)zSisr:;ů_z>z;kf,,h?KV`(V>>uCF=(pꌈ9H>O1˗a%^gEL5bQ)C$1)$HNLfհ:=$.:'m[}_*˳fm#0o:/?DDΜ={|D0Dfv6 VW:Q2pt-0\C{aGmK)I Q_Hp:6&{^U/.|ܞlWQ?ݻiIs'w[9zWebtQ0Tw":Cji*|1E.'OSw6sbs`7(]׾Nө}붱u G Z$aUcÄ>`󐕑]4RFİHk 0cCI%{'p$$qܸin磸@Ãԝ_tR3| )-ʎMMǯ!+2ӊaؓJt"dž &tXҜd^gçu+Z?!]oCU+.ol$5%r[-<񐈩qPS]--fXK9wA5BLɅ$%ENsbYYyć-7 SB&z/@SFe3 f_LսKi6(2.uRFlog\񐓙MS_il@K&#ٍ*/`bbI222t=D^a'D^2i^)Ii0rƨ\yҘoכH3)ҤGaYPg+ qWI/&uoR/)In7o21r;>:~VL7iLL`L`brcn0Sc)5#Dlkp|`rzUFAw)D:5V@4M#11@ xSO&&D(`, Vf'6zMp0W|V0gLL`M@IMsp F ɂ ji֔MpFuu Hj膎ұlW}inBѨNQa9 0Yt] g:R2ܜ 0Y%&*b\c[`k0B AD7PuAՍzC*P0 gy' bJl-8BQPUulocO_•8{wwoި3RFߨ`-gr9n,@L |d6WD,=0-vBjpx''3cW!7M!u[_-&m5B(D&{x? [|UXXX 144w,!'Ɋ\OtWyp -rnbYiah9!? j'=ť,*Ei;sYQYm*GN*+Hp1L͑և̎y|*BH[ݍ~˅oμɸ AaWPY* V3jj|~ļr!CtvMMT B/?oԶ V-.,)*#@ !qYNdL=I%<\k%f[̸'=L}'xpm!7mT\EqF&•^׺_.9\8V!P$a ˅͢ƞF߄!s4 "ሎfu`"A?Bs:I$ @aqq9bFxч)H nPqgP 6˯0m cVZS>rV #LMn })|~ºˁ*>0Rt9Yie)ce`F9pXUA8D*V30a4>a]t[FvPqy8,|_wU|goo;w/2z$'Kv'.->" ! T.W|##˅G4"ٝ4HϤ/8ItH( %^ˁSoo' '!5tb-8:*!h$WbV1eTP`;Uu-˰gY::k*>V<:JפiS Cbݵtc^zK]H9~?_ Ui9wSleꪳ4 +lyK<&{λ>5I8ؽtP?Jl0Z͙aJSN]EӽV-.V@>9L:k9YՄx3_}> mH=HGC=]#v *ZýqQ&i$nؾԻ#y~vl\>[o#uNP>žߢ1Ņ lu3|Rwb';dxuT6m\;2y^ -m~*(_Pѿpkrg(;oaxl.BNܟ,C~GFf'7 r:$.oxZMkHwBw^0LeENyɶ(mgs$-[N6N*%";חhb;pDh<丸*?F$x !躎^xvI qꛃ$kE"t$ =B{{ꗞd۪6Ӽ,ey?KO>De~ {/],|??{חPs3d'wtHP,[ʲDP(F:9zc:K7d͛Ɋee$d/+ثsp/~ЧHg hLQ:sc̑Lg4սHU0T^{qBh;?B/Do~vp&{ |mdxfuc~H?j.O_=kIwi|C=zpLA^{#o.[|_B{_Ճ{oO[}dJ6{K2|D O Sh>ֱte=,=(O?gl_U*b.Z#O|/= KSPe3WvP^~ATLݛ/;'I+nJ_G3aP( @ 6 Wk֥#GD%!{1r! Xm"J!jXOJl)hl e `=pkVvU"%+Vfb#Q $R/ZNF\a9 1f EJH+&'Yxԑˢ4fQ w:JmGDHV$xFJzӌCHT0l]6U29eU,RCM'8T7`#d鴭 y `x2ؒ<[Ptn-+^Gcj ,񾺌:Pfމb#x.r(DɬYQo3x,X5EհZmX,U`H)q:,]{!b(..  L[7f߁}8C7dP #$vt:qfe%j!  -UBWYNx,TWwUSQG$r]:C>"'d52 jHi+L3( ] ӕJb蒄%F}q⢅8ý ꙹ *LπRiT9NdE}٢tP,[`ׯsNSϞx1sR@ue xFػo$۩ͻ0맵Y8 Á$1%y]HIɚ"BEU:7QGUbeHB1U$'xIvۧ飆KIf9/pMɜ!gM| (Gqq!޳U+W+6`yFINv=]jWbtrW_=ϫG<eH;/~"NP_SWs L olB^'$#L4uR_GS0P0G)gDq8@(N#}w380}y,tW7J˦Ǿ7vVR{'+dr|@Aգtэ(au$NFslTn\>?kjim5@F |/'{{u}%?@ףk%=!zzш+{0z]ϳزm[,;aaG9ulWcXJjprCٽ(cG~w^|W?jP\QIq6jϟ|}3-t$~yh3{>>@[b3m>lKJ'?Io9uV2 JN 5'D9UFH8)(-%eP}ckK˖|q]r wz>وߞĢB`={?>BۘBfA  gd2ܡN;˩Gػw/f(b';;  dxAS9IOJb%%!G;9q >,*#-# '9qѰFvQ)d@kgxo-Z@qk'irc@S]dgg6=rUDibuo;H.(/ JW] m}($2SiU#8NNN˩|:UިXl\.9HA?P)%fr)h8H w:Ǎ``(jtΦزԀ?@D7 ÈJÁjDUTA('Ӂ*bu[QTu,6#" lv'M$}}_B@  B2FQ5{L<߁î L2]+_+!ufs[ ":Bp9*8\NT#B05ѥiU OEt{uuI1"z\sR*XN6->3&D:p9l |+ GQ-% PԋF%DU2NViaTb;YOuU`Cci)^WV4+~ 7V cwbc bG/tʐ#D5ueetpYbޘp*SK+/ sƒ[Zl-떆DѬ3y_cu9K 1SS)z)B/_ ڝnIH)ppNۊ1sՆbdZj~H3_m­΋5>?fC )YjNڦaHT͆3f~YNy6RgK+TӍ92@wQ^>u\<k !Ͳq+9 gTc@{{!?>2H{}-gCܷc5$DÌQRgV6^2pRy_U_e9]1x7[Z\ ɲMۨc~RTCfJ"VEe)Lqw;퇔_?LXh\^RRqZᆭ4~nfa^tJ3Sdx̰rp7Q~k]i8inRbhHi׏716hUQL]:Z284\"HNNr^!HLL$!!,BSVA7|բ-, 0117)%h,4횇Ph"z^0 Bph4BIq5{mMLfFini7f-Qăi \?bD^㴲iLL`nK xHrm"qk~7Uqd3L;.k7Uz BG{ikw@(8_DeE1NM\*9 MIҵSN1( `єK>Be,)LGc4#WW;'dJSW2l>z(x/R7fͦ{ٴ4/?Gm%H\}K|Kwhb.5i-_Ⱦ>PK|m^|jjZ܃G3/0ռn_.Lv?#kyxjӒIJJ!t5O}Ig^i$((@(1Sf;EQPUeεBkAQ]Hq^ VR*t:TU6"~N 'rwŮtK4w"/E7Q]0vSb%9ݶka?DD\VUg;_`#p=#ݯrfxBRwwyeo=h^:{D%a[{ȇ tZ OG LLm]Xp$c]ygy%8Ijf6a=# cY[~j'5+Ρ!&ыijieǶ)_\dvhik[<^@``EE5)I# =$أEKQN{HC|o>䏷sL!`s#tH/\ƽ~o=Ѧ|T EKKbcwUE;$d ş?|7`r0bSPʎ`qBÁ 4w2r> yƐzd&1E3B(n&#QfRp:x{(_\6v:DŽ/@r.bfR`*&d q~kb,<%;>#B^pY'MҜ‘SD5΀s'ESJGA7IؾLfN!\)'7RIc c!!%q?p|A0#+ɋf"i 1 c߯+w*.<;rݳ }.Bkx% Gc:BC'jĽXq~rYi. riՖZaCKGhՑ][]}ST%~ m#f7;ں JVmP"JoW/+(r[{G0@LbYRb`c}tL먮|] +61Oo͢`-/B1vΗYB"HĉsGtZkiopގ>#G„B#&GB1APF{m5t ÄA"ˉQOUS;:RhWnHo)J~#!j>xg8:j`b~$@OX7b]4x xJzk @#'U6ݻ4 xtp@L,J;*..VRbBۻ0 <̹j,W$>eeԜ:(;1T$-vr rI,$fFzj"2Fk0E,)Ifl,@j^.GO42&)'Yi>ə>E^qɉ^*}utddg`3Gk[+*Ed&' 0J} r3Med8BuT&ĆBg `rr2h DHJZh! (UAv ƕt֭)ktmFڻZ{Vaꦨc`=2?1\|N99s˃_f˃ϹHz4Lw1~iSOuY>NM~zj2GWBF\Y2x7ݘZOwb;O7bʺ Ҙ֜!i(S>3.LAʌOm}~|>EfT[i_󜡰4PU eրU4t1r3 B({G~쬬N}c#)X,~y9"% P4y[+8~ w[-DUޛI%fM .4h2(:3 󞥨,oAfF PK,bZƤgw TEUUٶu3ڀպl{Ϭ^W~a f8Kqѯ!1N{I)-ĆazM>(fT !h6<FVMvs9wYPf7eM>|Zmic͊f9?JW6OŎ]|FibrKVܹܹqobbQjũfXp uLYbٰX465بI&5n447! x=sar^΄in0BS39511 9 !MYtgL0dbbt,"zX-k47H$8ބ#4&C,()פinE(~vJRH)u*\zinCbQO%$Ô6 |Qx/52qsá_}y t9u!a͔e`D79bB-5Xخ|(jV< x]vL1AwԈ9HIK%mrht:N؀Faf2v'-bQfYEH? _gBlY Ȉ3G8Zۇ@h +եXqU S)WH}| GXWb[+c󗽑Bt]W/4%kh.dUPt؈˴[0"zwzj?e$$$5^Pg;eXKC:6u{7R*$畳vy??f2:/? , ](0H^,x$9 ՎnG3)\'WORv#<躁0&,w8qqE+L]EkL CO廷f?|xL몑Eaž26ʥg̓ Cc VMf_̮Lg/1 {Ȼ{MeͲs4 0PG: :pPx eihHBaN1f#:IՙE\۲DsjƑ{"ͥaDt6U<&';Κw.6Vf1\:FE*wl< Ra&''ђXD@gud2\CUC7%{ZVFO͉q/'(_綯&Q&:74ՈDQ-V*DcFdJŎA'rYv)I sY:ZyG? %GV2x>"vnZ5Á=\$k14?I{Ea3'i PvW!olU=##4DUzinuP\ '_;0:ϼFf975̋?Wv@0x}q<,j@I$7Y]**Ny췯qaReُ)O.{"u#;[/ F9o/~3-lS,/#*.O:VyKرz1#$Wl%q"( xL/W=VBt4ra^K[$ AڞD5G}>ð:HINĚRkKpm:HX<)d:is`L5NN^PBrg@ ė6mdeI rH CQĥlP0&[ <%y8AY~0ZMA2stWp׺ո,QN%YSL,hjm'ēZ̊ Y%9 <]\{=I4Zd (Rǰ%I`qSg\sksL:j8IX.N$9ɅKOl1I6C4m$m K&CBgLb:]u#LSw,/(w?(EH!sࣣЌ(5-$1 ťHCpӎDEML*FB%8^Ħq{ccCI}_[V[UHs-2/[+3R"<),pm1ӯ v4Hi ɔ$zh͢N7n[Ģ6\^v 4͂UT%6vvHZ,(*. (4꤭ lwǥǤa D44͆Ţ"XxN.#?nHa@jj.;?GOGQ%;7buyW8gKl 45aMy.%#`obkc`N"cW7;;SiVQhv7u|S+Տ`WD\] 6hrB'DXx]7F.PTAXJ#jfQ/<\^8{ ;+QjAPCHuݸ4FbjKbM㩿.t=Ͼq(ĤDk AFP c~:-cs΢狀(1X~.?>3ļ z CP]Mna\u'sh~|E@HO֑3\V/)'¨}d.4k[JLKmʓ.O;H(B ύczawHoz!%w_y#J+f=xDB2qS_T@ɞ^{uN]]PR`L 2ß.s`,RE8TC `tg0b_u!Ef3p0Q=D8Ix!&3+:GH0d(D4zyCj}R:REZ=^j0+ˁYYq%dpfnjeof0/=tVVz豵3WvhifeP_;]cN18N}>4w PJ0 -- 𠟆N*VSOŏ~dQr!Z|.Z 7Ne ,]^/.1~g{Xcg̱{ct>fw }! :9_Fdd6'o.`']?=?rE%٩ɔLH9UUK R\.D]<ʆe8= c}=2F;hn/AK(ivzZf>_ygk Mlh 2Ӓky.&#$+/pW5 lT, %Tfh桴t:*9%g{h|sO:K =)I/(eIaV`^ª"R\D#4{,DjA兙DG:8Wۂ_wP\ M EbCHxr(Iæ 4_B6I\J\njxRXRNSE&–dXNAN[*.KMq| I,^TD˂TGkScII#3=}zFEK)Ͱ\GUc .$m!0M]}+\'geqn"#~Mhf2Ki YE%(C1d(nĤթs b!y Piv.fcLwQ"c~#6_(b\1L9OX:lsiO9@Ucȋk>;6Ks>ó&x av 5LEQ-aHEOeva .x&71׼PJu˟2 sƏ]2ti}2ȋΙzEU期.~ys:~Kdpˤa̟O=.~s8uq.J5䳇s311 iLL`L`brcHs+ɂ!z`!D4 C?KiMոׂin 31Px47ݎ1o1̕s&Y;C;]oۡǥ#ykZ6 ?`ddf'SCFRREa@қO!Rt8HMMA,W}iFGFH^:-@ illnv{f  ^/ɷ]/@A$FRbU4w!Zb ~G07) ̊O˻bmW_NУ׶=4w [ze%/(ɷ[JrI@4[ 0CQV묨Gr'67 )Hˏ._w󾜂DvŞG)L#Ib>3Sz v89x9]7J@ g!0"~ۚihjg؏fi6R2r(YTBV F|Կ!7?K:/DCwD.xq)y Bh?Ge$B^jݱ ~[m(~t=2 |-Xߤv"%^lV>|CW"npCM&/oC`p+فpz?=;7WRU2HNL͏ⴀdޠW +z s~Lp'0 U 2~i*ҝ33Yd$WM4A GŌrFqZ=i,Hf=SX9'#~ؽcwWfjriׂI/~4ÿeMAt9efa gKHMu褦&cWuZNj4|!3\ 蘼{KFD5^??QBP߆ nM,dӺu8 txpR&NJ[GI1}=3D bą$Qz{ed2Ssvɹ$u1!k?ˮw^UX8Yup ko<͏RDGXs,Nwö/P\1) 'Ԡے(-D!81#0L]} }]ػ@ͷH۠Gײ1Ku}l3x5Ah3gj L OٽO,:mU2AӐƽ?ʲtmV.%^'BZ:lJ '"[~<5탔 M=}s,,CrvA^}@GCqcT.]JJJ:pG~<os=8(X6Rb֯!?ᅷvmZ$8=Js-^%LGS.nvt؋)IDttpyY?i` guF6nchyD&x׫L(9mCx-œ0ʳ;);~}L%%I6DdPHJjf.ɉ9d Bo_<[sV,l/z0}w İ%bY7s.hƳ!gSccPb'<6@Ӏ(F7bR~z|׃vaseՀW pDYa{vEI3SB%nci^xpܮ3]b'DJ<ƃ]x{Ǜ2I :vqj_<'l, dsr3&4O 8@0NHI#U E(H#J(#dNJV8_%+عc-p)^P:c=;(f?Xz ,,(>n7ݓspG gGٞZ_cy >(kKqZU|=uE4TQa7F]m xpE"p8&@* pp8=g<EH0ex|廼_2FPodTfZ BV"QKxy_YWWWJ3(lჷ^/\GF` L0! a4>63oO5=dz7u};nbzL>x=X4m39e+X3onk(MPocrR|e2PB\p|a{Xr(-ʧl1IKM#3YZQLK~"uuNPZAd20!%3. -dpp˅>Nvz}n)Q,ZRAnBWs-gHǀ5ܿm. !cZFCna">[Go@!'7Dv]itt:/uJ55˃:=q\Hl$  /@4,X\G#RY,#JMU1Q=&iT!Dq9seu(bASD\~HpEjզޯ&RSHMM) /nr 1gSNۘKM.@cc\ݎ^A޶X,,90roFpYm4wB6f'S! _>mF8z=s{6)%rQcHLLᛝO'Hv;vw$$$ p+B+.`08B`p:]tiEM݂!xMLq(+^u4h8;OtRp5_+IS_jrzDQ@_sGLa} o?m!9 o:E#=LNŒy-^<5<4ׇbP_'z>CS_8Fz<{5 !Mz-\HE]$tDyͻ`N6oMKȡ ˉ'#QNpml?؄;qQ}X(oO_|ϴ.F"o5N|x lbv~t}ʂlL3 +vBP$TߏJ49K:ylܼ'QT,2v6# |YJ5 IX9 1֔WodyYv&f%0E%71Tʗ=Ī= v $& ]GOn 2Po:dfq9*+tHNPRQEeF;5b%'}|6oNkWbycn.͇.pS <2%W@U.UsErc'$6̧̹Qիᐒx3:b+61 |SJ΀)%6wb㏒őǨ9ϣlܔDvRuQ!|6]lZLF Q=u 1 3%Lzl#!ǻQxk;@Q=>l@1 1ed.cҹXHpb"*|isẃ^0U!5ll&YHafMR(H]<脩tElFC]t<>86PU6UES15'~a@V\vWl[mfVMjEæj`~s{  $쥶^E" ^9C4Mc͚x=rssMSTTxr(!z!L)1M3|9nCŽ6΅ºii$ IÝ]4&U1äLG  ]SVO4aBfxSAOf7ƨ0Mdy G M&1]OcODJ02`%G{PTxS=$=5 7J&S4|.ZNOE@_~9Ed$i"짳>JrN=}E|ՋSKsT3i mӽhǙvG"ߣDxLu+*FP8axGP%dNhjd[XY%4=wOV)s Łwq'AՂ{/4 9Ǐ+J{h:u}O觷/DzA!>eϾ ZLu`ODKłųe߱"AzdnqƤ78g:(3"Fo)w' +qb6rJ2"5|g?GP!Kl?fٺd:>!Tp\x"ڹ,E_Ke;L_;}f@-?O|n d򎫱M|RY-)nuW`b:n^;V]bF\#s ;UUcD;f 'RK͌h )%~`0HCc# b&!Hq\״%ncl6;Ed-Ō4 qm[\͆~/m%,mfsW;8YXX\p#-&1`1$387h?Z *x0W+ٱm*IGLj5賸Jɇm\8X6EKr\*i@GAZX[~vnzex|ŧlr1 X6נ12!(D&C-=s{僬Hr㕄m:zd.^CQ:.pY,M\}hi0-._)Y-nz#k_Tm)˽">-i.R_`X"u˕+96r/ܒ<3 =m ͓FII >5o?Yͪ;kE Nɿb  &B!>y]Y%S6!N|W,7Ӥ4Or *<=~ݤ".%$M!Iܪ ^ C(x$%=y.{\ yPENiHG$]R=f[)Lf !~53L '|˼KԸ-B8\*6!38R82+Xfθ=+Qho5BQ|\c[P4VzA2"_l`cƷr5POiexbLT&&$Iz5GըdX]דctiӞgrݓAauݸB' ֍фG,7N*=~ʐ8eTtlIFLCL { 2$g"6i2k3vL5SR;`w .U~AˈI@B"frfXR2 9~6ِI\HVd*di @!?/˜9Ͼ. |}\A"Qm5V!íM .d#{qm<,-@HI,4@Ky>LK8}iaDp|?5CNfeؿ#+֕\Ks #Ãd*mמ6)@ܱo3 BH$9x˘_2yoqW?66w*J⊂Cs` L$3K|u7q.AP1~ $p9q<ձP/aVo*g<;'%c_m |_e8&Q)d jIfEbu^*T.@-i"Fg}!#cg#) W%c,|%ggg@¤P aH1E*pXP5{65GaijCf#x咺妄@\r3On ɐA]cK ؀$ܩLk/4(HBl,r(!AI4Q~\?F")'x^Tb#έo6ו:Kbs㊵sl#xa` ;|2_vZbm 7ߣu)tm6z:J6JP;T- ə1uÍ3sMDh-@ T"sh:M5J C{j;-fRO$44 mAt RQvAۈd0"iHLڄOxTh J! .q$}!B]Ph($;dC&+0F'P]1D9CNrIBx @"%Sdzi&ߎcLj;/OĝGq3'42H$)9 1ĕVJ95݁-4uM!ʖ<ȗz"`8 vfG_)k98ѻk%g( mT,[Omw=%!$%pgty 'O{S=xK泼t]kD"`#xCB4PǯGHX1sn BPLrϤ0SRJSh3iӥY6]&yȠVWX`N2UqI0!901 +ɡEW` JQ42{\󼂖A NE3vYv805iko_B,ai,RTz{zhejlFyJU 7s燜m S6.NΞ iOVq>OvDc\rq; 4o!zCvA)^ݻI{o9KW:M+^=K_("C_Cլj*f$O\H:Ăt/"1N9>IF~I%%GHW)( 7NG@SiӀިdȀjOLîN45222BQQ!9Swb/@nLk&CXi. 7e}5MiO:39t7}9E@IYzo'峲RB&2.]J,-uʤ5Vh.RucOCQyؾ>/rxכ4THa'T{%KctJꗬ/3VK>m\t!.Ǿ $tߺÒ/qW6LÎL=W?" D&rOv; . SlUJ\4'(SWfbtۉL8rcUYN S-/0SΥuRǖҜ2:6X|&\)t^ OyBL-`}6qV{i%SʱeڷK0X[h6=u[ZRQxk\wXB(]3-0o SlaSm)/Un) ) }:FP-i%5x5J8s7aJ(#i -GGsYR,p#R{Z-n_ +w݋)d[t%}Sm'#L[GF&86w%nc$5_iqHSbHOO`MB q:XaA]C_ LK0H)Q-V9[ܑ(µewMgq2:Rm&iE!ELLuoۄzF`v,GO_`0&Q5n jßKiy9%yhz AJER:t@'kKx =gd8V7RG(s&ˢ=62dVS]=)xөQ4ie ogo3 ^#[vOĬo|>W|y`#Ӎۡ 4˯.y/$K_[s`> ot }Ϭf߁Z\א퐘xXd.vq6@dYT9LQ1r;!xgA*֭ī% 1u8znI#˗Sc?5Fa5FoiI mgx f20Fe<цm%MW#Vi@I˧0ۇg d> 2DJl ]uDܩŒ Fm={![гy[~7^OmϬ.H42sriv?y٤wyT.F)c'ݟ[OiiX/'6˸&"L@85GXȜb߭vuP(EQ p$r6])Mgy 1m"۲ONCZ|W(_?o< H[_~# }t ϡt{X9?~QBr$s8Cl^D&D476 /hw[+<3|ϱ~Q)NKS[eSl6Dذf9XhǮi#\n2&@84Z?_(:k8hb,īBA,vqi 02rb ;׍sp`:ii.l6;+&L1DA~"Q Shv6հrp 6^76X7݅(`݆ثKqvx),k|aevZa]i>%}qɉپv0  P5UOu_ƥg !cSUl'n Пi p<1^i*Mʷ@{Ȱ3K)%nE Bwvٳoعn`P  "䯚CǃL|AT 1j!.]@]b RHG[x%\9g#q8?bYpҴ4(MsTCz|ɴI1=Zߧ?Ϲ0''9re(p.#O?EOÔ͓FЈ&M7._sM=qG5T4z:pBJ,Mݐ MфHt?ᶓ<'e^ct4p,-Kx}[0u`&~$پ 32bdp r僚7@ s׳=k"; ?#|xy/gy]9IǠ$-ONn>>1b,)bn9nT1CkWG?R0s/?I,"'x\v 914C8ܸ4xqm(B co*ͼ4 (e7 !n(O921B})?oKgTZAxdp4UzqhbRr]!  3`*v|~v5i0a`^ Ƴ%n$GХu3 Á*D ylO+-~bFzڔRsMZSbR6i2ĸRNR#'{sY7DzN~:sRL6_v܇t? ?4q:0Y 9R.}]e-$‘FYiZW^pvW~Nl`j-YXXL S;uL^[%nc;P޾԰UH$PelLmˍ4a(ձP ##JMW 9^saqr= K0XkVb `5I{+^vawm?!iX&1׆FRbD&?Xޞ^t]ntRr:ζZ\=BHOK#;;VW3!HPWWG("-m|!n999 ؈sdo {Ӕ춻6#ݖ| cjH@4lλvwRCCýΝ'&&ƜQX8Q0\`t&"!uݎMn sýU[5!-y3aG~EEIm|5d`(Wm\԰Fi0sK0Ìh B ؝4E_GNjc_o)c9ȶWi "Y|d޼j|ezgɶChsYn=x3/OL(J2[ dN ^;H&cXNq= Xýh?.$ ˻?w޸"}tY~y^xo |[GgRf1I] g.Osb*8a@R 0 GqeN I,4LD:p+1AbNvn6^6FIgPa󐝝ۮ"BC u˗A9Η W%!l{aey@b჏u旱ȅPa}0{NGa:#[^%P 玟%q0wV f>'0;[M7 ']@s<=[EU֋+oqltrvN  )jH W8/`AE6"](MlFh o*8mڴ Ez  S @ط}+A#$NF k(aqK%t A4M< y Yn"ih6x)id2_LYA2{,rCm}?DSS6\!Ff(- fG-5 %niR(>|B{p"4ۙ4Jb4*?/ﱪ,j s$kVf_Mgb^̯&] qYuJ0 ED9^_h%U9LLP7F GSÕqM)&x=Ϭ-ܻ_oȩ3 ;AcQ8>\뼀RqW7[zFb t=PWᄈےGSkIIL3A4' GceJZƿr-[= !B q98)l-YBe:N70^4Lf?҈Bs6Žu$pG6q$<7Uu\(*64$( :hK`בW w8WXX5x`&ai-^|]E5-X.¥>w-Oݬŵ{߽}^nZ]iqM!wm^D"L-HrS$Ҷ뺎J8c1s|~/==nuU>8v4JAJἶhP`GRxh4z prPTTH4+!NsM[Fܚ{x=^ۯk,`aa1K0XXXL S.[]1  8pI??sgf_[歮Ž`dk %tEXtdate:create2017-10-09T15:01:22+02:00%tEXtdate:modify2017-10-09T13:56:19+02:00yV0tEXtSoftwaregnome-screenshot>IENDB`Eqonomize-1.5.3/doc/html/C/figures/schedule.png000066400000000000000000004517751416454732000213600ustar00rootroot00000000000000PNG  IHDR]QݐgAMA a cHRMz&u0`:pQ<bKGDIDATxwt]u~uι9ދ$sKԲd9{eg<&3ϲ%˖cԹ[d79g qs  ;|ZPvS]`bbbbbbbbbbbbbbbbbbbbbbbbbAD?P(211111111111@`Xx_>gtEcqG8-^ŋe?&&&&&&&&&&&&0B|j/(uLLLLLLLLLLLL>vK( Ff}2]WNtq|j!EE1W?,rG( ʇv%z+ "lPN>}jbbb&.I1#ɒrdYҩt#3ۯBd&{%_y 00Mː|L6K6#S(1͒/>xr%z{B~f)> aqLQd˦N6x_uSa|c'?C> !KLd%TVGϊ|č" {ʮ4\id)ɹd˺,;.B@jj'/QHJVo{0ѳ mr1:lh ޸۬KIb"a&|Vl ' as}t~񓬭Opz߫|;I[>c[[^u`uQ20>M^f7U]Tˎ=I:V,2t0a\~_H)ќ^AwDž'9K|S|a+#>0凫!@-拴n~7o9kgg7Ր st/'DJqɆWbag5:qՕXUl?|]Vm] E!9xp>+<")v}x2CzG_)%] |.q?__$g~57vy@$Ol!s=v($W[}*忮CuyZwҐ7 q$<$%R\f\!kߵq{b.'R3̦uuNӵb`H l^n~D~״aW9&+|K#7uKU56;jjATTw)"4۬-'\BEUQUuEDqW0W 3jh0BEE44U]pCuss:{E[s E@QU4M[=BRٱʼW禐N҉aEXp9]xT. UpvԸD 3eOQuV Ei׬L+t .X{NNB dS92jW\Wť3iey/3嫷#@pv6'빸f\w*| >sVI(<=mJѳ'97dPUǪ)X\U<нU3}'C!%VVkr|"NqF`CAV2٨suR59ҼꋠȾL-X-* pAb%+l.B Uqi.Үg~Mbu/dzL`9lVlv UtZ[sχk@"+{zmbbbbxn"@EP(f2sy<~\ѱa OAO]Abj(\gkIDdɩI=|%8ɋOP쮭Cc$*mhĪ J8b+h]Nm c此U(d"#hmR`YNF]u(N&6X8/"6T om;k:ph9Mz.XV>#S z@CG+e(01Gx]qs5+B& kbmWe20R",#C%6j*=.1Us0Fyyz?ՆfYpr|[;O{YQB%p<+XP'8}~c(B.,7ttQs;tmlشJ-C`w]^fxp09iE-U>d>Aoo/,6 WM蒀LliRO+ZPca hsE{~q)ٴe}Sj;5b16.b )\ttvQtPAFSLrX,65[׌dNPA[喦FPf wJ< \9H=8iī8Dbu ./JCƒbxE߱_o^9VnsLM'3%M%1x@89ƐKC8PJs/~/vTߥ{,Ń_3oM:7׾Ϯ~_~91CS%]'vnz'H=Ow93It."% F?/%vz_?W?"z&P_Dco/~c {ΌD)L?O?}]Ĥ@ ?y/'|ͣD3ř K' fzyg1c1N_Ə!&H(j(41Wϻ}14wbHi rkB1ξL#dΝ.rډ\8Kϐ+e8P=hX.#gxkI"tm~%C*eO $%kj(~?+$K`՟}`jr?{N [~ɒ-?6؝vJыW+ I.'+&OH$F/L&Ao/W83HI~͗Fw&ѕ377)0ǻ;­'Ѳܣ9ilE/$)W`)=ήW_aеNt0tD6CXzA>aHsrݽ=dĻz2/4lY2%< {^z6~qduzX)| G~{ǦHjIK{MS]Txldf]U@sZc#q&C⦴2\w5RQHsM%<84؉6>4[7"[\DX45P(wTRyaOl%}7iڞר`hrlmuG.NsW}s#ObkW;Æ̌q;BۣOjs+po1^~/ ]X=hm"X{CA1B5I_@Q2#'^rN458&~ilBmoKֻ7bށc'ٳ Mz۷Й ,1PK?dt׷R베7?|/ !>zgXflw+nmq7N2caS^>e] %7IX+[B էƛwjC9(A0E/Nvҫ'Xϱ=bf͖uҍa0fƵ+XG[}fOq4ɢ@u;+ohZЗ gΪ/ͭTVdOU^wIwqwdYQA[k=w?1kZ@Qt&zO_1X]VVOJCEUS#ȹ=oztVի5i;tGkՙү<ݗ_^C`Ỵz:X$Gk%}^s4xvgf6TBM()~ N?)z>J[XYI}'xr'u29,ƭ&f(gw'y;etʙhbrXtYgH4[d ]l>wocUw*o>ܲs&&&&&K. Nԧiti!v _)d/=qiQM!aoKb0>$i!jZ$a#+d'HZR鴠:hv**p7G34X^YN84aP!ظ*7!Ιs"R Ղxh 7D}N$4{%˟uAe*ӟ~D6'*F]M5õg]&$H]ȹu,xh*B1_@W4?O+pE)1 ƍ_!׾e^=5b#ݼ;9;DN/DP"M%•WW^,R*zq|^t=~VN|_fIY )Jm>B O}d7;wf0YysԸP') g~w'Vpo)٥zL:NƇ_,Q' d,'!t24QEfy) Wl]K}{ FK3EB;~ W_dRY Y6 ]|~k \$Jx'=GdY$ e_"c*f|t)U7?k/GWp~FT,IfǸ8F ?7n\-yBK4;fH\lӬ M.^@޳[C5;}r77_~/e+PYج6lu;t@d1O4fJ=!9ts䞭k(膎aXmH7(B:L$U(g]n,<3(!R`0ϙtzbJm兖q̞UiJ$[Oڿ>`S-/tE,g|T\ %[vƻ/2pwJ/3y[amk6a\J> =@&#V_}!9x\ ! CĊE)N_@e5M*jӼNFŷNK$-Lp2J9J<. F\@iBzSsW@HT75gd)ҩujܾ ,w4Peu5x S)%yowXwt6<}-)Q25V(\sBd\ gfF`U$:9px,B`gާ/20].5pkhYH!yb ,?tcJyNՍ+/333]9rf3B%:S|<˿}+C3Ib¨[~.'tWb8ޗ @)/* =_@A(b|i\ӂ5&&&&wn"  3lʦvK94J$ӑ(R5BXD Rl⣟y_x`svSj+%Ec~mzr͙dTZQ{oӟz}~V->^>Vќ< ?)mmbEjp8J2$KbTz)ㄣILO9Ԇ|ddVBEe;ua[oK)dr:Lcr2BfE 'Ҍ\P̥G9y(<1 ;J?K$".#SyT4B$8ydv Pټ($;qcZɤd"=]Os)wT-~ZA,{am-P ՎhZCCV}?9}-nVUj?+b ES "8=f:#Ӊ$scgxc}kZ6R_T :5I$!>ps=:^9WO=cOowM'9>m#M@:h%XW-!HQF ,"O$%e%{94eu( +7QUdDH p:lzGtU篿 _ ٲKQi6VnGO?>u-] Ȣʭհ:[?{:8sF/Y'񓈔21A"Sa(D"scL `L_j*DH:5!Mݧx{G^7z)~6k5 uars(Š9 *Y zՍآ$HBͅX[!V!Gv{^lX4J<'SyC7_һ}3~]%9=Ś5kjVג..Cu|9w?oul󺩨n"?ʻQIM]fb/k Q[$HVXT4L:cE"ēI"%]/N~v11U$Cl`c[5Ϊ&m `_]BIiV̾Q"&F& ^C.LO&`9 ^}hGyx] ϣ\ Y3?W" ^a"Q_GQ*Cxnd)>%18P4d͊bqUT]jj 8m@3 ]%z+pU \M.+ъqz/Y=|G~iGj$2^Gۀߦ |OOxa +^[P.RC>salwk);WIwj> 3C 4s5{HC.l̯\U1!!L|Ee2Kg/KK1ߣ\ A-r\oތ`N~('3S_Kl(gvi}x3UQ]tze_/Ae~9{}.1% .Yz?)5{Y3`?/׹n2XהD:s-ԏKzr]]_igv^kV`k#3s5|}O\s?gu^bF6˝ӦŜ]]g1p^8oI4+uat)%R3pb/ k*P8O8hߡM9kϗtx~. t\e 8/olǦ߻lg++^n) t:3]=˱qO 3\-^7вaW|~yťĐWoٹJ9$yYԁ/.z].g&uzzzgbbbA4LL!{)H)? sp g_E7hַ);W QÐH *@ȷlݺ EAH$!Q@Qm-$_,aK+X]k|Y-! P( R%PU4n/_ǒ.EQnRb˷B\w]^.? ZqG~N"P(\Na\SW r 8_U!HLIdJMwc \ pUB^;;.~=sҗmaHi<ټբqhe+'o"^o{fK}͐:>OGGa( .\_qtC !toz%<K(\xzVvD_TE|y.^Ȗ[R0:tL&Y7R__j;RJvׯ 5Q.S g>{_qﮫrfTcY /CL&.OO!P'{!WB&cCta z.;<#tͪ!CCJJ1uTxlbw !(Ӥz +̦ͲxV=a΍e٬X5(86%d©[;Bh^!V6`U%HiD{CO0PdX?%`n& ~6 0Ƭ*NEYȒ-9T'q{<%rt[B9z}bJA8W9T1="sCl 31111,)bxxUU'/SO޲JMӮiy^ye,Ctuuյ㊢ Bb1rP]QUuEE>}%X,r9VZI(T(9ܹp8Ls󭕭 u7ޡWUd*E"r#D{ǁ>ۍ{e۶m8NN8޽{}7We(sa@^&AQL9/Rܵ \P2$*տ%uCE+rӛyͪbPi-]Nřߦվ{^P%(uZh A*x*ώ<JQ7J%_pNwr@mGkR,L9%sH$THLj!Taq/v@X{eiƾ4MP2RbL&scPt3g(BbtASr2_BJ^BQ'+S˾W\H&_ª(X,YtI"#ixfnKB sW&_@"Ǟ\e]abގtvԩvjj0n э?Anz{/y湰_YcgմǸk[2xˬ?0O>_^^2]u cvW}a CT,Q]SC{{0_,2NQRkz R=5'YkifDP, R (|bQRlū-oo@PdK8B,ZCSUTmu|h]Hq| ͹ B{VWZ|B!'}U kH&u'Nhaht]_"FU8NJ e}X$>c,a~P;z tvVb\ZJi0⫨8||F4llWI'?U \( z_wv(2\h qi4>zF'Nυr9chGyIP͇bۃ5k֒J&W_y}k4y_[{_l\6i }HH!X| C).Lh6f:fHkJ Ґ y8RՆGl,Va%Oo;gS4hfgk gP wU$mu`l %BбZhŗ{Y/LL0)}*ڞyMaxd}5c8AQ44x7ZX} EX3ylVi93yzP,搆f(M?RJƇy8op"P\! D`![2T*iq. Tzmjuΐ?̰cy)k(Ce+ ;gk7l@KC9k-]wj2#ϊi'Q*JCQ/OO(*v 얳Fߖ//eO]*f&MBP:u "2øuIQqJ=(j],e7t]k ɥBTvE*%|(lvSWWw)leifhhh.qggntw6Is$g(RUϕI)I$8vV\9Bl6n_J)q8lذqN\Z̭9ZaEo-k~wo֬V,.70OdGQ4[h[,Nw%18>~q!_#|ǹPYX&Y^?>ۮZNN!40r^պqafbbbbr[-Mtr+! >tFW(J*%<50;wyRJ Shoot7̤T*1==B!LLL`y,,08r(VMP*{^Ey,e&1---TV^ ZhN'52x9A:oYрdxgRtn}4}e,.LFm+hhhv/͈A{%39֍,MySDq-TT街L~;*u.HD )jCH RIIc81Tr7\|`%+\sL,8]J#J+B lB2@O=W(O 3vrیeGJzn{U~ B)%GfJTdÆ s=G[[;O=oX^=r7hE$--XDG2vʺ7Rߢv3EdU&pH%ɤSlܸ&Yn#HD{paa^nO l, [A K$]EQ4Y_yE:οUQo1Q݅@[фYi \adRJ4~\zlRFլ<5 n_AIژX`wB[jL # \g9[Hq.ttt]Q( AEEΝɓtttvZu͎n ٷogϜ!ܲ5McsWzo>c&ȗ$1?M!;UJ9(4QEe}Gn:uֲϾ8wl@oXouE6\({  q5ߢ[p 'GwM!0UPhX"&&&&&ctO(I0bv߶z!DڵNxWhjjfEGG8aӦMh{oti)ՓR G̙tuu.jR`1 ɞ=Yv-<܅ϳmCC='N -0=ߣҋac1<6W3o;ŏBCuj,xkoe=P^N+qU28؏$%ͽXABP,fop{ky ^ XK35P04pI_ƚ>=k ~`˒7Sg9ssX-NzV=Q0|%SE!#_hhQΜ!b) B g!b (UK$fzQ}}X|^3g Ø !unv;7ofppi֮];-_,ngӦMCccӢ]rɋ\]YpSpX |/\w![P*@_OPU MXh|&k..<9]<ܨ:n)nGRvBY$Lۈw%(\*cV-BE$~f61111Irw&A:lGydы059fcX,Vwvr!FGGyG򶕯 B>\} v 2C_>qml^'&r U.γyt{PD<̅^+P$H![$\q#)Hû+2Mߔgo6e|o"4]jhaΟVۥ$,0pi]X-k,~&&"@u]7%cξN<ڏUP8Mm`Z9&7"˴w91D.! JgB!ňbqڨp Omm-sg|> 79ϲaDQbܙ6NLL \J0= V+ՆKy\M;a׹߅{}J)G<(JgSKrvus8%)&N'ȹMH:M7bNvKH}=/PG>8Ӵo?ǻKu3f%t -[2:x$E\.\TrP+n)L$fcttƍ9w'OffL09v _#7zj}#6MXjpg A:XH(nؼ?b!8wTV7T)m|6H:v6 JutI@IN#f^kXd0Ej- jYӆA!^I);W( ===E,L@-[{nKgg'ׯGJtxr&Fh$B0Fc\ Ñӏ P]q“U4Ħ(Z<7dw"c =y,5O{)u4͉Z|bY݉`j(JSzN}|.QDGI(I/'O"TP~rtUPU㇟89[8|H,Ur׈ Q<Abl]rZfq~kXV,HՊf[qTJ$J,a"XVߪhnϢʞXr 8ٲl B߆ΤoGs ?#Tk0trOOqe]ljv95N)_1lpD"7 .;Ҍ.QN3=ʭIIPTeIlruEQPUu^{v=Յly/"ngAț57nbdF^};Rx!X #ͳ}֙, Cu3 w}}6#lv,RgjlJm]˭f:a) \ށNcS+ 'Ie4:kԘR񯠶  բqڟt\v+a9rgh|.{E`IF24T (|>O2bbbbZl6>84CCCC!\.עT*5w~0 dKQ g8׍ef VUS5jwX/ o"a4V7ch/)~,{猙M[k0Dz/7arX1+:NMDo,`)K`ƕfB;M[0B /.kQ\QEQ8vtلSUYuSϹsB0{u]'sQTUebb%+gg<Ģ+cd9;˶m<-`&zB(<(P3gp| wwzضmۜi~W~IvAWW;{V*EQHg2y b|>\.GPv U'=SG~.l6 RfQ~ʚ5,1V*9[.586(T[~@hm1͗8\A{w VqЏދlp{jnh44sEe:;x=-v\R )%Ng8g\ITU%ɐH$8p=~tx/i$ CXkRv;GY0eYy睹M!(FGQΝcEti^Q =>~2xwn|emך4 --tJk+c?r7 !P?Dq,VH/|dk6Dfɢ镨yX,vS4660u՝%S]S}K)YbDbo74SYYyK'š5k13\ !5552"'><aXqE*kfFGGI&S׮\ |;~RNTVVo>B}ݻfxZz_n}wLUv?uQqDU-~Iҩ.?CGP}_( 랠tjExx|K> (Fz;{Xi,0+++){y(K4jN1y^Ξ9kƍ  E&U*bMB]nii%\xYWpja0&+l D&t*Vaꉇ tK.{Q*=G (geYVG}6֦\v0J;Yv몠X̑ϥ(l6׌wƉʂKo H&b1W:\\?u.sTTp$S) \斛+MPBPLsL93r>j3Tmڴf9rYʙTGKr Rql.._5(Cfzxs~/,211YRJ(|u\x&HAB1g|& 24. ǃ_,!-_QY LƨiF"  .jw5Y{J)xsR~ `nܥ|ud2bBy>Qxbr d9jp$L&K$# ;u.!B]ER97b">1CuB ƜH)QPE1ӿ4H4^W2 CJM{]{^Ƙ Eff( RJ ØWUUR}De51,* !S9't%4+K!0 W2h~sxgd2Yr2sRrZuS~.BP*#Rd3(jxuUMLLm5E0 stsWCbvMƓg:whc1L$B@h?'BEJM4,T- Kx_x#Da{RU:\.ׂ_,>lph,^7cI D9U=|̣X,rz{/&Jinnj%y&'gڵ47~Y"&#d~yN*$j#TENe9ܟfSSCbƂK=+fw!0QD9sr?&!jRiP>gzzX,FjtsNzi|EyOƆX5B qNJ{Pr8~s纙" r҂ebr ˍezz/r1fJ:틕 `nA OÏ~_{t-0S7??q?l'd#?WvSoK">+X&0 {{9yBu_ڰLLLpIy=Jkk6n #<9Lê V:~N 7OO$G*VWR뻙YCOIfPU+J:VPy r.+ܬܡW( 3g0B:!Sz^6^").8ĮwXB)分h|{ :~j%#3 E1Vj<]\mK;4 歷)Ѻw 僰kq"ƳVCOTÍj`Hpm UNj ^v]τУ{.&h 89'UtX,j v dYT&}J`ԉfNO4JΝ#t:immn/8%f 5pl/Æ?O^ Ywg-Ѽa> KՒf>Qw7{fIڸ{qsQ)P1OR}yYuau~|0S$m~ ?2HTWvFj<䖡RXjnXrUBTfAB _U,g֮]i޽ͦi&UkĩBƼmr@4p `=?|..|&Ee&@7(39P0"5 躁yo9j1dS/h6.'ɤsE*Vˁ*C2y0M~Į^z8VGt*RP)!̶[QGGж0OeoǥЫK-煟, ͺ\.}F(eT4Ubg=BfC'̵eIH Rs!F\dPsAO ͐,Vac$BQT@AY-@( s*aJuu5a\usZJI0^`||1Y,e8]'hcDU: xed&&説'?$vC8TBa,y0hsfk.؝0SQy?DMe*( O3KR5|Lɩy@8eUFdlh"C!9=xee}UQ 'ѼndpEEF8拼y.öqj67bדO$P5ev;Zwy{h=n?·^6̎~‰ۓTB47PuRd| GyQLI$I @SmT54Pwgj|dJ{ ǂcY H#SDHe򔄅`U>:Qi Emm54 |֑LD"]MG(8\ͨMxļ ,%Æ˦?4N ,Ccv? 8$@cLSX=jBXٯcDY%WυA>$(ILMMqkg3i& `M-A!$ThB:ESM01>E(q zXX[$ʸ1.0]uI6SunGJ@^{%R"z))l-ͤN*'Sඕ"SQ}Hѩ)Ea!TUCW()fLLE)EUU%NE8jbX<7$tOJ/l%<0\VBUUxEbL3HIm}5.M*z{:tB؈|1jע v¦fzR(٢F搶sXƪ\ZtnwKVhyF'b;ȥ"MS\7ౖb6A`A4F -@QҹƍDJI8_㚛RJinnfddkt 4-cw6bU5<Х>dxiRJԹ0HL1:2N⥥ SHB:TLꬠR`˧"O+JҬ' bb:5@CLt }#k6T"c$RYXo©&+枬,9| K!tg`chh!~.(ǎtR_߰ #j[hwWb{YNcHIlc_A=Oϩ H=i]Y>ˎVl_S߮0vv7tM4UXEx9h2Ù=㟼˴nPH>wװ.Nsd; xzTNѼd,#TS]G9>=CL(Ulް ]C*(~a:j}-B~q֭xuA Ѽ ӊjuRSUAt$/yT:%`(>{]qS]¥d8Np94SڀhqtHر$B>HNĩHLPcw7(70'9}x7QJtԣ t3] P㷐ONQ'&xct#U.F_p(9o{>U1tsv(4J'9p4je#~"z駼n7 $9}h/ ;>s 7tAMUt/Ϗ:8G"i]{ |"M XBP,R^>#\tV?ښIgbB66~eYM hLz{| (VG |$xqΌez/u^At4/<"O<ӣߵ})VkS$N`$V(e:wsc%)N筝H`*J?Ɓskk%#g_x4ý>"BQNZVQB)ŹSL&,qb:R{|ծ13B )%B᪛lB($"}$ޢse%M6q9L\XD D -*thح7g~ !9v(w%*$'][ >&id?]HqgsXZi (Ɔٹ0)lA3E={r͗XBL& ~_.CtI) o{w*ׯ'sQ[UU|q~(\AtľsXƒ`qNI6<cQ,>s9ܪp71 SkXJ?y '_ݸVTI!L%PQGMOVܽ N*:-XǪeUW-#-lYHSƂt?x*B uaD"EP bmn`ßg#<;/4Gip$iYin;b\dB^s'Zpxh[4 X$.e3id'{ TȬҌES1vvǖϰdR*1N_o VVTzR?߽N?KE 95@m붳ruLJ !>;"U! I ihְJhꇷB(zl&`^d4V4t0 y3Wj$R%agX_f,όԆ, 68{K{CCEˡb_ch ;`GII*c-?Pfb<mM=DHQMk|3E%H4,[Ef)l{/}4=}C)s,]TJb+L+f]׭%d$l?yͷ]/!?Td8W (gN|ٸɪA9|vgZ ҩ8D3G8mk6%ȘH]^I0aMKcs]k$8~N&苩(6'Zԩ KJŒNMxl_]}IԞve;:InZo3qOBԸYó?ņ%!8rGv?+2P ܞzKBd';P巡gud,dQc%NO]=P,6zn}%3ueQWRo*+W$N !M&^6\~u"N屧ȉv\J=bIbth;K}eUn"'8V2nTJ??$q{Uܥ%2d⦶=͆-Y[B:cv ZiYP!$Hubr=[Vn`y6AAX>|26>F>TrbS8TUͯkvIyy9۷o,#N!uU c/ KPr;9x嵟-˷%Z\F9G?zZf5ãS*z6*Y< m߈ׯs|mcEs%C*L]/qb [TT<.ry@நgI]ļv_BH^x ˗duA>9x'V@X4/j#oqay:$DBRG Ӄn.hA/[a+ jweyd4W:nÃdݻILuشi 6slYI0yΞ;'Õ%뗲u8ar&S1<~w) O"ut>+-ڻ6wOP+'m*&Ul[(B`*C;T;_lݱ kɍ2cgY\ PTx+\sI%XPTfRL*P]U/-regӌ%AU̘Tfy4۝x\Nrc̓۰Z-  )%Ŋ}ح jt8唉y2}w--گPKvѾ6z>>c hO$J*{;HKGJI;رAo5l[*uEQ0ʹq)6mD8&GEx,>_~ES[R(BHZwMŃ7vB;B,b;ń)/# !5Eq:17c_'t{[MMy{=l۾sA3IUU0Txx=4߁T2ifC,n^Cu  L&9{,3%QWEQs3b$6Wo/_?L?|  ZL+ dq81k7HFbէ Z/Qq/ ~sClBBPX^|&3(ijK6hz*73a/}Mۍl 2=UUgvE`RB m{x{t8dJ$$#Ln.H2Ć$'cdu1kr-!kE`s gp^2rFaA!5Ւ<ϰB~s;fhZ!Zf]/gDN^;>IUC%!/4l2.E8éI˖|: z.飇8zxqy/d'Ɖ%R[{hf= Qָn4]#I+&A`Y1 drECt`[)IMN.(L*(*B(TʗǿHܴ=X3GI,:pm(gq"IL*-0ifAZff{:V-.AgѹG>%7TjRgp#Lo e|+F7vSCO}{K~a7(^.56uɷV5Zܷ3 쑟Cb)K6ݏؑv'>ol*oiySL%[jz>Kt3`QYr>"Ǜ)8?οKI&'XJi+LԭW?l^_~É)SᮡaXH"i(88!U!ßy.^CNMsS?iEɉTTNra`*Kβ5R.q5>Km~^NA^PfB$IO 01iָsbnAg`>O|6P)\mp:x^~?hA5 ]R˓׊PzYq|#tg"ͣΚ+O2Ob\0ihLAiSXKǙN׋:- (&n|/XwOP4H}mC=eQRvL; /9F~*46\o2X܀r9 Zqbgɷ\` Qq⤳9%{QiOu2O720K~qʧDҹL/rN e׊:$*f<޼): 5^%B 5*d+uTybs? BD wRZq)3&jtTDIdS1tgN3SĵicSTpursZqܗ^vw`s$ r8pO}<1B{k+Ѵ6kn([Q'2A^rR,VJú{27ߥs"3h.&KVS=WLylx%oFPJ,S?|xxk9ҙ< qF-w1Ӄ\3Ol̡lT4f"-GcJ"Z*r:NpZi.Ҥsbi ;o}m]h7x!s5ZVp{|LL˥Xwau6"L~1ry:ՓO։%2w[d}~~ttMqGɸ#TC^v8K,WCYȑ| :dzopWƩG3ρ݇Iy T]_i7 *L{)SHjyr7@M 9bucd ŝb]qx ^9]X32h?v}H;/N!a#d4<ѩ)\ Z_KU0 Gʙ<{ž!$\L&K:͛isMZRlD{/s RܡlSǬ~w?LNu :xr[o~锗S 6k5hi+7&Nw*m̝p&/R˒.d5o&g)7U. X(R)"{ﵝr A~CmPy7P'#$ 4h<ٜ/RI,t2gӤ9PȒ( yqv3=M{CB {';ƐJe>&KZXyמ3M@C'@ɄVPtn288/L]]< +V@{u:\x=~&&&( 9Vday#L.jjDBd[I3NLeKsN$bG;93*mI2Br)bJ}QԈI3HQ/Иua} npC ? |#В]\ _ |veIjWeqv{ AWgT,ZQ;^xYF6)H7+V-bۖuS9[z?ɁSNz6(x#fa}10# twX2k!JɤI2EwZd:E&)Hg HOa3-m=hctj7ղcks$LNߵ#`Ւz"CǞ 3YY'=&@~_r>EkoϋϿ½̇ES>C3f|2E*5@( }}~vq*k*yqK*3LTx>Β 2O&`XVvgmnƜd0F>%ʐLIحA΁=d]|;UPY b*KIAtSUs}AL&@ϯе'_@* *$dMHd39Z&8Go$pTra^RTS-aj:E&%JS H{XzW_3yʝewr[TEeċr󉔒@ (  B3k?k_~U,v5:;;OQq8n\H,|y'GvG9v.}[ai ^Y~7~][X^&4LE>A""H-ɓH$H$Rd$}O>Ⱦ###?+V@kn p#}N.bڻ̘d>*hhZ@%!ۨ_2/NoX IGr.m"-Cta& 6 D4- WR|8M9ε3X\^*#l (۰ۇ0X 7LEHW;ݽCl޸]\*"(c4FVZLeYuuu2שZ cugEQ撌u(IUͬ_ހ#dӉNFQ,_T5< @lhwH0HuC#^3cڅMԄ=d۵w{-•UUg]3.pw)EjyP OIL6e}AQsE -$춑OXeY rU;^xZ(d:@cj*ڵ+.T|ѱ1<`Q2;p8<Op\cL3K3Q:sCGRpX\X,I"][QMSdN|ѱ(elZ (k'[nlKnj!r&3.X,6•xy[VM+qX+먯pKK5,`S t7@RMl[^x%#Cg$H3捫ēy'9AoI%X޿ԙlbqP^#=C&@Y%~Nw[ ITTD+hZP)WKwձ`/CLdM,t/+Czv6eX&`PyPu8061 y!amm= N]9zr gFE7 41MzVT9B,fri}2.=gq& @Ks\;qX6|@'CQT(6ˍfbj|[ 0r؂):IKvo`1@Y!FoGܵxNbRME}#~Sc㤤ƅԖI>FAb2Y *8m] ƈ4emS+y/kfiuh4nf! QVV8t U @O}#MİW,Kj~n8i.l&bwSp(K :D^RLtBT}r s uvrdsy.^tQ !g宻bӦMXJ9[Bl^{6jjjVǵey_X>W^ [^v{.H5֕R Ti`p-^ Q(xW8y$Ν#HϓfI3&t:0SSS3'>R]/LEϸMf+y`իU.U>7]ټ6$⁸t/MHH!PdS,_?L>:Ă[j'gxhj\z6K(T~ W)sK>0ns'4I0܀UIq!phP-H<iWPR 0쨧s!B vlD'T5* Jۍ͆dqtR9w.ufWS&W?wr{?>#,fjժ+v/@UeLivEKK @Et:X6m>ϻ/.Kz`|hKQڻQ??t*O=BaF9sӧNqOXp:z>@W-b]c(0ۃZ+PKv7$P#6m_СcORVVFm!Rvÿ*Ӥ ]~Xp/V}E[8tXaA3N ed ˖a2] Db2;hZ$f-05'*C'W 6GIE 6&$t)륶ՊfCӴFd2bJR==ݼLNNf~?v{;5Mcxx{ى`ɒ444ޖB t]T*E4:/`||O7iΝe 0"%T|{i='G(++cfn'sM%8μFw*:I" D!MN "Cggk,Ru[tC{[ [ ) 5 _!p}H,VMK*='1[̔U?Hy͖9LN YOe4J9zRbYaISN… jIGGG!B,]K\*G #:9y]oXTWW'Y.GAQUf3rs>,kuA)rD;M!X׿|ϼP()h:T Dqzm.xZ>qFSŰ]V*[Qǔku ^@*Ɋr56]=݄A|>g]OMM B}r9!rUt`J]th6p{/(t r( HTE5m.u$l6{r"D \V'ŀb}LU''SӁcCêl_=}>xd:=tur0>TvAJjV'ctOl׏Qq**^?憪;g4 !c!tD8]% g\.NI;97kUO5.dV'cZz=L/}4ѩ)ɴ~PTǃn{ GA" xORT\>KyYB) v0 s '!d2 QYQzu^ rX-VMGKfWuM 'Oо~3)W5^B,~apP OIϝ JH'KqC'P ƦrH) RE[vtK820000000 0y~]ט2WxK΄txBnI69IW9drUxW|$l7J0‰@en@Pj dA&hܼSEJ TvW+/$ߌHJœBš{%ZAFiL5eMb[160T,N97-BBIy ] q\Isk\>O؄NP?{d,\P 4yliAx\Ku 288J2LUA.!WDR1C2cæL d??w7b?{.z. ,RTPp>?Rk14.Q/ F{O {!*E/:O~G/>iI[Br}a'4-[MR*DV([5(\w9  M^ͩ Sn.?|8 |HŧmǾ|6;R6zqg P9ܘJQ/}Z: 3{_ްǶDN 5N-<}=~˕6 Bex8h7я) 97R"noG[I/_Cct$G(_ OR2SHEA/ \^Պݡ {*jj3qDZ8c/O@-+Tsewmɻ*%dbӋdZPJQ#2, 캖'ۧL b*=DmwȌ//pW*LZsm800000000(1nu񏎮 ē,-?X_x ^[Y)tcEο¿K4gOQ%%ƻW/ޙwͣw{.(K= i7K>5]TL|e P.R TU)l*/}ЅTu]G0cR-Hf׮žg1_ߠk820000000dyu*W<8_}:dE>BjNF'cRy`Q(;/ȡ!ՕWt\|/Oo[=+{2~>61KTRV`j;'e|Ji/}v24l6@Rȧ?wG30YTV\ݴ O)XìZ2 ,g95BNH w2P4E!dR.*ݫUX(@MLrlx'77^Ś{R2><<‚96i(m݌OʼngtbY}-5ALX*g9ui⦅ <ʉ>Uvz\&$-ISz+P斜&O_9HPrNQnH]]KƂ۸@WgVj*c=!bmjfͲŪwfo-OwYj m|on9IobڕT}T,XgYK*}*ElX5G6L0BzvD:}XMaqGgYx%khGhZB@`u2Yx<.Lm%GwiOZ8,Rr&p-n33qsI:a|mTEbW9B^uu҉8hh,O;${aͺD ,_xM(6V,ZQ*._Î'R TWm]ϦHU q}r'B~+RnuXXSְf=FKHL p ?{iQ.x?fW;>K%⟿+׭y1pM2ΫKӠ`2QJlN7hR=Ċ-_HMR'9&')UUE5×uBOGڌEϫiW\$WWW}V6 Q .ev5+gYlNlAײLųX-) &gZaB5$ L-g8=yif"Ջ~zs):@_~6lތ[ںDO T 4jwⲘ1@"ۊi r uH: 9gbhd ^X͒5k|91@Mbvh9Ǩ) %']6`+bfر']\ϣ HCl:/䇼v\iei2I1@54MC hXiZYuX==|A5&]@J'95D)%Tԭ䱇e2Ay&3x/ppA>5EA ql7l|5 8# t)fT.;E'qQD`gѵR9 sT*/B۶2<2BSB6lXWoUQLUi yMt`Rd|X2?^RUs̪˨ނ ²er7sr]J@OzGSst~Ηo1=ՄIL]Xl(h1H޷}6fLfAo;}hiUm꺎je˖r9v<[ }z1e```````p5A>%O\K]S_&[ >}&pMߢ{)MGwu;S/ޖ@b9ց$}]MGذ S>tQƣyxw^._OMsлzpuK={sxVo V:P\X:pT4P봑ItL%ILM08H†NB&潐zd9ش˂+XM+޷^po`y% *cص݌(ب?ηvҫEX .MXX$5;oA{ҥ'1f,Wuq]L2Yrl```````Flyv5h#4V-4F{:"TœB^GXaj+qYՒJ oJPS$2g(A2t $w`TX,#N r30nQPGe":ù~M(stg4'\ˢ*&Azj*^Ԣ#o&C8TGģc[pȏӪMBکQd(!B]*O`ui^݄K0Twڪ2&qM>q&Q.X_xg9zz{i@&1J[K7 RQZ@*AZ\4/[IB>F 9PL' wF|6d?-hV? Mλh8}%U Mԅ]!QΞ9P\RVEue$} 'qʩaDi'crFgk iu4/0ϹfjNAGЅ2E"v!@2:G$&gں|+ z4MZ9'a# \,tPIk=_#e/16)>Dg E g?? l{-]^$@(JdCJt|$Vt2 L_t@yPC1h 8<(ޫ (WRv)tmf\LGu{y+=UQgT%a|ڠ(H<]"B(ER}ҼqYQ&u bޕux5mR 3KyͦRyai7\G2^'tIMC״hsۤ+^QM"W> Eɻ1+}{K^QtqSMǍ@+]fGJ W*u>7W|u{2u2oyE6w2va]/#4 W7X1y1a]_|npX.d UUq{Xz@6#KqFuFGEǟ5ПPns >:[蚎,.*@#UBcp{pa(QW7 !B݊v&h7Odo GO6l Jqm ).; ;K-rqf:wvqs̶8ZĆ;ֻSA{>z-h'Z%tM&E1$oB(dyLp;(<.IL8"Cຑzsvs3&\>>ɂ7~A *pp$8}'†_,{߷W+،rG#z&cn^͢r1 Љs7ML*6ȤһwtcM!w~n0>G{RIRI?[?M! .ut9 [V]{ :SiR԰jQ8 xʇjE=3y~?woZdF7voBM#=۷`ŗ!x`Tf X:$w$>8O>0@2~Dx#ۡW?ʿ4,W-pEHicOo$sP(93"YPMկbz}q$S`AhޟFR}_yF",NVl~WYPq˰:aB욟>&tλv40u ]#r9_]7~SUc3;0J2\\!t4:)/`Db)K~~$˧B$t@'v^|n'ϰ1 RXXa wW~6n&GIu !"ML01@(i"95TZ  La󅩈1)-&b"mBtD^Ůb2q& rK$@˥3X]6RL&}a{J|y=ar2J*P(V֔`u{Q؅D(*$PL)0eAǒBeTRS$ &jIH$Ӣil|M8)3;gRQ(*wq _!%$ sH(d M΃&赣 2X i -H-TBbl⦢܇&r8\^lf َLGJc) zP$5?!2y`P~LDJ`81&kM(Ǣ- Ħ 1:0qZE@rj9/waA6W,E˦'r\cc2P9Tl(EyY8 !в ǣ :I( ^ OpxCxm0cq,0U^T@jY8̓g|*S `QX?oh4%`*EzfBrh OyY%ghtd^!)4J@Y(D!PUh"DGHT<>> ېT,?<~h A(%C!0ϴUL|gcЗ_?#Ի̓O?Of9|(]6ZBP(DN;)3e?^6~;AOIac_ۗcU$ɑ6|'BС2I#;ʡMYeGxϟ}?>'/'Y*rzH}g67ᓴy"SQ._½F:>C4=z5UT_⩨%TVQӜ|eF583:!m:O>~姨u+fws'y8;ѩ M 1e;F1O }URca#%w7Ni(ߊrjGƈ&d㣴[#Tjnc*S_;-$T^E o}9d1RwF|Sܻ~`';S,p/?_3ܽłY~'m|vJfqt!@18Gd=7J[?>gG T6,aaCƍGG|%x6'a^ŏ9 p[ٺm;[5pVŒ!?EJl|k`";GLĸip{#qNp1' ..a Ɗ%D$[->7?XnMx|_f+`V>mlݺm,7V&ƢQ4 (f*4C!%d!Yw6/2CMVǷ5̷%$FK?=8= VӜOѴ_e O1u]d {EDy{5n+_ ˭ړh`;1:!8?W϶-}6jgO~MX֨O"HƠPZ>I#5X0~+~BrC:i< :bCEb1mg/|/lBE]i/0pؔIreV3spO>S.==JM^б+YD10*feDy( ,X)o,cM%;z_aէζ%!#zTTyrTTs[Pl4MP:c-p<,F&y1k[unC `t_W[gy<}ccƛX 3w=H)(oZdžw, 39J㺻q)`EiS `S6msp;[#8|O/=PLΩBf4Er-~f4&3z6ί;> mšfcu_"6i:B"TwY*'R %ALZj|/JB^7g?7nNwjZryxX=~*^, ړ`[&(hYZ"ugXLCEsxq)qcP.zh5 Μ#m]GUUOBUu9^ O"a/@!/BqӼ 9I:{ Sv+hNj XdF K 3MJ^UՄ|nP,/رi خEIuOy{6C)b}yhqLrޮI\rʂ6յ,hhi*sw;0I B54ݝxbS*BNՕBscn*84fcim@ѧ8!F-! %zgY@hOptmb ]ReG\l|ħb|6 ,ɱnVE+N;kZ1~p-i(:ukW4=dYᥠo;ҟ|_?ѱnT])tqCET禣8^{t< w 4$ӻJ#I>gJWXT8  1ҚWׇ)G/:2"Pd8ԣ' /m+ip3J#BiLob*LMۭjbk[% [Q$fmP8Nl6;^dU̧'M#f,fu, ́6##%*K3%;兂*甔퀸|h*naV%VoN#O PM5Uޫg^](dw)Q!~|~מF$n+MX%ehRGh2o<<ϿwQ\UJ&|!Lyܬn4$p+w92RAQt-O&cJ.NtM!.\! />K(2V̜3OX~~]e0/:l1= ]Cor#XE+Ayx2H]\|ikFc)1E@>6J*l\a֭Y?'ʥ?)V}Cd % BX{s !yPds& MK'2F"D:yu^*:{y] Hq3^LLP^sz2LoT+W"n+hn5a*:N:d"yNKNƉt3KS>ǾM_$$ۊw7Oˡ}dIǠ>#unM1rP;8Mo \anJ+ u~74 \6^{mރǤnK^烃x]tEUlAys/>ͻ/_F2wq\+}8N*'#ul&M&%'͐H H]bTp}Q8gyQ>ػt\&G.)^Bt6G.%ARyTX!‰wkq^"_K׼\.>gk(uM#NRHgH23c+[ uTcUf[J&[9KvSf߼5}m"6/xQš֡a$͐I'I00$͒Jo9,%|>MDŽտm/ݟc=1ywO#@Ӓ,x:ݻ{tA#ɒͦHs3.Cl6G6_8)ε3ʓ qP'Kʪ*'fv'Chwp\6G&#ΐ+"y|z;G61A!%͒7uO=OCn&uƅxE]o;Y Β˦5$rrYRbR#ɒe X< DP|cwkᣴEɤ9t)edED/%ːit3FKW=#d H%bLM% ,)rd3R4Cn%?ș]rn0V0UEi|ff734l\A)6%[:t|&C6"H~h+a&2Aoa*f0?`K(nip)wgwlg?ѼJYyygը]M[VGsɾN&Y}IM, 泥&# S= SSrp⤮i)kLriZIPִnc- V/ 4Iε2/^Nsm Mq-˩ٱ:DVc:n=PAyYsjO2EQ^]۪2q[$5^/pDN.gIsc "TI W0QQ_OeeMσ/T͒2cX8B) 8yL o1FEu{QUQ̘Dw7c-ER?i8dB:9rS^*7)%T g)l޻4fJMuǺ8EWO?5<}3a筌cp#Z#Ñ !Bg)g_׿5dt ?e3Uw[ l-WitY.K%VcȢ]2F D44 *44)K t]+W%7]bM/^\ReBY8`Q(T"V0Ei']4TeMP1tdnk&tf!Ph3E :EϺ#^@3;3$|y^xşM۴Pg:ͬP02t>B% y)ӼFw*OV/23.fp)N }ʥwd2aR.^P_iƕ%}yiVbx#gQjPL&L@ 67/bfl\ś,<~ܾ̞.dvw5˶^YzK|p i/9]7/0[90onk/[1tF:ޮؖ<@nb/%yM#[ЌzOR:y\ܶ)hw4ՕcRc CSd;X ɂ0֩O@D9u4d8m`````82-Qi _w \z޺\.*/'R,y͟E(&.>|!t6Bke]?!p|QT?Ӿ O6W%t W+I8S y*b[ ۅi/2U_3,tII:!v%/LR:)p\>4ښ'XP(h0GE$SiC7|kTTiBWNբ4at\BG n*hkDѾo.B6th3Z#/eUIBR*&C7qѼ n\]c`pSygr>~=ãIXe6OWeӥMx܂fv:a v2>%`1 V{MvFkV@E5+6y].WM|0%/ӄjj}TT֎9T ic*v6$%/^Fqta8{Ww]˽JϜt_v[k ւqzV9ohL.N*@V톽e!YJ.lkŦ2{ Z)Aހ\=pu7[x5r*-`0ٿ/'T A"$iIF? \8_(4~ܠmfAKR/@*+KRP uZ@DΪӖ;l"uǑBA.NOث U7*~זcܱ@z[\ :K5 >LCWPSЄ@J2.VGT ɢIqc*5IJ+\@So.}iIfAC`dA%dY&KIWKKpYU[- :$rLq|i |Q?7:l j4N R¢2_~ߖg5$2 &M9N$b&~dJ?w76.5)-.p0φk"XSXtɩ1 9")R*s񳩤ΛcOpXU)Г*.#vA]e\a˩̂uA& u±f3 M*ύyߍ6`W0iK'YZ\--J%8s Pi$l>8&3Lvn#W^/<i'CK L4H;]w T_KM$ vyCch /DļYɉI&w7DJKb1ap!`]DIOG=\PSB\YSy,$OJ"n[V׽CzqnTnbMҞe*#/餹x3gWxRAKKrV'%)p6SfA@ဠ/!)3?ә(2@PA抂dL+ vMA.>Qz箩):%9Iwn1lӍfV(:ϙW.]^U͈[2hR2AG!)MJ:D()"}} ti$\Х(6٫`5 |-Aͳ;Q$u n+lJtޜyvK ,FGNXU o6eiEgMv fa,s @{^OU(jdPz; PUB*G-yZ8*W1k\jx :؝H!/[TQTF5^X~G`W!%|qW0VuZu82LeIXaSH僄Fu*-1s)yrwͺ$ZzhNu^r.]W@d`p9[2#:qEdW 軹l OT4dI%*xV%3RA?Uu~6$ |\zIIԤG *IE({T_j,m/T.Ejp%yi2H"/&.nR62/LZʧC uw]}دsNF ̙Hʖ-y^{<3vٙ93 8-+ؒ@R$96F^VNh EIst{7Tխ[O+qCntitO8T\B1ACG)Ff~I#u&Uy?Q%mGJ(B1Q"]-J|g OHr{_84<DZ !殻䜺!U\j֖IZsJÒV cwqyp=u9H>b=XhˢkE]=fVQ,;-Yܗ[k[zµT!So.-WHF ([b̚7 eV;skny`N'ݐż඄AG*aPhNgW'qKk( n/L( Ry M{AVHZ|1zg*$1s1gc<}wuOwD"z+"ĀCͥ9ڋYתfz5O7\~'XxMAMP"ҽw&xqXWFk]gcn$,_hn5?^Jq1%;JĒgVsg7{7l׏%b. n:ދeO\c)Qe0ch:snH~7Oڊz$p%RlSpjf4%p\%Y&ɥidMLԚ}f\Q.|~AsP)'?RdH x>8@DD v@q!;gָްJ$>1j quAioñ&S.)1Fq`DљwHAR<13 ]3 {%LZJ j;AŔM>R%4U>צo!vs0 ׫  qAzF>PS!c? w \;+$)ū +&}+6E% 4$~JiJ咈 F 첵!+ͳÊ2u#6dr_'+y$>mZR@'b0Vՠٻ5$b jX*OTZ1jCEH9BcM&vۼ0*ḥ)Քk@&|I;W_PTD!B2ថ~745!)˯/&spLɚJVI \ TG$oU^;0ftpm {rVim{YBPCvUކA@*MhՐ5 M $ζvZD͉q|Ť`ع`ҁ5&T- 09`Là B7"~Ay}Bc;kL07Q*91M lj^gSɯVKΌ802y BUt4dGT> TE >]+rxáiM#]_‘A{mz H~dy懃p?o7Yၔ)I6F>39͑MSDuz ݶFゼ )͌?ms8FBX-(( I>j?wbC ڜi4iD5s@tUQhR1U#Qg {l6c7}60 h@iwLlŏ{m^Q4W~A 64%Cj2@sD(D{\Fc 7\m,.&5tÕCw^nQš)qѢS&ebj 1+=z%T[-0[|k9Δ&M54uhCgd!sު4%+ &μќWLVK9|{̥. I+O( |VhzW35pY9l fraɺ 7hs@OJe>h:td]7,T0mk'5cL+{M{Ж4 )`*?(D1iKRYE}W͂&(JAi@RRh-0k_*7TLf6`!`\KkCO] jPR B o`z#)Rrxa\c 6mi<^/# g-+\ruĦZ8nEk\lhJ7+Hjr(lnx;ҎMRgwyX};yP܈Z@b~풳,a<]BjgVҀ"mHvs3<~AN](Խ% (Php&$ sKb.M]:B H*OivIG5>H RZZC k6Pe{, I*# ShZsdBPy iU}dM)2mZ4褉״xZ̘$E'4[3(-yL㮀͑d)$P3 l:?^b6HBmX5[Ejj&m K|C׫b@1,>IDATɶ! yTRq9h87+=Ugrd$ρiŴ)hIV1H O9lMHd5 y#gHοx>FAePꃙb`-&lngVx #SrIˀñh ^.+Å+#2k+49[)ʿRi#} c>Ors~c޶ҥʰd[4ufO~%84x4& S#k(vF%[%S% hNH{c#VSnF>AQRRI<2"htD`! Ō^ؿR*xq="K$(yQi7A3\NWbh]CK\( UۚCɃtFӹ˦&MOǨ;/mkN+o|:g[oMx8dC$`~k C VW^ y5\o{w ??1xFKOh,Fٮ)KJ(h/״ ׀O4K>L0 @~/X Apg+-!4尳QYM;]-`'Vð `*Lc%JQ+XMfC Ape=ʔy|K6O4KZDS*&lh~U> x We/31~ O< ӡZ^9w '`^)pw׿EoM6RF W“+$%-H|@\*t!ǦmRd:)ܐռ7 \Oq7F$UncYXd$R brbk}Yha-7K_QR"@[L1!>'һ8Vd2O -dJل!<0^FY[+pJs=3!!dyق0Bk҅X!PJPACs\!! 9GҮ#2 W &@Au'4\^Z5۞R8.% \'dQH)cQm[qI .Qǀ8S ҵg!H7䮸MpMh2X WA(I7/~=&H) nP$Kg&l1L懣5}Yť=M&ݶÉ&:k=&wZ"Ҽ0nj & H)䎃Џ؟b+Q.1慨Yz q6fR*+)R\öz{~t2Wa[\z6|S9B:} }PÒ1=6g|JBMI׵CKq]ȝָBOWM*d 6U4 g27-\IO46y( ]bK K9ZbFq0f5(h 4>2ǩ@r<fo}]X*.Vz;!iSepen'lpgD0Մ{+$=#g.4\ו) Ɋ&$XlIzw[&Ui5.h Όl.\Bn)5VH֖]e5(3M% `eL0:ʄ nJhK0h rf:[ƤQ<3ٺ]42h rY74%;*  G3 ^ڄ[:Fz~LZJ6(7gJ3`C]akjAmHRW^A:j. Rt4M)x5Ld4#U; f λaaM^ UY&/㲦!I/X"sp-aP$"e4-*HeIMRlk @9PYbpOKsiZK1hPR1;kLERMwKjs.#u.SpA{ab׈"#%$A~=9;`@4" H48{M6F3)մv3 jLE*%5FhPe+(LJ98y]dǯϏNLru3aL$V<[г[ښk"LM7|NOv Zzq`BkWә(!=ht,g:o0+xBc a9c(7xSSu+F+| B Û&N15ߥ[F0GYhks",e=֮7Af^)k=9bWdJW SHS 4v| m3ph7#P< >G-T:gMhŅ^J4=!Y2ӊ,F%Tl jLA׌bIjdSDpzIWiXWf%&C# r9MoR J11FcêR%GsuJ3cJ@Yw u<`{Ak@PK*<r>愤1^>!l|"B-5BbZ. /p>\5Hnݻ[7-Lj}AAcHK)vقh}åQkIaʔb wUI6E%5&t͸9TCyAkݕIBiťqAW5{& l.3syOPj RYMwZw&#Tl )y܍AG°\ָ;U=?%A&&={L ^`EX̺NJ.EJK ,Ld49M~J W\`\^P8N: Y@)1`~H:^hei.%'Ԇ$a&0Ƣ< (qʁbוHtVs65 sU^Hk44\S`$x$j3'^7'2]Li"$) }i+IxMo8]jBleKkːk3E:T/wp)c;nW! IdUrҚ_3U" bJ jnitܹT{s_Rq-ϽImC5 YP9&+Cz*҂8 hrʽb.l^A\`nΓ_pIiŸrhCd޴ 6OLX)J_ _scXM#8)5w? B<տGcYjC2#W3;W o+Lem y'Ȧ>i:͟=5o߿]-q;V-vg7>G)B0~/H /~ f !=+lھ3x鍳XRZ+cXu u )‡\}QUWL!X}q_sj %b4d]eK|7TFLc3R:kgS[M9 x񻢢Y_1ǥQ 1-Em~[~*\ f~,5m=^F# Lv/; *}Wo4uL5}YSOUPy͠>pjšd<(^Ӂf܁nۚf)\ٴv\¢i f$ѦtX& O(Gӟ[!-^d #s*CiآrM^CP_k,KәΗƬ &>e>s#*3S ̓ ) "$s)^,4NྴfZdؘ#(s/].1 Ż8G%u缭¼9=tϤ36FU }dި_6Llͥ𾉴bI|k3j5xa )Gqu t 1LdƯ8Wu)-`Y oZ3R,|ֽ3yՖo52sͿ\)ŵZ{JCWӺhIwUWkH֞ )`w?\]b 5Ԍ{1(͹K`xLA[@s+I,|5HF/Xϒy7WmF1v7}Z6r3YMţ1=]>Z N<$nC#=W6"/}4U+oj>#5 J~jǶ!$o,K}2a#a G29:y9' xG{R\> .J|Ӷ})8],{&5=̭M_[_w 9.5v Splyg; Ϋ8\\'w ;Fs,6oK^8 ,bm>xyDѿD;zɽn,Md5cewz}QEhncU猷MqPs]֯5nu [znz poF%z7zF7~KbheQ+~4^״rnF4S4~r!\G JOa7j}uoc+UیEkR]}a1`cAv\fl`Rq)ƾP6z>dr|t-cX2eH`RY{{(C3@r>|qH9붶b"G)1G` Γ|?$UZnc(Ar|}{ĝT=L!PCCÌO5Ք ۠hc c)%U+diɑ&SYl%)&*xд |~?o2/:(,2)"l&G" J+k({e< UDz'V7P]!4N6L`@y)եXa*@P'ʨ83- o겨gN N 2<lgpxM0^FMeDYFFHer8OeuDk'RGSMi\ 2o0|Q[ݾe, 4'; ~ MtA>>9,+]X2pqpڛq欬BaGyGc\GLs5=Is~.NT\&mV9\>2O4>y>~^TPW!ڵܻ 7'acK Anz'.bˆ$.&1>ŽDnOa,;Ź/s 'ǵN}0z /=Fcܡ\Q[G'85@zmv> y b,lͧw4_/ N\! bM rݴ]]1LH3 ՛#!ʓȡSD|{76a\9h%^9PG|S'O K'v2xUr0o_aST?}w: oiαq*gf~,c l9x}rX3#}m7-;?]->44gp{?k|xK-,{cwRXU'Q~.h9@"+h >9!enI5 X23 e-<[,,9W$g12x|)R3r0?z>Y6ǐ3WOp࣑^b%ac- KՊv bg? rhd͟]<}%>6 '\'HPlXcSj[ض6?#ĝGxZ){`͌26%w_ #g'.L:z|ZV2l,IMp9T^G9pO`*_q ;˄[4 4]yGt8dbi*V_;˯#ҼIVMba{ ZK}6cd"OO*!9=>jh1$]7 SĶ X2@'c0'}w܇?׸>sh;N{|۪[پ*|O=ok^~8=mj1 GDK_au+ra&6 Fa IWɚw![7׫_XJsjLsb+k|r[[*]$|e,c˸EJp#oh|8~m"/C؄ yz/ l"P+ D %,`5|ҨF>+[waS RVg6ڜ;Iܫr4 jC!J) ўjV49dJKgO|P!AidS$#+Y]ċL B!AGj|R7L`Xi ':0y7?̖JlxN3od@Js mO~ds\vme5Z |+?1c#=wPǫl<@$d}`Id)(MPMcmeT&TkhoJR=sڰYaTR QWYFY؋ W:TCj̱pPZpҜ=x| ͠% <&cbYйul%hK~98J3y{u-1--cX{ԯ L7p)F]a{ ʑGD&ʓd $La;> .Dp Dۑ1i f OB9 @H6%\=݉^\z PP[ ;q@:ƒ_H$c˥yQ([PE1PP(|&Pn_ {y!"9'%(Rχƣ-k @MI8RCW} 8 LL{Zϫ@hÚ'D*9O&p)\Sjl-Ϡk$Sal$(Aoa+= e0=!jCz;EИ0L!%j^QZ@2E—y%pfmQ5/~b01*Nk&[O)-Fxbve|!f4qF6Um0JtZ`Tȏ8 %]41BϳjJiu V,(QZ,A:A(RJ7}km %^cNfFø , Cy]֫}n>'&gx*+A>šV=u\Re@)gQs_RE)Y>G ("Qޅ5pLcsߚ*E)(#V!pf`xDd, *}^Ջc唄-:ȶǨ (;O:,H"eULf6"͒tvwU9B;kQ&W RYYʫx]Cd6WPZ,eE3- d(~2^Zk0Ÿ?;=ɵiJʪH=KŬay0߮H;oaIO̳H ,Ma+QΕKZuGv>K:!˓4F1&D8,l- ˒XqִU1zG.O-!8t c>6oj'dG *Glj\N,?e"괤4;ʅ =8! ̵1|~j*#Lta^VlBSy'37_KsUTE9N1R\!XVC]99M4GdG9M:|m5:ʴ'IrNBe#+,Gp϶%J:xcGRh'G+$wrv2"9jcۺ6B^xe T&cF)-U\;ή71mAnjkCxKʩ.1xMLbz=īk iνǦE8SʺFf/dƍԕ\Gx RܵK3hS0z0om^g{q5c˝kEPN^0 :vc+h+e~$}tHTTA'MDZ3$7QaO7ʫgmmi#$w_pjZ*B |Ͼ1+J2&)yG"LD~Gᆢ*rYWN-ib8ȗNp߆&w Tj|yWM6Xca If"Ͽ*Ly)PXq?Wl+3˴?yJ@13>@GSx˥FccL%ѐ }vgs.\ŋ9w" AX]zT.:\c"EBxd:b*g/\ Q RNjo'ڥ\dhh!@„詹7pto͟M&.N8r"}}\:{S]#6H~/pv<2߲u3,t .Ϗ04K9v&6mmAzR(/)xHpyzm<uuuĂA Ld%5$"Q39ɥz*ޝ1HԶPJnb4%ulXD L8P pe RVUCme{ `y㴭ZI]"?ZAۊFG2TQ^ZJ<&^^A"{mDIDYe8zCR*VR!9:XZSʦJBx}]'ki"ꕨ$N/o ˩. c!jk zy㴶ju;%#؞(-+WPѶN3?U~#&f(Fe>uM-T&k(-M͍r%9!Jb>`9.Q4FY"!&ZjL 3T5Xf ZjK vrkgRZYOME+VPQ 04Zʆ "rVlkM?ѾDȇaF.pǖ L@IfT4! 83ӤEukWRCtUՔ//e}! 3ϱ9v,ϜrW7W/sy&W?Nom m]HK~4Ϟ䮻v.T`f<!ҺOw;3~{<.σ}mUx%Ʈˊ|x`]5-\^B㸚ߢt{>+|̈́ 5~Ii_|SC/]O~-aɮѿ NZ6r{SM @B /|??^_6e $͗~pWIYw6s5'.Ūr`YcccpbʂM ݾ-Z@.YΞK}׽i Ϲ W mu l(ƶX@av@<'DZl6xxw :6rp0|=yTT>;k1=6|`Yr /QWc9Jx fi Pd ~r-Es{w3Q7 g"ɠDql Gx=7/T*r/X?寮o?Hh~~V&z$*>~<;?Q: ^]wC r)F4=Q闾|ԭȯF3Lfwʿ%nRn\}%Ãlkjf/(WÖL,lx.TD_1xP؎w/0iG?Wٰ\:Q`u5mx~߱4h$73Ĺ _\f2?s ^+Y]'ùgR6zQC(G-HH.&*&łyuaqfR"Ax?5^=ra> JvY3Hc|(K]TBrW@hg1HRh-\b4| =g&}kyDM%nַ^Oʵ\c,UCeb178hDM\@Z"6\KXح Β OҽR)nȒmq izrXʋ؃yB̑u(~ ib S̈[j1ĜBe)@q eAHn~qtf R-%u()-K4Eb*Ƚʷlk5jngVaH:T\Q7X}[cn8p;đBJd!G)5KTNaBQ#2(0e{Uxf!l?;#uCCO oCx%ٺy{.&fp`e&8yhYQ,$.Dgس U7)\N$O rގOh\Yv%/s0YhYy莕e "l./ ԥ&[O0l )BW&RZMEcg: "lX(FPҰ7.,da߿?:Regv)YJ'ˌ|ܰq(NvΫ\!4ZC[mP'92PŠ>Z v@f aټi Q=NSն +jIBda|:%4S A{_@˯VkIu̇~™sWH{ؼuA!4~Ξpڭј׺(,RbrkhM;۷!h sx1&|5ܵc3~Ǟ"SU^Gse2FEUCIgC0 dYpؕh+/+\K@?,G. ɦ9X)V7^}*y^=|r?E&Օ$/_6g,.?o<:&Nwȟ}>tt{:G'AJ^}cY S0pU1u>ɢ(mдaV~k'خ78= o~~=_CC;Յ||{dG5߳GT?RO?>cW0p#)ɪ^2niEhǺV+˱1M腛Bkp)ʓΧ PKwUKx(ĂPln\Kp. |>/Gi70Ά9Vt:M&òm,ry2YkS+W9[މ~FH'˵n^Ko>bs;}zd}Krm*sas` Ǟ.zyS=gxeQj* E^fOq Q^k=D)4=^/T4G_?i!`gINo\NQYpFg!}:VT'8zKqQ**&ٷ(yLy^ziOڪF.>̫ONb˩* qe|/21 Ag?h%byc)n~w͟᳌stxveNR]]A4giNBgtsUl= __JͷpHd'O>g(.% z/\L2d}MkEkz#(Ʃ-O_߇!j ' p#-N:XּESka0Lb"0}}H3wL;AI@Vp?WgXYip~K^o?Gei3!cbm JA]|5q[ yDWsε&_<̦s[txNq0iYRGs4ei^Oyts >ƹ:;X}{+}OpR/߂[@>MO8ml_žr8uIRZ[ty1,e$Ȧ"LVB^Aʐͧp;!K3*w 5 O&O!kA Z/zNp {7?:9#c qn~vFiO+7`H̡ܤµ||>W6 Ac< e|Vmт`y3︓)j(]ic93lġ2~E2>浍ڶ*B'^'ٺchix6<6vNP߿xkSS5::dž{vBB_R3|4]}i<!1CxV*n#r` @e`Ek+ 煗^' ׯCklg񠈩Q&?hhZM,0}TQr'h Fb햝/s*zTCym#U%~m磽#KHd)N {yC;)[Ie6~w?#^|e7wk!">%>2EMYI,EOp(wܗ Gi< !dm1]GA#=Bd[k|Ac$"% ?ñcg4o1GzA^B:KJIxB9ysv†K"<~~\b 8obS[WN14- p(הHG" P!$PX :ťS|'>mAVj9,}t+O֬woy@}}#Ol'+юi/ehRd󳵏>(>Q¶{7sw 'VRAeZ ÃQHaAG 1VÔAn%^ӳ(F :0R&7庝Zy .y#L01sY2$az<ș2HÃ,D٨m( ! m,y# mz)O$#-K_(DAJA$^B,da٠`7dp(W]O ggfoVlⷿJP8 !}F1`<>? CK$[^)rx CiuSM r\) Pf79|gΐ?Fg86^B!IzSٸ-W(G MӜvh"ZXYQHO F"S ѝl1Dî~.9o?AS=9;{g}]eNkMb=~7jdf7^ͶM3g9t؂5.TsJeIG-@l vXm3Fu&Vx8:&랁Trܼ<gvIrc4)  O#(u5qzO3")7D)-ZHZ58~^b,XG>zcY'GG}ɱIgf&m-Lp,a&@B۪@BJ/&3 x9]xk7 d'Fɠ\F&h,yM !>\aK/ra(~>>A=rF*jKFkapt [Qy\ȁ34mIK‡cfzjU.0 0#V)*.v%3空vr.,*ŀb܂ Ј@5 Q"cira7\VFKL;`HGR߼YXc<ִy/ެaJ̾BiY[7xJ8){a! 7ǡ]gI*!9IXWN$3^[P0PFgW.!gǯ #ܾ} uZs,Ici x-nkޗ9?dZ].L\ $ֺ:X:ݹrf{ʏ)\4RbD/&ʰmlXKLglJl±Z+xQh]qQhNC)iH!0HP&Px8)4l]$Yy iz1M"n)dUǃ6ټ1KĚO< 2)f׋/sw5v6f05 1IggɸU+!c =/:%Yp {3-UYb%x_;fb#dڍwpM'yU8s].Si;+"/1]ö5 dSy}ejnJ{U `5%tT;=zXWT %Ư╃'Hi_@}u)S!0w)6^.Þi#ATy8rX;ޘ`ƍ%}= M0Zwn"-N%%5l\J+2@-llkx)&d TĂ,b*=ӒA@ @0iz6hio'(m垻6h3 x%--'􂓦{U[h.g,bbAsK5hRc}LYʨ&(OPVZFMu%լR:ʠy-oj#5W#cX*{>*BUPZ_~4R+, 21KVVPZҒrV[KsEG mlNܿK~ S]WJn|IfRyZp5D<o(Amm%є6#*S ZĪ*IUPW[KCC>4n~50j*iBUaJJVTRŜ;K)]Bh|s>{9G]&:k[ r|_ʚқ2L !Hvsh>Nwtq+.re{z DdxV&!q=E ^NWD@i7o w"e#ԬJJ8ƻOrf@SUDJCTA.?ϥWtNJ2j@x3 a1&^S^!LLʂ7Mkixm - tE p]zуx<^ í#dH-(2 Cnc{ek$(Ǯq JZW!R0g)ߋVvnۼciffh=;ヒֲýL4R^]MIagR++(gU Sr=jJD 6m%(3Hش NR^RNYF9YR4Jz"Ҳrjc  5Deq|USSUA̧8^z}?|]‹`@EYr^`$%S^SM,྇q5 ʪguԗ Jٶe-xu3֮ (ef6kzn]êCMZCl*l5%Py oR@k]9";NEJ!&@MY U&TwXfZbA;6hk)g/uu-ֹ lŤ]~Ka+ֻ"f2L]GU(֘;[HXpQb| 43](T(lJ9("B> .=(P[Řb*$ˢ@֫bBܼ]:©7/1s;-bllyVf}?|?9XIstp-cQ1rSd/?MOSr\ ]_KC{NӴq1.g?Ŗ c95Vv]u(,ks#lXQ)]Kґ;WC4 û蠙cP7%~^y[vNqXa%Avv '9?lr 1Ttn7_݋z'ۚK&, i~2?]X?Q󺐟`vOsE+;Oso 9H͆B_.W eńJY]8±-mM\xy{Bﳹ:0+oIiμbƮ]̋W|yܶP {i@S\/[=|Vk[1)a{+=, xs^l hh)A"vZ)nSk,mV\qkLc9FK͛*GNF9K}g[)Ĝov9p}(~f^pucѵ/z9):7)+io FMm^]v4Vdb*~P 4n㬿.F=! ;9-I\m&T{*6R]E*aԶQ+ꩽ6PLJ>W6Br{aX- ?3JO4wE@%rUI՜,hxܼE <R`'_o75j͊j*W5Wʚx5 BZ)r \rRUoU?,u|9JS=>l\]R)1=kD͒Y͹6Hn}+??d<?} ^ Q7X2 ! eKjPAr>YF; qC,5gHS$Si UHFi˒\f,V.K2"g-ڠt*I2uM.QB*$Ur)]t*L;(&{!'J]+-J=۶QJeH&Sd\̌]cHCg;`>&LԵ UZB&i%2c[ %nDtx"པL_{ ZaʤSڬd*!V>O6F+433)r3{@ !IώV6qu!笹ZZAeieHgm)߳\xB>2Ǒ^ЅkON2s]i|A2O e,cx I-)~@uYҐ8IΜ}] ~S"pĩ>!q2S={*0q7G{u'k{Q5 tdV'GUC_x]otQԕ#,7ɇ F'%O>F]X29p{3haS9.^ {}8x6SVwݗ9~}~cVL \bg/ b=k8 :U{:2}G;[a#'cIZ7nc]cš}혠}%r:7'g}} bbx]gm1T>V{h&%U:LnM- &cP_F]>ə~osIS+M~-ws'/mqc}\f|rҾ zAZK$WrmQF&5oM\<Eރҏ8[^M}C"dO tuie,cB+&j .~~u%s(5ܳ.*/QO&$L:gN7@ Fxl deӐ y(cuϳF4)L]l{؋׀Sz{;]Q7iOr{KFh_^ <'y$u=BzxCLՆWq_pC/1V#cCƉ ۹}=4ۯ<Nj+h̙A3x?x"}^47Pi&ȌMR<^lae,݇ Rl ћ_VnonI*'e,clPN kJI59ER[\>NO 1kΗ>Zz1MO0[f# ?-+u-[nk@(v\Amuv$MWjYSJk}njPkf9w^mDImm U~L| h6VWϋi~JK**}}n!yx=:ښЬho&Sak#gK\2@~Ң@ IqQ0'u˺Kc y6r!ţu#u Ud2tMQr(o^GE3Hx}>L{ rZZY~3D] l+3xŝFKԃmټo87mE=Q۩0Q+$Ԍ]Wt] <<ˊ TZ9=峧 5BVʞnaC>6=)zƾ/$`NrfRLmReG{*kugso^DaL1#%bz'qFYxa܊gX>geLh觟`O?K:?>&&r}BzuV 0cN ;̲:}N<==3=9# HD%?[,KזLJ$@DsΡscN3=A p<ޡvګjZ]YNB2|=#2Dyi^]~xx돭c5 jIҲ"^7PU/24?V\V\ۙ~ ( B3$6lʊ"bfsy 楘HplI[|vm;ޤq0Q8]¤'zuǃMO֭ i;9Thhê[+ 1[/psi88R\pK{d;1 J5Z3|0X9NZf~icnU ȉΝ;K߸1 ڶ=U0b8@lFb$R:i$I9;# i~7d*eѬ2HS._f,1 ;t} tv]ufήӍuݲ,> YymS9P挵CY|p,19ŚBH84D͊ TG/c`d&JUT`~F&ckwmX5'-P/۶+Ti~8{/XF"Ѥq0f88#6G8s"i_lgMC.p9jQ4T0#II[yGq\3͜>}IESGfb|h҄L,G"Q\v+9timHzpڅhI;n: _VJ_86nnd#ǚz׳fLzars 9|-[Ҽ\@f 6vs@m<~zFլSOΑ tvqbmӯr˜:DZDqR28aN2eq2cI a#seq'^ />EgO7>RZB3oo["7_:?z ηvȅfFqGF,s(;×iK3UG[G cM wq͔NSnWOVt2PXY~÷9BL0_ypi̮nbLZ>18CONV+m$}"V 8v CΟ>9y4;*p~h&s!J']j_9i&9{8^c$IN^A:EXI9&LJSIzoZ^{=;3]URd-Y|`8$'zwfN?Ic0J(?;}Hm(p1!$ܽ(C}\>w Yٰ|泧я%4dPJˉC<݊*524i_DA$U`1~{N=b PU]ϙ쑃=FBQRXDnn &)*!lM08!YPSA{e"gѢ"إ>d-gQN=DlXQO.̥q|"})bT.09~C1*ʊzUbcmE)(c${_$턩RttN_Tew+:{92F^Q%5z.w15TPqFnm-9Npq[:1Xv3+k d4Sb%#M%@* \wEE.aQ5zj֦f[iiiw_{+aqToɳ&UP]YBqa as9}IKlA B2S&lN*>*-Á}h PXPOi?{/1Q P^U̩t QyTVLv.NwL(Z@mic}MaE *)#4jSRZNY.tS԰aY%MIl²Aq$yXP!dןO>G5rHaDnw__ ~.ۖucwSҜgQtʹ??'#🦎ܱ zM6}WՇP@4|]|3<?=~竬, ^,<_?͂wmea_~r~KqXuQ.2l_(@vǑӍ:yqn_U/i˷y}I5'#F>êfcMGB4'ɱq UU2_^_bnހ8䩿 .+| Nl":6.-0Y]$0zy/_ms=x3?js?$"3~نaCEE㶙"K`92 d&O%77OW&Lx*Rн䄂D E' Qsps)l4P(&IE' hiH9 `N0$i$\" 4lHHhB!n%$`0'-^MEJI$ PDbgA+'4@3up-S"drac1RD phK(!^a9 l[V I2'e:('f"k<[m޹t.`& vb-oدz<lD4HL )(Q\ˣa`BQp z FzTqS!|V:I,DJWp )=trR 5LL@0Hf)$SUTEJ$1l$tqo(Bar|F*A6RJ#x4EH/ѯR["%7J œOYq1Ņ>$救 UU<@ n]rv>^ E[̶\ʹ4b&xɚ>B%ON$L""e%|Fނ:瞙1#L_9fa3rX^u~ZkUz Q"Bdx3fY%77g dn@8u _ 2>ɛ[??Wa|4" ̺oSyԀ[:H)Q=~"3.C:9djxf}Eu59`U%A@NwB Üof-Imb,|0kdBX 7@$pw]I"4a%(@⤓6>J(?ODz. ÌǑݧ#aKHn8f< A ]O"|4}F"H)QtN2p>"g)BսEZDc tQ P8n Ekm<b1ф% BQo9PT܄6t3Me9{5N)vJv-y-g/5y,(fnڴJD P8=Aa{v')›+#Y=)]RBp+] Օ 6=:#PUӻO15{f\1W^@1UT9c [ܿ?x}:~ehBIG%QJ>^wys+pQJKJrB>$Z<cUəc,2GǑ:Js<§VzsXl5^l% ߿0xf)ُIصeXB#bFh$%5 KVBl2xѬQ4|\:SYЩ[:g{N_w,%葳QIr%w>ƭ;pV&ٵ3Aђ-T7GHF(HA' б0%-]$$)( {3 O wlIɽ;<^w鸓m2Lsm[0bx/1̗<//>P}|}xְF#x޵tdO#gZAzi`Ãb =p Ξ8Ng*'7kI1d7;|1=:`5m_>Xa.7wS![_z.? e3bC>|Ђ<~[ZҀiRND,'D0?|MlYNR!P&i:uc ٕևJ) {tY|B Ca:D> qs!T !X$7@Qެl$)hՋRi٠h^}z c\Aʹ9BQ*!6]2ea:Ӕ 2ݸmU6ؕd_ma۶0-ßI-u˒^/4iH<>?+IJT"A(F*i/@S$&6Qtr]M}-҆[iDսx<EQ{Ƒ*MFkq<nc9pyQ{ﻋE&/9޻cr^z$[rMY$RIR}GjYө(щ/5hn}J 'H\|E.{-zZ[I ) аp~>J!>sl3IcneHOQritrT&IH .P0Gsvwo'G73K!yg8H!l%׾Bg7i>rnywJn3R9Ld3K6ne>|v!O|a=\naMu-jr~ 7mb˚:Kܾ'l/0Q2oجXZGIvqm 'y0tqF7ƆPƥG/a9t*Jse\OEXgB++]MnfI?_}Mw=,]&oHFeGD,tk ItC:h>ʊtM{6M촁*#="Yj.sUkQ\6))l&{jM{=:"'2ztTt Q4}5Ʋ4tyfm٠̞_\Q<=Di;6]:dtkBb) [%A,F*]:n~;(2a͇_cWW>_=T6w0h砤ygoa-OomimS` ?- QI7_pkis zJ"o , I^]x~-r+Þ-wx} y- .ͳ'O]_#Q>g]!od$z/Oob=enGݥQlqwHG||/z4Eڙr P )?q'H0bt(5C$ic<Q)[VSnErl"8{*{l aM'b1Q!!S=v`1B1 Rr$_gtKD"$\ƃyow=A.J^eJsd>;{]d7ʑG(؎>yzt*6YP]IA:K=6![Lpo_ǹmBor"7>၇PT u/8C ܅xS[U[?r+:{(x|>TH.e,()+a2ך')>Ӓx>z]&h+a9]6,96Th|j#09uP\ÙhaYt@3m)b_:X8,.ax4U3ΝG l=[QO"<:{OWU.i@8 vc..Eq-̺MxꝿP >;F, 7,(p( e˨&2}ADrXfZmz}YYNyEo мxo{p E!ov&{ TVaz n3iB/|cӑ+e٢᳜kpM H]9ܲŘ`tLTtA:+u5B(:9vb{GqN al oy>,qXe_Lb*Bjva~%!  SYU Z.@ PcsL#QFj`tL$1ZwUG+hn]15HyUP8,n~9{]3/]JvplgT490y1 JL;>p,9ڛtIDAT.əMll ɛ0lht׋>7`ad< )5wYn6PR{?yGxq&W߾˓$o7,,?m8S //<*,xKH!f(差;˒%~Q^u)g@Qދjn^Jn8@d0a* 6Daz' Wǎ%nDSV2IZYx#moDO)ܲ23b`w%Vc!@/ H ˙`ƆKZ`h_Ꮌ~7KؙR3JLPSSF^nz+o>XE02WHT?O/Jc$6;G bNazcLgY/}Sm@O<`2L9UUSRE#od#w&Pt%yNNejSK 넂i3 EF4TM 9\uTEEue A?ǧXf˖Wbnk`.ԧrgZ SGoEX$SilyrߪTca; <mP2$HƾSqb.FS1D_$[{33#v%)XH`7)$8PS@Q0݄BQ\LP&e+ޯRec[fJ&WN5w`>NwM{r/4iK! maп7/#%ʕܹ7{i-ݟZ673{39<୔_)q^W99Ih2VN)҆;K i14m3tqܹe0(#\Xɝw}[n_75԰vY5H%I'I&G?ygi8|#wSqIX~%y Nc$]W)i 6"(sYSȧ4/_!T޾*Y|TvUG鸄 Zh,z )4drnmtG( D)dIq]650qB8G&D4/U8 C )'qb3 cA4!1qLd@2cLP=~gT 7mv*f$"m:cmL8 o5J^}?]\ė9pW^Fs&2+:f8jQ~j<0\OM,,eaY :.s8[cۦtM'|²BZk]+{]V Ipa4~ō;AA4ׇ{(A2lbz&VIض@ 98za촉uC(u q=4,¶m\Ge'jhmQTT U<>5Ыkp0m: 1=EJSχף6$Rūΰ*V:{Qt/~ H>{O'2g,~*{r!]UQu>g&m4A`Y6}?Σ޹na˭U9|p=}#ܲy uy s:_ţRo|jadݿ/pjNXRRHhn;BShj6@6&Q>P$cM4I]m=gwd"c~ K1'{6F$C{s#х4ү{4/Lp#F WB#+n-ts]x5=+ !n4ncOSTdpmJrO3aSX^Ţ: Cs !yM\Sd̷dLrpٶ-vjF͆{nv>)p =-/N(4+ñݼSsM4C &BNO.}<(e;.STlϾ>VʕC߶Rdƀ3oZ`%kñ3ǪTDLrJ9Y|29e ,u22ΜݱmLuUUQds ˩;7catPYQQW%~[>7u*g.DzplIAU W/f!Ǯv9 yo:zzgsWW$⊺NsKe6\RM`|sRdi&#,\X`[wj.9߲lDF2kFwmKꒇi2zsRLA^sdbߧ :aʍ}z~Pθ4CLqMsY|$y:7\M2 ,f7j*2ZW%5sfNJ_ŘhWTHմT3;޲A+j9}X3SeciY4P4p E&9Nz>ο.zo$qc[R/W9TI׬ٻ]gWҹkW˜unW-x_y-Y^UG1ϼs4y!3d͂Fb>d?tmrL,: >:w*MKd2XD'#^q"3nm,>;AөtQХ,{`Y|\!\W1M4U)W|8Ov_=.ݞ*f=D_c&t#.3o6t]>a gʧu44u%XTOH LJ1-ǥ,xɑ TTWw ?9鹳(==\BE5 `wf0WXa|-~Fc)lF()."Q}31Ȏ0|=~=ѷKj ,붕ij$=wpR޳f$d7L,cfd" GW)-ūfOH'u-Vc !н~4̸*",~q릗Y|$ P@'(,nb$KMoƖ Orhjqw߹iRj7,6q 7͟E@4-p~Сr 5dyYŤx#eXZ͡ހr+aG|CvUP^D_XX*`Y_>?5{ҶE$G{Ax7*]1tQ z,>*]HRu%֕EYdqCi^E$%YڰugnLi:Ƴ?~WQjx3+%VhZ%Q˼q}ٰ 1)-j&%;R 4]N+? ^&|_(xT eo BwXr,YZGaD-]wc3CkypYM&Q,șWnX" KfRDݸk Yǥ*]YdE7 w8μ#BQ3BS|+_xl^*o#gf] _9-~+.WizTeU* 0}-T&8 e Q&%8#3Uih̹n=\6mT\eb?i=ϵ Ww}jJ#K)DQ>],TO%{dAŸ++䦄88-#Hr*%cߴU6efa6yxouPPuq% ܱ.t֋iu;EΤđ %7i˼x8wo`Uh?m]L-dR+flv'bLFD*fY%'wӯ3iT ooŚhh…X2["%~D@~-+SBڌwN_ QKͬo(qLFZȩYýwl "$$&hkal2J4nR\UeabL,L#Ņ NqZƽl^JI.~upyt|yN2Ng8$'kVQѼe0>Kh*Hlp 5'`jN+k*DI|t`+A>b(P6.ʧ.v)V\ؿ]_㡵8Fs,/U9vr<" /Rjeq<kJ:[`r2)gDTƳKhA #2@jܶNMLGO?Cx ui'3tW<!tQ.A0ĶLLGTlP"C 4{2Txo0W#\:{d!^ILvXnj#Mi{Wq 7raϡg% !\f(n&N:MS3_9ܧ)sY_ ,F[ܻ}{ƫ/ D,Mm 1zU^ymvϾG>H~n ./LhEt?<?u!ɑ6~ÿ=Iʏ0 Hu7"1/N۸ȳ?~v v|/Ɏ 4oS] J*/ Rmy%D'o x|Spy(l#IO?Yi;1wc}2{XQcrl;Ӷfj j:đW~ěgzh;SxAh#?ͣ&.yٶ};[=$sC'Hڠzs&CXj)@`rtH_ҞxuERr.#mH0#y 7X_1 C迨Ab2o<(^mwƅDGNCHJPX;ݣI@`'8<ۜ'K0u)o: 4gv;':qT/bxY8ًWx뚠5A'vS`s4Blv'ݶO*F,m3~_@FSU/{f(f<> 7iISL tJO$~AF&87EKIb{w+;ٻo?w,PB!vb$=w~țzJr१s7͌^(ަSst(eq]SZC S GCUĜF Q8>n{1eR"ՎL{c"#zkњ;\M))PA_"=ũw1tih,6Tpl@8z2/@WRR\7-0QRǦ;6G8wOSmŁZ^@+-䥾$˗7(߇];tvb8+h94_H@AQ ^{0VFXAzr$ɔ@P# i`;&]S1k5/fRڤRI,t~'n57w0.%nxrϼë ⯲6r6nXKEă(/Z"Nƃz#Y=]?/IBm(E"?^;ԇD{ipbgͺkFz|tDFEć"ܼ#U;z&"U\w10Q&8v} 1j_ iwZ EUlct4sgxU`)X GOyWKcހ9F^U~-,-}$4CY|p(Zŋ(.(\ζ͛ub]4KW.fseW/4EES~ WQA l+`Z*rdp +W3MQ()kV|aɣa }ۧmǸe+W͜wqiB (^}/ʛVPwO9,JNM*սضmMؾ-4\ExVn'd!Ăx5[s& 93ĤbtrbV5LmhI*kȐu(+kYu1x뇻َE|uVsOd. EWh LlD[T37?Wؖk%-o0I= H uѕ0\UϪ?׃6f,m TTE" T $`vc9xu1J( 5>|geӝ"4i#Rܾ:_Pz-v- ,ǃGX C@jbGƖR ,Y\7wٺdMx,gR:@/* ETMA|RR ds{RJUܺi+[w,C5GOKT2A(2ɩw^iܽmcY6RQ˽<:®aP Dk[&a`Z;̓o J6+&&(Ԭ>_/QДN_+؏,XbO7{tHp4CeE۱fmė_˯˟̟˿+7}˲2%\tm~JJ;,‘S80M+3f,LsZ09p"ML*㞛/!pە&peO׏3ܾ6(heN5YiՅ!K(^<(;_RRcɦ{{Y}Cn]`xqÚPPTez݋h9R:HEGB!?:J4X.vc)j&"pLˍ,#-Tq1,L`M-J2|~A&L;BTiKI͏*f6n9_3w)q4 9ˣx:oml5 ˞oBy4gdXwK-ôfi >?]NV^~)e7؆<*&p,O^1ax?.\n3VW'Y=jP1PTcS;E'R`%B^3Ss#'Olcie*wmgܹI:[i쥿wC}~<&;QvTn'A0`nFPCT. p8(8rR\"oN>E0[zH: YBQ&WASB0yùܻm'0knPcҰXE9᷸*O~鲍|Itd^ ;zQQ]>b4VbD'Hl|+ASG9~n _(Zg\ S|[nEnoxt ʍXRE?k1 .’0̡}Ǡ9vo}N}@&)¥kX V:N{3NT$kxVgϝs(c[L0gH/'\3b~6..Etl=zq/~qnIMrAZYHEN]WG<HF\l#fؘF oφ&$M 4jZ/޻7K~g^ !W3K_^JXM/ڷ<$/PP`rbB Y?晟f }ccqBEgJ8&-'vÃCALFIy*X-w^a/@IMB<.EfF;^w|"DPanX1Mci00Dlr5L$ӄ-wpPT|eϼ29l+O>JJ g%=S5}QV瓡^tOl9텠Tpߣ鯿Ozo khXϑ,Kb>W05))btMP^`|hX@]%Zi8m8E2$W~X`0++äc?e9t0l' T,[F;yWTD4:HXr'&/,SơGta%(XffN <^/-c۶2lg@uET:XQm$ -qX$)P=tUu4mW!"mLA(3#11,EQ<6UdG$i8u!M;ilf wrzc˗i飷wZ{fEefj$aK,D X~=5ARc|5sȃwOtq׸!X;dq}3g1̂uwo!WLrgxu8^*<.)D{{^GA@I:.ȥnly5wOd#/1JKﮭTz 6LGwd~k|baaH!;ezd/a[.̙+:x!bJw?EnW_eV}9+LB`9{= ypbO&mgExRXBri;wx՝,Uj4 axx%<|:B@r\_&BI|(mcyls9̼6z]Q6n\}.f#̊Gݿ¸\ (m:G֪X]['O7=GQWrζ{baJ|/2v JCyRj 4_DdH^?q,oh`Ad?Igr&[`_lGCWx~|M㡷9fi ^%+?v 2>( &9msaa 6 + pa>g_uzA/oV.Pޗ85Ƕ[1xf/_r$G_AyNV7ᏵΩߺh/o:S-QSC7ya_ U+Q .֥cܹRyao7+lie9˥8XYu1~ie%G4ZfFF'H e%|*NDFxr^XCqÜ8߬II*C9rqh[7/%QRZ3dpQ'vXK)a o=ˊ*)%9('/32"TVSTZw#'7IJRw XPGsF4$oRj* :صk?-#6SZOiI!F#I\IEQ1&-CGbF9}N4 Y?2*iŹIr*Xy2(G&JXPVB8qcgژL$I'Aϫ~aZ{reܲb  o9㥸9HCQy) ǎХ1.:޹dEuX8|<=Ì%5*TS__\lgb2.(*>Z[\iXit"$(7.iHi0Qxt4Uu+<'^hHv(]uT%ѽ!LT: Bm1m=2$MEW^^k&i[BEWo"qcnnΦWD QU;s>Ƕ۷sbOAa'Wn{*;ㅃ,^kL3 ;.R~ DZx{pMU,_RO(ӯ$T(^\_* rn (Mdi^=D$/g^At?r% ۈsf38]y* c' ($.s}Ide4L欼& XN¡ d)ז T A KJ HT+M>?37ֳi۝._m˖ԡ &'rB7"Am}b/Sj/e w|Zz}83DJFqOoaq9ƞ#U"#,T/ϒ߯w{4MC HA!xYjFF&)+GMeW Q`.%y>jk#} Y|C ϫ`xs|T/yo((Z|+_F #4G|cU)r )SI@ K|[I/D^8(2YmɔC0 mI7PRG7δ iڨ^_DŧCe{3* G2^%e#)ӞzMPU4e.IuTkqCYEE]\ks,lKd\] «kQ {/ #wDQv(zpRn{Ue'Cuhdm[go뛋 UUdR R 2zr5Io;/#H ߏG#Fٚ$`$0knU8?Oҗ>Ò.'tb%+=у;Y[,+{T$h~*떱` nYU͟_ry(%čJ HU 8v *WdӱQF=,JUc:i+ĬI,v+ 2=Ʃg(^w1 @XmF+% \ߓ>EG)9YHD0EK20E] 8tOyd|*]e\GBnuC/19>8&ۿXÒt)#BQ"SQi:`Kȭ^c\?G%/24@w^%ȩyѳxAS[ SRW/Y{@:Hl&Yp%GuCm-Y`/΍94-BBqm~LvZ!"Aq8,aY(w- K< qvb8pʅٝ˅"p@^w,8]MCX"ajHSK]Z0s3nUʕ\>+k(|nN5pQ%J0O"D ܒJKg9N)`ҢlR⡠Ye j(U/Ǚȥ.?# SӐB)dEzz)*xv=2mr D}DLyn] -7`ۦOJzf%%xsY)DH96_eO^9 \JŦz%TY0TXQbMF䲜2ߐ'HEb+S6ة$v@+wrlTu-{X45Ķ xrVU.8ʕ$Br+stƖ)4_. *Q$FJ/cYav"if{:=Dh²,<59TfbLfc+UsES&(uaKMl|/U:6ϕT47P:鶝")n6*&wN#cBƚ8yy\&y.+r/oٯS:q'_OF9zXf+Q:KQe m=0 kfj|`nplx$'/s$?_0I:+eЕ9{DO^izj>Î=9TfLWQ 9K&;L~s_%~ϙ\qSBqcv(twf_/g]9(W]"q}f;fw=;<;Fr<] {sIET_L)~׀#uV<L}J{w.t нc,,@**?{9.c)HǞ]QT*Md6GZ;\viΆL9U+`fH4fԮ@u>-!Kk߮xR$^]ah^/^Loz.]™&PT .0nJLRiK94C !qB('8Ѵ1',@a^>M"ɐ)j7+nS=D93mrK*) &H(\o[so#Koˏbnbd3:ĨRŠU\2,5mc6RQ14j7|Vk.pߥIυsr,Zƥu})yA:/r` 1Kc^hЛyn]m46^`[)rL7R w2WsiePidaB{NM~7ُD5lMuNx`Sƻ8y5|/?S?Î.k#I[b}骕ܺbE^]gk?4H{eDZ3Ad:N8]wd86Cw'_UWarZ|g>NM4ubYÏ#\ -sh$dO#[c,ZOM9EW ؗT/gNZkDebIc)&5$7 >\p`ִwEg,&a`Ʊ=͠Jڛ7Lp{AT+<\E%c%ǥ񾆲!T߇*-R4 Ӏ`b,N#(. G!Ӱ2$*o*<^^v:E0?%]%Wx=t݃ף_;(Wㄢ+4m%\5K9?|i/=v4q\V4yGO摋 rԯ:o'7rT4_-5 PBN$B_WmC,m`:L)Zf&3VmM"I38<[N-Nt(_By0Wwp9@H6:G$ﺋe9(zR&;Л |"R$&8u(]X݌t>",Ҳm iHfJc0(ed-)Wp8{LQUp3Tp둱 UGկMn\̰ N[lm qP MUq,ô(hle,d*I="3EAQ]Kô2US&mXDU5CڤE00mɲ-ӭ Bė٘iәu&Q,´\VEa<H2L XihMҥS.3ɯzA%5%{.o00UUTVTRUaۚh!6,,@U~?sr'q±U"D%~}mq†e$-ƾs8b֐j Jz;vD;l%N\hg=Ü6,[<;;M(.o Oqw8<@B wsa pˊzO<Hc coT.G0}W<$!*XPUE]M!}W6Ops)A@dlI,)PUPnA_&"sX(#,HA!!k  4r f{?KCĦ]d&.(Mj,MGGm4_<7`8M2> mI<>?t5\FyA  91G'1Re6mp:#Ecl2rN?&,FNyzU!HL22:%NOHd|hȵt WOУ"Etd!7?7 v:Xӑh atC #1$j BAғC^$&$8ãL T4 бHR$b1RD49ư$19x \hoN!bhh!+ 7fhtK((." 4#L$|"ITu4MFFF=3kUvLh,KqeL 9"؆1m+)]ϛҍLβXNV~E\[&1Ӕ2[& \_EFٛ#]Jnb9)]HqZ9uȫXɔ8x|9i7ש/`CCTIFGFB.tl1w~/,$ǧ$&(s""}ѱFp.Ad'a''4cC O$Q=AJ cQ@ YuTQRk.?'4!CCL$m9y`F'fx`aP$91D"|d>i[&]_y౼UܰU#܄& UǕWfx s>iy.vsŴp @V!\_UBLOYzLj d؊5{D$8^̌wR Ȟ\7{\oY|!YhM8LҜ=N梅W/C"1g7tnYtw gqTRe`nc}d\>aUx/DQ@h m&oRblA0q4'WѮ++֫:mA88 1^gq:d杯XKfQ޳1S(*2Ciz؝Q7?vCedkF~9}<#(]rk 3W댝"qww卍+I*W^ww{V+zvfqPKq0 ])r4A;==瞿Beйjox_78Ky5U9{S"K1ookbΦ4|b",) ϥ2暂eH L4-P4<=OYdsF6l/9$jWz?,>plTp,ã)]L0Sn|\Bϸn} x';|vVV> i*P>K`*Ҝ;&O)ǯi>y1!+U㱓Q ]W R0f|fꍬ}h=$AtRAIq!;*(OT{v+9ȱ#')Y'0hmR[x21LO U,-Aٗ/5nmY҆,xѻ*]xJUCq.\2?Wq9|u`Ɗ!|APɯZ&c=Q1z\Yt ][ߜM=[y\l;ウ d(9pv8pEWh^W)|#*!uZ.K4t2siK(iYݳħhe{vrY2dQnٴ|e٠س6QNLL)k%& 2C>+L:KqfVTS*F8jy%~ͽ O? pExqћSĦ!W<'=^V4MC>U8rWY׏3%2tS 3zkkvU2uIs)gADXY dR/f1NSO'%)$B=7t" WMt0O|9"!O N{ߵt,{,\QC۩Iz RJMEh+vmdN;擗E/?BJFL,]0 %5KK{V+( yBX4Ee4rI k؝ԅIEiooop~1(oFnB߲<xGWְ$׍r,L(}57aQ^%5Ec0Cɒu莉-a!K. xBec(EEU`J/ϴ >:FpR\<}y:Ahyl} >e](l+I_[}D-򅋨,ģdO['#ϥ~b < ZHJYQW칳jݺ|?d"(&O5TG-deA֬_IDMD EU,( #^FS* :,[͒KIZExH/]$i<ՔANq5'N2\NU]q˻OfpHL 1H^RJ':=)nFkبݏX" `hp~HZ.χ *zu>! dddɄw14瘪Na?pHFhw%IY|(0뎳AA&UTjB|91򃰭 ԛO߲0'E|b>.DZ {S4DH9:OaOrgy`+9ן/} &.~'{M=1.ɫtM( 9Ϟ~#":ք6HK?DBhvS;|I.gHg"BrןiB!>O?6&)z'PǞd+Li4plD ^z"1 :"ǑW|3B8d9A ft5/0tMZײ$WLr|..ź8tص$ 5DIaNrBK,tOަe$m龰o_^w!~o}ۼ0'NСLb\83] sSgN)m 'љȓ2wz8%]<ǹii.ABQ,¥8ux?=Bvܶ%Dնxޕt}FHCW^EAK,%.jqܸ0ܿHtYcnc%S}MZ؜c +p+:GUu)Ô-[e+;Ό6^M{Go(wI,_ 5u$5 %AlCb0"S?2]kXt"Lv5?cySy\UKrhifӒbLZ85n9(ogjR)=@ pX(i!2~C'H9 :2M2RGOD UuHJh;<@->U5Oo.XTz&HN6rrq( Ղ viv'Nb_}!{S[oe4r,ёioQe>^=[8 wbC8<ч).@WQ^.MC'XVצ`U%Ŋ%dvmiJ&HK .^ !y_ovtN4354 umTّDq Jb/nu)]Bb9z^8[G?).4̳/1+/▾Ry{C}uA$>Ǟg7t6UcE$ֱXK(0RS޿Cl=OˠΖ>? U!9OEᮕ~<7DC q_…_g_4'7Il%TOEXF4Tx>T|A-:ڿjg$cNd'ֲ4es{95Y]oA;܂DKE1dƄLs ufVV.@>YfEc( 2cxۅXSc:BuSSW_qgy\.NE1(p (&4& BQܰ=?_*=[aR E((Y'L"b%u}|" tDN;4h41S>7t[o'e!bqqćiniM.6!u0Pٝ8vE]0J^^> EafwpX ;FǥKL[.DnGڍiCMp(Ο'BPThEZSl~v>5,XP^;JHc`[\% BBk.R6oj'|&/wnUk u00H Eh,}nKX8:rl o|n*2DP dx XsB.㑏-+xoEh9s(7+6n;y7N!$\l o]daH{/_[_goaNMi@v j6P.-T64PSӎfixڴUYزĜ1ϴu ]̚*]E{4|TAcq.HIjwz؄С5+kC*A2+kSN3%W 0+ϔEL/oaXs+M5gޢ/ea09we B,#{ R[d XZGCGЫxh)賻+^F g_ɉ~~'[ŵ+D6 cC3gK|/3a$B9vG08@f}u]#d !ugyy jAdH|+9f5%H|ܟ|m/ $%KzێJkfE3JKhQYe+7p%IbɼbADz[iCOG%! %242&Aib62wwBbc[33չ26$S:h&Ƽ n:N<{`ω@)Iz`1RtX0tsݑ3}bHTJLu[\ᚙ%s:1=W/+1g.1O&'83eVUe",]\ASYNՂ^4tE͓EL~?>B PP pPb#>%+-ׯ,w_0|-h?{CHY榢yäa:Kx?4&Nd pY~ 9r(Z@ l[WS)`dl߾﷞#OqbZ!uqZb6l+9xLr+ְZ:s+$G/7b+(f ⟝* $IW~nV'x}D=ܱ5BkK3ę6-[Qe9#=pVEg|Km!uE.|0ش HW3[z7cu]1t&1H8o1+|w.wgù#tklHܠdI#E,) $Ա\IPYZuZϚR3DOEt=NnCMm'H&.qBqMGZ},ml"ET|΋g+g^`TnVe] tF{;f*ǖW5xd\LO̥Bq6<+<[SΧ^_@oBNTX\Ûc-fn;yn!@HśOcE1 oeI)S /ȇV,W_9SEswC{8uRĢq^?vjqFd'X"/S8o?~3SG#;:s 3#w\/0xx'O?B` X>+xo[]ͦd,e&) ]`\T-]{靈_E!(})ٞ"2abl"FۍbK1<[T_gͺ "2p5aiRزA <~pV0P\{os_HM!Wzf&ľ$Wr۶e 啼>i֥y8DՒGy~i!>H&NoftCOHnV64aM9QvcElT)اjxIF~Y%^DJh?}լ&`{ !HEF8wٶay.՜[k̒Tl_ఏ{ᅰB-I&B)-%ϱ0]eԹk$7c)f%h͜n`_XQYfeI'R^RC}qF"n'ltQ)U( Bf_G8y , MkF|Z/69/ _x$bdl]:m^O|癷Oc'xg_~h;:/jAWmDWu=A"6̫?퟾+UXmC A4O=:6Tfrl!_~T[%^{81\`6 y9>@w$G.3컯jno~ w̷C>َZo}?#]ٕg z4=:^G?6;L 0?&g {hj9Wy(RHzNw~q; R( r*V4i}^|m&Ŭ\ogI:]ʡN*X97'KST7R_课W~ĢJμ#LBWpa$&zN|?PVp{|0ŁeAU%Սذv%E~|)&F8˿|<[ɳ_~Oh,@Q{Wգ$J|0.}@`q;8Y]꾮6liLѳJ[n|DJ#`ϳo!̶5RRz%m\l޶ I_)nJ;GPK OaNVlHo-ay})/dl-urڿȱn[J,éYfT`IkqVQ 46`-n:!hL~b39Fic>U976ž=.F4ŪMYbjWϼε8n\˱PN3'v㗽g|?2Gg?YڻGpXv999n/*9u"KUoO; iM!q}VyLLS4~!dB nc7Ao9n)ɁKMy-YRJ)vvÖdFPLLJˁE6r~8GFidc9NqRbV{xmiFSmvÁ%k2ibx3wpScN&R@J;U3՘mbWI@mHIAeT7f SnZSͬV*V6ad|41l4V\z,3XXVS‹Ւ+z*N2=NJ+%lu(X<7+d,B$"d.X}7k3A)Jk2 FA XÂaQ6˷f4XÅUɴK=Ȫ-Ԓi.H)mǖeU'Rb+ba +fR&DN5Ӹ&v7qZIb,CtSV5 DO\I2&@lVd*!AG.l+U…;r݈lb`ՎjDio9Kg& P)~{yd6xynOEpڰ']lv_N6H6evj\bx&0Pݚܵ=ī_ 1;Wbڮ[}߶=~:y3et3o^Xp{<>VmaS$/XsJپqY9ډvY` J5ax-]rs漋\! Zs!]LS$Tq2dtb\.%p"Mk@ϞM~7c SgMu.e.$Vl~NUt)u]g'M'diJiNio1Vn[I͕s2u] Sqw"m2$n\9+ Ԝ((Lu<\xƗFҏ>}~ la%iZg Fd|]"si3Q2KCv9s*6<,ZFC^ZhsΗY3+3Fr)[&g7];g\^^cF;\.g)-1ݥ6?Mu(FZtjSxjXZ; +͆J.[%NƦ󻬢 1c~g] <#T"_~zxn0u## RtE`Nu9 CͦACO5Қ>LMG OM~[M_8o I4 M #P2ʜrKZ 6l̟nCJk4bzID#ΌTDw'CS39٦(HHOsE=u+pf;p|bꭐFӮ>MY_oHՕ_?KBFZCjܪ - %pypc!^y]0FmP{ܺ~5~> G:FHk:]c 0  !:3#,YbQ%4_hL$"3ym-i9( u qskGzٻ[(q)/Dv[$HE -D&8w~oT_EͨeBK%$ݞd[J+/^\ 1:F7=%c:Τ{?|F&BVrg82io &b&+L'VJj FO 2Nk)&Fǘ&qWd + Gu8caSht&HN;Iu8-6?'b. <*VTsIUU!=ʥ%ʷ2ctM ٶ8jYo=KNt:8Cas'䷏Ri\KXCZYaIC VzU=.bSVLb`pQٴb7F:JgX M ՂP%^ЌfB[ÆL'Id1DEeqbQ$dmF9ΏT *z&71f*.VA2#y +ܗȐ*Y^WP-XTEt:F]%B,BN ?Ȋ". o&St.0/~a4]#oMc^^inJKLurb.:(Y[q 4ݜ:o5(0͂B{_xn]#@'{_{gC`IMŹSyK/-_r;7Q≱?xJòZx/((!m]p}V# ?=W`o&Cb^y͛ucش($ԎRIDAT XTCYƻ' ; PZu"И3믿Aۈ՛(yQy79zaKsnš+)-(opݷxD+# ,ga(o9,Ƨ$:ﻅR}(zV7#bcyyiZ*Ksh9IoD.t>™ ? KtW gj ;)\e5TX8p{634:N_w?Rr\74LMm;$+gZ"PY!)1t =lyRpӓZ1(E`5@CAg̾ CAHM[0U-&ə]J-FG`ZF"bXhi@ZdS9Q2NTEf쮓$J%65"E"EEQ+Q%%RXQϚn|V]K]E1h>ʁK."6oJe%S^FUI!A,I.ʫ) )jl0U̎[wR_D aWRQZDIq!^5DJJ ((eFJrxr4YGCY20 S9 X?o_v_:@Rf} @:(*BQfeh!Pm6Ĝ$cRflkd3jEQ B"uJvj'c榪YCE`ZyR}2cOdvC bAU32Œgis||sr*M239eևj6P LLHR$I)-S.eN_ΚwOiSVCEUIj׮(z:64UZ)j`:9^yŬݸR?j LNLKI*Wne׆z\j&sNQ5˪ YձvrQW$&'fɣb*2K )*. '7HME9n r./>i5Dxш)/pa$R7qߝ)Вa&5(. RZ#9"ɣb|$SP\WCQ0HiqF(4n/`홱Ü;^(]3OL_MS|Uu~5c36dLiU 1?9񜕔1t71!-rxR.Pæ.RnEQ/3}ua/o;jڇP)%y'_h ymcɯ1=O'R>/3$u[ P`rtRcnofw^ئ@U{k4+Ru޽{6=BdRNelБrqh7`brPȜ(\Y0e5> 陾(Y+_'Mw/S#cxh {^!]ItlJME16EOX, p8iٗ}˫ȩi0sy*eV̺,e[l7{92~8's9s\8s̴ Cm#It*/Q |(7ǿ^(T;yEe`&̂u^ap-W]w+UoW Ԝ|13p)3+tO*;yB"^??شԇ9~Bn0]i-ry:zyf|Sxw0 Si9h !M~k$(ܲbFsm[䷂DN7lgNrNs`0 GA-`l&&&Hyjl2s\51\ҕIf_viW@""nYb&Mn(٤ BS0'o>Ldb;K\#Z>]&?ԓOLKիɍC06A7ML!ex\%癈N1No,0q&h) c 5,9,Nx~2W+*R&#=.?2'aΙl>9fs?4ϸ)1'W0smks45! :Ͽg#6yksVgzޡf&7!0~䵬HK{I ˧ 8gL~lr3mZ>կԡkˮIwyF <{NJȨmӉ y &x\m!0QB@.N`1a-'>2o! s[i:~N"~C-er*z=-bF ):.++i(g(0,m`3#Dt aNfH|_~Kc<y~ӗKqY:7rb&G8ݞ_s&NŃ<>ҔVאk50ְny5.ztM~0)N:w I~a\ jßR<6A6+Ý\r"?! "c\oaC:-(q~'^'@i^ye 7n]7Qc3o!c >vbQ\Z*67`SWxd$V6U%I'49;f\pWH=E Fɖ *& kQl9b!F63 -> wqGA:6NKu22cQxsT/m4ۢr oVP7= !$0+n0`#&ifz+xQGͳ#DYz3GQboTB@tw䙳t VGDF3{s/>YTz3Ktw~X*@I /߻Vu&z˰Yl,%OZ+s$ͼOyr~!6Q$CeUCWW2EX([Jq9^oмW|T*AYR_ݎ;SlWHŦh;slأu\Y,-,>p=/,2Iljwx#x6r]NTE~AG'n[_QRZV-/M oq_{){U-edO;ѵK9/NH{Ɯ~enS@O2|΃9׆USȣT(E}O?^j8xoery #rX%QN>mb~ե?͘ewla9s㏓pO;s|>nΆBvJ:\{O|cS /JlՕ8&7?7S( <78laE55n+ZvzINq|[o 8mTc{x3O9 $X4_=9XU_j*\\y@NiV1l0٩Wysa{=d\!9( i- UkB&Œa0)/26ʅAkGgIn@ xoD~?uRwDHGh9{'fLd0֢*xc|OO|AU2./XV׋|^/n擟z _~BPtv^El(:mteQDqqyYVVy= @*f1!2稳(S9]ʹ94}2dDb-H%S,Bt{pS%M}̆r>n7Jv7Ahi׾.lssmӋ32=TeȒyfѲ(3b\sL20 c*8 NSPa~SĪo!6TL~e=uJF()J*.En'ZhXR%c Bl2JWk;iܹTWC.Śb$392hX#U7ee' c$&JcPRǒ 0:9ݓK"4x{N!U\'Y2rK*i~`L?(dz*Ukwr|ػq l(FH)o`;3B5@XQTZJωLGh~|8 ;a2@ER yP FF'Q2)8/2f;#}} SQCpRB~q9^"O/Grjɴk!"r.@?a9cNʄԙd|*FPSIiat$P\NqX)~0d-y%5ԗf&kF&\djw} * J" WQ%5kɔҊ *ˊp̳]@gx<.˧8%^zPA )"[G!BI\dxpS.@?Պ@ wD8)#TS1r LP,5;VA-zIz48cg]8VgI->ϏCe}̊P$6F[T@%MΒ?>-$v!Sf㚫 w^ ۩˳cƜW3P\A֮G( (~zF,>**Kfm΄(#aIgNE~T$B@2bppx ? 93  ~)Jay%yI'cx-]K0W"68ҙGey1n$:>dxdH\CQU\ԕ/2vx V(ўcܺ^rs@j F[籣dN>%l*Bj16@(07ӟDQE(0==] U*j(ّR'61A$vpS)`i.|StSʗ,$&͊ }d}eҘ+$RuSb3R*oJa4e Vִb==? FI%CQq!nMדEe9BqzQG&\*+JpY?Sۧ+C3ΥIw&*}Mu(/=I^v.ÎPفR:.oji5.#B7P+eDG.x.gOr쉭O+*ɛ`Ŋ:: T vg`.~. )%"B'LD\n nYXm8ihhRk.j\V7T)iF ?D?'N =^H8w;xh{B(h1.9MT qڣ>ܱ6vws%/wKQtD-YC;EStoϾ /pK3o_|u|,šcSOcl|[;%7ūr1bn߱\5Fg vP|-,ȑ#]vSC9:Ko~)^=E;(Rhk>ΙA?K|*Ë́LiuWZ8b"m\rKlȬE;9q V=C*4&k@K(6z_i-E^Ԟٞyi;ąQ=ۖF8w0'E?wG_yPTx _`g>?ϟ9^YNx#GUcu9mgOp|;Tiz[sqTmܐݏQhj-C&:xo0{x^m<Ëi\}t9W% $8G)[Zۘ›oݻVq.cp,BW{/58?)S^mǎ3\>(E?lw jJW8Ӹn%8gг AՂ*ƗYS@:( Ն_oHZD({q!Hғc$vlNkfDQEBLۂXլͅFvHI܎BAG9sMQ]XJ2rVi/3@9R%㽭4_v̋4!v63u]DF8iM} d'/X7sKA ^|i{_~zOw`͝IZpsE2~g΄s7I >\>'^ζyơ)Z;wHx_#g)>'vnۖ V|z #;hIqQ뼊%P8[TUU2(s9Jvp~Y^uM~۸o!0bKd0˯^REp>^K]T9us|ɩ^N=-N}},ϗtȅzZ3эm$-'x機su2ծHJr{ݠSbI S?zl57ooa\{|6D]ܳx*@7;)ۯ8 v^B`[S) 9and:[h;v55&WGJ񒊌9zCM] 2gF~Y[o~Ӭq>ϥ/8U; +(2+i=ؿ=Rey쑝xb?>[KC15||88KănaLh(Q δ?4x8oh%J36d oO~qquP)XJMeUkwO|{6,0R7*F&y9SC!ifRݰ~/|745֐S\='9 .T'cSn瓟 [ /~8c͜mOҸu7ܳ c85ItbPw=ܼ\/Qz<8ceRyCkE{M.v38]ȳ'9ObIe [3xV;/%uFXᔖ]Tޓ Cs}cg1Pm~IySƟHJG+YYfq{ٸzѱC3r1uvSi¡;k7lⱏ~סxwHش&Ax^Vy< 7qӶe 5^93ݓIq X=44֓cfw`,PӸ;>9:aIJs'aythM1i_\ ł?'%66>:iF2[?1'|lq3۷o: 8q=E l~QC L'9vC(el~ }SVqw][@OrC+|'O|eXq0R̯# /3??= 4z/J*UM)wq[Yu;+t1_ۊr܁ Йq6 չGLk fij l({o-G5_7BҩD|/e.⎌E PPrr-e]}K@T4DdvT))qUICGJwTN3!*)J0 iZXIe?/SU]IDN|Inl* EQPU+n >UJ]qRa%dQxt]*x~C4?{ƀnfmpqիpC> c B^/rNtW-ߵq:GiZjlxAՊj5uC 5X2]5 ]X< ( zΒD)- r8^|K]%ءr64A8e]TNg'l4n,2jGφGpPQYNIiN3)uCsYѥB |m9wp|!b%H v`~.n0?C%XREiAh<Rb TQأz8?=9tlEK-۷ [ЩFT^API18%5:b-DPtӹ($膼HrR TqyM&oP60F;9tMKMe+ukQO8By='KDNOf1@:#d$j،gNcN^ekdo2"9z)::~j'5:d,؇ɿ39[<\X6l_mI̽wBUEJX;qb0>1Fژ\B6[paA敏wsYqcI&*e9Jvhz:H1$R O ! =fUam9TuEj ױ9,ؔ$-' ;jQf:c BID "!JƐJ*͙S l9Ʋ4q Û $.QT‚kMk Ǿ2Cڱ(ugv@C mM[ugsɡv;T~ ~ofTٱ@ lVCK'Ss22uN{r&M3"V8-+Njxa1aWAj:]Ғˊ5x{SǛf:F:J,]״4R*X*C򙶑 F$/e^\`$uf_H (*K8FB:ehJ#:ζOEٙH~-CGz q̤a‘ tc{OIHa%XRNuId):dL)ič/f F)(źhRzKǏ-aƌ$I[&5FGIL200AuJJs,̄4(t9LA՗~OGJdCR[Cޟ/ϼGޒ\Zsc!ԭH}g;\uVݺq{ZR_VI*[I%&/;d4iș]2}m^|%ZGb&B($Cr<0[<Ӝ`պԔ9q')%$Ҥ5c3!Hw(.n7ɿ&Z8Ġ梼t{ןfS͆UmeRF欝 Ax8e2\r걻Gu@|D ߦ&\Rf]<{^dߙ>BAB?tDf"bM sĞWB>;{0Q4t`9?d:+p|ZrʹOwSGXHVw!k*H:bO] \$P/ p;#ᩔ/_MCȾC&%VwE>gh6RAd2#`")3cz:N$iPTVK`P "cBT T(& @2 /;'"c}C4a3߹7yfr@ OtGKZ\y=,gSXe vtRLOS$6lN=J (\ۗ`EbHuVqJ"fdE89~E*G)&j>e5zs-^'(+ t|y s*F#++B!=6ŖNk!2l n N|9\~J s.hS0c3!gow7J .z,anr^~GȳgdDQ b;dh4N"%IhĢQ8hKI%ݼ/E(6գ#xʖF,!O%1ch "DxRCX丽 ?ٖ".'*CGĢbSv'veWG{0jwُNM S|]g[c X%YY"A =#*0uXܳEX9s E?˜@'hk1aYYؾ.Z ;O3M~F|.KZ- ˰)?&= 1HuA"%%2bIhD*MAvIBCh q#J"#Tn9?JNrˆv ^<\"4Ek@T9'cq˶YJh$L"2EY04ZOsCc7soۯ๥lc$-c^zh$}tvu2;6(h]J ]# b4ZG&Lʿؙ2[C<`=Ltd ƨ߶y &"1lEPP^Ci{nK}(V7 +(GNWw wq uhuyZԯ]GϺ@Bt7`(jehhaPsRTYG@˶b]M>:cݭ?ub`U$#q!U?k'E34 <2@gGg=#z5w+*d5, ?_Zˊ*<6Eop+mU5MceфҊ2YKu!u[Oqc$6U8fڰ_%eb)U:(:9ص\[&k|/JPUaYMEYE-^}S|A*K(^2/}uYVW̉s-8r + oDkiJ~q%%| r<ć/)(5Aa8w8:.pO7mZh>Xʲ;gVrê6OZXҊ|l^O9YfsQ#0]\*ʊpf)d7s nDlqn䖍*|f4&Y\'qFEU9~EXHrӦl2;uER\8~X?@Uy)N_A1SZTHݲ=:=}𰤱"VN5Isg8JOo}CxWc]~B~|VYACx)\8{Ħ*8s}X=ctq):N,d&|~jQhp^JkvO.9r0Fbi +z9s ŰSPZAIBWiSQYAyҢ`ncl3cqH΍x<${qq-4B|h0CѦ[{R CKR7RwvRs ^oƠOMb8 6-n,Mjmcr(wv*WV"¿5XG7Ѩҝ;)(Rd[y4\CCϞҮlHez).ǩqE& p()bF%ŵh.awSHEnF Uh.$9mHBNM9h;PB'h;E< mgN3.QݹT`p%"V^xU|{o/2(hz2cz}bR^Sۢ d #BOPS%%ht.e͊y}T,YFu^F"U4Vty#0:V;oF B!1NG0S@]M)9.? |D[9uqFAi%^ASp:|Wout*+JگvVri)~Ν=KkG}}.VoFSe>yr;]:˥$:r]qI5H.r XAe4yD{g7ubs}!A$6ϔѴz5%jݑOEsOvRUSNҁp'my:/O_kfN> f-E*5^A22J/|v.,O.Xd!gsL PDM'~V67¼lOTOEv<Ѓol dW^v\̘ 1hƧb=1Yxyf1kixLqؔ9YS39VvLOxg[bΊUt}>n^.4śEdL6Z!ٵϲ'2m~2}q!5.yMl_fmcsF>\<7m3]o[)q\&eN7\)70713rg^1E6wcݴ8@6ⴈ+L]˅*ӱٱטmobi:#/9-SeX}˘?i3s\?/Ε񗙁3k~7O$³sхMѢsn@0GIGN׏ػMLYg״;.⣕.ec.d~_/] nX\οOC7Fvʢ2Y>GNp^v? (b69c]m %i=XІLnMV,~ |(7ǿ|Vn Z3iWgYp _toIY)ΚοRy 1[S/_^erp2ګNfc >Ek_Қl7}?Y̩3~e L__ 7;%s{\d;>4'ŢL!QTpmc֭\=[mY\مgyYEϽv* d1}fZ7)Yy\#"L(b*vcSUNbl4e8`<㚜"E?F--- pWk.?v3$G?E;\6n0BmWpwa.L`rE$4ic 9KqX&#Ŋ=vmz6㧩_ߡ09Ko7ouLLL?X_<-݈wϞ{TšbT󛚘P˧ gAG:f@0A2Ȇ/W,׾ehiR`Z>0k&&&7 LEjY.teWMZpfk@8nՆk^kbbb8 vsQӷt8p&&&&&&&&&&&\ Eѯkʆ5wMLLLLLLLLLL>(FT 3 TLLLLLLLLLLLLn ebbbbbbbbbbbr1.t@Lb*]&&&&&&&&&&&&7S211111111111J TLLLLLLLLLLLLn ebbbbbbbbbbbr1.t@Lb*]&&&&&&&&&&&&7S211111111111J TLLLLLLLLLLLLn ebbbbbbbbbbbr1.t@Lb*]&&&&&&&&&&&&7S211111111111J TLLLLLLLLLLLLn ebbbbbbbbbbbr1.t@Lb*]&&&&&&&&&&&&7S211111111111J TLLLLLLLLLLLLn ebbbbbbbbbbbr1.t@LoU 1Z`"ޅN*I=AT"%dhnx3cy)_]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!]!:x/^=m/N]zo{nx-3279:Ut3ՏGsa2syͶ'eNn>o~?n$p9XgO'uf.nss:?>u3\?\97+SM87RH؞eyq ;9 :Eyp.z+w}I]8]'ͣt-̭;gϤefn|>XO4:^g޻?_|w-Zfu}y 5֙t~O4eYD5y3Vt@Htzw3'fG}Z׮}6_>GGG^4f7o'@w[~]%m%tEXtdate:create2017-10-09T15:10:07+02:00/%tEXtdate:modify2017-10-09T15:09:13+02:00GtEXtSoftwaregnome-screenshot>IENDB`Eqonomize-1.5.3/doc/html/C/figures/securities.png000066400000000000000000003240321416454732000217240ustar00rootroot00000000000000PNG  IHDRY}mgAMA a cHRMz&u0`:pQ<bKGDIDATxwIv~˶@{3;fg3咢x/%tERI{O5u%/zݝg0{h+23~ tWef'9 BP( BP( BP( BP( 1˿ߣ\.R( BP( B!p8//^YeB"x>+ BP( BЁRD¡˾4.~}9V( BP( BC!waLP( BP( NjۮLBi BP(n#^U( Bqʄ'/\ claU E MS3znPq)4 º'|Sؖfab'M BP|,@  EB\6K&W`'O>^ʟ* ҶQK6RB@XX*Q.) "7iһ^{\(HiS)Mɉo*XfeZT,CKnϽ W-I+^䝣Ø K*U-t0ή IBPL^g_x~A޺}$ o1|$Ҷ(ljR s^JJb4;\]l~k̠+eBP(ۀqV98yjºE2>hg~\3`sgO(*2>#S!$8>3>~ہ0ǏB^~ Jڳ Gygc1$ xvVqGхj^O=}k[1>{!MϝL)($>}]طn|Av,o?O-t\JH3ZeV;&.B@nG&Y#VۗoArj+Qbr>^OO[~Y93D;XO@>9̛?.ϼOʝܗbMSR{_[{t>E҉cGS)JR|$ BP(>ܸ2Ah_zy}4ʃO>EO+ G.E~_H)1Q<w&ʰ|xe +F|lVT'DKTk}|j NK^|8w¿)N>*MsnJsF$+qٸqw[Ζ8zFh|{osAq7v!rQ;>~?W^$'7~X ^I??,qN$0FА\&/9" DX+{- nrwȒDrɢYJ~fKAӚ]|-QJo kWrFV Aڲ{R[YvuН64tHZa( Bd nt1"58еy;kkфA׌B-u 75jf[Ox+; MC Co)BCγ>ꇫ3gc޳gQ 19՝^x,n`ڜgAHW ܼljp.tWw2L9?MYJ 4m\3uj\֦3eu}Vm/Ӟz!+́Nc~@hwY^\noJyb:}MN>Íy-i]biO6G/(LFNԠMCCsw]CNr\|6#BT06~Uҝ>jk#TȋЩ;/y" /y0ˁbNZӄ%.,p8b֡`f9 Rè T[7g "4daH\ hmSn<~٘pdiNfE`f9]KM($M'i1\i߾&.Eo8ƬΗ[.\ Dž1@B7xN'J3Kޤ\+ BfnU./+ YFdžjixu7IfjBok. _8ZtO#;iVׁe`$NC{KZpc lw%Kh аH]h%qh԰9ktv/%(3}IzֱͶ'eDjI18!дUK[>ηؓi!>Ke%lh0v AGÇ5B ЦٌARe$e͆U èmg|F;16Fj 3֥+Yj 0Ҽ,Y'BZ/pEw=kV-%ё6. V5u#Ё>{ Q`uR&\B6 %1mWfPɧUŌ ?4laՊn$3@2ghdYg#qB^"(gc"[2ᣵu)v)sg0~JDхĮî ,9?Bb4] vK|GVaq|ox+˾6;7|#, Yb?ؤ'H7xIpt&;xWy\`ϻ3Lq_y'|/r }}d#|\HU 4j$v$^u;9ö%$x%4= 9&&'xNbܻ)y#MqiL=H^t,'x#$ e*)v=M~, YӜ6$!o],o}ʘf؛c[ϲy./96=|?a@+׿$.3y~FNbc-O - xx7  ? Jb'2Fg-}j3z;7Aec3yAnvn)0GzCʦ{̙wN:մhcob(^`YOV)v<8jubY&ك@,_68}Nz4(r履`]%+Z&H A3{^ὉqZtف2Z/Y*X|,=ݟq.+"!R( <$=2Y䘳G,-n, q*?։udCmlqaMO;|vqr/[EK9±+6'|fSl۶bþـ䞗x1]jiO/$P/a%'A6|VW3v|,k՟u7gCP( " W&Hp5>O_'Y)p{}W~:ǩ3hsb_H9kκf3{;##uK?GFX #d[:, N%vh e8}A<qӂhR:}#+\v}єBwz58 +PGkMXœ'$[sMʓ<\kWus.k[翰CH2"VuT}A/rC7TJe,I8^s| uh8t(&Tl48WňiYH  ə*f1{ _Ҍ&m,+Y!|^` nXWkDŶqZX_O'yq%7&B詣D@/ɗʠU@{ RPD֛&'vv;~8V1Bpp*maI`e!KiOGL:ftf$%χC8=5jP: y2SI&H17JhP䄓}/|)~)~,jrx׻%U!224N֜c,R.Tb/1ζ-Be:-p"&7|NlىL+ޤ - uf0iro?{]o yș]QRuo˴Otl 5rwŁӮ(I.%{aX+˕$ڬX%.Sö*+`~1'/>ɑ? M9\ ۶0+%eqy fbYp~bA 94mr-6/C1cqsϕ{x?_d1̩ J9&%FtQ&s8Íw56JsI̋D^CvE>[UFm5_%H`f.=}xK+!e)KnP.0162Iqh t?۟~"qY_d|nזrB0ʹ8.=fBj~ipqP32͏=({>8ɹ>J5ySk6hgVxkiwrvp]Wm^^R9 Pvb' BP(~YAJ L Ǚ 8wꎶ5B`UJd^_VMFv Wň[PWc;w~t-ijeАRbZDJN"'Ύ`MGS tzVtU3"31f6k <+ɿ.21oΪ¦B,aKUkf3(ݝ݌%V.2Pt]u;Ylz\ºxl 6D_M~wpyB dEi k!B;+/b$SAYhk+q^GXULD5g* I\Ɯ@i,析rEyHMk[ڹݼ~/EO ld\t:i8nҥ兔0uuaZhU&t _a쨛\ikeik.*c4|1D Ӟ?kDx,or~+>3iI%*NS8}/܈,yt}%NdHrز칊je5s|.$GN+٤EbӰr=Q-C_UC`{{Ti!z^^"}J3tzcO¥UaX 6XSY7j BPy`Mƙ%(pa4F]{-nGU!mt2N&%OR2pL&SSx@sG>_闓ܳmR| EYɖc~-ri!t~,I1./kZfq^^?gVV)bݛy'8??cu:$ܵ~O.~-A[⃫q Am<̳vSIcX$U&xZ7,v] \X"K\CS4@>v}Ҁ=ݬ2us.\`wg*LP(Gpxt:8eUSJ!C<9уi.%r8;͒Px"KڎʕDD6CM,Iȁwy3+ 4"G')=!GDώz=|f P:ƺ̲ڝwRgy}D4x$9FtDKf>x/x:,9KħWJ '4eg%G,"Idyek:ͬ[UCS9mnpY&15A'ugW豩Tʌ|ӥz~3g7_w6J'9w^O|zpT,leeVx0_}[6jE=[v*Ț0o#&i9>8Uq0K"pO78"xl&K<lߴ7@,iRfSdž-{ȧ T&LH| ԇ,YŲF'cOax i{/Pr #57Bzޑ?&Z#dsn`Nw/f>3}ؾZRIF9}$}c=k7ie.*S ;pCXٌ!tMdz6ќ[#$. -mx#^?P= 970JƒМ^j#0'LB]l)#/ĞQ5ɿ'1}}\s V~*m]-;sΑ?' Lճ=풡iyyv{͔s6`l}T9c:=}er*#⍈>vwz_rl9[S}/^q5y|̗S9+7\*/ӥu~nn8u82;^3 #//Wse{\e /~1-.ge{;ej18ܒ+sda O"Grhؤ|}?O[2>_a.fdZq o/qNLܼ\+ BCP/5)mcͿ 7 LuwL]H[b]YW|لz"Abϻ4Wޖ*5/Bd;r*&/9k.l-LnDN[|W^}|̕Kv(+^rUN?19JS+ͭ_h]_s%j_.$78.^?_57"KW+˕./:Na$`kOۖhA1 ![٧5yEٽzo_1s  BP( ev BP|B!䔛GN)8mەRb>Oɴq1J BP(>RP(O&Ҷp-~<G,z/jgO#v}dB>i>86# BP(YPBP(~ZlkVk3 m [k2AP( qkb&( BB5(Hj9na@ BP((7BP( BP( B) BP( BP,LP( BP( B 2AP( BP( łPBP( BP( B) BP( BP,LP( BP( B ; Ⓤ@1v>ژj=(9}%s BP(nJPb^(ROS0ϩ fU4"}r!a4~ϝ#if4iB ضDi=I))W,ym+ ]aJۖrD{捦-p: 140M(f3#R.( B%,JiuKRJl-ל.M{OƂj]1ied(Wm۶_۶|D"(7?MNW_ғlвnR&lxlBJm hyķmN<QWWwd֖XXLdthx #^|-4!o#+%=|MO8p<>iY?umXH{C˂p80: rU#-CX+WA  BP(n+ ]ee[6MMu] ^ MӸp#bm+i|p&e[ i!m7ɆM 4n &8?X"jւ  z%O:P)%err 4;X Sdm7~·ځ_lfrr@ C")Kcۺ%D˂Cp8Xbmh$ȗ^BbU`Yiaę3w^{ /pP(  RJN>m CCt]ȑ|_#Nc_4y篺8|di{q^Yʼn  Չ rKb6qY> ڵkŲ-:sy|uMYvCuig;ǦMo2A4lfbb'fu_zkײ~p:w|PJaui_ˢFP]_*7e/%SH:mYWܜiݰ% )-&2HA<=E)2+0wd/4 [YXwOŰ@^P(W82T`,9D"RΓLb[&_7<{moRJ85rv\TLTcIJ%6/-ˋmKBM[lˡf6㿮 tA ڌehXG1-'\mal)qL%k,Y Ӆbلk1Ç{n>}پc˗/庵*׭/M-螙g/6BP8«W]Y&[_"V!omF8wkr/c85ljP*cq71K+;sצ%y$EGCBf,ÁN xMdu/|XBMpOQ?JSFvǹՖ 3hB0q\hCmȕI$mn'#q\Cش4jۻY (e XMbR(UEeV5RGeK4!q%qn C(MdeBb+2i T0)"X9]T [BMedn&36i"S)ЊE7p֯W. BP(0NmW\K["/Z<\۶BP(xWi|իW/jz3+WS!hmm)]ٲe mE?~ZJ:[i 8q=,GvuVzzzJrRJĉOMU݋), M`;p9 7hᒲ_Mqի v)1_}w2,CJW*cchB`?#D["Q BP( 涜0*\gc'Fql S:XG5jMXH 6wVc}Mp % {D QT*1c㳄Ɛ@EM 0}RMdZ fؗ#Cz-~YJy)+M606 ~~g`.jEӰΟ|k"3XxN@ْYrrq0x[7BP(?5re0v^5.aݺu7d.߰vuXBn͂RJI\&L(J P`0@6ȿ3!Xf LsA1#/٠7ޕb6\B>n89 `ҶBTG?sRb\nexbkזex#-T iJ Ӆ0J"Bp|0EIH&vF!;(A_Qt6oi@TKlip%D&=HŎ/4кIZb^y()%ty m^E`&BTkp:%o.rHvsLBin84}c#>Ug\ZFX}^92h ]t5n*~.Vt6ŌI"K{GjRP[WmTN7%UcYOZɱmNl wyH6 6Tl8rzpEt걌K՜~g.Pձ/inYf?g1.wX~šppH%F8sǤ0fJ׊j3ȗ{@o.gCt>U|iU88t7\݇i鸇H:P9aNA*]fxiK;wrJ,pfZ0sZuRyk!lۦ^7fC=6F?HWW^S*D"I<Gu(m355ࡇtlfhSw0 Ld޽ض䞻!ˈj[\yA4#U8óAM;q BhHi%8נrK[x ϹVl S(QR naes 645Fqu9DתDCˎd#dgX:CٽR=bGmXd='Ie[ZH1.b7]K{ӌB %t994й78y{C~jr,q ;1.-<@FPY9G _M'GG&p4IN:EviZ7qӞRJn{Z,˚/\CT*a @J0cc9-_aɚ3˲crr9sp/=:*(IH]ᅸ{ }2;wV;]5O#.NyY5.6u 7bkbY,V- f:ڴUEb r9*KVT( BAn2/f#%k֬?3o6 $N|.࣎H$JKK+?˿= ;0?0[EP_c?NKK ˈ\_y ![l}paG> +aLLAN:E\_{p8Ҟ|Sė&:>#+#lڰ C "׭:>tXVr)M׋8-Ç\ʢkd Qhta`o}b|\.W͙ aX 4`jjN֭[#JDɤ3=zQTXn [ؖSSSտmaz{{gsBh$ #S%SW=j5ut. bD$yקn݊hk*]wÀk0+$gc6jY![Ҳ03YDr.+B2٦mH+,hS( BmS&rؖi׵DYۭRrAv.BhXɆ{N om3w0FDQn7B:::RΚJf1 ˵`SF{^zN<) pAJ>{I*$NsiXl+WD6pǏ====}GtR֭[Gss3eqq=!ؽ{7''qCi+F\o>k Xɑ~1Jgo_,BU ma/DiYԬ]?إm;H0/M _d 8/tm#(Y?eg'iю񗺦hhv:SP( O3eGr˲Y88N^mˇx<[vcNV\ /mm,Yp8|K<X 555<{=zX{jj]fwRg>kjjNYlI"ZR)\ SR8F2}$!$}g r;a  Sdj,ٜI4k 3:>V? I\\06S{?|/}ς&Dww7/\ JGl)Ig2@ڶM2$JL)$:-)fA+phB;åBVO!h-?fllx d3go~Nߢ26B˂ɩ$^_22x&>_ RLzh= vqB288n {Gk+K1?Quv0ainIRt_\6FBk0 0Nv.(TJq5> }rLP r9'e֭;޽+Wvڝg*6A TD"A˴8ۋk:mۜ9s33J޾>]>yu'b;rĕJrc7?9X_<ΚQ(Xflo3<Î;8<ǎn26Le5zNl8P6s8?tZnbE`N̄i$f}pЧ5.Ӂy4M*–6iZk}6me˖155ᅬnx=Y7˲>Br*"HzOIٲemy ̦c8/Vp-6oQ5\D#|٢ݝN'. ۶Pnn7x<2 >!޽XbVVSd|AbGQu/r:nB. =rJTǃ !b4N$г÷%;ԇl M]mmS9¡k A6NC:׻QqQ;MKK }ZRF.,>pcS__[`rj)RK,˲fN:ロIΜ>unY~W_Ne˖Q)W4 ?xRkjy_G4FF`e,Eی/>ضEGf6xgS݄K~ %'Kp8۲t[>OR.4a։LN'XٰnA}FJIMx)2p}jZ,$-ݟ믯<˄yO圓9z~gi}.VuO4(eѐQ.fAnwONЀsVwE,cppp$翡vvpͶGR!]LX\Y#DJ[JIoo/J%be9|01>>k^zDx;45(d31Voun"ak Z?```7n 5~?hZ`%椭gILvBUfIgЄ;n=jZ[o$Q$Lh8u$gΜBIӼ{w}a~$`0d2޽r̪Unvj  vuja'X;9g&.W=O$#MvF)?{# x{Xrc6n';8Laf Rb7#Ya90n]PBP(?u,x%[UA7nw08Z+e&4A H ԺH%Dhƻ6M+M=O)Fw:1^n񒆆FnOܙ/Ĝ(9u$/26l  S*d3cq8@:aqU ,{D.N&iL]@$!6wj' u7&Y[%?}SCϐ>M!44[cG ]װ~j]Ԕ"AP( M0;kJ$S߯wӥgx(3/*n7rQF *ז՞u3rs ²,~FpN]W[JNq/ld"Ass3==^PTV A%{.^Jviؼǜx27-y7L׿Y.R1KiQ\`#pr;mE BP((?>/bQB8q5' ؃ nG`͏B4xt&C>Q!nkMEOȎ}U2¡P( BHLP9(w!7IfQ秽= e͞j2vbOx"AP( mE);R(~u&6ǭrR( BP9t BP( BP(>(eBP( BP( BP( BP(R&( BP( BXJP( BP( bA(eBP( BP( BP( BP(q# !>|* BP( )凝BXs]e\.i!WFXrR}$@4Rt8Ԙ!!mr2M2#w|4P1+8NLJ40 ׫6 &2!1MΫBqI$!5 c6~_*}HXE&! }YQPU EJC4&&'pQLc)?( ǖk*J%LT)ORYW@1Gࣅ]iCT(B4G4)JjjbZP(c&VP| H,T$ 04'+a#P5EB#T;Lٶ=[~&QP(7 `T(%)2`k{ae 쇃`K(Wl4M45!fd2+(n$anZXE*¬T0-r. Mp=|YU( O1U ɘ1T'S2Bc4s)D%M+w-Ʌ"Ģ!lZN4ISy `ppR뛵b.OWˤDD"e۴ H0>6F.%JQT, !v C~[Zxe*E4MwZB^'04á!&4t@J%R`h$ǖ%G 6džJu.bZLC#yyV4O@0K$I &Caj(|bhv]ei86e_ 4]۾9ؖ SR)r555477WO   ɤӴRWW(2͊@R0 I),? }KP(~eʄI\…8qQݳ,aY™ Xc!,9Ξ!pFFxU*ĵ/u8y56ܜL[ oӟU'Y-D"N`0~L}@Ϝs &oaInS(LM'p>-9=V"YqaHR6qd"'{>v5BaaəG-.$9d3'Ou?Ql4M4MCJIT"3::㡵1ON'gj!@BHC'95 6,ƸR>3[WDm'"}vLNyLNNÇ\)cYM7^7L+q%}y}^<mKх ,q>^G֪/ԵC݇o~7 >3BrK m?wGXjO}Izü;ؿ%=KYn=³QΎqKQeREmRj\ x@\bAF&ɖ%.pӽ#;g(, ] A;4Fq}r0LYSRUr{+BWsQ)'p4vqt{TXvCߧ_<'5(V'hg9af u-z&6t7wc iҾj\EPTlcE)Dd׏f8]nE8:gKC$c\s'+ùd oaMj 9Fm<@OyuM /OϊGH4c`6X]vx+V )%@woi19tg(&lOm;Hȸj* 3o._JF<}QI ?"r_=5`:2<xn|A(Q.'b JSSݼb14rD2Mb elXۊթ%Cg t7,WFqiΞʮ*wW[w B1V&!8q8=ceH)ٳw/왍 $ 3>>Ə~x5>u<'t{rhc Y {g5{ᅁf1ɱgp,щ4HO49s |`0Ȓ%Kpw奔\!a瞶S wr.mK,|]9h3PW$!HRL& Ν'V6|I{9R$##ܤB2rr/Is0Ha[jWvA-PI j[ۨ*K'RB4IeBP(n2-j~09qgɒ%7'Gu,)Y0}4tݕc Nh\Ol:46l_&ku5e Єfҩ>Ǟ_l綽5ߴY{XXe/ {nDT թy}֚F#Ч@mcSl"YٿA3Ef{5U3fvxsWBؖAr*\~0<`PLV-h"7\Ԏhwv;C`}ns~[5]sǷs~צK `SOYu4*5t>5M.]n1'm&&&f-".b8/=\7iw]ru\[#~e])g5\,#Wç3^lZ>g߿מ-i7@ a0HkP^=KiL MmR}}/3VRΗE`6 >xbȏ~#xm )%}<쳤I8uW q>Wrpٜg;Č[t;iӮr:K_7=".g1-BJ鶟rٻmFP(W(Y: p7|_X$.*A FrZ|ÜfB@1 K+x!@ xx*) uDjhB`O%(Yᡶ.ǡ!m\:A*Sm$GLBM=ݍB,Nf0>lX2 Tа <ʳmgmm- Sq e?ROm|[nږtV{R,Z kY ׌}b}^޾|"MAmK1*Ʀ:NRz_1~vڄ[ȥ*CDf\0 x|D.lmj6L|bl#Q>tm e䘘*jl$%(5D.@]&H-Hm-5.Mzjx:mxoqMpjRO>H,WW A8 ,MQ*xkZtC xRƉǡQHM042IY8kl&vhnjīRY 4N_0NqqXHHd TL/\KƃRȑV8ƦH*# 4DUyARę:>'B@9$QX8aj~ b87\GCط&Cw2(4$%)&!{&4QCJ2)cXf H6]rH|6C4:M&b,hcs&!+$c1,p#<32Œ-q`Ngu7cr*܀"|z"q7R ѺZ|.t /ux7o&#)O]A$JчoZix\::\s6PX͉-ڣ {,Ё@{3JR!DBǯL6QtS%QҼ46wTmbt#$- X{eM0KQ5C&RϞ`YGmS+M!Td@ŒB @v٢۩K1a 7uu-xÞ^  l+)r5M0>\8yw=xt`l, M&6N<\`}= DI.1d\4Fk('K ғ# ZXրCiOfx=F[>i .J<|Ӭnlsy7u>;JvJBKԈߥ! Q&SypikiX}iLMNR.Ynض8?~q~N ?7N}W߽@u4mF{9=a-K r0Aߩ!ϲvw#Ҍg,/ٶ9qT1}lkwpHB9{E: 4V7<ꆇЅkg哔P(A{??ͩgA>gb] 8"'j"MtoMf,fZ:/̖ͤ F9q,~-_#4td%K:J?GcnH=q6SՉ3as߽hNϳѰ^&8;E-nM;q gV{gO65`{V}p ?5I1Bjm[Xn F&9H.j X8\& A>،bJ&ҕIŒ8@e|3wk^#Go0gz縿@XfO{_,[+3'Sg( o9U/%yp]3Dt)Olt>QBʝH G';5"[z.g7_|s9=K8 rh'?$cc\lqBm۶w^.CCC,[bJ\]>1$?=t{cMq R|/<&'r|4ߥ11K_<ʃZʙ)^Ο$?"Q#́Wķ~J4Ͽ/Sgi{Os~ph"z/_Ԅ]LpQR(1x(5|w>.hmax~:{\DՒl?{%בx7Ϭʪ(`  < $H6m{G[RKgws;;7JMڲ&M6=A ={Mzso?2PI q yM"F|:T5fӦMx^~mX|9\#jRSSCWWJ.ZYu/wl߸+gP[m# P7}Sfv{ %=3ι^6;W4 C45v۝wVX[NzǛP}-0@B"eҗY7LRХ(..ѣ j*2 gϞEQ8q~k~3!HM0<9[`FR3sۗ$`B"HNri ŚNr7zҀ=!b`,B-öQYN:NQS˼txե^dbس%OCL0`)f睻X"×CDqtLwNWSϦD#CD~@D [߀;%1]#3aaEY2N? <_ڮ`ߌ3IH)pְs7QIݦ{XS_MdHlLw_5KXQWˁޢ wi[|'z*C::4^ziI^i- -⧿x })[xOGxY[dB9o? ~BK"lqY>b|`E})u&B$az_&_^ݮSbo`PM뻯Tp㓄]/]Iж{KGiJb=8٩cNBnLD%6mLo@.OpQeq*֬ZAS,]-6.[I}M?m`YQ5yy*Tҙ 1&#;Ft5߽g#)aE!Nx<-F*>; F,N 3Q3! [wsw]>.^xa_);zR#gp,¢j?1ApKX '<<~: DQ((((_GQV\I<'κL&TU.7)_7 Ǐ[-X]>ƫ/L,o 24IGdW/:_K^IrjLT,fqeDΜ^[;Nl<ܮ) "H@]W~l"ua #Te@:]g⫍TX"HeL2:4+;$X?驩Y7F8f*uuun~o ؽ{7EEEx":YW)X noYyշxOr:~p+-wԃ\4.gU&g+V^|ox9vnX#i9w,,"hZQ+|zmkҺz&H^'Z_$1zV*(eQqgeb$\?Io72bPXXđÇٲe ݿ#h}V+=>k^)h180TBmfs&3uQXS@b#*=񓧉wthĥ<l<+d4Kk*YZȾ]3@I /ÆPjCO3㯎'h3O{7[V\L@sF|(5x߲y{ye'{0W{ى Mh-e7^ͪwas9QLf3;t_ ݉<}'%lٷ d&Hh:.svRlZ"C2%4=F*o#eAX},Sos.j}N" p!QH}8햜yFwy2ܹ{ 91E'TSiܵEE7>Ax'$'ظqkT 3Dt:CS܁U,.*έ8 ヤ-&$x9oʭ|X;?݉7/iCCߺCG58NQG䒳T8|vbh WA~iv}'kkKH /G@}3ׅ@QL $3mkcV?E$ Wc|>LcUrp-2~Xa)IDATUe2_>`q{ zX`%HA:F$ vpѵG- )JkLFǕ_|~+(XyvTNIiG_?&(وGzVճk:lYu(B(ɧ}VjVGLc*)W͘mulEŎC-v`MI+ Uxd]>)pspBq+Ij.;"dQ2@pB^^MA7S<-}ņҬq`G|;!kdO)9z=Q蒀Fotk'KJ\M 03~[,6l؀ils!`Æ +0Zr_x$ /QȷzrDLhvh0(pƄ f- |%!5PXa*e&ASk⑇` FIDCt= ]ûYT'D]0̈́Ӵwv^]ש  b?{G(AUU2d*+XY5G{:SW=vިy509( 9֟/vbVC8$zbajwzx@(*9N Dt.^17739/\/gp10002_ތL)ٌl^;g ·xx _Gfc LƳQb Gē=dngj Bl2BJ&}T& iz!  vD*M*KA$@XٜU4,ȔSƽ_}(?$Ͻs6z@e!뛮R| _g=c JkJ^&BjJI7=ɂ{RI„Gh>}ڙkWM'ŒElj$$Ʉ)|xغ}=-70Jb5+J]hF2~Aja6'ٺ$[=n6Ӆ'LD OMX̦ܮ)~7_ݳX~~g9= yCh8$$q9tT;8Ba"$.w>!_Ed2cUR0/%kt3N1bgvv)%X~])5$ lе]n2$ꊧt~> m<_n&LL")̆o>${h㑀.5nⱵWر+ /|cx=^,$X+󓌶_y @V4-MxrXaL@UD$H͌1L!gǠِ$ghj ]g5w1u~?{YO !Zt7@SkmerZbw!8m&36/8~5|-G}5/}nq 0iĹܻC~I_!\}jyˏP!zy_v2:T4}}}vd2]&H)19ro"5Mc TI) ŒkTT#MGIfya1jsߋ0Q^&-g H`lb ,f3f jB(fV{d=to#Of\J)q=,awKѩi*|y(*QUhXUε.LzCllabib #q*tgF%' Ƣ F'#(ɤb2d)mnJNj\/+˿l7Mp$t 9)-3S4OPp!;8zeR$&Z5 J6o*F: (w ,LMS\PiM$Ҍi6S.@yS(:wZ?͍MLĵ9y;Ӵ>Md21,_ s52udE^}oGd>i!2y7˗Htf&t~h epI=M"JʂVH)r(&%DrrՈL(ELcϯjΖq;%>SRq"VG9mXHxTZqe#<ۜNxt.(=q?K& ^f22E0)8xH:'Ld:U<]NK[q%c x컏1TCÏבŲi4̐L%'X5<Ȧzg4}lپLBw9ZJ|Q:_A^~̦‚^ݳ9(h Xgװ5༰|^Exi;}8$I$HG a\L)!9%XP"OHOU*\ fԙQ*(SHL&CII ۶m.EBif22 +%U}%xh z:M"(*#|N"-)@QQDD*WDKfn|.+Bu6+'j%TQDˉoTx2F4bqtl(Gx.TUE4fnPA^}Ux衇r1>>rhܸM=\RZq+$ȱndF&$HJ\ F#tMrP;W7g20}&O.i2DbqT0K0000|,nQREl:ą]+(Ưg+ފKOѦYZ%MRX8<xF7$xUڱgds%*Dnʉ(b atwp,c%HL&'R=M<$7HiH GzdH3j9TRmmSkc L.߶O˓OFY>yyԗ{NF TT_K_ye~5n߾BUqwuce|!AzSMĈ%ЋcNB^޼Zn_u &(X7P sI:a1Xn':&-ƜleN&5E<$Hh-YN* LƓhdf?ɛ|f)5Kz6t|"ݽ8JVyms]YR b$2$K]#L&I$Ӏ- LIHuX}ן}-(4+ՕE56 yW/8͇Kd!'z@&{~+olqZ0Oi(X5)tF"#PcQR IAK%$Q NLl!:i*`E$Ǔ$,q# QªE.Be,bhfT'1YZQ9Fq(ᦻt-ZtsO1-l˖WtŲU.buz).1FAY%^ܾB %ʙS&QMf! <"ih'E}^4=,^J 5g4PY^L*1zFQE,_VNo{(wvQwfOLEazjX,F"f\0;C !GUUB!|>Z fkfzWV/irQ%%@ QT/]JY:HPq>v7PQ>RJ$'H*(cqU `inIW7cq8  }=$*(8s qg4f'".WزY׮,3000ui~.bv?0en25=}oɋ/O͛7ܹsG?"hƏ~#l67Ƃ/K^OlD֎!g?/EqZz) 's#/.?[B+jzngsI-M"B1[\3nu7{͋x^T9\#4?LOJ@ SC]:t|GbBG Pr~zSs-TӔ^ )%Sx=ޫ*G1͘T=[)]q ɔ Y]=BMW7Z8*wFT(sk:BlG|/l(MDޗ|e6vu\9b1t]r]) =Gh8[&eA֯)&6uit]Hħ(yE9+ Ҷyz[7vs2\~74M# 1EQuUUiooOuu5---(WY7 ¹M3.rg\/fǧeqI-ֶvҙ43s&&''ٶm6lduhv1㞲w^gWT]VFosM XyQ/\w3y{\__ +Mfby\rj/+tc7 ;M}:/\ֹw}uyk;Ww%=!j6e'zNޯ^\â(&IFFƩ(+.'DUttt"/ LӼr lMϫڼ.BkƍAj/|7:VNbE ǏD^]p_c|qu{Tߘ- ^9Ce v8$j v'"RU^q6vc5tz>u|!lLY7e˖QPP@SSNדZ?. <L1C>N7i?Jt199ɩShnnfcXfp`6uKQ(DyEu|T> ÌAk`$!HA5XTqS)~ؘ =)uҩ8FQTLf;2'  gϜAU|>s3EAoo/@k`pLT*EoOcc !(g2p8B׉31 (,,\<E*n Kf+WՆX'#d2SRP:4-Qz oqRJBLMMLtyۃw >RJf3U55 A2q"xE\.V`jScQ&040F7Bd (;RJ@Cbpۍ!NJf-BTUj*210000ؔ 7'ui,X?yfR$nb````isueœr600000^ɇRHi8 10000r=恵*2 dl nIJ 5MRnLT*iŀK}sƘuD vA nrq{f5_ WT&H)y8v:D`W,7n"cEJI(TD&Fo. 厁,0]g,Z&vvlWyq9v |x0 SC|AF?\ǐ帒knn,g( njLMM'>\+v;. eL&HH$b2d`6/.N399ol|L000000000iB05=M8r!0֟79tq4-qq < fE QTTta*ddtbی61#D2 V3 75xI~~3xՕ LfR6! RJt0q,( HH\ y%AlHH$udds000000000겒< .h"? AB9y_:2_1k̟cf~ eyO1}t!l~\gRau<>}xGYJpj"Dv]+raʤ4b2Fra➝ t1 6wE3 G'Ҩ67|?rCZ2TtFC*./~}%A)N]ns_>+)Ř=(cS ‚|fq28QtF /rj1€Q,HiHT|V>+{BQ7Rkl_voJBd&4)MGۋi *PHƦ&ё„#,*.EJymP&\4ŧh> yWV囝 kGP~xpX>E'dwB]#C06C8߹'+$#A$7 W9bcb4O?4-|O^y!d<2+D N9{3J;vl+PˀB_/'Q2dߙQTUnNeP Lr=l+ܾYAKEh9?g4>w3 1':$ ]Ӱپu9vq+/rݸL>/reLՂra8w^9e@(J.P>OnirrHr}]%~ۺ#.vo1#/"9ԡrq^ܺ0Qd˂62 T-XT; 2 լ.$9#ydvqۧ)X{v"{>NQ͝nғ؛rrƮ6>[2EU圳H3i.%@M?H8=!ٓ8=E͆ܶЉM xKi)p/gεyfj %.Nibt2h֯c$#4=K6r'iijoh̢Gɽj {v\;%k-p#$19@CC3#4X\ͤb3S\YÔ,Ķ_e|䒀9Wi2 4!Z)2+v&.]I"bV/-%~g4& h9EeFS[Dq;Dː]un@U)хś`{G{]%h'{2'Cm'y㤼x xH=E{Mä5vr!|W<ӽ, XYdcb+;F#h+V/1\g7, nz$I`osefbfuEyŗ9bw"?EcA7w0)MXN 6Oxل 390"!fw0l|l)x')"7=/DPI8?{ⷴgHMt+o3$۴%sĤ63/Cd!;ݤQHM/? oaddV~Ŀӷϐ$&<Wmvm2*+PFϰ6dǮj^ yU*;uwǾ'_/gy2M'8U@838v@a3=Ӌnlħ'γ`ro-:;oxFF(׀(:O=M__ǏÛ zhyob,.!9gSirSp9^iw1T/85Eګuq*q5zɟ#k1'8s:8Ɠ?c]h\H㦠w[DZM$IEKc'6Φ4 h҄l&/dHd|t V̳tW??yh3sͤoOC2S][VTR4~H+k(,#&nf BH`s{mL*citNŕZ&|/vo.gie ElߵxS t$ɔ)n+5o> +u䏿2s<vw$ټs;Uym-!YQ |}%Qܶa >r^\`)1 Yhf?#J:b+װc #3APZ֯cۮ=ܿ޶&idz.Z[z=߲M'Mְly=۷gcx* ZI(~Y%El~jvvzXT<[;qd ( Qd/^d$E,nf֯xŖMWqRt:ikkNDیcۮXWo߸ Ka{x8 6x7XH(vnc#ěWJ:K)dH3 FXpz9DQl ZT⣭ԮaeM)%lܶi~1⊃6u,[\0z0i  K6mgCM>WQ}~y=3 n~-6{y0~s=_-=@gabnA1㾮:l_̓ӻHd[yᅓME%w!<%,[/xg&ZC`[wnǭgQh#YU$s ]M=3A.ۭxvYx]*ꥻtMR^%9pMzR%l ?@\YW`rޯ?ïmJ=(h=j6mguPEu۶6I-,3,QHb'^SQN EQ& U6S3$l)Ʉlj6e* N{&BFP켽>$ߞ/~qE T?4N2T-=AéN۱=#A6$K. ))ZObwmd3=*EMo-5-&f+f@Jjw3Y :Wߡsn^{ X wގ3Jma>'6)ye+V9V/|ᘕ/n":{utmd]3/A b45%w׵$(eK$zRiʽLX=A* 9zNԜ:=2ȹi*BjڧðL000000000əcf>\4!躎p);{~I>AQ3tv;F׵l`LM'+7nw0(`m[XRݷ"LNԘ'KKڨYGn_%1x$$io4iRC Ghc,&-@qș5ج|eyʝsQu,ylYY9ٍϜ [,ø9\Zdҙہc|ek>oxg`jAҺɠizcmVng?dkZ|fb£i{:c]ڛj Er{ŗ(:~Mc)#w/vN Ԝy)z;:Nʋʝ9rHd1=W܃ f{ A3gl{7Xu;v]絥+٘ubq&S utatQ#ɬD3 hk4}~:d-, z(i9$:^S\$.}$B5a֓$)tY7, v &淵\'t鴎ehq~|N {IzbD2`|Rx+wJquDzC'x N'H%c 3IY[$x#*ظfE%~BQk9Ƒ6(R ˩,pQQ(/~HT"IKח{]^~4S4}݌'$&[d) $S9剜.g01EUUI&2ZNe8+)-*,#;wp.tY^x F"%&8֋yA"ZA:&5ESD qE GcDAJP/rwd:0CcќJuǽYjגfq V Km=<#1dSZ}IgCIL.a٬ B@GEUH5dɖo߇_ %97p-H)|чT'*L&WQt_YGg_ypT: Ó $ I'*RLf^3:/WI}8JR&UU~w?zQCQHg!ΐIk:Ŭ^*9sĤHL32MݖYTU%JOev;'Ó }eNt!E.SЛ"3 {K<V]Yp{SGHE(8 _x7>*J͹ESPFe>*o2`ǧLp}hettY T;D/ma7؊fi1;o^BAvG3I~w e}, p q8~N1::DDIY1bi}8 S7U8,f&;stXaيXTSS{su²Ex ^Ubc?pxM \/Nf4vmZ9> O=ɾ(֭%`.<{N~}m=KJ}(cv'ghxO<)x, ZYy}ٰM5EWlR0~>H_\-6CoaJ))æJ[>4IYDeXI|8d ˫K0'9mdqJ ~8G4gl|Kp[Vh#-$4==Lh^ʨ.#ww}@Cg/ĕUe/w#},ԕQPR3CC #}ja=_|}|-Ύh,mb4qU+p!C]/D:ajj@ 4#|bǃ2C((Gtdt.'YWaq)rk;N53<1pbN>8B4χenфTҜ9u(c ux}B~>ۑxG#a<grbvIͲ* )+p@t4Zw3yvBqtFH jBL݃cthǿ#QPǪ"^v*źY> ?~v?,/wq^/6un7wkOLN1A7Ǥ7E[3Mdl~/YJE{^`>JQN4ya$EXi;'ɯ.m `K-H=``:(,-k'gB(` 5U, B@*2Ag{;} jKn[zTUd¢B2LFR.k3̹&&vj-i Cqe Ů@hIN"c%w֏loaDR[S5nKL9AE- 2%eyL"|瓓LNNQZZr:S=?ƔfeU**ncJ PYa|AՕٸdzΎq*XLяcJH-PW äPXY"t|!/^LDlsBj n#lgqE>4v` Ql Nmsg?S%1;|TUWwHEi:ȴeѢrÝ $,^Ta"1=B{[CKY\YMdt̑{eZ'pXMEObx*PM (+ 411Qd%C.ƺ8:b~)GN%* âE5l,QQ^6O! Ct&,2.f{fp$#$V"Iբ90]57?Zwʳ|b}o$e,y^&Egf2v5[zEWCu16*"@:6NKS/β])2@G+K`IL5FQu-E*FpiW\IU n-f.-(hix_-|XQH'Hc_g.0sDŽ{l=U {϶}!vQԏ11KVJyy5+l7?eѴ v哴~g~.]ʫ#wqŸ2;׮;i 0. m)lT".2$Mh%KBD2oy> =לwVKuuqY]`g]IIZ1|5K_\-̗k w Cjkkfn}?w,W{\mH5>Q y?6xbka*<.+ZZs,ԟ.e2h 3,_r\p:)G f0=5͛O3oTgE|d+y, /D4 i Olل&VnOʗdR!TQCy %Y_C``````````pK!EkwRJ@ ?`|MAAv`( n~n][0/c䣸9ܺ\=,Hy|=>g9ѥxc5ʐ`C`````````p#H:H'˅*>|7/|9 h77 99C`````````p"j019:^F6d:c4Ld2iPc`h4j];6 |EQ,C`````````p"H$5˅띧HRbPW `04 FAaAßv1?J~~z.H2d2 (,,4?C!PUE!$4EQw:TUU]-,g/L000000000೉X\^bbׅL000000000000000.j[$)7-s%c|̴9<2aJV[?)54t(8芇 -bf'Nc6?b@b6_O*ZhL!L J1&! Vkc s)GtU&cJ xwH9.Oe322AaAp^E2d:#i@a4]aJ>$ \is-Y{c̥ >M O FuXP0] ( L i`oNUdo`pQ@`R&@P@fC"}DnLWC"rcXlpUxx$۷M"k@)B~y50 @al`|0K~#eB!Li!RKLe6e```C $cӌ3Mc'tR$L&:5E(RlWA( Jn@:!E]/>Cm[XWnv+|$;Vڋ:H;ϛAd_ڵjw$T.0sLμwl;H]~ą=IO{#M4sr_b[ !Pr~υt!o9c_ge :.{a @Jg2wlsqI60yPʄ`3w5wr߶:l";8 ! wppb̝ڌH$Rpk%ar;ض s=|fP$|Fiu%Y^ )7&9s/Iqb)+b̚]ڰfی٘2{l8ciLz.F)IARiٱĦT hFT,h6sKd"hbfG(&A<>2JJYHMA;ڜ9Nz>*tbv91kV2{ zsmL2c;#k;ǻ& 2̨}9_Nܜ}s>άg¹+ ?wMw+ǘ֯Tױ.ΝwJ(./JKX6vqSB @)/cqLļw#{|{A\zy2Ufߗ  >| 2;YVUyO_?β{\borbRgvh)&'eeHx44; f2G{Q2 &&'͜='w0tay0kfxf6c \JSRtͯ<2C|zHGkgv?D $Hu;QL'<H@#:5M,F&<>v0yGZ$'Oҵ2OU~) 34=AZYtIݢ DcILf $ a#A tD)σ ;+H ݓ_@CE.HjMWݻkWFHjۍEh'qz6qȎ՚Xn| pE~N?~a~ qZR0X&}#]'8Ӽ=lt;^+~ARJ+ٞc3S&dK,ЉNM2M",~ĆyOh ߾nJYek_(`RRGMp @"NB19uڐSaRjgR%{0B@-tpd4_4GCAq&+!uyOx}nBkRoCiS$Rtab5 $ qx@Ffz|p bpt f<>?(4@>B]W}xvfy)%E;~,kXbä'?;SAOװ<{ڭaq!|P H$&3ÿ<[AQ0X"ôvt·~G7?N,4>Eۄ{Қc'Q+omFKio)g:Ivdyzla "Nw[==N NY0G9s61@JJc*lwˋ>І+B^ „ӞU&z9Ka|h]r) 4罣<*a;vRmw$xk7ջ`?dwrBgz|T²6^Kdq?Na Marxo w ]N0v]Lysø"|{iIbzUPY_M|Ӯ4]GUMf*,RBҭ|e/+8EY^D =`)ވ[ޮ6wwgCТyz/z&9ج23+b#~BK> ? v/+V"@t41W1w߿2s Wz+31S/5\ȿw~=̝'r K3YƶJ;ͧq7Ɗ1 S45Dxή)|ژ>f"t糾>Z]ˊ =tINrl4cCtSw痸fεL%`(C|*gGӘFEjrᔋͷN]tY~sX7>\J*~cptCN(cσsȳB2GdIˇ'1OXs$NT,.ZM݌&%B(dx'iؽ{7ws/[U^x_U+j=XxN&ä2Isy5L rNKa21e۳ 2a /Iq.nٲwW'NriJqȝ :-WR[YJ;^m(>$d&9pк/rL|؃d_{[l[~mi6{]y$t :o7dZCP\7gw&U$!H&=ZZ9W ?q#Gͳ"ǚ M5Ya?*}LGc@jW_?FʶeU^S-+yG9ݹR34XY@Qxq9A̪uӉ4Rxpa%^ =[Jxෘ~'{3/2?&/ SiDQ@ĕRr*%Ba4V-a:sRGظWN=`Ë#ϩCͤ%+Z,TLRLMP] |ޑ9ݒPmT/ s>6!ܫJm?˹8= r**]ѴeM/y޷g5{xZ:TQ\gE! gzzKȷ)t+ dD̊Ö)aut)GHUD L1@S,xNY[KQ fycP 9$& ShHlR '_i:@p%5$PtKdٱZUhF*2HJf͎jc$^zΜKY:}iڽҒO*<NSS} eʱ9s NV{V|E緱 Ku]#QJUĞ}M<'9<29ٛT-4 0p17퐋Bh9>Z:IhKUYg⭧~D^1%~X~ǿgbYmN9dΤQ3`D~!DvBfRnۭ@!NkC3cI"beu^YY!xMM3?T,^BE(tBT3^~,HN%J{|=p}l6v~K}ڜh"v8Z{N%khhU"s.4/ឦ{pBpTJ Xzar-p pqhQ-gNSczq]Hf})0+/m,1?¶PA,/@ yLk=!\o[?mB^n zFRL#%hy=s&o$#x+ ӑi,!Ae&og(ӊٸaccse׿h(k u(FaݔɠS)~øKkY\Q b 'FqbMu[.otXxP>/|Ω4hC_Wଂy]8Yeh#/z_eue%QLUpd&9Cq$dE~i:Σ-"fl`9ZZk;oj$ȡr B$D w^#9r]Q1@qIEIluljTGA;vH꼎^}aafBH#-Ǿ˝Uc2xS$S L'JɤIӤ2ى5ҙ4T5224t)ڵ i~_Ξ>ĴgF|UX_dZ%{{㌍ Ged:i$i4/"|'©3M%DiM;Y?FSy~o^KXNc}t7 EܾC/_Ξ?g+93W}2r`$9KZ{z}o޽ٶVhYDR,0I`N>Drz"өj^}%OŪJt_}={`sy7߿) R~1/#ٲxA2ֳz|nìHc0\Nv˕\yEMU/AM*̱[h"3۹2BRH9p|)ʥc?p'+c/l9.R~Aʕ?W"aL@8KG7ƛ;ko26WygٙIG^&f2RB1$,RRh輜;gyq49SK ,b6+W?u3/?ȟ3(Op5i )OkV]E-z >BC;Ygطm˸U$:K9|ڮ=lEv  ÇxᅃU4 T7d͚v1v$ݸ|`-{=]VMsܹϾ@D?v~~^fʎD/z+n+mUUyy+==oLg!pѹ'Rug021==g#?k#!,KTXᕟ?ö-%imkҍAZ(N2R<})%Xa=$^;9l?8Lmf9S/TUkhLpխwBuWѱrW1ڳ7Y~_09G>'˝ 1%馫OFS49pr1YѽppϽyիik1>L - $G}G+շa Gص0d\V=$ .gvc[ud_W2fZݽ#dXa M Ggְa}7AzVYT5v,-8kkpm\[ʌ1Esd饿K!1;̞ [O36sLJ?-t4g ٚFjܵYKc[3rHU[m-Գf:a=đ#815뚱X4C¡#=-\wt4ڵFÑ{9|(;x2_7pg[:IyIspnMRƊs20ϓJ1aine硓2amM^boprʑжt"IkVUܿÇsu͝W!QgNjO@?W+)橗v1mZ:jN39|72uhh3ן\;^%$Jg[3u [ü(3d^Zr'?]7R]a,UK϶x} M-45TS= ϼƕlj&a ^*AylT&n;j,/y 4H*fŪ.Cc#$6olc8} :>VvvQSz^W"m֐-Ms[?K*L#66e4uee797AquQŦzМV2r~='6kŸ{xi!FXn\z žQr]lٸ֭›c7韆k7Ulldg?ѻ)끟>7}t[HsuD2Mӊ62x%^qISڵk ?LVRηWͿU. yr#!5yL|_:3/sWǚj0؅%H&xKhrhe\HT"# %gIT:0 (%(;%HY1Q VB 8rk0dppwGu!AాwJH$XBJ0xŕ)\D4s8̥e hz]brR9XdG/}o)LLN|9an \p$uK%0zW_,O* b:`^} ,(ڒJg'3019I-{4Ƃ+Sw+|/>/r敤<6qa@T[1XkfnB@Cdn/eX[?A2 :E3gatl 󨩮^Z a@X&) - |V&4*lks2 JJX$YFT* BI|{q4UcTj[[Xd"qJpBtMQ!c0.X,gH&1ѥR{&c#̝^ܿ؝y_/TT\x>I߯tz֖A󄏩 (X\ ՉYt.ATv,|Nڋb[/u g/axE J hR|Y9\Y?QWfnZ[0oo->8Tdʵ?Ϙ!A&;2WݩWA>c=C8WcEV e/rp100Hssp%~oc ?>S_W{Xg˖\xn~2uԒO$.a.l"gaZ~Lil=Ԣ/:8S?zK͢ft..SdrSWL-T@DrZHZ`7\Xݗ ͟ѿewpuHJԮbE})p 2&.jZ/.=\7^0z)o"yxbUDr}va,%H-:_Nʅm=|^$%?#jl,^o::ݧN<;e/ڟO0:1Fe`zaƧ`QHq;KȾudGyCYzِx>Tw~,/~r+S7d*쯬Nsϵk;nw.nSعtTKZ=%r_DD9<??v%S^?\F| q%zn㱧^м`Rd\Cyv!y+B sB]E rΑȵO|G&4QDbdzsOYz% kJz ߿9>?Zo?p^ؽw.x&ʊ: _a ""G`\_2 Wl;AmuԮP:l!#W[O#r1S "+O9!SSG q.CL1(W_x/"qW i2h" x3EN Z {]hBY!ی1- RN߯};LmΒ{c-V3LlIyJFoE~B݁G&%Gg)9ל [\{۱S| a;uE뢶\;߿8,.k=/]w8/ץ_]f:E^=?·8_ܒcv8[َki9\ܞiYqygYe/> g>s7ch-'\ZŢYֹǹ3m뙮 u,]d9g*g t;߇;ަU:aޒ yi½/]wxB3s׌2&9KŒ7]d|êwGZj-_u:CK2'fӡ *\R^\ap@uМ0YGޝX:rI䈛Y7w0< N& eu̞eY@{֐0Qp nHWe 8QC9mzsLa(hZ=(gEi3c! H$ 5 tNS`1tD..>!m`l1\>o Ck ah1ycc f/F׿pw%=CkRh!ZuJ+=ZԘ10[GwZ5WYZZ* Sm^lrjn eum/r9.mhL@9fβ.MҐ4ʁc)A2ahRf c@2GYBM]:|:g#h3rq" ΧsB99[,H2+:zև ˇk%mO0TveJZ ]rnT% +@צ]fSa4r.=3;nI夥TPڣ4plk}:l,h<~wH.0!jZɐSm7ܽ£Ǥ5t'2f*|2[t2t1*ܬZ}L@kreu@6i@Gc ]>N]%^,ư7 /m2BmpU9ayu4dgֹs|-_n7ў0zJb\KDaF M'ʼ6}=namaoF/Ym5 -XbX3xh>j (.j% w\ (B >&KP5-sO5<|LLS\瀆#mӖrO(BMrw\j>%BN>'=?r\sg.d< >7L/3Vx\p7ހt-9OZ>a!?<N֘eUol1/DqkRG5X9=pɀzO[R˭53ow{|h-sCC*C9y~%-[@Pr<7}±w8dDŽcko(Xʜ!UY??F. o;<3|9ڶjxrl&R/uyԚ.C[<>lX:'Zj<>j32ʆOv\<bǗ;< NJX`Ⱥߚ+h-~tt{|@6ϯXp]--^=6N_g!glh'~> QAU.ى<2x_MZr)'DՓ9Z{)G˼2 NCcWW{lLFgəGN22#%uStt|C9^;Q['.\c+=n|]uYB:xd ,_hNv!x|rp0e^Oِ^2,t(2 aO{s9ÑGzuzمqr2C{iG]Вd~ǥqRgM-rpϜipQdsy^~9|:PwѐZ\qUM:ɱ}e g8`Se/,<nl  `ܨflHѐQ uhRŒ&Ky&dO1Jc$$]qCΐx\g802ti6q#XN2 r?U<`0[lx2#GE [>7TR)-W^ޅ9x̿]|Q x`-c!JP,::=D oLDOG&CޘѕoxdoOajv wKJ*F7q\cF@>:=sRnjt 9<6*"g?4%`SGsx=L[nbK4c .O:~pS7Dwd&GGqxlXs:|2aYcEt9z* 0khGM!GCpR}mHȔ|+Z,-)jC g M2rx8Y`8 tVuy&c1¸Xu29[]^6Q/6Gl|WKם~ .:q9|Hpu^n2 G}2g*mhx_Hke2ץ3m~w{9w/ΎZ_[m.dNa=.O|㦚#Õ]b , *5uC]Q7ጡ@VzLZa_[SryMT8Ƕ=Kq&d6aRkI^,77Z}(τ<2F]ϱ)?JpdڱҖ4FO '*G;0\]\0:@Ȱ8n@RbO,xx"d쑴5t,G1tӎrѱ[289h\CyfjcWr‡0<tX$ !måR*:gUY:l1.궶2c,/24 & ӎ\%cpEnj4WGƽL30 ;k}1b~QZ8.E>6*kiUYxX L9fdR`)fe;͆.ϰP B&*Cfg!tTE$oO9>b 8wMAPMN9F}úG]%s _iIXo 50S9fG \^mx+Q[@/+IH)tUc^sKa̫Sp<@عxoxR/|i'`EJ&zB~r2:<>H .^G'ΧB>dc}:ٮu&NpmGq:d{39CkrpbQ ߏML|֧ p3*C0dqrVB-9ˍ (\\nɂc rk֝`PQ|5z|P[ -N{6ǵ/XhJZ0P+Ѳ&Xe%H I[CLZdB1l,ZS$Ѩ><#S}i6 W[(:y\]%3~;cja\7\YoYSMOh xOY W6Z:p6y$Hc!jOuX l+cKϭuQԘ&j`g|-9 8^ 3!?rܴ3 úFǶ3pmşqLxusp2DȝDc!&eRz&L% 5ZB@ٰR2O8Leʰjv圁RφChLpsS+뽱PrDoԦ\[PɱdžCfug*pEjË'8.iՒaoȨڿ7NecB xc&J>e3,ʧ7!O9DD#zFNs)Ǭ5||mD]n3)gWy9Ǔ}/Cc6*ݶ8$ ^9dxF-P 2 H/&Tpk@%_$204 U :f.yyP㟺o `TL$GIhJDB~,}IÊL4qtRv(W+P c}ݵ󁐋0KYg{BKPE?Q'<,Jˋ*UEGҋҟD4b9Xxc `2҆s̄nT!2s.0X4a,CΏ&D{'i?Kj,I1D&<իOJ3!oNE<å`aVᒃR4qZ/pU%9i(QCpёMF#.HV$glsK)Ȉ.ϵZ \on (Ժ->LDV{g>F5g_[gYeB OhPs2M҆*gABO.jntHPb PIjR~3<ur_χՁ'|~aү)!צ0y7.6aѾNvlq0[zWQ{f迫ҖkrP WW#u^fxFC,- ZKb9BΓ? 8R}~ke`<Ѿ,)G*$>w<uQ&#k fB9^9'}>gK? _ssax*duQל V;7 5LV|Ҝ|'1HHك#H{am|xGqL9<~wχ SyHZsgِWi__1eh|v':_X3\(cZUwNz͸wiѾv 1c`ё$L@Ac]eh*L͇(\[oi bɫ%CsK O{|d'eCBP`Gqs㎂.oLpOkeҍצǢF_!ptWg&| ?%89'a#'N%]:i0吟Yӕ3: 'Z,cSADO#Z:y8(h.- GCN2 K/7,O=2>6  ydHiM%J8lDOf!|?\w}~:R2RqXg A8;yKB`Ceq<2Y9#EHD mGtL2P(GIU[hݍփδ5yZ=iD]"$3B|_Eʡcjis]#<%zG%{p8Ҿai//9gYG!O._BDz}.?=R&] e&XtP,8 9f,w6^9Qfl瞚f+WB$+ c8tXkHUؔJCu2*O|NyQ/,-xѼeOŒg^t+&gӡ#C)4A+ECm!gH駑 !_d"eٲdcukdɝ2 7X.5te-wUC"i*{8`2X0=&7>D>^t7 {d1Vrlr@Ds,Ro.f}䖹nGG /.\SEN 0e/h.j&6 D\*!Wn: yjڱ19\tTgW.}B: 7Mk]k 3vM2JqPoLBm%MH!8.8x\.' LÅ^{A +ɐpeǚcǠ*cY<{i‡BXwӋRG&7sMua47M+¢&atd9Zr!ޙsPX˕!{&ϕ9@w#2Ggh^XX%()8-m(WP\S%+뒞]cю>W yzԱfr2@%tQE|swlE, ą.tZepO݋#7RNZ+@K fӕ'sgj&;eu̷=#BБ[xҙJW 9ZWohT5TGߢ10Ut,8r:$ ӎIw gڒ2䋎%hrC020>6DeT[}2OOW^k|qcG4y-#e*ѓa` lOsiǬ^()lDѝظq,MEc>Uu }Оl&KGc:4F!lHOq|:]_y{ ^4Ġ&n twghz+ЌwA ZМqaQ3Z>t[ zeQbXU!Lgjӿb=5N<0}׺ީh.tl;˃e2 ;MȟCʎ3К1*V?a#sL,]kDe1300∣㮺)"P0lǘ1NP@׺<(*+(!2C4hБ3pа8V }=R6m#!#aԛxWހnaaCrx'`_Q0?,. r Д5ԥg{GCc}n:DŽ|5s;Ax~ &DqU1l]Ԏr#e|.\fr_hK*0i L?VehV؜>̥H@)C]Ұҕ};C!a Ֆ9CDZC DoX]`59Zr 9^2l\4T40Z[|E(nudd3k!/L:!M;6u6ư%gݞL;<:.+j<>QEKʱ109r2oºخ*Ι'#G4gmkINڳj˺dW 31 >c6X, 9Zk}>P= y0Ĥ-sndK!CW+9_Bѐ#! ?]þ&AmP¶aG޼kPT V֤tk;*5WY>f99Z҆uKRJ>MCc!}r}MթhҩFy4 }B7I5 xq$<=ޡgNytqJ5YjBK=>ظPIvkãv( Hh F:> - mW$;h )l(<:p 9rCǡ|Pp2}$d$p4PkLEOVZ ѫok`lcXo*:w҆ؒ@2U>2.eeύU&z$+C^?𭞐*KC2 [ޭ1[v}}A& ]wM:6Fo0aU`5g"䩡d25{(9f:mq6WTpK[vt =QQ=>_ 9ntSTН#!g$$Z>!cM6X֧+ṡ|`uۖ.ct>ܓy,:NE*g<``x_XHL4dʕѼ!u9c؜5Y`2;R^`!6&gynls)#p 3wzNj*_w onwsS̷ 4 ppq Mk-|7R[ɨ-wu/8K=PU3t ^4/TC":z!Ծ5TѶ& `>?wTPȾXMxS<u,FMCt8k&K xh5z{>7:CoH5+ M~b2Ȥ-y\ScX3mS-5=mT&B+<Ӿi3#XiE6DޱƑX>*e8:W^[vg%:&(ZQT.>6i#ȇlwFݦ;k-ڬsUg?:(G.i0 <5NSE?eɲ:chJ[:=wzl1?SƒSoXSƨ-gqxuB0Rm%gY9~WZ8V{\'WH!j-5Ж%/:-U>f-6X!?.XmhLf!&cKR UqrajɲhaߤVLPivύ5YGOiRhZnoؒ3LGLrgG'UhxǞIDŽ;g-zA`!z~[UYhQHZ>f +08 <6$ ^Y<2%Ǟo*񩐣>v2zOE>zS=ӎju8Qsf6dc6y\Zc pbQƚ]>7Bd30ф׵xf!g}͖K-+p`\- QOk{q@]4~a{)\hS?<{?6:6/ugďz| k ar`2ؖL4Kh 5D MEU5 KChYVer щ:gKS!e% krviG m)CPr[æKhEG΃r8:-c;ͳP(FaS%iS#*ʌ!'ѫ!sądHrn}3=a_#ڧ-) ²cxE3!~Дt0`E]<ÆBwƌaU&z6w/d謲4' TQdM9ɩpMUfѻ*:Me`h:x#z@WP]bhicA[ֲ:G )DIGm[ʏI]00(q]F=/f̽.s`"dOeS9k̑E:3Q#pr:rL349ZԤ}(/ztge:ΜzLVT- |b:=i7ArL7aM%tLFein\k6ms@88;?Dduch`C!(8WuT yd tUYQcι_sQ5pXϱYljYGWZRћOF\OFͩMGےrqh2C;k`u=y4:ttޜyaKCS#kɭX6`dd8[E˚uWʱvS9a^t>WUSn ڳt4?D2LGOj|CT9KBtҰ&=nd*l4ikw1.M<}}hYVVUOO} ܔ1dlj%u*K!,/% ]9C=):L;+XXUeiKA~rz|D؜߃U9KSP.9LFuU5}d"zҕ4 NG=cKU솴auU+!HXV8g]Ֆ!(kmpxQ}m.$uaMuӻXvZsl#S͘ϑ1#L̄r4TRɐ<_SeOTTnlYd7"9VU‹b1jӍQ}+c(CO-6X1w웊H*uf !&KW5mGϢ\]ڋ0 1[Se*ue4  jsw\srL\ew ٘kK5`~YaB9̍Yl}f-WZggڱ˽kr̿Jgg;L3WhnT9~sgq]x{[e_/yyz!:m=1J% [Hȉ2z|{,[Z9-l)sgJx> 8srכXpʱ9g=풿?W{Ltt:Է9m_O_gOg's0;LxE8^q/"""r* +hR4yg!5XDD„sPY_ 40]ܻ"""""""408+U8k:㡞:> """""""1em&8`mk-eJyϱzsq yODDDDDDD$ """"dyK3˅h¶4? """"ʌZoO;?wXfjj^.n$|naĻ2oُ:~<}|Ҷ131L]8AFaȻ0 Cs?⟽- fy`/%˭"xKvn{c!$Ƙ?2 TL2]  s,՜y糟.wl8>_`\0cùm~>~.(2>6J!8I& ٗv?[zX8n#gcj8>s~~3=1B _ ƄyiM~m3pٹ֓}i9:nkst\p^~v EDDDb<1Ui\qщiB : t>>w-UBT<-w]{c? ~gu'I_Bpa0n=o O;h~9m cxc;/ "GWrњ38g ,02s5 Y,Ocfg(gA}OȋVnl ͧsユMٷ=υb]W}}e[.~ʹn:꒸4>ƒWzKٰP`SЮ>x+3HLWS0p=qUvyH+oMv!S=<O~#ü7K54dc>۵>>8?yUʫnwy6 =*aZ.][da3;>ǹ7Ls\v%4; 3=!Gώ'y!YԏogUs5aG}z {n6i7v񖻸!Ϗd'W53xxv]o;Hdj.xG=mb|VX-W^ByO\*P-jѷgͣ;X7Ulnbc\q&?SvֳeU ˌ[YY9"/Zs8yŵqtwTD>ȇ> `=<{JXKy17cgo̐HTkiPa GJca~ ƃ1X dU- Ugh;LnvاZóhPWS4NnN4$rS{nK[y04z'~/geCk.uU'ɗ*]ʃ<;~v?W!nd%7d/^^urAB@=cO?0;hDAFngnfG3\91IΟLw~x&;;Yj>sU+1sӗp掣۞ߤ'+1:~c8ċXMm6I}znV+mX$Ӿ}x鹟9?5Lœ/s[hnqU|%c{˼Cf_^Wߣ'|V6]w={m<9pNYGv5xr#;!C"]E}]D£m\z|U/00S?׬1sv1\8f*rYZWܜ9/2V6֞rY̅|eYՔ#ϥ+8 Gfrꚹk;u ^zؼWr:xyz5[.uWB$Xx jH%5hcEf]t^9Ɲ1x=Fʤ¦-74>ώ϶:6Wpz,yxR.6J ֆ |˺Ҽ9 """nq0U՗b=0t=l/SM׺>Zhb8/|*7. <8\Au٪v?F KMk.#u:VVSʏsѩ5-+h_h/L31>$V7cJy&LON״X=r%{{994NbE PcL;[ G2\嗶sZ%WUG2ؤXk-U+im8B}uZ}jE-cNxr u n<;wq}ڔ'y'Z~>yK][744p?`ۢ3M[uutºw>}}͇|qd(]+UAί_^E=&&;9TPL{k3٤lO Q;h2{1t dCV r-ZѰPNO G^zmT6͏OִbNcOm?NjDϾ79ՆGL5^rץ4zjGo)}Ƨk3u^S9AkJeIz }z'a|=Y/(SǮc㴯ȉ#$kh[|> DDDDMg,j L?1{ټރy?d^ۺE r+:ul}UFVfW9[_׏$ZhM屾F~;H֝) ɧ_;ܰ3aC<ʟq&V%1zG^G#++۵|},ng-q IԴr}Ұ}oX *gر{? _]??L02dQ#!4ד;HL>#ܰR^}ώr5BD"uwd:G/.АHG,dƕf-lyCpl$qU+k !WUmDy/<Onk3v\>A48 }xS}^u=e-^x7 PU5;Dǯ%3\uI=_{t^?EKKvas!Gy$KZ&(3:2to9L"IS]CLCcmt\ڞP( yOEn( cqNUpI,zD%J!A$29:VDsR#y6Slz|V׆w'xMOLec#=Q{>Gnڄɏrx/s <מ~7ſ+qWxc4&ys6z۷VW?<7W׍YtnC@_p#kHYpn)~DT WKs{6S_P/tlɥ. Բ -T狌 3:9x*E6Qiz -?x#[J%fsrp(4o{ȏ3u|Fɗ02[;'I18΃?zٚ~}?+_:~?_LzѰ0C3>WdXru4̎24wn޽Kr`[j9+olj9Ba""""4C83c#;X{ˇg??>l<t5YߖKtpog-genxڧoc+q}rGyҞ d\Nا1cj9y|Z5Ӂ1C߱^&%Mоz(XG'[ukX yps I2M:GWqG}cf:$2ѷG?|8D$np!f$d&`z1e^,7!?H"{_9=UJн_c#2R?nVR0N{((313Eg> 1yקg>>n\s'y?⅃#./p%HW5ic7 M~|枫J-7 f]'w<Wbgva& K\23;3v~ t2Mb4LXqb66+0KV+P?|?O_Lx=q>/;︌/: = O;>-49ɮm8>aΏɏK;Ҽ_g?>u7u'Oyr vu`>oo;ﻤ?ǚ͛i=ҝWi%p'2 8?GWzo,CD.#M5<08뿗P5[bfrieX &[_;BHT[|Ox`nW?4diOд2nr#=^N04+Ix6_}3DtǚrP^2YR\a?:6`xיYgil͐O\jWr+C՟O9T/Uw~_?7[/.yRS.iSE&{ OZWˊM;.?~`{@6UǕ}֧y'ἷR 70ώ_n;\XOP]K dx"@!,~r[6* ~5/U598 -_8AMS = M>c?_`}crdWsϧ'oHn|ﰭozkyU}K|εÿ{OEmCL:Gq@锞S%c9wtR_e5wZyosߋ(ؿ;dE} Vn=\Z3̷u/L!e7kn ׭#uewO|sZ:W6Ҵwl[׾elۘK7 a ]\vFx=5}Oh[z`=g n#>{})wC"ǥw|/} wz<7ޭ HR0M)Xx}sIHβLg `Jʥer SC:Mxk&>!ffl#w3V yzW'n1$Jۻ躮;}W읔HQ,[d{\$y&d&eK&ɋ筕yy)I&̚jmYͲfKV$J$ @(s @ @e>kA"n{ۡ,Ώn1|ÁĎ6m͍|Fm6S omx+8>,T]QBYb9:bX4,-Z; MiyxK+i=8LsB!%K'4ͣ/N"="nEr8ו#lŞᥢM'8r`"k_[ü $ gQfx;vp b/Uۓ5ŕbpm@3.[+?NncǪrhBEPԔrVS9 \wk  T*9R€pTE. O9ɥM2,_HiQ~g\h"sG5#2g0 \Hݷ&eδv6HF)G0y|Mz8Iviʌo{Fc*_übmY0:KodѸ4)*0|xBYqE$00g*²"Dc$"!""b)lT*.- vWPgN3/$b3rl'r>vQ}e @ۊٴ#VV޾?o#/M~P*eٗr_v嬔 r6Jikf^9j7_}ltbX {~>z7pBF;GoIKUV8Nwڒbn,YKIvuN$*k˨(bqF2j8D*K ֆI XMap9/^\k/Wj#8yRk9!ܵ"/ 8,9-<;ơ~0( =Ɂ)vBDžsCY4)*_Be IUW?;,YT`XVx~x%IAt.KFzv>2) LA?> c}FK8'fU Ksup-(t}qVXH2c8iMPZQ[HU ,B! C4-=4),OL;;p<9i*+?˲-eatG7,cAk0fs_R5e&KWʑnto?qupҟe Kz FK(qNWG r;3b򥄜6X'gϵ2qFXC{sb׳E, qB/Vl1.[L4)Hv>X0>b#7~O>>M@;x6me(N"g:s(edw)ci>_/Ŷ 2Hrn_6bM_P͒~Ν@"QbcB(ٲqK*\ CZZ($7 ,0w`B!i;GK#?yg/Y'7ndaY/Dؗc\rR]'Q6o?is=NpCbDԞ'X\#N.,8CN*y;(zyeGXq "Nm[Fz8*ٰvA48W{Z8z(?ő^pfԶz|JYЙvr #{u"ΊR?q3ZE䣟ơ"VO6RLΟljl]Yj᣽iL0!.fm7uT:#IAbkC}$ grVxۃ4c|8a~T1owrۤa^5pLiMpQ#-Gw6S cHjhm=.z`+G[5PHp-+Pgy7na|F~TL_\B֭k*mG{?|gi<ȧ>b.BCM)y6\'U {\VNV3{v D`݊zSV?ubby=~|NB*я`ױʗU`yEoge]1*;=8H c}y&kٰdBSl ^}Pa!#2M֛cÎm+ 9A K:G=:EuX=p?wŞY~^Ck6c~y2'8r,ZzTͧ=ĮWT,mM;wIqY ^XA.9B[2QN>˩9?`QY`So"^ ' 0\f%P"]ww,bh YЋVN NuSGеkذ'ӟɕJ!!B[G)EwgR^!kAꅬ]ހ#'8`_I߁2]3-2AQyͧx#es +*B/O(mBnETxq&` rh( VBцl|^,_B٣Rt THMM79lO͂%, ST P]^LAQK/K6[TźY^_akʖcDz`5s13B]sPO=#gs>,_Ŋ(E+װKW)nYGU,i[8x0g;,޺ zY'̼,Bi' ɝ+NXN) P)=],ăwFiAϙOx7*dNS~bx7|ʡA2z|NN;Owm;XZDYXi[/2#lٱEAEUC3\ƈ.ၻ;@[ YŠJ3sБ]!J Q>v6ҤFbtuuEɢki 0BYibJ)pZ %sD+j(Q3zO`#x62)(ϺKe9y8-}9n~?rd.|E Š 8tf`q Meu eEEEpXYr4Ԕs رmaץp8Hѓ j~ݬ-BiRVb[F}'Cr|R|NE]?s> qhMe]3tr,skab2`>ݭ~%;WLv"˱ z++JCpΔ¸1;vٳ*l>QJO{`j{uXO߬~1&.5ULYQ=9}x αH0A!Bʰs$I) 0;ڶ'%ӹΜ;WZ^;%J4xAahƶI4+ɓ5,_s5gIC2 9!B_=;hlbJڲ 6P 4$p+'gYLq-/# zڇ)ЕwB!į-1-ެΟ8g1,\Z7$ cJB!%3 $Y`B!B!fE B!B! &!B!bV$ B!BY`B!B!feFKC*nv !B!&r &h!}B!B!3M` a|5 CCC3i. #B!B_%LEE3~ϴD"=!B![.=43̙ !S]ο旹IPhl{DB!įٶ3 &!b20KMmkX"pϮ2 b yo@)4PJMklƶwmFbRFɁυ\_w^'!sN B!RhFz[ij"͑4څ//P7PPH'??edp)k5o7<0ľ鈥p\ a!8̪02ü#?x^ٖӼXmwՍs!B\S5 !bz w1l(**nf$r{5 WʞRU6fw˺9<w9(+-&_ŏΒ p]ܻn.c@cP2 +U%!B|!bN( +Ƈo9v_ k 7'ph+?:`xXK#Y4p`fp#9 ʔ5BHF&!sA)T.IONFX e׏ş7;ˉlaV{yO񯼋{/ęq.N$I([]wk/Gg9gw fh/}ˣmFzZ9q.vu<ec$  J`Fj) ;mTSC#Iz{ٶu=\!,ZlkMYbFo4?s9J@rt ΡX#_m[v~Bɒl s\ۘʦAKؾq5PkVcw$}=tņHR$3[B!~%cw`p:z[B_^adh=wSʹJ6RϽo"PN iK/(GЕ$#nR7oH"6aNujt0L0k$ C#IpzLr`'@8a@&1Ll(e8 RXÉ|PЇ1B)ȥ"e)#g˓Oz)BYEkk^-xB&ҿ휐`3 'i(F#o9HVoBϩL6K"Cx^JZF&!9TV@#;Ṿ~ s(d2457 Ó).*zsM STT4YbCnjkj^۲h:I##(`^}9V֚ -- p0Ar&LGdTBdgֱ׶T!աpLfǜiZpe ˿Zi zv7^41Ob5ayTkR 0Gny B!B!fd,p3 LSz&3MWC;S!oi0A&aF}<8}(fy*ZR(øt͡5?6D)ж-B+& qat `TP2mZWä-NbCD8>Va9'<!e5Z)*4q.͕ ,+N5]o(AR4̯(JMijjevPV;겻9$U{W&mhm' vt\h&:b(ktbRg8|iQc;+HuM9!CVBYRHA^.bP7=6Q|``t _7x93(W,,S :ł(-,Jio|7^9[ [WvMw-Sv3O8cdvs9PĻNR` %&ط ?4U)Ls uNaX4}lCځi|; Jm_S0!K דyx^O=?_u ck,nٺk06jy%@ s4B L0 ZxX,GoلT+@M] KVpU8-ΰ/}C0]Or!%ST!^O(Ŝ>!:{b؆ ŒxLpo'C6 rjgZډ|D<&LXVtdMjxtJФ p\ !Ĭ)Erp`b3'/|{?}ˢ ~ҶJA {X׸sO_ɟ=ïSW*Ǚ_~ wpy]_|qu%j ,@?i<`Sdh;ȞC͸+_ӽt5J\:Ʃ54<,_e3xߣoqe(*7ٳgiIy1iXv?!wW蹩(ɓ[wۤR475rٍk9rNEhsgϲn:ܗ-8;B!&T*tRgPȏQL[2$PZR_z ^H$' @9 t"gk  @X0 ɀtM&&gkqaFƖٰQ(mdцۅM6!k٘N7. \if +^m,[R1-|Ǹ@餸 (Γh1?0u(2 p5;&1=~^'CI&|`kJsI[:pq CE:h"Pm5&S(*,j #+ Ec 2.!ڶgwMeeWNظe-yq T.MGONa6ǥlƚzm}>cv>*&(˒drr(gy xUtzp;G{pEj2ڱp]{/PD.dz~k{^l ,v;q- RF40#gXu)nC0!įA1$`/}ڵ_kMOqYrդ2w᧩v 8|0?y_i Le;ʣ>űᫌ^ۏ?%K,k677o^|;O1zRt"ifIO320L;Ku8g kB|{D?7OӁ=t U˹sb Ax)_Gh(t_= efC5 W@r$C1uR]WK4AgvuҟԄCA#ĆBj*+ sF`8.̴i˒L&q6rrp<0~"ø'% Rpɐ!į5˲Gw979M;5p/.p S44DdviL(^aGX!Ο*NG~0Ja6v&ΡGqN]ԋ= !t2,L7D"R]i ܉R7いsΧYtws6~}#GsϱclذafLQm۔OS߃^+_ N 6ewLxfNx -^mx^?SO}ߢl>E>{j +MKn~K)L{w?#`M,qyͣܶ~+ų!eCz^{Ob7p,ŏ;hXwcq LUt.IGk 3HEEd/{bBCtH&ETw==v &pe\.:v 0#7ޯ! f(,| $M*d*5X2,N]ӷ#DCyttqWoxȦ2T78ߴG꠵j ,.@ qpv#Of_5uRb7iim{?0㧯AŎ)\ކb<ly'D"ɄS,\/~KIe\*ke^|~m]رcR7}H___O<ɱ_&N:~nvv|SN_0&pgvǗ;·8F+j.ZĊX C)aREŬ^{Z02)kX˦e!zr.XĂ"Jk|+hf ,/) j`q| eYhLKaa@NE&T4X#(©DքשK?3bs a{„}[rԄ◉vҒ($S)ZZZqxg=oJ:=/{}~6o۹w>}OšQ)`o& :.UTԗtYpz\,X,0pLN頣>jr|<t>|a7.Á vSnGfCk 5lv|Ca0 ḭ St/~xUwP0ed׈֚‚U[100?}CeLُvE}}|g@]ygYp!|ngZlۦ=#mw 3H8 ձZ"1О7oO>$ǎW^!NpGz8N֬]}3O(>gyky#nʀ0 V`Xo:]C\NlP1 0Gk"ZVMH5U~H ˅iJ&ĘvM8%=<@oDfJ-rt9SJOPX^A_&L&;vf͙xJ„0 *47<@OF ꥶa1E~E.g)_e}w? 35Dj{#cjn[ ˘سڠ|rKP(+i $37bmT"rAPx,5ZI z.9qa6-?45_R!Nwn+{RnLs9z}wX3 ?z9h!ɖ{h?‚B&RGs&\ ) ξSg)n {xs}(0 3 zla?, Z9jVt_h'aGzЅQ* at¥0)Zu%kGkilo t))a+V~x<> 6048Hcx)m۷Ç'M_ꝛ|!}ic?J)z{zXnU3a|zkll͛7csxwy2LH+5A,v&Kv$eLnGqj K: $H.N }`!h-*1{<;5ؖ}c+|63)L)JӇepl t=sTYWU[iZMjC{O?Wvޡ4`B{-?oն|BIudhgB_2aPZZBii csB.daq֋IfGN2,%u* 5P1uEpSg3y,eȟWRG)2GOw;-#.rYYm+`_ V֢ WY>K7ӜBɬ\xxds]9h( b65}^z_RhVΈ e<捷"3Љ.~NvrW H4٢,( J[oqzF~T+},|wW/ s]X(pLBZk+*x'S|k_Vlڼ˲xnq3lݺ GUV_;o R~}f'no?*3:v|ҋlڼyt"JK/rǟxklÍ/a 6GO<0/-.40 /rijkq8S><2BWW7߆Υ쏑@x!"!_~h>K"m' 4wehpTVL'p# B*>DP 'BP#?HQȏo0 xLP)H&$I¡'öd 4zZ~bZϯmhr t4 a8d2Yltp; lLkw;̉h4܄9?t_-WNLm,<2q;H<-K8!ĬYH«>MϹF^'=a٦m|THspL' +YP!=|^s!6Sd kAZ)tXd! q( MrdpRPmc  H8kbfe#. 'ՠ HQ)3w&@l _(Lsio+bxhx27  tX>]LQ[W۔6L!Ų,Ξkj4g6QPb{;O?u|G'-9k|+fIk9sU?n(E^'yw/~o|,_b;D4ZLIIRA[[;(.*ryfӣ'3+h>`OeEŤǻ{H$Nhkb>et_~|ǩrRֶvI罵˧$ vsUv㚰|ȄE Σ$Z6(_㿷GSK=)UwP_0ю z]ǁ3C`,(&X0q=&Vx| s3Ϻ}*1J]N%KM(tz((RxXh-dQõy !kPQYɷm:H:4b-ʠg|ʟMNalݶbdx۶?4U+{@ 0@̏ _x;6nԮ)E&oL%69(zڍnkOџ}Zc_e^|&x͍z[,ǑKb;DÁ쇞i=3|E!M5\FsƤfNch\k 0ӡSӷڏi^OSmB17^onUu51wI6 O|ߴuk'2 -[ӶC>ײ,b_g|@|R1۷߅| ymPV,aLpiH141*(2_S!gK+6!mf ty\.竼X]k)r4ptZ긞T=~ycʠ˵ڜ &k0=TOeqz|Y A!B4>|W)a7q՟x o 7MY !B!>4sݷɗ7|Os=y꩟зّ`,\Wʎ '_rH !įMt#4ןhJ!_?VyNӧc>﷚%0 4sOɤ\ !.\ỳ&H? Ql!d*{`Vs7,kڻmݔmۣ]lvVF~ԁ}{ m)ެ}R%p NO*՛"s0}ޛ^֚`0֚XVBpPTTtNl(MhclpLj `nFGD"h&O} 7 RVj1<22egR Q^VM~P^‘ *$0CR1@lPVB!B!~f>?l2^sd$B!B!gc;h5^R!B!_Q!B!"!B!BN?rzÄB!Bq8OzrR2~7d2[B!B!EN'/2O<[)B!B!B!B!B!B!B!B!B!B!?㙲#H%tEXtdate:create2017-10-09T15:01:22+02:00%tEXtdate:modify2017-10-09T13:51:33+02:00}stEXtSoftwaregnome-screenshot>IENDB`Eqonomize-1.5.3/doc/html/C/figures/setbudgetperiod.png000066400000000000000000000230621416454732000227350ustar00rootroot00000000000000PNG  IHDRQlҢgAMA a cHRMz&u0`:pQ<bKGD%$IDATxypy=3~7uHQeɶD>8j7Ǧj'JUvjub;V|H,Y7iEK)o}7wtM (^C 믿llllllllTnu|lllP23=o$`#حDžr!ɌCD|Vc|L%F֭!SЮ3 26667[Tl!cccsS1n<; K[;]~26 8bkSձspxX2?q"26 KAeB-)&}Ҝ W=RM +J Fј9x!#D(uoN`ao2sv-e>3,}a.!#@4N%%07`((3BWe{#,]Mg*&1Sa8&) @cGusV3 .5_g`'ε-"1+PAzP{SfN=¡9y,O|zӀ! Ic!d__@BFM|]IA~th? |w?@֒G3/;xwi3矤اޣug8u)̚'ث3Cux3SyԖe3YWl?0i<}OYVa) cAqh"_GG8Fm" ey,gz?v;j{)1i#0~ΠťF~Kyݔ=O } us=q'lbaa<"sOۂ* cw e`L V, : W;ؔ%(r  J>hq:c"Bd@b x<7fo,oȡݽ7P1˯MCM@ k~Oi4N1ޭq:\ē[ dϧ,*Wn^K -XtmKVG% A>熽Xcyw' ;,\ma4.o>_5cxuqMh:1/k><|+U+0z~'?~CrzF(B#D(]G$a͉a5CI -=JC(>-`Clڸ%DUbMc/3kxTz4yG(M~t81I^E }|vk rx7`: ^U:+btᥗ]ĸtp?~aXw4cieZ|q5VOwd[Ƶ]>CgP qzy9Y҅'7eeXUKXn=^F[ɴ \Β%/觿qr ǃk!0xIOU~:^_:Pq[Ym@<2Y@Q@i=udWVu.%8\>2ܸ=iP5.$b/-Ǘ}VSd)̢t?xX+Eȡ\ (b>;WYכU"?|DgXd}T)e͊Z._ǖ''DwzIOv{/*8?~ԮdeV>8ʢѰ@h:Lr2Lb4 GY6+´m#u#33"lJ#-%i2uUwɑ](aBQ݊Sq p(p͜k?㉏!$)" ۉ6*f]=\Hh~V<N9XYK(K}fG4݈iB mf,MsiDY ɿP=4 YG(DHUAfQ9g@e208L޼ }.]4 eA-|c.5J"9n3s4C5NCGS 4\^/BH\r Y“FEa t44C㭥Bɸ01'Nu-~V}TTⱯ|%5#Kb1O?^/TYW#znq vGJl"!x)LLijpݚL\KLŒxBUꥡ W`&FŋXst..t,AFQbR(Oq͓Om`ely3*385>8r@f;Jp: YrC-J _X> F@ Ye~h1'20 ̡+c#H71M7Yvdj*Htpp$D$R$G72ηxe"(hZKG),4wʳdThC|cBB;X ]d: Jq;ʯ.h5Nÿ(Nkֳ=4wE(*0' _‰AA|^@,v~>|᧴9_^Lvf:z |z^*eÚ+<|`͝FnV:4v0(͗6U̧8MZzbC4v+0]4/h,-NFB b>C^l:i8)DWtA9FOvC((sȂ6:; R_O36#ۥt7gIzG aTaAE)y9yi9}ZDGVQ 兌\̅ЁJ#7'<[#4tSRF^S tY9x"%k޽}u_ʢBٱZ&Kk?sW,_JMy1*4P:`7.\d3/>1v~w>K/$aN4SVxE'NqKd{h?Q0%P-`''Raώhbjrcc~X8in ШvH*F8,X sl3;G:J|': %Q+iyEVw/?r!bbc~0L:; *Kiqi#ZQz[Hϣ4+EkgQ$œL7Fsx/*":io (*."b Yy(AZz&>N:zFI/"#ǛSH~MhELe6+$5LsK+AEvA)E \C G^A.^GRPDiBTQXdffu!覣kɠ h0Kffz~{bdxQzp_p_p?]=Br-mRVPv t) ʸߌSԧ@HZ A_'!F,ڂ]<dPU;Sg]6x!BR7{)',)% MKv=d 'n #935rz34)e|XS9–oulP/Z!gP$R&M%%*y)e2="P|'(aL|IܣHudr2/kJ_!ٲЏDChnDq^}ÄJhz{HLHOMCr.4=~RH+ J&/4-=1[ q2I#s{/j\C$l|:@<7 >9+!s]KJʫn$5,볇²RH55AM[% ʊ20CC}٫Trq5ẒK^syAjrMnT\G8#ZJ33YKu'nCV5]+|!! vc̟)LS^& i^bw20;. 6ntZgAh:O~UM{{ pǠ8,^S5(K*Hs*z#<&3v#9}7 [\$R6[dT.ÝpQHaϓSqql]M|&-`2rc !R\Vޟ?E!>*apL4-J\&΂{C6SIZ06itv;BFq\t"Io1J>g:u %<κ 9D׶j?V"&Wpl?K,6nKEV.7p>v~rqx0G|c/{?qdֺ3Ե3{G@u'T* O_{f%mgڱ4ˇI%=s5O,>[=Ĵ,zODߞYq=P@/1 &߇FNA)Wd8z,͉1sf_lMfnH&`+!pƒ-_g o@szq $Qf/ͅۃ_XF#NQBP…B;,{p=}~ˋ/L|52%FB59cwfhUQ]hp:GM{rwN EԾlՑBD&L7+ThSPOSC mx q} L`v6p#'}C̫mg}JJ+W~LȤUT{tg j>*-,7J }&Nbk?? *I~pa)^hFZZڄAL$-c М~*jj(l̙]LCJ6nĢt#4锕Nie%V:I[l9B?tESO108Y鳹'B044D(t,3! Uܐn ]V4B(fpqjp$pc&8\n\N3&5Aq8 $HHBwcF[i IQ$ Bw'u376:EED(,,ch(ɴ!OFjTiE X2߻ơ; (h~cݦ23ϟw23\Glk *T|~ǔgSw;ǮxS25O6*$`8T>Gӝx}iW'26sFj7[M]O]P+ܘmύ26sƘ'Nޭvꯅ-dl掻5L\Ka 9aB[+ԔN8#;7l6x6s@`ZVb m[eŧ1L4SCwiy[aR.,.] OB<>čvC)vy[ N|FFFRuʌ\.~DW"FGGJս}-dl 3mK#|w;Mb -dllln*𿍍u`$d ?mƖ-[nulmll8nݺu ouDmllP2oulllllllllllllllllllll>?}C;%tEXtdate:create2017-10-09T15:01:22+02:00%tEXtdate:modify2017-10-09T13:56:58+02:00[k5tEXtSoftwaregnome-screenshot>IENDB`Eqonomize-1.5.3/doc/html/C/figures/setmaincurrency.png000066400000000000000000000441371416454732000227650ustar00rootroot00000000000000PNG  IHDR~h"gAMA a cHRMz&u0`:pQ<bKGDGQIDATxwǙ˪j===[xhDi]iN"v#̋3Ҋ2(K(Zހ$<033]O.q rPA~}_fE _\!BEro=mM3=X`Jybccs@U%o kD&<cccGFwW)\G.^ۂDU$yBw`}xk bTq-QRDGE RQiҦ^قZFJՎŵdSo֐^ҭ,ꇥDJe?$ȬĐ$cd]CJX';ge!b*2ya*f^܅XeMΏx׶\f%#`KHZ y1 $O!kq _I|zQ:܄Kxn RZl_NAO`d̜+r j<M@JtG%̢'EnHz㒤FBcEaI,Hd} MpcH:a1"ɯtd"Ѡ5^ J9;bC*w i`MH%>nİEr_i(-^2 | NKΐ)IצU RJL-% 3Y"۴eJ-ł_dC 㥟]!9ӳȆ# G;KȬzC(yi"s>cu:sGf EvbW&r,&tAڴ@ =bIɵCFF± mZH)DF 35xCRzU:#&sk7M2 Ӓ`3g)i#cx5AWp*a#rR6%e 05Eb4^CmVDN{Y,L&U}#Xك'{J(Tzym7< tgdim;7Q49sCgZSd)]}uՅn$`&:{Gъ~s%^x&|v`;ك쾟Yǐ/^ ~3E,IKb(fT> iޘZ1?\k&GM7*5 .`*3)%b'5%I#ۋ?-|є<;dқ\:]?s6\% ^լr}HR`S:c&"i9/94`ePegJ9ea)!~A{\T7aQ%b$RڽUt+ݑ1ܫ45׭G<ͷe&3O?C#MWUJ;PL[D y#I3/C7RJ*Y@Q:rBx\_MI < ʼnDU78N'q%3dwnmbݶ[QĴ@#pQMCb9ɏ) hX&tbB6[E۱ > q潽70aAQPxv=ᾍs$cj$ʊ-i*#NB%%h7(>f sN+6 ɫOkT%s]r3ŰdF6YPCC(*N4ȹDjˤYPM{V;Im]=nB6| 4'NZV_ѭ rW2+f ?ÔI6l)9zΘEIRf\+=H&Sȹ:~lOhP+1%x)A$53z^C_699/׹V ^6 kAGGr8bp-7RJ $ \+/su²Ab–JwӳYiia!97±r솩S¾4|dZUOu%[3ure%Yo*ɋof2-Q yaE9}De-c$]&b&~dP]AN"a,,3s\H(`|3=aGJT\ܲi{-i!["Xii>[ZiM֟+ -|g2-NuE*f\w>wui"2q)ʅiYx(!”B i*P(0LH&.5c"Q#Gd!KBQ7b:&t"D#/Yvڐ$}$S$󒻡'4kvc9uʰ>><,7FEۮ$1c^ݜiX.XIϗ?u Ӈg8D*coNqzŢ 1K`F΃Gfzvξ =WkI8vpnz&r;3/GPnٯ81=5l[co`ĕ7>ngU:.)I[ IЭz;|[Ң7aQA6 W{T L}q9J8R} SUnVI};JRbX m\g,mQ^+k=]7R4B8c M)R'h=$l*St O18NK ,-O~'~˯~ZMcm  2d]}Nz _GSoy*kucRZW1[^hMEq:Ssu/mY"[I$89J"Bd2K&DS&C8xMS"&'qEST>$72* BQޜ0IIKgdwF0>70Fqj,M3KnEBQ _NwJ7 %.9}i IG hTIҥ*l,qPA@&7n*U[ƌ a3qsHSqIu@8}:iE&Q!qIv&UTWa&ʂeaht \TVUP2cEaīVrώ58&bt`/ЗQY,cQTw|JWxŘ\:* %3#5Hd&c)֯tdΚk@BڰKXyuʣ.95W(Jo&|a13EPULܫR$03V& NMګM)JJqʟIֳs UGnIE*ENeXLRBOũ@,ayT*݂tb4 %^3YǧܧQ4,c&Fn/6;x=2F_Ɗ$S#$M",'睑HJfTPD (3ONCV?/R \3_wiIƉKO.-=bӑ/|N~+70ٸڣr;{l-!Cgƕ(6X2?o4 +̸ Ӝ{O,|{染 - g0e1g3 h( 2Qon+YOY^#spy~%Qα$o {iwzE~t([4_^;k>/ S) /w2?qw9"tAi3kCm-a{cYHBa]Ht |;Yk~Ѵw??\쪞6b.iU,֖.\=.^ۂ3C޾B5/E$t)tޭC@Hr^ %\Kbb+ml>Opr8y >MK\qWuD"Yr=J"z8㡥y՗yqbje],gm+A\B @d0{v_v5)lT{SԫP"='xsnm^ˉ\ Q;CyY($[yn;︋s %nN >/*?YCm4͕?(Nia:+NaDx?⿾?7DqTG7r)6PU K r*8i_-{@IM $(Nʛ{Ezs>Tw}}mv CWi_E] ~!iǹzK^:cTUV6 VR / q]{僝д5/2d)nef)\[S=dJ7yAf7j!LfK9g)/HWIkBr"k nf4ܾRݠ&@Π2g'"T& 2{ g Asl!avSkbldye||呟 M0t}p9Tl(_ct9qif'EW+E7(fa,Á" LK.oUŬZf ,+ђ?cWx>vn!2l<{NqPiͩ"ۊ2q]$E5=Oy?Sϔ%6?_>2ۆe^m"E-ru(NUSIKPdtv;@)ƇF&ӘMye>Ad*L 'ngpx\TWՖ 180dBRZ]Ki5rnBLJ&-PiE~c&`tZ'T^CE9B0# SQYG˭&Rgrh0iᢴ'S$LH ѱqbCME1ѰAeSe7`'!8#Qk) “X22h jk)pJ'F6 J.@N2Gc|x"?ʌuG`d"LBW)*+(D0 QQ© ta"Iwa5e>畇`hEqy^'OhYR^^Ecm9Vj7~O_hc4Z;bj)ToL4rIlr8a/4蝻uNGQy++qX F& PWPud$"n$+)+G¨~?Vt0Zڪ24c!I(0[/J'᥼CSg2 5U\k&# G.ÌETQ]^@:<)ᡪ[F"LoIUm !MO015+Ы"- G1Rx`1ãLFbwr2⧼{zjVPUHI?HaA`xxHZ\]ȴF'IK)F45F6)k}٪% evN&o V7f҈v(…C9Ƥw nbgǿ~ t{օ>yCgY}Ӄ|=.IA|S]LN ֫{1|. p?Gvx1c:N]~1 &zpf>HSc6uB`DG8zxٟƠŚHI^xz Cus=Pt"(Gџtq:ϴ+1Lj*Db񭺍)gSzr=/P z󣷸<OCF_{q_s%&JZ+׾Fe$'tvچ#S?) ;vlA r~-5~!NY}U|SqDˍr2])=Z81Es!tp#oAxf|7؅Ĝ^T3JljSջG1pe~QVnA NՍ#+L~O3]x=G^;wܻp~憊(/kg'.=qM x—Nu?irJzN+Kp$O<+fXKt#[H0!Rz0luܷӏ}V_e~'^_* =\*3w,&:SwFϰ̓\2x z4WQ-&&e%b]CE׳z ز75M+xdWܺ`t;iN(9ķ~b/sֱO޲jmKpOԆ5&>43y(&9=⾻;q )25xէn n?<w3:<:پe#QIN{j7Pm[^^bg<&Twk֭r;EN=֝) ʐ.R>Ǯ/Փ/^E}#e ;1BGWndMNv/?pllXCڕ8?4Bx47ޤ侯q뭍LOuLq}I= ?t?7o3TQ_C[q+_ܭx݊gk(bD`)CUla#ڊ[=(O~ϔf 95$k3# BUV1Y|#]G_.Og ~OP*F䜣>7;ssT>ƶ=ka&}gIvz?_sh.֬m04#]} Q{;;v|c[tnv%iyջMhx!Fעwh] / n\n Ǟ}3@Q-k[6w qbDBJ\roX__FEsh!g _mO..G#>p۹ϰ6 -o~wz* ua'SVT:?[i,*g8O?@SEbF'6ănpʹlΨ."-BM֫hu@"n>mh٭(-"`B?N+/|ӭ]$wX4︅&0ќ4 ndէ@覠b@[ɿgL;ܵ,([w3^()^:=% IAZw#m=pA.L,>`L} u#AaJ P錏4sBSPLIMEUu5x*. PU@]U A?QW}!C(HR^V#ji+$I$I`T@]4PE4Uңmia_ HSEQj+񷱦۶v(!FtÇ}0PUk?{QU,rXhc]'n+) RhbX6bA3!eTfD`gWmEUqzG9t<꺯ʇu݉ ,UáPDS]`b1Pp]30`e9fl(e8&%0-$'MkTD$f 63HCy(LLdAqDfE*@x2E"g<<Π;)%58nH+1"lR1Iie}B3X1c0LDONy9C.kcSa¤,G>Ot3Nj.bf-_} /~otŻ(q)3 2$15Okx.5I,VtY#2XqL9C(jF OH"eʜAZQf.58JzXIМ8sle1g rQ!s2c-S E] HrqJq}տ̣ev;Htt4Ց8l~XYCk^!\s2-DlIH N2sH#%TdG2xO&i#l|eZsGZ^ RZ"}j3wO@Z}^&c錧e051FRl\QRR?‘p; R85ZY*3i6mJcE2TP.8W`߫3mϘDTBO'0LiꙗX {st2N,@HN-[cY]d*`r |&wܸYD{IܱnKSuV6);K + ӓlc-s&'t<\/,%8ѣ'(X@KĈ&c K:XxE,v=Y$)lbUsVTh,FXOQw=+nX]HƉ1M,,R8DX</Hň$RDx׬*`17@Lzi^ %ZKH*֭[ ;HYu7R[\@qukJ04fWpuN&"nf)װa}sttu;nyZ|j޶NvE0y[XG;R˼;¹n_:pZI*+iXBu' ׳ǜc@wARjظH7g;P>{-~`$-c;DUezi"k8։e8)X\K  4ʫX%:JpwI-֭$%9sΩ8&* sMtxZIE40 xkPi9~HLҼ~ҞR6m݈H+)=~;XJsuqk>j(PLNE?L9zDMӖ@a&7眛ѕ&d/[aa-˛"</43qVv=RΝ?eދ-AVM Dip&eV\zD\הϋLY,Kb=Sf̶%z ks₶2SfRm;䳧7)g㘋L27 8o~;独 )Pap VHviuH$VT2u9eNt-\Y.fKf.:{bv! ' ͟97t@W3EtG>?'F09/b9d–EFD:X7KRX}-dt/o<#MdӶxxbAxb5yΙ}/.z朗d~E }US"Q\ .J/P__wAI0SB9˼q&&;r^=n[?0!d=迶/YF:$|4ԆX?8HtaP/;TSױC,\t9]W;"6666;L^Y [\c؂C㷱W>:崟[,SLbbbd2y(}p{h\Qf&5~"T෱Y!F"(B)7ejGʥntuu* Z6B0 \آNOo/C#Tx؂fb.q=?hEQu}8NDzT n\෱Y, yTI+ \ tقf2ʇNeW85M̗K66˙ܖB%\y?[C -yu7} 2斩^:W>^mH奪-,.G HiWE~-ml1ٕS Or1Lʼn_XJ}C=ԫc$8?y+N;݋I= R\W&Ü8p8nX*Y"Jv?sw$ܽ3- +Th,qoH=f9#eF@vF{)*jYD}U1s1?a!!6o@141F#gw ~innzg>M"G˧[wt;PNXޒ*BBvfE d~7<-_KՄǡlTۯܝer+O _pEYlOۼ .NxGqZ}WW677Q_WPW[DAGum5nΣ4?sv(EH늈 ,swh};WVia)Q\!e.,+#8LGXI L#$a5\2 &c&2r[K L#Mtz0ѤD/9ܿCSD>TnZ_&-L4Mgmw%4ӿ~S̃ۤ*xVjbeb]F걱G)\-Bhsg%rpJ36Cg{;CWT'6+/< [Vq#=Ο~v,#Nשt Now6@lN"ѩ1'Lz'[B T;3>HgbGO&NI|iԳgW/cPjV9t]kUEp Ұ{66SgbrISZlO>o|,/n/ZN}f}J@6>n-ʹ>$ǐZ湃C4mG|[i*罗~o8X$e >I[syzԖItr!]!׭R\Yj@73OS} 2q,WdrG).N,UKJPDswSPc@H"(c:֭lۼJb}˒JPH㍃clYG˷#??K].>a26ŒrAPpvP&`{x9~~Fk_`Suʻ^bpvf# ?SqRLuPIR@e( )=ۙd\%RftB_[U;@|DY?ebJI*2@dQ@yyeQ H\W.?v(XUd;Ic^x `J2X)ʗ>wZכ|Osn2=c<|>;e [61zP7f:kM<gbh%MaxH42nVg_?ɾ6ZS oJνSɗ9qGq{ Kfi.(|Djv)>y >K^k&ifҙ _f|(XBOung罟OٗηxHJ%1Ϳ5{|Bdm_L1yCxE*8BNΝ$ul[HIQS؈6{22иb!o{ݥ^LcJj U㽶.RZ5klhԱ м1ξ7_x8JVĭyLLLi~ߜG1.w,%+@5T-;p)Μmw;^"8DX` HmSs;BTRYSKW"vǃ[S_XxT!`ll !K !BHdD*E]sv;QEF$u! )˅bI$XRqr(IEP&Da؂fR\o2[ճ$෱XIENDB`Eqonomize-1.5.3/doc/html/C/figures/setquote.png000066400000000000000000000330201416454732000214100ustar00rootroot00000000000000PNG  IHDRq^gAMA a cHRMz&u0`:pQ<bKGD5IDATxwu<;9b"$ 3,ҵD۲-_gK}Wz~E]˒hIELA ryNGF,@A,G`jT9ꀍǍo}Tf_瞝4}D ̛]pO:pB)K ˛]bOo!~9YvKfccsb  666׍-@lll[\7ƍgaIA*P76_o i Hv(2jweP]E^_-~N!6WJI^>cg%!kH[x\[v\37h>k )%!lJJtg;QhiFJIW^w+`/ ŕ|ܱ>?53P/ӵ%^)BhJ1fy  5b},/M*5!.Il dJa“ HR*f%*i^n +RmLAKe+i(y qjb(c+7ٳ(THロ?}^-ۄ@&8 ~}Oê'nq8uC=81d}`n@%dMSyA| "6-#p h K%l5Pר dF2̌m07QH\qrH1`*:NRZ[iM Á/X@eUNZOFD>+MC5odӇ{pS,;صI^6K#cݜhOP{,W2 qD`fW:֗/x8UƑCywづu8[Xx(#X x\e=5A  4544kpp!,aui;5:9CKe**:zu/ěWDyy)9? 0Բ71G07V=օl;̏_?,IqK*!==9zd25yA8(όZ,\+kF~ajrJw3sj^P}Y)yKfӡNS||Πmw#yG<=CTБ%ߨשsrT_*[sWl5{ufnN-eҊJ|~Ɠ34LvJ_aH׹7OdWɦ~XQ+.yy[|1{AV-x23L9 7@]m @oo/}` 0NňE3.(ƙ֭kKR7o>>sW16Kd%ϬYې4>Ů~Oϰdg9G,_bs6mlILe}d03޽VE{ V+DfzbA߻JO;7`Eݛ7q84IBB/d#ttFKg6υ2St^ܩcsT"T5ϰmo"qw]#8F8c5ȝ[@Y=H8%zW0=c헂x<;d8ֿ#ǎsDzSDII*ǁ;,/ƥR-iYj K!mp=dIL[7r͊u/|+q8˿|CH niH8Ji?PK?y5 yu=ID:η_as0[\ ;MӚd,m(A#Cl:ͪ'?Y-mS8Ci Vϓвsoo]0x 7"j]ﰻ)&66mq){+l?EZ 4soA_EXOnT4,CUdLHJ:-ɰ>@P~ɩBMKC6l'OHs phdgvV oXˠᥑ32 ` =fݔCu vљ)pYR㔘JJ<ųo|%zw)J+>ܜv^ݰ+('[(uV.g0 )%n93k=e;_Br g[WgQ>Rs;o>5e;n{Bdȩ5(!P, Bʙܹ|.Z/[BKXA dѲ$Kfຕ]$YK?FgS1$t &K^GHl~}_ҚJV(Sˑ`(sSN2b$ J?tM X?9 !%!z +룼<1FOpP^V#RG>\QhWaN<4@Ͼ$,a4M$(9bKGhY3R}iqIj)x&{ TH%ȫ":8D4͹br*T tІ6?w=,~O]?Ք#.QKhDD*)Ȃ>n'BJfNE^ }QysϢnE;PI+ ᥱ:C@*s[qdKH!ťf݄T  NK?f%. %D|W>]"VN\ٕuA<J+ҊNF <{LS\YG}Ω'yreS2ҩt!7?~TėKo80~U 4^x6t1^˕&RBG44N0נnNGGG3slTv2)MIi>^_#!GmyuK)ɩ\kfs?*[ueM@_ӑvSZRiX`d)u? {:YBON%Igs') 3.+)9E,-pLD֑}~\*|^Af r 4*:3PK\dZq1+AScur7G$}qŅ(׭k gjEH*([C/#r]ӌ̶A9Ff&F<X jno>}×3 a$I?N(!hn9Ϲ)py D2')դ=%3R"}םUꜪEs惴rAN0k*rgO}cgHNU*Eo['S$O]p2^W~mm48NSG|2m"aR;O*my5,i )3(U`[#Mso $HIJIʴ,JjY̜ +?9?E[{+'=$=?yu@9WduҊ]ݒ@Pcs4Z$g ]YfH`0y 5.יm@qPwti* +,:GÈlR$Sm}AntAKd #&"; 5r55f:`g/$BcUk!Ki;ZYpЗߺg_ |x*hO3uNG%Hņh"c5<@47 }o>HG;] Ó)IKJa~D;t[Ym0BϞc'iDo}`m3 fӶ}t1rr))*$ZB@npk?b|Nh?>KG:ȬYPYS]{9sɥnf-T8p e0aS4ϦMr|bʊ 7t۶r<[(Ypw.E>ZVdNE]qBCYymGr7_AEUmlq..5[Og1:Cqbj+p&ؾe'aW UJI$g"Bh{ [UσEziŤ%X XQ( &-Uh:JƜ|:+tꝖչH#V*Q5|5.ar,nݫ+55jSݤSZ&A>Y{}I)`AFWP4Q+p9;] _FNd!i XZYʉiBwR!5sXːMS6iU}Yԩ rV>O99*l.lq _npn] E":Dh(JZ ]Cw2x0 }9s.3N-#!>+'& w8y >-H&9 (q_Vwt^V;kPjrEV).}N/%H˟KiNVk+Gۗ}@chxyxIWP ''i2ѝ^JS$u_Zn =R>"Åpq$7(Z PH?տE,HdwmunFBOb"Y"?Pd?%%ոTӦۜߘGӊhzt \&IQ P \fJٶ3IS '=A(4<||Q]GRx=}A֬)we&+̰Vu郝T\!VZ~&GXd6}8!w:_qIqܵ~9qh?+Or'WզȵJ]v.`~8 ns7}0\8wΞ>;ZjsMϭiFM @|NMCIEㄛNjfLW*|/ܺD3(GY]֙kNjxjY5KNg Yn][r+VM5q󱢔ß'Bi- f$M˳z-@nqtJ]ү=ͧ$LEGphnl2 p밮TBԴb ;U4[m2 PX޺VyǍT4a\ {Ȳn4b9|:/U[LL$Hd7ق*P i.tM,l2 R2ƫѱ@l]F ӀL&C:]~ 6WL)9{L&yRd hBl4NqC3 3 uHp@'i:!VA 41&Bʛ~rXӱsD%i9tҗ8]n9^@A Ԕԅ-H>AXqx3VHpW H$$=ka|"jfY5G~m4M=/?wk*`o1_cy,7B3Bq `ƻyo;o[CGӌRJ3o"Łxje5z+gϝ^r_E3]<ɻlќA:M;x$;N>I~xNܿVeT`{:|A>"hd{<6B")O#ʾyE0]TS6mԜEd B"(tz$2e~ JBNn1>BCy]%t˻{Of~%yUYX <"u{-T9|j; 1'yg< i+8(vPtlH8q* !2/I_n1pdjcm|G#TcVU%zqAFG@245YB %cV"(tUGLH5xŏ܇O5(B lU+W:p6CmM5wޱlJ5ud2$ipp|,\( r8HB@ =#rV %n>b<ԓUai @P^~a^>?luPxhAȻd3O#}[ZYt 0kɝOca+"nt80dr*Qgn0DIF䃰h2ơ]{34>*xq26Bh̛70?oΔk&`H v~wa)F--B@&IοoE 'D2:P$Rq~u,Vbh*"erF#MCIKW&Tdػ}'˙W⾬9y:'wr(@iN%IwvMPgY/K?˒r?f69@$"4!CW ie{j% r~Su3'ٷ}qIxu)R _`%_Z ]]RU?#D/Co4RL"̡Qמe|esYw|NE9p$wn`c'"j9GKg=]dblzx ڶKo'3{}_)˸{n1I:#Nʘc:sLOU)E Z;3䷾m$$8b(3'9 [:P*xIV.@܈:{SB]ipg/* uZN3'zf:ǡc uJ.Eź9t@BZq 7>A \`;ФxKR'?᤬~ ho#;y3g XìSf=KUC=Fsw ϩ%Hp!b (/ g'"N-\lo?p}ЛS!_Bm'hBGef0'ncΣqVsBMnV,vA]v4~;$-Cy(Ta8<3 'n!Me:I=TrɖiV[=K> /z?J_=ë?KEЍB]Wya%^_)E)/'!0v ( .>Ee U<Ԕ E{>؅%f8d$jkdw>{[@)4P'N<.3eLU\yI@S* RfPχYe 'm{O9ES: G2FҚY,wҸ"B*Lpxp0wnaב㙬 _:R"D)ûDa. Gd%T m7"x=x]h1ӱ7 6t:ivrޘRN٩ A:L RZmbsERx<9s]Ia^$`(ٳ nn.Gt:)))!M˸0BN'^wJ)n7biBr9z}u-@l }ݣԭb|"7\7nlbccs溱u3 sx |"03as9Tf7g|bcccccccccccccccccccsD7?/i%tEXtdate:create2017-10-09T15:01:22+02:00%tEXtdate:modify2017-10-09T13:55:45+02:00!tEXtSoftwaregnome-screenshot>IENDB`Eqonomize-1.5.3/doc/html/C/figures/sharesbought.png000066400000000000000000001341441416454732000222460ustar00rootroot00000000000000PNG  IHDRfDLgAMA a cHRMz&u0`:pQ<bKGDIDATxg}{NU8==9cA`L,kk{ݕwZuVHIbN `f0SXU螄0HWH@WwթSɠ((((OWG!}REQ=vz)~K? ̏:ኢ('hR>^*YvѿGbEQEQ>/AS((S^QEQA*+(5HxEQE(( ۇNrB;QEQ͇ ti>t+Wl.˥25 ߏ(RJ) r9?t+W )%}DQ.YB riMQ͇*Kir9uN{6 ,԰ۯ4 E<W%edzYR粬!I|ar%D>1Iǹn"噙Wt}揦]'0<£=ׅ%D{b&/f 2(ry}Nv"Dy:zd X˸rFo=Nʿ"u^}Q ]`s?<w(9KL6 Y Ѳn3뚫pj f>WlGWCOIbr3+!ְS^Uux ZQrXomaÆ 4s;EǓX8X/Iةw!ˆtō|wa]wCp%D/<TcǍA>KV.Nu xъw5w)._㭽Ljٰyu,z|X^^@EQ2ҜfKo2Y)ֵ$e(FETJ -H9LB @ʅmkZ)˒ tOh-0-M[k\2~> R]QN`EKM+ԇt<ȓ?~;nZʠc VLcboKJq7H濩d }^z.+ RQ[CMu e%Nlk#Km[>Y%RϵmD>/ip,N˛(TKtI6ʇfP)>d,A:G ;`.xx2@I ;R),DO DI@ 錁͡DY Ǎ0zi~r($+*e0r$Ri򆉰[agds0O&Ny4¯kU~ӄirnIֹٳMMNsr4̯Cx#C L0:]}B?IKMFIbmlj(Q,e)Kag]dt͟}K|氋񷮧:`'d6x#g)Vt>t jV´ B?;'mCE c xJزzƊd!NL%HαbBNHO~7P^o$:2椕'ѽ /Km0F 5u6fݎɣ| ?h/<>]+#aav7`/yWqZVڧ^ĺaݺ<"Ob<{װ}mAp!^D6NɃؗL? ;o$nLգ44ⱙikg]k%Sr2Rʮ;o&d@ᱣgƙ" H2Viu˗S=g8zNT R;N`4Λ>ě7"j60R\8wիɞ^zp۝[Ѻ{y|5ˈhvCk0}cYdh?5V. "ýi`uC7;(ʵa%6O7YiO?(?};L&-? = ځ۔[n!]2xLOKiZ+WrS MfdSP0++(鈰v6WjD7ה*TӰ:Bװml~k hVc)>uBi6<g^zz->}׍T.3d?HBW_RBGh6-b F \ٽ7S:AlXLNkUReְu[-Ғ 9h\ASM9666S2rUŨYOuw˟e:^>K]Į`In.͉!̵{k] eۿ :Zmg(p?;7T`Z͛oDqyyBwN T4RJ,#ͮEe`o$xBTh544SK, &Q]5t{ YC 谐r37߮tq9ԆCt'*$xW c:+Gg >Lܡj֔ .Ύz#luaJ-;m*+r,O ~&iv*[[(?X{㘢pH0-з MOYGbT-R#ΙmLeeq(ϫһ(?^1#gyq^#,)D9gXUy۽7KlI>tˍ?yo~{v8N PVc}qSL$&Hϒy-'70<'a\4Aز<Ʒe6Μ:$"}~`֛ϢҲ沤DųJ\ B8GO{OgOxl:I2G"1,y#O6/z'~<mm'cy,3O&o` ##o$ᣌIJd&"qb&<ƻ׶p XSaې^$Ns!v H)2X<%-l4;y8[;bg_d:85[Z;?yn7;8w8mF1NIi@/]924y)AZ&4쵰LxXRbIulh2x٧}4:9ud!- /e`&yDjvVnl7>S=~?N\Tr͌S/\W7mF-ݤ(0;+_# -!pzL\v{z߼ﺑS/N@rJ]EzVՕ0α.R5h( dG9qiAiE\U9Ux>,KM}~H{Ԯh2"N[ғLn:ZkLs#HV*:'qt;nkjfA2}7>h*aSV[e(9{$Sx-Wi UxEoM[_!R)vEIbcO1`;(%.)k~[Z/3E7 WS \$FJ<>:i.JKȼN8<#6Λ8\%TV1Ξ8A8Y$ Spaw]IJpMuR#]{F݆S_x.6=u)u;ևREQD)(5HxEQE((נekWo3שI[I1/U~*mJ· |>W*#,$Ha&AG^JGc#EQuBJJJz??TT_YHJIEEeeuR9WV"yѱ1N?/TYBY&ڊ(Jϟd(( EQ(\Tn(ruy½X (UE@'.]ťTƙ88Ο(ʲ bw ,UI@Zs٪EQMa|{aeG}r%G(\f^1WRO%HiYh\p{>!4&@ZXlhZ!e4-]m*ZBZѽ(!H.Ϥt˴JpW6M#s>͟ v4/ GK c 1<0DJx(('=Ïx]k.ۛ"`d"B֐8%TqhWSEQpyR4^ ,[q^~YNg>.»48|?o߯sz,iB2+|m&y@"8pt?/7ܑ $sG$EQwBԲ<)~~qϝwpsD&˕#En3ōB N%3pBwfͬ[Qdw'' V>AwYn=UA,|Kmһ+#GׂpZ6le*|UzW庵,UI|3l?۱$smb /چ,% mrABzKMێIN,#p4isۅvkSK׳ ܺ%v,)AhFP,.kI17ɵlᎭ+'8sޭҜw.NK|^R , BHux@~ZںEZ]'Ͳx"}Ǿ(%V5CR8Xl޼r i F|¹~8&nݸhodz) 2{:Emr-,qgw¨mo9k6!Fxus+w+)|jJD>8lWa}8K=@?}bGB ͅ6a9cfwgO_ vk*4zug8mwAY 359vnoh";=@g x4nVoLSTdՔd9yӢw9v,&n~n~QeO3x,#+1zvھ]7=&ce:뽁GQL!B˲~.ey,Ku7˿r=/c=,l6>:ϼu8J#o=;o{t錅 yoo5#LN8<q WlO>6N}Çf"MZv/xk`EQ"w!d2m" 7G饵]3Mޟo>Id UW7ܬz|N6VP$6h| >xV?S?}4&N?5R}__ϼq񼇦j&O|eF&2g-[mԝ%2.*dt;|8v~@M#e$O~x( 35;-;v}m%c]]D2G}EJ3A˲8vWpzK_'4~o%zyQUq`blkKɌ畷X_&e|*fNJ& ' ĺM0c74@ک]SDVq'3@l N|k tejXI-w季0Ցd([ 21b84fPid-wE3߲#a=|vC|j*K2ryKJv+׭Ŷb8 8=4jU„TAU+>Ra`X SCӴje/jVa׏u3Q3ZClCl 3kY_ek9-e-7SﱳA۹M{$rs`ůܻJIM& EQi)^#Gqt{&_U3a+V?|Z6Rq ]Yzp; Q X)s#m3cgIf,44EnhVh״=~S6[7Ãj}c4nތ2*k1S., !Ma;i~$y[obl|oeA!7S+䷘>XE> 1nRbvvr'܈n 6;N{vB0Ln/n~K_ 8.>ɥN]htӁMtt{R;qn*_9EΎ#TUV24<®]P___ ^ 8e]Rݟ_=Gl:!Ѧ8]!lt !.t+t[q?Ds}@J,۶ywaJhrOԦC,q%W[F#òLU-M;Q |RΫ kcs([  (;&옛]Ohz1f;eac*|[?$o}&oϾ;ͦGm'$C]Le 罴|LQ3]پ&$w=bYŹyb]2h |=PEڕTղv7}w dM146z5+"<0N*bjd Lݎө1<2B"%J05!cŞ'6SDiw$sVM `yDJQ/y噽9u||׏qMFt,@n~/+x慓iĭi!Yc6E>%4M˒Jg0SQ7)%~ښ+Z`W%q^B}w M'l;f>uFn7!&ڏ 362'ݣ 36_D]#aߛ蛊M28dfj݌w2,P8y7wZյlǔ&GyЋžԨO;n 1> vni\<DŽeI) g4St~UQOMy`3Tp#m-Nas\ kV#6\MYP[=qLBs( ,i %\[{ǹ&'ۃV9w$\:Vc{SToD'I%W^4Cbbz)o]GsUb79ٗe͍ >Ϋ1ee& q:'ҩ_QT|񃔮ĪQ!({4MMOxzE1^{5~uqg21'KAJ uK(wHp PWS+ $&8=Hԕ&S\"Xr%5a/xJ2g%TLwqk",IJZXR>Ν@iin"si39eOm# \ndǶatvqA=Nh U=ZVpAllRYQ0uwx SwS 7Cld]k~dzlJW4Dh^HωEƺrNgذf%A=Is G5nFcYl Mǯ%{9G4mᯨgMKvh4:@ts#2֬k"%4+T.LtξU+)՘9EQ]W˨(_rv~p$hòx(T%3_ъߑXm3m] M+Lfcpbe,"t]+t&B:kZq!Pofh醝lo24"t}cļMф@Zl2!?3dwHLR5BM\eqy:{} tYRZfaMm..4QlЌ3se{f;{oY,AQe]|HeCwmiYK40021LbƼcXAl wAZ>s&ł*0-r'ipq\wHk Ǒ_p->1i.qm -X.q),1Ix.L.{OG4 h׮ڵ{f(gs#9\XhԬ4l5H_(26K)(oOضQJup(3WLvORZA̻V&EQ WLvլ Jt8Q(W a/Kk딕FF(\+xz Ճ^QrNt((2UJ(W+)/&qOZ>l6 (W ) Y_UeL˃&ոp_+|`:+=%Ų>U&l ۱kjEQ|J?dMq!BUxY{EQk~$^(r ,^ ]ױl躎h@REQ@3hc4E׵b@Ӵ8{M YWL|5i\E/X'f:n;ܔUTQ⴩JEQey ؾ81ֶ6R_[סYFfh_?O70JF:bf=qEtlZ|cO8lV?~#ry4^~g?!ŒoT(uH@tϿE8ۜ!vɤxGybYrr 9s>4S.B%^tEQHA3o=ͷ>AyOps. +~‘gmC=´(_ACMwxrc<Ϳ R:H*(~np]_廏=ő hM3!NB!I:5E&'Oa38+!kX4N<2MBB(e2"-ZC[u8N,ˢ~T_Z6xMîA<$_zsDo%lNok$FfG8khcs8<>¥.4&Zqj6EQ는xk6Ϳ 77utO!t Mj1E BӐg]!4M0Bragl%ӥ8NV45rf{K)(/dD Taz'ح R1F'(+ QY[X?c a{mƒffR!'GvQ>7AQENH p%+| NÏ&kPcF"dfb4Ȥmx|a\΅1`2dGX.mש(UHΖ%l˱dJ [DK=4f{yLd Bogz '.e-\^`V~__{6$53@h@QEva"K8hVnH*Ay}T7BL9k!U.%FNz;ǦykXQa(CBӴe0=φuQL$aƂS4dѲTKѰA8{fS)ЊK[ٹ&DfÈpɚmhOqlyU|پ]溎KON2LL0rSyr*(,izΰ) 2;6`c9ӇHw&nO_{4P \C,4+ʙ1EkAewg8rIK1۶QjK ONM?04;=HG6"yL3ISFy*v< QyeV- Yn c%dFܰvmǧM3zvq}X]n\Ͼir#[Zo!?BU+\ U>s%zo}[6I MC>HLr>JJ31ɱ;?G_/2oA~q׍@/ݧx7{7W/O %%% SZ4TrEh;1'Kgdpp:t]4MOǙ"磷 Ps׭|I2D(-kHi`*Iiy~wK222Fʴ 䵑 !ݔ0%$ ɷ: f?j`EQ)"fbzkٱ)Q rLY*ʂ؋i&Rza\rщf#PZNm3XħǙenp{\.Oo_x*f'bNkz(/nZOJ6,\˒.Uu~oױ@Jv@`RQ_?\E@(\Gn?Jb~MA-K2݁0A I)qxC4J ߾CD_ZM \wwH.v_ѩj/zRb_]{|g~P\򻊢(5OJ tbCKaREA"gſ]͆vy{GTEQevWj8P(r R^QEQA*+(GrvSm)fWEZĒ'ЫsfG]i|vMwEQ!v.5.`Wi|EQ܂5A5N^l/׹+((S^U EQ(\T :jEQNrU)!0/P EQÓ ex8@O AFQbJgMZ/y5ΰ$ciZ/(d`),3ZkLێMX(U&E+mЮWC*EQ岻+AljDda2Ȓ  &&Zu((׊e B0M4, 0Ӝ|)%{Gu2Oǁ?y(#_. 1Ώ|1(|!LLӂb%-HYAEF qJE5}[i-q,QLoWC,{//F{8vh$NV:;Mh5`͎߭32pp,\8ye&Ϗ/YekQEX`e=ٞ!R9IIn޼m,B@6:ĉgJbn޸U5A,9vx*#TÍ[7Sw 3E$3)mZMW /mO`be67σ[ f+ Y\'CFuNjiGhʚzBApee!G)q+hᰩ1ꊢ(iWym;o~$/Ek+=?!ǣ~.2mD]H>Of3ݹO?yh^ Iϑxճ4mxo^ cϳnV:׾{ּJ)9zIFƯhy<Ӽs>NuC m;gsSʹ±i6- jBhmBhh@Bie!t}s^xh8QhZa_o/WBhl6l_ m6tMYLb664 9s3 t(r +=Fo\GkMع+`X,Ltᵳ6nZGw0Dwsjdje ܱ/sr0̍[YSrVv4yMFӼrxMYs]E6h,e8t˲xŗbefcuRz7.{29<@ T]+nO ?LYΪux 1]=8+i)!gha`hdDsxmGZF'* :~a0s/OLd [/#doo>iqFvx%|EQ! 11ġI֬&Q:"4Yl>sIg %^W5 )9CGϜۼMÒʆ'91ʍrÃ|?vsP{C]8eJg"zV^˲8r7ϿUB{YJAI&O~?o OvN;0`>smݜ?6?cH47y7yL#2=KL8=IrۉeYr8LzϝvNxoɌX;O<d|o} چh }yB M4c||o So'`$fmo[gGM %tIl#q\/>S94," dddx ;<žCQe9ecSgx̍7l~-`37An?o )4Uԕض|鋿ȍaCxgyx?UޓSQHl$3} .$T)}RZd9ty'2$3)$L۽́$O$0@tz0LI,"s.D*K:g,HŮ蘆eppXven/>6o'-J~u@u{QJCE% 9) zs˜6A0, B%~WWP8$|鷸5a1fb9~&5۵X2 M4q"wuoOOR0 W63'y>:6$Ěw )%abs50<) ;L8THfr̴/ =Vl7~7W#wXR=n<I0@hcۉ۾8j\Є*D+֛~JQHy?'g8I溈pWV&t}.͍L? oj!3tt[3]l|fciIj~lϒ0 LJ#%gf*!g)xg/0Wl[Zq_`]7Dm.Y,z %'̦mYY (GS11ÔqL=LYPp 5MTX:S(Ydp`@9ãSd!s̼AcEp0<1].Hx.jJHL'Ҁ@JI**TX蜤 ^`9h*4ZKÔWVC\bbG1G-6Pp&A_KtPnI`+{?z:O1̳hzbI(GdSLkn6mhf}b) 1>6g]A7aZd/MrUL$-kȌ0W%njr}4W&fDL3L]EQJ|F6n qdN"kY]BRv`SӸFtMc #ad_OI-kW!ϟa a Mؾo*vT{8IhH[X[rtb H08f(-!6M!ge14o$ojg:g8<ٰiui~>xCqnh\:t,lǚ XRO3H$3ḨF$SqMcLoVK;wź(mcjjڶ~ 15^;p ĝ ޿);ѧ澝pa-ux˒ 'zW$ |+pWϒ8``a5 4' 89w>p'-\K9pChFD9~~SZUGc \y&psyB#āCEE%V6('g:iQݲ xtgh%]Pp.QӭSZQ׌304$usJR -ln&2t~Fcz pYQ&=9x j*VTQQ[NYYy^M^}5 =ލRcSHjKltb,bsk4Dy`q顡G'Xn#-KNcJNY4:(&VUg$Bܳm%bפL&Oe֭(nмz50]}DL?w/B'7%kW;υau|⮭4(iB[͍؅ECjBr^S6v캏%. h\.Gcc= zc9*\%G1^/s _]LG -n `~O0g3g]R9׾?;`?\ҽ ٱ}V#r|0Kuu#y%FW|{ᵱ0 >}%92apW_s(gAQ|Kf!/|\}gk? DQjkkp\5`}w{(/n_jOJ6,_/z|ѿ%^>J~oZ.:/%=x6N lz/'\ nu8wEQkɇ r_~}ಲ0p_抮=hw;TN(ʵKF8ܱk[,mV!cY%Vpi߅\rqAEM !&$&VYB+LL%xI62_?mCL/&3B'\Rt1f p;T(e% >t_~hdtw^x34ۯ;瘜'~ȳvbT\L$g{?x4B:g_$'v?}{ !H$ ^teypR׺0ΚUܽkg[(~%K"m6c=.!p늢(@X  }:6ewp߭k h!y8[n/,n>|iGʸ۸g#3ϼArw޾{nm'y%BFy~_ l%xDh6ێnY-hipva-(K)MSZ߷,LZT/IJ,,K^,[UR.5̾,$s[:cn֒lZ% ļʋv:wq\Z?:)r`ĸ>B$G ,AͦM,}Q?Rhݲov=1?3F~݇{^n4cC%}^T9<"XR.-J4ʉEHA$_G~NA+mMi`,~f 'Nr?ArNލx#2YŮᶁO3p CvhhiD9r<x;wĹ·'i2q0c Yw[nXM+|Y4+7ٽgk.|n#?3{ΓG9ڳ{rs _Y!ka~'sbkkV.?{q=6ob*NC{i;ydBرcon/YƢqblڒLƒ$2%k7oraY |SQZ"9a1~")wپ] 80ŦnZ;YX ̹N^s y1-/wI:^R~ wѸFǶ_jNnMh^ύ"XC#O}r[r)5ðd]A,/]l0/|ӿk}(/У/- imĔ+o`с.I/By#"::ȰƊP*Beyy_665ռ(דB Tֱv'ݸ'|–_]CΙ(i ٔ OyC.@tӉ$\C"'"ɓ@8AJr4@Rcr,U6@0a+' D5M#1=ř MG+v %8JxzÙib]*IA,nV1XE%uyd"%Wȭޣ93\Лr*Ryg9ra,T -Y.6 1z0ymv۵0AQ"&p;us=X ?+֕Jw3Є@fLtW7 ފjNzG;~"<4U)o=ex*^@mLOhng[&L$O`ΫH3$S+G a2%J)>{WUןx7u10I{O^ch=]JKJ&)h4PG;oJv?#]LE;7ߺEy)%xpiJ(ʵCh1;!Νlg,z6e=^(4|7fe9i3¦۩+SQSt.Ĉ ]'SgSY椣,]Uxux(*karjT:*&޲jVT=8!44hTM31(DK?4AN:_z!1"X/UUU=v0sLTWʘ0+[TW"MN ginݲVl_id&5qzCTWddјEum%.]`p,%l*]50ɠ;=TVW᳿Tl>5TUV,zꢼñ}Tc/_Sá  %LնX j@4h ,7\Lg&Ƒ*v[DOwn(^E!4Q?s r9|>s%8KZwE6(ʵ\qzʃ:cy1Cs~cB-$gb&Qxƿ_9!\l6]9|MtcYYc \K%EYZs3Ii!E.v΋\$e.9{J:ȫE)\ E+oh-NPs1CJk޳w Cq\:@_6P#S uu3Œ(r[um΍" Z> X(u 𚝺7ӰEQqmx s+(4!_^#=>EQ+CQ\'5NAxNV !yo0ykl\|F*Bg Nuscǎa4rͺ(R\T:{Me'`_j+S&gS Mxl\S e8Dw-&Lj׍(\ڊ\TyGBt:/'S]U6&Kr*^;f&JH||)U7%`bwIVt;n-yuEt&BTkl& @}]-tTeqd2I0fD&>N;B PE_%R@3TFkZ&)>Y|ew/c~Y`Imt[ifB/k«SܿVKΞmK{vy˹sRy5s5m&} }9k.yʍ _| rH_; \n6a18CnswiFId($5=ٶvbZ 4n?e"!pE)}}oE2!HK\J*AN$&Ôxfczjh2;ԋF[<{r1S&*|X$J*Ǵ@ AsA31<2N LM0:SZNeȋM295M*' U.<tH"`cOLnj5$Klj%R a ER%Nie U%:9|,S . &NOGh?}XMHr.v}AXDGzxR HDL 24 0E.>Ag{)uAdI, 2|'d3Iz;8C<+BC8NN'N 2Ogyif:x$_%+p^d,N&oQ( 8c㓤9cj;p4#t$11sL$-4L"#8q]} 384B=T*@;HCsS+)GͰr]! JJ(7LtÁ*Qv2apk@Ig֕-Xn pWR`+B6'}榦6Lμ |1 Z&B Dsx(g&bߡLǒԅq ᦶ#ht*`0&$cꕴHI66DH`FZjHIg!Twmh`dDDBjJ ؙO 3$3m(hnӱ{<86&S(9[ -+phs鿸9FJpC] TT p]#af6G.osr~?KN0Sv+B%^Q UE/̓[DhvJYZ#$b##5:-|_DlbUgN2e-O@ZFt2IƴpAPVxL31ŴAKSӲM59~HlpalhQK/SbxxZK桺35(IOێЮ>$C|adFXuS]QKG˜bUlNۅ.t2 /F.K0 =iYR}K$lk ۳DS}fȘ/YPͧӤB@ZdsHL0J bּW31o.^'TY#5I$ %dL#C*Qb 4bH捅c/4렭?NiU %u3KK3?$=}ad3%ZW^IP3;î lq@G/z@$lk^ZUl^N^&§Vt&\!^Yhx/=6V$+pPNS$9ćFyM5N=R'<Ch+XN8wTW>Kkh}1B~'5~;۱eq!2!Si,x׎æ!qR@QoWGw,):hq! ˑH&}9ٌaDQ^n{s㱓KHep5uU°/a*D * xa`xDLյ\_zRn|TUUwl.~/;0A?~ۅ]$il/]rr0si)ۃvpH@=^l]#+4Z]!Lahnjjl$,n7>N*IJ9q}~?nAiee~Å"J u 㴣i xv2߅؝n%~w?f +8nt"v:z<6n^zA|^^Ӂ  B,-p EQ>h4&9?Wmt$ ,)%׽ׁiJ. v V[ܞ*h%:ڽd6Kv6G:E ,T8'Cd.4JڥL6smҋ'Y_N#~=}'i:D͟4hqtga.k맢|3ySá ::UR)%%u׻$߿G{?+LU.R]آE"Ҝx]ϐŝtǥ;}Y►}&?qſ QP:i>NǕ@XԷ.TTQjLWdfv/TAgW]Q*+$5ͫ((\TWEQk (r R^QEQAu0L>/(/Zryb(r}~yqiEilhp|EQFA>oۋyh&*_$87REQ~6vmnme:)(GԬ.[ ^h:V\K%WJ ˒j"4 me\tHeY(<uw=HҔH)pu2jjk( Qw_}k% f KmceAl܍OmvT)VX3`x2=XNCm%nK,E{Ѳ(1L^`#zwҎ94/<c 8xά˭H#MW=CdXY& bK1hP H'z WA>9I8Սj{nceD+쩼/< ,)uta\Z/1񓜘ȢV{Uh(mypPb%+øu׿7\NyB&3! O@>Z~p; o=M>1? A>>S}/>4%k_g<ƿҽ+ O)) `MS])t3';zߢ5$5p?}cC95bQW` uwq'x_ʆ:HO}Da+tA'I8Ws؄R(׀e*BJneaRSʶ>X_hY_RebBL]l}/.mz!&%At݆Vz ug=M4TmcWxwu#9E[7Vx 4o_0䣬j]ɯ޵MJi ]V/:]8*sðZs+[qʿ?x>Ϫœ?~L_ "e#͡'xP@72rjjK0 6CH)kx1+kJq44 ml#UtWe\w5edwJi9Clq3Uo|=Orj(9zS.anj 3y?cNCtoyM|Sp8t,t$n;%rLGѼAjL 3/ ]IUʚMe a+VpTFSHpoťReXE.t2 󘦉i",)(%1=T"ʁl@ˏw'WE[/G߁'O GzN7 GL>_w^>NF* P}wtd}}2 (B#;I6nMADA-ȻgǞ=^x<;rdQ9sjfrΡ*w*;߇ Tԯn'9[2HղlO <hYyT-Z ^ck* 駣` <d'_kh^F8?Υ~LCD,|L-bVUoўKPؑ=ES0Z b6c&>>C|O _ϜYm׀L 0OWه֐ś''ۗP7'[ M{)6Ӭm +SR iP7Ee<=zV6eFyrϲcV\PJz2޷׉R>YH*F7 6ƚR(er*^rJk顲F=g8ʂeMs|'Tٲ%]1G֭]܇'wV8LHrx}o[<:/}pDzCSt⍏_籍dK{Zj)?y{?M]_&wxSh:k!TTHښƾ6Ò~Rpg#|mZm%IUzeaǮfܷ)=F ByK)uw 2Vw`kgZCCC9qOw1@4OpYblxYzp5Yʢ)N_h"b5v]RIei0gÓMyr;;~G50 UE0P/K`WTTq=֚aԖur{l}+<c7|As7R__OMM 5]# G4eq9{p?细Q|(S Ǟ5<>îs%E Ν8KwvVm Uu$5䣝?Ӂ˟Oiqy~& N|VOl]ϔb]j~0ǵ@ g|./a?l+himm|,{$i q8S\`9 D AOr}}}ؖl"70 p~8p\l!\jiqBq{QB!<$^!6!k !gIm +^!nB9~g}$yβ,zz)-.v"!7N*E0kK4x<Bdۯ+RԬ_[vbhX4BBedY,'sg`6tKiL#'6+䇿?=c?K|T |r {9гe(-k_-57sO{R:ٿ{m>L +ϱiUhǒ;R1z bNW.J/gayK#,vfmʃmk][fd84-Xj J)b /r,Yɗ}Օ!.ć{9/iEyWtJBq#R ^(D\ƲRh ,=jtbj\tO=+N?4~s}Eןj'wG2WOhޔW{y…7JIDAT)r+u3v[?c;-{lÛ]۞8Fn1T }BխRHo/]C-(#QϩȪZ= ?G^O=N.d(58^gٲ|ΝT]/ūc띕 4tZ߶u Q*;geYPajQ]Lk%/IUY2*{]$ TbǩA+) Ё x= # YQ_6?j!;Do6^]E k徃O KX53lNBcxcYn#3'y\#aK"/;+ (9#8n.wFNwWa0!LM cn!X NIZ`7M-'9v^޼ Ctz5wqB -D)%x!ļrp\C}a8pW}Ŋ-DqWr-T$Q"$m2p&lJiEoh&(#L0ȯ\D0ڈ_i.'J b;F+k aM6[ AH J'ikeEۼmرajϞ!b#NW5 xSa  qh;ry,Azc,O{k1 0/ğԩtrzhm'hYirq+aY sORM[ 䃶mBKugg_~cM]і5ZBy4M{#J)y} c)--TO+eJ'>5)XhrA|HR`^W4;6O>!yx< .(﫩gܱt\e bKN.e{#owIjLӁ4QvC;#7o]ʅ8tX,F21BSm=lWyX+*^; ]ђY !nZk ஍sP\\t] ϴrY6A۹Զ),(/,OgF8c{T)*ZIzZ9vu[5%Xvv}Yn Yt]8̻B+c:I,,Ñ!J) d tSOvBV._LÍOy$-'LJOO>3utt;HeU9 \s?H gh/>|/Ӌ _`4328LW[-K)ڜ?-_Úf>~{'",ZlTPc[rm >8cs:/̶5}}Û5kW}8qn:;;줱,϶Qr4ӡo .pt}} [o3 LjecPUQC=5&YrY?S!nRJ)'#++ks YYY:/a?l+himm|R47RIVdYXUF0T{0XP +]#Iz;Z2SVD|M}6 SUd.,_>˖."hF+|!_I)zZh!lEͽdTPt6tނ> Lw8NNaUEx Jô1M KvA$FmdH)-g3A/U`RX//N(JRUH PGWRbT + q^Ae8j4gbn6. C D~ - 4D+$G\GNb?XDEI0`KUNRS[@A,(ɕE"PД) p:32L070Y iff=iaNlN5z >sV~4Lehe[hccS5  'a(<2t|g61h;iSX׃mOڜE)LH4dZVy43[{0zװ37`rNbD7 c&ܟL^fiFәǛcƗH߫r!H?km1hl¾ĹִOWĻt:S,0?y˻Dz\ޭOsuƚgWmX>.0k /;ϲR֗xo!K9c']1 !HfsZw]!cy!Hd7!*+ى,<3<< !5d4Ӭ/s$siR A2 B\_2 foyyAKNBqc M"6`^FgC!4jۄBۋB!! B!<$MX,Foo BLӤ AgdΎN中fR`n@ 0eZ*X4>@`p֧IlۦPzt !nV (==OZ)EWW7.PhV?˔xdS׭֪2{[6Z !7[wsj0@s#I|ٸ9 vj?Chc/Ϛt9ƙ&R{!ѩmug8zrGV|G !Jo>7*2uo'鬫k(>7RRt~?X[Әڊrr|G2&||6l(LӁ0fzDs5,#IaWZE7CҵދJ)z{ٳgτOAWgl4ʁaS朧kҗLxJ}pp{^~ sT8*>nWPJ<㫇8R8EEX"Ltb L4tt̋g[I) 8.w 9Ӂ샮,J$IlN3G-:W4пx>. P`H,ihQJmd26lc-hCݴw&(MĈDrH7g*l(ÁiB&t[rBe($ӵplۦuA&tدV̴8-n>g5+45DWei%;8}ǹVFЉ0'|y;+ 7`ϱZF"1lw><~o=ǡ5 '؎\6l(4X1ZjSNgG+]6, PslӬ,r 9x۟-Kjxg?#Q+ҷA} l6w/ ${8u814)LW`h8yF¿>u;v~dO~qB'#6p;?úE$L,,Z6_\ZRPP0s=sM}JYl}!oN2*eM6r r_1=|7؃RUs}-:9X}}ngQ@/Opl|zom ,+pt#=ﳸph=XX(5vY'+"q|ۜuvw^{ (U `?|' [U۩8봓Ƿ_ V ϕj5Ӽ4(%d畱鵅]? =hJOh>!²5v=1vj?9f3߾rd8!mb cP/}ܹq㔳-۞h/:^gWss( Jr=;mxeiDm0egYU Jk8̛.'lXHoy69m:V2Ѯb>u3[X&o X˭WVmO7ۚ;?B+WرX̀ύi s:GXGYR˩\ O^ ʃd9AyXXI~鿈)Ǎ&7 GaGzٳ49jY l+0}d9_C֜)WgO:۶yG{zNkw/5^kmDػo/֭ t1qW[k5kP zXq6֮YA: ߰`;Aһyu|N 6/-/=E?Ǟ-^x|]-rre[HanƎ~}ea{M0jҋe/eS'or wJ.CvaS_Aw;}?cwd|keҥ)+JNʹhv`qCBiKyԞ\Ί%KYO~ϼu/O~#6lXGȂPi9"At0WT'N1±St-!ts}tԴ˪@Sk 9y,c֧;?.dҥp'nf1b^lfbxt겑iŝacqzi6I7+m,7)//pL\`':>0;7cw M[>imm4'\"6ͧ0δw0e;+@~ <y9Y(;PH!/?ThD E1su($!;ONDa8QcLJ '>N?y,LR 20"+$40aA ğD `]bQ ׋s:H O0 7m8 vww3ps)i(D H ۋ5`[E[[;K,Et7=˲|~55AƂ`=԰iӦKR,v{֚*cJQЈ%k&ObϞ=l}pk:]jmO_˟,_[[G(T@aahJ) p:e`n`0NfS0g&]lv6+"'_A4ege5<\^. 4> PIÛCiE 7JrC?ťL"ޜ<*c@9\UPfr dOoSPVIh\~("ʦ/BBo?c-ˢfN5 iҥ\LR0 z'vڲ͘IמӯJ7M9FϿb4\kMYY?+<]ϼtԸV/(瞻t窚6g !׃zB3:7&]gx!}|/]ܤ;f?x!bNܨ;w޴Ba|_l 49= |zo:34[yIq{QJL&g|v1_r*ܧH$q4ħ˜LPIgy0 |>M-8BٔJY)e55AAA޴bs2 \~_l R`Hm:!5A$df52a15,\.*++(8ӥ{$ ';FgC!ȥMӜ˹Q^ {BۋLB!!&d!9U ۀmb&7B!nPx=)fyNkDrN@B!>=۶Fg3Zg|ORɉInLw+(cjP Xo-ơ,R=v,-d}!,x˜6?Scjڶ0UܵZcꦱHpgS,Zk,+L}C qge˗ti{`"-(mCD, uFW 䡷n r"n (l:"OS\IeQp=1Y45%XU o<Ə9XARB Wqih%%(x@@z^!i]{W =3RȚq a 67N8i=ww8ϲM|W`|fU)#{-l^Y}i[l]UH)~OL܋7ѽp-wkh8G[o[OC֓9e d1]ϻ|g:üFgG8wxz<ã+"vw3X,FJ[wTSrVyV{~77ֺ!B̅Y&QI,3(_om>ټRNB%8u?r<8xpo1j n)|yc>VoG|v^#dևycK=ޘIWIMS'cAdxGHbM|'yB5`)E,(R^}(NR`}ܹ0Ayg.29Q!֨~7g,7)/bB]RcJشy9VD-1=]bh(B<'Lؗ'^['IYSO:;O)cBjBkFP&Okc(7)*Ťk^dۊ•[wXlW| _~%֭$瘋 B fXyXy>^@m:3}t|7?9U‚20h =H[k╔] I31wb?m&=1h$7=@OF)0Q\{_JPRVA <ĿqN\h!cg荤dJB97;}Z -kyz%yc4uKgs5&M1< yO9ʎN///pȍ.B1J b:i2 !kYb)B!OF !x!bjgvz3y4ge Bq K$tuuH&f*=PPP锲_ BqRJr(ٙJ&oh=ze0}Lq'^w>D/4wfjNBMm}hӉ?E,qcmtGS|Q 3a˔Pv&j GHlKY| 8T:mpnj-Zß\xs1ER)UPJtS_SpX_GqڶUxلB9 :Ayw掲[#6oD/t\60\Kxey!aqbiPD Fqf)0H_;!b9)Yr8P m'`p$ >R J7{f{Ӂ]_ a+UQze/iq6cC <̦櫯~U%wUAP6Շh ?5YZYe75 :J33˪p邅tk(Mupnj#|~%>ZNګSk.et6_Z'\ËoiSB4%)Jq)z:?vh6Vƥۿ#g$L;ؓm2Ue`d!"tߵV?1<@pI'~~?,|n`L!g.wUe[-fi莥`B>@]M8B%,,āI ^~O>?e.Pj~96(rmA{y;8R# QN7WWjY~[ _Ƶ{)r9g/I PD0sؽ `'Gs>3 ~m#.]ΣޏQ`c[xo5qVUі3YTm|o}e3/A@bV&z Bq2)d KytFI,dy8\5_ȹFF"2E,$Hb頓J&I&$Icw XyKx⾥4%9}#qu =:? HLZWʮm,zK|5{{x J1]{o~As)l$M[D l˺[C_ESς~|;5#&bhx>wjMVk\>Z9}gkhlh} E;Y,/VWuV,aqA8IIe%vy=G$椢j!9D]?)o>K`R?ǙTvV-#EQbR4\8GcO -.=4uFXydee]yٯ.? W*䦫OBu aUk}\m[βs)zF4.G Js(__6dS\QAyMy쓜~SYx !cRc30T*I*e-V NVӉE21&)Bkp0JHN34li:q:2۸d[+N'жE2Jw&Ncjj  Wc>%HgPmLY Jp:]Ja$)Ȝ7WfO2L070 E/6t2S=0uM_0:cA73t;\2p\\lON 7a2L\.s Ӊf ^!ne{8v.AvBq^7ӎ%~$ !ĭnV^F7ϛ/o_o*\+!^!nQZ ԼR)teRD/l?mm vxWIBܢ|>JKF&vOYv./0YYY:n_ B!! B!<$^!$ !x!b<,*B!%9}3=9a|O?$HL !N'/2ntVB!B!B!B!B[Jwr%tEXtdate:create2017-10-09T15:01:22+02:00%tEXtdate:modify2017-10-09T13:55:15+02:00UtEXtSoftwaregnome-screenshot>IENDB`Eqonomize-1.5.3/doc/html/C/figures/splittransaction.png000066400000000000000000001626771416454732000231650ustar00rootroot00000000000000PNG  IHDR2nݱgAMA a cHRMz&u0`:pQ<bKGDIDATxwy{NUГsD΁I9-ruݻ}k_kٲrH1$@'`r`90|@WU5O?9 B!B!B\ 5_ʟ_#J]~ !B1n7O?+ϟwd<<2 tDžB! Lgs6&^ !Bq=6WgB!B\$XB!$XB!$XB!$XB!\ǂR7"B!>K 8C#h\~YH&xx:+e`3RJ8- S !\r2 .Mop΄p'5U\\5W@ FB!ՇP #5ʶwp-Lv 7)F1\ADb\pcƩY7gI_+o`Kw3 ˜A+?(չ( shöCT.Z%$-\'Z!FhwnDNA)A *įK(#sg2B)Ўe[Dx&&OLU)ISSۜviO)X;ͣ~Tb4XYЎsN&zV==e"UbzԴRp@nlb*KK)UT1>oдg~:N JCǬύƩ{x 7}7Ztc}jC2/}kHyw j;oXhlob&ˀh$H1$}^ۺ$ޱ&jry8 9vmƀCC}Xs=%cԓ`.fa֣G8Ǣ;3'c~p+o"QD68OwWq]XO+-8MxDnѮfN bYqzzVyt^r}jDy8]x3_UٺڵՌo(-(uWTA pD3MdξKon{4m!䦍+ !B\f.R87bw U+o㋿);kXtHpd:X ?ȯ~ܽ{yjIC-{x4'> 107oq,[-pؽm+1W^t" 4o#UA*27?ɍ y]DOrGt/%aӝs}}}'?x I0 G>Pzoy/&ILk_znW=>ܶ\Pe6kaۖdz{Oq}}xl`5I[);Fr-ۏ`6way=AdthAWϧ4۲3Azb~Vt߶EmyX7[x}1F"$Sѡ.j!BQZfQl=x }lݹ('Ҟc5D{N[[i&Ka"4>AH\B1#f`dWSQGWճd|.,&( $qCԖ5k8F]c4x!Y]_['iN¢ #(]|~Q.t9#a\&f|| e@twKP q}]>?{q3 NE-xŲ{H"6~^xG[VSp#*Xf5Vvkt"H(C3vSlF | ߨfyܹa/70 pA(aӅi<Leer~^>8HR^GN:= ;3ϴQsclaEU RRQAqA`^9 9Cl%~R9!Jqă ܹa~VQx}^#B!.K13.33YζmGAc{ضݣ3hGk20Ʒ֬aml"m((2vmp7@ёZHZd@NL3&wvy)F%;Fĭ'/ypJ?/|o?G{ÎnBVz'Jl~UD3"q#Dchl Afdxp{"Rc<ԩk_qƟɟ6Bc;'7'C ˋ h}f¥afΣci=yth-‘=4ެ1Y4G!o Gp= p'rbTga|Zk40_7} /z"jr1 ydfqHH26d Gj^&VWZw_NiF1<:;xIpom>=a|pYO o^ u Cxmm +vǺHkYlG8:6"mۀBk ˞ZAŔK/7FҜڷ9`ҜiQ__ ;E,c(99OH0ZLnY؎!ΧB!Ĺf6 CkT$Jb;ca$L cB|/ #aF#ݴw_J),{<(-R4d۱;T;իVLaw`/KkIƆ36fCeni~6cܼ f|VWz x}ij顨0t²R6nvֻi^ʍ!FO@ņONJXSid%iR4I杦QV\ҵkY7Nii"Jb'RmKnla߹P"ÖƗ%DFjQh9v_7P_ed8Ff4"]bĒi|ekGfJY倩PBnX¾glZ;O:BUe8E:mc[Yie,mUŵ< ʌf~vd~ 9‹zm7Pk0@Az\B!5˜W+39:8Rzx),2dr`'ma("?Y>/6*aAC1cCxj(G."h(1Լ-MTo O sN6r-()"jf3~=0Vj?Şk̯&';ˡaN&+)%eֽS*-+v!'i9BsWs$w@ qOy 1ĎwX0P9Ctރ'h鉱X7e5}\5t8|ۆP%x^KacN3fy_j K* Χ z8P\QZSGUq@69>Eɓt 2{t8Mä ݌v7)) O%yx].r*(uQ@>5q:A\Ue0-**qZO5&PPACmyTU`wIvSRUCY~9B!>ǁWzΆɐbxd/8_ Zk:4MοC:v2.i#ˍmfF"TBx\TL.I8Zcx.&eYhpy< 2rypLΆcJц ۅN(P ؤR ǛɣC*TS< Jf^2\}U&NIY6(ǃtMGc.?S%ßQ!B B!B\B!B\B!B\eXO| t,|"Bs &|p,+Z?6\.`|+(hJwE!R\z%. D_axLg( !;eۇP%=C !BK2>!$"B!$XB!$XB!dfkYY!sY\'ux&jI,Be(n*6YoxA G+6U6etY!sR0tYc"߫f4`y@TgRO!s[Н)vf~ 7ɐB!>&c$RG]QJaZP lH )@k۹үH!X2LL#`1 W`a+6JHPQ!Y4AbE!NVCRS_Vv|;=^6*sB3;"[2-Bk:EC>t.7,?n܂j,åGJAW}n`;zpRt,Tt4pLk$sh yS|QQ0&E劍<xfvvP:M!Zj*KpoFTvDgΟ.ʗ,giQRE$B1ffdY/$,k7^ڀ eK+}Ʒi g_XC)u 5qW|(ϦI 6)/.mj6(jXNQ?\ {ʢu+ݿ@ÿg]Mߍ1~ͯ#?yzb R&楽P]%s)F+5%PVsq{A!b6LRplv4cwy}2NF #Sm%L>t*ctd()a"8Ril! %qD2egzV`%㌎K3P؉a{d8Ad"x3ױE#akrtvR FGFı9JqIR6O,\˧\CD_+q`}Mxҹ>d,Xp$ό$[x߾ͳۏ?@8lA)p FGu.&9B,fxdX2} !Z3uFsXqZJ^ŎC4hd 26Hߐf;XQĮ-A"pwܾz觫gy%t[X[8f~fvΎ?:>Wُf5~vǀQʽ<Ɔ% 6WϽ)UE7J& y7mf%^S][[Hۦ^^xs8|67>I۰ wޟ%Qa0;0K)r')7'HЩ: {H cԱTféEWE8b]& 6޽nqݽO;7p?M&;ֻY]έ8=#]Gn_O+>J/BًҦjr J Orh< CJ9tɛdtgJ`|SnAkl{|M0fl}} *S{x@IIHwp/AŒx䑻)˷3N )^yEԬ??ZCi.vƀtm|v=lYj#6>a~ _2Zxu9(ۢdJJi0(nbޒU\=^xJ#(@>,8 h.ǩ*㳟`?ma>qn>1 JWQƮ wW_hQM~^=(E __i9l~ =X4nNB?VR#؎?*)t7چSp+qc-{nyq&ϗ4pST%j/楓{i_cC}j|)'Y7!BqP02M$|"RCJ?2ʨ((7O}Q v773H>@v2љZRg0TƋ;hv45 T*H</AsFRct&\~ fx| m}Y5yL'i7&*&m^;夓D1.vځ-6c0e(FNFsq!<9* Q1jJ qr3پ3+Yi ˁ??瑅OuƒB!  t ^?ͫON'󋬯Smqg6ss çvdXv?Ů#8y;c4連L3ѭq,hȔi$b+"sa~Z=>:h`;v:3*(^]Ӹg'#(j?ʼn.{B m,Fd6ch2Ҝ|YŮg%mvpc_w]_IX"SMWǣhm$mG;(o)?ݿmڱ1Hu{iU`&ǚZ8zp/GO~ȯYƝ68DBqL~+i091vy" r({hcQy[WTQ %Uuǩ!?ZݺSt=U/Ф^n$l{GiVT;i_bB9>CmfvȫgQU!FW_F84c c0]xth- ᭷sz8ATQ]?=ɦZ[hjb}"rr6}˗'ؾu7[RˢFqkQh]6늽xϚ=hxslJ|6qa;EKsj6\_W_{1kh.\Ӎ'inm ]Gﻉr{1#سM~a!>˼ cxױں: {wd dP__KݷxsnfW$ C!(`{oŹAYy$?~m0<2 _5TUU@hh"F8:Zt{ ܙg*+E,# Ysn`z|d(sX,F"ifyN GIZ6du8Vh$J/{'~ȼ߸[2}O!ЎE,!dIİ—$˗Y'M$r4+s\Si㐈E&R@v7HqyNO:~5|X_MϗfeO99b^ M2\s}/!B\&3X:-|bAѥ?̄=K@`_\\\.\o}sq5#!B||qWNG9u(4Qd !B<\qI/ÓEћB!s$Xe)GIuHB!M ]N\FvB!>&c=3c,\(2KGӚ<5<B1w)[gs`}/bM^B!ܥAEGsu&~dNB!ܤe@c,QǤ2B!>S 0GrB!>zB!ddySR;N!~s֚p8e2O!s&S2.r|h+5<􅶝%d5})B`Y'hmNw C(7&;TDM|W\aJh;E<6Rdxil%Ob+/ ,]<ߌ]SV*N,Bdey1XGhf gj|Z 1GKkTguTyY#R)pjsφGy~`|kłr:;o=Kq냟M2ʎㅟ^Oy[?}gq$}xWh/4aL */mln!B ,9૨BJkX{C'uyNO)0 0BF|u7F; U.ǘ1\^ڶq ON0\p 0UDQ/%$v3(y+c1لh1çv'Ƚ7Vb2;BѥRi(*,F)tY ) +Oh?cc5 O;Z{fmd[BED"Nwqo&>*n&K֊Z,7x癗}'%f/>9a FGeˣ@H"J7xc?@Epw+}Q/E9X:b~wkOgQ4E7rbYda Z6B}WP dFJFi-B!U)^;Mx^b%x<%^QJNH-Yy\ Bx=HYԠSJa9}pC9+w8hxX)\n$/Y *G Ў޿#녭;\a#]GEnִ4drp 2M Ul!oٶez)qc6%)P:2^p6W%{x?oJٝ_^_r/JNb=ɞh ǨuX9C;>~Ώ~{nQNC0᷸cIaw?;ЈV!n~1ٸ9x;?ܒ"rgn?X:ū'q8#ny[x{އqT9w޸8hx"N8r2A2 u-d&( !ڠ ‚\_ʟl9p8LnnqրNиwNvܚNcCɯ[C|fV]_ͪأJj*+ H{3-=dUP]U˒C:JLh1`Ex VK5qcccBӯkcַ80'>*/r) *YblܹT8bu?~z3CtrSM n~ey64[9vaշŚM](c2SĢqcBr!s0@ynzYy;쯿s6L~><2 _5TUU@mONN a`.WsfBؠzɎc8`ǔRhvPߥk% LZAC].WfVidլX<[~\)m 43 詥2)4Ndgab>;ض35ere*udvPt-&ڟq4XH B1565STT9g[[[;EEx =iP^9f, 0͋$@se056aLLy`JS3z='i]Ě5}8+n)ͥ0mƞe"H r8^9gLYqyuqSmh@ab yyx V N0:&iCVv.Y2PR1G#ǘzB!RM+yDβMPuUzj ;ekNjFNqd'xu>=5ǎ;BttN77=ob"ۣC/宛WSNҼ~i:/{O?`rkjR]9pӱ }ܳixmuxN[=Ts :Ģyx,wŠc{3yQ]{;JܐVN6wrt7yvnFG\C:L:\>~4صSr=7.§B!$e16&''J)"(V:Mnn4 9֔tC4d2y{oZ+f^|eE+!nlz!yjouĝc~ KMA7}A=+(rh#eX\*-;=Å5']xV/<=DAI ׳?POSw"|_~jq}ztRؑ:bin7.CsxYPAkp5m;r:1ʡ#G&MZT.Yy olef_)-B!Riݶ"֭[ioQ[SêU+&-36OXW3G[Oڳ?%;5l=BZ+ æ(ו f*ʽ vnN$ځP֬l@۩Y<V!/GoL/3'NYP(TSZ e!b(me* ޷|(O5'6#O.V>z/7/ ;;BDz ⵛ~ScTUHGiU5ETbWڽa^} )'ǿ=C_m>yA;pa&(BKUQQΝwΫPǦ[oOjrnȲRXZGɫ!/g؝vL`nΩw []ٿ{i(,+,:oD4c02B^WfҠ`0UfPs< yn&Ό+bC ƮQMQ7>˽=nޞA"#ݼ}z&8ZQ~w?K8tzhM::Wco(nv?@o8M:6P!z{i9vCG V,dTec[S#eJ,lک""B֚R֮Y绬VW`yarss228sO=Ͼ8*0 Jh:z"mh-CsaFm2j*i<c-$,^HEQT:ufZz[7g+GCt$.,o[ B4"{m UTIzg]$5.'o2~çp , x!#`^ 9SF㢠eKqh:qGrŬ]ʒ<('O4ceP_]Jow~Y ñu!oʠw7y]l]N WQ_fB!DKTJ144L O 8gYyh8Wm{/# Ņ:IUU9r4D qM=SIҖeta(M:$mk&L.D9eimq0ppOk͉,2ɉa(2p{j'BL 0, !B|R C!B `Y!B 49,J8ΕB!ĬRJx0f!T9jl,L8F!j |- 5TWWtwB!fm4fle (5.ӔqB! @d\%B!$XzB!XqqК"Htb9#WGB!gfruko а,l _k׳j^+4{l*fg_0 NcXuz֗Vz2]B!ĵjfBXGEd9SCu奃+2z =##TWpb|tDMn1>oxh!#B!Ux|~l<dSXwEg7"fela`&D`˅eb? sʿAaabn54gBNd(FN1ϣ,?@nJg0d)z-0`Sxr (u;tGFH t뤽gWv)uAla4mRPVE]EVN ,a^U!*oh< d 'PF05COE*. ̛B!W٩#CiVܿȮ %"-v kl{£hbJn _ud޼j|AgY؆ix dQ{ܵ/̖#tuw748v0*%s /SS*?%F,B!iG=\ W5IyVLn"#& vKֲb %xdGؿ$+piL̡ve]_ <0fpÜ8 WFpՕ= hlneI6˸q;z_u==¾='(|zlG3QtD ʣr A;i6+p !BÌP|/p3^6<ގpIMDVr~nbt47dczhF.* &6Fptc( "'8ࡒ]YQPKllGh2M-׃aJ֭᭟ȩC( #ftk!މdYt1su3[Aؖ-)B!W X683}ϫv9k52Z?Eú)Ovҳ ('@EY)ޖa&<9e9T6xNJrx7UՄp۱tp#i`V׿>I$!W. vIuɧSP@aeRS79pz44Xs=9IA!B\f(XvHƢc${'KJٌvӜ:J81FO)h YEaYehWoc˿fַٶ$Io>o׾omcod7nTWVgFS1F FdnLR-hn%:znZZB_Oy5 kI/׶;[~cň"IL([!sbB; !B\̉|+i09Y1N|p?':dx)*."7!S$;?k(Mł, KTR`MX`~=V5!\?%K0t˯dE|ֲtAz*|I-h/Ñ|=(pl(C(,$;Z?'<=B`i($)8׏Lfcxɬ(bjTlQjYl>f:B܄B0a@V#=йJ!b&4sw۸_=gd6<2 _5TUU^@}Jz3GӍ!Bkd[!#*F3LD"AVV֕B!ĬJt!^Gv!bnSJu?4 (GEE9uB!ZX9L)5+_G!B|\?!B!.@e!B!.@00IB!>.6oi6c+u;%eYCCXu"Be矷:m L$g0!;;q3\!'7Cls `ϏP"B|(L ZR `[6PLT2EOoa wphd*E(<ǵi1L<$X֤R)ByRoP!W,?C]#H _hIRlK&RJD D%X/βB1u[31¬ b4q34m3FN}.Sf?Tfߩ+߷ !Bbv" g+Y avڱHlN6c8H,,fPhƒܳmdU,aMQ;`W [{X|nBqїnV,+lF{{ S WK`VNjw.:bk` l>j rӼ mX>7O^'oB!zzt 0sFJ'š^Ǟ5#ˆ}'vo>Mէ=^_^vrhx^)uZcfr"^vOM Rl{=;YlƢ+)A96J֮ӧS4.)B!a[:քBlظsb$q>rOR ګiO_uͼOð56=k ?@~|VcHiF˜9A<>ٞkϜ\5%ay/Ͽέ 5^jJib%(のC=Kg:21.xw3/COE]!x951۶ٺmm{ƣ 5%%%0Zi;w윯 p_3c˸c}9ouv< u(:MIW-KˈdǾc 0s+嶛(Ct3Ia; VYFqFifN:MGw7c7'pceo.߅m%laΝHq]r2}<́')-S~/- nJJr<؉1N9HKO[[ 4b8sD߾sbi1 v ݶmnFnloEF4 v6ERA]+Y^8Σ_,56Nr~3|_Bc$,Mr|G$gZ;ͳ?.?1:ᶛY6m[.L㕟l{i$9NU~Z OyAE~1%%x ߛgyŕ<^1uG ;_%u|[s%5vSk^KKxc1?+͏ij1@u eӺMϢ |{Ygn?'kʼWB!-gY8#aÆ.[ӟ˶I~oadbJ,orʼ.}xcGe7Dnp'?Kp>^{[rX-*`GʊB)(8WNS¼ Yl \yxȥɀB!aƍZ`0 zgN |Ɍ0۶M2,Zxr4Z0 æU׳`~uT[>]]Mȣ(^{7?tO;z"nh(*XO~ПIW&fq}DY4g1Dcd5Dhn즽/<`]=#_ٓI6lgMnw0s7SL4t%W aOwPs][ 3%aO`#x}B'-kM}}=޺t:}) .t3ıR?)+-agv}G53Jd:똿|57^HwFPh\Rǟ~R_[O bԭ=E~ޮ8`.XX2= qTH%9Lxgu$9+<.o|5=\8r{ѩ6 883Gc.t)mPazpn"юcNfb+B!&^Xct˲.^ۘ0#=MtvPT~^Fa;]O Oĭq9iihF~ R4FU݇I)#uܸQ-8Oyݣ 1.R:SBYMg~‘Hdh4(tzHD,Fl;LA"+c۴DZ$ccaIt:ObaOV0abV._Ww00:Po;-}4^{ G3 !cC_ij4eAln>QT83a(E|7ܔjqI$g$ByWPC:HXCh9Ո'9Š[eyyMüul'vhmMq?˚ӟg 3^sv j*Xnv:OpE˳c7x MR_ʥ)O)6Yʪ˸ӟaO䷾K-`źg qڥxsb6@^kě r)OqpΓ^G/ȉ&V.?EOy̯dኵԩ4ٺ}ŷM][BLVۛ(;mΔ=j}Z<=XL>} 444YpFǾKǙ o{'_ XŲT* (8㮛 FRzn,/'?ny%DqIݢ` ]/AwvNURVĎ_ܨ+ !b* o`n@!~ {&ݟ40/ g_oI-=r r|5 7ϟԮk0'X>;+` ezZy7Yb\J˫3OqA='/mE!<Ʈ^i2 Q8Top(-I% !B\}?{*؎C<?DDYU|GJy \䑙уetM̂. +(62)Nfܼr{>J(7v&!ܹ93Ӆ_m:ָ4,[|5 | a~*QKk+aa~),$hLBT\P9 R`uFfv5eu-YIÔjB/,4@~ 2[be!B\r^}.:>5ExȲv *ñ,l4( C;Xi 3Gۚ_V*tښ*h;[4iFOV "JcMɇ`SR4f0O鉑Juf=ĉR m[iҖFM)vtfurJOAMv2ϟ?u!B!ĕ5{ux@cν#4+^MNG,hO3nKWɼ$fp Gup2F*Cw#mŷ`#&hf7Ehշiq.?c~z3ucl-*'([Z[}sRX*^ wleHkB8ȁ.OsA7Vlv6f,Xnb$((-AB!UaK<(ڎq7x2Fi"7p=g/eDNϟ孝'H˹ۙ? G-/a$9ă nSopܲ,Ė_bwi0rzm>@uN2JGw|r*{ck(i ÍǧxhM~oc10},I:͵R]O!b`Y_R/r: `Rn?1wsxOsb `.~o/:٦1tp)͑}GJ:a@|J˙qiE4.9la"VfRN%q&D{{_fGoWy#$T&e!BJ86m7Ck3#ƆJptrM2#2:B$iOc "CEu|;W0oaL sa {Om&n"x}DcabIBgn6rwua. ;‘C( 2;pH3zhmen#عlw}$8o?OXIYB!:l5 e}Oubn?L-בmrH nvlKm(/Rh!%;_'_%!-vK?Nc-.D8~NIS1Xy-ZHɮ7xWiQ.h=|e51~=lһOOGvt|Sy:,бDh9rޥԮ/M;6/Y:U&s]txSN-/-QzSO}T ^n:EAr=޼fcdzl 3 !B\yc# vZIUU%i^9M|lRyvNZ9h+@_?1CaQćIbG LE%}= ExC 20=Ys88Sb$aRP6qq2+(Dq30ǗOaP/Cc)Yu(md4""/EkM:>JoqE^Q1^C EО,JJQǰ1 C<Rڼh_:_#ߓm9s3m~/B!fe+'B!ĵFe!B!.@e!B!.@e!B!.@e!B!.`ƫa!B\5XC\Ak CJq=KqQ9ah`tt9-Y.ȇ1#֚~B+rO)E8lr_Z1Ra!7W~"HKk?VҖEkk+>дNQUY=HӴ2MfKА˧XqAJ)\ \. q(0MJ9{8GM\c-C*YA)E?gۅ =sB!~-\~is^kM?3O& qA |_>0\f]!tj| =?sįY 0.mc;cMaA_f5ڹ210#_(H 1fqљC:#Aq5מK"x Hۙ']siJ86\tc;W(VI`emzq{x H` $i+P]5?gJ8(2 QY]Meq.2&`y] ?Ȱa8z>gﲬ#Ji<Ɂ#'I)ٸƛ]E (B]}(.EK#^+מCa{| М?B?́h^Q]8hOQ`)/ }u\G6kشf.ee2?.Oތ\FO57x`i,uR^^FIA.c_LhjY5s KmQSE~rw%~Seq3{4|` Qo.A÷<8LgR=`9}{ma.__u7ƅԙ7MeYBO>py#?x@&6 wƃO~fȲV&dU<S-G G%`kM0gnʼ׾+y kS;8)>ڱcb1=~=^xvҴ MÌcX2\p`VcيU|鋏nzYZGp aYENxh4F MϼLOVøͬ:a ?/GFN4?-/=~#CaQ,^H(qr{:g '@`dɶzޕgٳw}mK%QL $ri09ӡG f 0 >_~~ygvZ(m1u=$'Ҍ [[v7F~ZGk3޾޶JzǓ Z,ܸZJ9]P-pw;u144D0xugک_3ɗ_ÿ}cmp3~g_DRݳ|}[W69Czݱ,Yn_IߡuO+3ѽ{iIvdR)ٴv>X)~vP K>4+on[N|{RVTm4(:=ǯ~$wqߝK,.kT>]<.ϵmleMK#xbg;ut{ 2VV6a(Mj1jp,7sӒz<:Dž{{j'$_=nϽİ>h!2,Yć>s/M!,YŁL?+ ͮ8_(wSWrhprI:Ϝg4A*1HEne>|kXO~lmR.rnY?D2?οo9v~4Ӆ 9yGa]R75J*(-+#9Xڢ} , b}D7>(|Ce*L&(^T.6Sr.^sJ8dZU?gud/=Nnd}]G%'rh7q~N{!<Qu+y]73z|'O_mWˎ.-'rmjn]s/suuOSd=Cd%:C*q,Ns{/O:NҌ{|_yhPd9 •^/?}[@`Ie:K[\?{lԹv{IfO?"g34.H̓|Gғ~yֻoQSo~/Vch+7g^B@ỵr'n(V*( fu}Ͻw%G!?xd [iS\?zx`~ͫs<@`Y+דJО~HI nfۺ 3v)E6csC+Ezb'~'O٤_e\̻65Jsz2\~ŲmtѶx!M!kˉw;Hd?߼ @BnMY-5m4J)B?VbMǟ[Gy8ˏa #ԭkEph[ 7BG'C4uS9v"_mʚs[s'[cbJvҼpljA6-4.XDCu96oȇGw#ݬǍ! jTyMNA)z%>A[]jŏ^[кh6.jw*:xU<19Cά4U`4n:\q^2 ,[ ^d3ܿa‹7r 5|3˖. j׭])o\B[s fAu15ieaYxf(R yF׳bBjB.*=Y# %Q61~B-իe Ӈia..x_9Z-d~s=:?z}ˎl?o`-4=?~VfT//<[E?x PTqMur U&i"T5;?$b~/Dˢ|hdk{j|uˢ84,x~Um M p!ƶ41қdAbKhǹ&k|>QA[k+O=T:M iܔ[)y9ӎv%7hm)~ՎmD=O:"6} }!}HڦNLj2'[MA)/\Z.㠵xe5Q؉:0.CQLJIlBC0eEjneŠL\q:N"dq45n({ JS|)Ga9suL\z؅2 a||%Kq^~-9Yq4 ԻO=ƦldIDAT%S'iPa#=\wr?so;7|l( 8;WBSsS/w6\ƯvcdwgV&Y҂Wrmo`6 gc˔q߽$X~Z[k(_nv5pMk~sW ( 9 mzZ̝wΑ#Gd[p@v)e`iEgwߵ`kc38LM+LT.ʟC7yqr(O$lrQ:Ә.0 Lj>~/c{Tזk<ɒU3F5Fj9{rCf"5e\o& (ˍi/C"{|7y*m!yWC%x i8hƧ@X]OU<,%)|Qw{w9=smĞخ} L?N-.4B$189YP KSv%]< Ur&ϭjv;]i]am|x~?fG 5xC:YS| _<V݀%~,H3m8w0n1ʇcWWѴ;nu>n"g=woN\ݯm 'k_5F׭&~9. 4.KJo( r~fmiжf-Ms|{?gtSR6:Zğqv2 0ʡ 4v?};>i\Re 0?xh;g.~=ɮr׻-%d{?%i8p4mZۅeδ|^:GqV Obh16ةRp3w޷ӻ812 #=37TGckgZ]8؎#-Ŝ:&c;3ʦ? q2iÌ28&X-=)*Ci)z2Nc2P"nǎpwGR~h'S0Yg|&s-^U03 xQx]Q0DC Le1qcJ*)$LQJm4rcYeܶu-7fQn= ŋ}vD6t~ ؾM PSICc#D7{B 3PJsKj]yy9Sf%_${ܹ{ONN 7)_ U# egM+aN>O|C1ȣ YΝop95\h-(_yod/u I N Ν:Mrr~0}7J*F`.uhܟiߗZJpfe., h#rB9ڤw!Rɪ6Wp3.ƕ7S1wcS0 MD4?BқhS ],ucmA7Qd.@4`Ymxpih]FS[ؒVw\5 _sw}'ql(*`9rDŵmDk *rJ|k^Uk֚\.wB@lvrSׁRhyޠR؎-wm[`Gc`V83+\C,XV(\aJ,fJoH8z+oiᐜkin/ee+/\.LӠB :qL\u_`0 JJ"W"B=(smD)E&!_v墺ql۹YXןe(Q.gYOk#&Wk/B7RF:Kip||U5/'NQI J\5i9\[:sR M%9Nʓ!TVIYD94cy PGH9  cAp!;K!mˎfBk^ZM) ЗVP 04p M*$k?1g)VJa&H&# `N+d R ?Hd!5\z_{-7me*2#t RvW`M&#'ۏ&T@iE`uT_)G%x38?]{Nq*3w`&Y*J)Q3UpMdV9sXVښpOvSwp?N3YX|p;;^:JekX]t+6='D0:mV6,#B]`Yk5V'Ҷ|($Y pCHc |^o.xO;GNSB9 ci}Vq!m93 tw=|᳟"(r^vl#g;8}}|p|\ {#TMd/?7Gy_G3ʾEU\k.63WIF]E\I% 2O۔2 GR(U(v?iKASJM5(fLf{j..SxgFKm0 `W}ĵ7Si^_4  V7qsE.CC(.:6*.`;zϢ ^w;)  avS|fyƅt]yVoʪRF{>ipQe-hL%ɻ,^g*kMsYRJoJkr>Fhe3.ģȧG9c Ҏ%+W%%x.~''jAb~)2i]s1z'pl(mXF.ȌqQyl^#_H{'kBؙǏc` `kq):ϟwd䄦u +0,Eqٳuk7'|_ QlXGM:6B!psGvB l~fPٲ8}OhVK+5SSk*Na"Nlco­}йB\d<}2 SSEkZ[SϞ?Q s}U%yW+x=alT;O!ش23//=~I͝j^x;pvSܯąܵ O,''#_:ڈgK! J >+3??~:ƶm9K/̭y?w%ٶ 3M^Xp7VO9\~֯h#1b<4ߺ%>>k~_G-irxIzrk|멝|O28tpYUcǰ[;OVK>uxڐ*ۑ֚s}YP҆ҩIJW(U !4o5(~_W+, =2>#m: YtywQLOjJnLCt9¹Dlڂ };Nвb8n^SG@9D0)΁6`)~81{ogci|@ q(+g]݄*P$;qd$)Th͹ FX.>t|p $ yK8? ?Pp8tz&hEI6.j_Ϟch&Nrϒۋ#2JDN 6ߺG(ZK8{m\DX[QSQq9u qHcS -$'v[63db XyFǟ_O~Ss<c}7uދ[n2">/nɪ#$nXp4!V8gMܺu=zμ #,h f(Q^~u[~A0TɎcp( M`A|AҖ];(J]nx&>_k#f9ZmaKucEeuy1_R;=<^F2?nH :iFǰm#!&һosx0$8@ܺN[&^ůCJ)t>CΞva2 Ә|*5[˗㟰x0<])NgN*ZFk-Y[x &čN&HNdua~\Ӛ[ \`(e8,g%]ܾ@S*:ZEoY]wHXnԗfLNlMym5a}i$biuTJi&`4YXV zB|hk~r$)l}:5Gʗ1'deyriA~SIVn}~F_8.nJu ujyݲ*_Kqrc<C>;iSAd#]rt,#?0e!+}=D"gc3Z/Eؠ:Rj%PD d"B,ώLӀLDY 7 (\ΓJ&IN!03+/X=fJʇG?öGgaYT=T./o͸ry9 ї-M~4:j@+l.F>\\ʵOPKqlzlb"=α=G/܈+y>v- KB5Q b{y}2~|>trz~fZ5U6iSܽpH On̤B7K+'NWg#~Μ`Y|JmOts캅r#ƮGض ˗}oͺ*ڻ0<#$yv Rn$XdP^^g>xy|y4k5 FYy>J\\X1܁v% KiQ((ۓ{GR{He۩ zY$ݧi3\{MsP{_ڎ?|^o[gށky)${dy?|}.~ ?@4yTtܺrXm8ˁŻ#i|'ZK%mPjF~"Aow'7$0˖ϧrz C#e{*ōF zXcNWp]nALӜm '}_Ҫ c +AkMOO =֚n4 9ɓDqbbjQx6<47GԸ/m:R鏣/60 dSԴL6$tYi2f`dעؼfzf s Kh:dJF70㸘 6By'~~s-ljCL_`yK=3M??M롐&h0sgqzSmQWj%މR 穨(y[ f?}8v>UK @b30.~rRNҟ hY bYfq-pH S񁞻`dGyyeuvvQQYg%\vÜuӶ ̼ݙZ^1;۱q+wqqf>}big^ qˎ{xܯ)WڔoFkmֳ53P.,0yq^crWͱ/;/YUmy%^ TEax2.v洺ɓL$&ɣzʑJO`xp/aD2db^s4<7ޒX8SX%ͤ% gY,#1L=mM0H\v*O^yF;9s8c|ab.Ci&3:aiېK#kl;u'x2 S&!M.#?ۇW3+K&v2b$I=]ijPZQEעQLΑp\6K޲f3؎tx\3<:J<&jo3|{7tv2G~b'spmde߈)LO2Zjk+ʼnm,i!ěD9Gfnm1*55GglS?+d~xW9>,>r&ˣtfh2ѱ'Le]KΓ&e啸ɓ ͌darqMU B*!.oz`(eވk,+^oxph 116Lz]{^_?AXe( 2ziN_\OE"iqzd'" ;tǶgkh(c͛g G9wE^>oqӺ׳5 {N疸t9m0^~w6PӞ9z3jPx_c9Q_J3Ԕ}$-/# 'b`hT& u\ 1>80x#46ŚdOƺ <+P0t[y%5%#v86N﹙Gw}Yp" SJXVfԶ/Ts)/9{,*j+ o}v+9J]m-xu! R][KD;ɱ*H@e }76R.wb[!;'?{SQJ66|Է.$o[#U]NSBQ[}=gYU809y 5| |h9'^>Lַꨉ@i<v5U_c:Zc[yJ?0"apY =ݴݷ?~MX1vlOJ{?̞a? H8Kp~'<]3Y?x7>9v97˦wr- (+Ɏ111l{?|Oݽ&A9v=Mu;z|#Fu3Ukٸs{?|Iǁg!GLjBϲ74cOI(A,±b9YeNerryuJ)t6 7Z˞'fvsv)P4C1勨<ѝOs=V|'R3{P +?'vr?GhUʥJ98d˶h4V#>t)ҹDi m|5JiWA"Ϙ\v_YRmH:@P0>ԋmmF{i&k_8 (i߲_%,δs?2 =}.I($͐NnK&7/X$qrc#d(H@'_Awsh7-3VpHA-Oオ=% а_?3nʛc¬b8 qa3NNIg-2CyL[֬y4UhY*ל&N0rqNPj+635tX,F,=S"MNe ,|Fj8vPʨ(sd+U!o-O-?WIM[d(eHI'C&&=1Az"`sZwѺVkeAC%7>5΋O%p2#飑;ߵp{rqDL"Qhd[yyn_;X]¡c]4l!\/*>Mke9nl$2ao%~WκNK{YQu3e5K\F)Eii `N4 skNK_+m% JJ"%.㔕E1Mv8LRй8:r_,V-"~|;&x9 z+YZAϾ<7FT1P6;bEc)hM>{F7j"}yljFy[ eٵ%uί`1=EwͦwҺ0p%˖ˏяTbrjK}ROw. L8 -TQ_mu3rlC0RASC#8`y)) 2yޱFaj*8dr9J??]7ƥ 9Sx`:P& SO֤j*к0Ydr:\@O\q.fD/O눥5δf{g~۞~\^|\żq#?v 񎣭 'vŏ=}乤xQIē\8]#YdUqp.4T3R($SQQ.%:;v϶C%0G0Tk֗^_*7m='셿pO{ǼBc.vf$9䗥5@WJp7f{+KH̿]n@ _ާUT!U?b&M W Y&scn^-lKOSB!7?TVޛ"so`Y)XKظ)B!dWݤRisqe!T䳎t$PB!x=,"LzQ,w8RD"k\ `þ&X !Bf22Mnc ɖe]u%-B!ov7dn=7[8XB!֛1J%ԜB!7WZ,Ӫ.):0dkR 3azSҤKB!78N:4c]VR  2^8qn"AowvJśVdqLn)B!z֋2v&Fs x^|^2{SgIda|RJW|Qz٫g.ȲB!;UI% 6 *(4Z- ~Ӵ,h:hR<|Is.ȲB! N;Nz)Ƹv( ]s˶l+1==f|!ҹmegWe!B>Ť D#:džO(qM'2XE. D,uPgǓd-+%J1zzp*|xb˶e SSUjüznf B! ^aÆ NL˛`M0?/{z<ý]d]8G\We44s) &we?':>(ntYe!B~-5) #d Q\ZCaʔkEO=g$aQZ_GZG+1^0 a.\&92BS_UGkt(DZa!BMO+92K&OcS.Yd\d, G(hNhmO{B- 0,tB!x&[^zb-38c *J.LD*N"13CZp,ccqic;z.VpyL2 bu;sAFB!nxJjvЎ&-ǶH'cCմW6rFWsA.g 3T Иa7}]\;q( 1M|&K6p7RF<ݝ\w`Y!' 2;$K`>.q vR[%1Ў(9G]i(!S388T)e!/ M=}u G(+w"5LOw7eee@w =Ba"zaH,B2;NTͣVO-0]&ƌukYPRe;(v,eޢh. /q^F+4i \.7.UZPYaݪny\K, !B^kY&RP.7kRˍVέPEC.<3֓=+{vo+`Y!'M̾Ĵ?_Z_ú^k'>~, !Be-ⷄ9A B!nxs7V!9B!u7~5?Ԇ]lVb]/Sj܈W|z4.uWz@ `x?hwZ">sP ]=$-BW`c'"╒B!xza=EK|׼p"Iep {%Ʌkoe5vf_*pJ<ֺa%Ult#/fG5]s/s4Mؗ莗X-k0)2I!Y(jr;c<.Rq7V`~sydwռ.`^ {y\ -Ԯw܂KAv'؋pɶaaB!'U@ނ~/GeuL*?gQV8W 6Rd{8|+V卲j |B5}j4Z֬^LPs+?rG8 lXw ;P9ʗ\cgG7~_rf8i(Oq شimYx3X(CvKXv7mWc 6oBe?}EjsʅB!v֮d\@vp+7gykmaYeAH;}|o y 8:^86Q10}mcY6mcN15Ʋ,,Brgjt4LO0 mU3-d3A'Ʊ5y,jå/89i D;۩JOax˸impn !mЅB0:˗FLPq"yqexۇQ5 f6P>yCsjXqs-Ka 4 ?}0>||wsq?H]AV9v8׭b?G8~<#%P5%9iZ6SC?i'غ STW~raĂd+?Ѷd)#G]+2P1[7:0sq e:xm mse]m˦\cm&ݚu! цAh1m #B!x6+T=PI_;ɼn9 Վ QYQ+\O'eX=׾Q/*,/@ e\mR+w8r,yOҒ(Mu8(6:pUTS?z}q&}Ìgl^3ǿ湓X(tv~u~bk~YUʓ?G]<<{ [fG{Yv#\{#Y `HIH'S&n n?F,12,B7$ѝ,ȆT6.]7b nO޳vp nPWrZmjWj%'`%r~Q˩m[5 /~(h \ZI!ΠTbE.!QM+) dy^2BQQ+C2FR#oR`!ge=󯦋H ߶ƒƒ¶ضM8'u_ DB)Ӱ;FxmTݨi_qS4޲lݺ~~8k~A̮#)[vͯīׅZ:JuE#Qqm01R/BIM4z"ΨRZG4lؚ*5W)(Bt0Rh4:fn&7Gvq;8r\ 7ʼ ?.a^{ؿ~~F&3ctw8(4P,qmrXVDm:A`&:; =S{Σ%x,y|r!2F`O[azrwr &(kօexӿ+;޽8N,ǯ+gfVPCݻeX V,$D)++,>J;8VaZC2 "JA.'q"X{8qc9dG7RTw'&OC+?6o?.᳧IV-d|*o^ECtrNӝܼڶnB!xSL~KxD"AIIØ-yx7=<e 4Vc~].ΝS9֙`p5C8sYܾRj+ ]8OW+BY `hp~;Ny!.=GP_'`<ưŮgdϙAd~J񐧻'I:,<5<֦r0b3g_͙={81tVnj)bhk`4On?Mo,Mܹ&J lF:ϰ @D!yf1 :=;/Y½[Wvr1:Α,Yʻ$Uw<|Z+ VU8A,> ,njjatJc#u0Bqbq`+; +_e7L kWZ֚@6>FLN Pe(Ҥc# A(^s2!9:hi1O8JJBU +)K RU(L)E>c`h pY%ea/רB!EEe%--k,Ri%ݴv.oQ-4YlFNB{/ef (vc]i۔!R@/v+VŪq1>8˩ K.OOmH LӢT*RA+1(' 1X'o9(e 573I_˯+.<|>/g!B|}ۯ@]~˻Mk SqLj}6Ҿj\R_-ˠnAKa{^!jϩa8x}i=K~u> !0&B!כДD!B' B!B!BBe!B!f!B!`Y!BYH,B!,^SB!x]xMal|s[!BWdYi`/UJ)'M^B!J-bkYv&{B!xմ~)X~&B!ۉTB!b, !B1ל!Bq#rF;*3V0f-8 jJJ$XB!;^>o144H&Eqh>K=܍Ր`Y!hJ)0h?zoΜm 㔗X<2im1ݲ,/tx(++{`Y!xr0 ㆬvQqp7+l~]`Y!@Bk0`ܿ+Q}5B!:UWr9s#B!UWPJaE;-Ns3i\5QYwk0yb%ibLf0L^ 좤a!B0BiPΝwqT+_>dٚܲakV,;CN [oFyKXl^Wy"__=K&ڛq˺U:׿O8@"WX6X^Kb$T(>` K}wYB!bH6}tU)No?ν_S]U{ZT\[SAlv6jr4W:'bLSM2S\Y)\7~k0˕FRsU(8ag5M%hG$ÿw/#PUUB8짪zOc_>)V7NJ7nK,Bw<=-A)b?CpcE=.43m9Wkai7Ji2c4?Byiº) rhhP dc?Bfٸ &-wq<߰ji3C l(~_w Ϻs,BA1>6Mklj9kD.@z,/<|=whp0}]1{VѷAu:gѺU(;'~N00c"c4u+NŃl+*/8(CA.>,AN02#o(Lw!.\w\ȲB!D_0tYc.g=הJ|Lh pM=&EKi=,5ʮQ?AC؍hJU8g>z?eۻ0^\jf0_վ]~J(X[|˞%O0 pb_ofDȲB!f*wȲ͛OCN?S7cTm9}a yGϓ*dh qp;¤=SnOsa(N".r;v>dT?IM$!ܨ)Ss+%.6gQO18bWy qcsʶ[=|;JB!x.qll[w%viyJ 38tvD>[J,G$){1Ⱗ'DaD^~a7YC)l~YŴL |Uw466\/}6(C;ǎpkZq| mҲ]'&{I1X㍼opZe!BYiSw.#?Og06eVsx7zΰh'#C){{Ob|t.p' ˣ=lyz7SsC^gEZw_#?v{vssG1ϓ[9 Z=O {Wr_޳$smGab&>mTxcȑZLd8Ϫ;>`;~~cd:J}KxB!xGPJJmP(tH֘KWVfcGst;.=vjV/l :87Jv>nGT55cγsa)j3v YoyhʼC'9z_. Q4ڰC$ Ѷ _n=/\O@5Ӎz B3=J`0FaiY /9t8ϜBeuf>a$8@ S\GI8Lüys}?xCMc#ڶ1~?`pEN?ʗ|1_wB!o J)TWW)孋MBL ULp@`f}%NO-{ᆱu* B!@ @ ޛSJ _w0ye!B!f!B!`Y!BYH,B!,$XB!bV8< X{ÄB!x5eQJK_+_r{B!sn5'!B!B!B!B!B!B!bXFDn%tEXtdate:create2017-10-09T15:01:22+02:00%tEXtdate:modify2017-10-09T13:58:42+02:00-xZtEXtSoftwaregnome-screenshot>IENDB`Eqonomize-1.5.3/doc/html/C/figures/transfers.png000066400000000000000000007362351416454732000215700ustar00rootroot00000000000000PNG  IHDRVEKgAMA a cHRMz&u0`:pQ<bKGDIDATxwu~NsFF$HIQŠhٲ$s=ؖϛw߽]όg3N-[-JV$ @Dd99O蓫j?NwFbFSU;kBP( B@JyP(: BP( NٳgϭΆBňL:? BP( BP(e%?7fG( BP( Bxr?.b" R(+* BP( B&r:y=}P(X: BP( BP(sFο*t!4ma0BP(7wz* BYp#?=`(Y[U1ծbJGil=-){|b&.*eBP( EM!#ɒfdS$8< M8|_^!f7e&HF.@s92 l\.O>'+e&%_4}f8b)sds^VPK~s2b˝k(-IF#._fS ʑoR_r<2vHn&$v󑏱loB8z.t2xg4XMF >RxpN-Ɩ +qNjt!$?#Q|-?]ou段lșc\j{5 oHQZm! BSU yӺhGw3m \h`ݶľA'8amV7*ow¿v E{]F:ul 7=E#mʧ_s_Ұtgέ& !$>x8?g>(*< Lqga6>) \ԆuƢ7PP( Ż+U+|𱏳]U;RfҜMQhZ)B{i3嚭S6_wbAuk3eh睯'!nfp93o|]Dk~{_|M)}}A;.st]]7?JyKe҄(}/I 4coqnLP]¡i8um4yvX}6ׅ(;øp̕:.?e8<9[Y\NG P^I縨)}kL@rÇ& VWuhk6`4) 8?wPd~{^Z^N*+9ۛ,CJujF&T6ᡢ~9h_Wݗ=:UR_ sh %mޘ-[>6Nt4t4M#=vo&-]8RpTphӾԘph%a̓ s,p2l{{IN3<#-hZF6>X#}UU g}My שm`YSN]Pg|r ]FeԕФp/}cSS.c"ӱl9a#Oй+,t|4 10"\dMvd?F>ۨ 8q}Y@`15dl$PL{C(Ljk[lo$B*>Cwfdx"?`MqeMSYN#˱]O"Gh`;XQ.VXF` 2RN۩ y1s`ŪN*K20~}9:cEm˅v!Ɂ:mw%8]bwV馘i,Z:^wN˪lc;FzʽHHd\Mcg<~(hjjbH28rԂ$LNQ>Vҏ\wdOE#˛K 5^7]<|[ҜI*2xt孵xO~xZj w}~捫Цiijֱ iFFeS 5Bt..FL0&`"YPӴ5ɍpn`tQc%A5Y\,5+Črp/@HI22LYZFadd mEkYKW[() BzE.y B Ӽw˿[~72Ͼptûwqz"d|+dI0S/|G~, #oql*mZ\Yv 7ؾ%zDYm35Ī7MN%gˇfӆuGJ4gZW*WG45d7}l3[}z#շR0`4z56?9EZ_N#GVJr;ɊlCC SWs:=ŊO56Йˢ70 ?KO D`Ew瘐ligUWmgܕ~SϿğ=9yzv dEYdz(<m BjkfpȢ˚=B_UO[]S0|457`? =EI3bᣭPioGׄ0-l .:|؞0'|sGpbbv2ҽ\aԿ#X~,ȿG He [? x2ˉ`V }e U>cْ,Դ]J@F+qG?H7;^e_]Ey7!`y[ ī'> ]rֵƝ)zbo| r.Yhq^y9u1S/Ǻ`8_ւ7S;nsf+5||K})&BP(WHu/@@.*kj )&&ַz7G?@5iފVon[oV3c/.M27g~~:XP&Ҭbz_O|e< U_m\w~R_/~1lpc 5Ҷ,ἺFӝ^s.σ7vKZ.Q,9X5l[j2_'G^Z6Sm~lkž̅8(U@~cȧ?ʶz't{px]``1 [p^s BP[sxBeWa,"GΜ-=z 7ɉI>c||;c9fI 3]P#dx2=!R2q,-0D' /*F[݂n/"|ճ72l!gPI R:&/Éܜ_qs91Nj4mz OLHqvy+=&?L4kro0M۲7(.*)Ѽu|7‘/9&rpZ^6, iW<: 3;űع0#ER.-6ZygogL`2|I4=o_'P,I10I4&Da&3\jA.4m|/z MMXgdGIܳAm/S8WoyLt'zHiNeH4*[_5k']f'9o7x*?B~2+;۬2?73^yu#Y&ӌL ݅_uݧ0'WϹa d2$ /˶>~棴a$#M!)߶/5rvyq<$R ceߛŨo_Cxk[; O~oCdߓB`88]Βoc6 #O(ަ^ Rv|( Bxr呴EwI]2WΝYȑLdXA g낲n7 oonfL"]ښkɟɳolґWvaMMmoÝ>Nx}vy^rB̗d7ձtwȹ@ 9)6<͆$gH ?~D]ܱy>e[ضHJ[~:Bl8ӲFpgGDD3>@IˊrN<78 rq:/Om$2M,m^ñ!%<m&z(Lqg魥g*إS CYիiѮ!:oJž8WHJXG~635pg-yD„+h)ٟdl|iIMkz$?{SH!%ʣi:-I$Y$W(`^VPrRbR" - N7ϕiILN1OӸ#;V8=0Rie8o7C\7Lye9 xb̒3z0ŦogEC9RJ6/8g-g(L +G4 ~_Nt`0gfsFbHqpgŦMD$&IX^X*,)j3[9劘7&Mu"hSU66ALGpׯ6%mjk/fo1sמ&Z\EvxXna<Ξ-KȲ0&R4!EHxjYP( sH0=#TTv9Ib*J*9M$#oV'OLD++}/7.ǃMMևKIŇNVb\3lBxX]qV!>p}+BW^wm⁇~m:*o⎵䧷WbENϛ~o!h%=dS-Q"ZH$J2&OaWOOJwDHLz|4Tz%BNF(zXۢSVq^F/OFH⌍GɴHD2/~f*17U%Iɞj-"KpFO( R(S)Y/G^^IU&V.A82L$m016ˣ~T&.2]l.CUT6vM*G4@d:O]|9t kvc*2E"$SB8Dbb1^qF׳qu5AB+6sD'&(ԙv\6bӫv| '>}kɎD?0^8K0yvv_Ĺsj|Ҥs3*ZI~]zZy{JX2MK8t Ka3po߬crcE?eOɺeZEйX"4cS)LΚYXE 4'D -@C39&ǻku84|mʑKP( Qp#ɺhj kn**+ zKmf'o PH39M*@yeUeԵ`&V}+їb<8GYu=a $}CJ@]l6[Rkcv$[ظE]* 16p|Jg\{57ɥr:׬Z*+id$+ Uk2%V:c}LZuwoyM%R&)k#RSSOK=rRVUI!XQKEM>غCwҀe8. Ti /0Me~&+nMxBU4sZ}jAECuUլXeu> zM[7\Ci O1aZ[O16mSSHe(@լu264x$(_ɇ?tA'V>A_?Lƺj(}ӔCTTPWFftqd> +^)c 8Hţrc:]6^$Pĺխ M(zrٲ]3oY67px4Շ$ QЈ8Ź < 54Toh+B[_Z.?L 18a*>Mu=߽2Am{':G:Ct[OG}ᣭk +x*Yu3tg\vtA&ꨬ(:7@QBb@%e54UphM%e4"tQQp+׬1 +na.^D>IImw|TB#=IX[ǽMkl3PI}YL| ᫤<0z;n*ZURtJ$pht128 R.gHw}u#&PﵙJf V5PqVQQ̺5+(sZsl]A"iNSȹdS[YFrlS4:. )u tZGWK5T8L&˨i"DD֤>X@:\L^BaI )/gfO?sW_aǎgyi)p ++gh|pf۲4Ett)ʫk 'v,){H**/#TVIMeʦla) /Z(F”+il°bd+b)N| CP( s zsT<}M;o)%\1L*)VZ:K߶Zd)g;-} "6gj;? h3. >r&ܳD)og~7/0l>LyĬϦ-KfZwt6] F=@+EGm9NKyk+f>u x8[__}?ֳ\{\lcJ5Rb(T[/\8fLv=os} ޼4g1ߵa~_z7 %.G*8s3ckn*}/g"^8{a=!"ϟٸh_>_..W.U>梾ϼ1۞/|a9nD_T} !,9>p_؏7m4gLCkC%䧣2GԻKuw] ˍ.|^^ V 磿?ݴgq*BP(a~|,苫:5@6|/e):I{."ug_,/ŧu.`0 }nqʼnb+m}vq^.m*{ur}RϿT_.QKԇ}]d/W |i^ᄡ E0 %dĵLsHRse_;.GĖ+nE_Hrs"U#4A~>_dC[J4aIŭX|\|^^.1)"* Bxr  Bxot/sQR)Fzӓ7M$|t.Ov:M BP߹*BP(Hװ_uRS_OKk'갗l.r3C>h(0yg[ٶP( UP( B)6ʼx bXX$ BP(޳\ BP_(P 6DBP( BP( BPPBP( BP(G(EBP( BP(#"@P( BP(JP( BP( P( BP( }R( BP( B>¸P(U.{t )Kyu:si6p835IiSYY|h E"KtJ:B][+ A&'1M]s ƾH5A Ӗ&n#IG3/YeXRJr\4}&1!(-68h 稡 Rpe\nQW׀垓D&q=a$b)Lyʮ=l)9rf^4 ځ\XU\n Gضn~sIug^+X|umE#rl y[adPR X:btqb^U裰P( WHIOO۷o'\Vƅ+ ]78|޿JxGx״4 ^| ^TG}wkl۾jTA$9ŀi,[ ۶43gp6le|M¸i^xy&''0oٺ~Cܼ4^:-){tN8A7oMJ!=1"ҋ/еj56l y,D. g\JergKm3iD!vmhjfVYskĖ&#S$#$Ĭ\ EItstEliRl"rI޵"M)n0tFɄ`ql8Dr;L. KJa@^_łK*K\nӒ~jCY|+W, H!a[hǏcML 3KX:"EŐ# 6l BP(޵,5pPW_OEEE 0/?Gz!+pyv94ڵXfU  )++S E>oN+++Ǐr-mDP5k\/ŋ/@,t,aD"25{!b^^߷TdӦMn=ʞ={o|zݱ.nu֗x|&7Üm)$?G]R@QJj?fFxf0X| CR\ |A1?o2u}mZ`:g12Áu dW u= E`8TX~D^_2::?B]ㆅ.67@V4Ah |TJJDhv!t7{8 H 714ӡ/9}(M[JlۦP1׋B(" &RJlc)~ ]ʛ8LaQ0-2=jm+rSo?]}f)@a~[C("ޑs&$,Z.w^/ZgrP( }ȒΚ__$p|6k&}=Wb6]z4Lpvݺ%>s域`0@WW''OMf:6nmPJ[]K)řϺM\O>O<'vmb6shooGu{ή.>G}۶뚟+Q%o !d=ݴuYdX.;A&c(_n3g˃$5 ɉeT*O2]ۛi -bY8e2c" txQZk=9AgcuWKp菰 tuvE@z"F̀-b$3zFSq.4\6H>tnn4=:Z ӟ"؈P1 BxqcN ),?{#8,[rfw.'ܗA8v^k*m,@s9{,##}v{ƅema8~8'OoQgd2P(.;ݲ WٖE,H5Ƨ]" /%u8O EK0<%2̕$!`^T{KO\65>bZ `CiSt1EL0874E*U NIѱv* $#QY@2Y 6q|NP/EӦoHD-P r^/PĖ:;M EZ; PtrJ++QN:]+pݔUT!$ϓ $YM[s>( csm TԓpxM`l1!9@_گG. /]jJy$޽06Vr?͖r CXas˫P( ]uWH)q8/vz_~Q&IG4lw#K)fR),Burܜ7mP(H0 NV,!W/~WΫT]RJ,HX ǼվD` 5i8 ǂ1b6er-\^b4e R\ O $OIDZgw5Ũ7e#D|hiKRRvyU= ̚:[ۅwF@eb!  Q<{ĵDׄkt icU)pY`(x3y &sYb^w~JȒ-%Yנz ,yde"$CҶ*;ofRhSSXؾ BP(]",V^z>C^ \ά=ؙ5߶~~+躎̙ץ@>+V]_d߮N㉫Jöm>y%' lu#۷w󯹜͢aOr@xNqdR'q0WoSx},F(Rw˷gf)+/}h~NVÍ{a5z/5҂Gϥ8yxЈ' ^_U5IJl F$!<Βoֻ_$,܌^xllns<,,f`\eZ|N?N{P#x7|˅eK`h-)m)$k JZ)&4MF%P(p:x^\n/>Ra{>m9d˶sF,=/"t#] 8~?2|xɽeτa S|E07~tL_(&EKA NLܑQjBn>bPB`XtDl'_7\&`Xcc荍p* Bu0 =״/m{kbYAN**+1ͷ_]+( \>3 ⛅isB͎OOXr%gR(P(099aTWWc6###Ajjjm8p]7;q8y^}unwޱH'+r0:2B[{UU8+v.$iH"71ɪ6NiAzNd;si; NKI 1@ =aLD4qM)q9]S9w8T7ܶB@<6@!3 (vciiL&)*NtiS`ksGքTh!m0GӜLMEk0pbHRR'FMMeea"78~p ~˿m*|YBPm,_Yѷ#*^;6Fd4ț%|&h4=P С!***bsqq4M|N6:2$XbNGŴLHRs 3666g)& Ż,%*kf?_P."RcWm=&4^&c|h`IEViǐG{&9rMUvB`Xr#gE4,P4f,t@P( Ż#]k,)%+;xJlfllD4jkyuAZhii/]sf|(C}=SOavB9ωOn3Wg_ׂWM*ba䜄U#M*1L"1`~鳬[ӅSD 4C=XS|>á60NO r3K"m2^&&领.4gPSzkyTmo ;Mu m%%1`l5;6P"ϱ'ࡇ,~BHy7) vZXDJgsJ-[4>G'?y}Q֮]wkڜ:'} $˗-Ci(^|稬R|? m28}tԬNQ [lFSҽ3i[w224x/oR5֑2qиňD&)oCh!axL2l- hv5݁;Z'\0D!Ex,\fŅ7@-C',_A9'iti HM16-~B%FJMsTٸ֭rQYf +W2=.~?޽ǏS^^AcSӢt:Yz5__$4[XAj IN%2I> z_kE;XE-aلlaͦM3i^o!;RRǯNp/~5b 0Ҝ|"@HȔk#vZUhҦY BP(ޭl&HZqBFٻw?˗`ppZZZꤢ:Νc*cҏzI_47{IUe%=!Μ=˪E)fu=\ىmY 6,,ݻضm---sy˲8|0uEM:уXWE>!R(@opmAÌOe`c!|{Mu ~@hj\hLhDJI0@}=tw pN**W=g^BPI;%*$#8qGfÃHڏ,k, yA']r.8~k䲣VXLAK]Lĉ3%0$8u$~7,I! p, EӎRPI)qWUQ{8%*՜uY*ʫy'tH/bD0Jm$@BP(g(EUػw/UUe&l%29eΊ+ؿuǸtf>|BmwdeCJIUU%UUs/E|m  s4`0(U8 BѤuL&>gжl yt ԯ,m/.1=Kw=tN[Ne*tW9EblټSW!麃k?[ArR]f3 N}2&ghkDZrݯ~USTG)h]^ g=Άm愄Ҙ[n~4m5`dtDUݦEMw6=^ p4Ѱ4nAuN?}NV3K$c6pw?!쫴H$hHX,F:&ɰj*Y~=f߾}0+6'HRsW¶-rX,Fb ƖeY02&$Lʜ̙RH4o@?bƢ{C}Vvwqs-* GX14{aEO/P( (EUb6poywÅp8L&֖VLjD"~̈́_JI.#t:~睼H)EvC4***-=LOOs=c==}[@阾) ٴC ".x)"1j[?I:)09bhdPuk;8u0GՉ9I6=i=nutXyw`&NkEDt*rc n^Eȟp=#•CWUSH;MqاI'OXΩȤ#  hacKMp.gϒ()  <e7miZXڒ"gΝp(h`br*lΝ;ٿ\,EH /X,=#`6(a(ZpD%%:?3#L/m T4Tx|3@O-mAV7њn#M aOp44\U~֭$ѧNar2CO3iԜaXӬC*u BP\w//*JkjXn=<D"LfkAJI ȑ# ͎;)$Q@|@Yٺ\n/ȓeYsu$rS(Yf ~6oOSN>Ls)hA#SI4˗5rhPX<\r\;hl."/DN\nC}1"+tv806 MfW~ vW_Nws%8]^l C1jk33CJjj12:T P#Xsms:~f ZC7!mvܥ>j[>p/RMӗ,9ƌa!Ed<ԍˊ$qi !XbsV.e~z9p/07>Rh׋ LND4 C_pٹrYWo}|!ں:|>p?}}},phBpO1@뤥a dKG R!ۈm݊rҕb_m!&S#a'(gE˕@P(!J.AJIP /XmŢl޲T^|M[msmgP,ݻNknҲ,bS1, 'OdbbÞ={&ϓH$ػw/TjHb)BL&9pMRNMװ-˶p o]ׯ McZy0lh'\m {_{pUeM"NKN24$.6i-?狀~e7 0fVׁIJ LBW{F ܂& 8>_5_Lo8TAw76F ;ix/_dqÁaض=t[oE2) q >\EM1<<륬lQ!D)YW]^pmc=C@A:&;6n{0́r ~?;L|.M;ߧ˖|{ʭ/s?{o.M>%fUL̄@sބQ Bx4E`N`YT"Qj$SҞ/w|!ZRu~I>߂kױ}]3Q-N淋P(tg}vgEy ?p_(ܹsyf i&:ӧ,}C%?g,zIN>u[~ޮ^/o v>7==ҋoS@~wp Mݦc^chp?i͛JiNۦ6)x:u oh0tuJ{>`ƖS/a[E[ALYFyJ[JPE׳jI4yŧqC3:3_R],=p HR^oIB\.N'}}}tvvRUUE 3 s2BFFF ۳(ؚ :4Ҟ MO>o۲5q:i?ӟ8 eZ<44,x.}w]MX&>f\h͙R?EܪF(klQJBP(ާ\T-P(Ow&{]rF5]LMM!91ɓ'v'''y7.{eYDQ8iLNNٹtg!E;IMMh7oO-<w?phڼ dB066JLDkŲ,vE0dڵsOAe~3=z;wҵj5+sKil6KPP(mL&C>Um<Oq ԑvmAY;>MuM6znlz|.͆mA(`f<*~oQ^у?ahh!jcs 4IӲ_  9Ճpѱv-Pǂ+m^q׀r],UВ|q+5H$k{^0 V\t\nxMAZJI.cΝF^: L엒l4zU~Es/c.:`ecrB_{3 R"dIiE\!IY]ŒKhK }ҟMZE_Mхw-y~`&OTVUusّcBH${rHLm3nni2XVۏof}Ci*"ISSS{w3yf6===={ёQp\IOOʊ+ohڔV'- Hp'^2RG([r.c.nf>liLM+ф^:I$V( B* ҐRH$(\޲d/ nλRDl6 ,..̩~J kqP( B粊ujBqBPVV]mUsH`0H]]\MnJuӃ5: BP\P(n2JWgb728BP( b BP( BP"@P( BP(JP( BP( P( BP( }R( BP( B>B) BP( Bx BP( BP0s9YP( Bx7#YP([*l&P,nu^r,n{ tZ2BjE.Ǣ[-mVgE .׋P] }ۮibe*7)%Dp( i|>ѹEiZՖ2[F>gddˉ)ow*eNouV3A]P(޷\Q fv,R}bGqk1W-Q 놔NnuN}>&'#H1w;4)nuF JKP(ޅHL f[!p^tv7W&z vMo>!IJM]u)jBP,TP(s4{9l= :cU姑ط:{KӒ &C(+9J&mB*ޖ6Pq`"3bmQ,4B B: BxrCaYmp8Zb;ltK zfHF`UUxUR"zfjTG{k&mc !ŢTWvB\]١WTVCiΎ) 'c2NqʨV^x(B'ttvb wt#,iJYBX?v9yi3Hk{ Ǝ'}߉[+;[=1boI)mLYSҎy@̥ 1k (AU2p8%i[[}|[l[2ʳ-+gv^V6y8cyf 5X LL-WN@d!޸Om[Gu's)~58,X 7I'Fy9Vpo ~|~ߏDsqmeh{%y)gƲ/5˹Y>>}nN`ҹ|:%w-ۖ<5\螣͟X-J,N}]zX 7H{"1376J4f"qؾ};ü<TUUa%AJIuu5wq>,T1+X,&Umr8d/_8,]O/;_5MpTb{u˲ҿd Bqi"&9 b%E >8}%wU=y#wpw[pA IOM26%3WXWc" T7RSC1:%oh \2ILo«whYjtV!DGY+1D=PEKs~OJw[#TװrYbI2pu#U $Ri\Ʈʿpjg->`8̿C2~|6&Zn,8.!''$`J~/LG93LAAX$Fhkm+rLL1>d&4p5MոcMf(mUuԔѰ$ēEa7bEBM4ׄgN6(#qҠM&ar*E` WS_¡C~:$M|%ec'O6 b[ntَ̓6u+ʐRR,ɤF NW]ES1#8I]K 5AcD57 T}BMF`uu5RmfFgd,tڈǞf`xtfk3atM-4TLGLj5.s#VVabHұǸn&lt:eYhvѻXJ !"Ǧp:z0வ-x _ M&&R0T3ϷO0"cjQ['g2fR@- ?<UBbRLe ]L2*X\Iq:J|**pybkRS+Xv!d,g 12<᧮K*f%6EUX? SS1,bA^/dgu]_e˖q8TV^&p!t'oa8Ӑa&v|&Sc F ZfPB6e2 7q*-!f"q$#;6IF'&PLM@'99D+븴.tu]{VTP(9{??w(\2L;B4ǏC"^zzz~z{{|Ç 74,2%ӽQ*hkwrv㘻b1Gq>r_2YN>h \DqZt8z_~3D#>žC)ꌞz>*ގ4 pt;]?O!fK|ўܹ)w-+*!7[oT\KОLac0!%,I%8} uk8F.:LGy%]LZork.hIGLw/7Bb7bB2}#)t]0=qOkcrl9˹/~[۩m%x80yAr* 4!"5r1#L!#'9A3oOH{/#47V^џZqTuh4 (#irڼkڻkg]{lFy3%9Ω$ T$]]u7dg\-lK#V j1t7aX|ByNPR# 2*}hsħȤ&9KXg*Bc .LJVD[2~g{ah?LOl Fj3'*X,gTז=O#y 8t~²2v{ޡg2J }Z&8-q\?5K(X1ғ>tF" }q;Iuu1c͇86?hP!ngO'W֊P=Pk,Q`( /\ hf8%mRYEolZfqwYicߞc{5A3v0?O6nw!JNL_S<˷Hjh-";ɯ~=y)#=6/m["7 @4g3BS@e5AF癓tLqX[9>Nqu}K6QNMey9 KWU\8~1BUE8.ɯ:bUA;0ζ2 c|tOoo~!~׵eL&q\b|l UUq\!(//fw^x^W!X,$I:;;C˥bbYΟ83t; .Y3' &Z99AIu-'NbZ`iF{/g^BT(lKj!ľ#LXCT{9ˁn61vi^C]#BS]NȩdQߢǾ^t~gށ@˦f*yE%r->dkaY3?ݦv'"q{)½G8vU$)B^f -芳/z)}m~,_gqFhlشBɁMLHn$TYvt Z<TpTXwz 8 X}࡯hi G-<`]}>wCndh/x7)Ɨ))*eHo-;ذI e")H)|q i@SDX"ctN7pG2g*oR`oSS F/KW5ⴥX,hsA"~GOooLdlڹ ~>Gf ܬ Ks%dGO㼫jXK?ŷP_W <B14&ISXC۳$5V(`gU}ыha}VN,YVC,"|c"ta!JtV.˨fN[?D sm#r0 )t B%g%1jcKtM`/Zgz,/.K˧a u^?Cv*<6ZO5pgoyh |V {$O`_[ƊK^'m^f֯81ʲrap[@Z`dIŢtX]YZ cpe|`U .r ##t8t~֡b̸ĩf)'yRJteEȢY@s[S1nZVغljܽ*Hid彏x8(2|16 7/=eCTHaEh4PZZ 8iSrJ,T;o? +h;š0w߿<; 2`@ Uk밯]3shjKIDATGVLE v-'f(KdHB1=s"禦XyddnU/TJE0޸EN_q*$ >埉ɧ`Z),,$Ns]wqF:;; Ü87߿@ ߟw@cbj(0G *uvrzL;9||0bi!SSCC!=ʉ+ɳH4]b󖱤On$O t{qج(V`dMyVrƇ*i|gw=q]YYfc>qXݔ{!o _Wxe7.SB)S X6B yݾB6"9s@C2ėACΤ$ٱ'@0㊠Rb_8"C6*y^. >LUM~ D χSH8֙taYzZQq5b(iO~ ËjA N4: *Ϟc*}t=ƠbP *YxD`׍}cHiPXF&2 J]:ԙhc|hx+¢%nI:5P=N^^ZIe4T ڡ<]ױ8<\9vUKq!O|<=zx|>\+* xZ$`+tMуf ;YUs\!Kw^Oy7K;/@`HՒQQa1DQ tVb!jQ.0X]n|nP<\H = M!`$'Ӈ|~?NUqS7CVJA2=l,w2u@KXJ::ˍ{^%X"Rji:{k+):4ۖz&kn<'q=bbh;v;yGX+i:}Ʉ@*f4#9)b1S$Yh-Kv&A`wKD]r"%gyH2ꗸʁwNc =p鬖 #6;o SRY*K5 84,FG:Ko%eIGN_*/;x)|C4ow~kmg ;M:֎@1QTzI'zoKgIFDtCcpQY"gd x#4duP浃6>L~giV 5Z5xx6 S;ś>B=S垿Bd==E\[L Kp &OiEW!b4_"Daf3)%:6}?g6{MFQN'n׋gxxp8L}}=%%% d{Ql>3[s!5n)EP9]cE, 1rI3%)6Gx"h#ƺ8zd'O?"]F5+ҭ Ҙ[*pNs93J-" u _Duy(|;ȷ TZb'23LO1Ty.[ȉׯPU2ĉh2w2IILG%uk eFB kaYzwStc9&N`wͿ1==DVҀdFh Ha|!^{y}I7gTjN R'P-z{L`M|el0u)%s 6\FHs}<ׯ+`Pb?IRUC6$ ʈHK?YQXD2P A2~ijVH 5+7vZ\~}S3kT2A"'rzW>T!( l)͹c(BKK .7n_*UUU?u<]s EDp9]MD/*. J^8 !L]ZW/X|T:u=&ox|ےܢ/=A{kCU\zsY|6N"nX _+CIe 62Dd$F*$%,/,,-kxl&N6c_XB:%HD!KIC S nXAOuVj2,65˫) ?xK +H`l(P(P' mJG%%TSpɨ^.WȢ*,HG~9˗pURWOll1;+n<OYQ>JqU ,:H\^?šdl)`!A^>~d<@/}CbFvZpX\SEOK+X` Zޞ~&S* (;2ƕW%K(˳01OwLGj/@Wi *YXOPB(S,y%(E*ExYUɎ&='8t{@Py9E%,jBO004x8MYz6!0؜6T#`O7 GQQ!y|jk8%H%Kwӓt3Pr2Zրkiiԉ_,36`3e8\.G!25 ]t NQR9skʢ|Ik,JIlE)`LL'([ lNIUUC͢T<CL 08]gah,Lf˱[,J+CKHVjQSġ 74fF|kxVր12xLrX,bÄ#Imb`NըH*@=SH?,.P >kҎR+&M)fYc >@I ^&'.|ۺE^dICxaI7{ (ͳ3xFv)( ]TOՈSKhh%m%gd,._ZYfQU >1z Bu fSA(((fq m2,'@0g.t{Bx]. z-v5`qS+ )k`㚥8 I^iybq#bBnƻ;fq).!Fl߰Kr `Y^"'ѩi {>KW*"2I{_Ӄ"T\ӪMT%f]]OH", L4t:=w,`xx˅b4`q F`*n5WRzJ|~q~6g uH$Xl !Oq(tdaP`~y>FA ͎?/S%:6@DA^υ˛%z Y OI( d3xC,YTn!oe7R]V!Č#F6:7\.;v ,^;餼sղ8xEA'$$7X\ȷK"(7..YvB :'lx ) /QYE,(jQTYCi i?~OYI-&QUP RXO^^.@wq݉@~!ux,h W~Ks\?5SU]Sa׹7`llp$rݍЮw敗_ ZZZwK80 ~v~~:-J\cyEdz_%ŬYNJxr+9;kv/SYϪdxMث=gh(V+֦~3[u.6 9d )Ξl"j Rw w|~k4(xSY3Zyf˜_w;\)%iyG8L 7pxX=BZs,2*=U%74+ym2} >z[4~7xpu)R7p~<{./;X,XϻO<vgӾMbQUWjy>Y 鈆F$gu|ŸW>ϲ㚍1G|~? V`J_ܘXfc;\\WBkL ^VXDUUt]grrL&(Jkk+---s裏R\\̙3g'Ss)Wr< ݗ \h89FƘA2]׉ƢA: OOs]wn:,\٤6Qh_WLNNRXbםSFu|Q\}s{_oquŸ7.߮`0H ƃV܂<|>⍛f0 ^y?N[[x~L&C:Fuy, La.IsU.[X]©ܮd"ٵ'뤍W*.殻쫖=ڬu߿%Ws.%='HO|} Jnè35`a\?_M.(^ I'g_ʽBP?]1v.iPX@OG)))Ðe}C^UС{aqi\! C k-XJO Zν l.166ă|N ګˏ+l>us&Wkɵ_Yf !Xz5մP\\̊p//О hg>yLGh%d+1.%ײ b5)nn$F@Wg'%Ey9ǻ/F8\n~yVDgrrX,F:2#\n7^Ҳ2}_+1c|JhcR-K?.QU _V'NP۟\&Ti(<}չj[uP(D2&pߴf|tH)X,TPPXH,%DHt: PUlMQ0'P,sܮ=\b^(ZGǃAut] b &&&&&&7MQ|rEsGιr) Ombbbbba"F|DbcC$&& 1?FmQ_WiL&J,l6q$HA: E4TIAJbZJ&b2iɤfbbr#%6`0x"@JI0?q5 Om`b1 UQLOUf[ 's옘.(@6fjKMɬOLLnr$9?S'y&f?=0&`8abNJ7\)0tT4F7&l D.ǀn躎>G7$[XSnXsME"AE>uɧ A6e:Shbbr+"`rr ÎB0zLn_;BZxܐ"vC(M7>&&&&&&&&&&&&>0EUP&HzRJ!1aZ 2Wf 'obdBs>m$|8LLLnIEAs'!PU\v Rf&-B(٤& }_.Ƿ2hb1ڎ\ I Ӂb'?TLuM5~'4C-}B&zH`wpT!bov.@I"H6<a611#Z>5֏@&ayεlJh$LBٶc3.3GP 6R ݂Mv ׬`r2-c!jɣP5(g+:UPUQFQ|;KLBN0o;$`sx ?| *5Tԧ7~}$U{bkC})snRJr?v?sQib@Q47꛼un˫{F<. -^OBʩ.2KM>VL4R\VNyO!ȧ l7)`$?xHoȩw>}̓;"@J*+ DC+s irR^{~{x N$!FF( P1OUo R]U=e6e}%R30,[T}o?}6})D8|̟7l+-mA Eu.a6:u|1Hq%p>ƥ(ri ?=}6S趣(Do-2!z|m@r6<-]Gu C:lzqv.Os;NlX,F"llwel2L%DX{& 64u0@S>69o-ө $(󓡑LjƓ3s\10:>C<%6'⤳'Nlj'R2\54Mǘ7⹵zNKbc^Id},d͏p& w)[6/٣rx[אGӛ.K5V8?^{xp GX@=S$1F'ɫ]k+Qb(JNod|`_xy_`6pv֕lgtd2ڵl߸9@2kLI?vt0:51xP7WP`ͽc<;kw/ȚR63Elq8g,޳Ofݯ[陈qyXeiqh)ΜcݎviF \9]Nش*`yN7Wt^䓌4FVe](@lٌLxutK?عɞ45urʎb!IMr Rb' ֭e:\2Ax4|X_,<6?S]T؂e瘶WؗȆ*?K1!s;8TX,*} L&md!8O5i?:Ǒ>Vo̒R?Zbvq`J{Z8y GFH7gO5>n/qZ,Ņu">֥{! 9Ǒ#'*Љ%26cˊ*\dbr@tC{)1JW-[c9vfŢd4jVnd lF}4wOp&h;-rkوzXrmcvBs<}L*YTBJɾv&H&a)Zʎm+zc/KPJA39>X7^lh%+ԏVJWoĺo1CG%3GoXÌGGa;pC<3 r 4yrm/ݼ>“}eNGC׾Y/*ƦH2INy};,g-THo")\*̩s|gZc፟}NzJXe=͟h,25ƞwON['_GC?Cn"u ‘C8Fb;h 6b|i:5(r֯ON #E}?BZȖR$/&TGTzS W?)6<╓HXԬZM 3!:ɮ'+,^w7_x#7ޤm" sf.C pßer/o"Gè6/K6RPG6"3ӑMߔRL4Q8)?Q;/C`ɒ Dbl)%zɟܷs>7~L'ԋ "9Tji4 J=%ݐXAJJh]^ʜ"QpKJG01E#՜4\ !-LLL>zLac)^~wsA-̙ q.U沗UE( B䂏Znh'FkoVY1 ͦ )?}J*h9BR` OWϬMUPD0394EFT(yCZɽd DUXaZ,@c8v&:=;F`"YZb_+p,[Hcd ۙF T[bqR; r3cn+6EY*+99,QPf!%(li TeZ9X$p R(RJd67; !r20@`G0?)ņccc`;|~Jm1F?kUf\_QUv@^&ZWEfIN@YY ^}.[. ⠪V6O5;u6t +ZB>p?E%%!5d#'hFo/\~l( }VLtOdnvInv4 \EK?wgWӺ%M6_H1iRCDDY&[xɧiIEVƻx`+ՅbHƒL1M 6!&&'i4lAq~8v 4k#M H))-)GhIRZZc~P4-DfOKFh96?|Xf ҧhs8u!Nn"l aty'?Աt%fhh>~4^GLg4ɥLl7σwl7Z$SSSܩn,T?J@hYdf-TE!3{cCgMf+%Gؽ8MD96rsd!m^^B _Rv_Fуt%Qmc\7*8AqNc`t EbdR\d!1cՔCbhr,ja310SPNzl#'e+ѤcdH \c#.zs'_ɝk*f, Ï\iah;wҥkI̹ʦsDJA|9t )!j'l㳘 ]Te0)~Aɹl6 ^}IBrO]Ptf}Z|y0v}VQT;u)/X]tNͯaiX߸R?/JoO;3@Ht-9mwDb;:LEŒsYݻe9w4漐Og~RĤAG!`4NvQ&Fh9Mv"}5VBni+XJel&)WS~(ϴ7~w RS]HrGO;SPNCu صB Hro'(qQv'rV%`=c)o E,vi% Yi;qzPq%NNMp o>HdE)wӴ=G`.&&Z$I, 6D/$S=M<ԋHSPQCuțho>űm Lz &A:S,2B9֎a+qq%J=oXjKÝ.:'XpǏ32 y\@ҊRFwq}Gλk/<]sIz&8oyUA*BQ):N⽃'.EB|.SH /%!'@1eA&{l>;/.v aB5T{?}݇1xQm.{qgj+ ނukrc!HRͶܭ1rwfx*<.758C\쥿vcM5$Չ8Kz2K܌tz<.MGW/qk/#2HGg}=tY>X^w9<y,-"3›1֨\@ˁ>2kh;{O3!,n#Ϙ`ݜ# xwIF4/uTSSc,ǛZJKETxh1Y^bG3GTwŕN43Rtv'(\;VVaMBc ŭl)]\x/sLM_g_S|McGJW\̛(u(v_"qc9Qۋ]d'\.VCЄǍݪ"Nr&v LO,liBK^3)8ڌ&"* NӁ`?@kDZpq9P0H'SY^v{M%SHՆHRDC8.<.;B$Q,b&³W<7mXln\ I&#bu8TucQBH҉Bപ$X8^ DX2Tlx}s`bq!`bbÁ횳x "8 Nsf/uT)p YBjF(ύEfFbd >k. +W*{3/^yuګOTuҊR-T6y|v\3ט(W @%;ؐWv|ӗWߵe2dҧrn\}_u|Ͻv5r _Ln%n2F7ֵֿ7rmV7M>HP=CLw6sxLkNەn`brzKo j*y>,Lebbbbbbbbbbrb*L>JX_ Ƽ &&&&&&&&&&&&75Ջo57) t.ɯ{BܒkxRdȤ]ZO,t:q#D5S@ׅV&ҐnA[Li;[>Oﯯłj*Lj0111P}E0AJdb$0ɭOaA.M mJ:A}ux<*ǃ@QH&8Č9ajMn5D.y47Hi/Ҍ7cbbbbkÒ(J}F.R| qrcCWD |.KLl!5Ԇf2:9εm04FRrdTo?=G (C'sHy:z?}r5K FPt4gdS t3糺.HE+`bfIy:(kJqMӺgQ#q2‚vM EA M&`YڄPK>4MeH22EEQVχaEƵf ?{~(gN& pzz7aj“S$(*._yn'"Ԓuh!>X(0yݏtuxovgú1\W"?@ pS, /Z$c2퟈MF04[9p{--PTAna`ΓBH27 F8$c(x|NV媛! LeQv^;ʼyY ID3ۉiΆG(Ic4UQPv^/N_~L/Au+ :]'o{eId:ֳ}|v(ԙk|{/[% \ %B@lXOmZfO>*n,3tnp_͇/4yutLgg6M7 2$ӤS4@ R|e؄-F[Z_}F*,Լn8wpi>J`*[t5S\<3ZHNP &5o]Ɔz'WLnHuzE&{wlhzvn(Ʈz֓m4Yt'$^ƚjCMd&ʹ9> .-$Xql+dJ08JU".d* ;MSUG5 Ab ?zm /YM&B Μ8LS8>폰6]ɾ~V+KA欧MLL>/Eh'GO4?4}AeJeA/×[ٯ:q NjbF$L@#fh?jQ,`}dy*0I'[`a*ܯ &,-Ǫ^7Pc8'OP %"pbޤR 5C ,) ly|_9ņzSBJ ԯisYQGC$-`$oBJ  \;ǭ1i[xp-k)-cscRrt9N^m1|'x-. /^hgW:-~㓄|uMpp+](?fKOSɬo_LמC|'b{N{m;jo'i *\@&y;;W֑!$#'4׏ˢtӍ$|.|؀z\Z%:]7(0jwc57>@2nG_`睧+:<8Vw`bj/AT`!Rx5y˖-(0>mbb}%UڭW|<@ĸW(0}|wŸC76/+ _O}vw(x騪zzzt?g_xD΄ OOly=.JhF38]$4.4R ݷO_x{UA®DJT^'. R_ɮ3Ok!+g@QY;f3}c䛼pWٵ3}B˕ {MQԹxk3er !.ݙ2\v1%)sr-<Fn<\-Bj}:_~?wիs>Dtٗ+ބcq~,nAoB/T չrz sQw>Ey0xzjrIL.)L4 *NeJP^~[Ҫ4'. 츏`j>>4t- eguEħ"X*/`-4(2ÙCt*AVVzV+7h0zjwV[A_Ŗ_k s %H(0NX:Uԯ=,g\`dIbLup9J﹗r,$#glل#%HAt7^yd g%{͟2m^y:oh.X+U5jG8Xk[LΟ3bʡ\ϙr? vPPDCک_L±9ܗǿ]ۀSYJ'+ﺛ[pz $m--t լ-_Dz~m~rt),_cMU1s'Q\WS!&IiQs"jsQY]/v2xiܰ(Oj^-;+B;(uf1fg(iYu׃{yzlmҭH ZNEgvZbGqGbز"J]bʨ\{n^M.F6`W qIsi3l̲`N#&3qxkT {wNZC;7d^y^G or3]8a<˹{S#X''Nc(r]-DA"Dzi$;C\Hc!69H[k+%(m4BUq] 8IOu?OJL=|'KWPt"W,rc{((Ƶ+ugbt;n\ٱm^ ~ K LOlì.\* Id-=YMԕQd3':"Y.VH xC0Ωr])ٮx" tGwuHC ô.`0ݩ?x'y2Lg[;ÓQ(_A,2qZΝg8 AS:9L|3'3عui6=9U< }LDV`bN3!ʖ5m;vРDb+ PLf:hR jEyN Јًd9δ `-Z=w=#Jay-=ĶTw/at*Fl,g9Ln.y J@|_k#zlj |iH1 -8 ,'Ho>K@%xŷIVXqe4tW Ēdb8Kq :T=mm NF%t"31zZ[hc,.)_+^Օ +oV;BW&cٲE8I3>A4Ee5qgܵi9~[~Z| L%1|6p`+d۲8yD'֠Ɂn_d`l7Pgn@[W? lY["r\;!T-^NCE :-@{)V (t Jq%8}-wncQwx)Κ~+(|R- ^zLN,-G1KEaKitGfi&([:zNGBnoo?'lg"> dn;1(c1M^9Տ3yP`M/OOPlco̶H ]ϒ5,3͆-!{s >}.nHEfw"4Wi- 7#_)FA==ԭXek_?|۶%<֯[qi_D_BNǪؼe.5Aoxݳl"&n.!C/gdfx6~dJ!_ơf wnYgcE",Ym+Bk:9zPk珿w8K=9< n@-((V˖y+6rצ!`<ʊ pXz~+FbccRڼ>)i4FD*3M#$he.N=eAkR2,eq4X 1~y_]B!( ù#^gOPѰK D jb7z[;6 ϴe*ZgN"%# >IhF~cӣ |Zܵ1K4(jN[h:}R(q QN.Ds{a,,ﱡ*!$(_5TRװڭLQt ݸFNY9Ѻ?jʮ#^^?|p+b=2Ēu[чXOz gƅfCuEI$uj`׾4StvH P)G:F?݋sAAzb-)]eʙ_`:&1K3XtFTHf1O`s)HE#6 S 4]0w!FZ4ڍR#uضc}-+$?DAgb8@wlo:߻w92VnQ rR~_nԗ,.9IlϫdUc /GXi+*hK;?8C,=~g>OEi9;'I+n+)= ';#J0{}@R0 3o?aYM>(n%bs:t%.HlyW\j9e9%vAiϟ~e՘S|cEX:Lеz^om2wt25u B0Xǚ|^β|l(J^ /6S[@p ϟf%E<WO1<2șd5wܵ%E mh6`OEFqJX+i;pʋ:(B5xcQ>Wl>S|v3ΐ] bBa&Od k9 /|6R$`ϙCkz͂ R< _o$)a }K]'1 !QT N-U4l?8I_(9M3H`&E*S9X븾{w?~n땽,ɖ%Qbŀ 9g NU>3 P{9Uu޷}ˍ W"/^`4%1cttYUHۍ7MP V9LiI%8OO|l):B.5e9t b-Y.7}tAj1I%irQPRHq[,Y*>ScT XNp}<ȳXcà 'Pʗv^ }0<;?πnx.J #4]箒 g?>II<R*hZŭVs$(sG.'Gh \nW.GI 麁BdRhԔ!TruROvy/z_S1grzpn7=M,G+7/O6S燲pͭ74) *\F`"!ʐSۨ qcP Eb46[>ZpcemEE.P94'|Ϭ"8?z l!1B f$=G;{@hkVX,.DaV60x)ܨ0uI4x*J#)"hv4T*(ÞAb)*EǠ 73簠("4t tQc{>B]TRFu2SǸ|gV执L70B2m7Hh:n/ !Mey!c=Sr%͒JJZCJ”֖X Yil=? zS85B`2Nsg9'IE6f 1| {f +!7Dr}1K>/tuWWH<(oJv1h%̥r|'<ȕ Ku,ݵPV^$R t]CfdgE d5 Lqhu =Em,s Z -=/}qb_WIK1VFy{>u䇷PҲl^edS1z&'dL+%M#;'p5K:`%M+Yِ.rJ1nذa5#?A'JZHU d{@jUd5XTd:+"6t2'3X$2&tҖd2SP$Q+jphRi,)1-kQ'*id'M[Wik_g0ʖ5=l.iZH@)XK864"7IΎOĬ5.ss&$C#d,I)լrn.Ee8:Tnn땔D6+< ;ff&naņس-$ve닧\UMeH2Ob,vdsdXfk$=5ROǹ IJh(n;w eZ* 4a:>bir4C} N,L.oS%Yj+sd#7虪gÊf BQSu\*B 'wz%+ WP).ur#A"I"gk)@M#LjlYV+ C_R XU&9$;6uVRr8JӐS1:1|VGfh΁Bӈ0^PȆ%=4/AN 4fO3CsQӼ)}O1sƆ@hw72̐&g<MC/<__`-ʊNM0LREZg6S[ySoM82裶ďט`ɺĞcH-5ɏ~"g{'r&KѴAFy9wQ-s3J/uՄЄ ]7'ȥLbd{tP~5}Μ~/fs)9iw/LϦg',g{L l];?Y39Ԭ1ٞg$u`Ύʵx+:0˫Xoqk#$Y9B`2qppxo2G<'%nS:JJr%|(p/ t/u-+h %8z,$CC\8y+S0()/:ϛolg/L;HOI<T77_;E_%[oy+(8u2eye@"a [[Kхd@9颤(~sV&\8((EKOpYRE+yQ'9{{җ E'p45>ʖ@ 1. h\ $G׹fFX~%EFk'w}W(k\Zj+r7vbK>Pg~Ɇ0& blގ,YR7wr=S:-;\cxma&SE>z̾]{:QMm4VWv [quGXV>W'>OǕ~U0xnw]R/qע}&ꋼs+p87V.IǑVR]"XZI0=9uA&5uuՕ>ĝS +Z(Dp[;3=Q)ntr,)P};vq5RHؕ}\I"&{Y5K(,:̹Azj-}=Lp[~mX^!e+opn VmYCEk^:Dwd $\Bp+tDz pm(MJ ] }4Sر"r#5k ''M.ߺGVC_RJs#WG.:·.l[_EAaB!N&bÝ7顐V^_6r|(C$Mp(0GbCx(˗/(+`7΁+q,wYz[Kzؽc7/t20O7\MWu+'9ڥxcgMuЙaϞLLP-|^O x)N7Ҳv5ՅfgHY$pA(fDR=8rhؔ=_`ֲLq:x,}\ORVUOI0ǩj%mԔqWHC]}"PZیu ԭYÊe܏6]o0O%=r0S`IߤiI=0;|3A^F߅#=ײ~i >188/$ʲX%;{P՘:~ mV <.ykjGoV+XŠkXXIAUlZK#PTAӒ <ҚZjJ f@ #i7K[Xņ̈́<.ki _ƖR[螩{rrфF}J+ R zq;++mB'!#ް7#La7n'f /b5UR߶u ]}r ds9мf Q(Cu]%~ _ ܳ mC +ytE5ʲUzzֆFJ#Ai*/eJe $ % K(Wfi-ulXNl*EIM+WlE3Ņ^"u,m'R\ĚXJcM5^_eX@q8Ly] [6,ҴMB$fk*IDAT,/%PѴ Ec1RYIɒu<* <f6DRUQFUi #Hqx_'m[6Pt1YG]M\Dy=^+)sRz\[6kAy:ֶ֠LS}<J1˱a T`ŧhjH+XHiAҚ%[ ej7STVQLNN+aym%T6Tߥ**!l(p~j)Y/ MTQY$=5,*J !˯s?voW4,`[ g`JRWUEqieš$6_ƚZ‘B*Jj\ʺ5Ԕ.bʹWG]Aa: #a*غi@ W-HMPB6>]~V*#xVv2V4RYVDȧnʊr*dZ@uye h*RV@ui_@˪iBW囷_FJAypFK@K0#457SR1Kcd]e۸L(SmViJ\Dc rEml[Ӏ[ho]ԔR]SLEhFt"Aju5Tptpox'&&t_0`S戎eNM} #x f& .3(wW|h`Mǰ)57@h=O#5+ñ>~6ꨔ APNܥ9Pw-{6wg_#~톦3f?ownNOxž f\ߧǀ /̸Mk h76i3D0͌YczNgƚc[Mgcffofї6'tݳڤqϼV%q՜Uw'fQ߁Bhsmz ;&  ~XxL{r)%G٩˅ZϿ׮tyb2J.|5p(Ïç9B4M0r׼ l͌}Mqv],dS@jN(kFg"tg-[uЌ]Hnߍ<'4sf˔ٿ< 3gI9-_e؏PU寓}ZwX9b\ig.Eg۶g͟fD5˒,Ky-59JYcwqP3abolvfqO& fM[1~Eg "sO@BwQPRI>cXݕ'۹ N}wW_t: ~soZ8Һu29l,OK90Bz ACϴPd~U yqu{}K4l5w~bx֜fשT,Z ɜ"6MRg˟]청@2lnZ_wPJaY%K)D̑R{3F۔rn;B){/DvBf%ZӪ֟?ey!w'k^M*_|ۋ5Bp}bOT"!AܼP!˅e%TS]*΍IN%n֣,P#l) [S ( i:$ӊ9$jtҔ!@K-,5!XSN¥)ӕnCxN2fgIv@1X;k @<86jq5se&M( D>Dy?!p Wl(Ш |J^Ua5訨+}9E-xupH ҀƳU:#.!ouYY-8pk}L޹dAP09+ \5{I$}w%$4rd,[ILH2 ]gpT\2"X@R2异$*8p0 e5?j888P@EDSՂ|Y싪uHc[N]NҾ9lNrɳM.YE_2Bƞ.+Bך j&'o ;OXoJVr/8_s:C(>7WW-s+Ku>Q3>igzlh<]k!M=k EJWiEQ JxzeͻVL33S-৊`uU#{,!wU1A^=E(IJsp[M)00%ڕ?S,-iN^b(%cq9HZ0Tx|pEbbNx`r`[F9yruuA^ͱg6e+~2AǨ+87bх}7jl/xT'2g @&%߻j?/evYt#B\bޣxZY?1ycTaffzRٻ2"}&7'^`_Z'?uIɵ[AmPTtY3['i0H:Y@:8:bP%'{%,id5\MH.%J")ɕ=nAF⊨&x I)9KQW5,SO5}M j + c, ":$3IE~S\)RB4"pIڮA 2 ;Ѣ 2\*$R*R( 4j3nZ uhޥ}"%3 v JWr!15҈FO^aѴ+ZQۧX[$H$%SYnS)]<,=]ZjK!ۃa08e5h kTz U\+b45A˖٣ E6o0* -ǧRݨCR%9( zSKP,-͒њu~MB+JAI@)5k38swvcδδ* fIn]4Y# m`Tyɔ+c!$碊u{_ rӡ'$%CYO|PeQR\ʙqw?OTL,0'S7!oyN8YxUURfWsw; T5VyX\Z`h^] ,4C1b[H+JC P4+Vn <` A)HY:b4kP~qR$-LB@7r Al (k廖 ?˼Nf#i{iU:`rłuzlBZ˙KxKZJ[|ɩQ.K:R:+J4$7,NFu.Jy5VT$ |:o8+6((*|"?a<'Ph GJ ň 5"yK ~N#R J|#G Rqzo)ZJ T)8p#"p&IBT',2PĹ -(F㹅=v5bԆ5k&/ K.YAJW)ir&kKuV{/ avCN)/h "_lD-{H!4n@Pѩs)^1JBpxTTtvYI䍳j}$MUÒy#$TF,\Mgzs0X]( i,(u٤S|֠ĒCiH*=bƯܸ.X[eGɑ v?[\MA'7l-La* 0r\^`j> vclϛ4 0zDy4>Z%$#`m@}s`j{7hP*6?tHŸ\$DiM|( 9нСD|IgBc2zӊ3SZ"Mh jȔG KY2)kǭz!f'\Yߦ$Q|עC ~FgZZL'2ir|@7 8=jq*F! '($Ӓ߮Xt(D%hASx2KiDFs*U&85x6xTnC'o']<]S/M^āN)x@Bxdg2!\OHFME%$G- ^6WoGsJ MYelZk&gӳ ^T]_떟]n1˕HX`^]2( \:h̖AeoM2̬S# qɓ;{2nQ"5~3IŕbPer:?iTI.kwy"KX06lt<C oHވ+J=XJZEB>#%:=g)ýp2uz&R6hF/X0+Z X]!S,$s)EfV=G)5άYTh:x+hꒃ㊜#qDXZPYh<=.nY|_2eOM)Z ~ŠJSĦws"fՄytN [#xX+(aJšb=9):b"挹鹧ɴb, @Ra!e^]f aHϲh2JJb,x@vB$Ғbݿ'ڞ!AOgiKX|ˤϴ'G988P^?܈)K PSzLL S1^̲5W^ i߃n{ݼ^a*Hg -:-0Y0eVl3ptg.a mUO}*QdJ}䟺Mu-ǿ;cg\TSd)2˾igu~YG-'arySdb$4p,5GY*Zi-hWahI{jD"&`mFf??X%$il2R `MF|Ȉ%zBu hv٧'4J2xi5Y[wOY0.tMNߑ{ FcۍASVŮ80 [OLF:;tyDVq%!ѵ|{/ݸ*;赸㼂sˋm7*)h ^d c<uL)&2 ,@˿a{[M풧áSYEnf|| YEЕ_Tac;~YIۯ5,=g=d U!2Qy\L'e¹0?WΛY؋M:Kns9ZsĒ%Ɛ519fq$n=!OKD5hL~䫝9W4i,7Mܶf5W/)a 쁈vS t-n=jpkf`i9܆ 3(0|ɹK\JFxΞq:88ZvzSTb(;G`KֈࡐIS؊emNRgq- } E}Φ=@[o :-&RJK^$$ A &bk9} Xnnۦ=f?Gb'${'wۡ 4j!IMӥ>n{={RgYP+G,FoMP)^:-DPcG̙$Mu|S9KqrD2xBoJo<]1uӂc-0RϛU" VFl>' bN9 ^,5h@AɵI}1ə t*tycNԲRk6NHt[~gۧB9c*ӊ-f/-Squimr ʼnITRq1(jTvH@W`$gcn{sDcUPpyJ2%2m J1E'(ڲ-li;oyU:>m™*L*^Jnl! `~~ĜpTkzDWtꌹ!̪c{KHa@;L;? då2bc#ӧP[/ r|t *=0R:[~ (턎QDF1o:qizn-1*'ods, h<_QVVM栤;sUL%,B'-Erx (a,}&jD#S>H[ L \}GcK}kΓ[ 86d3.ZXxs"Ud:K4")Is `{'}Q/5r&M( K+Y5sk#K Cr †}ܝ4)쬵R|= x$9{L|{%>B -7P[ɍJbY@Tr5uAey:hʯ .WEՁr\.q@qj6L^]\!C"el+p{1i&B A θdǘU:pdRQVź"t%(OB7e^+%hƐdT1l F1n1QfʙAOth kT\40X~aIh+AY$ (ukyp5DNmьIkNvJr8ZmREGn,uQ&Qۓ%:K5ʥINQK%Jtn5ǣ, i\A}m\'Vo0ޗШR&t{2[d J4V]PNKF,M:{g%]p:*`|ũbcAIWZ7ĀŎ>M:OThL+^Ѐɥd݊bkL"XuIG0 q==:D\v2 o`S? IouЀ3:_hvQ7hq"j' z$LtCPȠ"E 4@y4 QWדA=..''ag(B@ޘ?cG[!\+"kҩ2!ƺ̠۱'$&ԇ5F4CA7`wRĦEӊQ0l;388bѓs@NdәB5*֐.l%Kq|\ћQ !h kTԐšmYLH)W*Ҷѣ@^)s,rX˓qEO9h h-C D>/8 =V4if^e*8Ҡ eq9X^l# ńxLˎARMؓ׬XRM#&"ȘvlgJ1VJA]D#)R &9ڈ:m*zQɤ% jDt+LHʎ)(3 @inA.-91jdZq=m#fA686Ha',19ceA A SIۅ'4<}? Ima2[Td56hc i[fMEGLQToѝ?O k4`**ymDK0)>bU4ZB=`q* [3( h5<9ŏ-n9~285f'sƠFO0`CcHPc_ ɻ$T>dQ*΍K.!S\75 <R\@KF]^&SvWnhzҊXΗԙTT4vXZѝʐ:+tyFgkDc24)eNB~7-' /!9;@c{_MJOaq^t# ){,\) !Zt[2j/x#iۭQR E<(Fs""nHcn}M(Ҷ1+r8Ȍ?c~1XL,vJRyVFrh)H=X2,`E$Kc]D`=CE~Q@WD>X~ ?垙&&tRWz, ^g/{<]3(,V#(S\ܡif^wK=?l "sOٜ5#4qI62nw͝н$Xytpw|~ұNnkӿ1^=…wrʪwCy"OsO;Y@k!l @XwQ;i㽔Nt;yG%eo=G>垓>ZǸ#/ uppppE!kٮ7%a;~`y;-9*{ppppppp1phQyuj 42>IWy2L}#Uv#9 9``Nw4 xtG88888888+p_a)' #w4xt1# wQ޹!@Gq B Ĵ$#@cX&Riw!@*_ !JI,Kov; =B 2{hS S-RYhtvW{g888; MS.<@bF+ɂ+% 7&J)z}, 3Ǟҭ}_yV7$RHG((Pz}^1^U-V 'y[ぶ2aR(":t{3^ʇ>R}e|*zrڊҺ zPRqAhyc5MBu?S33Gqn5}K +PLw oK.[`R&'AK[iu|'/bv:MxtM_T~*9nA{dw tVsBd.IOEMH&[I!S\H,M6EWzM+.{ KZ]o1k#PL ʵ>ROCRjKs& JУ"]ZpLz(e),r"yyoo 6x{3ir!:FҔ6Mut=|:8g(fc!O—_Wﳪ}pHF:‹hsC+d{=ф9-cy/o-Cw/:xvS4VQb|a!91QbYAeS%A4@="nY!0qu 2WTG[\L !Iy QUSG}mnc O{i$:/}z)_ T3ɾW1=OwJs5drc `]H+g}>+St9++Js M(zN]bǙ (*`1ۛuN~oMf4j,W?}A#|[6 298{=lkΰ`)KkXI~$XW 9z {XhB1{_z-kRǭCt:o|/)+|6֬[EհAMrZJ["SJCTsBξɿiwOn~^&w[J>ˋ/kZi p05k|'~Om]=kWl(kw{0$7ev@_g mk]' c5=§ؔ/0oi\k?]Cs(PjWVksy M$Jom;^zt_1ȩ=?LJYkOs ]C|;oP?mvHkkSxE|{3Lp*n{K@vk}<.]G/J o˻޲ 4dCe?$T̸ξY >w=3cgi~GT*ƞ7;0ۖpoK=Ma&L +o`+,#fkS,/r}4Z>*U~OYײR,9#4R=Z7k~YV&pW*y]XZ VW7,_U*Xi?5ÍOf{- d-܍̆u P9+e-n7]u'3J7ʑGj5amazvgίQ yT&0S -k;t!`8?}ɥ}i*^;_)dK3Up$EJt nCB 57Pg[x{xo3 .&]>֔6PBR(^KLelU+-9Cɦd,BQPT/ؾ;|>܄9s 6?Q!+k~a0-mmGf lolE~ݝydա_РI~^-gC.a/HM -? RY %B(%6'+5 ^׭%%Z=}W>gוГ8ȏwWSEX-h- %(eɘ:9zN_˪ LM@. L#>B~L.!L#X"=!!>7TdB<~t%K` pdD ~C>2M&'FRx++Vl`U^;4Ca}g(r!M!+;9ӷ'<3wM:ōRQP]Js=|b3zQjH +GPSf {+]cɒ-RއZ&c9x7k`0:ϰY"+7>.G9xX "x纩X$')yM!5+](]=vY7kboIY wm$ҙ8a}a˗:8{mNtI>˿Co|wGx?{kn +OSo)| v^}o3V_'XZD_d>K[y27fJ)4b@aY `*j+Qi6”Fqeg6D,ضg@W$;}G|fkBqī7cɏg!N\gߞJV}mǠRX7;npw*xr]5"9ơ]eɦxcr wwppyN?ɵq7Os<}rU5\^Vנ)Av LŊ'_nz[P@~~S|?o̻y; J8׏]ǒѮ cVu<ǧ7xU>LAt)o)>؆I:#35~?X-clv0~$#:V4#wFI&& 7!{QդB`rvcE2WML_4nioHJ28Z?ICo~צ+Ԭu5\?{3]QlY->n\U wOS v2"U+os7>2{7KJE<[Oy5Lf*;ɮh>,ȇxt]37?{9qe>B?^ȧ?A*rxyT?(=!\MP2: DђUc9xe4888Q(mϔvÜ"ExkB6FH'3.C_ `t*-m,T[ǘ 2F J0aI[OTBs*H&dY+:ƍIubzne,7˶>> F!^z )M#3z81D*c!|}7z^[ˇ>Y~f]S͘aw~_34f r7f wg DE >?yiE=ɧ~`ڇ?% 72g`|Wa15˛9Crq|30۞_ytң5|KZpou[ =Wi/ 0uBa9Z*I%LZN9oWTm~ %ޠ{2KueԶ7_;_05'F$| yxc!w$!5&:hy|Sbeuxƀiie[g?I?h/{?69Y 3G B1u(5~i7ee[JoA'Wѯ>F.2Nv='l~)[/=҂W…e,m5>ȧ^Ιc'>Eiӳ<\rN3>H]tD>׭~M@7z<$RPشgBMq1uqR牱=R'-,@zOph:kT/oC.Rq]躁qO]eT7aY+LD)8=H Һ ]7\75S_PDeS;oQ_Rʇa۪:*(++$NnyrS'O214aicÝǸ2bjhOy%m E# k3o~u^Teh(B-<Jv<2@)ALB#XF: JJhko%k6"H|p 72JaQ!.MH2Tb<s|_=oDI_gϡ+dB?[nмla7wU<ŠWLZJѕ"PGVaM]"\'sKr{pΝ4ٺRMURKC4Z_Ee]37Mg @]x^n}>" ONcZb/+?+k(.K&Ĵp{1g׿ϹAҖL[iM[EIg- ;04cd6Ԧ||$Hbe hi[Ɔy#M-sŠY)6~ vu/>QYUIeEUEs|3EMS ElnaEcxuPhD)♙jLSPvs7ґ ײ>s9@rYրߊqR[T=)t+9r(n]j:VEC 3ovtTf`hP@<8{@+@K i/u>Lu_fИ>Zk(>2&9[Fsն t`Y'8ra 'SvAn]PYf%K5(x1 b$!>JTO&sR>.c"^j8Jhmn^[KB!7b*+sRu3X3]x㭷8qmܬR93Һz֭a%Fim,k,E[H)HJe_5NOה&M%1NJ"I!⓹#(DLgSPTVO%;|Dmf>hKҹvϨֵ1x WI ]$FrC209zi ="tkSgTh';888,=K'LSR5"gA o]t >;[ ;5ʕWH(_i^Vo.DOM)b}>1HVkL*=$LxxB/IΔDoN5%BLjm?K TF,/[lyh~ & ܴn{Ws쭗9tu M^3`P]RYo UNvOJpNW Wou|( //wG0eKXDM ض`4 J1sd-H o|}HK@ٲֲrX?. Ȍ^E'b BT=3JhTg:8h"T*`?}o ;8y i{j>x(g|`!.fOʏ  y9}(]t_Cd3,{W\&߁?bjjAFƈe iaෟG*_kt L͌\b/QRCx(c9J01brbѱQ.< *7CK)fδuXe6-Ru888ܟ81#?m?1.i-tSӈ_&Gvq,GC&*h)'u+7zчn >B>.7VtOq n\`GaSK5'\Ok0svF El|6C buݯ|7_F%=ƑÇy07ܱnwFWUΈh\ W_=9q;wdǞCtMXTrk|ˉ*)-@,7+ah^²eK8~({'UѶZjcgJ(Zi+"]W.r7poOoԧD|WNb8/OW }USZqx\&/}i+ {v̵1hm$w<;+synngekn.?ϩsfl^~Ξj %PH6CGy Q#On.dqvnv ,mi uv4uM,-B[%'P *?[lbr O?L6i4Xʶ]R pibld& |~?.],,R$Siۇ9nP4$)Lt|~?Îׯﳥ֏~CS,ĕ1z@3Cx]T/ߌ fd*Mδ7l:I2mbx|*G,g>!0)4^f60 \N.$΁gy]$I3}.H&nJdL𸍼'$0L"C$J1@]If>KOg?0S3%1ؑ Wm}:1, Y#X&D y]ȦsHMńl*C*+A BgV}D0r$ Bwyl9Hf>+&""t~/?!ɤRY4߇$NLeQsd1 n.I2(͖nM'Jpy|}nlx*c0 NxO R\D9FrƿjK$=sB6 1H4K(V.33x -2D^ץ>{hHRSܺ@'L^$eUD~ qppi0q:oDn ӱ 1/w3Ohi?⡆umX]fŨn5ֈ|NnnYNn[uy{kϼ,?gdž:S?XW)dtxb\vWλwצ;tz};5Op= _On6uBw-~p4>jB?y#tcoƻy/w+v gYt1mtywbSnsuw]]9냼MAw_n"(ɭa߭z_|jgUXR;?}fPZUvR݃n|Gi_9̞݅{O},.s%&H!Д$6>l OmD̫b=Iܢ{]7n r~y-1B+$8z0MQ|5~}{ }Ġqv}^qzI%m=ڰtppppxGVJyzV o(L}ώ 5JBf_I{8K@TU͌Ì,Y%yl^xϻke[ 5 ==]x3qoUWuWӀG-Oݛ7322rrHs #; bqQZ@Y*nMu#ER lL*Ӳƥ #⚆ D"QfŨ1n`````````````pNxHh4 77a&2 _o,W? .)\D\200č'zqG (( EI\.CM_UUEUSY\X =fG6M\yH][EU7EIw uxKHDt;ű]Ds100 04Hx,_$_y>rΜ^-ctn"q^QgZDW"{| T7$!N % ] )t$S~jR28p M1BN ]/&iQw/) EE]d!'uMhQEAgUEUM<dfxn9 C<0?_ O7L0!{ϲ398/cO˦wxq_b0CcD;yn OS1]r-У4<-_cM >83S[B 7ö7Y=h`QA ސNFuހH!rQׇcQ5l7'$?Nn2O c~g45"$!$cSc:&jEˎpw^HP:}yw!/+ ߧ|[_/ xhf7iv!$`lbPLb2),2238m7lh"_qn?cIy}rn @0q终ZXv59n!`,Yw ZGU\>C4Eˌ7-!6?v? yMYH6NTNU4"A]ssv6L6HI=#A+58-cHR^6ǩ~߿zB8=1y2pMXVHDE]CwBUn77 JY^.DOWN/?/gOx淟n'b;/఺ɒ͑)䠶a9i{hw tnĹk/܅R`IU7oÈ-nڻ̸f8sVdrK#c TfbUegN1%%,`ֆ}ӎc޷\e:] iY9vƺ yb&LD8{.BK3@F, B&9~pMC23ܘLflVqjo5jeSI{.L4Pq]..O8"o<ay-<Ď_B1e gؑW'ז,B(tq-eiG(v$/5FOsD33ͧO[V8K\`53-|~XΌy xi5$w%4wūFQMTaPrkآ~4#0M4(wm^Jˆ1v7O2LiUn$B9L(/W8Z'pfs'>Iөz!L‚5Wld]]!/BaQ}\Z>&5N!$`bbJ*dŊllsP븉Y-8L2:W@w}- e:^Ό%s! t/bZ?*&$H{3yn_'6>)ϱʿZ /TSYؒ_hy&nٚŠ=ʿ8[bsL#y3V=b.x`~OdO=̊|VI,8?:NbI!f W5[̨$5eWl3,G*7@ZOo㮍UZyO~5DB!ŅErm|O8byEKr4B3,F'j0ylj3{ 0]ʃ,̟mLdߩ>tdNt&k(F% ;x8f!Хq/F8oTbłYյQ文?ݗ?`;oi&B:1DI}N33X,3  .*wm<_GP'? Kݭ?e{ NmJclOqa<@ E2|K( b?؃ߙIy h R˥qn3j=ʙ#Sì+ĦiW[:8[ e ׸8] n0;2Hi %:O'43׏7!ӕ(aNczq!iy%X~gC]67Ed/tvRl:83EiI1&vO[7-#ö0_Q% Z*r2k t| YnOf J0?ʐ7LyLp۬ęad,HBstY(M3_[k@!Ltx7֯ , _3ŪqNS^_UDOg$*mkq&_KD:St ^;vyK"MnV[G{M]^C~"Lp(+ch4wYs:c<h ]d#QOph'O7qݷS_ 2Ib h3 -5Df9sqg!i n qCИ#'gswSngOƭȆ z΋.ƧHZbמyag؝kӴ5veudYa00(! ++x6G RSqRQ)*&?4qBx R5S\?iߝDzj+;D;!ˉ@"JnDCaR"`  ݡ up٩8h>7T4 alN&NiTc,lȹ%}"8GP*nayeB.dRV0O!^L { f?Jvy+bW!F}Qr+m 2w 53UoF=D˙̘Yf)=@yZ)b :qדHΛ"nj#},}AbVmMU}Egd`'Kof6T<5E렭 4{.nl;]mt16$l9wl]Ǥ3 =: MeToܿ4RJt-AoWak.;"} 8̮yk6sMTd #miX=WitI9'~ӻ,ʤ‚颼4v'4N+!mWb3+XRo&Pއ7352F۱>?I՚{f)Fgh1xoV'O0޲E9Kv-,7揿Sb,mA@!\[-DhO8=ߔeuDv򍟿Ɛ?-\ xMdoV#@\b 0i W8;eaiG^;NLO=w[cs#J$&SAYrXX/0 000aY! /gNvdݬ)qɁiKUE .O/AuO~\yسBfKZ!w>(+319sY++Y|~ <&};E,G&Pd3Tn接EеT˥@5054z@ Orl+5sn^41F\8k갊f%o [ kr*r֮_˲kx[)6ݾmM=MV3!0ɹ.bz2+u[ug&AbjwSPTJYaK*wjq V.e۸}M: q+SImc#fs,.]JEfa>IOӐk.f:2):*%+n2NB"a4t #IlfSi+B\~ 55ްB]cDGF >H L>;{0pOyiuBic<{`2$IӛIM./$S czK @2[]>b%ý.WבM]J=%+ײjR6y?JLcl&l%ݔ+t)˗TIb6=fzKӑÌ*e|wPƤd7ؖ DǒVR٬XKr.h0QE!6=ٶN2 St ްf[ıS@48/OLg9|~8V!Nv& VS!>6Ugv7G-ZYM'[OEe;ղqYnҥVhaw8Y\dlp`5I}X)kXNyU[Uq2bIOawz(.-8? OH|0vuݚUXUoa7I\S:s2ض6*VvrnV10:B0yGt+%*D&\N'6`,N"(ٸ_JU?>St΄)kXÆukYn=۶neuu. ;IŤ( %CeXƧ Dm03p#;\˃'"%q4=4: ?JoUj@)-n*0t 0B U,-s0I1 @r}U^8NDON,$U(KVDBP"(l0QK[gs~.t00rI61/% S&8IMNՎ5t wLs4> Մy(&3vsMlVmY+:Ngw\Xٙdžmh:C]S 6q7N^e`lOFnwQ#[J7D0a >HX2O~~5u />XR !Nqt5PaBÊj11%4̪ c[lRIsX0„p@!tba%S/BlgR#1tڰޏ)%yN \a{T\QUL&T8]*gl1ͪ5kٰn-6l[RQheJ`5)sou@g1iNc1pyL0T4t]bveRVXwl.fg琗B,OHH'x趍l\ n)4saFà(p;-avkjS$=:jlf1a"Toqǣ&g[I. *l2c26 )Ia)Q<;}yCW `fոbtw06KFɬ\=K9y7%L&=9墩) FZ9[ロ Kΰa#$ǘWm(/P1$Y 宻i,1 Dc=KT躞Lrқ'ń3͍nY 1_?ύX^,?$;iF@Hׇ,(&?;?rQU$^`Ud?q;K6ofi6۵(rɂW$db:x1^x}'>T i6j^| <_pz7oX½6 kZ%xzus*}W\º؋"*UP ȤR3bIy9u<܌/"msחLTŎG,x+X;x89B\bWm0\ >BЂ!B4Tr|LPjA~sH')\[4\2=8 K-x0flK nLI-)q Ҫȴ(0 %z$ f H,dqC̈́Kh&]ScXk@m$naA(~ΐ(7g[ן|-c@$UO = sqY[H !OPruְa VC_){'AIwza4EK'Dh [蛎( %dn2yĸ4Mb6 ˘WN¸ R.}JJbv 8N D /m#3 ojf& vb)G>~߾XΖ;C F[ؾiEUd"{=rjS_bVBEM9`/Ž@D'9z ca U@4,b\5/w0}#ޔnă!|(BMwQv5ev<(B?8K)Mq:;Ś[%:L\ăSa5iIK erEB# d,aeY懫 _$SxtOBdRQUc~gsv#˩G "\h'g~s.#A$'GI2a@rȪ/Uts0%K)Y8vS"DudF Ģ1⚞2\$f {H)m`=]{ >?DD"ɝBQ@CgsouR_Y&Dc1:x YS͉]WŪu+;zf1;ȫ$Ӊ )RS0e600JTU  ºlU!B" GrM9<}|I#kBwfmu&z}:f%NO 4[HD{(/"W(^VByƩ$TĔ`ݖB\&+[`| I03N ;K3Q.xcKx9^ߌ/vsh$y A*Vk)Qx7i&2djW8/^M ݝ݌#I]$%jZ Kܒ3?|=Ӡ(|ρ "`xEQ9~%ʺjVoG\IuOKE!6IFP)[P6Jw.lW]8}b';. h_ȌRbfaPwdy#H//<<:1ݝ0SLì\MLsOyZ = {9qb?';S^VIU=t}K+$K pjax|榲R1"a?m epCQedLqx^FF-Taf1zѬRk+ǧ8'ΎR\[GUqf-g#,wWf2 AΞhFFA VQcyw񠟮/X9v uҐgauxvCܽC!)s_}]zi SwwoOf?S|=*nA7FKKA]m!J),+ɰ2 0 4X &d`2/ Ό108FDSPTDǁ*$}~ħ?i8@wkQ/mLE --.*kj(J:QǼ芅"<9oX`0,(4/*vEN妏d"@ab&T-XL& rs2[qz[)-&82O))H?:ȸ?jqRP\DC%4=JgLUSaebw.UU%m=0ot)d-(Q ONtXWRAi~&&=`Q(q33EߨœCme)f"_RIIAfgjlLl x|Jskp ,r(v^ƃ痒308;L' -啐WL5Cqafb;2ɓMuUvKWgS!ܒr 3PS400x_%qΌiU'2. tTU/u4][ Ess֥~2%,6[eΕN:(^/ͥծ%PUxh^+َ.B]3H$ប)0B(Vfs9dHMƄtRXjMR ٶ !u-X]&yq,|7L&;ReNo΍yUMމ!tN"uĵK}5i8FgChs r$ ς%WVKtM#Z !Rx)"U.2h%䕌H-azWcwCΏyu܄ԵyQ)/d99~ )%&񔔑55z02N]|{-q6+N/.r I=p\.ǓƆ_UIs{-ǍeF꒸AIq-յ$M+JyEs9xa)YQH\3/c]>d\} ^ A3 a8Q|hpqzzzFEb!HLגk^&Z9s.HPl````1Z,Ȭ D5߭\ ]%[PNFQVl7& c;:W)o -RbrΏ17}=1:ܲXjte0X- 7e*FT_wyB"čU!@VU9 FӤQ'Ɋ'40"(WX=ꄧ?f| $zzE[Ǚ}pA!.300000xUR5duH-N$&7˂@QTT5UD,J8Eӯ4V(?QEO A~?>@ @({Er?wIr X`0H0" kYJh84wh\yv8x]BS|7~i^dOse)ދB/E=5Dx[$cmniy)*y!@'5y.$hp$..ZsH8F4_׊I:Tr'CA< #z{տE owh_;J=/_Bd ZүzH1(+U+QByVrnuhZ (վcilf ApZFD8oe")~F!! hP*QzZ=B4#na [<P0ca[q˒btR!a>\O';gl:ZT 3>ɾ B j{}uRhgpeh}%]+x􎥘Y5Æbtrm2NMhrz S=4#1J s@gk&Fİ|S-u`"B.. ID(lTAS̻PLqF( e˪YWP[gۦ$DpnK U9+x* e-=Ly}Lv77neI~e%VQD^~.  i2QT6_O^r7.@zfZ{J(1VlF]] `8x3q>'ﻕtk``pܸ!@&8Ut4َ gOџ_zx=.5ACt{bwO Mrlk|+w5wýJ1 D!z >x_&]R;ή7_daF(c/7x9;"@t=/n*9卬u!>/ %Dn|s|Wч̜\VU]IOǀH]qmxN^`YˣI}qV ~|;/N~e=+sw8uW)Yͦ%X;7.Gм9EΊɲw_{[əAa^)S;RǒQg@\ɢ\ u++8J3CKJ)X!+XENŒ'/BhK/ai}!k<tiie\sbUBVyȈOax@!oُf] O?L#[xFwv0Gȵ^2Nxx}d(B'0ǎ3!;/=#-t+Xupg ҂ǢsœO>K}lZ^Dryh]RGsls<{]Cۆ"tc=li*:xR)_ECٓD+IUO927ԋ~ )YK%HAY#B]ǘ-~ o7O~7?)V`P-؃w$&)ɰ EY-VLV+ O6B\b}ty([U3+b·gg'R(WzvTP0Q掽Xw~u Zcs+緳??FD!΅#4EX[b*gZ9CE\+|nY&#d{{cXWbam58!klWOgY}:VGZv+hp%>gHA(& jxͺlP8Ǹ.YoN?͓OJJ8d90:dȺ˯{ BSߒן/rt{ofg )Q7~hT P8"^*o$qz3sc0G?۬.ɀGbsg2;&feXj:m,cgP@=]d|ܐG-gCvCX>AT6V_%ˊ?ڪ\+@d_,0IwP͜Amm%N񈏁A4{-]Ø2Y4BC)UkQ+mwq8N1vkDٕdmױ);=+p%d-,51% n;ܲ;A /[&[;ϽWoW`&FSTWΞ |qh"*m;wt82VAܺrH=H?a+E.vt7K)q!D33Css;>S6V-#ϑaNuLȫbFҘ)9l޼Obi2t60ՍehS4_`2bvJ)#t\j)0e!{iBzXlo~m~z<@{_'Uܾe5.sr4^~log,hrDWT.GJХ-L_[+-#8 Y t)fZdsζ_;7*#@$( #b~֖f u+VQFH1ȩ^.􌠦z2mgk O>iN3Rj$ao[N3fvrTIxxNd&kcIx9w4m!m.ߝ\$c=t kPN_t6VbrZ{3)MK(#ϐ**H"qFpfikN%౤b3z)#L[!~=K3qB` ϴ˙F:bLzx R`RBx |aɀ/ a^ˢKAzN6Y~Np_?՛Q%Biu&&iX31*R3fteE؄b ?9L=# S@zOwW7ScCMu,+,"`o2sa=g{XQ؈2h!$!:cM/,(=t3P]MDtw&@SR]Mq h]C˖RS7pTpƥx dF6m}D,[t;^|;<Ǧq* ٸu 1]W;-ܽ"cВY͚ kҙ馹#5XJیu# OEHϰԌU ŗx0g%z,HOG;#T*(HmQin@ͬdj&L2qPlog'l\N}I69sqBQ1kI]ǚY=އ6?^F|9Od'oya =ܮgEœ+_/줵oןL\"RM#/-'fFy H,.\|ɕN9̔LZMK ɆWGtGN[Hdwv)Km:G7FϮ7v7Eף\nd"*=3tO2zWS{ T-TЏnqa5?I&u?'9xv>'vs(a/|_̾x7i pg?E4dff:w}tL]'q`ϑ7|@Ľ~q? ?{e/L 4^:I)@$ iؔd&qWys/f̄|&hx'阉Gs !L P0Ƿ?7_&jsa/:{/ 0?@:p N8|rcÓ~{ l?L c]Jb8#pzHOt3(&+kmCZ$%kTkd˳/tpX_r@jVI&u:dSm"MtX*RbYp 󆈄cH-itE085Gq"Vl)#;f 9׏b̧arS;$߮ ](qKanCE*d`'O=\dׇDVb~xϱS3)pbvr . PK+q׳Fm^K_ϲ|JmX4Cc}tOy-[bSQX±VXkR$rBT0K&ŵٲ͛Q/=ҕxtly R_PZ"+ Pk6n&߹չ^ϒGKhm薍]ع]"r]|rA^!$j ,+w:3U3cܶ}c7?0vACZ?I>ICoۜvܤ`:iyHNB8,Fc5+ms &?ӌj+q8)уh>2xh9e֎F0!,5H-;Ǹm†ߧy`;k((it8& bB S|'m7#ߩPWm} X7yU֩s}]LcdQW] ׭Me[ar8o!)OK#Y[JkՕDsM,]aBTLJrxΓoj,ҽcO$/fpLĽ:BbqQZ^Jv%N!`0ۏ|+zCEpzTW>wpc6RL+qꯦLA~|ظ tmjq)}[5لtPt/Dlm$>=Sf&Q2X*dG~bGjF_7 'v19~y+m A7ə[XC[A։GyGb6cDH̋A`B}D r6GD`sH%J$ t G'ihhuIEUjn][@_sh;}'oX$T7ḚX_`KP*.@&8O?/#T:AJj(p&e%'϶ԯr'ldO< DoكF=lSt6e:[D=h}O>xm<V m@܌'yPaEeM b Oq`w7R4Wd3p=G 0FjGf%GBRT][{wI#nYCl&_v41-(,l!w.s.=ƫk84 jPL6MYShnuw%3b/tƨ\uq=Œ }>~Ī Cg'⿳5h5-.6#g{&xtE>y[8c֭ͬ(wh4=ܬǻ0\W7ɒ-5 |9WqB~OUtӍvc3hjn7~FGL.@½nkGH$=!"hJY"aiw*\[ þI-A,D"J;9mYvSwdf3 IAWY}T?-GUzRG%pP6<.ŅfAQJf}C o4ulw=( :A8H{xd`xG951͕CI)%NݎlRtS;g|D$Oru%g>8/UӅnqc5)z6fl 2fe^0d%?3k E3_zj.d?DBՆa# ,> 8sG>Ǯk:;UxO I4'N ejEQq8>tC~C[J HL2obw8q:r8Aqy¹'Ğ,BAh<}H:MhP8\fH$q~DQ:=g3%'Â40IK%L635&t$́͢u@§JQt,_FcƷ8qOmvcHs #lP`"VIʀp5A +*x|^hOd7+v,(MyHI猭RJdm8լǘdc6 2\օY5Z0yDSNZLgt0ꋑRG۬L0'~DdQ2spt`be97ݔX=I3)ȳѥGzf|Gɶs <bLL%W-=- ):=obo{)#j㰛/+fn7{+@(ʰ2̊ قub” ⲻd/l ip7P~#OpϲIW;pc>,IQ(`ļ<]Ӑt;y_ENMA4%k0(MA(Z$jwr:p,&T yfK䶮K`ɦi8p|\|QTt)qՂa#=M˭ 6CөVJs'8{m[ƒCqR-6N ݊(xҳ̈&wQ7"YJB~1ܙso~OlL`X| ]Drn21+xtrV,"G {=zo-nSJ2).Ҙ!H a- gb;g&5Y] {id:]&m=5`n,,BC# +&)5nDXmd:8fLLc];כtOOJ_uY>9I(Β:ͩ6.LX1w!FKg(1}v"p/3pK{F"Jfq%Xu9{/]^K=~8:ĎiAda;\khb.Ō*;z>c is;6;;[|KxQU$,"KɥL#m`8@Ƣ.%$QS~"\V}LL3$G\\MK2\Z)dy_RIl6D"`(7$ADzUͬoa"}C6gOZLV399iœnxHX'ET.Pb4ב\8(EfrS4q 2\N|3>"\GMd-(=+%NL7^"er?M8+Of倘+(Ihq 2gVqļH8mWv.D>2FCTYKel[CĚp1jﻗMuys( Oc%w=co؝%4N$`h``pݼC@RRI)6h1:OH(ZefSSZHFv5%|#hezO3?.ll޺| MOɜd]#, 'f+yŒ@ЬFْ2"#yi9H;59Dqϗ:So!0)*@\OG#DS^%Kݧ'$HoI_4%:Hm*[Mz4L[ *34ϲ ۹XmC 2M Hs 15Ib29LZ,2p KnYBE ]31'(-X^gp 3 K2䰥D c^QPz"FvNOLT,"\(5`2No+ 0:NxRoG'wze.KM}ZDLt?KTsrQtLaY%ѣSxcw9CIE yB 5Sxd)_o7EzT6bN]L[ .%yK="qfu5|knE ^eΔVo!m}ډKUSWߢg: Hb?cqJ8+;L^S6+ w4R=CWPSA(qAt RKͭEJN9WYŒZ6W}BUM(44T`MbɒB&~:jj6iQφ_2[0|ؙ͝_-E) 䎑F9q-X~)y'KJ)B2zWIE Op#RAnu 3{).Ww3QQM|fC]{7w,p@M~Ĺa/No~6gX_Gaf:g1ɱG8y8wqBLLD8=`fvLZo@\fF8h`_eǡ^2Ks+LO}‰ ~ld1|N36gr\L/o>I\)m;V`!N3i##N$ i@#?}LJ(.ISGK[px mdX"?G븤<bcMp!6~[j2֢6C,Y4a:=2u뗒fpgRZՅ<]G aFwSb=EFVVe@˙]os=SDX9O~9ʪ[גcS>af U:},YD"a ɾsذOX3#?݂t*0رmzBnYVj̻@j1[%Ҩ%bldqm,/0v'ӏ&Orhnʰ0™qr )`(O@钵,Dx9E ),,jA6*ѵƁ&27R_d碍\=2wj ye1pOŎC Ɲ,]\ zhsMi%v5u%9d#Gα}~ZƘwr0X?~ji(d$}!9if&Q6=k0+@03M[YONf*V‰=qtR&6ś[&dOi}l|.A:cm1l-"X捝ɰ8qIYiYIWaj2틔2OSXSE%8ySxjX+gda䮾Go7N"\$-1uR_]SovN2gC#`7 Y[[E}Gd``>hYʥs Swwon Dtwv0dp8&q[!&DYl.@Jl酬XHC!)T5zi.⍽'0畓o2P|3¶@&62ӝTdLf:f`sX_FlrkC-IG _By~&V,6zx6?+oBd^!t#}D).îct>=ϕ1xYbnhBSeո*NeMJi8E6me9V!&; 2rl v4,-t❞FWp(t0(ˆX:nZCJfQ)YN6ƨ?MW2'wBtqeKiq e;͑Inf6%yVjEiVK3YPU 3璑EYqJp tr )$#',3(b sp;V׳buM6auNG_OcSLxQ3ʹ[qSHIBDR|=pX]Pq"'3 Q@"2Mg ֬B m~nF ܸJYcN6usP,NʋEx YeuYVEdY /3\o|s (\"\%d,$"3twq۬dZ-[Amx,35`qlyBLx˩*,EEYd喒oK)toB ,_%Ent055/ Un֕3r(͆X,9ظ,7ŝf# yDɁn5Ũ 3S v9VPUx/_A%H0E+n-8M *D5%kغAai jhFQF&ExygeRR\fX nމ!`/j3UTL _RnSP8= _'wTōW؍WuѰ% /P"uK\N! khOJ?ф,6ɘ(bQ ^`$dķB!>O~6;I!wa,P>;]urzF0j2nr$#{T2i u4!6sߪc~b````B :)CL"db qmDa隵ƺ͕\?ZsG600iѥJ_ _|Y{D/b````r<\ʣJ@ -vo %PR,wA7f}:Ap40000Pr|GE9mnl}sMC"(AmfAՁwq+|sG7􈁁Pr]9 ]faGWBhO(1Z,F$~mi'5EN$&Yx`$vcHTbpŘTrT_IЯd2ޯtxx|#u~WC@ydzQ#M{6Q8) D/$ﯯ-Wӵ7rI頤J5Ui|GOrχ=Z tƻOO.E)5z[h#!5f[#wB\Knׇ.(@OĈD㠘ڬ\RNM$ f b1W=\E8oص]݇jj*0mtMT.i,ǵ=B( R&u֦"Ibĵ˥XL ;!$ޡ6vIm=|'!C|hSVP~ئJ"̅+D.Ȅ-:͙G(Dc?kͷ^⋿e֗8ь76)o,:׺8! ڛ**\) seљ8LH L;2NsP_Y,=u0]7Rn&KۅQ 9,[,(hpzجV'yETWUnF}rw ;~չa.bzf!fȸ[KXZyVuB'8psf1V.'.("Fǁ7xo_ҩ'B4OPv5ld``rC! 4DZC9tQ'y,eJ (xi!((_g%92}lS h G& n[Ǣrvٸ Ͻɏ~xO~XgGJ @'GV+JQ(1^xX7U0̝u~c-(tlgRIJmB!:ʋ/)FTTON 4fTr.-RBNmaV1q300x|cAMuyAvyɽXZS6'+KOx3Ījhf/s͂n}}%/^'qF>6 qzoL(n/ciwd/Mf&xsXԲa qNw.h i`U,1)bכ?egmK]RK)KgkB^IY ^ ƺDLm~Bμſ|2U%]qs#ZBhgvv6%f&j)uHtiz|qJ0 )<~~"r6õA1oNh``pXy ηgTp׽wQmmAQ&&0eձbY#˖6Xw;izFJ .#!&Ef)D$O:*9uԖbsnWiE;мt AMgN38B(K.k.雔br6?{'u}N媮97s& I,ٖƞ;ϛo7{`IHQAsjt9Wuu:GU7@$dJ}>Quj^kW B0.P`YN _DAʥp`P,DuZNOGu31/\MG'w%/7rZh !aFƦfrsɱYn゙dbt@$0߇D3(.zh@c7ߗ099Ḛä392B avz(jFG'Icq8VIpMX0grrMWӜ̻a8%’1T_n@Q]!^\`se)~CTosfrTǖ#ߟ3wC"$"O .N hhtTxs8)BV'XqMrb=#KbوNOj8< >ÒL Eb`vpZMs1 `ACτ^7V`zr` W^y' TʷCc|QcAsAEnR CwO+¾W^Z{vcr&;@lwSAGSN)%3EL4VԛWc)u4 :ʥŮKM򋅦ocw=BkXjǐcý-5ԗ_Jn Lh9 a s ,0[ IMrW9ޣzA/_%`Z~)woK)FᦪL[/#0+ؗ>of9y='8*9jKኍDv_CdATGΑ0 "Pg6V6xuj/K: v]# T=ȗZNӡW9;j + aY~1ܥC,4_xv> 9ϻTKuTm;y(">"(Yd!+qd_$^Ħ~-Mq#Ʋmd.uN2Dg-'%6 Bht$bGB1Dmi"d(IsNHnQqe`$ЈԆ%m EuPL Ks] qRs\@ ۍy: \@Wϳ_#dz&t&{M3)ϑ \e8H"dS}/C~x*Kvfvhm|]8"}NuͰbXB}\r_REI.pk*?M_`·bǃwYnB&!]ʲJվc< ZCt+;|5nۯ`Yq pQř 2ٹaL\{Ͽɢ RE"8;/|ѕEr$ G+pXMMBou;&XدG6̌r)wX`Y{(a+Y׮bM!~XyzT# ttW'x๯u.^Ύfd7?m8o4]~i p[=5B]B`g“*QxypQWƉ.w9yI}j]\U[0yP~aob.Sezd.e[qhA5\a<{gw.#1&^G\MQ /\SK΋|o_7>9W^ZκHwx*|ןcU-{q1߃[` Ҹf%p'$b6zQVQgzKt=E^Gckԥ6RAjQ;)Y^" M7&ZNOZͣ=":^hBrjζ 5l|˽D,+wdˣ|w3W`W `H3E+x쓟YJׁ\ݒ@P",n?[Jݨ(l6v'yjf7\U2zg۴O~W"dGePgy WjN6~-(q݆ zسBbD _d,Rrf?Nu,ɤ}of< ^[]F,"5TYS˭EtxMcx˩[ t]'I`R\jR1[fDI:-%b5cHAp&)R&%HT(ĉLg݂%B1t 4mޠ@O3бLw / C`u~c|K$Tp +]#L$1z[!ۧɯÏ?g?iٲ\r|zOowQc[ 08GPvrw [nhIU%R׏ru(:[ CR]O~a섇k׳'>͓ۗ6vU^;>ٳa߳C|wOsrGzWVNJ29`S)kȞz3{d ǙV/__z1@wJ{#[WKR*ryϲ‰D|1V`aXr.k`:nb2j3t Y~>O_&TSoiُ?NE~-\UXI]bŶG'dYiJ KL )[eE:']&220|} ԬcO~< h?kɏ= j 1BҤ{n<.p>ʼn.@ NjbQQ-.ֱO&r .RT/%;U>yQELB($';9{5k;h+6/ ~Q&@2=5@˵.O_Ow̄>Ǚ$E&IQ1H )"Iv Rxr Ѥv8 gGY[v!I*XfW?{Z{/qyŦU kBPvriP*XRjhK9gY]fm$ʙ~GEq!^w%<ʪj(/0 %sr-dpSYZgQm=(hKgwV3vC8JK(/ȹIR7<{P u۟ U8lvrnRk*v= /ȉbuSZRy.y2ʊrq{YEM1M]I(VF82C"beE,,۾\ ~|GLOrh#or7׃LMxNB:hBGa5aPTXB;UحTQl&e&EWuU5cqp5n`B}&%EEa4$Od~SZ^AC^Y-*h4CE&Mx'x#%KEYn2^7,-p̐D'L8vۋ=g&C_@"Ӄ\Sxշi H(4#OEr/ƦFE *s-?F~jJH]*`\i$^<aU}s)MNs}(lB5Oc0?„B |xs Y{4F4 WHaxV'qM^?ruiV_@2K\5lYSM3 F4G{Q+Sbv(cW) !3$ 4LO0ٜř,MGH?<&{P$ ۯ27^w/29h=ť4\8rJ]7pWKt#/)!צ܊:T1yKXf).DVm`9&\ 93|ܾ<*ˊyܔ.6G!:A%PȖ@" ]u-/Ba;hc(_xc}}=/կ|oR3.\`$%mPRWv@0;7P,lA(-Toc2#}_Oh#AB<rv;_Ort+WS &g>[wM]tMQ ńjV n $HlǢ6#j`Ia ܬrD^YazEil{2/*y~:o⋿i'?K޸Ѓ!,Z8q72,Z![UZ۔M4v˿g/lJ*CZXail$c8hb˺5}}EY!\\#'vpjA,fj*B84B1tEq2t]GKr&d"YҲS(ETM|6xP<N,b`vpmb(4RD*9^VM\u+ t? 7]QHd0 )P3: =يtt1311H$2}91GWq1$̡xgI*DJK"vmT5B b[7noxO'ڗꗿwxv;DQ(D9YbHbLI6駞2:w*QprR"nܜZeCidnF:a{? adl{ o~p'zHm]8u:ڍ1Z9Eoo"Ԍ72ΟDjyT] }M€¥=rw.PZY`$'_ʗo|?gdsg$ffj&>뿓TdhbN 6&1cU`q2nVΐcvd* =}XH(,~ѸGC@q:^b\#;V㶪%7btq嶛7EGhiWb20L؜yݶ9DAVR̺ܥ=VqBՏ_ێg#IoF,ٵUEJXMt^XRfX&똼ٱX7QBۄk$hP$&m,ߵadLCNpuVocbHi$I̜F*$HjvAO_?cS)D0JfhVÐ]K'I$icݺ)vS :]b$9UgIE14$gx4@lja")bur:}h%U2q0H&$ISJOHƓhRL?H'S[alۺ5K*wLeYd ιw;h%):&rsi:UU2a} LԮ_IJ_#H6Ulu!.*G & vk-<*ə)^W:.`kLtƻG5ٵR #ȹ1b$ؗTa6%;~ |{1B4$iĂ}u&#(BJ '$RkGk$I8ɔB l^ŏjc40UXq'C7\/vͺ6Qh7ɳDEYUyy%,˜졵^4R|te nNx4"#mxz~9v;#mME` uqXLq"=:Mgr}` KuU!9dɎz3m] cXlcQ:Q<%,/! b˯`QUXV?֭ē lDu)j\)Ocݎr)Bd6Rpk2s7ϔo\+ӄ ;j~T^t\dzfc]sPM7t-]sUyMKߒ %M7e6MKwItMÐդ"1Y3!0jzM3&5HQ]XW0qh!AUMf7*qtL&7Jiű(0[躖I fJd'eQHƦik8K[K=j6D ,  hu27B.-Ept@7$w#Ѵtr<դ*7Ԁt|yB E`2)7ߥ, RGҲABfd4 4]K#L&ɣY50_N %H~j}(G (Ξ>s_z;io d¤ܾy{'ӡJ2{CH ]Ћ ItnKzN-@~٤ޒ')y{UfEƜ.N8ˁDӴL R"{DToz-> a/M㿾&,%UG&TqZWxmiS2PqZ* Kl\M2`dѬpϻ UNe6^-Ӈz+*JE;N"@J$^Tn7 ɑ٤sj~[87n.\(nUMͲn}q;?*tr mq`"{ _aM]*T4O1 #QT qC a%ܼoK}N*PܮI'mgEgik K/H02OkϠX Wb]{A*4ȡDTy&}T&260 qzƒl U7@Ydq3n7~ԢuIDAT`fjW7J\30c}}(kydM߳h#:Mm$t ]#02ȴ4egE#g/PLu]t38rYay!({PH^WORa6.ls2 Z!0ÖW͆8-Y?,"T\^/P/]щ if*;}kg*Hc%v3<6LBPZd,=G^HDÄf"Bjr91+ϕ0,nԓ# N8AQtgՌ崣 YdERz2 ]bp\nYdA= ѤltᴛZ8,#PrSJ:rwaVFfB=Vn}?!s8C9? }",NTLzr)ܳDQxVb~,dE7lV5{",","," )h*rgYCb L闬!*IuyMvdמʻֿg",^*%PnK;[g4 B(h@j4[{9Êyt?(`k͌Lm`h 珳wY{eR'&7+ԁДWgCACt{\nEQP;Љ(jѮP*b=twݱMβH1ȫ{ߡq`u$쑽v$ aڄ! k~V",#V[jKBLi* \ I)o }}CD4ezZa!˽ȴ{%F~ڙ&1la5+\>JJ()w""q۽odKV} O jϧwŃ^kg|auSY?CE-:IcC'6R,#h /~5o+B"ט6_~x)*\+@1b64c-FR4 YT.+! zZu|\y2i9=@9^*s0m'#a5²< VXwHL N28CuPYiM!8Lu~*w%B !zXf6y$C\djk? $8c\sG[/=Ϣ|=}0b5U`w`P\b10]P϶LwE0rՒ",?W:-J#`y~xuBbͱ>'Wc H&{gRwPRU @7oj.>pSI e^{!zk\W$QNߕ|/sYN>é3g9}5-.~?x~B8_uKQU>;9r.(k[Ae}Ye+ +2BF4H~?z0ŌlB&ô]8đkCTԯkgTJ u-BlYNK 0~V\~fHf 3<r>12OTQ`TNt̰$]#L+:%ϪBW S9D )hI7K\(Iko54$؋Ǯ8G%~ƙWJ$8޼ʄ (YAk;7/BԨnR']x- }aCmkAwF!@?^ /bٱX̘U;o1a 2ۗN Y 3ׯ4.XدX {~% Vv _~1K5k Q?d/B@|w^ c;04;{ +X$'r׭eie!vr",~2h .xOBctFYr%o̷!B_PsyAEh v39:ȵ${V<˿_ TΦ \h鰠Fѱ c7R_rgl \Qjqos.vxJU,&FbJpRcb"˓լ4xy:|||K&]'T[ $1$,dd|~u+XZGՍ_ F m+š$>W UAt/!$3 wDufGJҕ)~el,u!q⺥cl7B8$]s(`]ŮR sx'Q+{ȷpc?>󿿞%&,SC.RxKM\>\ͯՐoLװ_j_;_F峏ejkcM!cj?Ě"Pϳ1V7BbT!ugm|`oN@8+/[J͆/7>قOrg^@#rĮ]wyQ=-Ӯ6N|H9mc>{ 2HG oHLzo}7)zoA-OЊ M|\fL+$ߜI)AQdhN 6Gi}A}佑^44=YYdq➏&(4!3[Σ[2+$#triO8y3f">Ϸ޸oH >me|Kc]A*k"Z8w`<K/e˰+`hQz;  HYy;˜ ^r궑3ņLxSl#>ɏ}nJ26Ԇb _c0)3yy7 8-g:⹍mJT<ӓ#_kęRyk瞤ԥɣLPSﱧ{^ZTƋ4MDR'r%[ՐcQ1RQ;z,g&XسEം#IeΜo`J.9Z׾p?-LqWfz&VvNId MC$sc~k/W|3pi{^_B4L J#X Vc J-}(⑏}qwnv,DŽAt 21@Є՛7SWG"t];vm\L4g1|,qͭ[c7A} (Gh%]#~9 +!(gk|kͮ_E 2}#'c46{p] bR2`gI=VUAJp[$h1`p:H{z@c(ʃ]A™;rPqpyx]mqkT*1 ܍ 5ϑ 8`iy[NR)yiI&;8ə-$xSOЎ@PTG2o^b`boj|t'?`I.?,c)7Mq)sjxdFZ '=⥫u5pzu Ã>~ WHe$32:O#ԃDuV|uy1#)g=:togH8@*f1gӍtM3 cA&N΁$ecs9ʺ1xa~.^Ǔmh?w_:̔ܢ H1\?ҷrRO{/UN4\2N~K\AX!k/1ƒ}hx'yjf& #a qe]Y5P?SQ-72nO||!:òKWglZfWBA~oqlʮǟO}O]98}]>%ڶR|;vgYϐ@5|R&:'x=;B̸q3mddc &(_VG]J*EYLdɬb[13'Oa56tq+nM#N0LM& =TɔdFd5Db$-8J[ vpy7B (^'Z7xqo# E%^LgdŔ_R4@o=HWϓ~<YC3Q0S:v/|1jD9ӗ92Tz"o򣷎>fN^K;?[H) 22GN~ YGt`̓O@mz@& MO*_ K8.9 ǸrMNjl|I>OE2g+8'>g?\3hF?l;<o,_;OX[$m 'A(W-I`0}~_\X#0zOp/fe+')uޯF@@*8J[ K^c$1W_-Qȃ?0@P0b4y.cdQU`0`_O=S{62seۯ2ILk{U6 eUp{_6zm5f?qcv,C{Ǚ 0pۯHms6JI ƞe |f V),HGh#wuΜa<E wJ8 FWY+wm1BQmnhjJV>]$gNj99W,2bƤix(t++!_A59˭s]"X\O g d ՂݖU]ZVW4SͺUKZf:3oS6Qt3%Ko4)M-\S;k3.1^TªeX&VZFK׬eIͶ-Wf^j:T qt3-*ݠ iuPbYUKbv_<71KV;&χcA&4+Xa+9?PBl2a CQ-uRWSj[u@8DhUίeC{+F:\^!HΌp荷0+07 }qn_p)VRZhgŲżp(Fdͺ6v10m}O?ŋg<CYHrqm=Ahp1]eu@lweA7'B|'\xTmZV~valuCoc:VXʍp7Eb`Q +V`/Kְvi-&4;/&;p:,Xv>?>.TVEi0.KAҭ.&\ǢӤRWfy)umB%s1u/vqA liRy<:^#~`;-wbV㜚&?L)ޒՔaӺx,|A3&#d"1 䠢n%KVmm_wʎUp˒P oǪ$Y|̻\6Xg-fe}$#UZr? `:O<2)a:BRUPy_i$}MHzJL^ 192{3b54ArMK.w)1 VT%OgHA~*mF>2U"HעFJtCb-aYECD>Vq2:ITg~),,y|K:qTQ5.)ĄnBU3Xd!!%Z4PO[U7icd+"}S63027ƚ;ҜÖF)0 IExK4] }fc6s Q`~#VUJ؝6Tiܜ?k}gq:nbͯiSZTP@+ t5H}TEd P:HUt7vc(8l\![΢%K̿I7Bҽ œKP3 \(g,t:LBUf,oli=I3.0աZz-ˬCiRH=mˋ9̆*CJ0,ߨsIRnIsK#:ùS,޺ծ D(iV @KHL3Iߒ4*^5˱bE$X:gc$̹ЈLrXMAW*7?wlJwAbAQ60as(5&FHS][Gc'K8θVi.(>dkxB VftnBA1$RVL1J}( ?BJ&pl(8{8kQ w:cI@(}Mb4[H螘B1'G,TV nK2XQ#%f > Yא`񗳺2wt?9CY4g4iY  I;xB azIږ᱋9][RAn$pֳ~:GER 5UU*ɂ&I W?_X \̦("N1J)//¢Jڈ2$82m~°L,'4w8lS96Tz>5=ĥ,}( l%,r I N`Q[!@ sL3kQR_w_*d92`9.9V.\y\b4]l(nF#] |gWLD~)$:/+K^ {S+9u ao/%َ2KיNxɕnj}+bΥwLaf\K㡽N͛Ugx+|WhOYs =lw郶q b"8qM(H9=IދU~{nнo:d2p,}kdĕcf,W*n`I%xR ͥ浧˹d44jSN BUTH Chb@!n9#pyH%4;$0vcRo g)>%E<8mқY 1J` l)©He #NNde5Ol/Ŗ!d*iz`YWC]SI F0s+uϣLY%X*mK%[VH5ūlLz4”bΏQ̮x@HK1vbc mrgRQ;5rm`*sJ)kLEP9HJ%~x|/]%ɒ(b{)[9p0WG<ϱܽ#F!,"Jr9Fdr+M=2P0jK:lg"&odw-ly*60H[zL,fl,"t64.ŽUBg:&4Y0=HfFF( NW$'vO~9Rd/rAZZ(S.32C&FBqIi6Z_D0nx龐 tyjv?lǞM ?B'&0RJPX%F;D()qW /~7N^chdFw߾xk12ϵ ݱsivҕAV2Łݮr C OHUnf{8c4N8`b*D8%c&b:EޏK;tUr"t,Z'ޥaX~6 ];A UinhUkv]/bqAfb dFIVn`4dE>9ɟ;]? mͿ4eP糐kSm;ëGpbIMq9-r#mdk}9%%@M]#L u3GvP #4=L-0Y%1O߹cY3{v Йm\! 39Ն5FѺG³QRR[\N)3L,|ĦcztLn"vv>0ujp"Cf<$(F'8qE飽w5;ٵ 3Nõ:pwWa [GY1V9ӷk ǡr6Po#oyބ+(Ĺ|ƙ[**++pF9u$z'4ϻ!U5P/a @ɲTb r$Sg>Nu6\zOʯ`:3C\o>z;hiw%W Bׅ tL=Xfԩ$;dpZ|rkH&9G/63 iƙS{ Q2|~}Ghi@.m&:K㥫JQ'mg\E^R6͡ޡa8IiJjrn$(Lؘb*\Tl ȥn4[xVB*:fgb(RPZG94-CA X\TTWRq)dCbL)ZLEIeTj<˱3S@26ӝ k!xNƮcKĽ嬨_L*/c} 2Ek~TBlh%#6{HR|9.Rt5 T%,@#W{ihy2}h1yvA ?6pu3:Ɓ$l\EqaW 39s(Ʋm+X_ ć 98)'{,kFNs+t~)rRd)հk]!EyU4511s ɆW̾@{ ]vtKg{+C1@;#osb?jVo+xr+ʩ(ʡ9NX`ŕGyy E%M\N^Bε ! pZudѲUYkkNz{{hkk$ɲ)r0=`s4Ao9EUx{z"}0Ag S6v? k|k@pK{b(勫ط]:&L\"k dU}5nYdQBʀI6*rWi ٮtZT_#=δȡEU2n###b:?ÉA 0: (VEE,cSQ7y>;PLV.'6%ɥw^;[x\(F~ \4+$seR y% !t^?^u -%8`:PT\9r>&AjfY!I"DQU(f+Dž¼7!Z#BEbh ±8љ0IT׏ntÌMF^~.9y@Ղ|Q\ٞCύLtz@7]299ŝeEhCl޾w:߄ř%ѱ(*G3Exm05>L KqIAOF"rH=I`l&?&=8QMAI9\r=v3<E=t``(!TL&݅ϛEM&%Ur0%CLE |>dt:fܹ.LgrtX"BDc&B%"QLV|\)%Z,xl“nr'FIbuz)*#aF&?fC9,w&C352F D:e7gn>tfLnsXԴKL3ϏMƉi`sp-3dr:%m%:B\N,&ahL( ri>`l*%$`"I?WÜN• Q:rP0Sq&GG t9>JiFFHH_^!'ZW_kf'`ǜc!q&'#t_LoZ=5<dh*1sQ\$@)&DRNώBcLL8.Ns1i!eX2ߒ Q l%7ϙ OZX6.uӹCSS" ՔmxqZ!cbl`DÖ㧨MbŸ_eCA'b*Ec3)SB1LNy~,A80 RWTa"4>xW^^xd!)3Ip(;I+fr t.{6O?;<дXq ǟOAnN`fr@MJ.LO31$!,gd+ /brx(0&' ' ՌǟKU3R1&\"LTt⴫' DP. KaL#q(Kh@2:dHd2xV$:GۇKM1>:AD؝nnBA&$ !f^+EXT!  T~-M3Rczb@L.#LN'qs1k3O4sM2!. q熙,(!IוQުo~&MGbzΖp}۾58o1ޏY,PU5i8KWM˰̫yt@_n{>f7ӡdl|tyk̘νo6oG&ΰrO0]$t3Ǐ2G)saskLy7wb{ )tr+\΄drt̟CJ 8:LY3G "$ozp1K>5yy+n 5s2w 7faܼǻ8[ț~7bwڧDGg̕Mv~s Nqv=^sF/Z%çdvCKx~_Y:7'7y:qg9a{:Gz7 ?Tw%/fF?2kr˞<",~Y X5Lbوŕޙy݉v"4/p'&SvA,^UrO  c3܇M q׹0z_&ɜ6Iޞf'C\dlBޔ6Z[/ | [B Y}޼2^ox ]rTa:503XFf|zww\JnGT(H']+>bd%w^P~2M>ζWrލnmοzgC/&ʖn`٩y{ϳnE-Źn <š<"4Gg0ӭ4}d*f~ۆϳľ`,>ʪ{0*B"+ݘů:reXr{O?~7z4DَGYS],",~&|( ҀśYJ{G/⠴YdqD]xKNZpKL40W( 5UCYllNQ*k?YdEY3 CMEU7>3<"r ^8)1u]{Yڟ,",~ᐨY',"i@""zDgEYdEYdEYdvIUߗG@*"T.Y?d6#P4`(]1|?gYdŭR+d (U",H ,->}epsf˯;+enn/s04#}47uyk'2%ΖȚ=ӅvD#$c}4 n,@c?`+c%rpWw} bdW4,?  EAX%&F*N0a2#UQ37ͷBbf&LR*rr;CuUe4odf:D$ԠU98{V0F?`Խ?qwa4 &t.1YxVhä%vwyku0\=ci6~?ݯ|7(/x%>C׏~g%%Xeo"!zi#?|˟2M~ W4Jhj`{0YrD=/D?H)#J#)c"8ݤ!ͧ/_8aVQ@ I$ ?-Ů} ! dzr'D߅I(ݗFW %فcCPJp.O>IccS)Q5._ot -*[+*(+bcce=o7V34(_;0Js@ t#H9HdYs`x7۷{;;;3{a,[dŜI$HSs@$R#$$֭[:rY(\.2 =`FɴHki|-W/өiX@V:, Dd`PQx<2Kx2\&I6?J>qD'+03d+|V/Nb˹ʭy}jţ%íZW rb[ヌdq{2vg6Ͼ& kWmllBbB)|^͛J2='uВ j\E4/w${PfBHo/>Fkn FnlsⰫR^iҤLxO0`O7~u^;7T5#gk~< %F+Uqm{4hʜX+˴+E]m\EJ;8uAz.vfѸ#NY[Zt݂:ǚ䅗2c4 X\-*Pԥ].W8WUeQ !sa:_!`X (opMo4i~DiCZjf}5K, \:|.'ٰel[ͥr;9thcY!.;nsV[6 &sO؜QT4P`1zǺ4fQ[jGllUl 'sI:>ȴRGc}bGU>Nd̵svj^cfw+司vuahbnؾ}= ,C hV[9_=?k^e縴O l,j%9xTUŠ.m;u>kx;c1#F_Wd+G_aӝrǶZ\V|GfO‹@zVk|{,q~}/L4i>܀GdwS$m(|p .V*,4ﻋ'9~7e@ |mqWp4U;`_)% W: Ge2 n̖)TV5,&ȱWob:+$t3yQDb$| MY7-%35aQfRE 7Eh?zvЖ^)х?'•%;VA@,0 m*az,st]L;T5R"͙l޶gNtߺW8wdzs6mZ#To^K楟a}g'v-Ώd,@υ\h!,bfZSGs`XB#2Ն/%ݽ}9ݜꋰe^ LwzY={5.')o-p-J}w38_9Ĥ;nۅ[ {-Wp6{sï+5M4>TUiyh;Y%Pd4̕#DȱuAv~q.tc"L͎yj $aڇ"v,F `}f'!DɰSiqʢ5I"5)$i!%bn )\+]*% { k~5eIw3lPD'rA6WXr-VJoFCcY2"č;Ó_tEڇf*[Ϯu8%^g~Cr7eB]f | &hiĴs6JL25~q(܅àC^8K=$l߱"%-ӤIsü89L, dgSWSa`3;3B""vٓ\A1myh%mܱÜsd,U5x y [a LdP,ud ! b6B*yX|1AL7[XNxQNam0{_@:DN=N_G$})Ύh\_ R+8B7ͥ ޓ|[?htRĶLڎgF#J#"uq%<7??.Q| jഛIn֭JlU"pZ4N>IIPHy$Jl>-Iʬ` wOΥ^ i=*SlC6x %f#oq'bl5272da ʁCb']iπ4i\EJή%x~g"L D!0Tѵ`N0$&Wӂ|%%1-Cˈ "Luq~B-ts% sq0i1oEBf| s'$(87h:x;?e8Ms쵗2ga=YV##$a&jt~c=$J"0ˏ'~с%2<֏TDO(N65W"ad.HuT•&z1x0URu%zZh#s|e. *\8tL٬k#<ϝG>(GV6v A/G s:N#m==xHhu4F1edӸq3U0m}P7vexcd }'"0R_,Ed %6ɩg?}D3 M47λʔ\'e2!@zRlhh'á"ePF2s jU$ O^(2H5P뱦#t$'yme/DFN9MkD8i&:զgpǭ2PTL %8sٲ}'e_Q?ۋb+}^ / P‚\i::_UIW{?gZ5uM)ªAAȺ ϵI %6kGF}_ş܃󯞦ߣ"l"7R)iXG*cC[3,HgplxMRNnycCDidqQmٸ ae:y<Qs~QFHwL&ͿoXǟ|O~M_h"–]^+Q65oK0;RmHUZ@ie$5=)zIMA$NBבҊvIBu/ehIbRCI^WB< c}.r/WگH)^j@ *bV&oqlP77RP(*(10^^<`u%&Bi]yWȩlf&,"+>R/(x3ȘҸqv^l$1h>A 5Qb!$iト۷[7S*5 HH рY[2η;GdU!ҤIsc+E\ drmq |>zE͕xh?Z R-@5qg$tI2!at\qB!!o:5+h@1Z# [iI _׋P7F˘ƦI>HnQFCL"0S !Hن]n. 4=t̟DZ2ټs;sO_D.( 6LTj#D<|)lMY90%6ΟJjk*|b@jX06u)Kg^2a̗D4p9I4 :4=YyEY10/iWQ ,F;ne||P<5>YȎUt241Idmv"&ڹ5 NW .gg#2441M&M&B0_YyB޺ Lj %Wf.:gϐCc̈́b4'5-%[3KTVхw!IZqdBYjƸtCPiftl`xj`bN+YYFI`}s[y۩|vf#d\g:g_Rr3LzCQ(*¢ϡP0-LF&#PvN#2@);E$)5?Ջ/2/99^wz9zx,rp .̗Vfj6UHL&z`ցQ(.!8_ZY͠,R^PLf,s*ύPpp$S/H2'^\&FǙ EYݯTrNYۀ q\QDmX$ol1_eUȅ@,7:&mԉLESiD(cAגSif]vJ73CE .:Nf/ xP` p.E$Yk*%eROes_l^0y vl*(.qW s'`:Heώ正q97mkG $a*}c&EPuG'sHy r!UvPj͓R]͹s<͵dK]Q2ycEQTD4N,C}du ]Fa ϩcg$Xz.RC.e,(˂H zlkiBAfQ5j~uBR =^6nK%E4QZ]P$ѤJIS8̢ ϯ~W! ; NL;E5(F\llt4*6)ڙ˩[EH:O.@/X(jɗ1%& ʪxsD$&Ƙ R )xkԗD~ODP,̿Tϻ qիlKQ-⣿?Lg)x+}`PT4_gǭm:R(oގw:邌Z s \L&M1<l}3'Gh9uY371CQ 14]C-ye%hyӊ$8=]M"#9*m*ɵ)uZֱ*ar6"ٛu8b3KԽpjZxSdGu;)p;Y=`D"4aa<<]ƪ<'z6Q_H%ȉGd2gڧ/0%^:pKUe!V3zdO0신ӃD(,)“daqeݷ̈́ : dvS[&dt.|IeAd͛j4.I!Qo N0>G嶽% f=96jl@p0Qcx!P`!8‘]͹2dKSF:pǞbFGmlVCjaO}֪F[u ?}@P` c9|SQ# 6zο')j$^z P|{-ε1;5Θ/FNA1Cz ;a2_\Hr /vq妝4Wi}iv̒[T9>_eHxh^ pPް T/o<";O`ҜG@hATΥ$| ^hfݺ:YkW8R$N6&ÒWNMUQ%Vj{2ɠ1ف${ TAm17=BWg!3 ux2Lt+ki)s[~v&*3q/ʧ`q?l&uM8#;L0J(gvfс+>|[stN/UQbL\+J3](2_OdUSm=rR<]V-@eqc.((BA ץ6FK]/R5cFˤtP)1&>梨J*5cq.-9FJUteK"JUQ,$(p|VogwJ,W$@bI߯n4AUT"UjH毧!pL&ͯEQmJjt ]0x;X"[2ٚ✸x7T>PJdRލѴ$*U\%Mj6h~W/;Tbƪ+K}6Rk:l i x-ZG[2䒛"WAC]/mC_AJU+NILמ_' ]#RboB0<.u>iҤGuPT6TNr-m~~m;]Kl]U۸VI]#b_oWʊ۫FxʟZBcA1X]C$+۝}[tW2w\kjz !v~uiҤIsܐ!B΅7x@ 6U0Tf_c&M4iҤnM:D7-oŐ(d"ܲ E05Љ&v7G4iҤyW|( P|+9jqr󊨨cO~6HҤI&M4V,?é֮_Heu={i'M4iҼk AT %;(kڙd|4iҤI&M_3R nKvR~Wꓴ&M4iV E2TAEO&M4i|H?iҤIf9@fVɄ ط4 3JC"<=W!D*Gr䊘XҤI&ͿzR"D@H"w=ovp"͂^ECNH&T3E_|s $y/$1 Xb0M4iҤyxwHTs ?c ?gG:]XMM}vZJZ.^y_> %^Ӵş" ?/[Z[7ͻC,4Su{b@Iqq~K7aW玼YG3==M$/k䣺JAjўЪ:%2y.\̯뺜>ks__?L,G}p?:mG5y jg.HKq/Wu1J>4i|BELLLWx9؍5_<šQrjvOɺLiBbVHFC|M/$a9̰c,*%!.\̨/0eѼe%9u@ M̆ygfO,-WՙICQh}Eދ<'9 #'\Ov[PLCc=LK54D9{dt:{C1[054TcQMc@,8'`r&v`={qsۓLN== sbؓM]} "4Οb.=(Rbx,ܶ,;L1?‘&„;ogcԋF&0٭d9M/BHS8ʌ?1# [J0!5F5K8Y\\FqDϥ HV˩)"dju7:Kc̄]nl)P0T ИGEj1a0м"s`|'K T.kgjQ.K+7QS[,ic>zSvve#%cJoW@iE9t\"-fp 6n̟I4j=o"<_P{շZZTGre~v<ަ=qx\6T37 O>Fo2Ji"?>GfiҤ1nH=H w&{/ܔ7{V_u^Flv3Y.'FUI+*ꂋWېf'c=t$h^/Po>NDEG9gzܙvA8o P s?ċ\&/ Y_ͷ56Rq K\i#uL8ppfRVw%oݷym +9DNKŒ?Rq(B];Reua̭t  xTugK~W[%{|!eeP 6mcrGy6x_`߆Jr2m62qϝa`:X%N,gWΣk3bWʲ-+GY6iKE ?|)JeaN AAf>Rc[XMX9&Rڳ7,8]N\+et6f֒M4i~m!).&;;X\ś5&9/D2 M5,rG|tv0RjPߡ:RTa3j.Zag"l7qQ:. RױWQks%p8rhܘK^^ ?$z ݉bL/2 3ܳqvP@UNI]ǔQ}>}m5cVHƂMࠨɰB39IkV>%XT o+Mj.f}y.aM25m&f! 1ʊR\$]0r..\Ŝu832pax:=/I#Ef'edlH4bϦЋZ<$Ã14>{*/aVI'ycsw> Y__ۖ| WQ$g_cWhƦBmD44@K ÖSLeqH(A4}#sxk0#"Zd1Bq h'L)e->2`?fA 16dwapz(fXMM25FFfn d*DO$4LAUu)Vgrt@4-*&>cCH%lxTgNک,Šiat:AI}=)wP#Sb/cOߤ|l), 670S4 L/Eӳ3N32ǜY@eYC( KxHslAgvliB'\7K5dn+̦rf$ǓIĂ>a |cdS^Q, ãgd&۵Xc=KyY! axx`s&0ӄ"s0*-dph@,P⶛R'4;,O1Y6B3t 䲱Ak1&G ,C$͙e3/~/ϰ53/>$12la׌A{zv{1fQYQ˜}bFFT\E q{u~b*C[H~cCW H2;:@W!e^LM07csj[IDATb6RPZFaiҤ~n8]Rט?  wW{+d+|n~ wT߱h hJUZPD~)L1DQ]i'Ōdx hN_4y \veaVjsٙ'̑Dm څ@Gt\8G΄ƅ39eǾHdzA&;i,CWK[>%Q;j qELnh?v_W?d _`a>9)/ˏ؉a6lK-̕S{ۭT:5&F{9vuw_{Bd0q8'sGyœuY:86ƆӌfhTaxf orɗ}X|-Hg['!5z{+zF\h\0ȥcrvWYle~ bc7Otp=_}C2BB$rX8s/I`3H87?=d?7۩| n+8c'j_ 0Cs \,Dċ?کٻdU9mY0v>(F8tE\g3N=*'f&KLv[y_E-NO 'p: L^7|7er)eCX":?9NƧn:qW.RUW]9ʋo۷HNq詟.oK 8/!"3KfmH ŖCsM'^:sC<t_+rc-yϼvs7W9 ш hPn h 3UԪՂmu2ߧ ȰI%a#z0q jKL,~|cj3FHE94f'tqad AϩI7%iEf9i 1Ԑʃ<Ey4!pX&x0n 2͒Kqç)ʕsx y[2S{OA@x? [ށ[\9w7yZ7^=ڣ<ޚ?NfaժB ʪ8iUIj>6cqelos :P|Rg0g/ЅoCl)?(U͕1?_1?iw(8,ø7mgCY=9v>}bXގ M[èipf8:M5Ơdq^al@NwGM[8& t n$C@r"/2{-eA.^`r.B78s^ftjsC:~if_u[ln4rn @0 =˙ Ԗy)p96I*220hq񔛠ᥡWRo?2槳k;nc]qsd/q,v+k;:ǩ Y\FgH F Hi*% q  Jv`-w} 4@E[&$Gf6`0jv6 젱Σ ^NnsǸyK?|FoH4F f]űn oCA,#ݣr"nڱS-عgY V No4cB`zz\merfJo%7.ôwk{$DIV>udD˄շ᙮r5rF$̆X̅I=p/ ?\ ;KJpCbǾ sp%{)u?;c'On1fw򱻷b vW'/0O+}s4W{w{nފ#o<)Mę1T$,#~|e 1~ D4Arn` *??:ŗ~VH3z(R,FA'N Lk|3 `/y2h612ǝIF:|1)uƂYD @Q 8x=2%[6b I?㏰xyxK> x{rS#wwdbrN n7ߏx>I-w,")]Uß/WWJc!Y.t&*3>X8jP01"I2]u=`2ѥ/F8 ,dQHT :MG*W%#6H,NRcIp@'1,)LxJkسvwc۸s{ zY~«(t%%q S-ߠҡj&Z8dB#Cw [j_7qeTr[v~vt+7f3nd2|?"'iRiigI_':Ƹ6;7% '̬ۼlt_ tEw&M+7hHY٥ߢs|G7{0SxR+UYݖB2q||pD3!  ~zRlhPwJ?/D|(-4Ky/h^Aٓ)e>}G-H}>PTHT'͂x1¾BǢЕrp&{&y9nlYXL nagA^;NZ}ldd Ť$[7Z?<)#(#׃fA7Q^bƞEv`4̥!o-Dj:B|,h0f{ȰrXAx,$B<K&>"J@F Dh\[xKIF,PT$5 X3t).8/"J.}Q0'ߺD]wq5sv1Uqҭ4FB5#ѥlӉi |*+3xt0fl\VJO0;1 9_rQ <=T+VY6 Ħ*ʲ %RW!Ce|*ߎ409(,q 8ܸŠփtDΚ2 RG*E ۨ<‘gKY8z8m-,.q` DL'~-*eL90O-zyγ=8 "B,6hܖ&lVP *hd0 ib7QʪR DS8I40XL& *WWDudRdU9?5?f\u[HxyTDexM&t9k-_d5$;O2))t5 ꢰе )t3ce}Eh:`g23 lx98zs[brl$UKHjn0Y0O$V]@pv(YfI5 WÇZ[s vV{0H Md 8Ǟ9L2] JK3ѧ+$+@Y!i/bR{ ?^.)X:o NA'ӆ8M$A)?sIE4hj[B4gAO) ;ۅ ee/׼!36ǹcMVP_ii޾/6]0@RO& Ov&X6.,&Rs#y6ҤIkfrrAAy= 90_uqD{8cםQ籤ņ\$F t'^pe ki[.rx@g5XDY-)JHR(qյdtSAjDuKY8:܊X)D" -Vvj(z-GN2+׬'q$*F` 'f0Ljr<_[I4+h( Xy ͊Q{3gLp,O]pO|NumQUE&!p"N=œT)4..UPqfa"8I E;=Иf6h#xt~>\/ZKy4L*b`bh1)@)g6% QE. 0(iRw {?udRsx Iw=T>HDc7$Xg&XFF&H)_$QQ(ʶ"%(sVNJ!g6$)3 "3FG$U8L"%Rvl/Ы81JuN)NᐆŖ2+|:?>:h$Nݘ2|H$&KquX"$-CԪH $"j Dun$ڼAA'i8}}s>m)tRY%ܴ8;gI U=^~B$ԯiqR ЮLԘ즭{؊ u_ o'g_䩃J.@т>us }0m`[S%6M+^'%$5pM,Kx~<*m{h1Ƨg06QjM9bӎm*Km"ˋ_Uzf4~¢\yxq +eyDOsy"ʤ<}ZBAT?u-I2-eLtHyģD: aH (ȯl;865frMmY1VjE`6ҊG!HNsGRƖjuPZ$ЉÔR#8;FM4Q #3M XF%Ql[ƚaGˣL'SY'G|Xi.k {ԍTn,er'PC.&`M9&'#AljI ^L+1< C<\-AjL^%e/>0-(sE9D y%L9ě$H0H('Fn~!֟󍟾DX_2,Fl,w2yH&?AEڰ,G8ah`V vws#-=$$8sK N꫇(J*ϧ_!^;G"񐏈ͺ|Ƣ2$#fP@A$H|dɔgXq($R~8*,=nΝ?Cd1ijG\9g MH]yXJE&TU]TT?'Y΍d،$u};i8M_n#  ИLV#wƨ()Jl^x5zz]%"8@hBn\Ҙog~}ShqI2"0sgLm.n:#YֳD˶rKs!b~58 1;7G gf6@ЁIUBgI΍YyZk$VK$Qf}>#tu3QlBI&&8wU޸_r:/R{ോ;~E$S>7hhkljc^vV8 Nl2y0^SF|ޛP`e zEg^$SA:{Fqz66m'39m 2eP0\8?F. ~"1L$-ܵ3DQ+\A8 HY(z ?D8%#m2sEU^y<]¿/Kmef 0?s/<rZv33p /n1FݝX}!گ0ы7" 1;;K 'b|ԓ}>9&:o$נL&xK>n{S=rWO5sB"#ѸwQbe MMqF5`p MB8 T%¡I~?P9bIFJ[V O}DFnN bbέlu?gÏ(Sh1ʣ?DkFtH0~[6~p#[zo<:/a]W*B쾫Jq*q~7^x˹}C7G z9=ܻ-U(Tmk/GnaKyؤdWl_أ{1߽Dp7~;PN(ZaANaNn}'`sPD~Vwƭ/ط[Xk&7qN̉ `ٹ0ywO?#eT7&D ! k8 ?p@8J"B?q2?*1 A*X8E8&#l}qE2*#kPBm^o4#>֕`V^{F@FfEg$:{FV* IuE [I"fnnXaj:8G_8N]gpSxAMБv-K0&J)FBA±$    IhrF4i>,VnR?ggtjLd[F.?f㒘+=>n-YZ1P ͳlftLa˜YH]uno6|r2mw9C8).+ZL(OnbHffrzsf;wePUW  ߹, Hz t "3 29]V=•'P:;J.Bc g/ arO2KۥKtϒQ}~uDjU.b}C%,~llhm7"Pz1'clGfVnـ`!":9Ȱ_#LՅa!P(msf,I]26:LȘ-cd"j`jlm1D8K)@A`،{R2Vׂ\$UpeRYC` zf!9ƥ -* )(o(9ŵ47T`.oee^#[.g$gz9aAV^ey MaEdٍ$S\)(OMHpz .p1F L~qFO /Գ/qgZu$! 4oLbwP\**1p~YM08)/+'a&P޸ 3<451E#ai&J=2Kv;dwqǶj,Dfh*Bvq%%f吗 eemBXSpeSV%;'sd)BJ r0k R6mDCg2m]  12S[Ԓ!b`jlQq2 KɒSV EyMKkJ^cA7`Zq9FeQO;lQt284j'}6VW j/ZL'eK]X+yťe zZZQ08(/+!Ӫ &M'lVV.]~꯮gqYgu&AK%F璸_},n+'52 7O?{f#՗ E!4;o%Ӵaqtkjv5㻯wO+pyg|W;}XjKm<{(4xK۽flZ,Um8\aߩ:bޏ!WӼYΞ沽o;o\+_SKM֜W|/W~}ŸZsu+Ykkϭr:}Y}^=6˩PDIfFs(zlw掫}\y3̓o3O.~|g9\WPqct_ZԲk8V$k\]$I&A()_VY K࡬kPhўm{XD:@wƲ-Vo'dr\k>edwϪvk6kaf\&wxWf-%6Ym^|_5X㸫ƕwsk]f{ʹh4Qu cG0ġ璵|}igf噮4`^36 ~Fmj&ˬ ;Lt}e վ|Su߹O5_KV38ht =׺(#K<&w;fzyk:nP߮/osoڛ&MX)WEXW;*5qMIjk5b8h:=Brg{GN$&W17ߖ nEPٴkV>ViyF I#tsu+cIF sE4iҤyWx@j:NI7¦2TJ d SQ:}ۚp.cGܴbr~v%FW~  5%G*o's().w28]ӤI&uAez+hR$qb1=OӼD)h\ܪHDRC1QӡiҤI_!Dʫ-%0M6I&MW#@J9s]MfReҼՀE]QRƳ`}ҤI&M> [M+W$G7)M4iҬ H$J#S&M4iҤI&M4i|'Auz^G.A4i>`:IM/u >O "ROH&ͯHqMk:f"s{ٮ:.Qd@ͤnHUH{If-ލGmG( z2N,`h0 wPTUEQ|BAod E`PSEl5bs}I~x jH;/>3^>Ii aC#D2=ӤI#`3Cє}&M\!E jV!P%uL`bI[m4؅<7TT53(}GxOqn z1̍u3?#kxQJӣNfw\}H^0?W`N4i>yU2eTV(@ODmoViqQA$:TT_V- dE)]JH)W-'= N1ex*#ä,[BQ|XYWDH=>y93족$ <1:ɉE5ؾ ὿Bss\.~O.VF27 O@'kؿ|K#|髿"Zz M4B@?ǥ󃜉G]WPif$o1ʺ;) $ǣtO0KuSYU">]=3R/vfS=haT*V%V =D@##7RfeyAꧧ_Dd2b8+, r ߻.}y̷V+|>ܦ_cQBךU#,]L$b1,j*0wSO#_̦/I"0E 5ո vNBi|$!CxpKgOpE愛ݷLbv~|[ג4-4w%~h_Q9+!!?ƩNev6UzPiyY=h,lm BY @$sC\Ђ6 mH24?|9UIGe}1Q{-f;u~c?W($gzc?P t32%}󆛬Jj芬e liFJ,wPiJI=CLMk}D \''5l^}a!>{g(c%;- \l3cS}i~mc_]5B&i;|#Fvmˡe kSsEB9/ Z7-j H;/*"MUZ1~^{Ervwղ~C'y/7%*,0Fu%· #rBxbP +,20AIׅtN7Ս ,t9{$}W𑙝MI*ﬢk.$SObx*S׶fXdvf?q͸]ڶ#7⵫kM&G )>)Y{ٶ|2-'h)"Km 6l*v] ;39E.GQsK\NfmCM+uFyLVAtb_`C 5QL%^0B2N-5qSC/rq2q%~-g 46Mowb!J$ \[^xYr..mqaa[0+r:񎞄bv=2DO 31O;]W2-H?{W"t/ՎuMTR۴7³c5t@JFvXZctbTӉMp|'Q oVim:9B,8Clja4i,p-yr0MFmYLJim yh8b0a6$QL:d"PMhXdn5sTj&ve;1$(saO3 LJ<.u2 1.\掍؅5+b'zL2:/~OV&FUA/0LMk}:%m[x׎u ILh)zgЅ$@I"&ՆŨ_K2IobPS/z2F8C-ج&HIل*$HHLdc5oBA4!jbRAJb1^{7XdLi@4`hjgUptP$G8{)NκïcUSC%$'x3To/7/~czџ~bcx%rn,g{1@eQ`KTTnO6 N%E5`3Rb0:f8ᘆ椤ą,ἔX2X)S|ݭ,QA|+-HH$%y鼹#aQL}E&]IMqsF=' lܱu.IN {۶27 O>OKo0adv5[= >7s'hc-w{,s@O8sI~pzy0]z3Zp-4c''I}8M$Ct},G/pBοO|sY~t.OƩ$)<ɞqJ%W.\J}[q$eLc⁓ul߼;Np)L& !('t ?se$2  -}Tl.gvl`1K06^XQURbt LlȰriVu"aDi )vykBʙYf!X6Z1+Ƭ JtA?Q򱱰.H8z{(V]j%˹d"HO;9rS)l*q!p?=CcQf&&H˸喭x0=afgCɮ{o`٥ >v{?;:>𾿷s79g` &fDl[lzwg]%[Y"eJ"E1af89G f33:w}hH9g$议u_{Fx}7| c6G[Ǩ]DN7\ 9O? 5`oC.#t*6}몳n8\C%#V;βuA>~cT&G&f`O<ɚ4F{9wQzz3C4?^8: WS栯z'~GV2s>{>Cqz.79v%02`COк×yWl3lxQJԇ]e+q{ _B~k:&Ҍgs82?{wNR|6͚ '/OSj;br}boj-T{yX./8-9 ]k7=0<0P/Ty#6xÇN2<36v%WJNrxWIOG?&:o87bтFr\ u|4:^xfT~'7׾$iB|alU6yY\f>zGy?;aeIWk#1 In"TE"_M=r)^'|G7ɲdCG$X%iض0PPǗDX2ڄoމ3eб1N@n" Ӝ/)V2A2]uCH((]d/ ӣH6e x1~ D V[?~x/vfrC/qgu8S`m (K% b1l]KϜvmyO^s`8Ul,=Xe5._ϟFl߲\/6:5͊ qb!]%X{o"MC LӦN~YJWlO|uU̼ӼB!ć s|מ9s;;LL'NF9؃By Ca'-S1sv0p] G b$bߧ?qaiD }u; d"'6hhe:XQ9T.Ap$F"qA)ErrP}ormvP}щ>å)jV㏳4c8jPRɟ>D@̊|"_?O1GZ kRE)uDlܺb34/#yKؾiAg9~a=8t0&+69~8N( $Cz'Ԭt?OȨ4Gٻ,S3#r^>+{[[G{<4]d09?z^5YYAj,ɧn1kK[o^) r#GSp C<$i۳k&;XN)MLlQ1o}_Jb)%[T`O%r9V LSa Kc} fY)l|6m^` ƙOme)Y/E˩72`:\8 ǃ9̄@A9 j*)(,aMŹ!|m<9u{W N5'߇ꢌV@0]n:ϟ{4r0Il_[Kvv.EDb1$Z-1چb+d^i._65%4r*$lեUnbft2 2iHsb&ZJpX$ww̎vKGƁ&G9SLNLrxCa $H^5 $p:RK)CM$g?P P8)6 \ %,0 e$fߤ0qA.7Abxbp,{ZcTͧ,%-7ϖMwt"U%z 1cd{\Cͼ⛄ru}=~BkEzA%UEU\jJIʡd4r8q:MLǃ,P#>*ϱqeM_PIvN!e9>t8L܂z-+ FL waf^wf>LrQQSE^FʺTS^UDGZ6v2Lo@AZvq,sG oC.9LZpq~w25:a Pz;v3^I]~PT,e:^vǣӹl$^Ҽ8NƣH$q }lo:qBLS5N`l/#f"vHA }u[^32lmo"׼vLgܶmlmpMXct #'‚B (*`0nNC:]t%Ӎfv1Bq*jm9oƝUꥋjp8ho/TP[ql&k|K|OO.NA&JD˶g ǶmzHaf^}L6Iv~HelVFfB tR/=|[O4N5pSV=HxtMѮ,VYCg8CW JqT_NYJـtЩ֏Jg]+Ht3b|' K0lE+i}'= ];bg (mn>/}/G)g5{Re!19a"֕j%ajCyʗNaIx5.Z@_sٙ:zM !a @Hs4mb{=^'J[$ 0 "ԩȭEFz4, ؖ F*򗚂"}e+WwG^JGi=uɬzۼ+5 `?=c!R$FFUVWo> A 籼2\IZrQ.iv<2'c*0mOZDz̊ddMV~N}.OI&x?i,Y:'vs8LQE=lR[x3PY%榧m6Xػ,o)5$q16Tu{73|̏KB-H>&uzI6i.0^V??6GRPg XC E-R"Q&UeR塿eVpyԕxZ EEضҺ, ~{zBnY$,+7x|.zzfhtD&iYD,e%#?'-,J}haժeLGQNIмn-Nq+F5lY T;sBvXLOgphhRc2Yz#eW];5¶RO&iIXӣ)4Jp ٴq[7 辝%#Tr}$xK%ynDžgۙʟv;P++gpa >yٴX[QT"̹c6Ibj|/gy;`kΤ qՒą,l*YSD_w#Ao| ץ/ޤwk:ÿ[/qkD-;²-\Ҳ1~F.]ɳ Vn:Ϗ~39~8r qК$nY܆Bv>]^>x ˲m =߶X5$"I|W^x۹g&lyn҂S&lkePPv}H@ROc ?J񣜽e9w\Eo22<7Qh:NMX:6m$׫'4wcz0A̝NaQ (gXS?Ff) * H 5k!UR>TR0ԴEζ|4ǎȑctXtk:&zaAˮ]GfP^UJn~1%9v^f).Gx{?A^e A.bϡ3Vǡ\8@pVVv;LߘAy4ˡ *`av:ǘz^-~i^kLIyㅱK:|v\ܽyY]`H0h_/:\Qk6!?LF:8kzUQW裳(oi$l!'D 3r7_F>;qeHˣ('>!>NAkSg9aEl[[L+(p{?!֗t;(ǤB]L*VmO]4ddf8qaBlo$gb'"4h z=m룵kU+kXSC;=HqЦB?#N8pO-9ᢠ5D:thkLKeF +-#ؾ8H hd;AqU-TM dQVKfN%Y 6p9šj* =w]z_Ȋe]>Bz.PdvS1tp'Lza5K 6bǾ &sLrpϛ}4 'o^8FMaI!5P_zלl"Ң:Nٓpl_󨫫\GMm%yy%T3q'irJ1$J2 :/r֖v̒e<} 9^%1tFP?em/%%d;/Ͼ={86Bfa9./B[/x2(( E"ə ^n5͒LId3:EqAܹeTfpnJK[[;ylk97 Z;ꦴ PXS?qdV0B3t^8-LZ.Jk)"\o!鋝$iTTSGeep/Mtve]iI)pD;9zS@:136vO&\7 Gy)Zr~Μs4N0;ܬ)@|$T}uy}N 3ѱq ߙ {)&UiH'&éh#LpNꗈǒ(ÁeWb(i;I$&n+<>Nē`:8L&mL߃Jƙ EHjp{?>IDn7$kpp$PH8I]fjW2T(LLJ" ʁ4Vp(Dχauj.h(D4pر0h"&ߏa2ᭋ[/%8pNozg;#Ӄ M7ޙ:-q 58pjMaI"&DBS6CZKl/=pB^8D`9K3$L%H :N9XC2q7_q/M*>;H8F<1].^Ǖ7+VP(5uqx4m]-GDt;12Wb-p^ #OZ 4Pxty=DP(񺜩aԲ3 ""8Ӄ& $u“LLpxԪ3wU{/ +a*C+? WxTY`Q6~mճeb'bLN48=>> pH,5CZPXp$w_j0Zj]p4rzhR(l}󶞝$fqVN5 I(&q lbv~GL_[vt@0px=,xP$RQ ˑ b'I$l.lCJD Glxxf/IkE%cL#$T;5<6/jeXLvx{ƿ~.HjSLͶxNN̞+P"[8^)J Kڸ|~|TI)L, ӍƸjꏕH'1]|x ӉB8Gm/J,L|~lRr!>NIޥߪs^ xfF ﹣@=5Nsm3=T߅W_lGk;=j;j{ A SN)895Wz~;53snQÈx լ/x uHu[9$f媺xg֯^"VVa6JWg,rHBOsStkovۺgvp|fM_LcvYkoq pmxWNx(J3Z-]u<¹=׷q[ԏTWՑ[yH^Iݺ\>;icWN쑧XV CɅoOsVVǵ ͮ߮v@ozuM957M|n$C_n(5A+,/ y;uv3nۿdd gr}p<̊ +lHEWh J{E[ݶvve-_~ۺM}nG;jo[VM7+,:.qa20Óq݄ncxn}}qq|_uo߻\nɛ߬j <Ƒ3t Ci[C9_s-޻ o e뽷ms{>PoZWT~Ter{E)bxר}e^fLk3lofKI7א^isλŇwKOi,(/àf6jKҐQK936VRVG f5uu%ZVB=Md|@6Eٸ $>t}t:12!Env:NCBQD TidsJ@ܜRX z'qddJ@35_xD—KMV>h{v6!>l W%A?ߛL7Ey B4“EU0 [ִ)Jl:LB|}[ۅc}!B!CNj #tGy@CB!B!ćI*--z[H"!B!᎗B!B!GB!B9DB!B!"!B!b@B!B1H @!B!C$ B!B!B!B! !B!sB!B9DB!B!"!B!b@B!B1H @!B!C$ B!B!B!B! !B!sB!B9DB!B!"!B!b@B!B1H @!B!C$ B!B!B!B! !B!sB!B9DB!B!"!B!b@B!B1H @!B!C$ B!B!B!B! !B!sB!B9DB!B!"!B!b@B!B1H @!B!C$ B!B!B!B! !B!sB!B9DB!B!"!B!b@B!B1H @!B!C$ B!B!B!B! !B!sB!B9DB!B!"!B!b@B!B1H @!B!C$ B!B!B!B! !B!sB!B9DB!B!"!B!b@B!B1H @!B!C$ B!B!B!B! !B!sB!B9DB!B!"!B!b@B!B1H @!B!C$ B!B!B!B! !B!sB!B9DB!B!"!B!b@B!B1H @!B!C$ B!B!B!B! !B!sB!B9DB!B!"!B!b@B!B1H @!B!C$ B!B!B!B! B!B!;(L !B!"qMR{5`kXcz{=iB!B!TB2Kḃ &nO!B!W3"}gsjpB!B!Ŀ;p{;ݨB!B!>d@!B!&c\B! 4Qs;0M;,L+'Mw_|%1qsRa}R) Vp<1/!B|,(nW#I9t,áӵea`3oBqoFk M4 ralGy Q@HM.1J-gɂ*N[bnB/[at2JcJga6>zSŔ-(mZ)eN]OyUHՅD,JuuU{wC)$/deyAkX.\"A ŋ e'hkkO32Õ}>W0 ^_ȹ$%lVTf>8Ƌi巾N߉u)/ϽɦQ<|l\ɡ \b:Ԕ2f>_L$HZlp\($alhƯ w*d[D"Zxq9ٲŢ$-$h=F'vutv. !K)b]k [cOW/-~Ƕ :"fa(ꅬE ^q1p0?PJi&/s}KkL+p.E_>DZw'JAts]!Wo`Iis>,90݃$W;[Zd#-}Xv07bxs˧42U^Nq,']GMwFB}!D㚒XR`| {eqyNnˏK=/?aԫ| ho]gqfRSXK1Hu;9}t?f޶Lˎ  1(]β<J1}rbY>~<}q _y. }MUVco2ض˻_Go| 6^xocb/ok4Sv\ -Wy$<\U\H$ss)_^ϼ<ux4Ƽ:-,O * C,M~svdw^z1 79BEi ~ƀP/?/ Q䔯_}w>% ==r"G5?fL /lyG!I)Qt'x ̯b |Kc? D+Ci͆^;$VƵۻfR$i; ؆Ct6?笯H=iTJ1s^=83-L/k~JxICD1Mw8gղKjkeJCokۤvܻq%5Tt:J_C<ì[\;QAd/b( 5òo~j}C!ydIto<|o9Gv5Z+|م,h8[W = dl(iPd)Cc~n%ʈs#xQ\K C-h 9\-V<S)堰42`u~|s]_4A)mihOu} ?>G}䖦S|e@s#E<?~GUeR粧H2 f>&6"$ \ӣ=4q 4  /4&4>$IMn^.9!D&F%KMAѶ2Vw$" J@0+ ?D'GwI$B4]jgnNwBn`-a|_eslKX\2 /Y?LKF6.S 12 Iw_{j#- wnYGdΟ:3!2}NlmS4\`mxQN55xZi9ċbvLZ5ֳהRahxpRH$'+9sLSMZ8 0|xdX1GJ fCWKF'&LMY)zڤef240Mn0:r33V0ύSϰô R6,/Fen:lj yU[V4Ql uX ;G7Rl[,ɯ/%=݋'xeNК#6{ -+w$ B JFx6)vRh)~cMԘϱ%C_C^7y}a~yNz/q9:8(S:_c/շr rItzs|pM89FI ~v6g!چ5swh`oIAfY=o5c_O {ϮmɿwlʸgOĝ \dΉI.@k;Epqsq5oZ=6myw&HA`5= M.s71G?=jgc3}M74!>C,xOlfN.X pßcey%H dx׹ ;c|b;Nrn:xQzƱA{}{fhw=z}myNr le<G]!ڱqzSU!& 9 Ydbp<. ٜ=>#9AcC7Yw1ZTv ӷQ-qp\LS87O>Ɇj~} ;g(ywu0=48ĩ._b-AæA~.9eC}z6m Ǝ#Xi$.s#ΆO{x';[oUlhIO?YJ8e? cW=sU 2<1E$#1r<,UC⍬}y=kq[|Sq]33uO0((VLv1:9`O3"7o©l$m'Vm\fibE <Ĺp~u. $6 SGi;vG r%'z |p E ;724g2.6% y+_EL4ڛp7q|/fǸ;7Ud?GvΞ3lh_/}slCWE22_w4Ϯg<·ʉzO1 =ƕ:m2J2?Ms,ﳬY9 H#0㱧زJM3QZc%-l4?L`!5^l4~*gYnف<|'Z(\nv2V<e۠vXC|+L B!G34- ,V~R1hˁ1MD ' ϼ0\x|NC!,=qI-5lXtkǎ5fCݜlXa-+i#Gwϑ.>'Y[yG/dB:b?Ʈ>Oq:PdTPY^rYu/ȟ'b{}&-GwVl@IDATXQZks".<qszhWCfV܀ɮ *p^]R/tNaj2MuMr\85ys_Ӝ険dDB!> d2L<`a}$\iꫳPʠv dCjtPl'YWF/IGVi'npF$Y%9/6T NÛ?,vn5mYg8~rvt5z&Y_J̩ l7Xtv/Cn2<I"H2rv|r ؐ Ű'L'%wrzp{-x؇x\wW5p=L"DzG~Jy(Y̖~6;^['o5)iYiBN?*~۽[0/n$ }V148(0xt9OİQ\>ˡ3ep7NR!jhg.M놺Gۿ~DT{l `ܪnhl,|8p,O5XW] :^V?56W>>Zlہ'`b"+CsR/ۇ'`"Ŷd*}c.8`c%m0Xz]N5dsԗdqP([c'laX%Te{Pe>CܠɄE }7:Ktdtts{xZ.[33 /X\"$iqՍkTh˹oC :l(rڇq+O+\#b)VT_ {uNzHw K_̷~+A8!l95+(5ũ'q-Q; .8Pf[ʳ99l))+Y~F-U_Ny#B$ B r/(#Ma*XB5O#V ?YW-ε588}-L)}~̓4m1q:=fwjU:Va]lZh8c_ZZ E0pA50JXCR_~dh|ONAa<b>TqՓWWœINzaX$zfY[e( lm  O<^{ Jn'ŷ~Wz1> Y6&a^+bIy6JG8֋_z Ukxk,&=p2TH8DvZ4H(wAM(1KQm<33IKw`t"M2% zP~&) sE\e5Sa(_^ڛOpjLw:֬|W#Mp$H"u1 ˷/lC4HuIr :w_:qB R .>lOs\ˌ8]Lc͓Px _&\h Z^_}mlm`(ps0]Ԥ5q Wbiy/X]"֣]WTmڶbq@in2s 3PE$!H##&Lj'4¶D#Nrqwv/HѶ&t [Wq测޽]r Y>#lmc'-e115AvbL4\n7SS5ImXyR<^4[mF=xuLeSSgQ(֤r7=Fi.?BEFv꾮!_ǣ?…~ RC-i н8að@G,]A2@)*3#sZ9~a۷u\T,Ɠg.28`KބL B!GmYU urҴQ_uj`*Va*ʬ&RBۂy0 ];>I ,K%}ӡ6& ekfϾ( Δ,bM~Ls.@iƒ}KB, HȩZ̼$I(mj!&LDl)bxRGPW_JvV4vKjY[Cenڝ- Chh ~Sp\+H3iy䤛}wIؠ$c$Z?}PC=4p+#ykohNa/<}]h;Ng_.tI5Gw7:FQZOz) [ՙ3o ٞTG;?zn c"  GH$ӃԮLǚħh:{xk+I8"b%' DZ,E^*zh yv:FP?cͽOu,/ brk.\~ηlz wv:4!;Éek1]Aj/o'h?&aۘi%lXOd; ,@u7?~Y9N̲EIIBzc\f`NpB:r^?3>8'˲I/]}[S|o'Ύ㗉Gү~$z¶41$.9Yq^fF,!3O$]NQ]8o7p mfޒE0J@xx mßߦ'b]s4mOrTE"2Fs[E6S_ E e3>4Ԩ?eUΚ'x9;LwxWy٧yp3I;ı~84 ;N%u G/D#b 0 e`,N\wt˿[ !B|)5+~$I$_or|'.d7OFp)ddj+))-""(bUyȢr^Vy 0>*+ =}]Sҝ8iTTVCH0>By)//b$/ aTEM84I8ᠠleOmN0LDx@Rm\Fy]T G' 9Yx R]I_KL:ضmA<0v]NqHDQQVDzZڅ/NgSg1yed LOAAnQuu]D"q5Xf}s ѸBn90fj砕² *\86{bϮ;~ITTQU[Guq:aMa֬\@Nӊufng`\U2Ëg5frl\V"4tcGrk 6𤥑שHF&i;w]G.PaZ_wAfa99).65s]Ͻגu8}==5,-QZU\hiwfm,)KewR]Ik-4zFwQdХ~"ScYVWhg|JQNəˣ2q \VU`bJ]-8B"xWVqlAZGl<JۉR LƘ Lϧ0\v(8m#O1nq8dľmX?ä A KKd-{֔cNGJԮ.psXt]<Ɇn-7$/[앃$]~G՚,*5RtJAc|6 19GkkRx-˳ u1bt=1;Lx_Ja$'suvPE.Oذe-y~fn)cO@!@) pYN g<'ZJm[vj^aVW 9ض 4 l˚-+5w:+߯ W'Na`[k*-{on0,S+=Kp\O~-hmOos==7iak2LqsKoyEҲgjj%-,02jlah[c6=Cil+5VӉsix_=NqZc]200:ٸ'zp!+:I T꘯Qf e0MtSsqeLC]9_@2iߝ N-t=N^^k?#w9tu˶멁1sI^AZMjaϞOC%9gs0Ҳ KRInԸn"̈́F'4?ȅDZUm_~S?iX1.?CǘE (KǼ!/tb>+ulym]:uvJk'0׮J&(Rۙ)'0F_7*cPšνqefWFjg64TJݟScH&ze1{5 4IK_uOGe@+<׌m qL^>Ⱦ>W&ݕ:>Ξ=GEzN!UO1V`r*ӗq}.UW꒞#G`N_f~nyC͜mj'S]YLq:xfF @B!>T៘c?廿:d_gټ+5\ÉMt_8̂eeYoQBSD& /642ù dTSbr2N 3=n)`$/X0o[KX>^?څtwߙ-A O}d5NDg2.Vs>lŽM0Wiꪧ3.MS#vݸf0zϼe @V B!ǃؖßǶ'-_][XTfՊ%ex> v"Bc8#ioOǟZMvRh i> 3{m"F;5ц&*KVN, "4%b'. @jן?Kfԅ?_`!6|i8N(j O,uo+lK* - !c%Z:?%r*y=4>J?A6] $xj =+nϿAZv̻>Ckȭ}y]RRRDV0@ݖ'Yt>;^:VuC.|8h+J.ekYS_ɵl͏* B'0Äc ?~#ӃKD ߋy[Q PH4r8p{||GK:uL7>m25@!s(\n}tz G x@0@phmω6(o q{$ B0Oi q= w#}S !B!#!B!b@B!B1V$DB!B=ZkB0I+W/Lkmٸ\.  2 cdpB!bnx@$HW/Hքzˑ!aAFzo1!B!x@Rp(Lvv&@c7Z)2h+|;eJ)l¶Ysh0BkZM("=X:B!z#@ o,+PJog]&:5JGs?iUy?=r3j33? _DFip R_\);z|B[dž S^I}w|H!B!r[Sk;Kv2(;$;# dѱqBGfF:=ۢy9S1 LCa'D\|\/U!v<۫WЛ/r޳D-GG1 cz˲028~OR[9x N:w0 NJN4ѩq"1l2M2rN`-kx_s1RQAK}B!Bn/p3?_|UOWvlQI)qܓ^e`OX f3|ew6o[`DZWLuh×ɼrԫgf&d܌aWT*/=OTtes̚/%15L[XS{0'E[f>NiM~u l\Ofjr$wU:D]qlYhlNjH@!B!~gW @k;X~}Bk#[8Bꕔf-q^H"/\j}<|Mbj]X 7 t<5ڙGze.M"iaNOUױn%F}J{j^k{ _`ŠxOfРAܿϽ\Mk(GH۶QfHW\RN\`8̫ X)cbB!B>c5ZȟWCm&:y zsN7NG e􆑚Ki0eab&a7韕:()" 4q+mc[/% ȼjL"Կ;N90p0os)a^c ,Fܤ\N`e[BRLsv>n4SU?H}U*u UehO>`:RS~6,ԕ2>dyR8 45mcۊ`A-u(qvt}8PW՟k m6ŹB!B>G~?8 o~,?ϞHС0q{<8g:JIEK)t6eQ>mwΙ2K;gнq0:b]eʾ*0׌w`4v 4bI.2ΊM|ue;o:GEٺ tf{ ՕMM G]NDho:Eȗ/ΑC,~n9q,Vu7Q+Ho;mcg9.\$XMk6(M 4u Nx_B-gr?p&+=ªbd*bS4o0tEFw:JfibM2D&n"ld2u}v̞xFrZ8ƒRar‘ʟKMuA"46Hg </50bfBrB!ާFW=ՏxvG#;~[vx5Gx}^F/{?x2uE={8q9!jUž+d|K/ra|8#d)_~jY8 OrLZ^=J۟M3LZa׮cqM)J{n/ۿ'/ɩKt165;86Iv3oO_:AD)>zf籋A| mq7/HA22܌`N|/n+Xz%0{_{8&~g8=x)~?=*ηFD>$=\nkđ4b+Sg` nHӍt*jY4C-'uq9e^?L$:ݯ_ޓow(B!Bۍ`f5__?>Y|KE9cpwa)MFR*rY!6^b;,Ѯ6qMN]+p%ΒG1ld|&,թLV6~ԕb6˗.7VSyeTiIތ< {JYb9Y$}'OM SS}|*6KqE,-b^/zA!]ͭ9IbKc8ֻ֡M2T-f :nV0̬ujd'6@@ d|*@ ibAnU%΃`7J`8_̪ )$ÓL540S ջcwEV*mӹ(RA r_ɛ B!eO$-{zd&P/7Xm{}c>Jp$ڶ?58,\v8Ô|b#LQPS;>ęK!+]?Tb:+il|9YXmĆ =;+o( *(vS{ys.vMszEۘNZRoVowcްJ)ZJty_пg#(ض#cnvA={< #d B!B"Pfbݶ5|&k&5u+wa" 0dFۊzV8`9EEXQÅw^-YDUvqRV}1$q06&Gj̥vyT9Z},qE,%8|ӉMƣ$*5FgiOgOe7?Mp+VxšMV)Pꪧ:IoeTn-o,HSpF+pS\]KN4Ͻމ(D!10 P2>y!ltV7<2>6 ['',l;3MYa ߡcD2I,<I[] (A9B!B?5D.)1(Z?1{X,ƠrMK_CZ<6Ck+`ʅ:`SZdTr~9;ƅVY ) vmŦh`tsس'nk -'n-~x}u3 Yv?{%u}N9w# 0g,%w\x|g5~kfq%YEE*R$ 4cUW>g?эNT>os~p,';Y^Q\mzer*ʩWdC D'I16J zPSQ_PNQɾ^=YOUM=n'^(S޴`^A&&"twRP3s>!B!s_ss@6p:g N3>2((H0\B8qL ji׉ Ҽt9K*T6,fͲim,.e1  @KXT[S$SqJQ5fzTY\Wt2AdbVRYOU"5VR вx V4SSQJ~K2:n pz򨬪8vr$Ki-%\XD8AdlgAu%S QDa f6n^Kmy1-)PNŴUPRVNyi!Heиb#K cl2EyM3EET7/aYK-EA+Xry&q@1 ea fyi깿NN`\K%TE0 (0ƥm5Ä^\)/. TTFKK5P_tHLQRYG8#z4 B!p__{cgl|/:RRTT70L @i}}Bٹs; Lm_>eg+aY= s$s&{lmga\>- gaP9} sUn[mʑ+w۲l5Sq5 #잭 f掩Yem{f:idض}~_Dk͑cq9r 2 ܱgsadmϺG Z|O2fh{5gyމ墲BB!B' C@ضm[WBc[ٗmNOuZc[Xybd.~ +yq2h"se_UYX̜ryXy{0/}̅XX>μl_گB!B1c!WB!B!uNB!B!ć;O yz3KޤfF!B!K$i@mYl6\4`YT]' h@B!c~==c @k-b @k}?(B!FJ%Iӄw; ӔbJ)JJu1B!B\B:wyuB!Bߌ3r-B!BK@B!B!"SC7oR>!ךLB!3eNa.BayrSR B\t3 \G֌!4! +J1LQTT(ϮEǔ-.B,0z5!kAp \G,&HԘB!Rd2Μ=m2*`%,Mdj\!BmN'X4^OדY bAiR Xh `kEW0 !XxyNqHg29$ Cж}`(@U)2PhB!\|Ek20^AJa(A)3I&sMx,qWs:&>9Lۉӌ&wuν0-j;piNw cwwuJyckiH/'u0%-! u!x9pOp{E=< M7N?O?]+]Np/ .W#|夽/>ߐyB&L05FCI`Ϲ-t#2PJNę't6.^C;/ۧj?!AJ21 yk>%ydfW)eKam+1՝i Ӊk%(e1yۼx7Jk \̃=ToM?j3 ktҚj >5)0rd۹HfKNctfN"u`gCx k6BeP,pxm]F.X0pgv`yr6OXS╮ cuw˶`QΕuf@`g3N(1Eoa߿rgi\ȃna?`TOxmv3MܱhPȃ-lPIlh) >4ĕKT2 Θ9yL``FnwebL'~gJ_[c;B܈Lut6^Wʒ `Z4=T̏:|ޟ vwS)\}u~ SBe"k#|?s  UKxS:lWIαfߗQs"kfo}3Z6=,f G;#ٽoYDϘ7sɌ/|o|sׯg f&@dr=(3ɓ/u4b7o"LB=%.Զ xɓϾm˪(tA|b=Gc؎|ZPwpTzb.9wL,J|q O( <^#_OrORd11B2$Ǐzr* |$SǓ8}ʺFn۲mg)_DߍBLy&0=T7/8lq:I) 8u4CS&-ױ&<׹w0lz7NaYkNՋ)lv*¹S8r@JlP)?Fig֬Lͫظ9pӺVVr'/zWUQ³M(Ҝ?| w]#aZ[i;3DQK3y _yJm`C5kQ>v1BZƲ JkD8I$iaǺ鋥h 4$9OoOkG:Zu kBD;9z76nP=3BAJXta^sd۶m*bΝssݷSovGkزia*Bফ'c!(c3;Y MmQM6ҚN@lkVL|F#1*~ l[}DEKi.[H;C Ŭ]\;V~ (+P9NJCn:N{5xp]rye9އPw0y;*S6.aU BꘅjlK/fqzbyas_ fA}mYcEw)eν N%8*?}%=ʞ'c_}?ljQSüo'R$ Oںz*Jpo ݑ4C|?tCum T'??=hC3|Mk"7៾=N1 8#5^:6Ȼ]A)zη3t_7a9#MDasjq'0t"Kٌw[wx|ܵքZٶn }oġ):nkǎਫ%ibEy/J}K ~';qf$a: pQRUKs}5 ɨO͑!l3㯿$} ÀѶۉzƗ`0> s{O[xk^NNsdu`:4.-7!W~WOr; xM,?~ tw ט⍗s?g?)7L~:;9qt?~;Ǟes |<Gڪbf_v65It"rаn>z/w3iIy^1ե8@\SΠJe~^OڬYEz(!$'8w7L-ܪLJPqU]=l??>{.ii@X篿ţ/?%M~x%ٺc s#1~{VjC?_Dv*Ÿk J6t:; 7Yv=++XZDן3p"lg+} 5Z(kw>ˉb~o"P[@y;NR%҃(h4%e6yM4V8:V }QNdˢ"&dsܳomz|_q>ǼiPLwpqtsg k|h xsߡ҇uemplNjK/ uulL)S]2^,"`h* ?SxLi R2m-:E͒l]Vn1H'FՄT5y6BFk!x?LlY[q:~N>ߛmsSRq&GQhҩ~j Z3gnb߸oC|b]G3l"?ρeYhe(tr( q10p8f{p(ki-=$ i irp*n& Ă3楋|,탓4xݸ~_5 LLӏB@^t%5E sldd"FN{ӧ-~bwva\nʘ O[_;}^\Ne@P |k.4o pv嗒wFqOc#G2/;M0lpI-+sj,K5=n"OX+e0ic`2IAnI@y4nۋT !ݟ.8=&w: B\Oy}<‹Uyyko%_fs=iVܶ A =MݢDNWIYVF&Sٌ: ypp!Ob+41DkW"I6`>{4F^9k9Ah:JIpiu%l CQe%ƺNW, _,#Hf F6}zo1[r\Ft¶&옠b];Uj&r՜I[T1Oy)͋s;*f7ŗWɐN_h ͜\ v9Ϳ`gR,kV WJ2`=غe-RlCJk;[9ү8-4̪m'l棔f.ƪ\V:Cff 5sBqP\dJ{?+4E5-.R4 Elj%d*f&L? 7PgZcKϱdPٺ0 bbvhj"~{XƶRrhsrece O[,GHkMo(ͅ˜:tȎMY&Kn}O߽c~72 rj˲- dɊ'&u{ F'4,́yuy+dtT%nNd$p&v:BW˚) 1Lgt<֚t2T"zPvBT X քBAz#|,;ezKDG$94='PSC;w>Rч9?pvZj \U`]뤹e1)XR>skO=/ ^Œb<"6ݲDcd:;$Ag 3>>Io^@Yiz 5mP\RV6E/:k 2>1L(*nӼc7;DZg. :4@8FÑ$U>^' )d4N M,z4.Z}+gO?u"CyM#v?ƠNvd8_pnrJ(kVdY:1Fw $TLb1F{z(oNɴWTM9MaLmֵT4tz~F#+]PAo7_|jj c h4E/A_ocC ~o=7ܺiF)\# MaD\(K p*Iup7/ZLqur)6/#cԾ:DEk5näy-+_PGEf`$سB#v"VbtĤw(BIYeB4::{I pksDC Eu;4FUQ@2>kNJL 1к!ddxѲf޻w;,ee1^[:{dQ"޶erZjKp& lظRE Fp0!:e`pj,-§#y FjYQ!:~_LSac,,KRWS )-Xof ⶏ5چb 2q,|fpp~9eEEKQ7?mk(d \p?Qb8f[nuԆ8ZVodF|jjk)iL9X.V擎7Ғ2ʋrP[\Lie+3]вl1-_Dsk 5ىCj(+)<_>%+TL]u ~R*J)('L3R*ʋ(jb)奦yKhm @jl OMe@p/Dc]A[7Z o^>%YXap(iaIKaR0 7+ٶq1A**f&LTՕP\RAi8yf !> FGe9Ji# L4Q/02tdP>E,392s3A:o` OY ٺЎ2RZ^Aqi%y#(.|jX<׵eH)[?;7Q Yj %>&G$vYVVe`"Mmi9E%z$ SZBZ.4ᢨUK깂,]p᢬q)57R PS\^A]C^R4p3@)%%bÌ%STRBId+0e =SϿơxck+Qݲv@]6%RB^ؙ8C) )/-u): |JV]Cu؋+˗R[@.ne3I^I ['G`{Jvm4Z{ij!ϙM ظx4ה.5S N+-BQbK). PTVK j(XP{ַ4LxsϴLNN /~< /of ̛JKqQ!>oe13J_( e>'# ;k5rI.JaRh)Leck=g[e1[7asǙ]re`fvȹecMwi+.+y/ P4/ŲJaƜfd,hnj°Ŷɝc| :[~5쳶Gl ĸ5^R{7>Je?nƅ2[/Oy~Ɯ0 ncָu32wWP~WY!}Q03P 9W!=5gRQQ6RL]ԭ 3pͲ9RƬ>=?{i~W-+lc&ж%r}yQ@$msp0.hgfvv1mF.7rֵ=F0ggٶ>?7@$R3==T4Qu #_goG~kCE6n#Mi+qẁ<}5fR(c:oxvjivKum99n36{t~ !niA~08ܲ,9 y@h&cm.z۶.ea_bh[u!*ohN0a~15t9/u/%1Zc*R"m_H8}i;Kgnuۗwqny_eu͹p:Mk__ ^r\:'sy R_^ WyUl3Awy k3mKoae.ndrzIvmJa h½uL\Z߉KsZ˷K2s5/eB&,d-x}$cQƣSx2K! OHq+fMc).tjj= Ȉ8!X`ʱz{z/Ǒ>ַ1v!BU~`/os i5KJ pJ\!܁eR.:H@! ozfm6.f!iօ9JY!א>d}%9JI ̒@!Z˸@,1K6><!Wi0F-P; \G 4M'p]ҊBp$ICWT5R} !Xpjt,Ȉ, \G à0%B!>4(**̮.a( yXR !X`Jv/$pqTT_b!Iɼp̻B!ޑCHB!Bq@!B!CDB!B!ćL ewbB!WdŀKBe!K :355ږ<B!2~.Mɲ,ɤB2p] Ǔ@uIJ,Ʃr]!$S)zzzzmA$ʐQB!eYx=JKKp8>c#Zkx<Z(by=F,t:C,X!bZ2l9B @ÿBqc(Pʐ@Bgض ǻv0B6(l+|C/c`^áyJ)i  B6C~ PJag2؆)# ⦖_y- 0MP 4g06 Ñ"=5FGg"y{N2ꝊN}-~(*N'Cd@iK+񘗮cj#ԵR]G``:s \bZ5Q5yw30{`Ib In}`-aEqYKw 55AwG;]},Ӂ'j qﱱSt3vPtG~Bfes,_mt)ɇ79Oq4xz12.Ć8{n"LuHOp5|3wSsKzJKw.vtr ״BcP\↊\E"Bq)㙧y/EII%a3ʁG_jvjoؓef~Nr_V3~%'Zy`[?| .UOFTzٺЎqxP? z=<1J)wAmV 59BO ,]B0~<8'4-YLkC KZR]ɼB =_ۏ _^GkK3 ոc6HҥTT|-ܱG>:7_5( \ 1p_?{uY-0< tzNXq--KrǪ"^{ MUCvWvYkm,rǞGEmx,u+ֲeܶϱ`729sR>Ɠw JYmC}?o`Cb +GzFG¥ml%[>}|/u>]m([a _4V3"C.D8z59b{9^rO|ւoz_KYclcl*Q@uc6}sܷ =hTC1:ύ>_|XjRy.>7 #j7yt?%\fOG_=ņ r=׾O_(j_;7Vo;=o0`?-yLu9eBFiU:ʷCnlJj ^nǜ)w 0F6 PbבNF<Ž*,#\J0GB/=J)&;dsce57neUn2q.:5r*=ž}b g6>BNc}i;ő^D1ϲxvKoU38m6CGK>"ԇ8 #7d2E" mD1 7N9f bcزq ^;ڏ b& 0S#=tG4Fa3y׎tԠ^NQq-w~wol Hl[}e5b`d&x_p`4-w˃>[9Tbocn-G1嵧^Qýf4;v {o2`K?%)H8 \ym#y}[71vv7N]r{{QN eHBiʖ[͟׾4R~Sf2'rr!ȉѱ)25!& [(p̤( OZEN0 a"0Zx;Yb9mS\TzʊEж<jCyo__b"hoIXmZӗǝ>sɞfcyסr=x}4=ҡqQ>sXl;NvӼv>嗻\|''w)D#v0><C3Bv?p4¢|;W` nv3ض Pwf|4 .7n 9]44TPQĚխDbicM lߛ͞LJ*(/ SXUkv6jAr?, \JyT:F& խ&) I8!T93PMku!%enK +ncBUЅB4V.uyן6S i0LF4Iz[av`MN0qy9.d*=2 Á%` #W(.{qv(.*ʽ+քBACx:ώ_ /cq]mZuc=o}ʚغLJ^Y p{S6}d, }ۢ5]gem!2 !LayG<}I? 5~aoi,n)ghzX"sٞ~ԭ BwK'XƖ~m|W9}A~g .Cy8FLdgHLY8|c$,N p;[ 䗐 F#S|!)0 oKQ'hd"FYAk=R=4.NC(2|CmOg񇵎q PZϢj/{{VZî'(hLoQ0S6ܱʗo=0y{_bKKQth۶14FRJ!70Xl Kw`K,fM8/Dua;iL/Mg1ws+)^u5+;2)z҉)'54B\}|[ hSȚk(qs}~ʽ% |]L JM7b"܅,ZWY', CaM0мHŢGbXZiB)AJJZ+Sٴ~F"h2q,il!5RLF"ݷLc5G|G[jQ|jB&LrUģXea >D&&q􃷶5~v{+GL} 卷{?Oz&pi`_w(:Ƌ/cj1x~orA !׷eKpظa=7m4 uUM_@ *e}mZȯ[霠˘egHf,\tt$"vt304dɤ3tYVD²,KR͞'+ow0T6eHsI x %@'e`pָeJSUsYu#3g ) Qڢ!v2Lb }Fض&ɐdv/?԰B4eٜ,ot:J{62o>BۤR)҉|mkJm`cC>o~f 3ae)ŒmP#dt#Ga [A*®_}7?DwnMts=;ocRֺ[ꓼ1iX :zn۲餧gH$ =9t ;&ʠ(w)?{ {&"1=lVW8omd>u_Lko;uhbxILLvCk+>x$0csΑ 6emEAJcY2 .l;)np~ BqcRJ5Wp|d&Kїf D|8+ppZI&ڴT$TmQ5g%:ٵs'(ۃӌ<܌;ku46P;cq().4H߉=zQM҂ǏR[fwOq aawu BnN6l6Fp &t]IST5a 57QQিm*Vo\IomM40@B,0e8 3ġ}osN$ԲBEЙ]mj{1: Q\TLD9-a Nwt3I˦ٴwBs'NE_ISNqFlܼ:N:Ogg7 ܷi^LwښOp|ZͦdNj9ӧcw]E#`yv*{pxT5P硠|sg8ws:qlࡻQwSjWh828ss*ږ%4Wc;wajذ|i[TAyE@:N<™Np3l]M>{5D1^c W!BJ= ?㙷$`ȓO/rf μ=q8mI 3쒶- sn$md,pÌ=?q@&cGsSj͵8ʾl ua޶mH$H3\N^gf@vTL>=V$b1R8gY$)Kd<v&T<4/LS ҉8pz0CRXg{>񇨫Zs,嘦yVx,N(r[7ؠL<>/N#I&SNND"S) Tx"e20M& py}Et[ !q-s?-'C{3ҹ׀w!7 !B,u4B[~Y:×G!*BHB!QMB\ #&5p, &B̕dunZapȲ}B!V*q_vJ0sÐ! ֚@ނ5"N2œ׺8B!n2iR\\^|4(I!! N)  u1B caI :v_b!}XBq5Im%B!B|H @!B!!YvH!"9h.ÅB\- YK :c6D[jB![_%tht [׺(B!n2i $YHkM$EÔ! +ci4`@zeYr9q:y%baRiFG(**\IMuZJ)F!ĂmIX`eɤ02O!BQ*8{ RK :/9B!yw׶Bp^4|B\}!.B8"@]!%=B!WV&I<=(.i~σ@BqM:1E$#5ma8\n<.m\vRiz7ǷvpM#R RCi OnӁiKlwiZ!c(0oeX08)I3hep: {s]c`D%Ҡ0q{}nԢB! }>ϿM=`4ה1A6u,k^oXDGGIj> x;;IDATBm 0 Lg Qib>YATl leI( 0TÌF&piaE1FIX IA¸#95h"JPR9}mc6^9[3HNfpz<Xq˹m*N-!Z;(k\Ɗ0~3)&xsı~/ܻZ}ha2 v:m2IT!>dt+6zT`k$}=$,^Tw!`"2DtŔ\F&\HyPvzFf(姩cjg:ɘ.˂TWSW$wSfJ֧e?0@,ow|;) 4V:F#<{{:ORi1+{quOn`&if.ag2#N) C@$qD"< T,d4N*#.Ja$jSb*@A!~G ,m1>8H 7 O3vr)||(g020D,O17(eUT/apdt5X@bwys Ͽ~B8lyݝ|wXع;:SEtAi0͙mԬܝ.3>>yq.o^@]m1JN܎ .}/W ykip{h}oqj\X?Na9Yl0g <;~Et2UÜSН4NynR}i4!WF38.a`6XEEyNǨIex+R~c'ouGQWX[ymEzjS'&fkq)$g2)+~(M+7&39z+PŦMk(:ѶEds]}vdl^UOry %MY\SضF)C:B򁶆PQ55 _>ӿ̮LXND?GanE۞'7EO0`>ٱH9̣_1C'hTյr][0g:d&¹G[[Pt9NeMO2B"[Ϧ atn"I !I9Ga&ھt>Aaya]&ɐ$+om'9f˦5Td6O~‘),lش[n/|~\CXl޶>yZܩW*C lz §Xr7fͶ-vƒkIpcڵ fZJ<`iYLȑnFnʃ4ȑDR\yTU+`_ֈ+ϡgKSl֯"HFo8Bq["SBsORygyYl*uxǢu[; 3?Oyk1-p԰$K'fZ[?/z;/~ %%fdO6Yt%$ !Mtz(,)!UĒctuu,o^_at8P Ypp;p)E`f}6p 5pe1׶.p`:dRV6 0нZ]^ q;83^e)ڎS0>7m Mu=#vۃtq {<3<`p=].7|~ }~}^ܦ$ reHmRNneX ZkPۅuc`8]񴧱 |ش$-?y7uE. 6ڂ+XC B!np 3"f g{,ܾ d"mL5eaYu%/qgb4ɴL2p2Q5?I` krl ~9OPUQBqؤBKJHea0F'Qqy RL3}𝮶4^L d;s*tu;p|؉L:[v׍i)L&C:s~ϒMiηN΍g.fltHe$i00LrcK|+,7<~Z=1}_}/Qln2?^MpBc:WV]v9H!F{R 8p`& Md {KqX\NM:cxptBtD<6LL$Q2ws3m0Mk| VNqnDOS'F&Qs,Qk*NJhF4='Ž}$m 7!mg!aY^/F[Z8,&&bhCIb)Pq.夠8+1T<2 2SQ m{`mSQD''Ii"Ct*?&,$@Z)Lh$eοLLFܨT~bmۄ6݋>_(R:wYg:tMv\f=+T0sfwh]aAҖE*ett ± LmͿ~x5biHM91zB!D91@jh= 8Uʤ o#,*u}mݏ5/Y֒l6)PO}%n}wXV>|U8x}jB[bat(%Cy/\QOcC)w>O' 6--&NkpdlMYE%!O]i"LŒXIDt gW@uݣ z4*>"*~s Sw$c]pQP^STC^*ARQ]T34ȰFO%(=?O ?^~n7YN}|+u+( y)o^úݽOWbA& NP^OIu^d'7""JnXBIѷyџPr_k8 6ӯ/9? 9D"}9 oDFXA\D,GEnၻ6Rg l2Դ.gUk5SZ|ɔ~f/-dPPȊrRq&T]N/=WƦ[7Pt056J᧶20mMboY2&Oxdi"!Xh4xxʠ|߅qVx^>ۍT//eN饤3l8 8uTƕW@Ya(;-P8]y0ȤXI|s@4姴nN! ՟H&z3=s.Jj[Yz aW1$ɔErm]OyЉɧu2J<'[.lMKp*0L*JJK)3W^NUi1%1&~*k))-k3:aQ\@iI1Ec$UPZZNЕat,AҒ"ʋÄKYb UEWG&ZJ)/)8i'5QT TXAcYWS[Uct2Nz 67Hie+/4w,"\oB֚ѱ1B:\k$N?yǛjl|/:RR\T7PٹC&/XJeYvvflO@;!g_|Ne̚;Ona\Hd` l U*We lZmfttPHBqU($㚢Ƽz&C&;%@ϯf@K%Իӯgw}:J纔dEA5޻ߵh[0wYu׶-,;*izײ@3m[XL0Xv˲5ٶRIzPh;Hʕ-Y*[?ε )}"J144LScj !W`YmgQ]]5/`Y]]TVV^' CV жM'xԬcZI"uuIKl︭w^>J! Nmpec;=_K~s]JOM‰/Y^m]fumYس+pmceֽa&f/nN9.q]Z_u!t}ȷ-cG#ISc!⃑WB! vs+hz'uB!B048XqYy[n.<}!B!fv.I!B! lk] !7+ _]J*q!7 \GRI<4k]!7˲p<^a NC.B!.s)R` iYH!3"ȓ@Up806>% ba9&EEE VK :p8]b!II>PQ^~!&uCHB!nLR !׺B!B!͑@B!B!"SCm_"!I!vDlac(b)(/ /"BkH˲ u#&Lb!CK5Zkn,by3u&B|IwuEB!B\]hDRa0y5>58\s00.|@sQm^!B!ĵ6ё~::{-l[c:]8M?HqI !j&8 > ۶x w0N5J}i\rm 4 !B!J_ݬi.DžElbqʖn[Wj:RJ_;W j{n{"35Ȯ;y(+ ^}qe[p(8p gQ#[ ZpvMP/ho[hJi2I*jċ"gxzf 3Ī[neE]%!B!xO @V5=$w3zo_8qc/K߼CMEPZߖҌ`"/Q:4+5ϓgv#,a(RQ_W8?{'rp t$yA%ZQ1&ϲWO'|ꀓxA~,Wmˋ(QQ1Ξ?i*4ĆNS/sV8 $2ve B!2tָ||qȏy?{ tu!sy~W?yC 3 !*7 C!!P\6XZvMlkOП!*ضևxߣOmA6JmgW-P*Эt^≣N~ﳷpƅ`RL& 7l wⲧXߞ}7G|x0-@kū>͋o~=v2ȄMAx rYi1%|U '^{%% B!,xQGh-,j;߲rgs޿#]I [W8?>On?Eksm`brgQ#,&X$Js}r+^a`le E(;6ž7w1ZBg}06)~Y]Cb,NImw;.F:–m'rM?/g!Z5{u So8Dp!]1/LyQ!/$f%+bR:o4;|f֕%(D)u:VPk/ɮ6"1N~WNDXj-<j<U4V(j蝔&y_>ۋWG~|+їMZff%bk\q%#Iq% 9J)"/.H$x5]" !:smC0[ƦŬYx4J< xx(-Ta^9:E}S9y^/ᚥ| eeeB C>Lx$Qz{H.?㧜raOHzh @9Z^|uui *aG>[Z|><|*++( b^&袔Af7O$P!d.\0 \aa0`0ZZ])7?5>>O__?T/Bww7%E׺B!\J)IGTm,GźLr  32iӴ|5yf./ؖ}|-rv~8 VoaͬoR֊yakvq~(FS a '2h]Y31̙s,37f. 7:мbRA;7p:L=Jܶ &aY*i_7RAjCNl[B1[◿~@ ˲CRTT(B!caF\ܾP 39{Spx} ,|~_vUJr8ZsCŝ.7.ׇhyet:0nʛTbbzmc ٲ6ʜl(9IA)M}sWrՄ<&Љ$mJO)f^`(e{r<R[]NhLvTxj|欯W'.ڒl[^ƬḄ5ɶYxJ)z B!<($D08Gw/_mpF:y'y;⧵awu^w~ǿyI^rH6Koey9'mLd h̫ Zh1b88e;oX,+X%K\%zI^w}H"Q|4t<5O"4 H Ӕn /'8};I`SoO2隼Oh:Zs2yg_Kϑ_ۭ$]x@?u>F4Gibc ur[ƘHHL%.Z~aK_A^y͛Ctqz]s!>@Aɕe1ZsyqȎu`>LU""Wac{ꗿHEy.""""M o(^8weNs icrsg3 '-Yʴ).uTԸ"'9~*vsS]ֻc2P߸w_$"|6_"rӴӜ=s~zh|~v/!ac-S-]mgrw9S@Um9}nGؿyetelPGuAS-LⴵtQq^ݿcnfyPpiNxv^ }""7/@wCS. UF}cP ujK3O2PF]u| ͺ}di9:< lTdžܱ,o!GHz)߼ R^b"6RWQpt_f,fC=5Ѣ@|pgs̜"PP^Φ K3T@ u\GOGocSt71JLBVZZٰ/_)""r{s]|!ZVz{c `vIGޏl5xx^nqrGZϛ{q=>#7agޛ#Jv-@P$=\IW=o ?37duiřLA[t:z]]9xPDDDDDϵ \שzo7[<¬GNɏq{( 6.uxY mh @DDDDDD6u0AzR Rs  1)8f4p qrGFoSDD*+*掋ۓn1o߼rnAKr q,.H1b*j7Om_z;Sq\#_1ƙ>؉Lf,~tfw"""""_dLT4M?:ٞ}<-:ln~F&x@4tx 2cpnRY"]ū,_K{_K^7۟l빧&%)*+$h6Q[V[e Pp9(9.,჎^N MMԔh{$Cݶl^2/{)w"9j,8gy;՗y;xtKlإK& TD T|KRT`xT?=JUewl$ OLZʪ7P=LH"""""gd8D7͆́cmq49qh`lYL1P;;pUE188Fs֔>ncV?~ RS[>F{3Y,aŸSC47lz쟰oKζ \,D6~p$p^{O~ |!$ +׺-25:Hb]t',-!s3C7:^y<>UX5+/Қѽ{xGx򉇨yum Xv{U 65scdGz81HiCNr0Ze: &r>[Px?~0CiY~&e^o ?AB{y !?7ľOq[~k$7-/)qOM>/wĥ!28ñIܹϚY琌qh+>ɥF&X/ dmNWן~^}5;40D<%bxxJʣpx}qZz=5 jy~>Wrd+U3ɲ&xŷRgx]vkezr/$Hۻ[~#q&91ͩI7yj[)YbL.Bfnmppd5|Y)8.֏DDDDD$,L6lK_*Ts3=d '釚+L11 =$ZpR)b2Dwf WA78^q?Y߈,;Nev:LǧgW4x91{XBTF`=ofypRF<;3k>?~`6'ϛOp~!XsU f\|g?Sl<I:[/Ďj3t[.E7c3 r?Lɋ#Ml~.a༶<2i.OJ35@DDDDD5h҂u||.6sQTw1u J*(/ pY&v7=rwxȆZ`)|l7<эkvmD`d0IUԖfglc 15F 󱭵̦Ckk1B(E;SdVXqdւMdp9`K7yt'>nL2I2^QBAq5cazҹS 4Y;ڮ{!R@Y~v3lnNH>%5 """""yz:Rn2Co7o^g@Eʇځ {l v#vv1F"18ҍ{5?ǃwHl(y>$ωo'ݰp*X.|SD|Q3g08 >%۟]lDi&s]*6.mBzjv#gcQ9~% /C͎H?y#G LeI&O2$sw|뇎p[DJK rm=jw'8#|(=鹣%ƵS}3?@nd"S\ȇC,6F(" i2q3QV[OmyƂMOzqqhvw߱ga|%4ԔjhilwKuJ+PUEUE{[kQVVJAU bn Lq U4Fq&hE~/|װ6B#Sn;Yxuƈ.h,FAA@؍t|2I/ɥnZ8E*XC>'MiZ'T;vQv4HaǝwXUxO+:/a |Dk(a ˙`xҥfNvo#)Q`c\*aSC=2?×.1m ٲNjK/wyF-};111A$Y}XXj|%zǤ""""""9K%˿|2vֳy"@DDDDDqH&.:k=_$I1Kv}>dslK9DPfWH$8Y H^RYYAWw###7:7c Vޝϱ; rWp^QݯDDDDD$oѴL&srCc.c/.)cu)O"""""71ovUn+3k;8O+SDDDDDDDn#i+n |RəZf!""""""rHR8/;`%22:Jll\DDDDDDDn!P^^1ﱯ" PS]}c%eVyjZ [N  EDDDDDD#?Ͽ^|E>ϝ^ٵ΋/Gcc """"""gIENDB`Eqonomize-1.5.3/doc/html/C/figures/unpayedinterest.png000066400000000000000000000631041416454732000227700ustar00rootroot00000000000000PNG  IHDRQ;YgAMA a cHRMz&u0`:pQ<bKGDe6IDATxwx}U@7r$ᐓ85#mɒ:ػ{<׾Ϲ+=ڵrPH4I $9GsjUt}Ix쮮/!B!Ƨcx$rG!!?:_ 1#B߉o|_ߝT ~"#L~V!T0? cd2 `]=B!%2}2W$BB$B,$/Bd!@k}9khRr^gRW"Y>14<﬐H&юb(D3M\!.9 PTTC WF)phIRJ)la%u]V ^k{|p*lX  R<,˒/KB[edN~*9%|87Wrt=nn9ޫ;+ e(޴ZL!E]Y+-n#7 G&prG'pzSw$!P*w~ůo|ߵm#WJ3>{iOobk7sX8\ϭQ"]aB(t|s߽wŻ/̱!ƻ↮VjZ5F;^)~s;if#|vm-tw179Bq\Y ^kO # cV9Ef.ETVUszH3&3hGO cTߙ^5*δf:ydU2H8eQM 8 r53TUfeq<~ x(./<"-=]3oj|lr٩6}U`rXh>s9:{~&דyI朙Y髾9ꃄz6xPAkG+2qcb(c*\cxƊ1rcjbc)l{L;#Rxݚ1"'&v(c1,LrrCn 1'b,/H^\(7 Ň)@^|-Tl'/X?Ac[Gl;ʇVȁt;|w]Eƻٺy 0p׮ 0"mh꤫m=A=kA H60w1ƊMO8{әdUmd|[^{~4tm6An&\Uy"̚%Dz9qdO*s$n>E8V2Fw'q~tD?M$ArbQjmuH+BkVz_eݮfgw)-L[0㟟C忳CƟ]x H9}&A(k] ^FN|7~c-W= uwYw~֭]|} *1Fӡ]vJnWtu7mG?C̩oFohd2x [C0Jĕ'hJ 22p<w190:Eg,*"H0o0l!VA-a/)+FǩF:.fyhg'177ճdK㗷qu Uˋ8m,AїG;6żRbl],+'kBlv  :-X߰qQxEy^Pј5YΩ8A糨mC4xs 6}R_z;V!IX[@Ac;S{9npl/u =:i(HWi|" ?ᎍm+*>,&T[h~RGYM-%vD ˟!H=AjdmE^9رfW<}K k0]nDQXAaU=EZXq\.ɖut];ݳ!o\ jj7a:/%?KEu-uX4m!y6l4p{xn 4QY^Da3px#qpR4GZJEImJR"=9ȒU> kޅaJ !y]qVTi۶./ٶ0ݣq4i8J!j%_Q0[7/n=IBy f=IvttQ)krpu3a1/TbA3M7P.c1'K3Af8)GI2ڸ[yc1tX ?~b:FRvOs*n=/=ӁcU7S:ڶN5p{ A?n`)GMǯPHI12E,Ƕl'Mi9>T !\-S N^SU@_ŒnФ5kO6Ռζ}D=YaLQr uCD00M< 2!f @KNOSvf~=y|r%ljV^ٻMAar(.LqڇJ}y:c8xXDZIwjK9Z^6zf_ke_m9ԃa(²mD2܄ shm8JcL޶bArJjX|% =#t҅Y4_7w~?[9ԏxt LHX)I!~r;Ntm[Op+=DuN%I$)L(qI!a'$)l`, Kpuak1oX'hS7;^b9#}EAq)8xm?F,$6%hcLZqR:l+E*$H8G]z{TI>D Jt,vT"E;x_?z}N0n }_‘;tGBq~/_76f~kllP^Wh{?1KAy U&-v`;I8>?n5`)US\ME`=2%XZK}E!C|фIe}=1Ké9sx޵Tpi3rYxhy[ch҅5yMzqz N D;;F$PV;|J籰EK)Os{?u ݻ{0!Οgw1`*b~M1.5)FƈFNf3pWSl>E[9Ḙ8pw+#BU (,2䢯]#xe̛WC&'\3MSk7+nLcߛJprpHeJݓAfB+v40q\*ݦl[nfp(2,kΨ6 NL2_!2]f2:pHo]ci2atJ;Xr2ӎe Lca;sޕ21]Xvf!a,p۶ALlc|±tiǦ8qgfh0M״LiRUyBdgás^r99:;P όk:pBj'g{Ԏ+⎻ǖ- zZ8=hYmw&J2Ȗ9<@uJzzO3~~ŞŚ&9v#qmE,] hSt5d޽*NEi9q}q֕3|Cƣ<-M{ZcY6n̘uqpOF뫒d E5AZ4~O 9/8L7H?m/X2w~3̙SM0 _ϱ{'IM/8[:luz"x|AAGhQ:AGoaW!(/>:]1Vc^?{!r}^ 3‰'ܶ^;b`W9G{8V"=3SNvzq,,XϬdD{8GHrό'V21'SyؓcO\eaz*ẍ́C!(?%goar̘fwc {1dW/'톑anw|8L=0B٨t]|h"mF=pswlP02oAAJ5|Ď ajjq<IOeM2DqlRJqF{籢T~=՞/;9oo n VM=HII1sf(J@ ;-eXGﷲ3_ŸBlXǮ7~;N2,HH4apD5bAIt#KZN-;%䅸dZCْ/?j|!]10L\i85݇מH x2x[R:Ӌ^]˶RhmDh rrpMFx' V~{N.SȠdKq_̀y5ŘNX4F,FX|B d<2HC+4˖ů|7-eAMw?EZZk|%~k~m.'x'Y77HCc+} M]T8qbMFXRܳ&'4/6LwOQMQY9%hTlhӍ㧸L v3,?1:Q畎vBR& &bc32pq\CsXdB* wP0NxO LEe笀]D)x(m'=y̭(4=c8Z SZ 0ErJ!|,B qZ%3>!ד:7;qӆI]!%x!nIB Bbd7|&;!v36>.qHYh.:N:::,/uf0O$/-3gN%iB\ma\l'&/-vxn!ઍf%Cnҋ^!BR$w!nWkDT* dznT qLmgnN!BVW0(3wrI)5IHvi|Y xH_7=#ۅisBs\*!,R C(ɏ je(#Mpp*(0K酈M)E*o ST\߭پRJiarNۖ,q󚽀l'Ol'bnIac.ȆK֣A!! :M"I/e^M1B-vH9t'bQQKx; y/:P:EkdDXvm,*@boo?//@ =f-O?~A3wR vНgIm! @h>{q 3]hL,Oܜf'˙_f/|XX)F;s~ڴqE"Lq ꔂS;'Yt]T"ٳ >sBNaۋǸ _h;Aɝ|_~ķNusԅ-+X rqZ:I}aF9 ϽSɇ02 ͷS? o/X\[Bl}5^ߎuud yQܴfFka1rxX9ElytK?!1NMۦGD,~Z俅‰Xd ^hOtF]w_ 5o۶qpSd_n9{i{:&xhb9(Ge׳v4hi[4\&XKLn1E^lDtN>5g~󹧞 pKU&#P{?-Ggݧػw/|AU1ܼ~qa,^G5@ө 2:~9WV6X\>n eSvs| ,0)4ws{U3k-=BnS7؎ImXU:{eb48NST.\]yǛ[{$eUS27NQZ 3Hf> Ph0\TΥW'=#Qrsb6/S_2*XڕS'HHU7PFkiqιI":ڠ }Mc߻`тZzO9@R ;]Γ [?/ȞqH#?s;N(?~0 m"ey!.xHXd TҚ$h_Xぞ4vI_ضI07g͔GYVZ xryLz ~30u7s{k6ԏv1nfջR 2 :ǟdEeN:^SVo5TU6Xx"6OH$ST,p=&M}&Ghc`"5Ϋ?9/n!'uj*K ˶GOM/uɋq`6v>E 5c1;ۗQrq q!J)FGG|M?&N|3wSPiEqB|h]C cG/}yAe-8@Ww?I˜**]89<;5/O|W;9|7owk)- v}1:%<=ҽ&;8g;[e,e~M)ܦ"Ҷ?hfO07-.fRB  ۳>s'go_G"֠lbĬPDkCWVRZ'+m:OsgPy-m}K,ʼnE8Ĉ奲ξ1bjj㴟,0\”RwtPY^N0*M8 PSlXw[UJh t QUYF3mXpct=0A nm%ikt_j*KΌK7@k[;%Ÿ Ep'f)XauZ&㠵0ԙ4 ӯU2GLFaWt}np!MBldEUU%!?FFQN^Ȍ. ؓdWxm|cOP ю>k7ڙ1 YE2n&3maaOov۶~csTsβB/eUᙻ]Niїr ]k"/aq/ &"eZ!B$B,$/Bdk2Uq4]HבR)&G6 x!n!Zk d$=4Vq)CQщp>) x!n1iRZZrwCqIB$B,$/Bd! x!" I';!n1e108H2dלPaଯ]^[R!rABυ2{zz>TN^[LJ zO?1u ߔⲾ }Bq)H+o6GlrDZcWIe`(Mt-/_?UzǙ (;^[ ivS~byJJ1q^|^ˋ:Ώ#i}uou.ZWJ?cIR/!2)oQj.F GT>H`!Ew;Xx1sqr~Z@{>̀CeW//>faSymk Uwpb vsNcۯ_Ѩg.ʢ 9`3/`jn_[C7x U)EOo// / [DeݬkA`ά.юh;E,%OL%&qjal"Jr2U.DX,F"ieKm&OZLXxX"F2Vmk+ʱ_1& m+W㞼B!.B}#O81|,ް} JN9HcJ%8}7#j|hGQd j"9=dArr^=9ʁ@9w}7yե!X'ؿwq8_pOO/:s_m:$krgu w+YE}nr7?Sw-o ǩggE>)@k(ѱ#1款s8oorAwn!g-ot{qFȭ[}k7cA67w>c<_w(D#oݍᔏBšX|xR< gcةw:5@ D҂q#}40Q&)Pgڥ֘]STXqx'HYkrZkeRV9YpYf0D~|>/.Ӆ/$7k| eX~b\ ̧?‚k{a!c?d$P/ǏͼyQa8f~]_Rwpk/99AOl73B\?+~ÿ|5??\_9Oj8:nAI)m`.g:i0]n4dҚںa4p=XeO80Law㡲|}5߯;Uրnw4>ni?m+B!>3}R׹=M88$VUTVՒg֩Y)/ơc1NE0zsv~G]!?Q.KoWsxx,,paб^vКDƬ e7t"7A{GV6e+oK|{Uf^CJH.כxlGSTVSLܕ5Α*7xMml򘷪ht)[G#.K:;v49{h$P0z9voCG؞D<%CY>ǍR.90>EoHxr>kty!~ gb}ަ10 xuNEȃc_־Ibߞ]ly{;]w>@5<Ј# Z\vCpWh.SO᝜LR:9ĢgnMܿ@gaFS`'s®suMӠxѱ1Rhh7߾f|ؘ91B %Kvx7~$T{#xa=a#®-[q _E- vc&l7eϣȾi")KXf^2p)եAڎe&Fb6eԔv}>:JK[Uܻf!+#hl8@9fr EQJ1::J^n.z9Ξ}'8v=c,G[Kߡqǯ}#-ܳmrl7. \BU>4;A{o7bAn-meZCY^jH+;jka;>ÓCUe!}in:<)\.*9‰H%|m;׭e%3  1MD"|.췾sO/#|kZIuuy62:F D8p8tD&, \\&#2 mh;є%7ED"IGn^.~IMt|X/H^nxt8p"11K#s]RYI)E{GAy9ݹT%8!66h,ӗ sC`da<!rpyrLNTk'OBNnWNF`[FS(P(n~44ae,DqqytSR\)zx&?:w\Y\1Y5?9ڀ6z3sܴ}㟳eCOd+ xqQfTЙ^PMw.1̟6u>+E,c" ?]^ع'οJ9=zswD↢q&="S m}8k/1]E|kB!f^t=_&dB!B$B ے6x!n1J)l۾fB\8Sf5<޻#-qM+_Y$rmW&"J)|>yfrB܂~/޻! < !.Nz !YHJB܂7QM//-Fk8)+uwE[~;떀 0::zS !²-)/+%(FGG),,$/773p x!g>Xl !fErK008&]埌ű ׅ t|җOKr5.Y&5 T皞!ĥГ?gR Pgszk"M8~J'i=O?8.^ 323@K0yMζY*'i=w?Fw;`?|S {JrJI:1fPZUIW)am+ mѴUH_> V[ XEKq>Ovc\lR^]I5Xn0~1o !.MIu񓼻Ux5} V&4)1qP`!5~o:=B\Y*+9B!J)@ \nVB8oFSI{^%zniT3No]3_4Iלsӫ.Y|\awlNo"ۜ3\dwILS ϼwR9CxJ,-4;+NJ5W>sM{/NWμ]'DR].3C2J<}nt b)%eq=p9E&D`0ɏ !X&.$CQ'R,r J( P&Ƈ%嘄K(HF iYxs ( 1sʕR$'" M:C6N24DPQ)~v(kSR^AqTt8'(?eltDXtxJc(PVmh&" FqP (0F+NʼnDxFI*7N|hR*4=6@W0FnUex\&J;ךePvy|xL{ҤbmrrfFG3_rCDS@5)DK-™>0?k?oZo`o;to7>lͯ?Ay9Ƃ{ [yp% Z)YMÕ_1V.^D*\\Zy?O!/3_wsjAszAz%\$Sp!Բou=C8/<)|*>f3@'tY>8>Kh"R)),LՖD,‚3 _լd8+w׬7tp| }JrT_~,s%+-#? kWvW"H2DS{? o X͝r;cI%k[X[ޓxgwW_`Y=Q#9{ KK1$kex3=R$[x(\4-5xo d)Baw90Α~EA7qpyXm4 JMUOVh=P)hwbǗťS$ A)eYܹ0֯v100ŋ((ȿ1XÏ=I_CLmͿ|_|r_ғn) QRYIIA#ǣO=ʇ_-ThΓ p4_§XTNv5Dk_d]U.<ȓ.cZMɝU`:'<|.ƃA"e;4 PPV `ixpӓ 3p 3T?Hc0>6ch=[CV66~^K[xcw#_KeE)Wr; ܿגTڨyȑ-A_1Cvlh;Ƌ?9?ߠ>Oyi>f:zV՘iw) }糟fxL%/;୷EX`n~R-\8svhP.7@`N9 X83XR<çDSge$19њ@ayJ`i&@ߏ?23%ɦ3 SL>E;?,mm^D<@+ :~|6Bc|^7+u;^z;;o\L0>6Bm 0Ǟ4e8c=ܾv?vX:ÓʻeR= NgZ#̣vx! 5%%<#<#ܵΩ\-VEoĢ$::OW_tѻ{QFw'({*~Eac!N52οolP^@CSfrkဏҺ)rtΡ8,$y._y9u Ee,0?@g;c%K)&̙SKa~>8JRY]K/H[P̯!cw#^~m!owSZEue%,"d)OWM/!6Ʈ]{Jv)."Oa65 ?ᅢ[k>$]qr]vSJ144v.'h?v=GZ.t#'{_pO? u"] {ᤇjÊp{ӗCjR'ع4UΡ2px?G*|\4!nL+  < 1 N~<物{줺rl{j" ¥41 4q&0L#sҘScr3;t`3̍// 0ЎםYғ̐ޞiLM۷m0͙ۜqo1p&*3יzlMT6Gim] `';nY >M7o[ӏ%32sn&9̱]ݰ#<Ù^E>JzJ)' ;uQ\*ST:KtT盆~fR s201.J娘j*!5y  c5>r[Mzصrjǻ`+bj+)-)n՝U>AզR?Vh6Jq8YpF,iq̹;u](OO~MXn>Cqe`j9DGq}(n@n"'WQyB׍7+>B䤫H 5!8Hve`pHz4vln7Wx x!n!Zm*5XLj̈́i~u\V rQRRr[!%? +ݘB! E/Bd! x!" ]vB:OR}+ǑBX*D"Y9I (,(Y_ x!I)Dp\TVT\ݹ*,ˢC~~eBc;x<LʪjǃBaYeBd;t6\|[?Bq(JWENv$%x!oGr)PP* ~v.WeSc۳wƸG&A=c HwSJs9R 00H 82283K{v gBq#_Z)졩aӃ&ں: 0y'tt+{4{.p }cIH'N;:A*STɂ(-}me(AQ"g5y&ãP\bnQ+dر<BЉv8=cޒe\E$vq^c XbynsSGof_eYl?FN/;klfS@~F:Nqu(r~/7 VSczps/?`Ӳ Ӓ$ 7R*]U:/TjV3}nuZ;h4}g|mWVc8Bq3KSM ͪ˿t_Iqϼ09p7Rt$8uQ&"RpBnl%nDhX}&n OdWVRVWGvpְZ^qfy弩m८$knz/7tx=mL8(+`d1mzGkcB 6&޹m'U:Is1W:;|/< C`xsI#$=z KgJ:]~Z~pG r:^j +)@Ćs4IGeǑBdc@&Akp(ȋ5p o2ڼQv4sSνl;,=8{0.!.%ޮ̬M_d ǹHCÇM?5bͽK|_Jy~kB:)ن9R?x7Zkmk0Gw`&vf7q6zqr) z|1Tr;36ѐw$  xEnr\9Te^çHXghmՎYXN]u .+;_~o_y8|ǐBZ:$gv28bz۰ov#=s$M 9:^,bj~7{iʙq|9wm0 V%|v 6h!j98Ctw_XٍyڱHS$6d m/Oyޢk4qiSol!)G)E?$gemkÜhlVr~%9F{"ϡ&h38=pm3uQ;w.%'vmg>bϩv<.:NHcPʥn.(o@AVcVG Q?:7 K>ˢ57ŋ )OrqNjs@bz |;xr+'z<m{qMyu5,'goex$7O!e(Egw7aPTXxщgJ%H&-4 ˅FtJ4ndvzR Re)KxӷqU*]M&SZ,d(Ӎ>orcS3__0Ф )PכX7 Ne4JxLCeljS`pY^yBz !DәYLsd|܅כ8unYX5g, OL{3}kLtMH !,,~_d'7LoF۔%I !.SN*z!ey5ESV>Bfv7[/BܤNKYV֖`mF;~^!nbtvuF;V>K!/7)5@rYL)>93~$&"''+r7iB!B$B,$/Bdw0B!2}K<ǀ !xGP* B!֚ !B!B!B!B!d4%tEXtdate:create2017-10-09T15:01:22+02:00%tEXtdate:modify2017-10-09T14:08:50+02:00ziPtEXtSoftwaregnome-screenshot>IENDB`Eqonomize-1.5.3/doc/html/C/import_export.html000066400000000000000000000154661416454732000212040ustar00rootroot00000000000000Chapter 8. Import & Export of Transactions

    Chapter 8. Import & Export of Transactions

    QIF Files

    Files using the Quicken Interchange Format can be read by most personal money management software. The format is however old and has limitations, which means that data might be lost during import and export.

    QIF Import

    Select FileImportImport QIF File and follow the instructions. QIF is a file format that might differ much depending on the software that saved the file. How much details you will need to provide about the file depends on ambiguity of the date format, how localised the file is, and how well accounts are defined. Securities, investment transactions, memorised transactions, budgets, and classes are not imported.

    QIF Export

    Activate FileExport QIF File and select account to export, format for dates and numbers, and filename. It is possible to export transactions from all accounts, but multi-account QIF files are not always supported by other software. Not all transaction properties are exported.

    CSV Import

    This function imports data files with clear text values in columns separated by a character (comma, space, tab, etc.), with a new transaction on each row. Select FileImportImport CSV File and enter details about the structure of the file you want to import. Transaction parameters can either be imported from a column in the file or a set to a specified value.

    CSV or HTML Export

    Every account and transaction list in Eqonomize! can be saved to a HTML or CSV file. HTML files are suitable for display in a web browser and CSV (comma separated values) files can be opened in most spreadsheet programs. Use FileExport View or the corresponding toolbar button to save a list of accounts, expenses, incomes, transfers, securities or scheduled transactions. The displayed values will be exported (for accounts and securities the current time period is used and for transactions the current filter and sort order is adhered to). The ledger can be exported using the Export button in the upper left corner of the ledger window.

    Merge Eqonomize! File

    Accounts and transactions from another Eqonomize! file can be imported to the current file using FileImportImport Eqonomize! File. All accounts and transactions from the file will be copied. When the file has been selected you will be presented with alternatives for handling of duplicate transactions, accounts, categories and securities. If you select the rename options ("imported") will be appended to the name, otherwise the transactions will be added to the already present accounts with the same name. This makes it easier to distinguish and manipulate imported transactions. (For information on how to modify/move mmultiple transactions at the same time see the section called “Edit Multiple Transaction Simultaneously”.)

    Eqonomize-1.5.3/doc/html/C/index.html000066400000000000000000000205721416454732000173720ustar00rootroot00000000000000Eqonomize! Manual v1.0.0

    Eqonomize! Manual v1.0.0

    Hanna Knutsson

    This manual describes version 1.0.0 of Eqonomize!.

    Feedback

    To report a bug or make a suggestion regarding the Eqonomize! application or this manual create a new issue at https://github.com/Eqonomize/Eqonomize/issues.

    Abstract

    Eqonomize! is a personal accounting software, with focus on efficiency and ease of use for the small household economy. Eqonomize! provides a complete solution, with bookkeeping by double entry and support for scheduled recurring transactions, security investments, and budgeting. It gives a clear overview of past and present transactions, and development of incomes and expenses, with descriptive tables and charts, as well as an approximation of future account values.


    Eqonomize-1.5.3/doc/html/C/introduction.html000066400000000000000000000106021416454732000207750ustar00rootroot00000000000000Chapter 1. Introduction

    Chapter 1. Introduction

    Eqonomize! is a tool for keeping track of and monitoring personal finances. This means entering of everyday expenses and incomes – when you buy something, receive salary, pay bills, transfer money between bank accounts, invest in stock, etc. Eqonomize! provides tools for making this process as easy and efficient as possible. You can then effortlessly retrieve information and statistics about your financial situation. You will for example be able to easily identify major leaks, and direct saving efforts to the right areas. You can also monitor performance in relation to a budget and check what your choices might mean for your future wealth.

    The purpose of this manual is to describe how to practically use Eqonomize! for those who do not find the graphical user interface self-explanatory, as well as document some less obvious efficiency-enhancing features and explain how Eqonomize! interprets the data you provide.

    When using Eqonomize! for the first time you should read Chapter 2, Getting Started.

    Accounting with Eqonomize!

    The basics principle behind accounting in Eqonomize! is the idea of money flowing through transactions between accounts as reservoirs. A transaction represents a gain (you receive money), loss (you buy something), or transformation (you withdraw from or deposit in a bank account) of money.

    A transaction always means that money is moved from one account to another. An expense (something is bought) can for example mean that you pay with cash from your cash account. The money is then put in an expense account. This account represents the products and services you pay for. It represents the money that you do not have as a result of expenses, and is therefor useful for record keeping.

    Incomes is usually put in a bank account and withdrawn from an income account. This means that income accounts will have a negative value, but to avoid confusion, the value of income accounts are shown as positive values.

    Different income and expense accounts are used for categorisation, and are therefor more naturally referred to as categories. Other accounts, which represents the money you actually have and often represents real world bank accounts, are simply referred to as accounts.

    Eqonomize-1.5.3/doc/html/C/securities.html000066400000000000000000000155611416454732000204440ustar00rootroot00000000000000Chapter 5. Securities

    Chapter 5. Securities

    Securities represents money invested in stock, bonds and mutual funds. Eqonomize! does not differentiate between different kinds of securities, even though the terminology used is better suited for some. Securities and associated statistics are displayed in the securities view.

    The create a new security in Eqonomize! use SecuritiesNew Security or the New Security button. First select an account. Securities are associated with an account of securities type, which cannot be associated with ordinary transactions. Enter name of the security and select type. Specify initial shares if you do not want to back-track all transactions (it is always preferred to use transactions instead, for better statistics), and enter a quotation with associated date.

    Automatic updates of stock quotes are not supported. You will have to update the value per share manually (using Set Quote or Edit Quotes in Securities or context menu) for the security value to be up to date.

    Security Transactions

    The following transactions are supported for securities:

    Shares bought

    When additional shares of a security have been bought or received (as an income). Specify two of number of shares bought, price per share and total cost (including fees/commission), and select an account (if bought) or income category (if received).

    Shares sold

    When some shares of a security have been sold or given away (or used as payment). Specify two of number of shares sold, price per share and total income, and select an account (if sold) or expense category (if given away).

    Shares traded

    When shares of one security are sold and shares of another security are bought for the same amount of money, without transfer of income to an account in between.

    Dividend

    When money is received for each share of a security. Specify income and income category.

    Reinvested dividend

    When dividend is received as additional shares.

    All shares bought and sold are listed as transfers (listed in the transfers view), unless recieved/given away (in which case the transaction are listed as an income or expense), and dividends as incomes (in the incomes view). You can list all transactions associated with a single security using SecuritiesTransactions (or the context menu).

    The Securities View

    Statistics displayed for each security:

    Value

    Value at period end date date (quotation * shares).

    Quotation

    Price per share at period end date.

    Shares

    Shares at period end date.

    Cost

    Total price paid for all buys minus sells, at end date.

    Profit

    Profit during the period (value + dividends - cost).

    Yearly Rate

    Percent increase of value per share (for a share bought at the beginning of the period), during the period on a yearly basis. Includes dividends.

    In the total statistics displayed below the security list, quotation and yearly rate are weighted based on the value of each security.

    Predictions are simplistic and based on previous development, with respect to dividends and quotations, only. Future quotations are calculated using quotations during the nearest past time. The quotation one month from current date is assumed to have increased at the same rate as during the past month (or the date before with a specified quotation). Dividends are always predicted using full past years (they are assumed to occur on a yearly basis).

    Eqonomize-1.5.3/doc/html/C/statistics.html000066400000000000000000000172451416454732000204600ustar00rootroot00000000000000Chapter 7. Statistics

    Chapter 7. Statistics

    You can get an overview of your economical situation by using the charts and reports accessible from the Statistics menu.

    Categories Comparison

    The categories comparison report allows comparison between or within expense and/or income categories. The initial view shows all categories with subcategories hidden, with values for the past year. The display settings can be changed at the bottom of the window.

    The source can changed to also display every separate subcategory, or only show a single category. If a specific category is selected, you will have the option to compare the values for subcategories, different transaction descriptions or payees/payers. The data can be broken even further down by only comparing descriptions for a specific payee/payer, payees/payers for a specific description.

    Below, the period shown can be selected. For dates extending into the future, scheduled transactions are included in the value, but not budgeted incomes/expenses.

    Finally you can select which columns shall be displayed. Displayable columns include total value, averages based on different time periods (e.g. the daily average equals the total value divided by the number of days in the selected time period), total quantity, and average value of each item (total value divided by total quantity).

    The buttons in the upper right corner allows you to save the view as a HTML file or print it on paper.

    The categories comparison chart displays the same total values as the report, but in a pie or bar chart. The chart type and style is selected in the upper right corner of the window.

    For the chart you can select (in the lower right corner) to display all expense or income categories (with subcategories shown or hidden), or a specific category. If a single category is selected, the data is divided into subcategories, or (if there are no subcategory) into different transaction descriptions. Here you will also have the option to compare the value of different accounts (assets).

    As in the report you can select the time period values are shown for (for accounts the from date is ignored). In the upper right there also here buttons for saving (to an image file), or printing the chart.

    Click on a sector, or the corresponding title in the legend, to show it exploded (separated).

    Development Over Time

    The development over time report shows values for each separate month and year. Initially total profits (incomes minus expenses) are shown. Below the table you will have the option to show expenses or incomes separately instead. These can be further broken down into separate categories and transaction descriptions. Note that payments that reduces a debt are not counted as expenses.

    At the bottom of the window displayed columns can be selected. The columns include total value, averages based on different time periods (e.g. the daily average equals the total value divided by the number of days in the selected time period), total quantity, and average value of each item (total value divided by total quantity). The buttons in the upper right corner allows you to save the view as a HTML file or print it on paper.

    The development over time chart shows how expenses and incomes change over time, with values grouped by month, in line or bar chart. The chart type and style is selected in the upper right corner of the window. Initially incomes and expenses are shown from the month and year of the first transaction to the the end of the last budget month (unless the first and last month are the same).

    The time span displayed can be changed below the chart. Bar chart can at most display one whole year at the same time. For future dates scheduled transactions are included, but budgeted incomes/expenses are only included when all categories are combined (including the profits source).

    Below the table you will have the option to show profits(expenses minus incomes) or specific categories. Categories can be shown combined or separately ⸺ all with separate lines/bars or only one. Categories can be further broken down into transaction descriptions and separate payees/payers. There is also an option to display total accumulated assets and liabilities (the Assets and Liabilities source).

    The char can show the total values for each month, the daily average (within each month), the total quantity, or average value per quantity each month. Daily averages compensates for the different number of days in month, but this is offset by the fact that large expenses and incomes often occur monthly.

    Click on a label in the chart legend to hide a data series from the chart. Move the mouse over a line or a bar to show details above single values. Click, hold and move the pointer (drag) to zoom in the chart. In the upper right there also here buttons for saving (to an image file), or printing the chart.

    Eqonomize-1.5.3/doc/html/C/transactions.html000066400000000000000000000612031416454732000207670ustar00rootroot00000000000000Chapter 4. Transactions

    Chapter 4. Transactions

    Expenses, incomes and transfers

    Eqonomize! has three different basic transactions types – expenses, incomes, and transfers.

    Expenses represent a loss of money, a transaction where you give away money, mostly in return for something else. This can be a payment for products and services, or a gift.

    Incomes represent a gain of money; when you are given money. This is when your at the other end of an expense, when you receive payment for products and services you provide (often as salary for your regular job), or when someone gives you money as a gift.

    The third transaction type, transfer, represents neither a loss nor gain, but a transfer of money from one account to another. This can for example be when you withdraw money from your bank account as cash, or when you transfer money to a savings account. Loans, and loan payments reducing the debt, are also transfers (from a liability account to an assets account, and vice versa), even though Eqonomize! provides alternative methods for recording these.

    Each transaction has a number of mandatory or optional properties. All the basic transactions have four mandatory properties – value, date, and from and to accounts/categories. Value represents the amount of money that is affected by the transaction, date when the transaction occurred, from account where the money was taken from and to account where money was put. These are the generic property names, which shows that all transaction types basically are the same.

    For expenses the value is a cost, a positive value representing a loss of money, from the account that the expense is paid from, to an expense category. For incomes the value is an income, a positive value representing a gain of money, from an income category, to the account that the income is deposited in. For transfers the value is referred to as amount, or withdrawal (from an account) and deposit (to an account).

    Table 4.1. Mandatory Properties

    Generic

    Expense

    Income

    Transfer

    Value

    Cost

    Income

    Amount (withdrawal and deposit)

    Date

    Date

    Date

    Date

    From Account/Category

    Account (account)

    Category (income category)

    From (account)

    To Account/Category

    Category (expense category)

    Account (account)

    To (account)


    All transactions do in addition have three optional properties. The description property provides information about the nature of the transaction. This can be considered a final level of categorisation (you get enhanced statistics and increased efficiency if you keep the description consise and without inflections, and reuse it for similar transactions).

    The comment property is used for any additional information, not used for categorisation, about the transaction. If you for example buy a pair of shoes, you might create an expense in a clothing category, with the description Shoes and comments Shiny red Pradas.

    The third property, associated file, allows you to specify a link to a file on the computer which will be connected to the transaction. This will typically be receipt, invoice or payslip, but any file can be selected. The file will not be moved, copied or modified. If the file is moved or renamed outside of Eqonomize!, the file will not be accessible from within the program.

    Expenses have two additional properties which can be shown or hidden using SettingsUse Additional Transaction Properties (deactivating this option will not permanently remove any data from already entered transactions). The quantity property denotes how many entities was involved in the transaction. This can be a whole number, as in two CD's, or a fraction, as in 0.56 kg apples (units are not included). This property is by default set to 1 and does not affect the value (the value per entity equals value divided by quantity). The payee property represents the person or entity, for example the store where goods where bought, which receives the money. Incomes have a similar payer property, representing the one who gave you the money, for example your employer.

    The Transactions Views

    The transactions views show a list of expenses, incomes or transfers. By default all transactions (including scheduled transactions, shown in italics) up till and including the current date are shown, sorted in falling date order. The sort order can be changed by clicking the appropriate column header. Transactions with the same date are shown in the order they were entered.

    Statistics are shown immediately below the list. These numbers summarises all transactions currently in the list, unless two or more transactions are selected (in which case the numbers only refers to selected transactions).

    Filter Transactions

    Below the list of transactions is a section for filtering transactions. By default the tab for editing transactions is shown instead. To show the filter tab, click on Filter above the input fields. This enables you to select which transactions are shown in the list above.

    You can filter transactions based on date, value, account, category, description and/or payee/payer. Unless the exact match box is marked, text in the description and payee/payer fields will be matched against any part of the of the corresponding transaction properties, including comments in the case of the description field. You can opt to show all transactions that do not match (all) the filter criteria, by activating Exclude instead of Include.

    Create/Edit Transactions

    New transactions can be entered in two ways, either with the new expense/income/transfer dialogs (accessed from context menus, the Transactions menu or the toolbar), or from the transactions views, below the transaction list. The edit a previous transaction either double-click the transaction (there are further options in different menus) or select (single-click) the transaction in the transactions view and change the values in the fields below the list. Notice that you have to press Apply or the changes are lost.

    Both the Enter key and the Tabulator key, on the keyboard, can be used to move to the next field. When in the last field of column (in the transaction edit dialog this is the last input field; in the transaction view this refers to both the date field and the comments field), the Enter key will however instead confirm the entered values (equivalent to pressing OK in the transaction edit dialog, or the Add button in the transaction view).

    When entering a previously used description in the description field, all are other fields (except date) will be automatically filled with the values of the last transaction with the same description. This requires that the current value in the value/cost/income field is zero. If the description field is empty, the category and payee/payer fields exhibit a similar behaviour.

    The Value Input Field

    The input field for transaction values support basic arithmetic calculation. Addition, subtraction, multiplication, division and exponentiation are supported and uses standard order of operations (1+2*3 equals 7, not 9).

    Currency conversion is also supported. Currencies will be converted to the currency of the currently selected account of the transaction. Note that the currency symbols used for conversion must be unambiguous. Symbols used for multiple currencies are not allowed (e.g. $ is used by many currencies, and you should therefor type USD instead for conversion from U.S. dollars), except for the main currency.

    By default the value field uses the current currency as prefix or suffix. This can be omitted when entering a new value and is ignored when using currency conversion (expressions similar to £5 € are allowed).

    If arithmetic or conversion have been used, the calculated expression is copied to the comments field, if empty.

    Edit Multiple Transaction Simultaneously

    It is possible to change the value of one or more properties of multiple transactions at the same time (e.g. if you want to move some transactions to a new subcategory). Select the transactions you want to edit in the transaction list and select Edit transactions (Occurrence) from the context menu or the Transactions menu. A window will open with a list of properties that can be changed. The fields are prefilled with the values of the first transaction. Next to each property is a box for marking each property that will be changed. Properties with equal value for all selected transaction are marked for change by default. Enter new values for appropriate properties and click OK to make the change.

    Refunds and Repayments

    You should enter a refund instead of an income when you receive money as a refund for a previous expense. This can for example be if you return a product and get your money back, or if you buy a present that you and your friend will give to a mutual friend, and you receive your friends share of the cost later.

    The create a new refund use TransactionsNew Refund/Repayment or the context menu with the refunded expense selected in the expense list. You will have to enter the amount of money refunded (initially set to full refund) and the date of the refund. In addition you should specify the product quantity returned by you. In the first expample above this is clearly 1, but in the second case this is less clear. It can either be 0.5 if you count it as a half product, or 0 if considered a whole gift (none returned). The use is more obvious if the quantity property is activated for all expenses and incomes. The refund is recorded as an expense with negative cost and quantity.

    Repayments are similar tto refunds, but is used for incomes that you have been forced to repay.

    Split Transactions

    Split transactions are used when a single transfer to/from an account is used for multiple transactions. This is not when money is withdrawn from a bank account through an ATM and you go shopping (that is first a transfer from a bank account to cash, then multiple regular expenses). A split transaction will for example be appropriate when you make a single payment for multiple products (especially if they are categorised differently), or when you pay with your credit card in a store and tell them to withdraw some extra money, which you get as cash in your hand.

    It is up to you how and when you want to use split transactions. Multiple ordinary transactions can be used with the same end result, even though one way might represent reality better.

    A split transaction can be created from scratch using TransactionsNew Split Transaction or from the context menu. It is however often more efficient to use the join action. This way you can enter transactions the usual way and later join them in a split transaction. Select the transactions to join and activate Join Transactions from the Transactions menu or the context menu, and enter a description. All transactions in a split transaction share a common date, account and payee/payer.

    To reverse the action and transform transactions in a split transaction to ordinary transactions, select a split transaction and use Split Up.

    In the transaction list (ledger) for the account associated with the split, the split will be shown as only one transaction, but everywhere else the parts of the split will appear as ordinary transactions. You cannot edit a transaction that is part of a split transaction directly from the fields below the transaction lists. Instead you should press Edit to edit the whole split transaction, or double click the transaction in the list to edit the separate transaction (excluding the common date, account and payee/payer properties of the split transaction).

    Expenses with Multiple Payments

    Expenses with multiple payments are similar to split transactions, but instead of using a common date and account, they share description, category, quantity and comments. The intended usage is for when multiple payments, primarily from different accounts, are made for a single product/service. They should not be used for payment plans/loans (although an expenses with multiple payments is created for expenses with downpayment).

    Expenses with multiple payments can be created using the TransactionsNew Expense with Multiple Payments or by selecting Multiple accounts/payments in the account menu for an expense.

    Expenses with multiple payments will show up as a single transaction in the expenses view, but as multiple transactions in the ledger. Similarly to split transactions they cannot be edited directly from the fields under the expenses list.

    Note that even if you create a recurring expense with multiple payments where each payment has a different date, all recurrences after the first occurrence will use the same date for each separate payment. If a future date is set for the first, or only, occurrence, the program will only ask for confirmation of the expense on the first date.

    Expense Paid with Loan

    An expense paid with loan is not actually recorded as a specific kind of transaction, but is a shortcut for creating a debt account and an expense with multiple payments (or a regular expense if downpayment is zero). Expenses with multiple payments can be created using the LoansExpense Paid with Loan or by selecting Paid with loan in the account menu for an expense.

    Enter the usual expense properties (account excluded), an optional lender and optional value and account for downpayment (represents the amount of money you pay immediately).

    Debt Payments

    Debt payments are a third kind of combined transaction. These group together repayment, interest and fees. Ordinary transactions can also be used for these purposes. Interest and fee are expenses and loan reductions are transfers.

    Debt reduction represents the amount you (re)pay that actually reduces the value of the debt. Interest represents the amount the debt has increased (before debt reduction) and may or may not be paid directly. Fee usually represents an administration fee added to each bill. You only need the enter one of the three values (the other can be zero).

    LoansNew Unpaid Interest also creates loan payment transactions but provides a simplified dialog when the debt has increased because of added interest.

    Transactions in a loan payment cannot be edited separately.

    Scheduled Transactions

    A scheduled transaction is a transaction that is planned to occur, and thus it has not occurred yet. It is basically just a transaction, of any type, that has a date set in the future. When a scheduled transaction has occurred, it becomes a regular transaction. Scheduled transactions makes it possible to keep track of and be reminded of future transactions. Eqonomize! will ask for confirmation when the transaction is expected to have occurred.

    A scheduled transaction can be recurring, thus it will regularly occur on a certain date or with a certain interval. This is useful mostly for bills and salaries, which then need not be entered manually each time, and you can check Eqonomize! for upcoming payments. When a recurring scheduled recurring transaction has occurred, a regular transaction is created, the occurrence date is removed from the recurrence, and the scheduled transaction date is moved forward to the next occurrence. If you modify the properties of a recurring transaction, the previous occurrences will not be affected and vice versa. A scheduled transaction with no occurrences left is removed.

    Single occurrence scheduled transactions are create just like ordinary transactions, except with a future date. Recurring transactions can only be created from the transaction dialogs (opened from the schedule view, toolbar buttons or menu items, or when double clicking a transaction), with recurrences specified in the second tab.

    The next occurrence of each scheduled transaction is displayed in the schedule view. You can edit or delete either the single occurrence or all future recurrences. If a single occurrence is edited, it will be created as a separate transaction, and any changes made to recurring transaction will not affect this occurrence. If the date is changed to the current or a past date, the scheduled transaction becomes an ordinary transaction.

    When a scheduled transaction is due, when the current date has gone past the date of the occurrence (or same date after 6 pm), Eqonomize! will ask you to confirm that the transaction really has occurred. You are then given the option to accept the transaction as it is, make some changes (for example the cost of your telephone bill might vary slightly), or postpone it. If the scheduled transaction is not postponed, it will become an ordinary transaction.

    Eqonomize-1.5.3/doc/html/C/using-eqonomize.html000066400000000000000000000251321416454732000214110ustar00rootroot00000000000000Chapter 2. Getting Started

    Chapter 2. Getting Started

    The main window consists of six different views. When Eqonomize! is started, the accounts view is shown. To change view click on the corresponding icon in the horizontal list above.

    Create Accounts

    The first time you start Eqonomize! a predefined set of accounts and categories are already present. These can be considered an example or a starting point for a setup matching your own conditions. You can either begin by modifying the suggested accounts and categories or start from scratch with FileNew (Ctrl+N).

    Accounts should be created to match your real world bank accounts plus at least one account for cash. Categories are used to keep incomes and expenses better organised. Each transaction must be connected to an account and a category, or two accounts for transfers between accounts. To create accounts and categories use the Accounts menu or the context menu of accounts view. Accounts and categories can also be added as needed when entering new transactions. A monthly budget can be set for each separate category.

    Enter Transactions

    Now it is time to start recording transactions each time money have been deposited or withdrawn from one of you accounts. If you have kept book before, either on paper, or in another program, you can either import a file from another program (see Chapter 8, Import & Export of Transactions), enter each transaction manually by hand, or start from scratch (remember to enter the correct opening balance for each account).

    Transactions can be entered in two ways, either using the new expense/income/transfer dialogs (where you have the option to create a recurring transaction), or from the transaction views. The latter option is usually preferred.

    The first time you record an expense you should follow these steps:

    1. Switch to the expenses view, using the top icons. The input focus is now in the description entry.

    2. Type in a description for the expense. You are free to use the description property as you want, but I suggest you keep short and consistent without any inflections, as a final level of categorisation, for optimum efficiency and good statistics. For example, if you buy a delicious red Ingrid Marie apple and have an expense category for fruit, the description will be Apple, and if you want to record additional information put Delicious red Ingrid Marie apple as comment (others might find it more appropriate to use Groceries as category and Fruit as description). Press Enter or Tab and focus will move to the cost entry.

    3. Enter what you paid. Note that the value should not be negative (except for refunds) and you do not need to type any currency. Press Enter or Tab.

    4. Optionally enter a quantity (if you bought multiple apples). Note that the previously entered value is the total cost and independent of the quantity. This and the payee field can be hidden from the settings menu, if not used. Press Enter or Tab.

    5. Select the date when the transaction occurred. To change the date, either write a valid date, select one from the pop-up calendar, or increment/decrement the current value with up/down keys. If you now press Enter, the new expense record will be created, but we do not want do that this time since the current account and category probably are not correct.

    6. Select the correct account (where the money for the expense is taken from) and expense category from the drop-down lists on the right. (If you have not yet added the category and/or account, select New expense category or New account from the top list.)

    7. Optionally enter a payee (the store where you bought the apple).

    8. Optionally enter a comment (memo) for the expense.

    9. Click Add or press Enter.

    Note

    Enter adds a transaction if pressed with input focus in the date or comment entry. Otherwise it moves input focus to the next entry.

    Repeat the process to record another expense. When you enter the next (and all subsequent expenses) expense you can however usually do it more efficiently. Date, account and category will not be reset each time, so often you need at least not change account. More importantly Eqonomize! remembers the last expense entered for each unique description. When you enter a description, all values, except date, will be filled in with the properties of the last expense with the same description. Even more so, as you type the description a list will pop up with all previous descriptions with matching opening letters. This means that you often will follow this much shorter process:

    1. Type the first letter of a description and select the correct one from the list.

    2. Check if the cost is the same this time and press enter.

    3. Press enter to move past the quantity field, if enabled.

    4. Check the date and press enter.

    The same process as for recording expenses is repeated for incomes, except that the quantity field is absent. Click the incomes icon on the left and enter an income instead of a cost (still positive, but instead means amount deposited, added, to the account).

    To record a transfer from one account to another (for example an ATM withdrawal from a bank account to cash) follow the same process as for expenses and incomes. Click the transfer icon on the left. Enter the amount transferred (positive) and select the from account (withdrawn from) and the to account (deposited to).

    Saving

    When you have made some changes you need to save your work. Save the file using FileSave (Ctrl+S) or the corresponding toolbar button. The first time your work is saved Eqonomize! will ask for a location and name for the file. Eqonomize! will then automatically open that file each time the program is started.

    If when closing Eqonomize! there are some changes that have been made after the last save, you will be asked if the file should be saved before closing.

    Before the file is saved, a backup copy is made with the name prefixed by ~. Also the current data is continuously (at most once per minute) saved to prevent data loss in case Eqonomize! exits unexpectedly.

    Eqonomize-1.5.3/eqz_file_format000066400000000000000000000171621416454732000165740ustar00rootroot00000000000000The Eqonomize! accounting file format (EQZ) The file is an xml file encoded in UTF-8 with doctype EqonomizeDoc. It should begin with The top element is EqonomizeDoc with attributes version (Eqonomize! version), revision (integer, last revision of file), and lastid (64-bit unsigned integer, the highest id in the file). Subelements: synchronization budget_period currency category account security schedule transaction Schedules and transactions should be listed last. Common properties ----------------------------------- revisions: The revisions attribute specifies the file revision when the transaction was created (before ':') and last modified (after ':', if differs). The revisions attributes is optional. id: The id of each new transaction must be unique and higher than the 'lastid' specified by the loaded file. timestamp: Unix time when the transaction was created. The time stamp is specified in microseconds in Eqonomize! <= 1.3.2, but changes to seconds in later versions. Synchronization ----------------------------------- attributes: type (text string, ignored) autosync (boolean integer) revision (integer, synchronized revision) elements: url download (command) upload (command) Budget period ----------------------------------- elements: first_day_of_month (default: 1) first_month_of_year (default: 1) Currency ----------------------------------- Specifies the default currency for the file. Defaults to local currency. attributes: code (three letter ISO 4217 currency code) Category ----------------------------------- attributes: id name (text string) type (text string) description (text string, optional) revisions (optional) types: expenses incomes elements: budget category (only one level of subcategories is supported in Eqonomize!) budget attributes: value (floating point) date (a full date in ISO 8601 format) Budget values are specified monthly using the first day of the month. Months without a specified budget uses the budget value of the previous month. A negative value (-1.0) unsets the budget. Account ----------------------------------- attributes: id name (text string) type (text string, optional) group (text string, optional) lender/issuer/bank (text string, optional) currency (three letter ISO 4217 currency code, otional) initialbalance (floating point, optional) budgetaccount (boolean integer, optional) closed (boolean integer, optional) revisions (optional) description (text string, optional) types: current savings credit card liabilities securities cash other (default) If type is not set, then type is 'other'. If type is 'securities', initialbalance and budgetaccount is not allowed. budgetaccount can only be set to true for one account. If group is empty automatic grouping based on type is assumed. Use "-" to specify no group. Security ----------------------------------- attributes: name (text string) type (optional) account (account id of a securities account) initialshares (floating point, optional) decimals (integer, optional) quotationdecimals (integer, optional) desciption (text string, optional) types: bond stock mutual fund other (default) elements: quotation quotation attributes: date (a full date in ISO 8601 format) value (floating point) auto (boolean integer, optional) Transaction ----------------------------------- common attributes: id (64-bit unsigned integer, optional) type (text string) revisions (integer, optional) timestamp (integer, optional) date (a full date in ISO 8601 format) comment (text string, optional) file (a file location, optional) tags (comma separated text strings) links (comma separated 64-bit unsigned integers) types: expense/refund income/repayment/dividend transfer balancing reinvested_dividend security_buy security_sell security_trade multiitem (or deprecated 'split') multiaccount debtpayment attributes for expense: description (text string, optional) cost (floating point) income (negated alternative to cost) quantity (floating point, optional, default 1.0) category (expense category id) from (account id) payee (text string, optional) reconciled (boolean integer, optional) attributes for income: description (text string, optional) income (floating point) cost (negated alternative to income) quantity (floating point, optional, default 1.0) category (income category id) to (account id) payer (text string, optional) security (security id, optional, used for dividends) reconciled (boolean integer, optional) attributes for transfer: description (text string, optional) amount (floating point) withdrawal (used instead of amount if accounts uses different currencies) deposit (used instead of amount if accounts uses different currencies) from (account id) to (account id) reconciled (boolean integer, optional) attributes for balancing: description (text string, optional) amount (floating point) account (account id) attributes for reinvested_dividend: category (income category id) security (security id) value (floating point) shares (floating point) sharevalue (floating point) Two of value, shares and sharevalue are required. attributes for security_buy: account (account id) security (security id) cost (floating point) shares (floating point) reconciled (boolean integer, optional) attributes for security_sell: account (account id) security (security id) income (floating point) shares (floating point) reconciled (boolean integer, optional) attributes for security_trade (common attributes does not apply): date (a full date in ISO 8601 format) from_security (security id) to_security (security id) from_shares (floating point) to_shares (floating point) timestamp (integer, optional) attributes for multiitem: description (text string, optional) account (account id) payee (text string, optional) elements for multiitem: transaction (date, from/to, payee/payer is set from multiitem attributes) attributes for multiaccount: description (text string, optional) quantity (floating point, optional, default 1.0) category (category id) elements for multiaccount: transaction (only incomes and expenses allowed; category and description is set from multiaccount attributes) attributes for debtpayment: debt (account id) from (account id) payment (floating point, used when currencies of accounts differ) interestpaid (boolean integer, optional, default true, 'interestpayed' occurs in Eqonomize! < 1.3.2) expensecategory (expense category id, optional) reduction (floating point, optional) interest (floating point, optional) fee (floating point, optional) In Eqonomize! > 1.3.2 type is not strictly required for expenses, incomes and transfers, value can be used instead of income/cost/amount, and to/from can be used instead of category. Schedule ----------------------------------- attributes: id (optional) revisions (optional) elements: transaction (mandatory) recurrence (optional) recurrence attributes: type (daily, weekly, monthly, or yearly) startdate (a full date in ISO 8601 format) enddate (a full date in ISO 8601 format, optional) frequency (integer, optional) attributes for weekly recurrence: days (a list of days of week numbers beginning at 1 with no whitespace or other characters inbetween) attributes for monthly reccurence: week (week of month, can be negative to count from end) and dayofweek; day (day of month, can be negative to count from end) and weekendhandling (0=none, 1=before, 2=after, 3=nearest, optional); attributes for yearly reccurence: dayofyear and weekendhandling (optional); month, dayofweek and week (can be negative); month, dayofmonth and weekendhandling (optional); recurrence elements: exception exception attributes: date (a full date in ISO 8601 format) Eqonomize-1.5.3/flags.qrc000066400000000000000000000131471416454732000153050ustar00rootroot00000000000000 data/flags/AED.png data/flags/AFN.png data/flags/ALL.png data/flags/AMD.png data/flags/ANG.png data/flags/AOA.png data/flags/ARS.png data/flags/ATS.png data/flags/AUD.png data/flags/AWG.png data/flags/AZN.png data/flags/BAM.png data/flags/BBD.png data/flags/BDT.png data/flags/BEF.png data/flags/BGN.png data/flags/BHD.png data/flags/BIF.png data/flags/BMD.png data/flags/BND.png data/flags/BOB.png data/flags/BRL.png data/flags/BSD.png data/flags/BTC.png data/flags/BWP.png data/flags/BYN.png data/flags/BYR.png data/flags/BZD.png data/flags/CAD.png data/flags/CDF.png data/flags/cent.png data/flags/CHF.png data/flags/CLP.png data/flags/CNY.png data/flags/COP.png data/flags/CRC.png data/flags/CUP.png data/flags/CVE.png data/flags/CYP.png data/flags/CZK.png data/flags/DEM.png data/flags/DJF.png data/flags/DKK.png data/flags/DOP.png data/flags/DZD.png data/flags/EEK.png data/flags/EGP.png data/flags/ERN.png data/flags/ESP.png data/flags/ETB.png data/flags/eurocent.png data/flags/EUR.png data/flags/FIM.png data/flags/FJD.png data/flags/FKP.png data/flags/FRF.png data/flags/GBP.png data/flags/GEL.png data/flags/GGP.png data/flags/GHS.png data/flags/GIP.png data/flags/GMD.png data/flags/GNF.png data/flags/GRD.png data/flags/GTQ.png data/flags/GYD.png data/flags/HKD.png data/flags/HNL.png data/flags/HRK.png data/flags/HTG.png data/flags/HUF.png data/flags/IDR.png data/flags/IEP.png data/flags/ILS.png data/flags/INR.png data/flags/IQD.png data/flags/IRR.png data/flags/ISK.png data/flags/ITL.png data/flags/JMD.png data/flags/JOD.png data/flags/JPY.png data/flags/KES.png data/flags/KGS.png data/flags/KHR.png data/flags/KMF.png data/flags/KPW.png data/flags/KRW.png data/flags/KWD.png data/flags/KYD.png data/flags/KZT.png data/flags/LAK.png data/flags/LBP.png data/flags/LKR.png data/flags/LRD.png data/flags/LSL.png data/flags/LTL.png data/flags/LUF.png data/flags/LVL.png data/flags/LYD.png data/flags/MAD.png data/flags/MDL.png data/flags/MGA.png data/flags/MKD.png data/flags/MMK.png data/flags/MNT.png data/flags/MOP.png data/flags/MRO.png data/flags/MRU.png data/flags/MTL.png data/flags/MUR.png data/flags/MWK.png data/flags/MVR.png data/flags/MXN.png data/flags/MYR.png data/flags/MZN.png data/flags/NAD.png data/flags/NGN.png data/flags/NIO.png data/flags/NLG.png data/flags/NOK.png data/flags/NPR.png data/flags/NZD.png data/flags/OMR.png data/flags/PAB.png data/flags/PEN.png data/flags/PGK.png data/flags/PHP.png data/flags/PKR.png data/flags/PLN.png data/flags/PTE.png data/flags/PYG.png data/flags/QAR.png data/flags/RON.png data/flags/RSD.png data/flags/RUB.png data/flags/RWF.png data/flags/SAR.png data/flags/SBD.png data/flags/SCR.png data/flags/SDG.png data/flags/SEK.png data/flags/SGD.png data/flags/SIT.png data/flags/SKK.png data/flags/SLL.png data/flags/SOS.png data/flags/SRD.png data/flags/STD.png data/flags/SVC.png data/flags/SYP.png data/flags/SZL.png data/flags/THB.png data/flags/TJS.png data/flags/TMT.png data/flags/TND.png data/flags/TOP.png data/flags/TRY.png data/flags/TTD.png data/flags/TWD.png data/flags/TZS.png data/flags/UAH.png data/flags/UGX.png data/flags/USD.png data/flags/UYU.png data/flags/UZS.png data/flags/VEF.png data/flags/VND.png data/flags/VUV.png data/flags/XAF.png data/flags/XCD.png data/flags/XOF.png data/flags/XPF.png data/flags/YER.png data/flags/ZAR.png data/flags/ZMK.png data/flags/ZMW.png Eqonomize-1.5.3/icons.qrc000066400000000000000000000657241416454732000153340ustar00rootroot00000000000000 data/index.theme data/scalable/eqonomize.svg data/scalable/eqz-account.svg data/scalable/eqz-balance.svg data/scalable/eqz-categories-chart.svg data/scalable/eqz-categories-report.svg data/scalable/eqz-currency.svg data/scalable/eqz-debt-interest.svg data/scalable/eqz-debt-payment.svg data/scalable/eqz-edit.svg data/scalable/eqz-expense.svg data/scalable/eqz-export.svg data/scalable/eqz-import.svg data/scalable/eqz-income.svg data/scalable/eqz-join-transactions.svg data/scalable/eqz-ledger.svg data/scalable/eqz-liabilities.svg data/scalable/eqz-next-month.svg data/scalable/eqz-next-year.svg data/scalable/eqz-overtime-chart.svg data/scalable/eqz-overtime-report.svg data/scalable/eqz-previous-month.svg data/scalable/eqz-previous-year.svg data/scalable/eqz-refund-repayment.svg data/scalable/eqz-schedule.svg data/scalable/eqz-security.svg data/scalable/eqz-split-transaction.svg data/scalable/eqz-tag.svg data/scalable/eqz-transactions.svg data/scalable/eqz-transfer.svg data/standard/application-exit.svg data/standard/document-new.svg data/standard/document-open.svg data/standard/document-print.svg data/standard/document-print-preview.svg data/standard/document-save-as.svg data/standard/document-save.svg data/standard/edit-clear.svg data/standard/edit-copy.svg data/standard/edit-delete.svg data/standard/edit-find.svg data/standard/go-down.svg data/standard/go-jump.svg data/standard/go-up.svg data/standard/view-calendar-day.svg data/standard/view-refresh.svg data/standard/preferences-desktop-font.svg data/standard/preferences-desktop-locale.svg data/standard/mail-attachment.svg data/16/eqonomize.png data/16/eqz-account.png data/16/eqz-balance.png data/16/eqz-categories-chart.png data/16/eqz-categories-report.png data/16/eqz-currency.png data/16/eqz-debt-interest.png data/16/eqz-debt-payment.png data/16/eqz-edit.png data/16/eqz-expense.png data/16/eqz-export.png data/16/eqz-import.png data/16/eqz-income.png data/16/eqz-join-transactions.png data/16/eqz-ledger.png data/16/eqz-liabilities.png data/16/eqz-next-month.png data/16/eqz-next-year.png data/16/eqz-overtime-chart.png data/16/eqz-overtime-report.png data/16/eqz-previous-month.png data/16/eqz-previous-year.png data/16/eqz-refund-repayment.png data/16/eqz-schedule.png data/16/eqz-security.png data/16/eqz-split-transaction.png data/16/eqz-tag.png data/16/eqz-transactions.png data/16/eqz-transfer.png data/standard/16/application-exit.png data/standard/16/document-new.png data/standard/16/document-open.png data/standard/16/document-open-recent.png data/standard/16/document-print.png data/standard/16/document-print-preview.png data/standard/16/document-revert.png data/standard/16/document-save-as.png data/standard/16/document-save.png data/standard/16/edit-clear.png data/standard/16/edit-copy.png data/standard/16/edit-delete.png data/standard/16/edit-find.png data/standard/16/go-down.png data/standard/16/go-jump.png data/standard/16/go-up.png data/standard/16/help-about.png data/standard/16/help-contents.png data/standard/16/system-run.png data/standard/16/tools-report-bug.png data/standard/16/view-calendar-day.png data/standard/16/view-refresh.png data/standard/16/preferences-desktop-font.png data/standard/16/preferences-desktop-locale.png data/standard/16/mail-attachment.png data/32/eqonomize.png data/32/eqz-account.png data/32/eqz-balance.png data/32/eqz-categories-chart.png data/32/eqz-categories-report.png data/32/eqz-currency.png data/32/eqz-debt-interest.png data/32/eqz-debt-payment.png data/32/eqz-edit.png data/32/eqz-expense.png data/32/eqz-export.png data/32/eqz-import.png data/32/eqz-income.png data/32/eqz-join-transactions.png data/32/eqz-ledger.png data/32/eqz-liabilities.png data/32/eqz-next-month.png data/32/eqz-next-year.png data/32/eqz-overtime-chart.png data/32/eqz-overtime-report.png data/32/eqz-previous-month.png data/32/eqz-previous-year.png data/32/eqz-refund-repayment.png data/32/eqz-schedule.png data/32/eqz-security.png data/32/eqz-split-transaction.png data/32/eqz-tag.png data/32/eqz-transactions.png data/32/eqz-transfer.png data/standard/32/application-exit.png data/standard/32/document-new.png data/standard/32/document-open.png data/standard/32/document-open-recent.png data/standard/32/document-print.png data/standard/32/document-print-preview.png data/standard/32/document-revert.png data/standard/32/document-save-as.png data/standard/32/document-save.png data/standard/32/edit-clear.png data/standard/32/edit-copy.png data/standard/32/edit-delete.png data/standard/32/edit-find.png data/standard/32/go-down.png data/standard/32/go-jump.png data/standard/32/go-up.png data/standard/32/help-about.png data/standard/32/help-contents.png data/standard/32/system-run.png data/standard/32/tools-report-bug.png data/standard/32/view-calendar-day.png data/standard/32/view-refresh.png data/standard/32/preferences-desktop-font.png data/standard/32/preferences-desktop-locale.png data/standard/32/mail-attachment.png data/48/eqz-account.png data/48/eqz-balance.png data/48/eqz-categories-chart.png data/48/eqz-categories-report.png data/48/eqz-currency.png data/48/eqz-debt-interest.png data/48/eqz-debt-payment.png data/48/eqz-edit.png data/48/eqz-expense.png data/48/eqz-export.png data/48/eqz-import.png data/48/eqz-income.png data/48/eqz-join-transactions.png data/48/eqz-ledger.png data/48/eqz-liabilities.png data/48/eqz-next-month.png data/48/eqz-next-year.png data/48/eqz-overtime-chart.png data/48/eqz-overtime-report.png data/48/eqz-previous-month.png data/48/eqz-previous-year.png data/48/eqz-refund-repayment.png data/48/eqz-schedule.png data/48/eqz-security.png data/48/eqz-split-transaction.png data/48/eqz-tag.png data/48/eqz-transactions.png data/48/eqz-transfer.png data/standard/48/application-exit.png data/standard/48/document-new.png data/standard/48/document-open.png data/standard/48/document-open-recent.png data/standard/48/document-print.png data/standard/48/document-print-preview.png data/standard/48/document-revert.png data/standard/48/document-save-as.png data/standard/48/document-save.png data/standard/48/edit-clear.png data/standard/48/edit-copy.png data/standard/48/edit-delete.png data/standard/48/edit-find.png data/standard/48/go-down.png data/standard/48/go-jump.png data/standard/48/go-up.png data/standard/48/help-about.png data/standard/48/help-contents.png data/standard/48/system-run.png data/standard/48/tools-report-bug.png data/standard/48/view-calendar-day.png data/standard/48/view-refresh.png data/standard/48/preferences-desktop-font.png data/standard/48/preferences-desktop-locale.png data/standard/48/mail-attachment.png data/64/eqonomize.png data/64/eqz-account.png data/64/eqz-balance.png data/64/eqz-categories-chart.png data/64/eqz-categories-report.png data/64/eqz-currency.png data/64/eqz-debt-interest.png data/64/eqz-debt-payment.png data/64/eqz-edit.png data/64/eqz-expense.png data/64/eqz-export.png data/64/eqz-import.png data/64/eqz-income.png data/64/eqz-join-transactions.png data/64/eqz-ledger.png data/64/eqz-liabilities.png data/64/eqz-next-month.png data/64/eqz-next-year.png data/64/eqz-overtime-chart.png data/64/eqz-overtime-report.png data/64/eqz-previous-month.png data/64/eqz-previous-year.png data/64/eqz-refund-repayment.png data/64/eqz-schedule.png data/64/eqz-security.png data/64/eqz-split-transaction.png data/64/eqz-tag.png data/64/eqz-transactions.png data/64/eqz-transfer.png data/standard/64/application-exit.png data/standard/64/document-new.png data/standard/64/document-open.png data/standard/64/document-open-recent.png data/standard/64/document-print.png data/standard/64/document-print-preview.png data/standard/64/document-revert.png data/standard/64/document-save-as.png data/standard/64/document-save.png data/standard/64/edit-clear.png data/standard/64/edit-copy.png data/standard/64/edit-delete.png data/standard/64/edit-find.png data/standard/64/go-down.png data/standard/64/go-jump.png data/standard/64/go-up.png data/standard/64/help-about.png data/standard/64/help-contents.png data/standard/64/system-run.png data/standard/64/tools-report-bug.png data/standard/64/view-calendar-day.png data/standard/64/view-refresh.png data/standard/64/preferences-desktop-font.png data/standard/64/preferences-desktop-locale.png data/standard/64/mail-attachment.png data/22/eqonomize.png data/22/eqz-account.png data/22/eqz-balance.png data/22/eqz-categories-chart.png data/22/eqz-categories-report.png data/22/eqz-currency.png data/22/eqz-debt-interest.png data/22/eqz-debt-payment.png data/22/eqz-edit.png data/22/eqz-expense.png data/22/eqz-export.png data/22/eqz-import.png data/22/eqz-income.png data/22/eqz-join-transactions.png data/22/eqz-ledger.png data/22/eqz-liabilities.png data/22/eqz-next-month.png data/22/eqz-next-year.png data/22/eqz-overtime-chart.png data/22/eqz-overtime-report.png data/22/eqz-previous-month.png data/22/eqz-previous-year.png data/22/eqz-refund-repayment.png data/22/eqz-schedule.png data/22/eqz-security.png data/22/eqz-split-transaction.png data/22/eqz-tag.png data/22/eqz-transactions.png data/22/eqz-transfer.png data/standard/22/application-exit.png data/standard/22/document-new.png data/standard/22/document-open.png data/standard/22/document-open-recent.png data/standard/22/document-print.png data/standard/22/document-print-preview.png data/standard/22/document-revert.png data/standard/22/document-save-as.png data/standard/22/document-save.png data/standard/22/edit-clear.png data/standard/22/edit-copy.png data/standard/22/edit-delete.png data/standard/22/edit-find.png data/standard/22/go-down.png data/standard/22/go-jump.png data/standard/22/go-up.png data/standard/22/help-about.png data/standard/22/help-contents.png data/standard/22/system-run.png data/standard/22/tools-report-bug.png data/standard/22/view-calendar-day.png data/standard/22/view-refresh.png data/standard/22/preferences-desktop-font.png data/standard/22/preferences-desktop-locale.png data/standard/22/mail-attachment.png Eqonomize-1.5.3/po/000077500000000000000000000000001416454732000141125ustar00rootroot00000000000000Eqonomize-1.5.3/po/eqonomize.pot000066400000000000000000005241611416454732000166550ustar00rootroot00000000000000msgid "" msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Language: sv\n" "X-Qt-Contexts: true\n" #: ../src/accountcombobox.cpp:228 msgctxt "AccountComboBox|" msgid "New account…" msgstr "" #: ../src/accountcombobox.cpp:229 msgctxt "AccountComboBox|" msgid "Paid with loan…" msgstr "" #: ../src/accountcombobox.cpp:230 msgctxt "AccountComboBox|" msgid "Multiple accounts/payments…" msgstr "" #: ../src/accountcombobox.cpp:193 msgctxt "AccountComboBox|" msgid "New income category…" msgstr "" #: ../src/accountcombobox.cpp:211 msgctxt "AccountComboBox|" msgid "New expense category…" msgstr "" #: ../src/accountcombobox.cpp:329 msgctxt "AccountComboBox|" msgid "New Account" msgstr "" #: ../src/accountcombobox.cpp:313 msgctxt "AccountComboBox|" msgid "New Income Category" msgstr "" #: ../src/accountcombobox.cpp:321 msgctxt "AccountComboBox|" msgid "New Expense Category" msgstr "" #: ../src/transaction.cpp:947 msgctxt "Balancing|" msgid "Account Balance Adjustment" msgstr "" #: ../src/budget.cpp:198 msgctxt "Budget|Name of account for transactions that adjust account balances" msgid "Balancing" msgstr "" #: ../src/budget.cpp:444 ../src/budget.cpp:745 ../src/budget.cpp:1435 #: ../src/budget.cpp:1466 ../src/budget.cpp:1606 #, qt-format msgctxt "Budget|" msgid "Couldn't open %1 for reading" msgstr "" #: ../src/budget.cpp:751 ../src/budget.cpp:1443 ../src/budget.cpp:1474 #: ../src/budget.cpp:1612 #, qt-format msgctxt "Budget|" msgid "" "Not a valid Eqonomize! file (XML parse error: \"%1\" at line %2, col %3)" msgstr "" #: ../src/budget.cpp:1204 ../src/budget.cpp:1238 ../src/budget.cpp:1274 #: ../src/budget.cpp:1298 msgctxt "Budget|" msgid "imported" msgstr "" #: ../src/budget.cpp:455 ../src/budget.cpp:752 ../src/budget.cpp:1447 #: ../src/budget.cpp:1478 ../src/budget.cpp:1613 #, qt-format msgctxt "Budget|" msgid "Invalid root element %1 in XML document" msgstr "" #: ../src/budget.cpp:486 ../src/budget.cpp:1314 ../src/budget.cpp:2077 #, qt-format msgctxt "Budget|" msgid "Unknown XML element: \"%1\" at line %2, col %3" msgstr "" #: ../src/budget.cpp:451 ../src/budget.cpp:498 ../src/budget.cpp:515 #: ../src/budget.cpp:1329 ../src/budget.cpp:2084 #, qt-format msgctxt "Budget|" msgid "XML parse error: \"%1\" at line %2, col %3" msgstr "" #: ../src/budget.cpp:492 #, qt-format msgctxt "Budget|" msgid "Unable to load %n currency/currencies." msgid_plural "Unable to load %n currency/currencies." msgstr[0] "" #: ../src/budget.cpp:1412 ../src/budget.cpp:2169 #, qt-format msgctxt "Budget|" msgid "Unable to load %n account(s)." msgid_plural "Unable to load %n account(s)." msgstr[0] "" #: ../src/budget.cpp:1416 ../src/budget.cpp:2173 #, qt-format msgctxt "Budget|" msgid "Unable to load %n category/categories." msgid_plural "Unable to load %n category/categories." msgstr[0] "" #: ../src/budget.cpp:1420 ../src/budget.cpp:2177 #, qt-format msgctxt "Budget|Financial security (e.g. stock, mutual fund)" msgid "Unable to load %n security/securities." msgid_plural "Unable to load %n security/securities." msgstr[0] "" #: ../src/budget.cpp:1424 ../src/budget.cpp:2181 #, qt-format msgctxt "Budget|" msgid "Unable to load %n transaction(s)." msgid_plural "Unable to load %n transaction(s)." msgstr[0] "" #: ../src/budget.cpp:699 ../src/budget.cpp:2192 msgctxt "Budget|" msgid "File is a directory" msgstr "" #: ../src/budget.cpp:192 msgctxt "Budget|" msgid "European Euro" msgstr "" #: ../src/budget.cpp:567 ../src/budget.cpp:575 ../src/budget.cpp:616 #: ../src/budget.cpp:688 msgctxt "Budget|" msgid "No exchange rates found." msgstr "" #: ../src/budget.cpp:624 msgctxt "Budget|" msgid "USD currency missing." msgstr "" #: ../src/budget.cpp:707 ../src/budget.cpp:2200 msgctxt "Budget|" msgid "Couldn't open file for writing" msgstr "" #: ../src/budget.cpp:728 ../src/budget.cpp:732 ../src/budget.cpp:2344 #: ../src/budget.cpp:2348 msgctxt "Budget|" msgid "Error while writing file; file was not saved" msgstr "" #: ../src/budget.cpp:1515 #, qt-format msgctxt "Budget|" msgid "Download command (%1) failed: %2." msgstr "" #: ../src/budget.cpp:1535 #, qt-format msgctxt "Budget|" msgid "Failed to download file from %1: %2." msgstr "" #: ../src/budget.cpp:1589 #, qt-format msgctxt "Budget|" msgid "Upload command (%1) failed: %2." msgstr "" #. Financial year when first month is not January (e.g. 2018-19). #: ../src/budget.cpp:3094 msgctxt "Budget|" msgid "yyyy-yy" msgstr "" #: ../src/budget.cpp:3309 ../src/budget.cpp:3359 msgctxt "Budget|" msgid "Transaction Accounts" msgstr "" #: ../src/budget.cpp:3311 ../src/budget.cpp:3360 msgctxt "Budget|" msgid "Savings Accounts" msgstr "" #: ../src/budget.cpp:3313 ../src/budget.cpp:3361 msgctxt "Budget|" msgid "Credit Cards" msgstr "" #: ../src/budget.cpp:3315 ../src/budget.cpp:3362 msgctxt "Budget|" msgid "Debts" msgstr "" #: ../src/budget.cpp:3317 ../src/budget.cpp:3331 ../src/budget.cpp:3363 #: ../src/budget.cpp:3373 msgctxt "Budget|Financial security (e.g. stock, mutual fund)" msgid "Securities" msgstr "" #: ../src/budget.cpp:3319 ../src/budget.cpp:3333 ../src/budget.cpp:3358 #: ../src/budget.cpp:3368 msgctxt "Budget|" msgid "Cash" msgstr "" #: ../src/budget.cpp:3323 ../src/budget.cpp:3369 msgctxt "Budget|" msgid "Transaction Account" msgstr "" #: ../src/budget.cpp:3325 ../src/budget.cpp:3370 msgctxt "Budget|" msgid "Savings Account" msgstr "" #: ../src/budget.cpp:3327 ../src/budget.cpp:3371 msgctxt "Budget|" msgid "Credit Card" msgstr "" #: ../src/budget.cpp:3329 ../src/budget.cpp:3372 msgctxt "Budget|" msgid "Debt" msgstr "" #: ../src/budget.cpp:3374 msgctxt "Budget|" msgid "Other" msgstr "" #: ../src/qifimportexport.cpp:1118 ../src/qifimportexport.cpp:1228 #: ../src/qifimportexport.cpp:1368 msgctxt "Budget|" msgid "Unnamed" msgstr "" #: ../src/qifimportexport.cpp:1150 ../src/qifimportexport.cpp:1286 msgctxt "Budget|" msgid "Uncategorized" msgstr "" #: ../src/categoriescomparisonchart.cpp:118 msgctxt "CategoriesComparisonChart|" msgid "Save As…" msgstr "" #: ../src/categoriescomparisonchart.cpp:121 msgctxt "CategoriesComparisonChart|" msgid "Print…" msgstr "" #: ../src/categoriescomparisonchart.cpp:142 msgctxt "CategoriesComparisonChart|" msgid "From" msgstr "" #: ../src/categoriescomparisonchart.cpp:149 msgctxt "CategoriesComparisonChart|" msgid "To" msgstr "" #: ../src/categoriescomparisonchart.cpp:167 msgctxt "CategoriesComparisonChart|" msgid "Source:" msgstr "" #: ../src/categoriescomparisonchart.cpp:104 msgctxt "CategoriesComparisonChart|" msgid "Theme:" msgstr "" #: ../src/categoriescomparisonchart.cpp:99 msgctxt "CategoriesComparisonChart|" msgid "Chart type:" msgstr "" #: ../src/categoriescomparisonchart.cpp:101 msgctxt "CategoriesComparisonChart|" msgid "Pie Chart" msgstr "" #: ../src/categoriescomparisonchart.cpp:102 msgctxt "CategoriesComparisonChart|" msgid "Bar Chart" msgstr "" #: ../src/categoriescomparisonchart.cpp:106 msgctxt "CategoriesComparisonChart|" msgid "Default" msgstr "" #: ../src/categoriescomparisonchart.cpp:170 #: ../src/categoriescomparisonchart.cpp:1372 msgctxt "CategoriesComparisonChart|" msgid "All Expenses, without subcategories" msgstr "" #: ../src/categoriescomparisonchart.cpp:171 #: ../src/categoriescomparisonchart.cpp:1373 msgctxt "CategoriesComparisonChart|" msgid "All Expenses, with subcategories" msgstr "" #: ../src/categoriescomparisonchart.cpp:172 #: ../src/categoriescomparisonchart.cpp:1374 msgctxt "CategoriesComparisonChart|" msgid "All Incomes, without subcategories" msgstr "" #: ../src/categoriescomparisonchart.cpp:173 #: ../src/categoriescomparisonchart.cpp:1375 msgctxt "CategoriesComparisonChart|" msgid "All Incomes, with subcategories" msgstr "" #: ../src/categoriescomparisonchart.cpp:174 #: ../src/categoriescomparisonchart.cpp:187 #: ../src/categoriescomparisonchart.cpp:1376 #: ../src/categoriescomparisonchart.cpp:1395 msgctxt "CategoriesComparisonChart|" msgid "All Accounts" msgstr "" #: ../src/categoriescomparisonchart.cpp:177 #: ../src/categoriescomparisonchart.cpp:683 #: ../src/categoriescomparisonchart.cpp:1380 #, qt-format msgctxt "CategoriesComparisonChart|" msgid "Expenses: %1" msgstr "" #: ../src/categoriescomparisonchart.cpp:181 #: ../src/categoriescomparisonchart.cpp:684 #: ../src/categoriescomparisonchart.cpp:1386 #, qt-format msgctxt "CategoriesComparisonChart|" msgid "Incomes: %1" msgstr "" #: ../src/categoriescomparisonchart.cpp:279 #: ../src/categoriescomparisonchart.cpp:310 #: ../src/categoriescomparisonchart.cpp:451 #: ../src/categoriescomparisonchart.cpp:483 msgctxt "CategoriesComparisonChart|" msgid "Error" msgstr "" #: ../src/categoriescomparisonchart.cpp:279 #: ../src/categoriescomparisonchart.cpp:310 msgctxt "CategoriesComparisonChart|" msgid "Invalid date." msgstr "" #: ../src/categoriescomparisonchart.cpp:451 msgctxt "CategoriesComparisonChart|" msgid "Couldn't open file for writing." msgstr "" #: ../src/categoriescomparisonchart.cpp:483 msgctxt "CategoriesComparisonChart|" msgid "Error while writing file; file was not saved." msgstr "" #: ../src/categoriescomparisonchart.cpp:602 msgctxt "CategoriesComparisonChart|" msgid "Expenses" msgstr "" #: ../src/categoriescomparisonchart.cpp:629 #, qt-format msgctxt "CategoriesComparisonChart|" msgid "Expenses, %1" msgstr "" #: ../src/categoriescomparisonchart.cpp:643 #, qt-format msgctxt "CategoriesComparisonChart|" msgid "Incomes, %1" msgstr "" #: ../src/categoriescomparisonchart.cpp:644 msgctxt "CategoriesComparisonChart|" msgid "Incomes" msgstr "" #: ../src/categoriescomparisonchart.cpp:656 msgctxt "CategoriesComparisonChart|" msgid "Accounts" msgstr "" #: ../src/categoriescomparisonchart.cpp:680 #, qt-format msgctxt "CategoriesComparisonChart|" msgid "Expenses, %2: %1" msgstr "" #: ../src/categoriescomparisonchart.cpp:681 #, qt-format msgctxt "CategoriesComparisonChart|" msgid "Incomes, %2: %1" msgstr "" #: ../src/categoriescomparisonchart.cpp:922 #: ../src/categoriescomparisonchart.cpp:923 msgctxt "" "CategoriesComparisonChart|Referring to the transaction description property " "(transaction title/generic article name)" msgid "Other descriptions" msgstr "" #: ../src/categoriescomparisonchart.cpp:1078 #: ../src/categoriescomparisonchart.cpp:1234 #: ../src/categoriescomparisonchart.cpp:1283 msgctxt "" "CategoriesComparisonChart|Referring to the transaction description property " "(transaction title/generic article name)" msgid "No description" msgstr "" #: ../src/categoriescomparisonchart.cpp:1086 #: ../src/categoriescomparisonchart.cpp:1242 #: ../src/categoriescomparisonchart.cpp:1291 msgctxt "CategoriesComparisonChart|" msgid "Other accounts" msgstr "" #: ../src/categoriescomparisonchart.cpp:1087 #: ../src/categoriescomparisonchart.cpp:1243 #: ../src/categoriescomparisonchart.cpp:1292 msgctxt "CategoriesComparisonChart|" msgid "Other categories" msgstr "" #: ../src/categoriescomparisonchart.cpp:1170 msgctxt "CategoriesComparisonChart|" msgid "Value" msgstr "" #: ../src/categoriescomparisonchart.cpp:1171 msgctxt "CategoriesComparisonChart|" msgid "Income" msgstr "" #: ../src/categoriescomparisonchart.cpp:1172 msgctxt "CategoriesComparisonChart|" msgid "Cost" msgstr "" #: ../src/categoriescomparisonchart.cpp:1565 #, qt-format msgctxt "CategoriesComparisonChart|" msgid "" "%1\n" "Value: %2" msgstr "" #: ../src/eqonomize.cpp:1168 msgctxt "CategoriesComparisonChartDialog|" msgid "Chart" msgstr "" #: ../src/categoriescomparisonreport.cpp:78 msgctxt "CategoriesComparisonReport|" msgid "Save As…" msgstr "" #: ../src/categoriescomparisonreport.cpp:80 msgctxt "CategoriesComparisonReport|" msgid "Print…" msgstr "" #: ../src/categoriescomparisonreport.cpp:94 msgctxt "CategoriesComparisonReport|" msgid "Source:" msgstr "" #: ../src/categoriescomparisonreport.cpp:99 #: ../src/categoriescomparisonreport.cpp:2090 msgctxt "CategoriesComparisonReport|" msgid "All Categories, excluding subcategories" msgstr "" #: ../src/categoriescomparisonreport.cpp:100 #: ../src/categoriescomparisonreport.cpp:2091 msgctxt "CategoriesComparisonReport|" msgid "All Categories, including subcategories" msgstr "" #: ../src/categoriescomparisonreport.cpp:101 #: ../src/categoriescomparisonreport.cpp:2092 msgctxt "CategoriesComparisonReport|" msgid "All Tags" msgstr "" #: ../src/categoriescomparisonreport.cpp:103 #: ../src/categoriescomparisonreport.cpp:2094 msgctxt "CategoriesComparisonReport|" msgid "All Payees and Payers" msgstr "" #: ../src/categoriescomparisonreport.cpp:135 msgctxt "CategoriesComparisonReport|" msgid "Subcategories" msgstr "" #: ../src/categoriescomparisonreport.cpp:110 #: ../src/categoriescomparisonreport.cpp:1569 #: ../src/categoriescomparisonreport.cpp:1572 #: ../src/categoriescomparisonreport.cpp:1583 #: ../src/categoriescomparisonreport.cpp:2101 #, qt-format msgctxt "CategoriesComparisonReport|" msgid "Expenses: %1" msgstr "" #: ../src/categoriescomparisonreport.cpp:114 #: ../src/categoriescomparisonreport.cpp:1574 #: ../src/categoriescomparisonreport.cpp:1577 #: ../src/categoriescomparisonreport.cpp:1584 #: ../src/categoriescomparisonreport.cpp:2106 #, qt-format msgctxt "CategoriesComparisonReport|" msgid "Incomes: %1" msgstr "" #: ../src/categoriescomparisonreport.cpp:117 #: ../src/categoriescomparisonreport.cpp:2110 #, qt-format msgctxt "CategoriesComparisonReport|" msgid "Tag: %1" msgstr "" #: ../src/categoriescomparisonreport.cpp:124 #: ../src/categoriescomparisonreport.cpp:2116 msgctxt "CategoriesComparisonReport|" msgid "All Accounts" msgstr "" #: ../src/categoriescomparisonreport.cpp:148 msgctxt "CategoriesComparisonReport|" msgid "Payees/payers for" msgstr "" #: ../src/categoriescomparisonreport.cpp:168 msgctxt "CategoriesComparisonReport|" msgid "Period:" msgstr "" #: ../src/categoriescomparisonreport.cpp:171 msgctxt "CategoriesComparisonReport|" msgid "From" msgstr "" #: ../src/categoriescomparisonreport.cpp:178 msgctxt "CategoriesComparisonReport|" msgid "To" msgstr "" #: ../src/categoriescomparisonreport.cpp:193 msgctxt "CategoriesComparisonReport|" msgid "Columns:" msgstr "" #: ../src/categoriescomparisonreport.cpp:215 #: ../src/categoriescomparisonreport.cpp:1652 #: ../src/categoriescomparisonreport.cpp:1657 msgctxt "CategoriesComparisonReport|" msgid "Value" msgstr "" #: ../src/categoriescomparisonreport.cpp:218 msgctxt "CategoriesComparisonReport|" msgid "Daily" msgstr "" #: ../src/categoriescomparisonreport.cpp:221 msgctxt "CategoriesComparisonReport|" msgid "Monthly" msgstr "" #: ../src/categoriescomparisonreport.cpp:224 msgctxt "CategoriesComparisonReport|" msgid "Yearly" msgstr "" #: ../src/categoriescomparisonreport.cpp:227 #: ../src/categoriescomparisonreport.cpp:1662 msgctxt "CategoriesComparisonReport|" msgid "Quantity" msgstr "" #: ../src/categoriescomparisonreport.cpp:230 msgctxt "CategoriesComparisonReport|" msgid "Average value" msgstr "" #: ../src/categoriescomparisonreport.cpp:454 #: ../src/categoriescomparisonreport.cpp:2034 msgctxt "CategoriesComparisonReport|" msgid "All payees" msgstr "" #: ../src/categoriescomparisonreport.cpp:455 #: ../src/categoriescomparisonreport.cpp:2035 msgctxt "CategoriesComparisonReport|" msgid "All payers" msgstr "" #: ../src/categoriescomparisonreport.cpp:139 msgctxt "" "CategoriesComparisonReport|Referring to the transaction description property " "(transaction title/generic article name)" msgid "Descriptions for" msgstr "" #: ../src/categoriescomparisonreport.cpp:139 msgctxt "" "CategoriesComparisonReport|Referring to the transaction description property " "(transaction title/generic article name)" msgid "Descriptions" msgstr "" #: ../src/categoriescomparisonreport.cpp:196 msgctxt "CategoriesComparisonReport|" msgid "Months" msgstr "" #: ../src/categoriescomparisonreport.cpp:199 msgctxt "CategoriesComparisonReport|" msgid "Years" msgstr "" #: ../src/categoriescomparisonreport.cpp:202 #: ../src/categoriescomparisonreport.cpp:1561 #: ../src/categoriescomparisonreport.cpp:1562 #: ../src/categoriescomparisonreport.cpp:1583 #: ../src/categoriescomparisonreport.cpp:1584 #: ../src/categoriescomparisonreport.cpp:1585 msgctxt "CategoriesComparisonReport|" msgid "Tags" msgstr "" #: ../src/categoriescomparisonreport.cpp:205 msgctxt "CategoriesComparisonReport|" msgid "Total:" msgstr "" #: ../src/categoriescomparisonreport.cpp:432 #: ../src/categoriescomparisonreport.cpp:2012 msgctxt "" "CategoriesComparisonReport|Referring to the transaction description property " "(transaction title/generic article name)" msgid "All descriptions" msgstr "" #: ../src/categoriescomparisonreport.cpp:456 #: ../src/categoriescomparisonreport.cpp:2036 msgctxt "CategoriesComparisonReport|" msgid "All payees/payers" msgstr "" #: ../src/categoriescomparisonreport.cpp:461 #: ../src/categoriescomparisonreport.cpp:1548 #: ../src/categoriescomparisonreport.cpp:1553 #: ../src/categoriescomparisonreport.cpp:1557 #: ../src/categoriescomparisonreport.cpp:1570 #: ../src/categoriescomparisonreport.cpp:1575 #: ../src/categoriescomparisonreport.cpp:1579 #: ../src/categoriescomparisonreport.cpp:1773 #: ../src/categoriescomparisonreport.cpp:2046 msgctxt "" "CategoriesComparisonReport|Referring to the transaction description property " "(transaction title/generic article name)" msgid "No description" msgstr "" #: ../src/categoriescomparisonreport.cpp:467 #: ../src/categoriescomparisonreport.cpp:1549 #: ../src/categoriescomparisonreport.cpp:1558 #: ../src/categoriescomparisonreport.cpp:1571 #: ../src/categoriescomparisonreport.cpp:1580 #: ../src/categoriescomparisonreport.cpp:1770 #: ../src/categoriescomparisonreport.cpp:2063 msgctxt "CategoriesComparisonReport|" msgid "No payee" msgstr "" #: ../src/categoriescomparisonreport.cpp:468 #: ../src/categoriescomparisonreport.cpp:1554 #: ../src/categoriescomparisonreport.cpp:1558 #: ../src/categoriescomparisonreport.cpp:1576 #: ../src/categoriescomparisonreport.cpp:1580 #: ../src/categoriescomparisonreport.cpp:1771 #: ../src/categoriescomparisonreport.cpp:2064 msgctxt "CategoriesComparisonReport|" msgid "No payer" msgstr "" #: ../src/categoriescomparisonreport.cpp:494 #: ../src/categoriescomparisonreport.cpp:525 #: ../src/categoriescomparisonreport.cpp:612 #: ../src/categoriescomparisonreport.cpp:620 msgctxt "CategoriesComparisonReport|" msgid "Error" msgstr "" #: ../src/categoriescomparisonreport.cpp:494 #: ../src/categoriescomparisonreport.cpp:525 msgctxt "CategoriesComparisonReport|" msgid "Invalid date." msgstr "" #: ../src/categoriescomparisonreport.cpp:612 msgctxt "CategoriesComparisonReport|" msgid "Couldn't open file for writing." msgstr "" #: ../src/categoriescomparisonreport.cpp:620 msgctxt "CategoriesComparisonReport|" msgid "Error while writing file; file was not saved." msgstr "" #: ../src/categoriescomparisonreport.cpp:1547 #: ../src/categoriescomparisonreport.cpp:1550 #: ../src/categoriescomparisonreport.cpp:1561 #, qt-format msgctxt "CategoriesComparisonReport|" msgid "Expenses, %2: %1" msgstr "" #: ../src/categoriescomparisonreport.cpp:1548 #: ../src/categoriescomparisonreport.cpp:1549 #, qt-format msgctxt "CategoriesComparisonReport|" msgid "Expenses, %3: %2, %1" msgstr "" #: ../src/categoriescomparisonreport.cpp:1552 #: ../src/categoriescomparisonreport.cpp:1555 #: ../src/categoriescomparisonreport.cpp:1562 #, qt-format msgctxt "CategoriesComparisonReport|" msgid "Incomes, %2: %1" msgstr "" #: ../src/categoriescomparisonreport.cpp:1553 #: ../src/categoriescomparisonreport.cpp:1554 #, qt-format msgctxt "CategoriesComparisonReport|" msgid "Incomes, %3: %2, %1" msgstr "" #: ../src/categoriescomparisonreport.cpp:1557 #: ../src/categoriescomparisonreport.cpp:1558 #, qt-format msgctxt "CategoriesComparisonReport|" msgid "%3: %2, %1" msgstr "" #: ../src/categoriescomparisonreport.cpp:1559 #, qt-format msgctxt "CategoriesComparisonReport|" msgid "%2: %1" msgstr "" #: ../src/categoriescomparisonreport.cpp:1563 #, qt-format msgctxt "CategoriesComparisonReport|" msgid "Tags, %1" msgstr "" #: ../src/categoriescomparisonreport.cpp:1565 #, qt-format msgctxt "CategoriesComparisonReport|" msgid "Incomes & Expenses, %1" msgstr "" #: ../src/categoriescomparisonreport.cpp:1570 #: ../src/categoriescomparisonreport.cpp:1571 #, qt-format msgctxt "CategoriesComparisonReport|" msgid "Expenses: %2, %1" msgstr "" #: ../src/categoriescomparisonreport.cpp:1575 #: ../src/categoriescomparisonreport.cpp:1576 #, qt-format msgctxt "CategoriesComparisonReport|" msgid "Incomes: %2, %1" msgstr "" #: ../src/categoriescomparisonreport.cpp:1579 #: ../src/categoriescomparisonreport.cpp:1580 #, qt-format msgctxt "CategoriesComparisonReport|" msgid "%2, %1" msgstr "" #: ../src/categoriescomparisonreport.cpp:1587 msgctxt "CategoriesComparisonReport|" msgid "Incomes & Expenses" msgstr "" #: ../src/categoriescomparisonreport.cpp:1616 #, qt-format msgctxt "" "CategoriesComparisonReport|html format; %1: title; %2: from date; %3: to date" msgid "%1 (%2–%3)" msgstr "" #: ../src/categoriescomparisonreport.cpp:1617 #, qt-format msgctxt "CategoriesComparisonReport|html format; %1: title; %2: to date" msgid "%1 (to %2)" msgstr "" #: ../src/categoriescomparisonreport.cpp:1636 #: ../src/categoriescomparisonreport.cpp:1642 #: ../src/categoriescomparisonreport.cpp:1656 msgctxt "CategoriesComparisonReport|" msgid "Category" msgstr "" #: ../src/categoriescomparisonreport.cpp:1637 #: ../src/categoriescomparisonreport.cpp:1648 msgctxt "CategoriesComparisonReport|" msgid "Payee" msgstr "" #: ../src/categoriescomparisonreport.cpp:1638 #: ../src/categoriescomparisonreport.cpp:1644 #: ../src/categoriescomparisonreport.cpp:1651 msgctxt "" "CategoriesComparisonReport|Referring to the transaction description property " "(transaction title/generic article name)" msgid "Description" msgstr "" #: ../src/categoriescomparisonreport.cpp:1639 msgctxt "CategoriesComparisonReport|" msgid "Cost" msgstr "" #: ../src/categoriescomparisonreport.cpp:1643 #: ../src/categoriescomparisonreport.cpp:1649 msgctxt "CategoriesComparisonReport|" msgid "Payer" msgstr "" #: ../src/categoriescomparisonreport.cpp:1645 msgctxt "CategoriesComparisonReport|" msgid "Income" msgstr "" #: ../src/categoriescomparisonreport.cpp:1650 #: ../src/categoriescomparisonreport.cpp:1654 msgctxt "CategoriesComparisonReport|" msgid "Payee/Payer" msgstr "" #: ../src/categoriescomparisonreport.cpp:1635 #: ../src/categoriescomparisonreport.cpp:1641 #: ../src/categoriescomparisonreport.cpp:1655 msgctxt "CategoriesComparisonReport|" msgid "Tag" msgstr "" #: ../src/categoriescomparisonreport.cpp:1659 msgctxt "CategoriesComparisonReport|" msgid "Daily Average" msgstr "" #: ../src/categoriescomparisonreport.cpp:1660 msgctxt "CategoriesComparisonReport|" msgid "Monthly Average" msgstr "" #: ../src/categoriescomparisonreport.cpp:1661 msgctxt "CategoriesComparisonReport|" msgid "Yearly Average" msgstr "" #: ../src/categoriescomparisonreport.cpp:1664 msgctxt "CategoriesComparisonReport|" msgid "Average Cost" msgstr "" #: ../src/categoriescomparisonreport.cpp:1666 msgctxt "CategoriesComparisonReport|" msgid "Average Income" msgstr "" #: ../src/categoriescomparisonreport.cpp:1668 msgctxt "CategoriesComparisonReport|" msgid "Average Value" msgstr "" #: ../src/categoriescomparisonreport.cpp:469 #: ../src/categoriescomparisonreport.cpp:1772 #: ../src/categoriescomparisonreport.cpp:2065 msgctxt "CategoriesComparisonReport|" msgid "No payee/payer" msgstr "" #: ../src/categoriescomparisonreport.cpp:1676 #: ../src/categoriescomparisonreport.cpp:1804 #: ../src/categoriescomparisonreport.cpp:1877 #: ../src/categoriescomparisonreport.cpp:1947 msgctxt "CategoriesComparisonReport|" msgid "Total" msgstr "" #: ../src/categoriescomparisonreport.cpp:1877 msgctxt "CategoriesComparisonReport|" msgid "Total incomes" msgstr "" #: ../src/categoriescomparisonreport.cpp:1947 msgctxt "CategoriesComparisonReport|" msgid "Total expenses" msgstr "" #: ../src/categoriescomparisonreport.cpp:1970 msgctxt "CategoriesComparisonReport|" msgid "Total (Profits)" msgstr "" #: ../src/eqonomize.cpp:1138 msgctxt "CategoriesComparisonReportDialog|" msgid "Report" msgstr "" #: ../src/eqonomize.cpp:1190 msgctxt "ConfirmScheduleDialog|" msgid "" "The following transactions was scheduled to occur today or before today.\n" "Confirm that they have indeed occurred (or will occur today)." msgstr "" #: ../src/eqonomize.cpp:1199 ../src/eqonomize.cpp:1259 msgctxt "ConfirmScheduleDialog|" msgid "Date" msgstr "" #: ../src/eqonomize.cpp:1200 msgctxt "ConfirmScheduleDialog|" msgid "Type" msgstr "" #: ../src/eqonomize.cpp:1201 msgctxt "" "ConfirmScheduleDialog|Transaction description property (transaction " "title/generic article name)" msgid "Description" msgstr "" #: ../src/eqonomize.cpp:1202 msgctxt "ConfirmScheduleDialog|" msgid "Amount" msgstr "" #: ../src/eqonomize.cpp:1215 msgctxt "ConfirmScheduleDialog|" msgid "Edit…" msgstr "" #: ../src/eqonomize.cpp:1217 msgctxt "ConfirmScheduleDialog|" msgid "Postpone…" msgstr "" #: ../src/eqonomize.cpp:1219 msgctxt "ConfirmScheduleDialog|" msgid "Delete" msgstr "" #: ../src/eqonomize.cpp:1276 msgctxt "ConfirmScheduleDialog|" msgid "Error" msgstr "" #: ../src/eqonomize.cpp:1276 msgctxt "ConfirmScheduleDialog|" msgid "Can only postpone to future dates." msgstr "" #: ../src/eqonomize.cpp:565 msgctxt "ConfirmScheduleListViewItem|" msgid "Transfer" msgstr "" #: ../src/eqonomize.cpp:567 msgctxt "ConfirmScheduleListViewItem|" msgid "Dividend" msgstr "" #: ../src/eqonomize.cpp:568 msgctxt "ConfirmScheduleListViewItem|" msgid "Income" msgstr "" #: ../src/eqonomize.cpp:571 msgctxt "ConfirmScheduleListViewItem|" msgid "Expense" msgstr "" #: ../src/eqonomize.cpp:572 msgctxt "" "ConfirmScheduleListViewItem|Financial security (e.g. stock, mutual fund)" msgid "Securities Purchase" msgstr "" #: ../src/eqonomize.cpp:573 msgctxt "" "ConfirmScheduleListViewItem|Financial security (e.g. stock, mutual fund)" msgid "Securities Sale" msgstr "" #: ../src/eqonomize.cpp:592 msgctxt "ConfirmScheduleListViewItem|" msgid "Debt Payment" msgstr "" #: ../src/currencyconversiondialog.cpp:40 msgctxt "CurrencyConversionDialog|" msgid "Currency Converter" msgstr "" #: ../src/transaction.cpp:510 #, qt-format msgctxt "DebtFee|" msgid "Debt payment: %1 (fee)" msgstr "" #: ../src/transaction.cpp:558 #, qt-format msgctxt "DebtInterest|" msgid "Debt payment: %1 (interest)" msgstr "" #: ../src/transaction.cpp:2672 #, qt-format msgctxt "DebtPayment|" msgid "Debt payment: %1" msgstr "" #: ../src/transaction.cpp:915 #, qt-format msgctxt "DebtReduction|" msgid "Debt payment: %1 (reduction)" msgstr "" #: ../src/editaccountdialogs.cpp:61 msgctxt "EditAssetsAccountDialog|" msgid "Type:" msgstr "" #: ../src/editaccountdialogs.cpp:74 msgctxt "EditAssetsAccountDialog|" msgid "Group:" msgstr "" #: ../src/editaccountdialogs.cpp:95 msgctxt "EditAssetsAccountDialog|" msgid "no group" msgstr "" #: ../src/editaccountdialogs.cpp:113 msgctxt "EditAssetsAccountDialog|" msgid "Currency:" msgstr "" #: ../src/editaccountdialogs.cpp:117 msgctxt "EditAssetsAccountDialog|" msgid "Edit" msgstr "" #: ../src/editaccountdialogs.cpp:120 msgctxt "EditAssetsAccountDialog|" msgid "Name:" msgstr "" #: ../src/editaccountdialogs.cpp:123 ../src/editaccountdialogs.cpp:286 msgctxt "EditAssetsAccountDialog|" msgid "Bank:" msgstr "" #: ../src/editaccountdialogs.cpp:127 msgctxt "EditAssetsAccountDialog|" msgid "Debt:" msgstr "" #: ../src/editaccountdialogs.cpp:136 msgctxt "EditAssetsAccountDialog|" msgid "Transferred to:" msgstr "" #: ../src/editaccountdialogs.cpp:141 msgctxt "EditAssetsAccountDialog|" msgid "Date:" msgstr "" #: ../src/editaccountdialogs.cpp:151 ../src/editaccountdialogs.cpp:285 msgctxt "EditAssetsAccountDialog|" msgid "Lender:" msgstr "" #: ../src/editaccountdialogs.cpp:157 msgctxt "EditAssetsAccountDialog|" msgid "Default account for budgeted transactions" msgstr "" #: ../src/editaccountdialogs.cpp:163 msgctxt "EditAssetsAccountDialog|" msgid "Description:" msgstr "" #: ../src/editaccountdialogs.cpp:169 msgctxt "EditAssetsAccountDialog|" msgid "Account is closed" msgstr "" #: ../src/editaccountdialogs.cpp:401 msgctxt "EditAssetsAccountDialog|" msgid "Zero value not allowed." msgstr "" #: ../src/editaccountdialogs.cpp:224 msgctxt "EditAssetsAccountDialog|" msgid "Warning" msgstr "" #: ../src/editaccountdialogs.cpp:254 msgctxt "EditAssetsAccountDialog|" msgid "Type cannot be changed to securities for accounts with transactions." msgstr "" #: ../src/editaccountdialogs.cpp:284 msgctxt "EditAssetsAccountDialog|" msgid "Issuer:" msgstr "" #: ../src/editaccountdialogs.cpp:254 ../src/editaccountdialogs.cpp:390 #: ../src/editaccountdialogs.cpp:396 ../src/editaccountdialogs.cpp:401 msgctxt "EditAssetsAccountDialog|" msgid "Error" msgstr "" #: ../src/editaccountdialogs.cpp:127 msgctxt "EditAssetsAccountDialog|Account balance" msgid "Opening balance:" msgstr "" #: ../src/editaccountdialogs.cpp:132 msgctxt "EditAssetsAccountDialog|Account balance" msgid "Opening balance" msgstr "" #: ../src/editaccountdialogs.cpp:194 msgctxt "EditAssetsAccountDialog|" msgid "New currency…" msgstr "" #: ../src/editaccountdialogs.cpp:224 msgctxt "EditAssetsAccountDialog|" msgid "" "If you change the currency of an account, the currency of all associated " "transactions will also change, without any conversion. Do do wish to " "continue anyway?" msgstr "" #: ../src/editaccountdialogs.cpp:390 msgctxt "EditAssetsAccountDialog|" msgid "Empty name." msgstr "" #: ../src/editaccountdialogs.cpp:396 msgctxt "EditAssetsAccountDialog|" msgid "The entered name is used by another account." msgstr "" #: ../src/editcurrencydialog.cpp:48 msgctxt "EditCurrencyDialog|" msgid "Edit Currency" msgstr "" #: ../src/editcurrencydialog.cpp:49 msgctxt "EditCurrencyDialog|" msgid "New Currency" msgstr "" #: ../src/editcurrencydialog.cpp:59 msgctxt "EditCurrencyDialog|" msgid "Code:" msgstr "" #: ../src/editcurrencydialog.cpp:68 msgctxt "EditCurrencyDialog|" msgid "Symbol:" msgstr "" #: ../src/editcurrencydialog.cpp:74 msgctxt "EditCurrencyDialog|" msgid "Prefix" msgstr "" #: ../src/editcurrencydialog.cpp:75 msgctxt "EditCurrencyDialog|" msgid "Suffix" msgstr "" #: ../src/editcurrencydialog.cpp:76 ../src/editcurrencydialog.cpp:96 msgctxt "EditCurrencyDialog|" msgid "Default" msgstr "" #: ../src/editcurrencydialog.cpp:87 msgctxt "EditCurrencyDialog|" msgid "Name:" msgstr "" #: ../src/editcurrencydialog.cpp:91 msgctxt "EditCurrencyDialog|" msgid "Decimals:" msgstr "" #: ../src/editcurrencydialog.cpp:105 msgctxt "EditCurrencyDialog|" msgid "Date:" msgstr "" #: ../src/editcurrencydialog.cpp:116 msgctxt "EditCurrencyDialog|" msgid "Main currency" msgstr "" #: ../src/editcurrencydialog.cpp:153 ../src/editcurrencydialog.cpp:173 #: ../src/editcurrencydialog.cpp:181 ../src/editcurrencydialog.cpp:186 msgctxt "EditCurrencyDialog|" msgid "Error" msgstr "" #: ../src/editcurrencydialog.cpp:153 ../src/editcurrencydialog.cpp:173 #, qt-format msgctxt "EditCurrencyDialog|" msgid "Error saving currencies: %1." msgstr "" #: ../src/editcurrencydialog.cpp:181 msgctxt "EditCurrencyDialog|" msgid "Empty code." msgstr "" #: ../src/editcurrencydialog.cpp:186 msgctxt "EditCurrencyDialog|" msgid "Code already exists." msgstr "" #: ../src/editsplitdialog.cpp:186 msgctxt "EditDebtPaymentDialog|" msgid "Debt Payment" msgstr "" #: ../src/editsplitdialog.cpp:1140 msgctxt "EditDebtPaymentWidget|" msgid "Debt:" msgstr "" #: ../src/editsplitdialog.cpp:1145 msgctxt "EditDebtPaymentWidget|" msgid "Date:" msgstr "" #: ../src/editsplitdialog.cpp:1154 msgctxt "EditDebtPaymentWidget|" msgid "Debt reduction:" msgstr "" #: ../src/editsplitdialog.cpp:1157 msgctxt "EditDebtPaymentWidget|" msgid "Reduction payment:" msgstr "" #: ../src/editsplitdialog.cpp:1167 msgctxt "EditDebtPaymentWidget|" msgid "Interest:" msgstr "" #: ../src/editsplitdialog.cpp:1180 msgctxt "EditDebtPaymentWidget|" msgid "Paid" msgstr "" #: ../src/editsplitdialog.cpp:1182 msgctxt "EditDebtPaymentWidget|" msgid "Added to debt" msgstr "" #: ../src/editsplitdialog.cpp:1187 msgctxt "EditDebtPaymentWidget|" msgid "Fee:" msgstr "" #: ../src/editsplitdialog.cpp:1194 msgctxt "EditDebtPaymentWidget|" msgid "Account:" msgstr "" #: ../src/editsplitdialog.cpp:1200 msgctxt "EditDebtPaymentWidget|" msgid "Expense category:" msgstr "" #: ../src/editsplitdialog.cpp:1209 msgctxt "EditDebtPaymentWidget|" msgid "Associated file:" msgstr "" #: ../src/editsplitdialog.cpp:1217 msgctxt "EditDebtPaymentWidget|" msgid "Select a file" msgstr "" #: ../src/editsplitdialog.cpp:1221 msgctxt "EditDebtPaymentWidget|" msgid "Open the file" msgstr "" #: ../src/editsplitdialog.cpp:1229 msgctxt "EditDebtPaymentWidget|" msgid "Comments:" msgstr "" #: ../src/editsplitdialog.cpp:1491 msgctxt "EditDebtPaymentWidget|" msgid "Total value:" msgstr "" #: ../src/editsplitdialog.cpp:1549 ../src/editsplitdialog.cpp:1557 #: ../src/editsplitdialog.cpp:1562 ../src/editsplitdialog.cpp:1565 msgctxt "EditDebtPaymentWidget|" msgid "Error" msgstr "" #: ../src/editsplitdialog.cpp:1549 msgctxt "EditDebtPaymentWidget|" msgid "No suitable account available." msgstr "" #: ../src/editsplitdialog.cpp:1557 msgctxt "EditDebtPaymentWidget|" msgid "Invalid date." msgstr "" #: ../src/editsplitdialog.cpp:1562 msgctxt "EditDebtPaymentWidget|" msgid "Interest must not be zero." msgstr "" #: ../src/editsplitdialog.cpp:1565 msgctxt "EditDebtPaymentWidget|" msgid "At least one value must non-zero." msgstr "" #: ../src/recurrenceeditwidget.cpp:53 msgctxt "EditExceptionsDialog|" msgid "Edit Exceptions" msgstr "" #: ../src/recurrenceeditwidget.cpp:61 msgctxt "EditExceptionsDialog|" msgid "Occurrences:" msgstr "" #: ../src/recurrenceeditwidget.cpp:69 msgctxt "EditExceptionsDialog|" msgid "Add Exception" msgstr "" #: ../src/recurrenceeditwidget.cpp:72 msgctxt "EditExceptionsDialog|" msgid "Remove Exception" msgstr "" #: ../src/recurrenceeditwidget.cpp:77 msgctxt "EditExceptionsDialog|" msgid "Exceptions:" msgstr "" #: ../src/recurrenceeditwidget.cpp:82 msgctxt "EditExceptionsDialog|" msgid "Only the first fifty occurrences are shown." msgstr "" #: ../src/editaccountdialogs.cpp:525 msgctxt "EditExpensesAccountDialog|" msgid "Name:" msgstr "" #: ../src/editaccountdialogs.cpp:528 msgctxt "EditExpensesAccountDialog|" msgid "Parent category:" msgstr "" #: ../src/editaccountdialogs.cpp:532 msgctxt "EditExpensesAccountDialog|" msgid "None" msgstr "" #: ../src/editaccountdialogs.cpp:544 msgctxt "EditExpensesAccountDialog|" msgid "Monthly budget:" msgstr "" #: ../src/editaccountdialogs.cpp:550 msgctxt "EditExpensesAccountDialog|" msgid "Description:" msgstr "" #: ../src/editaccountdialogs.cpp:607 ../src/editaccountdialogs.cpp:613 msgctxt "EditExpensesAccountDialog|" msgid "Error" msgstr "" #: ../src/editaccountdialogs.cpp:607 msgctxt "EditExpensesAccountDialog|" msgid "Empty name." msgstr "" #: ../src/editaccountdialogs.cpp:613 msgctxt "EditExpensesAccountDialog|" msgid "The entered name is used by another expense category." msgstr "" #: ../src/editaccountdialogs.cpp:419 msgctxt "EditIncomesAccountDialog|" msgid "Name:" msgstr "" #: ../src/editaccountdialogs.cpp:422 msgctxt "EditIncomesAccountDialog|" msgid "Parent category:" msgstr "" #: ../src/editaccountdialogs.cpp:426 msgctxt "EditIncomesAccountDialog|" msgid "None" msgstr "" #: ../src/editaccountdialogs.cpp:439 msgctxt "EditIncomesAccountDialog|" msgid "Monthly budget:" msgstr "" #: ../src/editaccountdialogs.cpp:445 msgctxt "EditIncomesAccountDialog|" msgid "Description:" msgstr "" #: ../src/editaccountdialogs.cpp:502 ../src/editaccountdialogs.cpp:508 msgctxt "EditIncomesAccountDialog|" msgid "Error" msgstr "" #: ../src/editaccountdialogs.cpp:502 msgctxt "EditIncomesAccountDialog|" msgid "Empty name." msgstr "" #: ../src/editaccountdialogs.cpp:508 msgctxt "EditIncomesAccountDialog|" msgid "The entered name is used by another income category." msgstr "" #: ../src/editsplitdialog.cpp:214 msgctxt "EditMultiAccountDialog|" msgid "Expense with Multiple Payments" msgstr "" #: ../src/editsplitdialog.cpp:215 msgctxt "EditMultiAccountDialog|" msgid "Income with Multiple Payments" msgstr "" #: ../src/editsplitdialog.cpp:778 msgctxt "EditMultiAccountWidget|" msgid "Quantity:" msgstr "" #: ../src/editsplitdialog.cpp:785 msgctxt "EditMultiAccountWidget|" msgid "Category:" msgstr "" #: ../src/editsplitdialog.cpp:814 msgctxt "EditMultiAccountWidget|" msgid "Comments:" msgstr "" #: ../src/editsplitdialog.cpp:818 msgctxt "EditMultiAccountWidget|" msgid "Transactions:" msgstr "" #: ../src/editsplitdialog.cpp:827 msgctxt "EditMultiAccountWidget|" msgid "Date" msgstr "" #: ../src/editsplitdialog.cpp:828 msgctxt "EditMultiAccountWidget|" msgid "Account" msgstr "" #: ../src/editsplitdialog.cpp:772 msgctxt "" "EditMultiAccountWidget|Transaction description property (transaction " "title/generic article name)" msgid "Description:" msgstr "" #: ../src/editsplitdialog.cpp:790 msgctxt "EditMultiAccountWidget|" msgid "Tags:" msgstr "" #: ../src/editsplitdialog.cpp:796 msgctxt "EditMultiAccountWidget|" msgid "Associated file:" msgstr "" #: ../src/editsplitdialog.cpp:804 msgctxt "EditMultiAccountWidget|" msgid "Select a file" msgstr "" #: ../src/editsplitdialog.cpp:808 msgctxt "EditMultiAccountWidget|" msgid "Open the file" msgstr "" #: ../src/editsplitdialog.cpp:829 msgctxt "EditMultiAccountWidget|" msgid "Cost" msgstr "" #: ../src/editsplitdialog.cpp:830 msgctxt "EditMultiAccountWidget|" msgid "Income" msgstr "" #: ../src/editsplitdialog.cpp:839 msgctxt "EditMultiAccountWidget|" msgid "New" msgstr "" #: ../src/editsplitdialog.cpp:841 msgctxt "EditMultiAccountWidget|" msgid "Edit…" msgstr "" #: ../src/editsplitdialog.cpp:844 msgctxt "EditMultiAccountWidget|" msgid "Delete" msgstr "" #: ../src/editsplitdialog.cpp:930 msgctxt "EditMultiAccountWidget|" msgid "Total cost:" msgstr "" #: ../src/editsplitdialog.cpp:1113 ../src/editsplitdialog.cpp:1121 msgctxt "EditMultiAccountWidget|" msgid "Error" msgstr "" #: ../src/editsplitdialog.cpp:1113 msgctxt "EditMultiAccountWidget|" msgid "No suitable expense categories available." msgstr "" #: ../src/editsplitdialog.cpp:1121 msgctxt "EditMultiAccountWidget|" msgid "A split must contain at least two transactions." msgstr "" #: ../src/editsplitdialog.cpp:245 msgctxt "EditMultiItemDialog|" msgid "Split Transaction" msgstr "" #: ../src/editsplitdialog.cpp:306 msgctxt "EditMultiItemWidget|" msgid "Date:" msgstr "" #: ../src/editsplitdialog.cpp:311 msgctxt "EditMultiItemWidget|" msgid "Account:" msgstr "" #: ../src/editsplitdialog.cpp:318 msgctxt "EditMultiItemWidget|" msgid "Payee/Payer:" msgstr "" #: ../src/editsplitdialog.cpp:385 msgctxt "EditMultiItemWidget|" msgid "Transactions:" msgstr "" #: ../src/editsplitdialog.cpp:394 ../src/editsplitdialog.cpp:401 msgctxt "EditMultiItemWidget|" msgid "Type" msgstr "" #: ../src/editsplitdialog.cpp:281 msgctxt "" "EditMultiItemWidget|Transaction description property (transaction " "title/generic article name)" msgid "Description:" msgstr "" #: ../src/editsplitdialog.cpp:357 msgctxt "EditMultiItemWidget|" msgid "Tags:" msgstr "" #: ../src/editsplitdialog.cpp:363 msgctxt "EditMultiItemWidget|" msgid "Associated file:" msgstr "" #: ../src/editsplitdialog.cpp:371 msgctxt "EditMultiItemWidget|" msgid "Select a file" msgstr "" #: ../src/editsplitdialog.cpp:375 msgctxt "EditMultiItemWidget|" msgid "Open the file" msgstr "" #: ../src/editsplitdialog.cpp:381 msgctxt "EditMultiItemWidget|" msgid "Comments:" msgstr "" #: ../src/editsplitdialog.cpp:395 msgctxt "" "EditMultiItemWidget|Transaction description property (transaction " "title/generic article name)" msgid "Description" msgstr "" #: ../src/editsplitdialog.cpp:396 ../src/editsplitdialog.cpp:408 msgctxt "EditMultiItemWidget|" msgid "Account/Category" msgstr "" #: ../src/editsplitdialog.cpp:397 msgctxt "EditMultiItemWidget|" msgid "Value" msgstr "" #: ../src/editsplitdialog.cpp:402 msgctxt "EditMultiItemWidget|" msgid "Income" msgstr "" #: ../src/editsplitdialog.cpp:403 msgctxt "EditMultiItemWidget|" msgid "Expense" msgstr "" #: ../src/editsplitdialog.cpp:414 msgctxt "EditMultiItemWidget|" msgid "New" msgstr "" #: ../src/editsplitdialog.cpp:418 msgctxt "EditMultiItemWidget|" msgid "New Expense…" msgstr "" #: ../src/editsplitdialog.cpp:419 msgctxt "EditMultiItemWidget|" msgid "New Income…" msgstr "" #: ../src/editsplitdialog.cpp:420 msgctxt "EditMultiItemWidget|" msgid "New Deposit…" msgstr "" #: ../src/editsplitdialog.cpp:421 msgctxt "EditMultiItemWidget|" msgid "New Withdrawal…" msgstr "" #: ../src/editsplitdialog.cpp:422 msgctxt "EditMultiItemWidget|Financial security (e.g. stock, mutual fund)" msgid "New Securities Purchase…" msgstr "" #: ../src/editsplitdialog.cpp:423 msgctxt "EditMultiItemWidget|Financial security (e.g. stock, mutual fund)" msgid "New Securities Sale…" msgstr "" #: ../src/editsplitdialog.cpp:424 msgctxt "EditMultiItemWidget|" msgid "New Dividend…" msgstr "" #: ../src/editsplitdialog.cpp:425 msgctxt "EditMultiItemWidget|" msgid "Edit…" msgstr "" #: ../src/editsplitdialog.cpp:428 msgctxt "EditMultiItemWidget|" msgid "Delete" msgstr "" #: ../src/editsplitdialog.cpp:525 msgctxt "EditMultiItemWidget|" msgid "Total value:" msgstr "" #: ../src/editsplitdialog.cpp:733 ../src/editsplitdialog.cpp:741 #: ../src/editsplitdialog.cpp:745 ../src/editsplitdialog.cpp:755 msgctxt "EditMultiItemWidget|" msgid "Error" msgstr "" #: ../src/editsplitdialog.cpp:733 msgctxt "EditMultiItemWidget|" msgid "No suitable account available." msgstr "" #: ../src/editsplitdialog.cpp:741 msgctxt "EditMultiItemWidget|" msgid "Invalid date." msgstr "" #: ../src/editsplitdialog.cpp:745 msgctxt "EditMultiItemWidget|" msgid "A split must contain at least two transactions." msgstr "" #: ../src/editsplitdialog.cpp:755 msgctxt "EditMultiItemWidget|" msgid "Cannot transfer money to and from the same account." msgstr "" #: ../src/eqonomize.cpp:987 msgctxt "EditQuotationsDialog|" msgid "Date" msgstr "" #: ../src/eqonomize.cpp:968 ../src/eqonomize.cpp:975 msgctxt "EditQuotationsDialog|Financial quote" msgid "Quotes" msgstr "" #: ../src/eqonomize.cpp:988 msgctxt "EditQuotationsDialog|Financial Shares" msgid "Price per Share" msgstr "" #: ../src/eqonomize.cpp:1008 msgctxt "EditQuotationsDialog|" msgid "Add" msgstr "" #: ../src/eqonomize.cpp:1010 msgctxt "EditQuotationsDialog|" msgid "Modify" msgstr "" #: ../src/eqonomize.cpp:1013 msgctxt "EditQuotationsDialog|" msgid "Delete" msgstr "" #: ../src/eqonomize.cpp:1043 #, qt-format msgctxt "EditQuotationsDialog|Financial quote" msgid "Quotes for %1" msgstr "" #: ../src/eqonomize.cpp:1074 ../src/eqonomize.cpp:1096 msgctxt "EditQuotationsDialog|" msgid "Error" msgstr "" #: ../src/eqonomize.cpp:1074 ../src/eqonomize.cpp:1096 msgctxt "EditQuotationsDialog|" msgid "Invalid date." msgstr "" #: ../src/recurrenceeditwidget.cpp:185 msgctxt "EditRangeDialog|" msgid "Edit Recurrence Range" msgstr "" #: ../src/recurrenceeditwidget.cpp:193 ../src/recurrenceeditwidget.cpp:234 #, qt-format msgctxt "EditRangeDialog|" msgid "Begins on: %1" msgstr "" #: ../src/recurrenceeditwidget.cpp:198 msgctxt "EditRangeDialog|" msgid "No ending date" msgstr "" #: ../src/recurrenceeditwidget.cpp:202 msgctxt "EditRangeDialog|" msgid "End after" msgstr "" #: ../src/recurrenceeditwidget.cpp:208 msgctxt "EditRangeDialog|" msgid "occurrence(s)" msgstr "" #: ../src/recurrenceeditwidget.cpp:210 msgctxt "EditRangeDialog|" msgid "End on" msgstr "" #: ../src/recurrenceeditwidget.cpp:298 ../src/recurrenceeditwidget.cpp:304 msgctxt "EditRangeDialog|" msgid "Error" msgstr "" #: ../src/recurrenceeditwidget.cpp:298 msgctxt "EditRangeDialog|" msgid "Invalid date." msgstr "" #: ../src/recurrenceeditwidget.cpp:304 msgctxt "EditRangeDialog|" msgid "End date before start date." msgstr "" #: ../src/editscheduledtransactiondialog.cpp:504 msgctxt "EditScheduledDebtPaymentDialog|" msgid "Transaction" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:507 msgctxt "EditScheduledDebtPaymentDialog|" msgid "Recurrence" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:571 #: ../src/editscheduledtransactiondialog.cpp:591 msgctxt "EditScheduledDebtPaymentDialog|" msgid "Edit Debt Payment" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:562 #: ../src/editscheduledtransactiondialog.cpp:571 #: ../src/editscheduledtransactiondialog.cpp:591 msgctxt "EditScheduledDebtPaymentDialog|" msgid "New Debt Payment" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:377 msgctxt "EditScheduledMultiAccountDialog|" msgid "Transactions" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:380 msgctxt "EditScheduledMultiAccountDialog|" msgid "Recurrence" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:438 #: ../src/editscheduledtransactiondialog.cpp:447 #: ../src/editscheduledtransactiondialog.cpp:457 #: ../src/editscheduledtransactiondialog.cpp:477 msgctxt "EditScheduledMultiAccountDialog|" msgid "New Expense with Multiple Payments" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:438 #: ../src/editscheduledtransactiondialog.cpp:447 #: ../src/editscheduledtransactiondialog.cpp:457 #: ../src/editscheduledtransactiondialog.cpp:477 msgctxt "EditScheduledMultiAccountDialog|" msgid "New Income with Multiple Payments" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:457 #: ../src/editscheduledtransactiondialog.cpp:477 msgctxt "EditScheduledMultiAccountDialog|" msgid "Edit Expense with Multiple Payments" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:457 #: ../src/editscheduledtransactiondialog.cpp:477 msgctxt "EditScheduledMultiAccountDialog|" msgid "Edit Income with Multiple Payments" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:256 msgctxt "EditScheduledMultiItemDialog|" msgid "Transactions" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:259 msgctxt "EditScheduledMultiItemDialog|" msgid "Recurrence" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:322 #: ../src/editscheduledtransactiondialog.cpp:331 #: ../src/editscheduledtransactiondialog.cpp:351 msgctxt "EditScheduledMultiItemDialog|" msgid "New Split Transaction" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:331 #: ../src/editscheduledtransactiondialog.cpp:351 msgctxt "EditScheduledMultiItemDialog|" msgid "Edit Split Transaction" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:50 msgctxt "EditScheduledTransactionDialog|" msgid "Expense" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:55 msgctxt "EditScheduledTransactionDialog|" msgid "Dividend" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:56 msgctxt "EditScheduledTransactionDialog|" msgid "Income" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:61 msgctxt "EditScheduledTransactionDialog|" msgid "Reinvested Dividend" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:66 msgctxt "EditScheduledTransactionDialog|" msgid "Transfer" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:71 msgctxt "" "EditScheduledTransactionDialog|Financial security (e.g. stock, mutual fund)" msgid "Securities Purchase" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:76 msgctxt "" "EditScheduledTransactionDialog|Financial security (e.g. stock, mutual fund)" msgid "Securities Sale" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:84 msgctxt "EditScheduledTransactionDialog|" msgid "Recurrence" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:152 #: ../src/editscheduledtransactiondialog.cpp:178 #: ../src/editscheduledtransactiondialog.cpp:203 #: ../src/editscheduledtransactiondialog.cpp:225 msgctxt "EditScheduledTransactionDialog|" msgid "New Expense" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:152 #: ../src/editscheduledtransactiondialog.cpp:178 msgctxt "EditScheduledTransactionDialog|" msgid "New Expense Paid with Loan" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:154 #: ../src/editscheduledtransactiondialog.cpp:180 #: ../src/editscheduledtransactiondialog.cpp:206 #: ../src/editscheduledtransactiondialog.cpp:227 msgctxt "EditScheduledTransactionDialog|" msgid "New Dividend" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:155 #: ../src/editscheduledtransactiondialog.cpp:181 #: ../src/editscheduledtransactiondialog.cpp:207 #: ../src/editscheduledtransactiondialog.cpp:229 msgctxt "EditScheduledTransactionDialog|" msgid "New Income" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:158 #: ../src/editscheduledtransactiondialog.cpp:184 #: ../src/editscheduledtransactiondialog.cpp:210 #: ../src/editscheduledtransactiondialog.cpp:232 msgctxt "EditScheduledTransactionDialog|" msgid "New Transfer" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:159 #: ../src/editscheduledtransactiondialog.cpp:185 #: ../src/editscheduledtransactiondialog.cpp:211 #: ../src/editscheduledtransactiondialog.cpp:233 msgctxt "" "EditScheduledTransactionDialog|Financial security (e.g. stock, mutual fund)" msgid "New Securities Purchase" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:160 #: ../src/editscheduledtransactiondialog.cpp:186 #: ../src/editscheduledtransactiondialog.cpp:205 #: ../src/editscheduledtransactiondialog.cpp:227 msgctxt "EditScheduledTransactionDialog|" msgid "New Reinvested Dividend" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:162 #: ../src/editscheduledtransactiondialog.cpp:188 #: ../src/editscheduledtransactiondialog.cpp:212 #: ../src/editscheduledtransactiondialog.cpp:234 msgctxt "" "EditScheduledTransactionDialog|Financial security (e.g. stock, mutual fund)" msgid "New Securities Sale" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:205 #: ../src/editscheduledtransactiondialog.cpp:227 msgctxt "EditScheduledTransactionDialog|" msgid "Edit Reinvested Dividend" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:211 #: ../src/editscheduledtransactiondialog.cpp:233 msgctxt "" "EditScheduledTransactionDialog|Financial security (e.g. stock, mutual fund)" msgid "Edit Securities Purchase" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:212 #: ../src/editscheduledtransactiondialog.cpp:234 msgctxt "" "EditScheduledTransactionDialog|Financial security (e.g. stock, mutual fund)" msgid "Edit Securities Sale" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:203 #: ../src/editscheduledtransactiondialog.cpp:225 msgctxt "EditScheduledTransactionDialog|" msgid "Edit Expense" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:206 #: ../src/editscheduledtransactiondialog.cpp:228 msgctxt "EditScheduledTransactionDialog|" msgid "Edit Dividend" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:207 #: ../src/editscheduledtransactiondialog.cpp:229 msgctxt "EditScheduledTransactionDialog|" msgid "Edit Income" msgstr "" #: ../src/editscheduledtransactiondialog.cpp:210 #: ../src/editscheduledtransactiondialog.cpp:232 msgctxt "EditScheduledTransactionDialog|" msgid "Edit Transfer" msgstr "" #: ../src/eqonomize.cpp:1629 msgctxt "EditSecurityDialog|" msgid "Type:" msgstr "" #: ../src/eqonomize.cpp:1632 msgctxt "EditSecurityDialog|" msgid "Mutual Fund" msgstr "" #: ../src/eqonomize.cpp:1633 msgctxt "EditSecurityDialog|Financial stock" msgid "Stock" msgstr "" #: ../src/eqonomize.cpp:1634 msgctxt "EditSecurityDialog|" msgid "Other" msgstr "" #: ../src/eqonomize.cpp:1637 msgctxt "EditSecurityDialog|" msgid "Name:" msgstr "" #: ../src/eqonomize.cpp:1640 msgctxt "EditSecurityDialog|" msgid "Account:" msgstr "" #: ../src/eqonomize.cpp:1644 msgctxt "EditSecurityDialog|Financial shares" msgid "Decimals in shares:" msgstr "" #: ../src/eqonomize.cpp:1650 msgctxt "EditSecurityDialog|Financial shares" msgid "Initial shares:" msgstr "" #: ../src/eqonomize.cpp:1653 msgctxt "EditSecurityDialog|Financial quote" msgid "Decimals in quotes:" msgstr "" #: ../src/eqonomize.cpp:1659 msgctxt "EditSecurityDialog|Financial quote" msgid "Initial quote:" msgstr "" #: ../src/eqonomize.cpp:1664 msgctxt "EditSecurityDialog|" msgid "Date:" msgstr "" #: ../src/eqonomize.cpp:1669 msgctxt "EditSecurityDialog|" msgid "Description:" msgstr "" #: ../src/eqonomize.cpp:1693 ../src/eqonomize.cpp:1706 msgctxt "EditSecurityDialog|" msgid "Error" msgstr "" #: ../src/eqonomize.cpp:1693 msgctxt "EditSecurityDialog|" msgid "Empty name." msgstr "" #: ../src/eqonomize.cpp:1706 msgctxt "EditSecurityDialog|" msgid "No suitable account available." msgstr "" #: ../src/eqonomize.cpp:831 msgctxt "EditSecurityTradeDialog|" msgid "All" msgstr "" #: ../src/eqonomize.cpp:795 msgctxt "" "EditSecurityTradeDialog|Shares of one security directly exchanged for shares " "of another; Financial security (e.g. stock, mutual fund)" msgid "Securities Exchange" msgstr "" #: ../src/eqonomize.cpp:802 msgctxt "EditSecurityTradeDialog|Financial security (e.g. stock, mutual fund)" msgid "From security:" msgstr "" #: ../src/eqonomize.cpp:826 msgctxt "EditSecurityTradeDialog|Financial shares" msgid "Shares moved:" msgstr "" #: ../src/eqonomize.cpp:837 msgctxt "EditSecurityTradeDialog|Financial security (e.g. stock, mutual fund)" msgid "To security:" msgstr "" #: ../src/eqonomize.cpp:842 msgctxt "EditSecurityTradeDialog|Financial shares" msgid "Shares received:" msgstr "" #: ../src/eqonomize.cpp:846 msgctxt "EditSecurityTradeDialog|" msgid "Date:" msgstr "" #: ../src/eqonomize.cpp:940 ../src/eqonomize.cpp:952 ../src/eqonomize.cpp:956 #: ../src/eqonomize.cpp:960 msgctxt "EditSecurityTradeDialog|" msgid "Error" msgstr "" #: ../src/eqonomize.cpp:940 msgctxt "" "EditSecurityTradeDialog|Shares of one security directly exchanged for shares " "of another; Financial security (e.g. stock, mutual fund)" msgid "No other security available for exchange in the account." msgstr "" #: ../src/eqonomize.cpp:952 msgctxt "EditSecurityTradeDialog|Financial security (e.g. stock, mutual fund)" msgid "Selected to and from securities are the same." msgstr "" #: ../src/eqonomize.cpp:960 msgctxt "EditSecurityTradeDialog|Financial shares" msgid "Zero shares not allowed." msgstr "" #: ../src/eqonomize.cpp:956 msgctxt "EditSecurityTradeDialog|" msgid "Invalid date." msgstr "" #: ../src/eqonomize.cpp:1918 msgctxt "Eqonomize|" msgid "Accounts && Categories" msgstr "" #: ../src/eqonomize.cpp:1920 ../src/eqonomize.cpp:1968 #: ../src/eqonomize.cpp:6129 msgctxt "Eqonomize|" msgid "Expenses" msgstr "" #: ../src/eqonomize.cpp:1922 ../src/eqonomize.cpp:1966 #: ../src/eqonomize.cpp:6056 msgctxt "Eqonomize|" msgid "Incomes" msgstr "" #: ../src/eqonomize.cpp:1924 msgctxt "Eqonomize|" msgid "Transfers" msgstr "" #: ../src/eqonomize.cpp:1928 msgctxt "Eqonomize|" msgid "Schedule" msgstr "" #: ../src/eqonomize.cpp:1942 msgctxt "Eqonomize|" msgid "Account / Category" msgstr "" #: ../src/eqonomize.cpp:6460 msgctxt "Eqonomize|" msgid "Accounts" msgstr "" #: ../src/eqonomize.cpp:1989 ../src/eqonomize.cpp:6234 msgctxt "Eqonomize|" msgid "Includes budgeted transactions" msgstr "" #: ../src/eqonomize.cpp:1962 ../src/eqonomize.cpp:5945 msgctxt "Eqonomize|" msgid "Assets" msgstr "" #: ../src/eqonomize.cpp:1970 ../src/eqonomize.cpp:2262 #: ../src/eqonomize.cpp:4372 ../src/eqonomize.cpp:4386 #: ../src/eqonomize.cpp:6205 ../src/eqonomize.cpp:6571 #: ../src/eqonomize.cpp:8060 msgctxt "Eqonomize|" msgid "Tags" msgstr "" #: ../src/eqonomize.cpp:1997 msgctxt "Eqonomize|" msgid "Period" msgstr "" #: ../src/eqonomize.cpp:2001 ../src/eqonomize.cpp:2182 #: ../src/eqonomize.cpp:2259 msgctxt "Eqonomize|" msgid "From" msgstr "" #: ../src/eqonomize.cpp:2012 ../src/eqonomize.cpp:2194 #: ../src/eqonomize.cpp:2260 msgctxt "Eqonomize|" msgid "To" msgstr "" #: ../src/eqonomize.cpp:2029 msgctxt "Eqonomize|" msgid "Select Period" msgstr "" #: ../src/eqonomize.cpp:2031 ../src/eqonomize.cpp:6638 msgctxt "Eqonomize|" msgid "Current Month" msgstr "" #: ../src/eqonomize.cpp:2032 ../src/eqonomize.cpp:6639 msgctxt "Eqonomize|" msgid "Current Year" msgstr "" #: ../src/eqonomize.cpp:2033 ../src/eqonomize.cpp:6640 msgctxt "Eqonomize|" msgid "Current Whole Month" msgstr "" #: ../src/eqonomize.cpp:2034 ../src/eqonomize.cpp:6641 msgctxt "Eqonomize|" msgid "Current Whole Year" msgstr "" #: ../src/eqonomize.cpp:2035 msgctxt "Eqonomize|" msgid "Whole Past Month" msgstr "" #: ../src/eqonomize.cpp:2036 msgctxt "Eqonomize|" msgid "Whole Past Year" msgstr "" #: ../src/eqonomize.cpp:2037 msgctxt "Eqonomize|" msgid "Previous Month" msgstr "" #: ../src/eqonomize.cpp:2038 msgctxt "Eqonomize|" msgid "Previous Year" msgstr "" #: ../src/eqonomize.cpp:2041 msgctxt "Eqonomize|" msgid "Show partial budget" msgstr "" #: ../src/eqonomize.cpp:2046 msgctxt "Eqonomize|" msgid "Edit Budget" msgstr "" #: ../src/eqonomize.cpp:2050 msgctxt "Eqonomize|" msgid "Budget:" msgstr "" #: ../src/eqonomize.cpp:2060 msgctxt "Eqonomize|" msgid "Month:" msgstr "" #: ../src/eqonomize.cpp:2068 msgctxt "Eqonomize|" msgid "Result previous month:" msgstr "" #: ../src/eqonomize.cpp:2134 msgctxt "Eqonomize|" msgid "New Transaction" msgstr "" #: ../src/eqonomize.cpp:2149 ../src/eqonomize.cpp:5948 #: ../src/eqonomize.cpp:6006 ../src/eqonomize.cpp:6208 msgctxt "Eqonomize|" msgid "Name" msgstr "" #: ../src/eqonomize.cpp:2150 ../src/eqonomize.cpp:6244 msgctxt "Eqonomize|" msgid "Value" msgstr "" #: ../src/eqonomize.cpp:2153 msgctxt "Eqonomize|" msgid "Cost" msgstr "" #: ../src/eqonomize.cpp:2154 msgctxt "Eqonomize|" msgid "Profit" msgstr "" #: ../src/eqonomize.cpp:2155 msgctxt "Eqonomize|" msgid "Yearly Rate" msgstr "" #: ../src/eqonomize.cpp:2156 ../src/eqonomize.cpp:2256 msgctxt "Eqonomize|" msgid "Type" msgstr "" #: ../src/eqonomize.cpp:2157 msgctxt "Eqonomize|" msgid "Account" msgstr "" #: ../src/eqonomize.cpp:2178 msgctxt "Eqonomize|" msgid "Statistics Period" msgstr "" #: ../src/eqonomize.cpp:2238 msgctxt "Eqonomize|" msgid "New Schedule" msgstr "" #: ../src/eqonomize.cpp:2241 msgctxt "Eqonomize|" msgid "Edit" msgstr "" #: ../src/eqonomize.cpp:2245 ../src/eqonomize.cpp:6537 msgctxt "Eqonomize|" msgid "Remove" msgstr "" #: ../src/eqonomize.cpp:2255 msgctxt "Eqonomize|" msgid "Next Occurrence" msgstr "" #: ../src/eqonomize.cpp:2258 msgctxt "Eqonomize|" msgid "Amount" msgstr "" #: ../src/eqonomize.cpp:2261 msgctxt "Eqonomize|" msgid "Payee/Payer" msgstr "" #: ../src/eqonomize.cpp:2263 msgctxt "Eqonomize|" msgid "Comments" msgstr "" #: ../src/eqonomize.cpp:2500 msgctxt "Eqonomize|" msgid "Set Schedule Confirmation Time" msgstr "" #: ../src/eqonomize.cpp:2503 msgctxt "Eqonomize|" msgid "Schedule confirmation time:" msgstr "" #: ../src/eqonomize.cpp:2522 msgctxt "Eqonomize|" msgid "Set Budget Period" msgstr "" #: ../src/eqonomize.cpp:2525 msgctxt "Eqonomize|" msgid "First day in budget month:" msgstr "" #: ../src/eqonomize.cpp:2527 msgctxt "Eqonomize|" msgid "1st" msgstr "" #: ../src/eqonomize.cpp:2528 msgctxt "Eqonomize|" msgid "2nd" msgstr "" #: ../src/eqonomize.cpp:2529 msgctxt "Eqonomize|" msgid "3rd" msgstr "" #: ../src/eqonomize.cpp:2530 msgctxt "Eqonomize|" msgid "4th" msgstr "" #: ../src/eqonomize.cpp:2531 msgctxt "Eqonomize|" msgid "5th" msgstr "" #: ../src/eqonomize.cpp:2532 msgctxt "Eqonomize|" msgid "6th" msgstr "" #: ../src/eqonomize.cpp:2533 msgctxt "Eqonomize|" msgid "7th" msgstr "" #: ../src/eqonomize.cpp:2534 msgctxt "Eqonomize|" msgid "8th" msgstr "" #: ../src/eqonomize.cpp:2535 msgctxt "Eqonomize|" msgid "9th" msgstr "" #: ../src/eqonomize.cpp:2536 msgctxt "Eqonomize|" msgid "10th" msgstr "" #: ../src/eqonomize.cpp:2537 msgctxt "Eqonomize|" msgid "11th" msgstr "" #: ../src/eqonomize.cpp:2538 msgctxt "Eqonomize|" msgid "12th" msgstr "" #: ../src/eqonomize.cpp:2539 msgctxt "Eqonomize|" msgid "13th" msgstr "" #: ../src/eqonomize.cpp:2540 msgctxt "Eqonomize|" msgid "14th" msgstr "" #: ../src/eqonomize.cpp:2541 msgctxt "Eqonomize|" msgid "15th" msgstr "" #: ../src/eqonomize.cpp:2542 msgctxt "Eqonomize|" msgid "16th" msgstr "" #: ../src/eqonomize.cpp:2543 msgctxt "Eqonomize|" msgid "17th" msgstr "" #: ../src/eqonomize.cpp:2544 msgctxt "Eqonomize|" msgid "18th" msgstr "" #: ../src/eqonomize.cpp:2545 msgctxt "Eqonomize|" msgid "19th" msgstr "" #: ../src/eqonomize.cpp:2546 msgctxt "Eqonomize|" msgid "20th" msgstr "" #: ../src/eqonomize.cpp:2547 msgctxt "Eqonomize|" msgid "21st" msgstr "" #: ../src/eqonomize.cpp:2548 msgctxt "Eqonomize|" msgid "22nd" msgstr "" #: ../src/eqonomize.cpp:2549 msgctxt "Eqonomize|" msgid "23rd" msgstr "" #: ../src/eqonomize.cpp:2550 msgctxt "Eqonomize|" msgid "24th" msgstr "" #: ../src/eqonomize.cpp:2551 msgctxt "Eqonomize|" msgid "25th" msgstr "" #: ../src/eqonomize.cpp:2552 msgctxt "Eqonomize|" msgid "26th" msgstr "" #: ../src/eqonomize.cpp:2553 msgctxt "Eqonomize|" msgid "27th" msgstr "" #: ../src/eqonomize.cpp:2554 msgctxt "Eqonomize|" msgid "28th" msgstr "" #: ../src/eqonomize.cpp:2555 msgctxt "Eqonomize|" msgid "Last" msgstr "" #: ../src/eqonomize.cpp:2556 msgctxt "Eqonomize|" msgid "2nd Last" msgstr "" #: ../src/eqonomize.cpp:2557 msgctxt "Eqonomize|" msgid "3rd Last" msgstr "" #: ../src/eqonomize.cpp:2558 msgctxt "Eqonomize|" msgid "4th Last" msgstr "" #: ../src/eqonomize.cpp:2559 msgctxt "Eqonomize|" msgid "5th Last" msgstr "" #: ../src/eqonomize.cpp:3561 msgctxt "Eqonomize|" msgid "Timestamp" msgstr "" #: ../src/eqonomize.cpp:5057 msgctxt "Eqonomize|" msgid "Synchronization Settings" msgstr "" #: ../src/eqonomize.cpp:5060 msgctxt "Eqonomize|" msgid "Web address:" msgstr "" #: ../src/eqonomize.cpp:5064 msgctxt "Eqonomize|" msgid "Download command:" msgstr "" #: ../src/eqonomize.cpp:6556 msgctxt "Eqonomize|duplicate as verb" msgid "Duplicate Transaction…" msgstr "" #: ../src/eqonomize.cpp:6725 msgctxt "Eqonomize|" msgid "New Tag…" msgstr "" #: ../src/eqonomize.cpp:6726 msgctxt "Eqonomize|" msgid "Rename Tag…" msgstr "" #: ../src/eqonomize.cpp:6727 msgctxt "Eqonomize|" msgid "Remove Tag" msgstr "" #: ../src/eqonomize.cpp:8079 msgctxt "Eqonomize|" msgid "New Tag" msgstr "" #: ../src/eqonomize.cpp:8079 ../src/eqonomize.cpp:8140 msgctxt "Eqonomize|" msgid "Tag name:" msgstr "" #: ../src/eqonomize.cpp:8111 msgctxt "Eqonomize|" msgid "Remove tag?" msgstr "" #: ../src/eqonomize.cpp:8111 #, qt-format msgctxt "Eqonomize|" msgid "Do you wish to remove the tag \"%1\" from %n transaction(s)?" msgid_plural "Do you wish to remove the tag \"%1\" from %n transaction(s)?" msgstr[0] "" #: ../src/eqonomize.cpp:8140 msgctxt "Eqonomize|" msgid "Rename Tag" msgstr "" #: ../src/eqonomize.cpp:6661 msgctxt "Eqonomize|" msgid "Select Font…" msgstr "" #: ../src/eqonomize.cpp:5062 ../src/eqonomize.cpp:5066 msgctxt "Eqonomize|" msgid "optional" msgstr "" #: ../src/eqonomize.cpp:5068 msgctxt "Eqonomize|" msgid "Upload command:" msgstr "" #: ../src/eqonomize.cpp:5070 msgctxt "Eqonomize|" msgid "mandatory" msgstr "" #: ../src/eqonomize.cpp:5073 msgctxt "Eqonomize|" msgid "Automatic synchronization" msgstr "" #: ../src/eqonomize.cpp:5079 msgctxt "Eqonomize|" msgid "Upload" msgstr "" #: ../src/eqonomize.cpp:5116 msgctxt "Eqonomize|" msgid "Uploading…" msgstr "" #: ../src/eqonomize.cpp:5127 msgctxt "Eqonomize|" msgid "Error uploading file" msgstr "" #: ../src/eqonomize.cpp:5127 #, qt-format msgctxt "Eqonomize|" msgid "Error uploading %1: %2." msgstr "" #: ../src/eqonomize.cpp:5159 msgctxt "Eqonomize|" msgid "Synchronizing…" msgstr "" #: ../src/eqonomize.cpp:5170 ../src/eqonomize.cpp:5179 msgctxt "Eqonomize|" msgid "Error synchronizing file" msgstr "" #: ../src/eqonomize.cpp:5170 ../src/eqonomize.cpp:5179 #, qt-format msgctxt "Eqonomize|" msgid "Error synchronizing %1: %2." msgstr "" #: ../src/eqonomize.cpp:5171 msgctxt "Eqonomize|" msgid "Synchronization error" msgstr "" #: ../src/eqonomize.cpp:5200 msgctxt "Eqonomize|" msgid "Synchronize file?" msgstr "" #: ../src/eqonomize.cpp:5200 msgctxt "Eqonomize|" msgid "" "The file has been modified by a different user or program. Do you wish to " "merge changes?" msgstr "" #: ../src/eqonomize.cpp:6533 msgctxt "Eqonomize|" msgid "Reconcile Account…" msgstr "" #: ../src/eqonomize.cpp:6657 msgctxt "Eqonomize|" msgid "Cloud Synchronization (experimental)…" msgstr "" #: ../src/eqonomize.cpp:7554 msgctxt "Eqonomize|" msgid "" "Only use this when unable to find the cause of the incorrect recorded " "account balance." msgstr "" #: ../src/eqonomize.cpp:8035 ../src/eqonomize.cpp:9674 msgctxt "Eqonomize|Mark account as not closed" msgid "Reopen Account" msgstr "" #: ../src/eqonomize.cpp:5116 ../src/eqonomize.cpp:5159 #: ../src/eqonomize.cpp:5434 msgctxt "Eqonomize|" msgid "Abort" msgstr "" #: ../src/eqonomize.cpp:5451 ../src/eqonomize.cpp:5471 #, qt-format msgctxt "Eqonomize|" msgid "Failed to download exchange rates from %1: %2." msgstr "" #: ../src/eqonomize.cpp:5456 ../src/eqonomize.cpp:5478 #, qt-format msgctxt "Eqonomize|" msgid "Error reading data from %1: %2." msgstr "" #: ../src/eqonomize.cpp:5530 msgctxt "Eqonomize|" msgid "Unrecognized Currency" msgstr "" #: ../src/eqonomize.cpp:5535 #, qt-format msgctxt "Eqonomize|" msgid "" "No exchange rate is available for the default currency (%1). If you wish to " "use multiple currencies you should set the exchange rate manually." msgstr "" #: ../src/eqonomize.cpp:5559 msgctxt "Eqonomize|" msgid "Set Main Currency" msgstr "" #: ../src/eqonomize.cpp:5564 msgctxt "Eqonomize|" msgid "Currency:" msgstr "" #: ../src/eqonomize.cpp:5584 msgctxt "Eqonomize|" msgid "Replace all occurrences of the former main currency" msgstr "" #: ../src/eqonomize.cpp:6510 msgctxt "Eqonomize|" msgid "Update Exchange Rates" msgstr "" #: ../src/eqonomize.cpp:6534 msgctxt "Eqonomize|Referring to account balance" msgid "Adjust balance…" msgstr "" #: ../src/eqonomize.cpp:6622 msgctxt "Eqonomize|" msgid "Show payee and quantity" msgstr "" #: ../src/eqonomize.cpp:6627 msgctxt "Eqonomize|" msgid "Show quantity and payer/payee properties for incomes and expenses." msgstr "" #: ../src/eqonomize.cpp:6614 msgctxt "Eqonomize|" msgid "Set Main Currency…" msgstr "" #: ../src/eqonomize.cpp:7533 msgctxt "Eqonomize|" msgid "Adjust Account Balance" msgstr "" #: ../src/eqonomize.cpp:7544 #, qt-format msgctxt "Eqonomize|Referring to account balance" msgid "of which %1 is balance adjustment" msgstr "" #: ../src/eqonomize.cpp:2825 msgctxt "Eqonomize|" msgid "Total value:" msgstr "" #: ../src/eqonomize.cpp:2825 msgctxt "Eqonomize|" msgid "Cost:" msgstr "" #: ../src/eqonomize.cpp:2825 msgctxt "Eqonomize|" msgid "Profit:" msgstr "" #: ../src/eqonomize.cpp:2825 msgctxt "Eqonomize|" msgid "Rate:" msgstr "" #: ../src/eqonomize.cpp:2950 ../src/eqonomize.cpp:2952 #: ../src/eqonomize.cpp:4561 ../src/eqonomize.cpp:4591 #: ../src/eqonomize.cpp:4684 ../src/eqonomize.cpp:4715 #: ../src/eqonomize.cpp:4995 ../src/eqonomize.cpp:5209 #: ../src/eqonomize.cpp:5451 ../src/eqonomize.cpp:5456 #: ../src/eqonomize.cpp:5471 ../src/eqonomize.cpp:5478 #: ../src/eqonomize.cpp:5482 ../src/eqonomize.cpp:5553 #: ../src/eqonomize.cpp:6277 ../src/eqonomize.cpp:6282 #: ../src/eqonomize.cpp:6287 ../src/eqonomize.cpp:6292 #: ../src/eqonomize.cpp:6297 ../src/eqonomize.cpp:6309 #: ../src/eqonomize.cpp:6314 ../src/eqonomize.cpp:6319 #: ../src/eqonomize.cpp:6324 ../src/eqonomize.cpp:6329 #: ../src/eqonomize.cpp:6366 ../src/eqonomize.cpp:6371 #: ../src/eqonomize.cpp:6376 ../src/eqonomize.cpp:6381 #: ../src/eqonomize.cpp:6386 ../src/eqonomize.cpp:6414 #: ../src/eqonomize.cpp:6421 ../src/eqonomize.cpp:6900 msgctxt "Eqonomize|" msgid "Error" msgstr "" #: ../src/eqonomize.cpp:2938 msgctxt "Eqonomize|" msgid "Date:" msgstr "" #: ../src/eqonomize.cpp:2563 msgctxt "Eqonomize|" msgid "First month in budget year:" msgstr "" #: ../src/eqonomize.cpp:2950 ../src/eqonomize.cpp:4561 #: ../src/eqonomize.cpp:4591 ../src/eqonomize.cpp:4684 #: ../src/eqonomize.cpp:4715 msgctxt "Eqonomize|" msgid "Invalid date." msgstr "" #: ../src/eqonomize.cpp:2952 msgctxt "Eqonomize|" msgid "Future dates are not allowed." msgstr "" #: ../src/eqonomize.cpp:3079 ../src/eqonomize.cpp:3163 msgctxt "Eqonomize|" msgid "Bond" msgstr "" #: ../src/eqonomize.cpp:3081 ../src/eqonomize.cpp:3165 msgctxt "Eqonomize|" msgid "Mutual Fund" msgstr "" #: ../src/eqonomize.cpp:3082 ../src/eqonomize.cpp:3166 #: ../src/eqonomize.cpp:4845 ../src/eqonomize.cpp:4850 msgctxt "Eqonomize|" msgid "Other" msgstr "" #: ../src/eqonomize.cpp:4406 msgctxt "Eqonomize|" msgid "Add Loan" msgstr "" #: ../src/eqonomize.cpp:4410 msgctxt "Eqonomize|" msgid "Add Category" msgstr "" #: ../src/eqonomize.cpp:4457 ../src/eqonomize.cpp:4468 #: ../src/eqonomize.cpp:4552 msgctxt "Eqonomize|" msgid "Ledger" msgstr "" #: ../src/eqonomize.cpp:4841 msgctxt "Eqonomize|" msgid "Cash" msgstr "" #: ../src/eqonomize.cpp:4843 msgctxt "Eqonomize|" msgid "Savings Account" msgstr "" #: ../src/eqonomize.cpp:4844 msgctxt "Eqonomize|" msgid "Salary" msgstr "" #: ../src/eqonomize.cpp:4846 msgctxt "Eqonomize|" msgid "Bills" msgstr "" #: ../src/eqonomize.cpp:4847 msgctxt "Eqonomize|" msgid "Clothing" msgstr "" #: ../src/eqonomize.cpp:4848 msgctxt "Eqonomize|" msgid "Groceries" msgstr "" #: ../src/eqonomize.cpp:4849 msgctxt "Eqonomize|" msgid "Leisure" msgstr "" #: ../src/eqonomize.cpp:4963 msgctxt "Eqonomize|" msgid "Import Options" msgstr "" #: ../src/eqonomize.cpp:4966 msgctxt "Eqonomize|" msgid "Ignore duplicate transactions" msgstr "" #: ../src/eqonomize.cpp:4968 msgctxt "Eqonomize|" msgid "Rename duplicate accounts" msgstr "" #: ../src/eqonomize.cpp:4970 msgctxt "Eqonomize|" msgid "Rename duplicate categories" msgstr "" #: ../src/eqonomize.cpp:4972 msgctxt "Eqonomize|" msgid "Rename duplicate securities" msgstr "" #: ../src/eqonomize.cpp:4991 ../src/eqonomize.cpp:5205 #: ../src/eqonomize.cpp:6894 msgctxt "Eqonomize|" msgid "Couldn't open file" msgstr "" #: ../src/eqonomize.cpp:4991 ../src/eqonomize.cpp:5205 #: ../src/eqonomize.cpp:6894 #, qt-format msgctxt "Eqonomize|" msgid "Error loading %1: %2." msgstr "" #: ../src/eqonomize.cpp:5072 msgctxt "Eqonomize|" msgid "%f = local file (temporary), %u = url" msgstr "" #: ../src/eqonomize.cpp:5184 ../src/eqonomize.cpp:5221 #: ../src/eqonomize.cpp:5267 msgctxt "Eqonomize|" msgid "Couldn't save file" msgstr "" #: ../src/eqonomize.cpp:5184 ../src/eqonomize.cpp:5221 #: ../src/eqonomize.cpp:5267 #, qt-format msgctxt "Eqonomize|" msgid "Error saving %1: %2." msgstr "" #: ../src/eqonomize.cpp:5385 msgctxt "Eqonomize|" msgid "New version available" msgstr "" #: ../src/eqonomize.cpp:5385 #, qt-format msgctxt "Eqonomize|" msgid "A new version of %1 is available.

    You can get version %2 at %3." msgstr "" #: ../src/eqonomize.cpp:5770 ../src/eqonomize.cpp:5776 msgctxt "Eqonomize|" msgid "Transaction Schedule" msgstr "" #: ../src/eqonomize.cpp:1946 ../src/eqonomize.cpp:5893 #: ../src/eqonomize.cpp:5989 ../src/eqonomize.cpp:6044 #: ../src/eqonomize.cpp:6113 ../src/eqonomize.cpp:6186 msgctxt "Eqonomize|" msgid "Total" msgstr "" #: ../src/eqonomize.cpp:5937 msgctxt "Eqonomize|html format" msgid "Accounts & Categories" msgstr "" #: ../src/eqonomize.cpp:5942 #, qt-format msgctxt "Eqonomize|html format" msgid "Accounts & Categories (%1–%2)" msgstr "" #: ../src/eqonomize.cpp:5943 #, qt-format msgctxt "Eqonomize|html format" msgid "Accounts & Categories (to %1)" msgstr "" #. Noun, how much the account balance has changed #: ../src/eqonomize.cpp:1945 ../src/eqonomize.cpp:5950 #: ../src/eqonomize.cpp:6008 ../src/eqonomize.cpp:6063 #: ../src/eqonomize.cpp:6136 ../src/eqonomize.cpp:6210 #: ../src/eqonomize.cpp:6244 msgctxt "Eqonomize|" msgid "Change" msgstr "" #: ../src/eqonomize.cpp:1964 ../src/eqonomize.cpp:6003 msgctxt "Eqonomize|" msgid "Liabilities" msgstr "" #: ../src/eqonomize.cpp:2257 msgctxt "" "Eqonomize|Transaction description property (transaction title/generic " "article name)" msgid "Description" msgstr "" #: ../src/eqonomize.cpp:6059 ../src/eqonomize.cpp:6132 msgctxt "Eqonomize|" msgid "Category" msgstr "" #: ../src/eqonomize.cpp:6060 ../src/eqonomize.cpp:6133 msgctxt "Eqonomize|" msgid "Budget" msgstr "" #: ../src/eqonomize.cpp:1943 ../src/eqonomize.cpp:6061 #: ../src/eqonomize.cpp:6134 msgctxt "Eqonomize|" msgid "Remaining Budget" msgstr "" #: ../src/eqonomize.cpp:5482 ../src/eqonomize.cpp:5553 #, qt-format msgctxt "Eqonomize|" msgid "Error saving currencies: %1." msgstr "" #: ../src/eqonomize.cpp:6064 msgctxt "Eqonomize|" msgid "Total Incomes" msgstr "" #: ../src/eqonomize.cpp:6137 msgctxt "Eqonomize|" msgid "Total Expenses" msgstr "" #. Noun, how much the account balance has changed #: ../src/eqonomize.cpp:6244 msgctxt "Eqonomize|" msgid "Account/Category" msgstr "" #: ../src/eqonomize.cpp:6277 ../src/eqonomize.cpp:6309 #: ../src/eqonomize.cpp:6366 msgctxt "Eqonomize|" msgid "Empty expenses list." msgstr "" #: ../src/eqonomize.cpp:6282 ../src/eqonomize.cpp:6314 #: ../src/eqonomize.cpp:6371 msgctxt "Eqonomize|" msgid "Empty incomes list." msgstr "" #: ../src/eqonomize.cpp:6287 ../src/eqonomize.cpp:6319 #: ../src/eqonomize.cpp:6376 msgctxt "Eqonomize|" msgid "Empty transfers list." msgstr "" #: ../src/eqonomize.cpp:6297 ../src/eqonomize.cpp:6329 #: ../src/eqonomize.cpp:6386 msgctxt "Eqonomize|" msgid "Empty schedule list." msgstr "" #: ../src/eqonomize.cpp:6414 msgctxt "Eqonomize|" msgid "Couldn't open file for writing." msgstr "" #: ../src/eqonomize.cpp:6421 msgctxt "Eqonomize|" msgid "Error while writing file; file was not saved." msgstr "" #: ../src/eqonomize.cpp:6447 msgctxt "Eqonomize|" msgid "&File" msgstr "" #: ../src/eqonomize.cpp:6448 msgctxt "Eqonomize|" msgid "&Accounts" msgstr "" #: ../src/eqonomize.cpp:6449 msgctxt "Eqonomize|" msgid "&Transactions" msgstr "" #: ../src/eqonomize.cpp:6450 msgctxt "Eqonomize|" msgid "&Loans" msgstr "" #: ../src/eqonomize.cpp:6452 msgctxt "Eqonomize|" msgid "Stat&istics" msgstr "" #: ../src/eqonomize.cpp:6453 msgctxt "Eqonomize|" msgid "S&ettings" msgstr "" #: ../src/eqonomize.cpp:6454 msgctxt "Eqonomize|" msgid "&Help" msgstr "" #: ../src/eqonomize.cpp:6456 msgctxt "Eqonomize|" msgid "File" msgstr "" #: ../src/eqonomize.cpp:6464 msgctxt "Eqonomize|" msgid "Transactions" msgstr "" #: ../src/eqonomize.cpp:6468 msgctxt "Eqonomize|" msgid "Statistics" msgstr "" #: ../src/eqonomize.cpp:6475 msgctxt "Eqonomize|" msgid "&New" msgstr "" #: ../src/eqonomize.cpp:6477 msgctxt "Eqonomize|" msgid "&Open…" msgstr "" #: ../src/eqonomize.cpp:6479 msgctxt "Eqonomize|" msgid "Open Recent" msgstr "" #: ../src/eqonomize.cpp:6489 msgctxt "Eqonomize|" msgid "Clear List" msgstr "" #: ../src/eqonomize.cpp:6491 msgctxt "Eqonomize|" msgid "&Save" msgstr "" #: ../src/eqonomize.cpp:6493 msgctxt "Eqonomize|" msgid "Save As…" msgstr "" #: ../src/eqonomize.cpp:6494 msgctxt "Eqonomize|" msgid "&Revert" msgstr "" #: ../src/eqonomize.cpp:6495 msgctxt "Eqonomize|" msgid "S&ynchronize" msgstr "" #: ../src/eqonomize.cpp:6497 msgctxt "Eqonomize|" msgid "&Print…" msgstr "" #: ../src/eqonomize.cpp:6498 msgctxt "Eqonomize|" msgid "Print Preview…" msgstr "" #: ../src/eqonomize.cpp:6501 msgctxt "Eqonomize|" msgid "Import" msgstr "" #: ../src/eqonomize.cpp:6503 msgctxt "Eqonomize|" msgid "Import CSV File…" msgstr "" #: ../src/eqonomize.cpp:6504 msgctxt "Eqonomize|" msgid "Import QIF File…" msgstr "" #: ../src/eqonomize.cpp:6505 msgctxt "Eqonomize|" msgid "Export View…" msgstr "" #: ../src/eqonomize.cpp:6507 msgctxt "Eqonomize|" msgid "Export As QIF File…" msgstr "" #: ../src/eqonomize.cpp:6515 msgctxt "Eqonomize|" msgid "&Quit" msgstr "" #: ../src/eqonomize.cpp:6517 ../src/eqonomize.cpp:6522 msgctxt "Eqonomize|" msgid "Add Account…" msgstr "" #: ../src/eqonomize.cpp:6518 msgctxt "Eqonomize|" msgid "New Account…" msgstr "" #: ../src/eqonomize.cpp:6520 msgctxt "Eqonomize|" msgid "New Income Category…" msgstr "" #: ../src/eqonomize.cpp:6521 msgctxt "Eqonomize|" msgid "New Expense Category…" msgstr "" #: ../src/eqonomize.cpp:4408 ../src/eqonomize.cpp:6523 msgctxt "Eqonomize|" msgid "Add Account" msgstr "" #: ../src/eqonomize.cpp:1926 ../src/eqonomize.cpp:5852 #: ../src/eqonomize.cpp:5858 msgctxt "Eqonomize|Financial security (e.g. stock, mutual fund)" msgid "Securities" msgstr "" #: ../src/eqonomize.cpp:2132 ../src/eqonomize.cpp:6588 msgctxt "Eqonomize|Financial security (e.g. stock, mutual fund)" msgid "New Security…" msgstr "" #: ../src/eqonomize.cpp:2151 msgctxt "Eqonomize|Financial shares" msgid "Shares" msgstr "" #: ../src/eqonomize.cpp:2754 msgctxt "Eqonomize|Financial security (e.g. stock, mutual fund)" msgid "New Security" msgstr "" #: ../src/eqonomize.cpp:2790 msgctxt "Eqonomize|Financial security (e.g. stock, mutual fund)" msgid "Edit Security" msgstr "" #: ../src/eqonomize.cpp:2832 msgctxt "Eqonomize|Financial security (e.g. stock, mutual fund)" msgid "Delete security?" msgstr "" #: ../src/eqonomize.cpp:2832 #, qt-format msgctxt "Eqonomize|Financial security (e.g. stock, mutual fund)" msgid "" "Are you sure you want to delete the security \"%1\" and all associated " "transactions?" msgstr "" #: ../src/eqonomize.cpp:2933 msgctxt "Eqonomize|Financial shares" msgid "Price per share:" msgstr "" #: ../src/eqonomize.cpp:2979 msgctxt "Eqonomize|Financial security (e.g. stock, mutual fund)" msgid "Security Transactions" msgstr "" #: ../src/eqonomize.cpp:3080 ../src/eqonomize.cpp:3164 msgctxt "Eqonomize|Financial stock" msgid "Stock" msgstr "" #: ../src/eqonomize.cpp:5434 msgctxt "Eqonomize|" msgid "Updating exchange rates…" msgstr "" #: ../src/eqonomize.cpp:5568 ../src/eqonomize.cpp:5621 msgctxt "Eqonomize|" msgid "New currency…" msgstr "" #: ../src/eqonomize.cpp:5953 ../src/eqonomize.cpp:6010 #: ../src/eqonomize.cpp:6212 msgctxt "Eqonomize|Noun. Balance of an account" msgid "Balance" msgstr "" #: ../src/eqonomize.cpp:6292 ../src/eqonomize.cpp:6324 #: ../src/eqonomize.cpp:6381 msgctxt "Eqonomize|Financial security (e.g. stock, mutual fund)" msgid "Empty securities list." msgstr "" #: ../src/eqonomize.cpp:6451 msgctxt "Eqonomize|Financial security (e.g. stock, mutual fund)" msgid "&Securities" msgstr "" #: ../src/eqonomize.cpp:6502 #, qt-format msgctxt "Eqonomize|" msgid "Import %1 File…" msgstr "" #: ../src/eqonomize.cpp:6509 msgctxt "Eqonomize|" msgid "Currency Converter" msgstr "" #: ../src/eqonomize.cpp:6519 msgctxt "Eqonomize|" msgid "New Loan…" msgstr "" #: ../src/eqonomize.cpp:6532 msgctxt "Eqonomize|" msgid "Edit…" msgstr "" #: ../src/eqonomize.cpp:6539 msgctxt "Eqonomize|" msgid "Show Transactions" msgstr "" #: ../src/eqonomize.cpp:6540 msgctxt "Eqonomize|" msgid "Show Ledger" msgstr "" #: ../src/eqonomize.cpp:6543 msgctxt "Eqonomize|" msgid "New Expense…" msgstr "" #: ../src/eqonomize.cpp:6545 msgctxt "Eqonomize|" msgid "New Income…" msgstr "" #: ../src/eqonomize.cpp:6547 msgctxt "Eqonomize|" msgid "New Transfer…" msgstr "" #: ../src/eqonomize.cpp:6549 msgctxt "Eqonomize|" msgid "New Split Transaction…" msgstr "" #: ../src/eqonomize.cpp:6551 msgctxt "Eqonomize|" msgid "New Expense with Multiple Payments…" msgstr "" #: ../src/eqonomize.cpp:6552 msgctxt "Eqonomize|" msgid "Refund…" msgstr "" #: ../src/eqonomize.cpp:6553 msgctxt "Eqonomize|" msgid "Repayment…" msgstr "" #: ../src/eqonomize.cpp:6554 msgctxt "Eqonomize|" msgid "New Refund/Repayment…" msgstr "" #: ../src/eqonomize.cpp:6558 msgctxt "Eqonomize|" msgid "Edit Transaction(s) (Occurrence)…" msgstr "" #: ../src/eqonomize.cpp:6559 msgctxt "Eqonomize|" msgid "Edit Occurrence…" msgstr "" #: ../src/eqonomize.cpp:6560 msgctxt "Eqonomize|" msgid "Edit Schedule (Recurrence)…" msgstr "" #: ../src/eqonomize.cpp:6561 msgctxt "Eqonomize|" msgid "Edit Schedule…" msgstr "" #: ../src/eqonomize.cpp:6562 msgctxt "Eqonomize|" msgid "Edit Split Transaction…" msgstr "" #: ../src/eqonomize.cpp:6563 msgctxt "Eqonomize|" msgid "Join Transactions…" msgstr "" #: ../src/eqonomize.cpp:6574 msgctxt "Eqonomize|" msgid "Edit Timestamp…" msgstr "" #: ../src/eqonomize.cpp:6583 msgctxt "Eqonomize|" msgid "New Debt Payment…" msgstr "" #: ../src/eqonomize.cpp:6584 msgctxt "Eqonomize|" msgid "New Unpaid Interest…" msgstr "" #: ../src/eqonomize.cpp:6585 msgctxt "Eqonomize|" msgid "New Expense Paid with Loan…" msgstr "" #: ../src/eqonomize.cpp:6589 msgctxt "Eqonomize|Financial security (e.g. stock, mutual fund)" msgid "Edit Security…" msgstr "" #: ../src/eqonomize.cpp:6590 msgctxt "Eqonomize|Financial security (e.g. stock, mutual fund)" msgid "Remove Security" msgstr "" #: ../src/eqonomize.cpp:6592 msgctxt "Eqonomize|Financial shares" msgid "Shares Bought…" msgstr "" #: ../src/eqonomize.cpp:6593 msgctxt "Eqonomize|Financial shares" msgid "Shares Sold…" msgstr "" #: ../src/eqonomize.cpp:6616 msgctxt "Eqonomize|" msgid "Use Exchange Rate for Transaction Date" msgstr "" #: ../src/eqonomize.cpp:6621 msgctxt "Eqonomize|" msgid "" "Use the exchange rate nearest the transaction date, instead of the latest " "available rate, when converting the value of transactions." msgstr "" #: ../src/eqonomize.cpp:6633 msgctxt "Eqonomize|" msgid "Set Budget Period…" msgstr "" #: ../src/eqonomize.cpp:6631 msgctxt "Eqonomize|" msgid "Set Schedule Confirmation Time…" msgstr "" #: ../src/eqonomize.cpp:6647 msgctxt "Eqonomize|" msgid "Backup Frequency" msgstr "" #: ../src/eqonomize.cpp:6650 msgctxt "Eqonomize|" msgid "Daily" msgstr "" #: ../src/eqonomize.cpp:6651 msgctxt "Eqonomize|" msgid "Weekly" msgstr "" #: ../src/eqonomize.cpp:6652 msgctxt "Eqonomize|" msgid "Fortnightly" msgstr "" #: ../src/eqonomize.cpp:6653 msgctxt "Eqonomize|" msgid "Monthly" msgstr "" #: ../src/eqonomize.cpp:6654 msgctxt "Eqonomize|" msgid "Never" msgstr "" #: ../src/eqonomize.cpp:6664 msgctxt "Eqonomize|" msgid "Language" msgstr "" #: ../src/eqonomize.cpp:6668 msgctxt "Eqonomize|" msgid "Default" msgstr "" #: ../src/eqonomize.cpp:6721 ../src/eqonomize.cpp:6872 #, qt-format msgctxt "Eqonomize|" msgid "About %1" msgstr "" #: ../src/eqonomize.cpp:6811 msgctxt "Eqonomize|" msgid "Restart required" msgstr "" #: ../src/eqonomize.cpp:6811 msgctxt "Eqonomize|" msgid "Please restart the application for the language change to take effect." msgstr "" #: ../src/eqonomize.cpp:6872 msgctxt "Eqonomize|" msgid "A personal accounting program" msgstr "" #: ../src/eqonomize.cpp:6872 msgctxt "Eqonomize|" msgid "License: GNU General Public License Version 3" msgstr "" #: ../src/eqonomize.cpp:6889 #, qt-format msgctxt "Eqonomize|" msgid "" "%1 exited unexpectedly before the file was saved and data was lost.\n" "Do you want to load the last auto-saved version of the file?" msgstr "" #: ../src/eqonomize.cpp:6564 msgctxt "Eqonomize|" msgid "Split Up Transaction" msgstr "" #: ../src/eqonomize.cpp:6536 ../src/eqonomize.cpp:8038 #: ../src/eqonomize.cpp:9678 msgctxt "Eqonomize|Mark account as closed" msgid "Close Account" msgstr "" #: ../src/eqonomize.cpp:6576 msgctxt "Eqonomize|" msgid "Remove Transaction(s) (Occurrence)" msgstr "" #: ../src/eqonomize.cpp:6577 msgctxt "Eqonomize|" msgid "Remove Occurrence" msgstr "" #: ../src/eqonomize.cpp:6578 msgctxt "Eqonomize|" msgid "Delete Schedule (Recurrence)" msgstr "" #: ../src/eqonomize.cpp:6579 msgctxt "Eqonomize|" msgid "Delete Schedule" msgstr "" #: ../src/eqonomize.cpp:6580 msgctxt "Eqonomize|" msgid "Remove Split Transaction" msgstr "" #: ../src/eqonomize.cpp:6596 msgctxt "Eqonomize|" msgid "Dividend…" msgstr "" #: ../src/eqonomize.cpp:6597 msgctxt "Eqonomize|" msgid "Reinvested Dividend…" msgstr "" #: ../src/eqonomize.cpp:6599 msgctxt "Eqonomize|" msgid "Transactions…" msgstr "" #: ../src/eqonomize.cpp:6604 msgctxt "Eqonomize|" msgid "Development Over Time Report…" msgstr "" #: ../src/eqonomize.cpp:6606 msgctxt "Eqonomize|" msgid "Categories Comparison Report…" msgstr "" #: ../src/eqonomize.cpp:6609 msgctxt "Eqonomize|" msgid "Development Over Time Chart…" msgstr "" #: ../src/eqonomize.cpp:6611 msgctxt "Eqonomize|" msgid "Categories Comparison Chart…" msgstr "" #: ../src/eqonomize.cpp:6635 msgctxt "Eqonomize|" msgid "Initial Period" msgstr "" #: ../src/eqonomize.cpp:6642 msgctxt "Eqonomize|" msgid "Remember Last Dates" msgstr "" #: ../src/eqonomize.cpp:6716 ../src/eqonomize.cpp:6845 msgctxt "Eqonomize|" msgid "Help" msgstr "" #: ../src/eqonomize.cpp:6719 msgctxt "Eqonomize|" msgid "Report Bug" msgstr "" #: ../src/eqonomize.cpp:6723 msgctxt "Eqonomize|" msgid "About Qt" msgstr "" #: ../src/eqonomize.cpp:6889 msgctxt "Eqonomize|" msgid "Crash Recovery" msgstr "" #: ../src/eqonomize.cpp:4828 ../src/eqonomize.cpp:7100 msgctxt "Eqonomize|" msgid "Untitled" msgstr "" #: ../src/eqonomize.cpp:4842 msgctxt "Eqonomize|Transactional account" msgid "Checking Account" msgstr "" #: ../src/eqonomize.cpp:6572 msgctxt "Eqonomize|" msgid "Select Associated File" msgstr "" #: ../src/eqonomize.cpp:6573 msgctxt "Eqonomize|" msgid "Open Associated File" msgstr "" #: ../src/eqonomize.cpp:6594 msgctxt "" "Eqonomize|Shares of one security directly exchanged for shares of another; " "Financial shares" msgid "Shares Exchanged…" msgstr "" #: ../src/eqonomize.cpp:6595 msgctxt "Eqonomize|Financial shares" msgid "Shares of one security directly exchanged for shares of another" msgstr "" #: ../src/eqonomize.cpp:6602 msgctxt "Eqonomize|Financial quote" msgid "Edit Quotes…" msgstr "" #: ../src/eqonomize.cpp:5314 ../src/eqonomize.cpp:7131 msgctxt "Eqonomize|" msgid "Eqonomize! Accounting File" msgstr "" #: ../src/eqonomize.cpp:7190 msgctxt "Eqonomize|" msgid "Save file?" msgstr "" #: ../src/eqonomize.cpp:7190 msgctxt "Eqonomize|" msgid "The current file has been modified. Do you want to save it?" msgstr "" #: ../src/eqonomize.cpp:7231 msgctxt "Eqonomize|" msgid "Confirm Schedule" msgstr "" #: ../src/eqonomize.cpp:7353 msgctxt "Eqonomize|" msgid "New Account" msgstr "" #: ../src/eqonomize.cpp:7380 msgctxt "Eqonomize|" msgid "New Loan" msgstr "" #: ../src/eqonomize.cpp:7417 msgctxt "Eqonomize|" msgid "New Income Category" msgstr "" #: ../src/eqonomize.cpp:7434 msgctxt "Eqonomize|" msgid "New Expense Category" msgstr "" #: ../src/eqonomize.cpp:7540 msgctxt "Eqonomize|" msgid "Book value:" msgstr "" #: ../src/eqonomize.cpp:7547 msgctxt "Eqonomize|" msgid "Real value:" msgstr "" #: ../src/eqonomize.cpp:7608 msgctxt "Eqonomize|" msgid "Edit Account" msgstr "" #: ../src/eqonomize.cpp:7701 msgctxt "Eqonomize|" msgid "Edit Income Category" msgstr "" #: ../src/eqonomize.cpp:7740 msgctxt "Eqonomize|" msgid "Edit Expense Category" msgstr "" #: ../src/eqonomize.cpp:7852 msgctxt "Eqonomize|" msgid "Remove subcategories?" msgstr "" #: ../src/eqonomize.cpp:7852 msgctxt "Eqonomize|" msgid "Do you wish to remove the category including all subcategories?" msgstr "" #: ../src/eqonomize.cpp:7901 msgctxt "Eqonomize|" msgid "Move transactions?" msgstr "" #: ../src/eqonomize.cpp:7910 msgctxt "Eqonomize|" msgid "Move to:" msgstr "" #: ../src/eqonomize.cpp:7912 msgctxt "Eqonomize|" msgid "" "Remove irreversibly from all accounts\n" "(do not do this if account has been closed!)" msgstr "" #: ../src/eqonomize.cpp:7919 msgctxt "Eqonomize|" msgid "" "The category contains some expenses.\n" "What do you want to do with them?" msgstr "" #: ../src/eqonomize.cpp:7930 msgctxt "Eqonomize|" msgid "" "The category contains some incomes.\n" "What do you want to do with them?" msgstr "" #: ../src/eqonomize.cpp:7941 msgctxt "Eqonomize|" msgid "" "The account contains some transactions.\n" "What do you want to do with them?" msgstr "" #: ../src/eqonomize.cpp:7969 ../src/eqonomize.cpp:7970 msgctxt "Eqonomize|" msgid "Remove Category?" msgstr "" #: ../src/eqonomize.cpp:7969 msgctxt "Eqonomize|" msgid "" "The category contains some expenses that will be removed. Do you still want " "to remove the category?" msgstr "" #: ../src/eqonomize.cpp:7970 msgctxt "Eqonomize|" msgid "" "The category contains some incomes that will be removed. Do you still want " "to remove the category?" msgstr "" #: ../src/eqonomize.cpp:7971 msgctxt "Eqonomize|" msgid "Remove Account?" msgstr "" #: ../src/eqonomize.cpp:7971 msgctxt "Eqonomize|" msgid "" "The account contains some transactions that will be removed. Do you still " "want to remove the account?" msgstr "" #: ../src/eqonomize.cpp:1959 ../src/eqonomize.cpp:9173 #: ../src/eqonomize.cpp:9198 ../src/eqonomize.cpp:9528 #: ../src/eqonomize.cpp:9529 #, qt-format msgctxt "Eqonomize|%1: budget; %2: remaining budget" msgid "%2 of %1" msgstr "" #: ../src/eqonomize.cpp:2137 ../src/eqonomize.cpp:6601 msgctxt "Eqonomize|Financial quote" msgid "Set Quote…" msgstr "" #: ../src/eqonomize.cpp:2152 msgctxt "Eqonomize|Financial quote" msgid "Quote" msgstr "" #: ../src/eqonomize.cpp:2928 #, qt-format msgctxt "Eqonomize|Financial quote" msgid "Set Quote (%1)" msgstr "" #: ../src/eqonomize.cpp:9634 ../src/eqonomize.cpp:9658 #, qt-format msgctxt "Eqonomize|" msgid "%1 (with no budget)" msgstr "" #: ../src/eqonomize.cpp:9635 ../src/eqonomize.cpp:9659 #, qt-format msgctxt "Eqonomize|" msgid "%1 (with budget %2)" msgstr "" #. Only used when Qt translation is missing #: ../src/eqonomize.cpp:9992 msgctxt "EqonomizeTranslator|" msgid "OK" msgstr "" #. Only used when Qt translation is missing #: ../src/eqonomize.cpp:9994 msgctxt "EqonomizeTranslator|" msgid "Cancel" msgstr "" #. Only used when Qt translation is missing #: ../src/eqonomize.cpp:9996 msgctxt "EqonomizeTranslator|" msgid "Close" msgstr "" #. Only used when Qt translation is missing #: ../src/eqonomize.cpp:9998 msgctxt "EqonomizeTranslator|" msgid "&Yes" msgstr "" #. Only used when Qt translation is missing #: ../src/eqonomize.cpp:10000 msgctxt "EqonomizeTranslator|" msgid "&No" msgstr "" #. Only used when Qt translation is missing #: ../src/eqonomize.cpp:10002 msgctxt "EqonomizeTranslator|" msgid "&Open" msgstr "" #. Only used when Qt translation is missing #: ../src/eqonomize.cpp:10004 msgctxt "EqonomizeTranslator|" msgid "&Save" msgstr "" #. Only used when Qt translation is missing #: ../src/eqonomize.cpp:10006 msgctxt "EqonomizeTranslator|" msgid "Look in:" msgstr "" #. Only used when Qt translation is missing #: ../src/eqonomize.cpp:10008 msgctxt "EqonomizeTranslator|" msgid "File &name:" msgstr "" #. Only used when Qt translation is missing #: ../src/eqonomize.cpp:10010 msgctxt "EqonomizeTranslator|" msgid "Files of type:" msgstr "" #: ../src/eqonomizevalueedit.cpp:292 ../src/eqonomizevalueedit.cpp:509 msgctxt "EqonomizeValueEdit|" msgid "Error" msgstr "" #: ../src/eqonomizevalueedit.cpp:397 msgctxt "EqonomizeValueEdit|" msgid "Empty denominator." msgstr "" #: ../src/eqonomizevalueedit.cpp:399 msgctxt "EqonomizeValueEdit|" msgid "Empty factor." msgstr "" #: ../src/eqonomizevalueedit.cpp:406 msgctxt "EqonomizeValueEdit|" msgid "Division by zero." msgstr "" #: ../src/eqonomizevalueedit.cpp:465 ../src/eqonomizevalueedit.cpp:483 #: ../src/eqonomizevalueedit.cpp:497 #, qt-format msgctxt "EqonomizeValueEdit|" msgid "" "Unknown or ambiguous currency, or unrecognized characters, in expression: %1." msgstr "" #: ../src/eqonomizevalueedit.cpp:504 msgctxt "EqonomizeValueEdit|" msgid "Empty base." msgstr "" #: ../src/eqonomizevalueedit.cpp:509 msgctxt "EqonomizeValueEdit|" msgid "Empty exponent." msgstr "" #: ../src/eqonomizevalueedit.cpp:532 msgctxt "EqonomizeValueEdit|" msgid "Unrecognized characters in expression." msgstr "" #: ../src/qifimportexport.cpp:451 msgctxt "ExportQIFDialog|" msgid "Export QIF File" msgstr "" #: ../src/qifimportexport.cpp:459 msgctxt "ExportQIFDialog|" msgid "Account:" msgstr "" #: ../src/qifimportexport.cpp:468 msgctxt "ExportQIFDialog|All accounts" msgid "All" msgstr "" #: ../src/qifimportexport.cpp:472 msgctxt "ExportQIFDialog|" msgid "Date format:" msgstr "" #: ../src/qifimportexport.cpp:480 msgctxt "ExportQIFDialog|" msgid "Value format:" msgstr "" #: ../src/qifimportexport.cpp:487 msgctxt "ExportQIFDialog|" msgid "File:" msgstr "" #: ../src/qifimportexport.cpp:543 ../src/qifimportexport.cpp:557 #: ../src/qifimportexport.cpp:567 msgctxt "ExportQIFDialog|" msgid "Error" msgstr "" #: ../src/qifimportexport.cpp:543 msgctxt "ExportQIFDialog|" msgid "Selected file is a directory." msgstr "" #: ../src/qifimportexport.cpp:550 msgctxt "ExportQIFDialog|" msgid "Overwrite" msgstr "" #: ../src/qifimportexport.cpp:550 msgctxt "ExportQIFDialog|" msgid "" "The selected file already exists. Would you like to overwrite the old copy?" msgstr "" #: ../src/qifimportexport.cpp:557 msgctxt "ExportQIFDialog|" msgid "Couldn't open file for writing." msgstr "" #: ../src/qifimportexport.cpp:567 msgctxt "ExportQIFDialog|" msgid "Error while writing file; file was not saved." msgstr "" #: ../src/importcsvdialog.cpp:63 msgctxt "ImportCSVDialog|" msgid "Import CSV file" msgstr "" #: ../src/importcsvdialog.cpp:67 msgctxt "ImportCSVDialog|" msgid "Transaction Type Selection" msgstr "" #: ../src/importcsvdialog.cpp:73 msgctxt "ImportCSVDialog|" msgid "Expenses" msgstr "" #: ../src/importcsvdialog.cpp:78 msgctxt "ImportCSVDialog|" msgid "Incomes" msgstr "" #: ../src/importcsvdialog.cpp:81 msgctxt "ImportCSVDialog|" msgid "Transfers" msgstr "" #: ../src/importcsvdialog.cpp:84 msgctxt "ImportCSVDialog|" msgid "Expenses and incomes (negative cost)" msgstr "" #: ../src/importcsvdialog.cpp:87 msgctxt "ImportCSVDialog|" msgid "Expenses and incomes (separate columns)" msgstr "" #: ../src/importcsvdialog.cpp:90 msgctxt "ImportCSVDialog|" msgid "All types" msgstr "" #: ../src/importcsvdialog.cpp:99 msgctxt "ImportCSVDialog|" msgid "File Selection" msgstr "" #: ../src/importcsvdialog.cpp:103 msgctxt "ImportCSVDialog|" msgid "File:" msgstr "" #: ../src/importcsvdialog.cpp:113 msgctxt "ImportCSVDialog|" msgid "First data row:" msgstr "" #: ../src/importcsvdialog.cpp:116 msgctxt "ImportCSVDialog|" msgid "Auto" msgstr "" #: ../src/importcsvdialog.cpp:119 msgctxt "ImportCSVDialog|" msgid "Column delimiter:" msgstr "" #: ../src/importcsvdialog.cpp:122 msgctxt "ImportCSVDialog|" msgid "Comma" msgstr "" #: ../src/importcsvdialog.cpp:123 msgctxt "ImportCSVDialog|" msgid "Tabulator" msgstr "" #: ../src/importcsvdialog.cpp:124 msgctxt "ImportCSVDialog|" msgid "Semicolon" msgstr "" #: ../src/importcsvdialog.cpp:125 msgctxt "ImportCSVDialog|" msgid "Space" msgstr "" #: ../src/importcsvdialog.cpp:126 msgctxt "ImportCSVDialog|" msgid "Other" msgstr "" #: ../src/importcsvdialog.cpp:134 msgctxt "ImportCSVDialog|" msgid "Columns Specification" msgstr "" #: ../src/importcsvdialog.cpp:159 msgctxt "" "ImportCSVDialog|Transaction description property (transaction title/generic " "article name)" msgid "Description:" msgstr "" #: ../src/importcsvdialog.cpp:142 ../src/importcsvdialog.cpp:161 #: ../src/importcsvdialog.cpp:180 ../src/importcsvdialog.cpp:199 #: ../src/importcsvdialog.cpp:218 ../src/importcsvdialog.cpp:238 #: ../src/importcsvdialog.cpp:260 ../src/importcsvdialog.cpp:279 #: ../src/importcsvdialog.cpp:300 ../src/importcsvdialog.cpp:318 msgctxt "ImportCSVDialog|" msgid "Column" msgstr "" #: ../src/importcsvdialog.cpp:150 ../src/importcsvdialog.cpp:169 #: ../src/importcsvdialog.cpp:188 ../src/importcsvdialog.cpp:207 #: ../src/importcsvdialog.cpp:226 ../src/importcsvdialog.cpp:246 #: ../src/importcsvdialog.cpp:268 ../src/importcsvdialog.cpp:287 #: ../src/importcsvdialog.cpp:308 ../src/importcsvdialog.cpp:326 msgctxt "ImportCSVDialog|" msgid "Value" msgstr "" #: ../src/importcsvdialog.cpp:177 ../src/importcsvdialog.cpp:196 #: ../src/importcsvdialog.cpp:496 msgctxt "ImportCSVDialog|" msgid "Cost:" msgstr "" #: ../src/importcsvdialog.cpp:140 msgctxt "ImportCSVDialog|" msgid "Date:" msgstr "" #: ../src/importcsvdialog.cpp:215 ../src/importcsvdialog.cpp:497 #: ../src/importcsvdialog.cpp:509 ../src/importcsvdialog.cpp:536 #: ../src/importcsvdialog.cpp:548 msgctxt "ImportCSVDialog|" msgid "Category:" msgstr "" #: ../src/importcsvdialog.cpp:235 ../src/importcsvdialog.cpp:498 #: ../src/importcsvdialog.cpp:521 msgctxt "ImportCSVDialog|" msgid "From account:" msgstr "" #: ../src/importcsvdialog.cpp:257 msgctxt "ImportCSVDialog|" msgid "Quantity:" msgstr "" #: ../src/importcsvdialog.cpp:276 ../src/importcsvdialog.cpp:499 msgctxt "ImportCSVDialog|" msgid "Payee:" msgstr "" #: ../src/importcsvdialog.cpp:297 msgctxt "ImportCSVDialog|" msgid "Tags:" msgstr "" #: ../src/importcsvdialog.cpp:316 msgctxt "ImportCSVDialog|" msgid "Comments:" msgstr "" #: ../src/importcsvdialog.cpp:336 msgctxt "ImportCSVDialog|" msgid "Create missing categories and accounts" msgstr "" #: ../src/importcsvdialog.cpp:495 msgctxt "ImportCSVDialog|" msgid "" "Imports data as expenses. Costs have positive value. Value is the only " "required column." msgstr "" #: ../src/importcsvdialog.cpp:507 msgctxt "ImportCSVDialog|" msgid "Imports data as incomes. Value is the only required column." msgstr "" #: ../src/importcsvdialog.cpp:508 ../src/importcsvdialog.cpp:547 msgctxt "ImportCSVDialog|" msgid "Income:" msgstr "" #: ../src/importcsvdialog.cpp:510 ../src/importcsvdialog.cpp:522 msgctxt "ImportCSVDialog|" msgid "To account:" msgstr "" #: ../src/importcsvdialog.cpp:511 msgctxt "ImportCSVDialog|" msgid "Payer:" msgstr "" #: ../src/importcsvdialog.cpp:519 msgctxt "ImportCSVDialog|" msgid "Imports data as transfers. Value is the only required column." msgstr "" #: ../src/importcsvdialog.cpp:520 msgctxt "ImportCSVDialog|" msgid "Amount:" msgstr "" #: ../src/importcsvdialog.cpp:530 msgctxt "ImportCSVDialog|" msgid "" "Imports data as expenses and incomes. Costs have negative value. Value and " "category are both required columns." msgstr "" #: ../src/importcsvdialog.cpp:535 ../src/importcsvdialog.cpp:563 msgctxt "ImportCSVDialog|" msgid "Value:" msgstr "" #: ../src/importcsvdialog.cpp:537 ../src/importcsvdialog.cpp:549 msgctxt "ImportCSVDialog|" msgid "Account:" msgstr "" #: ../src/importcsvdialog.cpp:538 ../src/importcsvdialog.cpp:550 #: ../src/importcsvdialog.cpp:566 msgctxt "ImportCSVDialog|" msgid "Payee/payer:" msgstr "" #: ../src/importcsvdialog.cpp:542 msgctxt "ImportCSVDialog|" msgid "" "Imports data as expenses and incomes. Costs and incomes have separate " "columns. Income, cost, and category are all required columns." msgstr "" #: ../src/importcsvdialog.cpp:554 msgctxt "ImportCSVDialog|" msgid "" "Imports data as expenses, incomes, and transfers. Costs have negative or " "positive value. Value, to, and from are all required columns. Accounts and " "categories must be existing." msgstr "" #: ../src/importcsvdialog.cpp:564 msgctxt "ImportCSVDialog|" msgid "From:" msgstr "" #: ../src/importcsvdialog.cpp:565 msgctxt "ImportCSVDialog|" msgid "To:" msgstr "" #: ../src/importcsvdialog.cpp:592 ../src/importcsvdialog.cpp:598 #: ../src/importcsvdialog.cpp:602 ../src/importcsvdialog.cpp:608 #: ../src/importcsvdialog.cpp:880 ../src/importcsvdialog.cpp:914 #: ../src/importcsvdialog.cpp:922 ../src/importcsvdialog.cpp:937 #: ../src/importcsvdialog.cpp:940 ../src/importcsvdialog.cpp:1434 #: ../src/importcsvdialog.cpp:1445 msgctxt "ImportCSVDialog|" msgid "Error" msgstr "" #: ../src/importcsvdialog.cpp:592 msgctxt "ImportCSVDialog|" msgid "A file must be selected." msgstr "" #: ../src/importcsvdialog.cpp:598 msgctxt "ImportCSVDialog|" msgid "Selected file is a directory." msgstr "" #: ../src/importcsvdialog.cpp:602 msgctxt "ImportCSVDialog|" msgid "Selected file does not exist." msgstr "" #: ../src/importcsvdialog.cpp:608 msgctxt "ImportCSVDialog|" msgid "Empty delimiter." msgstr "" #: ../src/importcsvdialog.cpp:880 msgctxt "ImportCSVDialog|" msgid "The same column number is selected multiple times." msgstr "" #: ../src/importcsvdialog.cpp:914 msgctxt "ImportCSVDialog|" msgid "Selected from account is the same as the to account." msgstr "" #: ../src/importcsvdialog.cpp:922 ../src/importcsvdialog.cpp:1422 msgctxt "ImportCSVDialog|" msgid "Invalid date." msgstr "" #: ../src/importcsvdialog.cpp:937 #, qt-format msgctxt "ImportCSVDialog|" msgid "Couldn't open %1 for reading." msgstr "" #: ../src/importcsvdialog.cpp:940 #, qt-format msgctxt "ImportCSVDialog|" msgid "Error reading %1." msgstr "" #: ../src/importcsvdialog.cpp:1413 #, qt-format msgctxt "ImportCSVDialog|" msgid "Successfully imported %n transaction(s)." msgid_plural "Successfully imported %n transaction(s)." msgstr[0] "" #: ../src/importcsvdialog.cpp:1415 msgctxt "ImportCSVDialog|" msgid "Unable to import any transactions." msgstr "" #: ../src/importcsvdialog.cpp:1419 #, qt-format msgctxt "ImportCSVDialog|" msgid "Failed to import %n data row(s)." msgid_plural "Failed to import %n data row(s)." msgstr[0] "" #: ../src/importcsvdialog.cpp:1428 msgctxt "" "ImportCSVDialog|Referring to the account used for adjustments of account " "balances." msgid "Balancing account wrongly used." msgstr "" #: ../src/importcsvdialog.cpp:1420 msgctxt "ImportCSVDialog|" msgid "Required columns missing." msgstr "" #: ../src/importcsvdialog.cpp:1421 msgctxt "ImportCSVDialog|" msgid "Invalid value." msgstr "" #: ../src/importcsvdialog.cpp:1423 msgctxt "ImportCSVDialog|" msgid "Empty category name." msgstr "" #: ../src/importcsvdialog.cpp:1423 ../src/importcsvdialog.cpp:1424 msgctxt "ImportCSVDialog|" msgid "Empty account name." msgstr "" #: ../src/importcsvdialog.cpp:1425 msgctxt "ImportCSVDialog|" msgid "Unknown category found." msgstr "" #: ../src/importcsvdialog.cpp:1425 ../src/importcsvdialog.cpp:1426 msgctxt "ImportCSVDialog|" msgid "Unknown account found." msgstr "" #: ../src/importcsvdialog.cpp:1427 msgctxt "ImportCSVDialog|" msgid "Cannot import security transactions (to/from security accounts)." msgstr "" #: ../src/importcsvdialog.cpp:1429 msgctxt "ImportCSVDialog|" msgid "Same to and from account/category." msgstr "" #: ../src/importcsvdialog.cpp:1431 msgctxt "ImportCSVDialog|" msgid "No data found." msgstr "" #: ../src/importcsvdialog.cpp:1436 msgctxt "ImportCSVDialog|" msgid "Information" msgstr "" #: ../src/importcsvdialog.cpp:1445 msgctxt "ImportCSVDialog|" msgid "Unrecognized date format." msgstr "" #: ../src/importcsvdialog.cpp:1450 msgctxt "ImportCSVDialog|" msgid "Specify Format" msgstr "" #: ../src/importcsvdialog.cpp:1455 msgctxt "ImportCSVDialog|" msgid "" "The format of dates and/or numbers in the CSV file is ambiguous. Please " "select the correct format." msgstr "" #: ../src/importcsvdialog.cpp:1460 msgctxt "ImportCSVDialog|" msgid "Date format:" msgstr "" #: ../src/importcsvdialog.cpp:1503 msgctxt "ImportCSVDialog|" msgid "Value format:" msgstr "" #: ../src/qifimportexport.cpp:65 msgctxt "ImportQIFDialog|" msgid "Import QIF file" msgstr "" #: ../src/qifimportexport.cpp:71 msgctxt "ImportQIFDialog|" msgid "File Selection" msgstr "" #: ../src/qifimportexport.cpp:72 msgctxt "ImportQIFDialog|" msgid "" "Select a QIF file to import. When you click next, the file be analysed and " "you might need to answer some questions about the format of the file." msgstr "" #: ../src/qifimportexport.cpp:75 msgctxt "ImportQIFDialog|" msgid "File:" msgstr "" #: ../src/qifimportexport.cpp:87 msgctxt "ImportQIFDialog|" msgid "Local Definitions" msgstr "" #: ../src/qifimportexport.cpp:88 msgctxt "ImportQIFDialog|" msgid "" "Unknown elements where found in the QIF file. It is possible that this is " "because of localized type names. Please map them to the correct standard " "names." msgstr "" #: ../src/qifimportexport.cpp:94 msgctxt "ImportQIFDialog|" msgid "Local Text" msgstr "" #: ../src/qifimportexport.cpp:95 msgctxt "ImportQIFDialog|" msgid "Standard Text" msgstr "" #: ../src/qifimportexport.cpp:98 msgctxt "ImportQIFDialog|" msgid "Select standard text:" msgstr "" #: ../src/qifimportexport.cpp:104 msgctxt "ImportQIFDialog|" msgid "Date Format" msgstr "" #: ../src/qifimportexport.cpp:105 msgctxt "ImportQIFDialog|" msgid "" "The date format in the QIF file is ambiguous. Please select the correct " "format." msgstr "" #: ../src/qifimportexport.cpp:108 msgctxt "ImportQIFDialog|" msgid "Date format:" msgstr "" #: ../src/qifimportexport.cpp:114 msgctxt "ImportQIFDialog|" msgid "Default Account" msgstr "" #: ../src/qifimportexport.cpp:115 msgctxt "ImportQIFDialog|" msgid "" "Could not find any account definitions in the QIF file. Please select a " "default account. It is also possible that this is caused by a localized " "opening balance text." msgstr "" #: ../src/qifimportexport.cpp:118 msgctxt "ImportQIFDialog|" msgid "Default account:" msgstr "" #: ../src/qifimportexport.cpp:128 msgctxt "ImportQIFDialog|" msgid "Opening balance text:" msgstr "" #: ../src/qifimportexport.cpp:134 msgctxt "ImportQIFDialog|" msgid "Import File" msgstr "" #: ../src/qifimportexport.cpp:135 msgctxt "ImportQIFDialog|" msgid "" "No (further) issues were found. Press finish to import the selected QIF file." msgstr "" #: ../src/qifimportexport.cpp:138 msgctxt "ImportQIFDialog|" msgid "Ignore duplicate transactions" msgstr "" #: ../src/qifimportexport.cpp:239 ../src/qifimportexport.cpp:245 #: ../src/qifimportexport.cpp:249 ../src/qifimportexport.cpp:259 #: ../src/qifimportexport.cpp:262 ../src/qifimportexport.cpp:316 #: ../src/qifimportexport.cpp:404 ../src/qifimportexport.cpp:407 msgctxt "ImportQIFDialog|" msgid "Error" msgstr "" #: ../src/qifimportexport.cpp:239 msgctxt "ImportQIFDialog|" msgid "A file must be selected." msgstr "" #: ../src/qifimportexport.cpp:245 msgctxt "ImportQIFDialog|" msgid "Selected file is a directory." msgstr "" #: ../src/qifimportexport.cpp:249 msgctxt "ImportQIFDialog|" msgid "Selected file does not exist." msgstr "" #: ../src/qifimportexport.cpp:259 ../src/qifimportexport.cpp:404 #, qt-format msgctxt "ImportQIFDialog|" msgid "Couldn't open %1 for reading." msgstr "" #: ../src/qifimportexport.cpp:262 ../src/qifimportexport.cpp:407 #, qt-format msgctxt "ImportQIFDialog|" msgid "Error reading %1." msgstr "" #: ../src/qifimportexport.cpp:285 ../src/qifimportexport.cpp:293 #: ../src/qifimportexport.cpp:309 msgctxt "ImportQIFDialog|" msgid "Unknown" msgstr "" #: ../src/qifimportexport.cpp:294 msgctxt "ImportQIFDialog|" msgid "Account" msgstr "" #: ../src/qifimportexport.cpp:295 msgctxt "ImportQIFDialog|" msgid "Bank" msgstr "" #: ../src/qifimportexport.cpp:296 msgctxt "ImportQIFDialog|" msgid "Cash" msgstr "" #: ../src/qifimportexport.cpp:297 msgctxt "ImportQIFDialog|" msgid "Cat (Category)" msgstr "" #: ../src/qifimportexport.cpp:298 msgctxt "ImportQIFDialog|" msgid "CCard (Credit Card)" msgstr "" #: ../src/qifimportexport.cpp:299 msgctxt "ImportQIFDialog|" msgid "Invst (Investment)" msgstr "" #: ../src/qifimportexport.cpp:300 msgctxt "ImportQIFDialog|" msgid "Oth A (Other Assets)" msgstr "" #: ../src/qifimportexport.cpp:301 msgctxt "ImportQIFDialog|" msgid "Oth L (Other Liabilities)" msgstr "" #: ../src/qifimportexport.cpp:302 msgctxt "ImportQIFDialog|" msgid "Security" msgstr "" #: ../src/qifimportexport.cpp:303 msgctxt "ImportQIFDialog|" msgid "Other" msgstr "" #: ../src/qifimportexport.cpp:316 msgctxt "ImportQIFDialog|" msgid "Unrecognized date format." msgstr "" #: ../src/qifimportexport.cpp:419 #, qt-format msgctxt "ImportQIFDialog|" msgid "Successfully imported %n transaction(s)." msgid_plural "Successfully imported %n transaction(s)." msgstr[0] "" #: ../src/qifimportexport.cpp:422 #, qt-format msgctxt "ImportQIFDialog|" msgid "Successfully imported %n account(s)." msgid_plural "Successfully imported %n account(s)." msgstr[0] "" #: ../src/qifimportexport.cpp:426 #, qt-format msgctxt "ImportQIFDialog|" msgid "Successfully imported %n category/categories." msgid_plural "Successfully imported %n category/categories." msgstr[0] "" #: ../src/qifimportexport.cpp:430 #, qt-format msgctxt "ImportQIFDialog|" msgid "%n duplicate transaction(s) was ignored." msgid_plural "%n duplicate transaction(s) was ignored." msgstr[0] "" #: ../src/qifimportexport.cpp:434 #, qt-format msgctxt "ImportQIFDialog|" msgid "Failed to import %n transaction(s)." msgid_plural "Failed to import %n transaction(s)." msgstr[0] "" #: ../src/qifimportexport.cpp:438 #, qt-format msgctxt "ImportQIFDialog|Financial security (e.g. stock, mutual fund)" msgid "%n security/securities were not imported." msgid_plural "%n security/securities were not imported." msgstr[0] "" #: ../src/qifimportexport.cpp:442 #, qt-format msgctxt "ImportQIFDialog|Financial security (e.g. stock, mutual fund)" msgid "%n security transaction(s) were not imported." msgid_plural "%n security transaction(s) were not imported." msgstr[0] "" #: ../src/qifimportexport.cpp:444 msgctxt "ImportQIFDialog|" msgid "Information" msgstr "" #: ../src/transaction.cpp:659 #, qt-format msgctxt "Income|" msgid "Dividend: %1" msgstr "" #: ../src/transaction.cpp:747 #, qt-format msgctxt "Income|" msgid "Reinvested dividend: %1" msgstr "" #: ../src/ledgerdialog.cpp:203 msgctxt "LedgerDialog|" msgid "Account:" msgstr "" #: ../src/ledgerdialog.cpp:217 msgctxt "LedgerDialog|" msgid "Edit Account…" msgstr "" #: ../src/ledgerdialog.cpp:220 msgctxt "LedgerDialog|" msgid "Export…" msgstr "" #: ../src/ledgerdialog.cpp:222 msgctxt "LedgerDialog|" msgid "Print…" msgstr "" #: ../src/ledgerdialog.cpp:228 msgctxt "LedgerDialog|Accounting context" msgid "Mark all as reconciled" msgstr "" #: ../src/ledgerdialog.cpp:247 msgctxt "LedgerDialog|Accounting context" msgid "Opening balance:" msgstr "" #: ../src/ledgerdialog.cpp:264 msgctxt "LedgerDialog|Accounting context" msgid "Closing balance:" msgstr "" #: ../src/ledgerdialog.cpp:292 msgctxt "LedgerDialog|Header for account reconciled checkbox column" msgid "R" msgstr "" #: ../src/ledgerdialog.cpp:293 msgctxt "LedgerDialog|" msgid "Date" msgstr "" #: ../src/ledgerdialog.cpp:294 msgctxt "LedgerDialog|" msgid "Type" msgstr "" #: ../src/ledgerdialog.cpp:296 msgctxt "LedgerDialog|" msgid "Account/Category" msgstr "" #: ../src/ledgerdialog.cpp:303 msgctxt "LedgerDialog|Noun. Balance of an account" msgid "Balance" msgstr "" #: ../src/ledgerdialog.cpp:332 msgctxt "LedgerDialog|" msgid "New" msgstr "" #: ../src/ledgerdialog.cpp:344 msgctxt "LedgerDialog|" msgid "Edit…" msgstr "" #: ../src/ledgerdialog.cpp:347 msgctxt "LedgerDialog|" msgid "Delete" msgstr "" #: ../src/ledgerdialog.cpp:350 msgctxt "LedgerDialog|" msgid "Join…" msgstr "" #: ../src/ledgerdialog.cpp:353 msgctxt "LedgerDialog|" msgid "Split Up" msgstr "" #: ../src/ledgerdialog.cpp:582 ../src/ledgerdialog.cpp:589 #: ../src/ledgerdialog.cpp:597 ../src/ledgerdialog.cpp:604 #: ../src/ledgerdialog.cpp:853 ../src/ledgerdialog.cpp:880 #: ../src/ledgerdialog.cpp:887 ../src/ledgerdialog.cpp:997 #: ../src/ledgerdialog.cpp:1038 ../src/ledgerdialog.cpp:1379 #: ../src/ledgerdialog.cpp:1385 ../src/ledgerdialog.cpp:1391 msgctxt "LedgerDialog|" msgid "Error" msgstr "" #: ../src/ledgerdialog.cpp:582 ../src/ledgerdialog.cpp:597 msgctxt "LedgerDialog|" msgid "Invalid date." msgstr "" #: ../src/ledgerdialog.cpp:589 msgctxt "LedgerDialog|" msgid "Opening date is after closing date." msgstr "" #: ../src/ledgerdialog.cpp:604 msgctxt "LedgerDialog|" msgid "Closing date is before opening date." msgstr "" #: ../src/ledgerdialog.cpp:853 ../src/ledgerdialog.cpp:997 msgctxt "LedgerDialog|" msgid "Empty transaction list." msgstr "" #: ../src/ledgerdialog.cpp:880 msgctxt "LedgerDialog|" msgid "Couldn't open file for writing." msgstr "" #: ../src/ledgerdialog.cpp:887 msgctxt "LedgerDialog|" msgid "Error while writing file; file was not saved." msgstr "" #: ../src/ledgerdialog.cpp:908 msgctxt "LedgerDialog|" msgid "Ledger" msgstr "" #: ../src/ledgerdialog.cpp:914 #, qt-format msgctxt "LedgerDialog|" msgid "Transactions for %1" msgstr "" #: ../src/ledgerdialog.cpp:1016 msgctxt "LedgerDialog|" msgid "Select Time Period" msgstr "" #: ../src/ledgerdialog.cpp:1020 msgctxt "LedgerDialog|" msgid "From:" msgstr "" #: ../src/ledgerdialog.cpp:1024 msgctxt "LedgerDialog|" msgid "To:" msgstr "" #: ../src/ledgerdialog.cpp:1038 msgctxt "LedgerDialog|" msgid "To date is before from date." msgstr "" #: ../src/ledgerdialog.cpp:1196 ../src/ledgerdialog.cpp:1197 msgctxt "LedgerDialog|Account balance" msgid "Balance change:" msgstr "" #: ../src/ledgerdialog.cpp:1226 msgctxt "LedgerDialog|" msgid "Delete transactions?" msgstr "" #: ../src/ledgerdialog.cpp:1226 #, qt-format msgctxt "LedgerDialog|" msgid "Are you sure you want to delete all (%1) selected transactions?" msgstr "" #: ../src/ledgerdialog.cpp:1379 msgctxt "LedgerDialog|Financial security (e.g. stock, mutual fund)" msgid "" "Cannot set the value of security transactions using the dialog for modifying " "multiple transactions." msgstr "" #: ../src/ledgerdialog.cpp:1385 msgctxt "" "LedgerDialog|Referring to the transaction description property (transaction " "title/generic article name); Financial security (e.g. stock, mutual fund)" msgid "Cannot change description of dividends and security transactions." msgstr "" #: ../src/ledgerdialog.cpp:1391 msgctxt "LedgerDialog|Financial security (e.g. stock, mutual fund)" msgid "Cannot change payer of dividends and security transactions." msgstr "" #: ../src/ledgerdialog.cpp:1449 msgctxt "LedgerDialog|Account balance" msgid "Opening balance" msgstr "" #: ../src/ledgerdialog.cpp:1628 msgctxt "LedgerDialog|" msgid "Account Balance Adjustment" msgstr "" #: ../src/ledgerdialog.cpp:1670 msgctxt "LedgerDialog|Account balance" msgid "Current balance:" msgstr "" #: ../src/ledgerdialog.cpp:1196 ../src/ledgerdialog.cpp:1670 msgctxt "LedgerDialog|Account balance" msgid "Average balance:" msgstr "" #: ../src/ledgerdialog.cpp:1668 msgctxt "LedgerDialog|" msgid "Current debt:" msgstr "" #: ../src/ledgerdialog.cpp:370 msgctxt "LedgerDialog|" msgid "Edit Transaction(s)…" msgstr "" #: ../src/ledgerdialog.cpp:375 msgctxt "LedgerDialog|" msgid "Remove Transaction(s)" msgstr "" #: ../src/ledgerdialog.cpp:376 msgctxt "LedgerDialog|" msgid "Mark as reconciled" msgstr "" #: ../src/ledgerdialog.cpp:521 ../src/ledgerdialog.cpp:522 #: ../src/ledgerdialog.cpp:523 #, qt-format msgctxt "LedgerDialog|Accounting context" msgid "Reconciled: %1 (%2)" msgstr "" #: ../src/ledgerdialog.cpp:780 msgctxt "LedgerDialog|" msgid "Ascending order" msgstr "" #: ../src/ledgerdialog.cpp:1668 msgctxt "LedgerDialog|" msgid "Total debt reduction:" msgstr "" #: ../src/ledgerdialog.cpp:1668 msgctxt "LedgerDialog|" msgid "Total interest and fees:" msgstr "" #: ../src/ledgerdialog.cpp:1196 ../src/ledgerdialog.cpp:1197 #: ../src/ledgerdialog.cpp:1670 msgctxt "LedgerDialog|" msgid "Number of transactions:" msgstr "" #: ../src/ledgerdialog.cpp:1475 msgctxt "LedgerDialog|" msgid "Split Transaction" msgstr "" #: ../src/ledgerdialog.cpp:224 msgctxt "LedgerDialog|Accounting context" msgid "Reconcile" msgstr "" #: ../src/ledgerdialog.cpp:257 msgctxt "LedgerDialog|Accounting context" msgid "Change:" msgstr "" #: ../src/ledgerdialog.cpp:297 msgctxt "LedgerDialog|" msgid "Payee/Payer" msgstr "" #: ../src/ledgerdialog.cpp:299 msgctxt "LedgerDialog|" msgid "Comments" msgstr "" #: ../src/ledgerdialog.cpp:301 msgctxt "LedgerDialog|Money put into account" msgid "Deposit" msgstr "" #: ../src/ledgerdialog.cpp:302 msgctxt "LedgerDialog|Money taken out from account" msgid "Withdrawal" msgstr "" #: ../src/ledgerdialog.cpp:524 ../src/ledgerdialog.cpp:525 #: ../src/ledgerdialog.cpp:526 #, qt-format msgctxt "LedgerDialog|Accounting context" msgid "Book value: %1 (%2)" msgstr "" #: ../src/ledgerdialog.cpp:309 ../src/ledgerdialog.cpp:1502 #: ../src/ledgerdialog.cpp:1531 ../src/ledgerdialog.cpp:1560 #: ../src/ledgerdialog.cpp:1588 msgctxt "LedgerDialog|" msgid "Debt Payment" msgstr "" #: ../src/ledgerdialog.cpp:298 msgctxt "LedgerDialog|" msgid "Tags" msgstr "" #: ../src/ledgerdialog.cpp:1502 msgctxt "LedgerDialog|" msgid "Reduction" msgstr "" #: ../src/ledgerdialog.cpp:1531 msgctxt "LedgerDialog|" msgid "Fee" msgstr "" #: ../src/ledgerdialog.cpp:1560 msgctxt "LedgerDialog|" msgid "Interest" msgstr "" #: ../src/ledgerdialog.cpp:1622 msgctxt "LedgerDialog|" msgid "Income" msgstr "" #: ../src/ledgerdialog.cpp:1623 msgctxt "LedgerDialog|" msgid "Repayment" msgstr "" #: ../src/ledgerdialog.cpp:300 ../src/ledgerdialog.cpp:1625 msgctxt "LedgerDialog|" msgid "Expense" msgstr "" #: ../src/ledgerdialog.cpp:295 msgctxt "" "LedgerDialog|Transaction description property (transaction title/generic " "article name)" msgid "Description" msgstr "" #: ../src/ledgerdialog.cpp:1626 msgctxt "LedgerDialog|" msgid "Refund" msgstr "" #: ../src/ledgerdialog.cpp:1631 msgctxt "LedgerDialog|" msgid "Transfer" msgstr "" #: ../src/editsplitdialog.cpp:131 msgctxt "MultiItemListViewItem|" msgid "Dividend" msgstr "" #: ../src/editsplitdialog.cpp:132 msgctxt "MultiItemListViewItem|" msgid "Income" msgstr "" #: ../src/editsplitdialog.cpp:133 msgctxt "MultiItemListViewItem|" msgid "Repayment" msgstr "" #: ../src/editsplitdialog.cpp:135 msgctxt "MultiItemListViewItem|" msgid "Expense" msgstr "" #: ../src/editsplitdialog.cpp:136 msgctxt "MultiItemListViewItem|" msgid "Refund" msgstr "" #: ../src/editsplitdialog.cpp:138 msgctxt "MultiItemListViewItem|Financial security (e.g. stock, mutual fund)" msgid "Securities Purchase" msgstr "" #: ../src/editsplitdialog.cpp:140 msgctxt "MultiItemListViewItem|Financial security (e.g. stock, mutual fund)" msgid "Securities Sale" msgstr "" #: ../src/editsplitdialog.cpp:142 msgctxt "MultiItemListViewItem|" msgid "Account Balance Adjustment" msgstr "" #: ../src/editsplitdialog.cpp:144 msgctxt "MultiItemListViewItem|" msgid "Transfer" msgstr "" #: ../src/transactioneditwidget.cpp:2111 msgctxt "MultipleTransactionsEditDialog|" msgid "Modify Transactions" msgstr "" #: ../src/transactioneditwidget.cpp:2124 msgctxt "" "MultipleTransactionsEditDialog|Transaction description property (transaction " "title/generic article name)" msgid "Description:" msgstr "" #: ../src/transactioneditwidget.cpp:2134 msgctxt "MultipleTransactionsEditDialog|" msgid "Amount:" msgstr "" #: ../src/transactioneditwidget.cpp:2135 msgctxt "MultipleTransactionsEditDialog|" msgid "Income:" msgstr "" #: ../src/transactioneditwidget.cpp:2136 msgctxt "MultipleTransactionsEditDialog|" msgid "Cost:" msgstr "" #: ../src/transactioneditwidget.cpp:2144 msgctxt "MultipleTransactionsEditDialog|" msgid "Date:" msgstr "" #: ../src/transactioneditwidget.cpp:2155 msgctxt "MultipleTransactionsEditDialog|" msgid "Category:" msgstr "" #: ../src/transactioneditwidget.cpp:2168 msgctxt "MultipleTransactionsEditDialog|" msgid "Payer:" msgstr "" #: ../src/transactioneditwidget.cpp:2169 msgctxt "MultipleTransactionsEditDialog|" msgid "Payee:" msgstr "" #: ../src/transactioneditwidget.cpp:2332 ../src/transactioneditwidget.cpp:2340 #: ../src/transactioneditwidget.cpp:2351 msgctxt "MultipleTransactionsEditDialog|" msgid "Error" msgstr "" #: ../src/transactioneditwidget.cpp:2332 msgctxt "MultipleTransactionsEditDialog|" msgid "No income category available." msgstr "" #: ../src/transactioneditwidget.cpp:2340 msgctxt "MultipleTransactionsEditDialog|" msgid "No expense category available." msgstr "" #: ../src/transactioneditwidget.cpp:2351 msgctxt "MultipleTransactionsEditDialog|" msgid "Invalid date." msgstr "" #: ../src/overtimechart.cpp:181 msgctxt "OverTimeChart|" msgid "Save As…" msgstr "" #: ../src/overtimechart.cpp:184 msgctxt "OverTimeChart|" msgid "Print…" msgstr "" #: ../src/overtimechart.cpp:208 msgctxt "OverTimeChart|" msgid "Source:" msgstr "" #: ../src/overtimechart.cpp:220 msgctxt "OverTimeChart|" msgid "Incomes and Expenses" msgstr "" #: ../src/overtimechart.cpp:221 ../src/overtimechart.cpp:3324 #: ../src/overtimechart.cpp:3580 ../src/overtimechart.cpp:3864 msgctxt "OverTimeChart|" msgid "Profits" msgstr "" #: ../src/overtimechart.cpp:222 ../src/overtimechart.cpp:3341 #: ../src/overtimechart.cpp:3585 ../src/overtimechart.cpp:3589 #: ../src/overtimechart.cpp:3869 ../src/overtimechart.cpp:3873 msgctxt "OverTimeChart|" msgid "Expenses" msgstr "" #: ../src/overtimechart.cpp:223 ../src/overtimechart.cpp:3335 #: ../src/overtimechart.cpp:3584 ../src/overtimechart.cpp:3588 #: ../src/overtimechart.cpp:3868 ../src/overtimechart.cpp:3872 msgctxt "OverTimeChart|" msgid "Incomes" msgstr "" #: ../src/overtimechart.cpp:230 ../src/overtimechart.cpp:724 #: ../src/overtimechart.cpp:4422 msgctxt "OverTimeChart|" msgid "All Categories Combined" msgstr "" #: ../src/overtimechart.cpp:167 msgctxt "OverTimeChart|" msgid "Theme:" msgstr "" #: ../src/overtimechart.cpp:160 msgctxt "OverTimeChart|" msgid "Chart type:" msgstr "" #: ../src/overtimechart.cpp:162 msgctxt "OverTimeChart|" msgid "Line Chart" msgstr "" #: ../src/overtimechart.cpp:163 msgctxt "OverTimeChart|" msgid "Vertical Bar Chart" msgstr "" #: ../src/overtimechart.cpp:164 msgctxt "OverTimeChart|" msgid "Horizontal Bar Chart" msgstr "" #: ../src/overtimechart.cpp:165 msgctxt "OverTimeChart|" msgid "Stacked Bar Chart" msgstr "" #: ../src/overtimechart.cpp:236 ../src/overtimechart.cpp:567 #: ../src/overtimechart.cpp:713 ../src/overtimechart.cpp:4284 #: ../src/overtimechart.cpp:4395 ../src/overtimechart.cpp:4444 msgctxt "" "OverTimeChart|Referring to the transaction description property (transaction " "title/generic article name)" msgid "All Descriptions Combined" msgstr "" #: ../src/overtimechart.cpp:627 msgctxt "" "OverTimeChart|Referring to the transaction description property (transaction " "title/generic article name)" msgid "All Subcategories and Descriptions Combined" msgstr "" #: ../src/overtimechart.cpp:629 ../src/overtimechart.cpp:4285 msgctxt "" "OverTimeChart|Referring to the transaction description property (transaction " "title/generic article name)" msgid "All Descriptions Split" msgstr "" #: ../src/overtimechart.cpp:674 ../src/overtimechart.cpp:3612 #: ../src/overtimechart.cpp:3619 ../src/overtimechart.cpp:3658 #: ../src/overtimechart.cpp:3660 ../src/overtimechart.cpp:3667 #: ../src/overtimechart.cpp:3669 ../src/overtimechart.cpp:3676 #: ../src/overtimechart.cpp:3678 ../src/overtimechart.cpp:3896 #: ../src/overtimechart.cpp:3903 ../src/overtimechart.cpp:3942 #: ../src/overtimechart.cpp:3944 ../src/overtimechart.cpp:3951 #: ../src/overtimechart.cpp:3953 ../src/overtimechart.cpp:3960 #: ../src/overtimechart.cpp:3962 ../src/overtimechart.cpp:4252 #: ../src/overtimechart.cpp:4326 msgctxt "" "OverTimeChart|Referring to the transaction description property (transaction " "title/generic article name)" msgid "No description" msgstr "" #: ../src/overtimechart.cpp:2925 msgctxt "" "OverTimeChart|Referring to the transaction description property (transaction " "title/generic article name)" msgid "Other descriptions" msgstr "" #: ../src/overtimechart.cpp:3574 ../src/overtimechart.cpp:3858 msgctxt "OverTimeChart|" msgid "Assets" msgstr "" #: ../src/overtimechart.cpp:224 msgctxt "OverTimeChart|" msgid "Assets and Liabilities" msgstr "" #: ../src/overtimechart.cpp:244 ../src/overtimechart.cpp:581 #: ../src/overtimechart.cpp:679 ../src/overtimechart.cpp:719 #: ../src/overtimechart.cpp:4313 ../src/overtimechart.cpp:4399 #: ../src/overtimechart.cpp:4450 msgctxt "OverTimeChart|" msgid "All Payees/Payers Combined" msgstr "" #: ../src/overtimechart.cpp:264 msgctxt "OverTimeChart|" msgid "Start date:" msgstr "" #: ../src/overtimechart.cpp:270 msgctxt "OverTimeChart|" msgid "End date:" msgstr "" #: ../src/overtimechart.cpp:276 msgctxt "OverTimeChart|" msgid "Value:" msgstr "" #: ../src/overtimechart.cpp:280 msgctxt "OverTimeChart|" msgid "Annual total" msgstr "" #: ../src/overtimechart.cpp:284 msgctxt "OverTimeChart|" msgid "Monthly total" msgstr "" #: ../src/overtimechart.cpp:288 msgctxt "OverTimeChart|" msgid "Daily average" msgstr "" #: ../src/overtimechart.cpp:292 ../src/overtimechart.cpp:3185 #: ../src/overtimechart.cpp:3209 msgctxt "OverTimeChart|" msgid "Quantity" msgstr "" #: ../src/overtimechart.cpp:296 ../src/overtimechart.cpp:3213 msgctxt "OverTimeChart|" msgid "Average value" msgstr "" #: ../src/overtimechart.cpp:579 ../src/overtimechart.cpp:677 #: ../src/overtimechart.cpp:717 ../src/overtimechart.cpp:4311 #: ../src/overtimechart.cpp:4449 msgctxt "OverTimeChart|" msgid "All Payers Combined" msgstr "" #: ../src/overtimechart.cpp:580 ../src/overtimechart.cpp:678 #: ../src/overtimechart.cpp:718 ../src/overtimechart.cpp:4312 #: ../src/overtimechart.cpp:4448 msgctxt "OverTimeChart|" msgid "All Payees Combined" msgstr "" #: ../src/overtimechart.cpp:626 msgctxt "OverTimeChart|" msgid "All Subcategories Split" msgstr "" #: ../src/overtimechart.cpp:3219 msgctxt "OverTimeChart|" msgid "Annual value" msgstr "" #: ../src/overtimechart.cpp:3220 msgctxt "OverTimeChart|" msgid "Annual profit" msgstr "" #: ../src/overtimechart.cpp:3221 msgctxt "OverTimeChart|" msgid "Annual income" msgstr "" #: ../src/overtimechart.cpp:3222 msgctxt "OverTimeChart|" msgid "Annual cost" msgstr "" #: ../src/overtimechart.cpp:3236 ../src/overtimechart.cpp:4010 msgctxt "OverTimeChart|" msgid "Includes budgeted transactions" msgstr "" #: ../src/overtimechart.cpp:3317 #, qt-format msgctxt "OverTimeChart|" msgid "Value: %1" msgstr "" #: ../src/overtimechart.cpp:3318 msgctxt "OverTimeChart|" msgid "Assets & Liabilities" msgstr "" #: ../src/overtimechart.cpp:3328 #, qt-format msgctxt "OverTimeChart|" msgid "Incomes & Expenses, %1" msgstr "" #: ../src/overtimechart.cpp:3329 msgctxt "OverTimeChart|" msgid "Incomes & Expenses" msgstr "" #: ../src/overtimechart.cpp:3334 #, qt-format msgctxt "OverTimeChart|" msgid "Incomes, %1" msgstr "" #: ../src/overtimechart.cpp:3340 #, qt-format msgctxt "OverTimeChart|" msgid "Expenses, %1" msgstr "" #: ../src/overtimechart.cpp:3305 ../src/overtimechart.cpp:3348 #, qt-format msgctxt "OverTimeChart|" msgid "Incomes, %2: %1" msgstr "" #: ../src/overtimechart.cpp:3306 ../src/overtimechart.cpp:3349 #, qt-format msgctxt "OverTimeChart|" msgid "Incomes: %1" msgstr "" #: ../src/overtimechart.cpp:3308 ../src/overtimechart.cpp:3356 #, qt-format msgctxt "OverTimeChart|" msgid "Expenses, %2: %1" msgstr "" #: ../src/overtimechart.cpp:3309 ../src/overtimechart.cpp:3357 #, qt-format msgctxt "OverTimeChart|" msgid "Expenses: %1" msgstr "" #: ../src/overtimechart.cpp:3369 ../src/overtimechart.cpp:3403 #, qt-format msgctxt "OverTimeChart|" msgid "Incomes, %3: %2, %1" msgstr "" #: ../src/overtimechart.cpp:3370 ../src/overtimechart.cpp:3404 #, qt-format msgctxt "OverTimeChart|" msgid "Incomes: %2, %1" msgstr "" #: ../src/overtimechart.cpp:3375 ../src/overtimechart.cpp:3410 #, qt-format msgctxt "OverTimeChart|" msgid "Expenses, %3: %2, %1" msgstr "" #: ../src/overtimechart.cpp:3376 ../src/overtimechart.cpp:3411 #, qt-format msgctxt "OverTimeChart|" msgid "Expenses: %2, %1" msgstr "" #: ../src/overtimechart.cpp:3386 #, qt-format msgctxt "OverTimeChart|" msgid "Incomes, %4: %3, %2, %1" msgstr "" #: ../src/overtimechart.cpp:3387 #, qt-format msgctxt "OverTimeChart|" msgid "Incomes: %3, %2, %1" msgstr "" #: ../src/overtimechart.cpp:3391 #, qt-format msgctxt "OverTimeChart|" msgid "Expenses, %4: %3, %2, %1" msgstr "" #: ../src/overtimechart.cpp:3392 #, qt-format msgctxt "OverTimeChart|" msgid "Expenses: %3, %2, %1" msgstr "" #: ../src/overtimechart.cpp:3575 ../src/overtimechart.cpp:3859 msgctxt "OverTimeChart|" msgid "Liabilities" msgstr "" #: ../src/overtimechart.cpp:3685 ../src/overtimechart.cpp:3969 msgctxt "OverTimeChart|" msgid "Other accounts" msgstr "" #: ../src/overtimechart.cpp:4645 ../src/overtimechart.cpp:4654 #: ../src/overtimechart.cpp:4700 ../src/overtimechart.cpp:4701 #, qt-format msgctxt "OverTimeChart|" msgid "" "%1\n" "Value: %2\n" "Date: %3" msgstr "" #: ../src/overtimechart.cpp:4654 ../src/overtimechart.cpp:4701 msgctxt "OverTimeChart|Month and year" msgid "MMMM yyyy" msgstr "" #: ../src/overtimechart.cpp:677 ../src/overtimechart.cpp:4311 msgctxt "OverTimeChart|" msgid "All Payers Split" msgstr "" #: ../src/overtimechart.cpp:678 ../src/overtimechart.cpp:4312 msgctxt "OverTimeChart|" msgid "All Payees Split" msgstr "" #: ../src/overtimechart.cpp:685 ../src/overtimechart.cpp:3386 #: ../src/overtimechart.cpp:3387 ../src/overtimechart.cpp:3403 #: ../src/overtimechart.cpp:3404 ../src/overtimechart.cpp:3595 #: ../src/overtimechart.cpp:3625 ../src/overtimechart.cpp:3642 #: ../src/overtimechart.cpp:3667 ../src/overtimechart.cpp:3668 #: ../src/overtimechart.cpp:3879 ../src/overtimechart.cpp:3909 #: ../src/overtimechart.cpp:3931 ../src/overtimechart.cpp:3951 #: ../src/overtimechart.cpp:3952 ../src/overtimechart.cpp:4256 #: ../src/overtimechart.cpp:4342 msgctxt "OverTimeChart|" msgid "No payer" msgstr "" #: ../src/overtimechart.cpp:686 ../src/overtimechart.cpp:3391 #: ../src/overtimechart.cpp:3392 ../src/overtimechart.cpp:3410 #: ../src/overtimechart.cpp:3411 ../src/overtimechart.cpp:3599 #: ../src/overtimechart.cpp:3637 ../src/overtimechart.cpp:3652 #: ../src/overtimechart.cpp:3676 ../src/overtimechart.cpp:3677 #: ../src/overtimechart.cpp:3883 ../src/overtimechart.cpp:3921 #: ../src/overtimechart.cpp:3936 ../src/overtimechart.cpp:3960 #: ../src/overtimechart.cpp:3961 ../src/overtimechart.cpp:4254 #: ../src/overtimechart.cpp:4343 msgctxt "OverTimeChart|" msgid "No payee" msgstr "" #: ../src/overtimechart.cpp:726 ../src/overtimechart.cpp:738 #: ../src/overtimechart.cpp:4423 msgctxt "OverTimeChart|" msgid "All Categories Split" msgstr "" #: ../src/overtimechart.cpp:815 ../src/overtimechart.cpp:845 #: ../src/overtimechart.cpp:875 ../src/overtimechart.cpp:912 #: ../src/overtimechart.cpp:1025 ../src/overtimechart.cpp:1058 msgctxt "OverTimeChart|" msgid "Error" msgstr "" #: ../src/overtimechart.cpp:815 ../src/overtimechart.cpp:845 #: ../src/overtimechart.cpp:875 ../src/overtimechart.cpp:912 msgctxt "OverTimeChart|" msgid "Invalid date." msgstr "" #: ../src/overtimechart.cpp:1025 msgctxt "OverTimeChart|" msgid "Couldn't open file for writing." msgstr "" #: ../src/overtimechart.cpp:1058 msgctxt "OverTimeChart|" msgid "Error while writing file; file was not saved." msgstr "" #: ../src/overtimechart.cpp:2919 msgctxt "OverTimeChart|" msgid "Other payees" msgstr "" #: ../src/overtimechart.cpp:2921 msgctxt "OverTimeChart|" msgid "Other payers" msgstr "" #: ../src/overtimechart.cpp:4063 msgctxt "OverTimeChart|" msgid "Time" msgstr "" #: ../src/overtimechart.cpp:3595 ../src/overtimechart.cpp:3599 #: ../src/overtimechart.cpp:3879 ../src/overtimechart.cpp:3883 #, qt-format msgctxt "OverTimeChart|%1: Category; %2: Payee/Payer" msgid "%1/%2" msgstr "" #: ../src/overtimechart.cpp:169 msgctxt "OverTimeChart|" msgid "Default" msgstr "" #: ../src/overtimechart.cpp:225 ../src/overtimechart.cpp:3305 #: ../src/overtimechart.cpp:3306 ../src/overtimechart.cpp:3308 #: ../src/overtimechart.cpp:3309 ../src/overtimechart.cpp:3312 msgctxt "OverTimeChart|" msgid "Tags" msgstr "" #: ../src/overtimechart.cpp:250 ../src/overtimechart.cpp:4476 msgctxt "OverTimeChart|" msgid "All Accounts Combined" msgstr "" #: ../src/overtimechart.cpp:251 ../src/overtimechart.cpp:4477 msgctxt "OverTimeChart|" msgid "All Accounts Split" msgstr "" #: ../src/overtimechart.cpp:679 ../src/overtimechart.cpp:4313 msgctxt "OverTimeChart|" msgid "All Payees/Payers Split" msgstr "" #: ../src/overtimechart.cpp:687 ../src/overtimechart.cpp:3396 #: ../src/overtimechart.cpp:3397 ../src/overtimechart.cpp:3416 #: ../src/overtimechart.cpp:3417 ../src/overtimechart.cpp:3631 #: ../src/overtimechart.cpp:3647 ../src/overtimechart.cpp:3658 #: ../src/overtimechart.cpp:3659 ../src/overtimechart.cpp:3915 #: ../src/overtimechart.cpp:3926 ../src/overtimechart.cpp:3942 #: ../src/overtimechart.cpp:3943 ../src/overtimechart.cpp:4344 msgctxt "OverTimeChart|" msgid "No payee/payer" msgstr "" #: ../src/overtimechart.cpp:750 ../src/overtimechart.cpp:4386 msgctxt "OverTimeChart|" msgid "All Tags Split" msgstr "" #: ../src/overtimechart.cpp:2917 msgctxt "OverTimeChart|" msgid "Other tags" msgstr "" #: ../src/overtimechart.cpp:2923 msgctxt "OverTimeChart|" msgid "Other payees/payers" msgstr "" #: ../src/overtimechart.cpp:3186 msgctxt "OverTimeChart|" msgid "Value" msgstr "" #: ../src/overtimechart.cpp:3202 msgctxt "OverTimeChart|" msgid "Daily average value" msgstr "" #: ../src/overtimechart.cpp:3203 msgctxt "OverTimeChart|" msgid "Daily average profit" msgstr "" #: ../src/overtimechart.cpp:3204 msgctxt "OverTimeChart|" msgid "Daily average income" msgstr "" #: ../src/overtimechart.cpp:3205 msgctxt "OverTimeChart|" msgid "Daily average cost" msgstr "" #: ../src/overtimechart.cpp:3214 msgctxt "OverTimeChart|" msgid "Average income" msgstr "" #: ../src/overtimechart.cpp:3215 msgctxt "OverTimeChart|" msgid "Average cost" msgstr "" #: ../src/overtimechart.cpp:3226 msgctxt "OverTimeChart|" msgid "Monthly value" msgstr "" #: ../src/overtimechart.cpp:3227 msgctxt "OverTimeChart|" msgid "Monthly profit" msgstr "" #: ../src/overtimechart.cpp:3228 msgctxt "OverTimeChart|" msgid "Monthly income" msgstr "" #: ../src/overtimechart.cpp:3229 msgctxt "OverTimeChart|" msgid "Monthly cost" msgstr "" #: ../src/overtimechart.cpp:3235 ../src/overtimechart.cpp:4009 msgctxt "OverTimeChart|" msgid "Includes scheduled and budgeted transactions" msgstr "" #: ../src/overtimechart.cpp:3237 ../src/overtimechart.cpp:4011 msgctxt "OverTimeChart|" msgid "Includes scheduled transactions" msgstr "" #: ../src/overtimechart.cpp:3311 #, qt-format msgctxt "OverTimeChart|" msgid "Tags, %1" msgstr "" #: ../src/overtimechart.cpp:3322 #, qt-format msgctxt "OverTimeChart|" msgid "Incomes − Expenses, %1" msgstr "" #: ../src/overtimechart.cpp:3323 ../src/overtimechart.cpp:3579 #: ../src/overtimechart.cpp:3863 msgctxt "OverTimeChart|" msgid "Incomes − Expenses" msgstr "" #: ../src/overtimechart.cpp:3325 msgctxt "OverTimeChart|Financial security (e.g. stock, mutual fund)" msgid "Excluding any profits or losses in trading of security shares" msgstr "" #: ../src/overtimechart.cpp:3363 #, qt-format msgctxt "OverTimeChart|" msgid "%2: %1" msgstr "" #: ../src/overtimechart.cpp:3381 ../src/overtimechart.cpp:3416 #, qt-format msgctxt "OverTimeChart|" msgid "%3: %2, %1" msgstr "" #: ../src/overtimechart.cpp:3382 ../src/overtimechart.cpp:3417 #, qt-format msgctxt "OverTimeChart|" msgid "%2, %1" msgstr "" #: ../src/overtimechart.cpp:3396 #, qt-format msgctxt "OverTimeChart|" msgid "%4: %3, %2, %1" msgstr "" #: ../src/overtimechart.cpp:3397 #, qt-format msgctxt "OverTimeChart|" msgid "%3, %2, %1" msgstr "" #: ../src/overtimechart.cpp:3662 ../src/overtimechart.cpp:3671 #: ../src/overtimechart.cpp:3680 ../src/overtimechart.cpp:3946 #: ../src/overtimechart.cpp:3955 ../src/overtimechart.cpp:3964 #, qt-format msgctxt "OverTimeChart|%1: Description; %2: Payee/Payer" msgid "%1/%2" msgstr "" #: ../src/eqonomize.cpp:1153 msgctxt "OverTimeChartDialog|" msgid "Chart" msgstr "" #: ../src/overtimereport.cpp:85 msgctxt "OverTimeReport|" msgid "Save As…" msgstr "" #: ../src/overtimereport.cpp:87 msgctxt "OverTimeReport|" msgid "Print…" msgstr "" #: ../src/overtimereport.cpp:101 msgctxt "OverTimeReport|" msgid "Source:" msgstr "" #: ../src/overtimereport.cpp:106 ../src/overtimereport.cpp:459 msgctxt "OverTimeReport|" msgid "Profits" msgstr "" #: ../src/overtimereport.cpp:107 ../src/overtimereport.cpp:461 #: ../src/overtimereport.cpp:486 ../src/overtimereport.cpp:508 #: ../src/overtimereport.cpp:528 ../src/overtimereport.cpp:1105 msgctxt "OverTimeReport|" msgid "Expenses" msgstr "" #: ../src/overtimereport.cpp:108 ../src/overtimereport.cpp:460 #: ../src/overtimereport.cpp:477 ../src/overtimereport.cpp:498 #: ../src/overtimereport.cpp:518 ../src/overtimereport.cpp:1141 msgctxt "OverTimeReport|" msgid "Incomes" msgstr "" #: ../src/overtimereport.cpp:110 ../src/overtimereport.cpp:147 msgctxt "OverTimeReport|" msgid "Tags" msgstr "" #: ../src/overtimereport.cpp:115 ../src/overtimereport.cpp:325 #: ../src/overtimereport.cpp:1466 msgctxt "OverTimeReport|" msgid "All Categories Combined" msgstr "" #: ../src/overtimereport.cpp:140 msgctxt "OverTimeReport|" msgid "Columns:" msgstr "" #: ../src/overtimereport.cpp:144 msgctxt "OverTimeReport|" msgid "Categories" msgstr "" #: ../src/overtimereport.cpp:150 msgctxt "OverTimeReport|" msgid "Total:" msgstr "" #: ../src/overtimereport.cpp:159 ../src/overtimereport.cpp:537 #: ../src/overtimereport.cpp:562 ../src/overtimereport.cpp:573 msgctxt "OverTimeReport|" msgid "Value" msgstr "" #: ../src/overtimereport.cpp:162 msgctxt "OverTimeReport|" msgid "Daily" msgstr "" #: ../src/overtimereport.cpp:165 msgctxt "OverTimeReport|" msgid "Monthly" msgstr "" #: ../src/overtimereport.cpp:168 msgctxt "OverTimeReport|" msgid "Yearly" msgstr "" #: ../src/overtimereport.cpp:171 ../src/overtimereport.cpp:1181 msgctxt "OverTimeReport|" msgid "Quantity" msgstr "" #: ../src/overtimereport.cpp:174 msgctxt "OverTimeReport|" msgid "Average value" msgstr "" #: ../src/overtimereport.cpp:121 ../src/overtimereport.cpp:252 #: ../src/overtimereport.cpp:321 ../src/overtimereport.cpp:1487 msgctxt "" "OverTimeReport|Referring to the transaction description property " "(transaction title/generic article name)" msgid "All Descriptions Combined" msgstr "" #: ../src/overtimereport.cpp:109 ../src/overtimereport.cpp:539 msgctxt "OverTimeReport|" msgid "Assets & Liabilities" msgstr "" #: ../src/overtimereport.cpp:127 ../src/overtimereport.cpp:1504 msgctxt "OverTimeReport|" msgid "All Accounts" msgstr "" #: ../src/overtimereport.cpp:272 ../src/overtimereport.cpp:309 #: ../src/overtimereport.cpp:515 ../src/overtimereport.cpp:516 #: ../src/overtimereport.cpp:525 ../src/overtimereport.cpp:526 #: ../src/overtimereport.cpp:570 ../src/overtimereport.cpp:571 #: ../src/overtimereport.cpp:1136 ../src/overtimereport.cpp:1137 #: ../src/overtimereport.cpp:1146 ../src/overtimereport.cpp:1147 msgctxt "" "OverTimeReport|Referring to the transaction description property " "(transaction title/generic article name)" msgid "No description" msgstr "" #: ../src/overtimereport.cpp:401 ../src/overtimereport.cpp:409 msgctxt "OverTimeReport|" msgid "Error" msgstr "" #: ../src/overtimereport.cpp:401 msgctxt "OverTimeReport|" msgid "Couldn't open file for writing." msgstr "" #: ../src/overtimereport.cpp:409 msgctxt "OverTimeReport|" msgid "Error while writing file; file was not saved." msgstr "" #: ../src/overtimereport.cpp:476 #, qt-format msgctxt "OverTimeReport|" msgid "Incomes, %1" msgstr "" #: ../src/overtimereport.cpp:478 ../src/overtimereport.cpp:497 #: ../src/overtimereport.cpp:517 ../src/overtimereport.cpp:1140 msgctxt "OverTimeReport|" msgid "Average Income" msgstr "" #: ../src/overtimereport.cpp:485 #, qt-format msgctxt "OverTimeReport|" msgid "Expenses, %1" msgstr "" #: ../src/overtimereport.cpp:487 ../src/overtimereport.cpp:507 #: ../src/overtimereport.cpp:527 ../src/overtimereport.cpp:1104 msgctxt "OverTimeReport|" msgid "Average Cost" msgstr "" #: ../src/overtimereport.cpp:495 ../src/overtimereport.cpp:1143 #, qt-format msgctxt "OverTimeReport|" msgid "Incomes, %2: %1" msgstr "" #: ../src/overtimereport.cpp:496 ../src/overtimereport.cpp:1144 #, qt-format msgctxt "OverTimeReport|" msgid "Incomes: %1" msgstr "" #: ../src/overtimereport.cpp:505 ../src/overtimereport.cpp:1133 #, qt-format msgctxt "OverTimeReport|" msgid "Expenses, %2: %1" msgstr "" #: ../src/overtimereport.cpp:506 ../src/overtimereport.cpp:1134 #, qt-format msgctxt "OverTimeReport|" msgid "Expenses: %1" msgstr "" #: ../src/overtimereport.cpp:515 ../src/overtimereport.cpp:1146 #, qt-format msgctxt "OverTimeReport|" msgid "Incomes, %3: %2, %1" msgstr "" #: ../src/overtimereport.cpp:516 ../src/overtimereport.cpp:1147 #, qt-format msgctxt "OverTimeReport|" msgid "Incomes: %2, %1" msgstr "" #: ../src/overtimereport.cpp:525 ../src/overtimereport.cpp:1136 #, qt-format msgctxt "OverTimeReport|" msgid "Expenses, %3: %2, %1" msgstr "" #: ../src/overtimereport.cpp:526 ../src/overtimereport.cpp:1137 #, qt-format msgctxt "OverTimeReport|" msgid "Expenses: %2, %1" msgstr "" #. Noun, how much the account balance has changed #: ../src/overtimereport.cpp:452 #, qt-format msgctxt "OverTimeReport|" msgid "Change: %1" msgstr "" #. Noun, how much the account balance has changed #: ../src/overtimereport.cpp:456 msgctxt "OverTimeReport|" msgid "Change" msgstr "" #: ../src/overtimereport.cpp:535 #, qt-format msgctxt "OverTimeReport|" msgid "Value: %1" msgstr "" #: ../src/overtimereport.cpp:1169 msgctxt "OverTimeReport|" msgid "Year" msgstr "" #: ../src/overtimereport.cpp:1170 msgctxt "OverTimeReport|" msgid "Month" msgstr "" #: ../src/overtimereport.cpp:541 msgctxt "OverTimeReport|" msgid "Assets" msgstr "" #: ../src/overtimereport.cpp:542 msgctxt "OverTimeReport|" msgid "Liabilities" msgstr "" #: ../src/overtimereport.cpp:559 #, qt-format msgctxt "OverTimeReport|" msgid "%2: %1" msgstr "" #: ../src/overtimereport.cpp:561 ../src/overtimereport.cpp:572 msgctxt "OverTimeReport|" msgid "Average Value" msgstr "" #: ../src/overtimereport.cpp:570 #, qt-format msgctxt "OverTimeReport|" msgid "%3: %2, %1" msgstr "" #: ../src/overtimereport.cpp:571 #, qt-format msgctxt "OverTimeReport|" msgid "%2, %1" msgstr "" #: ../src/overtimereport.cpp:1177 msgctxt "OverTimeReport|" msgid "Daily Average" msgstr "" #: ../src/overtimereport.cpp:1178 msgctxt "OverTimeReport|" msgid "Monthly Average" msgstr "" #: ../src/overtimereport.cpp:1179 msgctxt "OverTimeReport|" msgid "Yearly Average" msgstr "" #: ../src/overtimereport.cpp:1257 ../src/overtimereport.cpp:1367 msgctxt "OverTimeReport|" msgid "Subtotal" msgstr "" #: ../src/overtimereport.cpp:543 ../src/overtimereport.cpp:1214 #: ../src/overtimereport.cpp:1395 msgctxt "OverTimeReport|" msgid "Total" msgstr "" #: ../src/overtimereport.cpp:453 msgctxt "OverTimeReport|Money put into account" msgid "Deposit" msgstr "" #: ../src/overtimereport.cpp:454 msgctxt "OverTimeReport|Money taken out from account" msgid "Withdrawal" msgstr "" #: ../src/overtimereport.cpp:1424 msgctxt "OverTimeReport|" msgid "Includes scheduled transactions" msgstr "" #: ../src/overtimereport.cpp:1428 #, qt-format msgctxt "OverTimeReport|" msgid "Adjusted for the average month / year (%1 / %2 days)" msgstr "" #: ../src/eqonomize.cpp:1123 msgctxt "OverTimeReportDialog|" msgid "Report" msgstr "" #: ../src/main.cpp:75 msgctxt "QApplication|" msgid "Start with expenses list displayed" msgstr "" #: ../src/main.cpp:77 msgctxt "QApplication|" msgid "Start with incomes list displayed" msgstr "" #: ../src/main.cpp:79 msgctxt "QApplication|" msgid "Start with transfers list displayed" msgstr "" #: ../src/main.cpp:81 msgctxt "QApplication|" msgid "Synchronize file" msgstr "" #: ../src/main.cpp:83 msgctxt "QApplication|" msgid "Document to open" msgstr "" #: ../src/main.cpp:98 #, qt-format msgctxt "QApplication|" msgid "%1 is already running." msgstr "" #: ../src/eqonomize.cpp:468 msgctxt "QObject|" msgid "Transfer" msgstr "" #: ../src/eqonomize.cpp:470 msgctxt "QObject|" msgid "Dividend" msgstr "" #: ../src/eqonomize.cpp:471 ../src/eqonomize.cpp:511 ../src/eqonomize.cpp:517 #: ../src/eqonomize.cpp:610 ../src/eqonomize.cpp:614 msgctxt "QObject|" msgid "Income" msgstr "" #: ../src/eqonomize.cpp:475 ../src/eqonomize.cpp:512 ../src/eqonomize.cpp:518 #: ../src/eqonomize.cpp:611 ../src/eqonomize.cpp:615 msgctxt "QObject|" msgid "Expense" msgstr "" #: ../src/eqonomize.cpp:478 msgctxt "QObject|Financial security (e.g. stock, mutual fund)" msgid "Securities Purchase" msgstr "" #: ../src/eqonomize.cpp:479 msgctxt "QObject|Financial security (e.g. stock, mutual fund)" msgid "Securities Sale" msgstr "" #: ../src/eqonomize.cpp:484 msgctxt "QObject|" msgid "Debt Payment" msgstr "" #: ../src/eqonomize.cpp:513 ../src/eqonomize.cpp:612 msgctxt "QObject|" msgid "Split Transaction" msgstr "" #: ../src/recurrenceeditwidget.cpp:319 msgctxt "RecurrenceEditWidget|" msgid "Enable recurrence" msgstr "" #: ../src/recurrenceeditwidget.cpp:322 msgctxt "RecurrenceEditWidget|" msgid "Recurrence Rule" msgstr "" #: ../src/recurrenceeditwidget.cpp:327 msgctxt "RecurrenceEditWidget|" msgid "Daily" msgstr "" #: ../src/recurrenceeditwidget.cpp:328 msgctxt "RecurrenceEditWidget|" msgid "Weekly" msgstr "" #: ../src/recurrenceeditwidget.cpp:329 msgctxt "RecurrenceEditWidget|" msgid "Monthly" msgstr "" #: ../src/recurrenceeditwidget.cpp:330 msgctxt "RecurrenceEditWidget|" msgid "Yearly" msgstr "" #: ../src/recurrenceeditwidget.cpp:348 ../src/recurrenceeditwidget.cpp:359 #: ../src/recurrenceeditwidget.cpp:382 ../src/recurrenceeditwidget.cpp:468 msgctxt "RecurrenceEditWidget|" msgid "Recur every" msgstr "" #: ../src/recurrenceeditwidget.cpp:352 msgctxt "RecurrenceEditWidget|" msgid "day(s)" msgstr "" #: ../src/recurrenceeditwidget.cpp:363 msgctxt "RecurrenceEditWidget|" msgid "week(s) on:" msgstr "" #: ../src/recurrenceeditwidget.cpp:386 msgctxt "RecurrenceEditWidget|" msgid "month(s), after the start month" msgstr "" #: ../src/recurrenceeditwidget.cpp:391 ../src/recurrenceeditwidget.cpp:443 msgctxt "RecurrenceEditWidget|" msgid "Recur on the" msgstr "" #: ../src/recurrenceeditwidget.cpp:397 ../src/recurrenceeditwidget.cpp:448 #: ../src/recurrenceeditwidget.cpp:501 msgctxt "RecurrenceEditWidget|" msgid "1st" msgstr "" #: ../src/recurrenceeditwidget.cpp:398 ../src/recurrenceeditwidget.cpp:449 #: ../src/recurrenceeditwidget.cpp:502 msgctxt "RecurrenceEditWidget|" msgid "2nd" msgstr "" #: ../src/recurrenceeditwidget.cpp:399 ../src/recurrenceeditwidget.cpp:450 #: ../src/recurrenceeditwidget.cpp:503 msgctxt "RecurrenceEditWidget|" msgid "3rd" msgstr "" #: ../src/recurrenceeditwidget.cpp:400 ../src/recurrenceeditwidget.cpp:451 #: ../src/recurrenceeditwidget.cpp:504 msgctxt "RecurrenceEditWidget|" msgid "4th" msgstr "" #: ../src/recurrenceeditwidget.cpp:401 ../src/recurrenceeditwidget.cpp:452 #: ../src/recurrenceeditwidget.cpp:505 msgctxt "RecurrenceEditWidget|" msgid "5th" msgstr "" #: ../src/recurrenceeditwidget.cpp:402 msgctxt "RecurrenceEditWidget|" msgid "6th" msgstr "" #: ../src/recurrenceeditwidget.cpp:403 msgctxt "RecurrenceEditWidget|" msgid "7th" msgstr "" #: ../src/recurrenceeditwidget.cpp:404 msgctxt "RecurrenceEditWidget|" msgid "8th" msgstr "" #: ../src/recurrenceeditwidget.cpp:405 msgctxt "RecurrenceEditWidget|" msgid "9th" msgstr "" #: ../src/recurrenceeditwidget.cpp:406 msgctxt "RecurrenceEditWidget|" msgid "10th" msgstr "" #: ../src/recurrenceeditwidget.cpp:407 msgctxt "RecurrenceEditWidget|" msgid "11th" msgstr "" #: ../src/recurrenceeditwidget.cpp:408 msgctxt "RecurrenceEditWidget|" msgid "12th" msgstr "" #: ../src/recurrenceeditwidget.cpp:409 msgctxt "RecurrenceEditWidget|" msgid "13th" msgstr "" #: ../src/recurrenceeditwidget.cpp:410 msgctxt "RecurrenceEditWidget|" msgid "14th" msgstr "" #: ../src/recurrenceeditwidget.cpp:411 msgctxt "RecurrenceEditWidget|" msgid "15th" msgstr "" #: ../src/recurrenceeditwidget.cpp:412 msgctxt "RecurrenceEditWidget|" msgid "16th" msgstr "" #: ../src/recurrenceeditwidget.cpp:413 msgctxt "RecurrenceEditWidget|" msgid "17th" msgstr "" #: ../src/recurrenceeditwidget.cpp:414 msgctxt "RecurrenceEditWidget|" msgid "18th" msgstr "" #: ../src/recurrenceeditwidget.cpp:415 msgctxt "RecurrenceEditWidget|" msgid "19th" msgstr "" #: ../src/recurrenceeditwidget.cpp:416 msgctxt "RecurrenceEditWidget|" msgid "20th" msgstr "" #: ../src/recurrenceeditwidget.cpp:417 msgctxt "RecurrenceEditWidget|" msgid "21st" msgstr "" #: ../src/recurrenceeditwidget.cpp:418 msgctxt "RecurrenceEditWidget|" msgid "22nd" msgstr "" #: ../src/recurrenceeditwidget.cpp:419 msgctxt "RecurrenceEditWidget|" msgid "23rd" msgstr "" #: ../src/recurrenceeditwidget.cpp:420 msgctxt "RecurrenceEditWidget|" msgid "24th" msgstr "" #: ../src/recurrenceeditwidget.cpp:421 msgctxt "RecurrenceEditWidget|" msgid "25th" msgstr "" #: ../src/recurrenceeditwidget.cpp:422 msgctxt "RecurrenceEditWidget|" msgid "26th" msgstr "" #: ../src/recurrenceeditwidget.cpp:423 msgctxt "RecurrenceEditWidget|" msgid "27th" msgstr "" #: ../src/recurrenceeditwidget.cpp:424 msgctxt "RecurrenceEditWidget|" msgid "28th" msgstr "" #: ../src/recurrenceeditwidget.cpp:425 msgctxt "RecurrenceEditWidget|" msgid "29th" msgstr "" #: ../src/recurrenceeditwidget.cpp:426 msgctxt "RecurrenceEditWidget|" msgid "30th" msgstr "" #: ../src/recurrenceeditwidget.cpp:427 msgctxt "RecurrenceEditWidget|" msgid "31st" msgstr "" #: ../src/recurrenceeditwidget.cpp:428 ../src/recurrenceeditwidget.cpp:453 #: ../src/recurrenceeditwidget.cpp:506 msgctxt "RecurrenceEditWidget|" msgid "Last" msgstr "" #: ../src/recurrenceeditwidget.cpp:429 ../src/recurrenceeditwidget.cpp:454 #: ../src/recurrenceeditwidget.cpp:507 msgctxt "RecurrenceEditWidget|" msgid "2nd Last" msgstr "" #: ../src/recurrenceeditwidget.cpp:430 ../src/recurrenceeditwidget.cpp:455 #: ../src/recurrenceeditwidget.cpp:508 msgctxt "RecurrenceEditWidget|" msgid "3rd Last" msgstr "" #: ../src/recurrenceeditwidget.cpp:431 ../src/recurrenceeditwidget.cpp:456 #: ../src/recurrenceeditwidget.cpp:509 msgctxt "RecurrenceEditWidget|" msgid "4th Last" msgstr "" #: ../src/recurrenceeditwidget.cpp:432 ../src/recurrenceeditwidget.cpp:457 #: ../src/recurrenceeditwidget.cpp:510 msgctxt "RecurrenceEditWidget|" msgid "5th Last" msgstr "" #: ../src/recurrenceeditwidget.cpp:434 msgctxt "RecurrenceEditWidget|" msgid "day" msgstr "" #: ../src/recurrenceeditwidget.cpp:436 ../src/recurrenceeditwidget.cpp:489 #: ../src/recurrenceeditwidget.cpp:528 msgctxt "RecurrenceEditWidget|" msgid "possibly on weekend" msgstr "" #: ../src/recurrenceeditwidget.cpp:437 ../src/recurrenceeditwidget.cpp:490 #: ../src/recurrenceeditwidget.cpp:529 msgctxt "RecurrenceEditWidget|" msgid "but before weekend" msgstr "" #: ../src/recurrenceeditwidget.cpp:438 ../src/recurrenceeditwidget.cpp:491 #: ../src/recurrenceeditwidget.cpp:530 msgctxt "RecurrenceEditWidget|" msgid "but after weekend" msgstr "" #: ../src/recurrenceeditwidget.cpp:492 ../src/recurrenceeditwidget.cpp:531 msgctxt "RecurrenceEditWidget|" msgid "nearest weekend day" msgstr "" #: ../src/recurrenceeditwidget.cpp:472 msgctxt "RecurrenceEditWidget|" msgid "year(s), after the start year" msgstr "" #: ../src/recurrenceeditwidget.cpp:439 msgctxt "RecurrenceEditWidget|" msgid "on nearest weekday" msgstr "" #: ../src/recurrenceeditwidget.cpp:477 msgctxt "" "RecurrenceEditWidget|part before XXX of 'Recur on day XXX of month YYY'" msgid "Recur on day" msgstr "" #: ../src/recurrenceeditwidget.cpp:485 msgctxt "" "RecurrenceEditWidget|part between XXX and YYY of 'Recur on day XXX of month " "YYY'" msgid "of" msgstr "" #: ../src/recurrenceeditwidget.cpp:496 msgctxt "" "RecurrenceEditWidget|Part before NNN in 'Recur on the NNN. WEEKDAY of MONTH'" msgid "On the" msgstr "" #: ../src/recurrenceeditwidget.cpp:514 msgctxt "" "RecurrenceEditWidget|part between WEEKDAY and MONTH in 'Recur on NNN. " "WEEKDAY of MONTH'" msgid "of" msgstr "" #: ../src/recurrenceeditwidget.cpp:519 msgctxt "RecurrenceEditWidget|" msgid "Recur on day #" msgstr "" #: ../src/recurrenceeditwidget.cpp:526 msgctxt "" "RecurrenceEditWidget|part after NNN of 'Recur on day #NNN of the year'" msgid " of the year" msgstr "" #: ../src/recurrenceeditwidget.cpp:541 msgctxt "RecurrenceEditWidget|" msgid "Range…" msgstr "" #: ../src/recurrenceeditwidget.cpp:543 msgctxt "RecurrenceEditWidget|" msgid "Occurrences/Exceptions…" msgstr "" #: ../src/recurrenceeditwidget.cpp:741 ../src/recurrenceeditwidget.cpp:753 #: ../src/recurrenceeditwidget.cpp:767 ../src/recurrenceeditwidget.cpp:780 #: ../src/recurrenceeditwidget.cpp:797 msgctxt "RecurrenceEditWidget|" msgid "Error" msgstr "" #: ../src/recurrenceeditwidget.cpp:741 msgctxt "RecurrenceEditWidget|" msgid "No day of week selected for weekly recurrence." msgstr "" #: ../src/recurrenceeditwidget.cpp:753 ../src/recurrenceeditwidget.cpp:780 #: ../src/recurrenceeditwidget.cpp:797 msgctxt "RecurrenceEditWidget|" msgid "Selected day will never occur with selected frequency and start date." msgstr "" #: ../src/recurrenceeditwidget.cpp:767 msgctxt "RecurrenceEditWidget|" msgid "Selected day does not exist in selected month." msgstr "" #: ../src/eqonomize.cpp:708 ../src/eqonomize.cpp:730 msgctxt "RefundDialog|" msgid "Repayment" msgstr "" #: ../src/eqonomize.cpp:709 ../src/eqonomize.cpp:731 msgctxt "RefundDialog|" msgid "Refund" msgstr "" #: ../src/eqonomize.cpp:693 msgctxt "RefundDialog|" msgid "Date:" msgstr "" #: ../src/eqonomize.cpp:711 msgctxt "RefundDialog|" msgid "Cost:" msgstr "" #: ../src/eqonomize.cpp:712 msgctxt "RefundDialog|" msgid "Income:" msgstr "" #: ../src/eqonomize.cpp:721 msgctxt "RefundDialog|" msgid "Account:" msgstr "" #: ../src/eqonomize.cpp:717 msgctxt "RefundDialog|" msgid "Quantity:" msgstr "" #: ../src/eqonomize.cpp:728 msgctxt "RefundDialog|" msgid "Comments:" msgstr "" #: ../src/eqonomize.cpp:787 msgctxt "RefundDialog|" msgid "Error" msgstr "" #: ../src/eqonomize.cpp:787 msgctxt "RefundDialog|" msgid "Invalid date." msgstr "" #: ../src/transaction.cpp:1121 #, qt-format msgctxt "SecurityBuy|Financial security (e.g. stock, mutual fund)" msgid "Security: %1 (bought)" msgstr "" #: ../src/transaction.cpp:1171 #, qt-format msgctxt "SecuritySell|Financial security (e.g. stock, mutual fund)" msgid "Security: %1 (sold)" msgstr "" #: ../src/eqonomize.cpp:1409 #, qt-format msgctxt "SecurityTransactionsDialog|" msgid "Transactions for %1" msgstr "" #: ../src/eqonomize.cpp:1417 msgctxt "SecurityTransactionsDialog|" msgid "Date" msgstr "" #: ../src/eqonomize.cpp:1418 msgctxt "SecurityTransactionsDialog|" msgid "Type" msgstr "" #: ../src/eqonomize.cpp:1419 msgctxt "SecurityTransactionsDialog|" msgid "Value" msgstr "" #: ../src/eqonomize.cpp:1420 msgctxt "SecurityTransactionsDialog|Financial shares" msgid "Shares" msgstr "" #: ../src/eqonomize.cpp:1535 msgctxt "SecurityTransactionsDialog|Financial shares" msgid "Shares Bought" msgstr "" #: ../src/eqonomize.cpp:1581 msgctxt "SecurityTransactionsDialog|Financial shares" msgid "Shares Bought (Recurring)" msgstr "" #: ../src/eqonomize.cpp:1596 msgctxt "SecurityTransactionsDialog|" msgid "Dividend (Recurring)" msgstr "" #: ../src/eqonomize.cpp:1598 msgctxt "SecurityTransactionsDialog|" msgid "Dividend (Scheduled)" msgstr "" #: ../src/eqonomize.cpp:1610 msgctxt "SecurityTransactionsDialog|" msgid "Reinvested Dividend (Recurring)" msgstr "" #: ../src/eqonomize.cpp:1612 msgctxt "SecurityTransactionsDialog|" msgid "Reinvested Dividend (Scheduled)" msgstr "" #: ../src/eqonomize.cpp:1536 msgctxt "SecurityTransactionsDialog|Financial shares" msgid "Shares Sold" msgstr "" #: ../src/eqonomize.cpp:1566 msgctxt "" "SecurityTransactionsDialog|Shares of one security directly exchanged for " "shares of another; Financial shares" msgid "Shares Sold (Exchanged)" msgstr "" #: ../src/eqonomize.cpp:1566 msgctxt "" "SecurityTransactionsDialog|Shares of one security directly exchanged for " "shares of another; Financial shares" msgid "Shares Bought (Exchanged)" msgstr "" #: ../src/eqonomize.cpp:1582 msgctxt "SecurityTransactionsDialog|Financial shares" msgid "Shares Sold (Recurring)" msgstr "" #: ../src/eqonomize.cpp:1584 msgctxt "SecurityTransactionsDialog|Financial shares" msgid "Shares Bought (Scheduled)" msgstr "" #: ../src/eqonomize.cpp:1585 msgctxt "SecurityTransactionsDialog|Financial shares" msgid "Shares Sold (Scheduled)" msgstr "" #: ../src/eqonomize.cpp:1434 msgctxt "SecurityTransactionsDialog|" msgid "Edit…" msgstr "" #: ../src/eqonomize.cpp:1436 msgctxt "SecurityTransactionsDialog|" msgid "Delete" msgstr "" #: ../src/eqonomize.cpp:1541 msgctxt "SecurityTransactionsDialog|" msgid "Dividend" msgstr "" #: ../src/eqonomize.cpp:1549 msgctxt "SecurityTransactionsDialog|" msgid "Reinvested Dividend" msgstr "" #: ../src/transactioneditwidget.cpp:85 ../src/transactioneditwidget.cpp:87 #: ../src/transactioneditwidget.cpp:98 msgctxt "TagButton|" msgid "no tags" msgstr "" #: ../src/transactioneditwidget.cpp:153 msgctxt "TagMenu|" msgid "New tag…" msgstr "" #: ../src/transactioneditwidget.cpp:288 msgctxt "TagMenu|" msgid "New Tag" msgstr "" #: ../src/transactioneditwidget.cpp:288 msgctxt "TagMenu|" msgid "Tag:" msgstr "" #: ../src/transactioneditwidget.cpp:2078 msgctxt "TransactionEditDialog|" msgid "Edit Expense" msgstr "" #: ../src/transactioneditwidget.cpp:2080 msgctxt "TransactionEditDialog|" msgid "Edit Dividend" msgstr "" #: ../src/transactioneditwidget.cpp:2081 msgctxt "TransactionEditDialog|" msgid "Edit Income" msgstr "" #: ../src/transactioneditwidget.cpp:2084 msgctxt "TransactionEditDialog|" msgid "Edit Transfer" msgstr "" #: ../src/transactioneditwidget.cpp:2085 msgctxt "TransactionEditDialog|Financial security (e.g. stock, mutual fund)" msgid "Edit Securities Purchase" msgstr "" #: ../src/transactioneditwidget.cpp:2086 msgctxt "TransactionEditDialog|Financial security (e.g. stock, mutual fund)" msgid "Edit Securities Sale" msgstr "" #: ../src/transactioneditwidget.cpp:2087 msgctxt "TransactionEditDialog|" msgid "Edit Reinvested Dividend" msgstr "" #: ../src/transactioneditwidget.cpp:377 ../src/transactioneditwidget.cpp:475 msgctxt "TransactionEditWidget|" msgid "Cost:" msgstr "" #: ../src/transactioneditwidget.cpp:378 ../src/transactioneditwidget.cpp:473 msgctxt "TransactionEditWidget|" msgid "Income:" msgstr "" #: ../src/transactioneditwidget.cpp:400 msgctxt "TransactionEditWidget|" msgid "All" msgstr "" #: ../src/transactioneditwidget.cpp:427 ../src/transactioneditwidget.cpp:522 msgctxt "TransactionEditWidget|" msgid "Date:" msgstr "" #: ../src/transactioneditwidget.cpp:905 msgctxt "TransactionEditWidget|" msgid "Amount:" msgstr "" #: ../src/transactioneditwidget.cpp:509 msgctxt "TransactionEditWidget|" msgid "Downpayment:" msgstr "" #: ../src/transactioneditwidget.cpp:385 msgctxt "TransactionEditWidget|Financial shares" msgid "Shares added:" msgstr "" #: ../src/transactioneditwidget.cpp:412 msgctxt "TransactionEditWidget|" msgid "Set security share value" msgstr "" #: ../src/transactioneditwidget.cpp:421 msgctxt "TransactionEditWidget|" msgid "Total value:" msgstr "" #: ../src/transactioneditwidget.cpp:515 msgctxt "TransactionEditWidget|" msgid "Quantity:" msgstr "" #: ../src/transactioneditwidget.cpp:540 msgctxt "TransactionEditWidget|" msgid "From:" msgstr "" #: ../src/transactioneditwidget.cpp:546 msgctxt "TransactionEditWidget|" msgid "To:" msgstr "" #: ../src/transactioneditwidget.cpp:555 ../src/transactioneditwidget.cpp:594 #: ../src/transactioneditwidget.cpp:602 msgctxt "TransactionEditWidget|" msgid "Category:" msgstr "" #: ../src/transactioneditwidget.cpp:561 ../src/transactioneditwidget.cpp:586 msgctxt "TransactionEditWidget|" msgid "To account:" msgstr "" #: ../src/transactioneditwidget.cpp:567 msgctxt "TransactionEditWidget|" msgid "Payer:" msgstr "" #: ../src/transactioneditwidget.cpp:577 ../src/transactioneditwidget.cpp:612 msgctxt "TransactionEditWidget|" msgid "From account:" msgstr "" #: ../src/transactioneditwidget.cpp:609 msgctxt "TransactionEditWidget|" msgid "Downpayment account:" msgstr "" #: ../src/transactioneditwidget.cpp:619 msgctxt "TransactionEditWidget|" msgid "Payee:" msgstr "" #: ../src/transactioneditwidget.cpp:628 msgctxt "TransactionEditWidget|" msgid "Lender:" msgstr "" #: ../src/transactioneditwidget.cpp:664 msgctxt "TransactionEditWidget|" msgid "Comments:" msgstr "" #: ../src/transactioneditwidget.cpp:1426 msgctxt "TransactionEditWidget|Financial security (e.g. stock, mutual fund)" msgid "No security available." msgstr "" #: ../src/transactioneditwidget.cpp:355 ../src/transactioneditwidget.cpp:439 msgctxt "TransactionEditWidget|Financial security (e.g. stock, mutual fund)" msgid "Security:" msgstr "" #: ../src/transactioneditwidget.cpp:359 ../src/transactioneditwidget.cpp:443 #: ../src/transactioneditwidget.cpp:1055 msgctxt "TransactionEditWidget|Financial security (e.g. stock, mutual fund)" msgid "New Security…" msgstr "" #: ../src/transactioneditwidget.cpp:390 msgctxt "TransactionEditWidget|Financial shares" msgid "Shares bought:" msgstr "" #: ../src/transactioneditwidget.cpp:395 msgctxt "TransactionEditWidget|Financial shares" msgid "Shares sold:" msgstr "" #: ../src/transactioneditwidget.cpp:408 msgctxt "TransactionEditWidget|Financial shares" msgid "Price per share:" msgstr "" #: ../src/transactioneditwidget.cpp:460 msgctxt "" "TransactionEditWidget|Transaction description property (transaction " "title/generic article name)" msgid "Description:" msgstr "" #: ../src/transactioneditwidget.cpp:465 msgctxt "TransactionEditWidget|" msgid "Transaction title/generic article name" msgstr "" #: ../src/transactioneditwidget.cpp:470 ../src/transactioneditwidget.cpp:903 msgctxt "TransactionEditWidget|Money taken out from account" msgid "Withdrawal:" msgstr "" #: ../src/transactioneditwidget.cpp:499 msgctxt "TransactionEditWidget|Money put into account" msgid "Deposit:" msgstr "" #: ../src/transactioneditwidget.cpp:517 msgctxt "TransactionEditWidget|" msgid "" "Number of items included in the transaction. Entered cost is total cost for " "all items." msgstr "" #: ../src/transactioneditwidget.cpp:569 msgctxt "TransactionEditWidget|" msgid "Payer of parent split transaction" msgstr "" #: ../src/transactioneditwidget.cpp:621 msgctxt "TransactionEditWidget|" msgid "Payee of parent split transaction" msgstr "" #: ../src/transactioneditwidget.cpp:634 msgctxt "TransactionEditWidget|" msgid "Tags:" msgstr "" #: ../src/transactioneditwidget.cpp:642 msgctxt "TransactionEditWidget|" msgid "Associated file:" msgstr "" #: ../src/transactioneditwidget.cpp:650 msgctxt "TransactionEditWidget|" msgid "Select a file" msgstr "" #: ../src/transactioneditwidget.cpp:654 msgctxt "TransactionEditWidget|" msgid "Open the file" msgstr "" #: ../src/transactioneditwidget.cpp:1048 msgctxt "TransactionEditWidget|Financial security (e.g. stock, mutual fund)" msgid "New Security" msgstr "" #: ../src/transactioneditwidget.cpp:1372 ../src/transactioneditwidget.cpp:1376 #: ../src/transactioneditwidget.cpp:1383 ../src/transactioneditwidget.cpp:1387 #: ../src/transactioneditwidget.cpp:1394 ../src/transactioneditwidget.cpp:1401 #: ../src/transactioneditwidget.cpp:1408 ../src/transactioneditwidget.cpp:1415 #: ../src/transactioneditwidget.cpp:1419 ../src/transactioneditwidget.cpp:1426 #: ../src/transactioneditwidget.cpp:1437 ../src/transactioneditwidget.cpp:1447 #: ../src/transactioneditwidget.cpp:1451 ../src/transactioneditwidget.cpp:1458 #: ../src/transactioneditwidget.cpp:1465 ../src/transactioneditwidget.cpp:1472 #: ../src/transactioneditwidget.cpp:1480 ../src/transactioneditwidget.cpp:1484 #: ../src/transactioneditwidget.cpp:1488 ../src/transactioneditwidget.cpp:1500 msgctxt "TransactionEditWidget|" msgid "Error" msgstr "" #: ../src/transactioneditwidget.cpp:1372 ../src/transactioneditwidget.cpp:1376 #: ../src/transactioneditwidget.cpp:1387 ../src/transactioneditwidget.cpp:1408 #: ../src/transactioneditwidget.cpp:1419 msgctxt "TransactionEditWidget|" msgid "No suitable account available." msgstr "" #: ../src/transactioneditwidget.cpp:1383 ../src/transactioneditwidget.cpp:1401 msgctxt "TransactionEditWidget|" msgid "No income category available." msgstr "" #: ../src/transactioneditwidget.cpp:1394 msgctxt "TransactionEditWidget|" msgid "No suitable account or income category available." msgstr "" #: ../src/transactioneditwidget.cpp:1415 msgctxt "TransactionEditWidget|" msgid "No expense category available." msgstr "" #: ../src/transactioneditwidget.cpp:1437 msgctxt "TransactionEditWidget|" msgid "Invalid date." msgstr "" #: ../src/transactioneditwidget.cpp:1447 msgctxt "TransactionEditWidget|" msgid "Cannot transfer money to and from the same account." msgstr "" #: ../src/transactioneditwidget.cpp:1451 msgctxt "TransactionEditWidget|" msgid "Downpayment must be less than total cost." msgstr "" #: ../src/transactioneditwidget.cpp:1458 msgctxt "TransactionEditWidget|" msgid "Cannot create a regular transfer to/from a securities account." msgstr "" #: ../src/transactioneditwidget.cpp:1465 msgctxt "TransactionEditWidget|" msgid "Cannot create a regular income to a securities account." msgstr "" #: ../src/transactioneditwidget.cpp:1472 ../src/transactioneditwidget.cpp:1480 msgctxt "TransactionEditWidget|" msgid "Zero shares not allowed." msgstr "" #: ../src/transactioneditwidget.cpp:1484 msgctxt "TransactionEditWidget|" msgid "Zero value not allowed." msgstr "" #: ../src/transactioneditwidget.cpp:1488 msgctxt "TransactionEditWidget|" msgid "Zero price per share not allowed." msgstr "" #: ../src/transactioneditwidget.cpp:1500 msgctxt "TransactionEditWidget|" msgid "Cannot create a regular expense from a securities account." msgstr "" #: ../src/transactioneditwidget.cpp:1581 #, qt-format msgctxt "TransactionEditWidget|" msgid "Loan for %1" msgstr "" #: ../src/transactionfilterwidget.cpp:55 ../src/transactionfilterwidget.cpp:72 msgctxt "TransactionFilterWidget|" msgid "From:" msgstr "" #: ../src/transactionfilterwidget.cpp:62 ../src/transactionfilterwidget.cpp:76 msgctxt "TransactionFilterWidget|" msgid "To:" msgstr "" #: ../src/transactionfilterwidget.cpp:80 msgctxt "TransactionFilterWidget|" msgid "Min amount:" msgstr "" #: ../src/transactionfilterwidget.cpp:81 msgctxt "TransactionFilterWidget|" msgid "Max amount:" msgstr "" #: ../src/transactionfilterwidget.cpp:83 ../src/transactionfilterwidget.cpp:94 msgctxt "TransactionFilterWidget|" msgid "Category:" msgstr "" #: ../src/transactionfilterwidget.cpp:87 msgctxt "TransactionFilterWidget|" msgid "To account:" msgstr "" #: ../src/transactionfilterwidget.cpp:91 msgctxt "TransactionFilterWidget|" msgid "Min income:" msgstr "" #: ../src/transactionfilterwidget.cpp:92 msgctxt "TransactionFilterWidget|" msgid "Max income:" msgstr "" #: ../src/transactionfilterwidget.cpp:98 msgctxt "TransactionFilterWidget|" msgid "From account:" msgstr "" #: ../src/transactionfilterwidget.cpp:102 msgctxt "TransactionFilterWidget|" msgid "Min cost:" msgstr "" #: ../src/transactionfilterwidget.cpp:103 msgctxt "TransactionFilterWidget|" msgid "Max cost:" msgstr "" #: ../src/transactionfilterwidget.cpp:116 msgctxt "" "TransactionFilterWidget|Transaction description property (transaction " "title/generic article name)" msgid "Description:" msgstr "" #: ../src/transactionfilterwidget.cpp:124 msgctxt "TransactionFilterWidget|" msgid "Tag:" msgstr "" #: ../src/transactionfilterwidget.cpp:131 msgctxt "TransactionFilterWidget|" msgid "Include" msgstr "" #: ../src/transactionfilterwidget.cpp:135 msgctxt "TransactionFilterWidget|" msgid "Exclude" msgstr "" #: ../src/transactionfilterwidget.cpp:138 msgctxt "TransactionFilterWidget|" msgid "Exact match" msgstr "" #: ../src/transactionfilterwidget.cpp:141 msgctxt "TransactionFilterWidget|" msgid "Exclude subcategories" msgstr "" #: ../src/transactionfilterwidget.cpp:145 msgctxt "TransactionFilterWidget|" msgid "Clear" msgstr "" #: ../src/transactionfilterwidget.cpp:155 #: ../src/transactionfilterwidget.cpp:156 #: ../src/transactionfilterwidget.cpp:159 #: ../src/transactionfilterwidget.cpp:342 #: ../src/transactionfilterwidget.cpp:349 #: ../src/transactionfilterwidget.cpp:379 msgctxt "TransactionFilterWidget|" msgid "All" msgstr "" #: ../src/transactionfilterwidget.cpp:737 #: ../src/transactionfilterwidget.cpp:768 msgctxt "TransactionFilterWidget|" msgid "Error" msgstr "" #: ../src/transactionfilterwidget.cpp:737 #: ../src/transactionfilterwidget.cpp:768 msgctxt "TransactionFilterWidget|" msgid "Invalid date." msgstr "" #: ../src/transactionlistwidget.cpp:110 msgctxt "TransactionListWidget|" msgid "Date" msgstr "" #: ../src/transactionlistwidget.cpp:118 msgctxt "TransactionListWidget|" msgid "Cost" msgstr "" #: ../src/transactionlistwidget.cpp:119 ../src/transactionlistwidget.cpp:133 msgctxt "TransactionListWidget|" msgid "Category" msgstr "" #: ../src/transactionlistwidget.cpp:120 msgctxt "TransactionListWidget|" msgid "From Account" msgstr "" #: ../src/transactionlistwidget.cpp:121 msgctxt "TransactionListWidget|" msgid "Payee" msgstr "" #: ../src/transactionlistwidget.cpp:127 ../src/transactionlistwidget.cpp:139 #: ../src/transactionlistwidget.cpp:2008 ../src/transactionlistwidget.cpp:2028 msgctxt "TransactionListWidget|" msgid "Tags" msgstr "" #: ../src/transactionlistwidget.cpp:132 ../src/transactionlistwidget.cpp:326 msgctxt "TransactionListWidget|" msgid "Income" msgstr "" #: ../src/transactionlistwidget.cpp:134 msgctxt "TransactionListWidget|" msgid "To Account" msgstr "" #: ../src/transactionlistwidget.cpp:135 msgctxt "TransactionListWidget|" msgid "Payer" msgstr "" #: ../src/transactionlistwidget.cpp:144 msgctxt "TransactionListWidget|" msgid "Amount" msgstr "" #: ../src/transactionlistwidget.cpp:145 msgctxt "TransactionListWidget|" msgid "From" msgstr "" #: ../src/transactionlistwidget.cpp:146 msgctxt "TransactionListWidget|" msgid "To" msgstr "" #: ../src/transactionlistwidget.cpp:151 msgctxt "TransactionListWidget|" msgid "Comments" msgstr "" #: ../src/transactionlistwidget.cpp:187 msgctxt "TransactionListWidget|" msgid "Add" msgstr "" #: ../src/transactionlistwidget.cpp:188 ../src/transactionlistwidget.cpp:1891 msgctxt "TransactionListWidget|" msgid "Apply" msgstr "" #: ../src/transactionlistwidget.cpp:190 msgctxt "TransactionListWidget|" msgid "Delete" msgstr "" #: ../src/transactionlistwidget.cpp:111 msgctxt "" "TransactionListWidget|Transaction description property (transaction " "title/generic article name)" msgid "Description" msgstr "" #: ../src/transactionlistwidget.cpp:198 msgctxt "TransactionListWidget|" msgid "New/Edit Expense" msgstr "" #: ../src/transactionlistwidget.cpp:199 msgctxt "TransactionListWidget|" msgid "New/Edit Income" msgstr "" #: ../src/transactionlistwidget.cpp:200 msgctxt "TransactionListWidget|" msgid "New/Edit Transfer" msgstr "" #: ../src/transactionlistwidget.cpp:203 msgctxt "TransactionListWidget|" msgid "Filter" msgstr "" #: ../src/transactionlistwidget.cpp:326 ../src/transactionlistwidget.cpp:331 #: ../src/transactionlistwidget.cpp:513 msgctxt "TransactionListWidget|" msgid "Quantity:" msgstr "" #: ../src/transactionlistwidget.cpp:331 msgctxt "TransactionListWidget|" msgid "Total:" msgstr "" #: ../src/transactionlistwidget.cpp:326 ../src/transactionlistwidget.cpp:331 #: ../src/transactionlistwidget.cpp:531 msgctxt "TransactionListWidget|" msgid "Average:" msgstr "" #: ../src/transactionlistwidget.cpp:189 msgctxt "TransactionListWidget|" msgid "Clear" msgstr "" #: ../src/transactionlistwidget.cpp:326 msgctxt "TransactionListWidget|" msgid "Cost:" msgstr "" #: ../src/transactionlistwidget.cpp:331 msgctxt "TransactionListWidget|" msgid "Monthly:" msgstr "" #: ../src/transactionlistwidget.cpp:424 msgctxt "TransactionListWidget|" msgid "Sort by creation time" msgstr "" #: ../src/transactionlistwidget.cpp:454 ../src/transactionlistwidget.cpp:466 msgctxt "TransactionListWidget|" msgid "Expenses" msgstr "" #: ../src/transactionlistwidget.cpp:455 ../src/transactionlistwidget.cpp:467 msgctxt "TransactionListWidget|" msgid "Incomes" msgstr "" #: ../src/transactionlistwidget.cpp:456 ../src/transactionlistwidget.cpp:468 msgctxt "TransactionListWidget|" msgid "Transfers" msgstr "" #: ../src/transactionlistwidget.cpp:122 msgctxt "TransactionListWidget|" msgid "Quantity" msgstr "" #: ../src/transactionlistwidget.cpp:517 msgctxt "TransactionListWidget|" msgid "Total cost:" msgstr "" #: ../src/transactionlistwidget.cpp:521 msgctxt "TransactionListWidget|" msgid "Total income:" msgstr "" #: ../src/transactionlistwidget.cpp:525 msgctxt "TransactionListWidget|" msgid "Total amount:" msgstr "" #: ../src/transactionlistwidget.cpp:533 msgctxt "TransactionListWidget|" msgid "Monthly average:" msgstr "" #: ../src/transactionlistwidget.cpp:909 ../src/transactionlistwidget.cpp:915 #: ../src/transactionlistwidget.cpp:921 ../src/transactionlistwidget.cpp:929 #: ../src/transactionlistwidget.cpp:935 msgctxt "TransactionListWidget|" msgid "Error" msgstr "" #: ../src/transactionlistwidget.cpp:909 msgctxt "TransactionListWidget|Financial security (e.g. stock, mutual fund)" msgid "" "Cannot set the value of security transactions using the dialog for modifying " "multiple transactions." msgstr "" #: ../src/transactionlistwidget.cpp:915 msgctxt "" "TransactionListWidget|Referring to the transaction description property " "(transaction title/generic article name); Financial security (e.g. stock, " "mutual fund)" msgid "Cannot change description of dividends and security transactions." msgstr "" #: ../src/transactionlistwidget.cpp:921 msgctxt "TransactionListWidget|Financial security (e.g. stock, mutual fund)" msgid "Cannot change payer of dividends and security transactions." msgstr "" #: ../src/transactionlistwidget.cpp:929 msgctxt "" "TransactionListWidget|Referring to the transaction description property " "(transaction title/generic article name)" msgid "" "Cannot change date, description, expense category or payee of transactions " "that are part of a debt payment using the dialog for modifying multiple " "transactions." msgstr "" #: ../src/transactionlistwidget.cpp:935 msgctxt "TransactionListWidget|" msgid "" "Cannot change date of transactions that are part of a split transaction, " "unless all individual transactions are selected." msgstr "" #: ../src/transactionlistwidget.cpp:1206 ../src/transactionlistwidget.cpp:1288 msgctxt "TransactionListWidget|" msgid "Delete transactions?" msgstr "" #: ../src/transactionlistwidget.cpp:1206 #, qt-format msgctxt "TransactionListWidget|" msgid "" "Are you sure you want to delete all (%1) transactions in the selected split " "transaction?" msgstr "" #: ../src/transactionlistwidget.cpp:1288 #, qt-format msgctxt "TransactionListWidget|" msgid "Are you sure you want to delete all (%1) selected transactions?" msgstr "" #: ../src/transactionlistwidget.cpp:1870 msgctxt "TransactionListWidget|" msgid "* Part of split transaction" msgstr "" #: ../src/transactionlistwidget.cpp:1871 #, qt-format msgctxt "TransactionListWidget|" msgid "* Part of split (%1)" msgstr "" #: ../src/transactionlistwidget.cpp:1866 msgctxt "TransactionListWidget|" msgid "** Recurring (editing occurrence)" msgstr "" #: ../src/transactionlistwidget.cpp:1887 msgctxt "TransactionListWidget|" msgid "Modify…" msgstr "" #: ../src/transactionlistwidget.cpp:1889 msgctxt "TransactionListWidget|" msgid "Edit…" msgstr "" Eqonomize-1.5.3/snap/000077500000000000000000000000001416454732000144355ustar00rootroot00000000000000Eqonomize-1.5.3/snap/gui/000077500000000000000000000000001416454732000152215ustar00rootroot00000000000000Eqonomize-1.5.3/snap/gui/eqonomize.desktop000066400000000000000000000011251416454732000206210ustar00rootroot00000000000000[Desktop Entry] Name=Eqonomize! GenericName=Personal Accounting GenericName[sv]=Bokföring GenericName[de]=Buchhaltung GenericName[ro]=Contabilitate Personala Exec=eqonomize-hk %U Icon=${SNAP}/meta/gui/eqonomize.svg Type=Application MimeType=application/x-eqonomize; X-DocPath=eqonomize/index.html Categories=Qt;KDE;Office;Finance; X-KDE-StartupNotify=true #X-DBUS-StartupType=Unique #X-DBUS-ServiceName=eqonomize Terminal=false Comment=Manage your personal finances Comment[sv]=Hantera din privatekonomi Comment[de]=Verwaltung der persönlichen Finanzen Comment[ro]=Gerează finanțele personale Eqonomize-1.5.3/snap/gui/eqonomize.svg000066400000000000000000000654431416454732000177640ustar00rootroot00000000000000 image/svg+xml Eqonomize-1.5.3/snap/snapcraft.yaml000066400000000000000000000043501416454732000173040ustar00rootroot00000000000000name: eqonomize-hk title: Eqonomize! version: '1.5.3' license: GPL-2.0+ summary: Efficient and easy accounting for small households description: | Eqonomize! is a cross-platform personal accounting software, with focus on efficiency and ease of use for small households. Eqonomize! provides a complete solution, with bookkeeping by double entry and support for scheduled recurring transactions, security investments, and budgeting. It gives a clear overview of past and present transactions, and development of incomes and expenses, with descriptive tables and charts, as well as an approximation of future account values. grade: stable confinement: strict base: core18 apps: eqonomize-hk: command: bin/desktop-launch eqonomize plugs: [x11, desktop, desktop-legacy, wayland, unity7, gsettings, home, network, cups-control, removable-media] parts: eqonomize: source: https://github.com/Eqonomize/eqonomize/releases/download/v1.5.3/eqonomize-1.5.3.tar.gz source-type: tar source-checksum: sha512/2aff1681e336ceaad794461a84de57b074a99c0c7ba8f5ec8b03617df2a76e4d9189c78c3324fece4f5e102e438fb9319311c133fab18f2ae7822298eb6ea3b5 plugin: qmake qt-version: qt5 after: [desktop-qt5] options: - PREFIX=/usr - COMPILE_RESOURCES="yes" desktop-qt5: source: https://github.com/ubuntu/snapcraft-desktop-helpers.git source-tag: v20180201 source-depth: 1 source-subdir: qt plugin: make make-parameters: ["FLAVOR=qt5"] build-packages: - build-essential - qtbase5-dev - libqt5charts5-dev - dpkg-dev stage-packages: - libxkbcommon0 - ttf-ubuntu-font-family - dmz-cursor-theme - light-themes - adwaita-icon-theme - gnome-themes-standard - shared-mime-info - libqt5core5a - libqt5gui5 - libqt5network5 - libqt5printsupport5 - libqt5charts5 - libgtk2.0-0 - libgdk-pixbuf2.0-0 - libqt5svg5 - qtwayland5 - qt5-gtk-platformtheme - qt5-style-plugins - locales-all - xdg-user-dirs - fcitx-frontend-qt5 override-build: | snapcraftctl build sed -i '/export QT_QPA_PLATFORMTHEME=appmenu-qt5/d' $SNAPCRAFT_PART_INSTALL/bin/desktop-launch Eqonomize-1.5.3/src/000077500000000000000000000000001416454732000142635ustar00rootroot00000000000000Eqonomize-1.5.3/src/account.cpp000066400000000000000000000477241416454732000164410ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016-2017 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include "account.h" #include "budget.h" Account::Account(Budget *parent_budget, QString initial_name, QString initial_description) : o_budget(parent_budget), i_id(parent_budget->getNewId()), i_first_revision(parent_budget->revision()), i_last_revision(parent_budget->revision()), s_name(initial_name.trimmed()), s_description(initial_description.trimmed()) {} Account::Account(Budget *parent_budget, QXmlStreamReader *xml, bool *valid) : o_budget(parent_budget) { QXmlStreamAttributes attr = xml->attributes(); readAttributes(&attr, valid); readElements(xml, valid); } Account::Account(Budget *parent_budget) : o_budget(parent_budget), i_first_revision(parent_budget->revision()), i_last_revision(parent_budget->revision()) {} Account::Account() : o_budget(NULL), i_id(0), i_first_revision(1), i_last_revision(1) {} Account::Account(const Account *account) : o_budget(account->budget()), i_id(account->id()), i_first_revision(account->firstRevision()), i_last_revision(account->lastRevision()), s_name(account->name()), s_description(account->description()) {} Account::~Account() {} void Account::set(const Account *account) { i_id = account->id(); i_first_revision = account->firstRevision(); i_last_revision = account->lastRevision(); s_name = account->name(); s_description = account->description(); } void Account::readAttributes(QXmlStreamAttributes *attr, bool*) { read_id(attr, i_id, i_first_revision, i_last_revision); s_name = attr->value("name").trimmed().toString(); s_description = attr->value("description").trimmed().toString(); } bool Account::readElement(QXmlStreamReader*, bool*) {return false;} bool Account::readElements(QXmlStreamReader *xml, bool *valid) { while(xml->readNextStartElement()) { if(!readElement(xml, valid)) xml->skipCurrentElement(); } return true; } void Account::save(QXmlStreamWriter *xml) { QXmlStreamAttributes attr; writeAttributes(&attr); xml->writeAttributes(attr); writeElements(xml); } void Account::writeAttributes(QXmlStreamAttributes *attr) { attr->append("name", s_name); write_id(attr, i_id, i_first_revision, i_last_revision); if(!s_description.isEmpty()) attr->append("description", s_description); } void Account::writeElements(QXmlStreamWriter*) {} const QString &Account::name() const {return s_name;} QString Account::nameWithParent(bool) const {return s_name;} Account *Account::topAccount() {return this;} void Account::setName(QString new_name) {s_name = new_name.trimmed(); o_budget->accountNameModified(this);} const QString &Account::description() const {return s_description;} void Account::setDescription(QString new_description) {s_description = new_description.trimmed();} bool Account::isClosed() const {return false;} Budget *Account::budget() const {return o_budget;} qlonglong Account::id() const {return i_id;} void Account::setId(qlonglong new_id) {i_id = new_id;} int Account::firstRevision() const {return i_first_revision;} void Account::setFirstRevision(int new_rev) {i_first_revision = new_rev; if(i_first_revision > i_last_revision) i_last_revision = i_first_revision;} int Account::lastRevision() const {return i_last_revision;} void Account::setLastRevision(int new_rev) {i_last_revision = new_rev;} Currency *Account::currency() const {return o_budget->defaultCurrency();} AssetsAccount::AssetsAccount(Budget *parent_budget, int initial_type, QString initial_name, double initial_balance, QString initial_description) : Account(parent_budget, initial_name, initial_description), at_type(initial_type), d_initbal(initial_type == ASSETS_TYPE_SECURITIES ? 0.0 : initial_balance), b_closed(false) { o_currency = parent_budget->defaultCurrency(); } AssetsAccount::AssetsAccount(Budget *parent_budget, QXmlStreamReader *xml, bool *valid) : Account(parent_budget) { o_currency = NULL; QXmlStreamAttributes attr = xml->attributes(); readAttributes(&attr, valid); readElements(xml, valid); } AssetsAccount::AssetsAccount(Budget *parent_budget) : Account(parent_budget), at_type(ASSETS_TYPE_CASH), d_initbal(0.0), b_closed(false) { o_currency = parent_budget->defaultCurrency(); i_id = parent_budget->getNewId(); } AssetsAccount::AssetsAccount() : Account(), at_type(ASSETS_TYPE_CASH), d_initbal(0.0), b_closed(false), o_currency(NULL) {} AssetsAccount::AssetsAccount(const AssetsAccount *account) : Account(account), at_type(account->accountType()), d_initbal(account->initialBalance()), b_closed(account->isClosed()), o_currency(account->currency()) {} AssetsAccount::~AssetsAccount() {if(o_budget->budgetAccount == this) o_budget->budgetAccount = NULL;} void AssetsAccount::set(const AssetsAccount *account) { Account::set(account); at_type = account->accountType(); d_initbal = account->initialBalance(); b_closed = account->isClosed(); o_currency = account->currency(); } void AssetsAccount::readAttributes(QXmlStreamAttributes *attr, bool *valid) { Account::readAttributes(attr, valid); QString type = attr->value("type").trimmed().toString(); at_type = o_budget->getAccountType(type); if(attr->hasAttribute("lender")) s_maintainer = attr->value("lender").trimmed().toString(); else if(attr->hasAttribute("issuer")) s_maintainer = attr->value("issuer").trimmed().toString(); else s_maintainer = attr->value("bank").trimmed().toString(); s_group = attr->value("group").trimmed().toString(); if(s_group == o_budget->getAccountTypeName(at_type, true, true)) s_group = ""; QString s_cur = attr->value("currency").trimmed().toString(); if(!s_cur.isEmpty()) { o_currency = o_budget->findCurrency(s_cur); } if(!o_currency) o_currency = o_budget->defaultCurrency(); if(!isSecurities()) { d_initbal = attr->value("initialbalance").toDouble(); if(attr->hasAttribute("budgetaccount") && !isLiabilities()) { bool b_budget = attr->value("budgetaccount").toInt(); if(b_budget) { o_budget->budgetAccount = this; } } } if(!isDebt() && attr->hasAttribute("closed")) { b_closed = attr->value("closed").toInt(); } else { b_closed = false; } } bool AssetsAccount::isDebt() const { return o_budget->accountTypeIsDebt(at_type); } bool AssetsAccount::isCreditCard() const { return o_budget->accountTypeIsCreditCard(at_type); } bool AssetsAccount::isSecurities() const { return o_budget->accountTypeIsSecurities(at_type); } bool AssetsAccount::isLiabilities() const { return o_budget->accountTypeIsLiabilities(at_type); } bool AssetsAccount::isTypeOther() const { return o_budget->accountTypeIsOther(at_type); } void AssetsAccount::writeAttributes(QXmlStreamAttributes *attr) { Account::writeAttributes(attr); if(o_currency) attr->append("currency", o_currency->code()); if(!isSecurities()) { attr->append("initialbalance", QString::number(d_initbal, 'f', SAVE_MONETARY_DECIMAL_PLACES)); if(o_budget->budgetAccount == this) { attr->append("budgetaccount", QString::number(o_budget->budgetAccount == this)); } } attr->append("type", o_budget->getAccountTypeName(at_type)); if(!s_group.isEmpty()) attr->append("group", s_group); if(!s_maintainer.isEmpty()) { if(isDebt()) attr->append("lender", s_maintainer); else if(isCreditCard()) attr->append("issuer", s_maintainer); else attr->append("bank", s_maintainer); } if(b_closed) attr->append("closed", QString::number(b_closed)); } bool AssetsAccount::isBudgetAccount() const { return o_budget->budgetAccount == this; } void AssetsAccount::setAsBudgetAccount(bool will_be) { if(will_be) { o_budget->budgetAccount = this; } else if(o_budget->budgetAccount == this) { o_budget->budgetAccount = NULL; } } double AssetsAccount::initialBalance(bool calculate_for_securities) const { if(isSecurities()) { if(!calculate_for_securities) return 0.0; double d = 0.0; for(SecurityList::const_iterator it = o_budget->securities.constBegin(); it != o_budget->securities.constEnd(); ++it) { Security *sec = *it; if(sec->account() == this) { d += sec->initialBalance(); } } return d; } return d_initbal; } void AssetsAccount::setInitialBalance(double new_initial_balance) {if(!isSecurities()) d_initbal = new_initial_balance;} AccountType AssetsAccount::type() const {return ACCOUNT_TYPE_ASSETS;} void AssetsAccount::setAccountType(int new_type) { at_type = new_type; if(isDebt()) setAsBudgetAccount(false); if(isSecurities()) d_initbal = 0.0; } void AssetsAccount::setAccountTypeName(const QString &new_type, bool localized) { setAccountType(o_budget->getAccountType(new_type, localized)); } QString AssetsAccount::accountTypeName(bool localized, bool plural) const { return o_budget->getAccountTypeName(at_type, localized, plural); } QString AssetsAccount::group() const { if(s_group.isEmpty()) return o_budget->getAccountTypeName(at_type, true, true); if(s_group == "-") return ""; return s_group; } void AssetsAccount::setGroup(QString group_name) { s_group = group_name.trimmed(); if(s_group.isEmpty()) s_group = "-"; else if(s_group == o_budget->getAccountTypeName(at_type, true, true)) s_group = ""; } bool AssetsAccount::isClosed() const { if(isDebt()) return true; return b_closed; } void AssetsAccount::setClosed(bool close_account) { b_closed = close_account; if(b_closed) setAsBudgetAccount(false); } const QString &AssetsAccount::maintainer() const {return s_maintainer;} void AssetsAccount::setMaintainer(QString maintainer_name) {s_maintainer = maintainer_name.trimmed();} int AssetsAccount::accountType() const {return at_type;} Currency *AssetsAccount::currency() const {if(!o_currency) return o_budget->defaultCurrency(); return o_currency;} void AssetsAccount::setCurrency(Currency *new_currency) {o_currency = new_currency;} bool account_list_less_than(Account *t1, Account *t2) { if(t1->type() != ACCOUNT_TYPE_ASSETS && t2->type() != ACCOUNT_TYPE_ASSETS) { CategoryAccount *cat1 = (CategoryAccount*) t1; CategoryAccount *cat2 = (CategoryAccount*) t2; if(cat1->parentCategory() != cat2->parentCategory()) { if(!cat1->parentCategory()) { if(cat2->parentCategory() == cat1) return true; return QString::localeAwareCompare(cat1->name(), cat2->parentCategory()->name()) < 0; } else if(!cat2->parentCategory()) { if(cat1->parentCategory() == cat2) return false; return QString::localeAwareCompare(cat1->parentCategory()->name(), cat2->name()) < 0; } else { return QString::localeAwareCompare(cat1->parentCategory()->name(), cat2->parentCategory()->name()) < 0; } } } return QString::localeAwareCompare(t1->name(), t2->name()) < 0; } CategoryAccount::CategoryAccount(Budget *parent_budget, QString initial_name, QString initial_description) : Account(parent_budget, initial_name, initial_description), o_parent(NULL) {} CategoryAccount::CategoryAccount(Budget *parent_budget, QXmlStreamReader *xml, bool *valid) : Account(parent_budget), o_parent(NULL) { QXmlStreamAttributes attr = xml->attributes(); readAttributes(&attr, valid); readElements(xml, valid); } CategoryAccount::CategoryAccount(Budget *parent_budget) : Account(parent_budget), o_parent(NULL) {} CategoryAccount::CategoryAccount() : Account(), o_parent(NULL) {} CategoryAccount::CategoryAccount(const CategoryAccount *account) : Account(account), o_parent(NULL) {} CategoryAccount::~CategoryAccount() { if(o_parent) o_parent->removeSubCategory(this, false); for(AccountList::const_iterator it = subCategories.constBegin(); it != subCategories.constEnd(); ++it) { CategoryAccount *ca = *it; ca->o_parent = NULL; delete ca; } subCategories.clear(); } void CategoryAccount::set(const CategoryAccount *account) { Account::set(account); setParentCategory(account->parentCategory()); mbudgets = account->mbudgets; subCategories = account->subCategories; } void CategoryAccount::setMergeBudgets(const CategoryAccount *account) { Account::set(account); setParentCategory(account->parentCategory()); mergeBudgets(account, false); subCategories = account->subCategories; } void CategoryAccount::mergeBudgets(const CategoryAccount *account, bool keep) { for(QMap::const_iterator it = account->mbudgets.begin(); it != account->mbudgets.end(); ++it) { if(!keep || !mbudgets.contains(it.key())) mbudgets[it.key()] = it.value(); } } void CategoryAccount::readAttributes(QXmlStreamAttributes *attr, bool *valid) { Account::readAttributes(attr, valid); if(attr->hasAttribute("monthlybudget")) { double d_mbudget = attr->value("monthlybudget").toDouble(); if(d_mbudget >= 0.0) { QDate date = QDate::currentDate(); date.setDate(date.year(), date.month(), 1); mbudgets[date] = d_mbudget; } } } bool CategoryAccount::readElement(QXmlStreamReader *xml, bool *valid) { if(xml->name() == XML_COMPARE_CONST_CHAR("budget")) { QXmlStreamAttributes attr = xml->attributes(); QDate date = QDate::fromString(attr.value("date").toString(), Qt::ISODate); mbudgets[date] = attr.value("value").toDouble(); return false; } else if(xml->name() == XML_COMPARE_CONST_CHAR("category")) { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) QStringView ctype = xml->attributes().value("type"); #else QStringRef ctype = xml->attributes().value("type"); #endif bool valid2 = true; if(type() == ACCOUNT_TYPE_EXPENSES && ctype == XML_COMPARE_CONST_CHAR("expenses")) { ExpensesAccount *account = new ExpensesAccount(budget(), xml, &valid2); if(valid) { budget()->expensesAccounts_id[account->id()] = account; budget()->expensesAccounts.append(account); budget()->accounts.append(account); addSubCategory(account); } else { delete account; } return true; } else if(type() == ACCOUNT_TYPE_INCOMES && ctype == XML_COMPARE_CONST_CHAR("incomes")) { IncomesAccount *account = new IncomesAccount(budget(), xml, &valid2); if(valid) { budget()->incomesAccounts_id[account->id()] = account; budget()->incomesAccounts.append(account); budget()->accounts.append(account); addSubCategory(account); } else { delete account; } return true; } return false; } return Account::readElement(xml, valid); } void CategoryAccount::writeAttributes(QXmlStreamAttributes *attr) { Account::writeAttributes(attr); } void CategoryAccount::writeElements(QXmlStreamWriter *xml) { Account::writeElements(xml); QMap::const_iterator it_end = mbudgets.end(); for(QMap::const_iterator it = mbudgets.begin(); it != it_end; ++it) { xml->writeStartElement("budget"); xml->writeAttribute("value", QString::number(it.value(), 'f', SAVE_MONETARY_DECIMAL_PLACES)); xml->writeAttribute("date", it.key().toString(Qt::ISODate)); xml->writeEndElement(); } for(AccountList::const_iterator it = subCategories.constBegin(); it != subCategories.constEnd(); ++it) { CategoryAccount *cat = *it; xml->writeStartElement("category"); if(cat->type() == ACCOUNT_TYPE_INCOMES) xml->writeAttribute("type", "incomes"); else xml->writeAttribute("type", "expenses"); cat->save(xml); xml->writeEndElement(); } } double CategoryAccount::monthlyBudget(int year, int month, bool no_default) const { QDate date; date.setDate(year, month, 1); return monthlyBudget(date, no_default); } void CategoryAccount::setMonthlyBudget(int year, int month, double new_monthly_budget) { QDate date; date.setDate(year, month, 1); return setMonthlyBudget(date, new_monthly_budget); } double CategoryAccount::monthlyBudget(const QDate &date, bool no_default) const { if(mbudgets.isEmpty()) return -1.0; QMap::const_iterator it = mbudgets.find(date); if(it != mbudgets.end()) { return it.value(); } if(no_default) return -1.0; it = mbudgets.begin(); if(it.key() > date) return -1.0; QMap::const_iterator it_e = mbudgets.end(); --it_e; while(it_e != it) { if(date > it_e.key()) return it_e.value(); --it_e; } return it.value(); } QString CategoryAccount::nameWithParent(bool formatted) const{ if(o_parent) { if(formatted) return o_parent->name() + QString(": ") + name(); else return o_parent->name() + QString(":") + name(); } return name(); } Account *CategoryAccount::topAccount() { if(o_parent) return o_parent; return this; } void CategoryAccount::setMonthlyBudget(const QDate &date, double new_monthly_budget) { mbudgets[date] = new_monthly_budget; } bool CategoryAccount::removeSubCategory(CategoryAccount *sub_account, bool set_parent) { if(set_parent) return sub_account->setParentCategory(NULL); return subCategories.removeAll(sub_account) > 0; } bool CategoryAccount::addSubCategory(CategoryAccount *sub_account, bool set_parent) { if(o_parent) return false; if(set_parent) return sub_account->setParentCategory(this); subCategories.inSort(sub_account); return true; } CategoryAccount *CategoryAccount::parentCategory() const { return o_parent; } bool CategoryAccount::setParentCategory(CategoryAccount *parent_account, bool add_child) { if(parent_account == o_parent) return false; if(parent_account) { if(type() != parent_account->type()) return false; if(!subCategories.isEmpty()) return false; if(add_child && !parent_account->addSubCategory(this, false)) return false; if(o_parent) o_parent->removeSubCategory(this, false); } else if(o_parent) { o_parent->removeSubCategory(this, false); } o_parent = parent_account; return true; } IncomesAccount::IncomesAccount(Budget *parent_budget, QString initial_name, QString initial_description) : CategoryAccount(parent_budget, initial_name, initial_description) {} IncomesAccount::IncomesAccount(Budget *parent_budget, QXmlStreamReader *xml, bool *valid) : CategoryAccount(parent_budget) { QXmlStreamAttributes attr = xml->attributes(); readAttributes(&attr, valid); readElements(xml, valid); } IncomesAccount::IncomesAccount(Budget *parent_budget) : CategoryAccount(parent_budget) { i_id = parent_budget->getNewId(); } IncomesAccount::IncomesAccount() : CategoryAccount() {} IncomesAccount::IncomesAccount(const IncomesAccount *account) : CategoryAccount(account) {} IncomesAccount::~IncomesAccount() {} AccountType IncomesAccount::type() const {return ACCOUNT_TYPE_INCOMES;} ExpensesAccount::ExpensesAccount(Budget *parent_budget, QString initial_name, QString initial_description) : CategoryAccount(parent_budget, initial_name, initial_description) {} ExpensesAccount::ExpensesAccount(Budget *parent_budget, QXmlStreamReader *xml, bool *valid) : CategoryAccount(parent_budget) { QXmlStreamAttributes attr = xml->attributes(); readAttributes(&attr, valid); readElements(xml, valid); } ExpensesAccount::ExpensesAccount(Budget *parent_budget) : CategoryAccount(parent_budget) { i_id = parent_budget->getNewId(); } ExpensesAccount::ExpensesAccount() : CategoryAccount() {} ExpensesAccount::ExpensesAccount(const ExpensesAccount *account) : CategoryAccount(account) {} ExpensesAccount::~ExpensesAccount() {} AccountType ExpensesAccount::type() const {return ACCOUNT_TYPE_EXPENSES;} Eqonomize-1.5.3/src/account.h000066400000000000000000000174451416454732000161030ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016-2017 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifndef ACCOUNT_H #define ACCOUNT_H #include #include #include #include "eqonomizelist.h" class QXmlStreamReader; class QXmlStreamWriter; class QXmlStreamAttributes; class Budget; class Currency; typedef enum { ACCOUNT_TYPE_ASSETS, ACCOUNT_TYPE_INCOMES, ACCOUNT_TYPE_EXPENSES } AccountType; typedef enum { ASSETS_TYPE_CASH = 100, ASSETS_TYPE_CURRENT = 101, ASSETS_TYPE_SAVINGS = 102, ASSETS_TYPE_CREDIT_CARD = 103, ASSETS_TYPE_LIABILITIES = 104, ASSETS_TYPE_SECURITIES = 105, ASSETS_TYPE_BALANCING = 106, ASSETS_TYPE_OTHER = 107 } AssetsType; class Account { protected: Budget *o_budget; qlonglong i_id; int i_first_revision, i_last_revision; QString s_name, s_description; public: Account(Budget *parent_budget, QString initial_name, QString initial_description); Account(Budget *parent_budget, QXmlStreamReader *xml, bool *valid); Account(Budget *parent_budget); Account(); Account(const Account *account); virtual ~Account(); virtual void set(const Account *account); virtual void readAttributes(QXmlStreamAttributes *attr, bool *valid); virtual bool readElement(QXmlStreamReader *xml, bool *valid); virtual bool readElements(QXmlStreamReader *xml, bool *valid); virtual void save(QXmlStreamWriter *xml); virtual void writeAttributes(QXmlStreamAttributes *attr); virtual void writeElements(QXmlStreamWriter *xml); const QString &name() const; virtual QString nameWithParent(bool formatted = true) const; virtual Account *topAccount(); void setName(QString new_name); const QString &description() const; void setDescription(QString new_description); virtual bool isClosed() const; Budget *budget() const; qlonglong id() const; void setId(qlonglong new_id); int firstRevision() const; void setFirstRevision(int new_rev); int lastRevision() const; void setLastRevision(int new_rev); virtual AccountType type() const = 0; virtual Currency *currency() const; }; class AssetsAccount : public Account { protected: int at_type; double d_initbal; bool b_closed; QString s_maintainer, s_group; Currency *o_currency; public: AssetsAccount(Budget *parent_budget, int initial_type, QString initial_name, double initial_balance = 0.0, QString initial_description = QString()); AssetsAccount(Budget *parent_budget, QXmlStreamReader *xml, bool *valid); AssetsAccount(Budget *parent_budget); AssetsAccount(); AssetsAccount(const AssetsAccount *account); virtual ~AssetsAccount(); virtual void set(const AssetsAccount *account); virtual void readAttributes(QXmlStreamAttributes *attr, bool *valid); virtual void writeAttributes(QXmlStreamAttributes *attr); bool isBudgetAccount() const; void setAsBudgetAccount(bool will_be = true); double initialBalance(bool calculate_for_securities = true) const; void setInitialBalance(double new_initial_balance); bool isClosed() const; void setClosed(bool close_account = true); const QString &maintainer() const; void setMaintainer(QString maintainer_name); AccountType type() const; void setAccountType(int new_type); int accountType() const; void setAccountTypeName(const QString &new_type, bool localized = false); QString accountTypeName(bool localized = false, bool plural = false) const; QString group() const; void setGroup(QString group_name); bool isCreditCard() const; bool isDebt() const; bool isLiabilities() const; bool isSecurities() const; bool isTypeOther() const; Currency *currency() const; void setCurrency(Currency *new_currency); }; bool account_list_less_than(Account *t1, Account *t2); template class AccountList : public EqonomizeList { public: AccountList() : EqonomizeList() {}; void sort() { std::sort(QList::begin(), QList::end(), account_list_less_than); } void inSort(type value) { QList::insert(std::lower_bound(QList::begin(), QList::end(), value, account_list_less_than), value); } }; class CategoryAccount : public Account { public: CategoryAccount(Budget *parent_budget, QString initial_name, QString initial_description = QString()); CategoryAccount(Budget *parent_budget, QXmlStreamReader *xml, bool *valid); CategoryAccount(Budget *parent_budget); CategoryAccount(); CategoryAccount(const CategoryAccount *account); virtual ~CategoryAccount(); virtual void set(const CategoryAccount *account); void setMergeBudgets(const CategoryAccount *account); void mergeBudgets(const CategoryAccount *account, bool keep = true); QMap mbudgets; virtual void readAttributes(QXmlStreamAttributes *attr, bool *valid); virtual bool readElement(QXmlStreamReader *xml, bool *valid); virtual void writeAttributes(QXmlStreamAttributes *attr); virtual void writeElements(QXmlStreamWriter *xml); double monthlyBudget(int year, int month, bool no_default = false) const; void setMonthlyBudget(int year, int month, double new_monthly_budget); double monthlyBudget(const QDate &date, bool no_default = false) const; void setMonthlyBudget(const QDate &date, double new_monthly_budget); QString nameWithParent(bool formatted = true) const; virtual Account *topAccount(); virtual AccountType type() const = 0; bool removeSubCategory(CategoryAccount *sub_account, bool set_parent = true); bool addSubCategory(CategoryAccount *sub_account, bool set_parent = true); CategoryAccount *parentCategory() const; bool setParentCategory(CategoryAccount *parent_account, bool add_child = true); AccountList subCategories; CategoryAccount *o_parent; }; class IncomesAccount : public CategoryAccount { public: IncomesAccount(Budget *parent_budget, QString initial_name, QString initial_description = QString()); IncomesAccount(Budget *parent_budget, QXmlStreamReader *xml, bool *valid); IncomesAccount(Budget *parent_budget); IncomesAccount(); IncomesAccount(const IncomesAccount *account); virtual ~IncomesAccount(); virtual AccountType type() const; }; class ExpensesAccount : public CategoryAccount { public: ExpensesAccount(Budget *parent_budget, QString initial_name, QString initial_description = QString()); ExpensesAccount(Budget *parent_budget, QXmlStreamReader *xml, bool *valid); ExpensesAccount(Budget *parent_budget); ExpensesAccount(); ExpensesAccount(const ExpensesAccount *account); virtual ~ExpensesAccount(); virtual AccountType type() const; }; #endif Eqonomize-1.5.3/src/accountcombobox.cpp000066400000000000000000000427601416454732000201650ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include "accountcombobox.h" #include "account.h" #include "budget.h" #include "editaccountdialogs.h" QComboBoxListViewEq::QComboBoxListViewEq(AccountComboBox *cmb) : combo(cmb) {} void QComboBoxListViewEq::keyPressEvent(QKeyEvent *e) { QString str = e->text().trimmed(); if((!str.isEmpty() && str[0].isPrint()) || (!filter_str.isEmpty() && (e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Delete))) { QSortFilterProxyModel *filterModel = (QSortFilterProxyModel*) model(); if(e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Delete) { filter_str.chop(1); #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) QRegularExpression reg(filter_str.isEmpty() ? "" : QString("\\b")+filter_str, QRegularExpression::CaseInsensitiveOption); filterModel->setFilterRegularExpression(reg); #else QRegExp reg(filter_str.isEmpty() ? "" : QString("\\b")+filter_str, Qt::CaseInsensitive); filterModel->setFilterRegExp(reg); #endif return; } #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) QRegularExpression reg(QString("\\b")+filter_str+str, QRegularExpression::CaseInsensitiveOption); filterModel->setFilterRegularExpression(reg); #else QRegExp reg(QString("\\b")+filter_str+str, Qt::CaseInsensitive); filterModel->setFilterRegExp(reg); #endif if(filterModel->rowCount() == 0) { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) filterModel->setFilterRegularExpression(filter_str.isEmpty() ? "" : QString("\\b")+filter_str); #else filterModel->setFilterRegExp(filter_str.isEmpty() ? "" : QString("\\b")+filter_str); #endif } else if(filterModel->rowCount() == 1 && filterModel->data(filterModel->index(0, 0), Qt::UserRole).value() != NULL) { combo->hidePopup(); } else { filter_str += str; } return; } QListView::keyPressEvent(e); } void QComboBoxListViewEq::resizeEvent(QResizeEvent *event) { resizeContents(viewport()->width(), contentsSize().height()); QListView::resizeEvent(event); } QStyleOptionViewItem QComboBoxListViewEq::viewOptions() const { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) QStyleOptionViewItem option; initViewItemOption(&option); #else QStyleOptionViewItem option = QListView::viewOptions(); #endif option.showDecorationSelected = true; if(combo) option.font = combo->font(); return option; } void QComboBoxListViewEq::paintEvent(QPaintEvent *e) { if (combo) { QStyleOptionComboBox opt; opt.initFrom(combo); opt.editable = combo->isEditable(); if(combo->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, combo)) { //we paint the empty menu area to avoid having blank space that can happen when scrolling QStyleOptionMenuItem menuOpt; menuOpt.initFrom(this); menuOpt.palette = palette(); menuOpt.state = QStyle::State_None; menuOpt.checkType = QStyleOptionMenuItem::NotCheckable; menuOpt.menuRect = e->rect(); menuOpt.maxIconWidth = 0; #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) menuOpt.tabWidth = 0; #endif QPainter p(viewport()); combo->style()->drawControl(QStyle::CE_MenuEmptyArea, &menuOpt, &p, this); } } QListView::paintEvent(e); } QComboBoxDelegateEq::QComboBoxDelegateEq(QObject *parent, QComboBox *cmb) : QStyledItemDelegate(parent), mCombo(cmb) {} bool QComboBoxDelegateEq::isSeparator(const QModelIndex &index) { return index.data(Qt::AccessibleDescriptionRole).toString() == QLatin1String("separator"); } void QComboBoxDelegateEq::setSeparator(QAbstractItemModel *model, const QModelIndex &index) { model->setData(index, QString::fromLatin1("separator"), Qt::AccessibleDescriptionRole); if (QStandardItemModel *m = qobject_cast(model)) if (QStandardItem *item = m->itemFromIndex(index)) item->setFlags(item->flags() & ~(Qt::ItemIsSelectable|Qt::ItemIsEnabled)); } void QComboBoxDelegateEq::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { if (isSeparator(index)) { QRect rect = option.rect; if (const QAbstractItemView *view = qobject_cast(option.widget)) rect.setWidth(view->viewport()->width()); QStyleOption opt; opt.rect = rect; mCombo->style()->drawPrimitive(QStyle::PE_IndicatorToolBarSeparator, &opt, painter, mCombo); } else { QStyledItemDelegate::paint(painter, option, index); } } QSize QComboBoxDelegateEq::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { if (isSeparator(index)) { int pm = mCombo->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, NULL, mCombo); return QSize(pm, pm); } return QStyledItemDelegate::sizeHint(option, index); } AccountComboBox::AccountComboBox(int account_type, Budget *budg, bool add_new_account_action, bool add_new_loan_action, bool add_multiple_accounts_action, bool exclude_securities_accounts, bool exclude_balancing_account, QWidget *parent) : QComboBox(parent), i_type(account_type), budget(budg), new_account_action(add_new_account_action), new_loan_action(add_new_loan_action && i_type == ACCOUNT_TYPE_ASSETS), multiple_accounts_action(add_multiple_accounts_action && i_type == ACCOUNT_TYPE_ASSETS), b_exclude_securities(exclude_securities_accounts), b_exclude_balancing(exclude_balancing_account) { setEditable(false); added_account = NULL; block_account_selected = false; sourceModel = new QStandardItemModel(this); filterModel = new QSortFilterProxyModel(this); filterModel->setSourceModel(sourceModel); QListView *listView = new QComboBoxListViewEq(this); listView->setTextElideMode(Qt::ElideMiddle); setView(listView); setItemDelegate(new QComboBoxDelegateEq(listView, this)); setModel(filterModel); connect(this, SIGNAL(activated(int)), this, SLOT(accountActivated(int))); connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(onCurrentIndexChanged(int))); } AccountComboBox::~AccountComboBox() {} void AccountComboBox::hidePopup() { QComboBox::hidePopup(); #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) filterModel->setFilterRegularExpression(""); #else filterModel->setFilterRegExp(""); #endif ((QComboBoxListViewEq*) view())->filter_str = ""; if(!currentAccount()) setCurrentIndex(firstAccountIndex() < count() ? firstAccountIndex() : -1); } int AccountComboBox::firstAccountIndex() const { int index = 0; if(new_account_action) index++; if(new_loan_action) index++; if(multiple_accounts_action) index++; if(index > 0) index++; return index; } Account *AccountComboBox::currentAccount() const { if(!currentData().isValid()) return NULL; return (Account*) currentData().value(); } void AccountComboBox::setCurrentAccount(Account *account) { if(account) { int index = findData(QVariant::fromValue((void*) account)); if(index >= 0) setCurrentIndex(index); } } int AccountComboBox::currentAccountIndex() const { int index = currentIndex() - firstAccountIndex(); if(index < 0) return -1; return index; } void AccountComboBox::setCurrentAccountIndex(int index) { index += firstAccountIndex(); if(index < count()) setCurrentIndex(index); } #define APPEND_ACTION_ROW(s) {QStandardItem *row = new QStandardItem(s);\ row->setData(QVariant::fromValue(NULL), Qt::UserRole);\ sourceModel->appendRow(row);} #define APPEND_ROW {QStandardItem *row = new QStandardItem(account->nameWithParent());\ row->setData(QVariant::fromValue((void*) account), Qt::UserRole);\ sourceModel->appendRow(row);} #define APPEND_SEPARATOR {QStandardItem *row = new QStandardItem();\ row->setData(QVariant::fromValue(NULL), Qt::UserRole);\ row->setData(QString::fromLatin1("separator"), Qt::AccessibleDescriptionRole);\ row->setFlags(Qt::NoItemFlags);\ sourceModel->appendRow(row);} void AccountComboBox::updateAccounts(Account *exclude_account, Currency *force_currency) { Account *current_account = currentAccount(); sourceModel->clear(); switch(i_type) { case ACCOUNT_TYPE_INCOMES: { if(new_account_action) { APPEND_ACTION_ROW(tr("New income category…")); } for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) { IncomesAccount *account = *it; if(account != exclude_account) { if(new_account_action && count() == 1) APPEND_SEPARATOR APPEND_ROW } } if(current_account) setCurrentAccount(current_account); if(currentIndex() < firstAccountIndex()) { if(firstAccountIndex() < count()) setCurrentIndex(firstAccountIndex()); else setCurrentIndex(-1); } break; } case ACCOUNT_TYPE_EXPENSES: { if(new_account_action) { APPEND_ACTION_ROW(tr("New expense category…")) } for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) { ExpensesAccount *account = *it; if(account != exclude_account) { if(new_account_action && count() == 1) APPEND_SEPARATOR APPEND_ROW } } if(current_account) setCurrentAccount(current_account); if(currentIndex() < firstAccountIndex()) { if(firstAccountIndex() < count()) setCurrentIndex(firstAccountIndex()); else setCurrentIndex(-1); } break; } default: { if(new_account_action) APPEND_ACTION_ROW(tr("New account…")); if(new_loan_action) APPEND_ACTION_ROW(tr("Paid with loan…")); if(multiple_accounts_action) APPEND_ACTION_ROW(tr("Multiple accounts/payments…")); int cactions = count(); bool add_secondary_list = false; for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { AssetsAccount *account = *it; if(account != exclude_account && (!force_currency || account->currency() == force_currency)) { bool b_add = false; if(i_type >= 100) { if(account->accountType() == i_type) { if(account->isClosed()) add_secondary_list = true; else b_add = true; } } else if(i_type == -3) { if(account->accountType() == ASSETS_TYPE_CREDIT_CARD || account->accountType() == ASSETS_TYPE_LIABILITIES) { if(account->isClosed()) add_secondary_list = true; else b_add = true; } } else if((account->accountType() == ASSETS_TYPE_SECURITIES && !b_exclude_securities) || account->accountType() == ASSETS_TYPE_LIABILITIES || (account == budget->balancingAccount && !b_exclude_balancing) || account->isClosed()) { add_secondary_list = true; } else if(account->accountType() != ASSETS_TYPE_SECURITIES && account != budget->balancingAccount) { b_add = true; } if(b_add) { if(cactions > 0 && count() == cactions) APPEND_SEPARATOR APPEND_ROW } } } if(i_type == -1) { if(count() > 0 && count() >= cactions) APPEND_SEPARATOR for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) { IncomesAccount *account = *it; if(account != exclude_account) { APPEND_ROW } } } if(i_type == -2) { if(count() > 0 && count() >= cactions) APPEND_SEPARATOR for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) { ExpensesAccount *account = *it; if(account != exclude_account) { APPEND_ROW } } } if(add_secondary_list) { if(count() > 0 && count() >= cactions) APPEND_SEPARATOR for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { bool b_add = false; AssetsAccount *account = *it; if(i_type >= 100) { if(account->accountType() == i_type && account->isClosed()) { b_add = true; } } else if(i_type == -3) { if((account->accountType() == ASSETS_TYPE_CREDIT_CARD || account->accountType() == ASSETS_TYPE_LIABILITIES) && account->isClosed()) { b_add = true; } } else if((account->accountType() == ASSETS_TYPE_SECURITIES && !b_exclude_securities) || account->accountType() == ASSETS_TYPE_LIABILITIES || (account == budget->balancingAccount && !b_exclude_balancing) || account->isClosed()) { b_add = true; } if(b_add) { APPEND_ROW } } } if(current_account) setCurrentAccount(current_account); if(currentIndex() < firstAccountIndex()) { if(firstAccountIndex() < count()) setCurrentIndex(firstAccountIndex()); else setCurrentIndex(-1); } break; } } } bool AccountComboBox::hasAccount() const { return count() > firstAccountIndex(); } Account *AccountComboBox::createAccount() { Account *account = NULL; switch(i_type) { case ACCOUNT_TYPE_INCOMES: { EditIncomesAccountDialog *dialog = new EditIncomesAccountDialog(budget, NULL, this, tr("New Income Category")); if(dialog->exec() == QDialog::Accepted) { account = dialog->newAccount(); } dialog->deleteLater(); break; } case ACCOUNT_TYPE_EXPENSES: { EditExpensesAccountDialog *dialog = new EditExpensesAccountDialog(budget, NULL, this, tr("New Expense Category")); if(dialog->exec() == QDialog::Accepted) { account = dialog->newAccount(); } dialog->deleteLater(); break; } default: { EditAssetsAccountDialog *dialog = new EditAssetsAccountDialog(budget, this, tr("New Account"), false, i_type == -3 ? ASSETS_TYPE_LIABILITIES : (i_type >= 100 ? i_type : -1), i_type >= 100); if(dialog->exec() == QDialog::Accepted) { account = dialog->newAccount(); } dialog->deleteLater(); break; } } if(account) { budget->addAccount(account); updateAccounts(); setCurrentAccount(account); emit accountSelected(account); } return account; } void AccountComboBox::accountActivated(int index) { if(!itemData(index).isValid() || itemData(index).value() == NULL) { if(new_account_action && index == 0) { setCurrentIndex(firstAccountIndex()); emit newAccountRequested(); return; } else if(new_loan_action && ((index == 1 && new_account_action) || (index == 0 && !new_account_action))) { setCurrentIndex(firstAccountIndex()); emit newLoanRequested(); return; } else if(multiple_accounts_action && ((index == 2 && new_account_action && new_loan_action) || (index == 1 && !(new_account_action) != !(new_loan_action)) || (index == 0 && !new_account_action && !new_loan_action))) { setCurrentIndex(firstAccountIndex()); emit multipleAccountsRequested(); return; } } if(!block_account_selected) { Account *account = NULL; if(itemData(index).isValid()) account = (Account*) itemData(index).value(); emit accountSelected(account); } } void AccountComboBox::onCurrentIndexChanged(int index) { Account *account = NULL; if(itemData(index).isValid()) account = (Account*) itemData(index).value(); emit currentAccountChanged(account); } void AccountComboBox::keyPressEvent(QKeyEvent *e) { block_account_selected = true; QString str = e->text().trimmed(); if(!str.isEmpty()) { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) QRegularExpression reg(QString("\\b")+str, QRegularExpression::CaseInsensitiveOption); #else QRegExp reg(QString("\\b")+str, Qt::CaseInsensitive); #endif Account *account = currentAccount(); #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) filterModel->setFilterRegularExpression(reg); #else filterModel->setFilterRegExp(reg); #endif if(filterModel->rowCount() == 0) { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) filterModel->setFilterRegularExpression(""); #else filterModel->setFilterRegExp(""); #endif setCurrentAccount(account); } else if(filterModel->rowCount() == 1 && filterModel->data(filterModel->index(0, 0), Qt::UserRole).value() != NULL) { account = (Account*) filterModel->data(filterModel->index(0, 0), Qt::UserRole).value(); #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) filterModel->setFilterRegularExpression(""); #else filterModel->setFilterRegExp(""); #endif setCurrentAccount(account); } else { ((QComboBoxListViewEq*) view())->filter_str = str; showPopup(); } return; } QComboBox::keyPressEvent(e); block_account_selected = false; if(!e->isAccepted() && (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return)) emit returnPressed(); } void AccountComboBox::focusAndSelectAll() { setFocus(); } Eqonomize-1.5.3/src/accountcombobox.h000066400000000000000000000075641416454732000176350ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifndef ACCOUNT_COMBO_BOX_H #define ACCOUNT_COMBO_BOX_H #include #include #include class Account; class Budget; class Currency; class QSortFilterProxyModel; class QStandardItemModel; class AccountComboBox : public QComboBox { Q_OBJECT protected: int firstAccountIndex() const; int i_type; Budget *budget; bool new_account_action, new_loan_action, multiple_accounts_action; bool b_exclude_securities, b_exclude_balancing; bool block_account_selected; Account *added_account, *exclude_account; QSortFilterProxyModel *filterModel; QStandardItemModel *sourceModel; void keyPressEvent(QKeyEvent *e); public: AccountComboBox(int account_type, Budget *budg, bool add_new_account_action = false, bool add_new_loan_action = false, bool add_multiple_accounts_action = false, bool exclude_securities_accounts = true, bool exclude_balancing_account = true, QWidget *parent = NULL); ~AccountComboBox(); Account *currentAccount() const; void setCurrentAccount(Account *account); int currentAccountIndex() const; void setCurrentAccountIndex(int index); void updateAccounts(Account *exclude_account = NULL, Currency *force_currency = NULL); bool hasAccount() const; Account *createAccount(); void hidePopup(); signals: void newLoanRequested(); void newAccountRequested(); void multipleAccountsRequested(); void accountSelected(Account*); void currentAccountChanged(Account*); void returnPressed(); public slots: void focusAndSelectAll(); protected slots: void accountActivated(int); void onCurrentIndexChanged(int); }; class QComboBoxListViewEq : public QListView { Q_OBJECT public: QComboBoxListViewEq(AccountComboBox *cmb = NULL); QString filter_str; protected: void resizeEvent(QResizeEvent *event); QStyleOptionViewItem viewOptions() const; void paintEvent(QPaintEvent *e); void keyPressEvent(QKeyEvent *e); private: AccountComboBox *combo; }; class QComboBoxDelegateEq : public QStyledItemDelegate { Q_OBJECT public: QComboBoxDelegateEq(QObject *parent, QComboBox *cmb); static void setSeparator(QAbstractItemModel *model, const QModelIndex &index); static bool isSeparator(const QModelIndex &index); protected: void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; private: QComboBox *mCombo; }; #endif Eqonomize-1.5.3/src/budget.cpp000066400000000000000000004260671416454732000162600ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016-2020 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include "budget.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "recurrence.h" void read_id(QXmlStreamAttributes *attr, qlonglong &id, int &rev1, int &rev2) { id = attr->value("id").toLongLong(); #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) QStringView rev = attr->value("revisions"); #else QStringRef rev = attr->value("revisions"); #endif if(rev.contains(':')) { #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) QVector rev_strs = rev.split(':'); #else QVector rev_strs = rev.split(':'); #endif if(rev_strs.isEmpty()) { rev1 = rev.toInt(); } else if(rev_strs.size() == 1) { rev1 = rev_strs[0].toInt(); } else { rev1 = rev_strs[0].toInt(); rev2 = rev_strs.last().toInt(); } } else { rev1 = rev.toInt(); rev2 = rev1; } if(rev1 <= 0) rev1 = 1; if(rev2 <= rev1) rev2 = rev1; } void write_id(QXmlStreamAttributes *attr, qlonglong &id, int &rev1, int &rev2) { attr->append("id", QString::number(id)); if(rev2 == rev1) attr->append("revisions", QString::number(rev1)); else attr->append("revisions", QString::number(rev1) + ':' + QString::number(rev2)); } void write_id(QXmlStreamWriter *writer, qlonglong &id, int &rev1, int &rev2) { writer->writeAttribute("id", QString::number(id)); if(rev2 == rev1) writer->writeAttribute("revisions", QString::number(rev1)); else writer->writeAttribute("revisions", QString::number(rev1) + ':' + QString::number(rev2)); } int compare_id(const int &id1, const int &id2) { if(id1 < 0) { if(id2 < 0) { if(id1 > id2) return -1; if(id1 < id2) return 1; } else { return 1; } } else if(id2 < 0) { return -1; } else { if(id1 < id2) return -1; if(id1 > id2) return 1; } return 0; } bool transactions_less_than_stamp(Transactions *t1, Transactions *t2) { if(t1->timestamp() == 0 && t2->timestamp() == 0) return t1->date() < t2->date() || (t1->date() == t2->date() && t2->description().localeAwareCompare(t1->description()) < 0); return t1->timestamp() < t2->timestamp() || (t1->timestamp() == t2->timestamp() && t2->description().localeAwareCompare(t1->description()) < 0); } bool transactions_less_than_trade_stamp(Transactions *t1, SecurityTrade *t2) { return t1->timestamp() < t2->timestamp || (t1->timestamp() == t2->timestamp && t1->date() < t2->date); } bool transaction_list_less_than_stamp(Transaction *t1, Transaction *t2) { if(t1->timestamp() < t2->timestamp()) return true; if(t1->timestamp() > t2->timestamp()) return false; if(t1->timestamp() == 0) { if(t1->date() < t2->date()) return true; if(t1->date() > t2->date()) return false; } if(t1->parentSplit()) { if(!t2->parentSplit()) { return t2->description().localeAwareCompare(t1->parentSplit()->description()) < 0; } else if(t1->parentSplit() != t2->parentSplit()) { if(t1->parentSplit()->timestamp() != t2->parentSplit()->timestamp()) return t1->parentSplit()->timestamp() < t2->parentSplit()->timestamp(); int r = t2->parentSplit()->description().localeAwareCompare(t1->parentSplit()->description()); if(r == 0) return (void*) t1->parentSplit() < (void*) t2->parentSplit(); else return r < 0; } } else if(t2->parentSplit()) { return t2->parentSplit()->description().localeAwareCompare(t1->description()) < 0; } return t2->description().localeAwareCompare(t1->description()) < 0; } bool transaction_list_less_than(Transaction *t1, Transaction *t2) { if(t1->date() < t2->date()) return true; if(t1->date() > t2->date()) return false; if(t1->timestamp() < t2->timestamp()) return true; if(t1->timestamp() > t2->timestamp()) return false; if(t1->parentSplit()) { if(!t2->parentSplit()) { return t2->description().localeAwareCompare(t1->parentSplit()->description()) < 0; } else if(t1->parentSplit() != t2->parentSplit()) { if(t1->parentSplit()->timestamp() != t2->parentSplit()->timestamp()) return t1->parentSplit()->timestamp() < t2->parentSplit()->timestamp(); int r = t2->parentSplit()->description().localeAwareCompare(t1->parentSplit()->description()); if(r == 0) return (void*) t1->parentSplit() < (void*) t2->parentSplit(); else return r < 0; } } else if(t2->parentSplit()) { return t2->parentSplit()->description().localeAwareCompare(t1->description()) < 0; } return t2->description().localeAwareCompare(t1->description()) < 0; } bool split_list_less_than_stamp(SplitTransaction *t1, SplitTransaction *t2) { if(t1->timestamp() == 0 && t2->timestamp() == 0) return split_list_less_than(t1, t2); return t1->timestamp() < t2->timestamp() || (t1->timestamp() == t2->timestamp() && t2->description().localeAwareCompare(t1->description()) < 0); } bool split_list_less_than(SplitTransaction *t1, SplitTransaction *t2) { return t1->date() < t2->date() || (t1->date() == t2->date() && (t1->timestamp() < t2->timestamp() || (t1->timestamp() == t2->timestamp() && t2->description().localeAwareCompare(t1->description()) < 0))); } bool schedule_list_less_than_stamp(ScheduledTransaction *t1, ScheduledTransaction *t2) { if(t1->timestamp() == 0 && t2->timestamp() == 0) return schedule_list_less_than(t1, t2); return t1->timestamp() < t2->timestamp() || (t1->timestamp() == t2->timestamp() && t2->description().localeAwareCompare(t1->description()) < 0); } bool schedule_list_less_than(ScheduledTransaction *t1, ScheduledTransaction *t2) { return t1->date() < t2->date() || (t1->date() == t2->date() && (t1->timestamp() < t2->timestamp() || (t1->timestamp() == t2->timestamp() && t2->description().localeAwareCompare(t1->description()) < 0))); } bool trade_list_less_than_stamp(SecurityTrade *t1, SecurityTrade *t2) { return t1->timestamp < t2->timestamp || (t1->timestamp == t2->timestamp && t1->date < t2->date); } bool trade_list_less_than(SecurityTrade *t1, SecurityTrade *t2) { return t1->date < t2->date || (t1->date == t2->date && t1->timestamp < t2->timestamp); } bool security_list_less_than(Security *t1, Security *t2) { return QString::localeAwareCompare(t1->name(), t2->name()) < 0; } bool is_zero(double value) { return value < 0.0000001 && value > -0.0000001; } Budget::Budget() { currencies.setAutoDelete(true); expenses.setAutoDelete(true); incomes.setAutoDelete(true); transfers.setAutoDelete(true); securityTransactions.setAutoDelete(true); transactions.setAutoDelete(false); scheduledTransactions.setAutoDelete(true); splitTransactions.setAutoDelete(true); securities.setAutoDelete(true); expensesAccounts.setAutoDelete(true); incomesAccounts.setAutoDelete(true); assetsAccounts.setAutoDelete(true); securityTrades.setAutoDelete(true); accounts.setAutoDelete(false); o_sync = new BudgetSynchronization(); o_sync->clear(); currency_euro = new Currency(this, "EUR", "€", tr("European Euro"), 1.0); currency_euro->setAsLocal(false); addCurrency(currency_euro); loadCurrencies(); default_currency = currency_euro; last_id = 0; balancingAccount = new AssetsAccount(this, ASSETS_TYPE_BALANCING, tr("Balancing", "Name of account for transactions that adjust account balances"), 0.0); balancingAccount->setCurrency(NULL); balancingAccount->setId(0); assetsAccounts.append(balancingAccount); accounts.append(balancingAccount); budgetAccount = NULL; i_share_decimals = 4; i_quotation_decimals = 4; i_budget_day = 1; i_budget_month = 1; i_revision = 1; i_opened_revision = 0; last_id = 0; b_record_new_tags = false; b_record_new_accounts = false; b_record_new_securities = false; i_tcrd = TRANSACTION_CONVERSION_RATE_AT_DATE; null_incomes_account = new IncomesAccount(this, QString()); struct lconv *lc = localeconv(); monetary_decimal_separator = QString::fromLocal8Bit(lc->mon_decimal_point); if(monetary_decimal_separator.isEmpty()) monetary_decimal_separator = QLocale().decimalPoint(); monetary_group_separator = QString::fromLocal8Bit(lc->mon_thousands_sep); monetary_negative_sign = QString::fromLocal8Bit(lc->negative_sign); monetary_positive_sign = QString::fromLocal8Bit(lc->positive_sign); if(monetary_negative_sign == "-" && QLocale().negativeSign() == QChar(0x2212)) monetary_negative_sign = QLocale().negativeSign(); monetary_group_format = lc->mon_grouping; monetary_decimal_places = 2; decimal_separator = QString::fromLocal8Bit(lc->decimal_point); if(decimal_separator.isEmpty()) decimal_separator = QLocale().decimalPoint(); group_separator = QString::fromLocal8Bit(lc->thousands_sep); negative_sign = QString::fromLocal8Bit(lc->negative_sign); positive_sign = QString::fromLocal8Bit(lc->positive_sign); if(negative_sign == "-" && QLocale().negativeSign() == QChar(0x2212)) negative_sign = QLocale().negativeSign(); group_format = lc->grouping; #ifdef Q_OS_ANDROID currency_symbol_precedes = true; currency_code_precedes = true; currency_symbol_precedes_neg = true; currency_code_precedes_neg = true; currency_symbol_space = false; currency_code_space = true; currency_symbol_space_neg = false; currency_code_space_neg = true; monetary_sign_p_symbol_neg = 1; monetary_sign_p_symbol_pos = 1; monetary_sign_p_code_neg = 1; monetary_sign_p_code_pos = 1; #else currency_symbol_precedes = lc->p_cs_precedes; currency_symbol_precedes_neg = lc->n_cs_precedes; currency_symbol_space = (lc->p_sep_by_space == 1); currency_symbol_space_neg = (lc->n_sep_by_space == 1); monetary_sign_p_symbol_neg = (int) lc->n_sign_posn; monetary_sign_p_symbol_pos = (int) lc->p_sign_posn; # ifdef _WIN32 currency_code_precedes = currency_symbol_precedes; currency_code_precedes_neg = currency_symbol_precedes; currency_code_space = true; currency_code_space_neg = true; monetary_sign_p_code_neg = monetary_sign_p_symbol_neg; monetary_sign_p_code_pos = monetary_sign_p_symbol_pos; # else currency_code_precedes = lc->int_p_cs_precedes; currency_code_precedes_neg = lc->int_n_cs_precedes; currency_code_space = (lc->int_p_sep_by_space == 1); currency_code_space_neg = (lc->int_n_sep_by_space == 1); monetary_sign_p_code_neg = (int) lc->int_n_sign_posn; monetary_sign_p_code_pos = (int) lc->int_p_sign_posn; #endif if(monetary_sign_p_symbol_neg > 4) monetary_sign_p_symbol_neg = 1; if(monetary_sign_p_symbol_pos > 4) monetary_sign_p_symbol_pos = 1; if(monetary_sign_p_code_neg > 4) monetary_sign_p_code_neg = 1; if(monetary_sign_p_code_pos > 4) monetary_sign_p_code_pos = 1; /*monetary_decimal_places = (int) lc->frac_digits; if(monetary_decimal_places < 0 || monetary_decimal_places > 20) monetary_decimal_places = 2;*/ #endif monetary_group_format = monetary_group_format.trimmed(); if(monetary_decimal_separator.isEmpty()) monetary_decimal_separator = QLocale().decimalPoint(); if(monetary_group_separator.isEmpty()) monetary_group_separator = QLocale().groupSeparator(); } Budget::~Budget() {} qlonglong Budget::getNewId() { last_id++; return last_id; } int Budget::revision() {return i_revision;} void Budget::clear() { i_revision = 1; i_opened_revision = 0; last_id = 0; transactions.clear(); scheduledTransactions.clear(); splitTransactions.clear(); securities.clear(); expenses.clear(); incomes.clear(); transfers.clear(); securityTransactions.clear(); securities.clear(); accounts.clear(); securityTrades.clear(); o_sync->clear(); assetsAccounts.setAutoDelete(false); assetsAccounts.removeRef(balancingAccount); assetsAccounts.setAutoDelete(true); for(AccountList::const_iterator it = incomesAccounts.constBegin(); it != incomesAccounts.constEnd(); ++it) { CategoryAccount *ca = *it; if(ca->parentCategory()) ca->o_parent = NULL; ca->subCategories.clear(); } for(AccountList::const_iterator it = expensesAccounts.constBegin(); it != expensesAccounts.constEnd(); ++it) { CategoryAccount *ca = *it; if(ca->parentCategory()) ca->o_parent = NULL; ca->subCategories.clear(); } incomesAccounts.clear(); expensesAccounts.clear(); assetsAccounts.clear(); tags.clear(); assetsAccounts.append(balancingAccount); accounts.append(balancingAccount); budgetAccount = NULL; } QString Budget::formatMoney(double v, int precision, bool show_currency) { return default_currency->formatValue(v, precision, show_currency); } QString Budget::formatValue(double value, int nr_of_decimals, bool always_show_sign) { if(is_zero(value)) value = 0.0; QString s; bool neg = false; if(value == 0.0) { s = "0"; if(nr_of_decimals > 0) { s += decimal_separator; while(nr_of_decimals > 0) { s += '0'; nr_of_decimals--; } } } else { neg = value < 0; s = QString::number(neg ? -value : value, 'f', nr_of_decimals); int i = s.indexOf('.'); if(decimal_separator != ".") s.replace(i, 1, decimal_separator); if(!group_separator.isEmpty() && !group_format.isEmpty()) { int group_size = 3, i_format = 0; if(group_format.length() > i_format) { group_size = group_format[i_format]; } while(i > group_size) { i -= group_size; s.insert(i, group_separator); if(group_format.length() > i_format) { i_format++; if(group_format[i_format] == (char) CHAR_MAX) break; if(group_format[i_format] > (char) 0) group_size = group_format[i_format]; } } } } if(always_show_sign && value == 0.0) { s.insert(0, "±"); } else if(neg) { if(!negative_sign.isEmpty()) s.insert(0, negative_sign); else s.insert(0, QLocale().negativeSign()); } else { if(!positive_sign.isEmpty()) s.insert(0, positive_sign); else if(always_show_sign) s.insert(0, QLocale().positiveSign()); } return s; } QString Budget::formatValue(int value, int nr_of_decimals, bool always_show_sign) { QString s; bool neg = false; if(value == 0) { s = "0"; if(nr_of_decimals > 0) { s += decimal_separator; while(nr_of_decimals > 0) { s += '0'; nr_of_decimals--; } } } else { neg = value < 0; s = QString::number(neg ? -value : value); if(!group_separator.isEmpty() && !group_format.isEmpty()) { int group_size = 3, i_format = 0; if(group_format.length() > i_format) { group_size = group_format[i_format]; } int i = s.length(); while(i > group_size) { i -= group_size; s.insert(i, group_separator); if(group_format.length() > i_format) { i_format++; if(group_format[i_format] == (char) CHAR_MAX) break; if(group_format[i_format] > (char) 0) group_size = group_format[i_format]; } } } if(nr_of_decimals > 0) { s += decimal_separator; while(nr_of_decimals > 0) { s += '0'; nr_of_decimals--; } } } QString sgn; if(always_show_sign && value == 0.0) { sgn = "±"; } else if(neg) { if(!negative_sign.isEmpty()) sgn = negative_sign; else sgn = QLocale().negativeSign(); } else { if(!positive_sign.isEmpty()) sgn = positive_sign; else if(always_show_sign) sgn = QLocale().positiveSign(); } s.insert(0, sgn); return s; } void Budget::loadCurrencies() { loadGlobalCurrencies(); loadLocalCurrencies(); } void Budget::loadGlobalCurrencies() { loadCurrenciesFile(DATA_DIR "/currencies.xml", false); } void Budget::loadLocalCurrencies() { loadCurrenciesFile(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/currencies.xml", true); } void Budget::loadCurrenciesFile(QString filename, bool is_local) { QFile file(filename); if(is_local && !file.exists()) { QString error = saveCurrencies(); if(!error.isNull()) qCritical() << error; return; } if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) { qCritical() << tr("Couldn't open %1 for reading").arg(filename); return; } else if(!file.size()) { return; } QXmlStreamReader xml(&file); if(!xml.readNextStartElement()) { qCritical() << tr("XML parse error: \"%1\" at line %2, col %3").arg(xml.errorString()).arg(xml.lineNumber()).arg(xml.columnNumber()); return; } if(xml.name() != XML_COMPARE_CONST_CHAR("Eqonomize")) { qCritical() << tr("Invalid root element %1 in XML document").arg(xml.name().toString()); return; } bool oldversion = (xml.attributes().value("version").toString() != QString(VERSION)); int currency_errors = 0; while(xml.readNextStartElement()) { if(xml.name() == XML_COMPARE_CONST_CHAR("currency")) { bool valid = true; Currency *currency = new Currency(this, &xml, &valid); if(valid) { if(is_local) { Currency *currency_old = findCurrency(currency->code()); if(currency_old) { currency_old->merge(currency, false); delete currency; } else { currency->setAsLocal(); currencies.append(currency); } } else { currencies.append(currency); } } else { currency_errors++; delete currency; } } else { qCritical() << tr("Unknown XML element: \"%1\" at line %2, col %3").arg(xml.name().toString()).arg(xml.lineNumber()).arg(xml.columnNumber()); xml.skipCurrentElement(); } } if(currency_errors > 0) { qCritical() << tr("Unable to load %n currency/currencies.", "", currency_errors); } currencies.sort(); if(xml.hasError()) { qCritical() << tr("XML parse error: \"%1\" at line %2, col %3").arg(xml.errorString()).arg(xml.lineNumber()).arg(xml.columnNumber()); } file.close(); if(oldversion && is_local) { QString error = saveCurrencies(); if(!error.isNull()) qCritical() << error; } } QString Budget::loadECBData(QByteArray data) { QXmlStreamReader xml(data); if(!xml.readNextStartElement()) { return tr("XML parse error: \"%1\" at line %2, col %3").arg(xml.errorString()).arg(xml.lineNumber()).arg(xml.columnNumber()); } bool had_data = false; while(xml.readNextStartElement()) { if(xml.name() == XML_COMPARE_CONST_CHAR("Cube")) { while(xml.readNextStartElement()) { if(xml.name() == XML_COMPARE_CONST_CHAR("Cube")) { QXmlStreamAttributes attr = xml.attributes(); QDate date = QDate::fromString(attr.value("time").trimmed().toString(), Qt::ISODate); while(xml.readNextStartElement()) { if(xml.name() == XML_COMPARE_CONST_CHAR("Cube")) { attr = xml.attributes(); QString code = attr.value("currency").trimmed().toString(); double exrate = attr.value("rate").toDouble(); if(!code.isEmpty() && code != "EUR" && exrate > 0.0 && date.isValid()) { if(!had_data) { for(CurrencyList::const_iterator it = currencies.constBegin(); it != currencies.constEnd(); ++it) { Currency *cur = *it; if(cur->exchangeRateSource() == EXCHANGE_RATE_SOURCE_ECB) { cur->setExchangeRateSource(EXCHANGE_RATE_SOURCE_NONE); } } } Currency *cur = findCurrency(code); if(cur) { bool keep_old = cur->rates.size() > 1; if(!keep_old) { for(AccountList::const_iterator it = assetsAccounts.constBegin(); it != assetsAccounts.constEnd(); ++it) { if((*it)->currency() == cur) {keep_old = true; break;} } } if(!keep_old) cur->rates.clear(); cur->setExchangeRate(exrate, date); } else { cur = new Currency(this, code, QString(), QString(), exrate, date); addCurrency(cur); } cur->setExchangeRateSource(EXCHANGE_RATE_SOURCE_ECB); had_data = true; } } xml.skipCurrentElement(); } } xml.skipCurrentElement(); } } xml.skipCurrentElement(); } if(!had_data) return tr("No exchange rates found."); return QString(); } QString Budget::loadMyCurrencyNetData(QByteArray data) { QJsonDocument jdoc = QJsonDocument::fromJson(data); if(!jdoc.isArray()) return tr("No exchange rates found."); QJsonArray jarr = jdoc.array(); bool had_data = false; for(int i = 0; i < jarr.count(); i++) { if(jarr[i].isObject()) { QJsonObject jobj = jarr[i].toObject(); QString code = jobj["currency_code"].toString().trimmed(); double exrate = jobj["rate"].toDouble(); QString name = jobj["name"].toString().trimmed(); if(!code.isEmpty() && code != "EUR" && exrate > 0.0) { if(!had_data) { for(CurrencyList::const_iterator it = currencies.constBegin(); it != currencies.constEnd(); ++it) { Currency *cur = *it; if(cur->exchangeRateSource() == EXCHANGE_RATE_SOURCE_MYCURRENCY_NET) { cur->setExchangeRateSource(EXCHANGE_RATE_SOURCE_NONE); } } } Currency *cur = findCurrency(code); if(cur && cur->exchangeRateSource() != EXCHANGE_RATE_SOURCE_ECB) { bool keep_old = cur->rates.size() > 1; if(!keep_old) { for(AccountList::const_iterator it = assetsAccounts.constBegin(); it != assetsAccounts.constEnd(); ++it) { if((*it)->currency() == cur) {keep_old = true; break;} } } if(!keep_old) cur->rates.clear(); cur->setExchangeRate(exrate); cur->setExchangeRateSource(EXCHANGE_RATE_SOURCE_MYCURRENCY_NET); } else if(!cur) { cur = new Currency(this, code, QString(), name, exrate); cur->setExchangeRateSource(EXCHANGE_RATE_SOURCE_MYCURRENCY_NET); addCurrency(cur); } had_data = true; } } } if(!had_data) return tr("No exchange rates found."); return QString(); } QString Budget::loadMyCurrencyNetHtml(QByteArray data) { Currency *cur_usd = findCurrency("USD"); if(!cur_usd) return tr("USD currency missing."); double usd_rate = cur_usd->exchangeRate(); bool had_data = false; int i = data.indexOf("class=\'country\'"); while(i >= 0) { QString code, name; double exrate = 0.0; i += 15; int i2 = data.indexOf("data-currency-code=\"", i); if(i2 >= 0) { i2 += 19; int i3 = data.indexOf("\"", i2 + 1); if(i3 >= 0) { code = data.mid(i2 + 1, i3 - (i2 + 1)); } } i2 = data.indexOf("data-currency-name=\'", i); if(i2 >= 0) { i2 += 19; int i3 = data.indexOf("|", i2 + 1); if(i3 >= 0) { name = data.mid(i2 + 1, i3 - (i2 + 1)).trimmed(); } } i2 = data.indexOf("data-rate=\'", i); if(i2 >= 0) { i2 += 10; int i3 = data.indexOf("'", i2 + 1); if(i3 >= 0) { exrate = data.mid(i2 + 1, i3 - (i2 + 1)).toDouble(); } } if(!code.isEmpty() && code != "EUR" && exrate > 0.0) { if(!had_data) { for(CurrencyList::const_iterator it = currencies.constBegin(); it != currencies.constEnd(); ++it) { Currency *cur = *it; if(cur->exchangeRateSource() == EXCHANGE_RATE_SOURCE_MYCURRENCY_NET) { cur->setExchangeRateSource(EXCHANGE_RATE_SOURCE_NONE); } } } Currency *cur = findCurrency(code); if(cur && cur->exchangeRateSource() != EXCHANGE_RATE_SOURCE_ECB) { bool keep_old = cur->rates.size() > 1; if(!keep_old) { for(AccountList::const_iterator it = assetsAccounts.constBegin(); it != assetsAccounts.constEnd(); ++it) { if((*it)->currency() == cur) {keep_old = true; break;} } } if(!keep_old) cur->rates.clear(); cur->setExchangeRate(exrate * usd_rate); cur->setExchangeRateSource(EXCHANGE_RATE_SOURCE_MYCURRENCY_NET); } else if(!cur) { cur = new Currency(this, code, QString(), name, exrate * usd_rate); cur->setExchangeRateSource(EXCHANGE_RATE_SOURCE_MYCURRENCY_NET); addCurrency(cur); } had_data = true; } i = data.indexOf("class=\'country\'", i); } if(!had_data) return tr("No exchange rates found."); return QString(); } QString Budget::saveCurrencies() { QString filename = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/currencies.xml"; QFileInfo info(filename); if(info.isDir()) { return tr("File is a directory"); } info.dir().mkpath("."); QSaveFile ofile(filename); ofile.open(QIODevice::WriteOnly); if(!ofile.isOpen()) { ofile.cancelWriting(); return tr("Couldn't open file for writing"); } QXmlStreamWriter xml(&ofile); #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) xml.setCodec("UTF-8"); #endif xml.setAutoFormatting(true); xml.setAutoFormattingIndent(-1); xml.writeStartDocument(); xml.writeStartElement("Eqonomize"); xml.writeAttribute("version", VERSION); for(CurrencyList::const_iterator it = currencies.constBegin(); it != currencies.constEnd(); ++it) { Currency *currency = *it; xml.writeStartElement("currency"); currency->save(&xml, true); xml.writeEndElement(); } xml.writeEndElement(); if(ofile.error() != QFile::NoError) { ofile.cancelWriting(); return tr("Error while writing file; file was not saved"); } if(!ofile.commit()) { return tr("Error while writing file; file was not saved"); } return QString(); } TransactionConversionRateDate Budget::defaultTransactionConversionRateDate() const {return i_tcrd;} void Budget::setDefaultTransactionConversionRateDate(TransactionConversionRateDate tcrd) {i_tcrd = tcrd;} QString Budget::loadFile(QString filename, QString &errors, bool *default_currency_created, bool merge, bool rename_duplicate_accounts, bool rename_duplicate_categories, bool rename_duplicate_securities, bool ignore_duplicate_transactions) { QFile file(filename); if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) { return tr("Couldn't open %1 for reading").arg(filename); } else if(!file.size()) { return QString(); } QXmlStreamReader xml(&file); if(!xml.readNextStartElement()) return tr("Not a valid Eqonomize! file (XML parse error: \"%1\" at line %2, col %3)").arg(xml.errorString()).arg(xml.lineNumber()).arg(xml.columnNumber()); if(xml.name() != XML_COMPARE_CONST_CHAR("EqonomizeDoc")) return tr("Invalid root element %1 in XML document").arg(xml.name().toString()); QStringList s_versions = xml.attributes().value("version").toString().split('.'); int i_version[] = {0, 0, 0}; if(s_versions.size() > 0) i_version[0] = s_versions[0].toInt(); if(s_versions.size() > 1) i_version[1] = s_versions[1].toInt(); if(s_versions.size() > 2) i_version[2] = s_versions[2].toInt(); qint64 curtime = QDateTime::currentMSecsSinceEpoch() / 1000; if(!merge) { tags.clear(); clear(); i_opened_revision = xml.attributes().value("revision").toInt(); if(i_opened_revision <= 0) i_opened_revision = 1; i_revision = i_opened_revision; last_id = xml.attributes().value("lastid").toLongLong(); if(last_id < 0) last_id = 0; } errors = QString(); int category_errors = 0, account_errors = 0, transaction_errors = 0, security_errors = 0; assetsAccounts_id[balancingAccount->id()] = balancingAccount; QHash merge_transaction_ids; QList update_links_list; Currency *cur = NULL, *prev_default_cur = default_currency; if(default_currency_created) *default_currency_created = false; bool set_ids = false; if(!merge) o_sync->clear(); i_budget_month = 1; while(xml.readNextStartElement()) { if(xml.name() == XML_COMPARE_CONST_CHAR("budget_period")) { if(merge) { xml.skipCurrentElement(); } else { while(xml.readNextStartElement()) { if(xml.name() == XML_COMPARE_CONST_CHAR("first_day_of_month")) { QString s_day = xml.readElementText(); bool ok = true; int i_day = s_day.toInt(&ok); if(ok) setBudgetDay(i_day); } else if(xml.name() == XML_COMPARE_CONST_CHAR("first_month_of_year")) { QString s_month = xml.readElementText(); bool ok = true; int i_month = s_month.toInt(&ok); if(ok) setBudgetMonth(i_month); } else { xml.skipCurrentElement(); } } } } else if(xml.name() == XML_COMPARE_CONST_CHAR("synchronization")) { if(merge) { xml.skipCurrentElement(); } else { o_sync->clear(); o_sync->autosync = xml.attributes().value("autosync").toInt(); o_sync->revision = xml.attributes().value("revision").toInt(); while(xml.readNextStartElement()) { if(xml.name() == XML_COMPARE_CONST_CHAR("url")) { o_sync->url = xml.readElementText().trimmed(); } else if(xml.name() == XML_COMPARE_CONST_CHAR("download")) { o_sync->download = xml.readElementText().trimmed(); } else if(xml.name() == XML_COMPARE_CONST_CHAR("upload")) { o_sync->upload = xml.readElementText().trimmed(); } else { xml.skipCurrentElement(); } } } } else if(xml.name() == XML_COMPARE_CONST_CHAR("currency")) { QString cur_code = xml.attributes().value("code").trimmed().toString(); if(!cur && !cur_code.isEmpty()) { cur = findCurrency(cur_code); if(cur) { default_currency = cur; } else { cur = new Currency(this, cur_code); addCurrency(cur); default_currency = cur; if(default_currency_created) *default_currency_created = true; } } xml.skipCurrentElement(); } else if(xml.name() == XML_COMPARE_CONST_CHAR("schedule")) { bool valid = true; ScheduledTransaction *strans = new ScheduledTransaction(this, &xml, &valid); if(valid && merge && ignore_duplicate_transactions) { for(ScheduledTransactionList::const_iterator it = scheduledTransactions.constBegin(); it != scheduledTransactions.constEnd(); ++it) { if((*it)->date() > strans->date()) break; else if(strans->equals(*it, false)) {delete strans; strans = NULL; break;} } } if(valid && strans) { if(merge) { qlonglong old_id = strans->id(); strans->setId(getNewId()); merge_transaction_ids[old_id] = strans->id(); if(strans->linksCount(false) > 0) update_links_list << strans; strans->setId(getNewId()); strans->setFirstRevision(i_revision); strans->setLastRevision(i_revision); old_id = strans->transaction()->id(); strans->transaction()->setId(getNewId()); merge_transaction_ids[old_id] = strans->transaction()->id(); strans->transaction()->setFirstRevision(i_revision); strans->transaction()->setLastRevision(i_revision); } else { if(!set_ids) set_ids = strans->id() == 0; if(!set_ids) set_ids = strans->transaction()->id() == 0; } if((i_version[0] < 1 || (i_version[0] == 1 && (i_version[1] < 3 || (i_version[1] == 3 && i_version[2] <= 2)))) && strans->timestamp() > curtime) strans->setTimestamp(strans->timestamp() / 1000000L); if((i_version[0] < 1 || (i_version[0] == 1 && (i_version[1] < 3 || (i_version[1] == 3 && i_version[2] <= 4)))) && strans->associatedFile().contains(",")) { strans->setAssociatedFile(QString("\"") + strans->associatedFile() + "\""); } scheduledTransactions.append(strans); if(strans->transaction()) { if(strans->transactiontype() == TRANSACTION_TYPE_SECURITY_BUY || strans->transactiontype() == TRANSACTION_TYPE_SECURITY_SELL) { ((SecurityTransaction*) strans->transaction())->security()->scheduledTransactions.append(strans); } else if(strans->transactiontype() == TRANSACTION_TYPE_INCOME && ((Income*) strans->transaction())->security()) { if(strans->transactionsubtype() == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND) ((Income*) strans->transaction())->security()->scheduledReinvestedDividends.append(strans); else ((Income*) strans->transaction())->security()->scheduledDividends.append(strans); } Transactions *trans = strans->transaction(); for(int i = 0; i < trans->tagsCount(false); i++) { if(!tags.contains(trans->getTag(i))) tags << trans->getTag(i); } if(trans->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { SplitTransaction *split = (SplitTransaction*) trans; int c = split->count(); for(int i = 0; i < c; i++) { trans = split->at(i); for(int i2 = 0; i2 < trans->tagsCount(false); i2++) { if(!tags.contains(trans->getTag(i2))) tags << trans->getTag(i2); } } } } } else if(!valid) { transaction_errors++; if(strans) delete strans; } } else if(xml.name() == XML_COMPARE_CONST_CHAR("transaction")) { SplitTransaction *split = NULL; Transaction *trans = NULL; #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) QStringView type = xml.attributes().value("type"); #else QStringRef type = xml.attributes().value("type"); #endif bool valid = true; if(type.isEmpty()) { QXmlStreamAttributes attr = xml.attributes(); if(attr.hasAttribute("shares") && attr.hasAttribute("security")) { if(attr.hasAttribute("cost")) attr.append("type", "security_buy"); else if(attr.hasAttribute("income")) attr.append("type", "security_sell"); else if(attr.hasAttribute("from")) attr.append("type", "security_buy"); else if(attr.hasAttribute("to")) attr.append("type", "security_sell"); } else if(attr.hasAttribute("cost") || (attr.hasAttribute("category") && attr.hasAttribute("from"))) { attr.append("type", "expense"); } else if(attr.hasAttribute("income") || (attr.hasAttribute("category") && attr.hasAttribute("to"))) { attr.append("type", "income"); } else if(attr.hasAttribute("amount") || attr.hasAttribute("withdrawal")) { attr.append("type", "transfer"); } else if(attr.hasAttribute("from") && attr.hasAttribute("to")) { qlonglong id_from = attr.value("from").toLongLong(); qlonglong id_to = attr.value("to").toLongLong(); if(expensesAccounts_id.contains(id_to) || expensesAccounts_id.contains(id_from)) attr.append("type", "expense"); else if(incomesAccounts_id.contains(id_from) || incomesAccounts_id.contains(id_to)) attr.append("type", "income"); else if(assetsAccounts_id.contains(id_from) && assetsAccounts_id.contains(id_to)) attr.append("type", "transfer"); } type = attr.value("type"); } if(type == XML_COMPARE_CONST_CHAR("expense") || type == XML_COMPARE_CONST_CHAR("refund")) { Expense *expense = new Expense(this, &xml, &valid); if(valid && merge && ignore_duplicate_transactions) { for(TransactionList::const_iterator it = expenses.constBegin(); it != expenses.constEnd(); ++it) { if((*it)->date() > expense->date()) break; else if(expense->equals(*it, false)) {delete expense; expense = NULL; break;} } } if(valid && expense) { trans = expense; expenses.append(expense); } else if(!valid) { transaction_errors++; if(expense) delete expense; } } else if(type == XML_COMPARE_CONST_CHAR("income") || type == XML_COMPARE_CONST_CHAR("repayment")) { Income *income = new Income(this, &xml, &valid); if(valid && merge && ignore_duplicate_transactions) { if(income->security()) { for(SecurityTransactionList::const_iterator it = income->security()->dividends.constBegin(); it != income->security()->dividends.constEnd(); ++it) { if((*it)->date() > income->date()) break; else if(income->equals(*it, false)) {delete income; income = NULL; break;} } } else { for(TransactionList::const_iterator it = incomes.constBegin(); it != incomes.constEnd(); ++it) { if((*it)->date() > income->date()) break; else if(income->equals(*it, false)) {delete income; income = NULL; break;} } } } if(valid && income) { trans = income; incomes.append(income); if(income->security()) income->security()->dividends.append(income); } else if(!valid) { transaction_errors++; if(income) delete income; } } else if(type == XML_COMPARE_CONST_CHAR("dividend")) { Income *income = new Income(this, &xml, &valid); if(!income->security()) valid = false; if(valid && merge && ignore_duplicate_transactions) { for(SecurityTransactionList::const_iterator it = income->security()->dividends.constBegin(); it != income->security()->dividends.constEnd(); ++it) { if((*it)->date() > income->date()) break; else if(income->equals(*it, false)) {delete income; income = NULL; break;} } } if(valid && income) { trans = income; incomes.append(income); income->security()->dividends.append(income); } else if(!valid) { transaction_errors++; if(income) delete income; } } else if(type == XML_COMPARE_CONST_CHAR("reinvested_dividend")) { ReinvestedDividend *rediv = new ReinvestedDividend(this, &xml, &valid); if(valid && merge && ignore_duplicate_transactions) { for(SecurityTransactionList::const_iterator it = rediv->security()->reinvestedDividends.constBegin(); it != rediv->security()->reinvestedDividends.constEnd(); ++it) { if((*it)->date() > rediv->date()) break; else if(rediv->equals(*it, false)) {delete rediv; rediv = NULL; break;} } } if(valid && rediv) { trans = rediv; incomes.append(rediv); rediv->security()->reinvestedDividends.append(rediv); } else if(!valid) { transaction_errors++; if(rediv) delete rediv; } } else if(type == XML_COMPARE_CONST_CHAR("security_trade")) { SecurityTrade *ts = new SecurityTrade(this, &xml, &valid); if(valid && merge && ignore_duplicate_transactions) { for(SecurityTradeList::const_iterator it = securityTrades.constBegin(); it != securityTrades.constEnd(); ++it) { if((*it)->date > ts->date) break; else if(ts->date == (*it)->date && ts->from_shares == (*it)->from_shares && ts->to_shares == (*it)->to_shares && ts->from_security == (*it)->from_security && ts->to_security == (*it)->to_security) {delete ts; ts = NULL; break;} } } if(valid && ts) { if(merge) { ts->id = getNewId(); ts->first_revision = i_revision; ts->last_revision = i_revision; } else { if(!set_ids) set_ids = ts->id == 0; } if((i_version[0] < 1 || (i_version[0] == 1 && (i_version[1] < 3 || (i_version[1] == 3 && i_version[2] <= 2)))) && ts->timestamp > curtime) ts->timestamp = ts->timestamp / 1000000L; securityTrades.append(ts); ts->from_security->tradedShares.append(ts); ts->to_security->tradedShares.append(ts); } else if(!valid) { transaction_errors++; if(ts) delete ts; } xml.skipCurrentElement(); } else if(type == XML_COMPARE_CONST_CHAR("transfer")) { Transfer *transfer = new Transfer(this, &xml, &valid); if(valid && merge && ignore_duplicate_transactions) { for(TransactionList::const_iterator it = transfers.constBegin(); it != transfers.constEnd(); ++it) { if((*it)->date() > transfer->date()) break; else if(transfer->equals(*it, false)) {delete transfer; transfer = NULL; break;} } } if(valid && transfer) { trans = transfer; transfers.append(transfer); } else if(!valid) { transaction_errors++; if(transfer) delete transfer; } } else if(type == XML_COMPARE_CONST_CHAR("balancing")) { Transfer *transfer = new Balancing(this, &xml, &valid); if(valid && merge && ignore_duplicate_transactions) { for(TransactionList::const_iterator it = transfers.constBegin(); it != transfers.constEnd(); ++it) { if((*it)->date() > transfer->date()) break; else if(transfer->equals(*it, false)) {delete transfer; transfer = NULL; break;} } } if(valid && transfer) { trans = transfer; transfers.append(transfer); } else if(!valid) { transaction_errors++; if(transfer) delete transfer; } } else if(type == XML_COMPARE_CONST_CHAR("security_buy")) { SecurityBuy *sectrans = new SecurityBuy(this, &xml, &valid); if(valid && merge && ignore_duplicate_transactions) { for(SecurityTransactionList::const_iterator it = sectrans->security()->transactions.constBegin(); it != sectrans->security()->transactions.constEnd(); ++it) { if((*it)->date() > sectrans->date()) break; else if(sectrans->equals(*it, false)) {delete sectrans; sectrans = NULL; break;} } } if(valid && sectrans) { trans = sectrans; securityTransactions.append(sectrans); sectrans->security()->transactions.append(sectrans); } else if(!valid) { transaction_errors++; if(sectrans) delete sectrans; } } else if(type == XML_COMPARE_CONST_CHAR("security_sell")) { SecuritySell *sectrans = new SecuritySell(this, &xml, &valid); if(valid && merge && ignore_duplicate_transactions) { for(SecurityTransactionList::const_iterator it = sectrans->security()->transactions.constBegin(); it != sectrans->security()->transactions.constEnd(); ++it) { if((*it)->date() > sectrans->date()) break; else if(sectrans->equals(*it, false)) {delete sectrans; sectrans = NULL; break;} } } if(valid && sectrans) { trans = sectrans; securityTransactions.append(sectrans); sectrans->security()->transactions.append(sectrans); } else if(!valid) { transaction_errors++; if(sectrans) delete sectrans; } } else if(type == XML_COMPARE_CONST_CHAR("multiitem") || type == XML_COMPARE_CONST_CHAR("split")) { split = new MultiItemTransaction(this, &xml, &valid); } else if(type == XML_COMPARE_CONST_CHAR("multiaccount")) { split = new MultiAccountTransaction(this, &xml, &valid); } else if(type == XML_COMPARE_CONST_CHAR("debtpayment")) { split = new DebtPayment(this, &xml, &valid); } else { xml.skipCurrentElement(); transaction_errors++; } if(split) { if(valid && merge && ignore_duplicate_transactions) { for(SplitTransactionList::const_iterator it = splitTransactions.constBegin(); it != splitTransactions.constEnd(); ++it) { if((*it)->date() > split->date()) break; else if(split->equals(*it, false)) {delete split; split = NULL; break;} } } if(!valid) { transaction_errors++; if(split) delete split; split = NULL; } else if(split) { if(merge) { qlonglong old_id = split->id(); split->setId(getNewId()); merge_transaction_ids[old_id] = split->id(); if(split->linksCount(false) > 0) update_links_list << split; split->setFirstRevision(i_revision); split->setLastRevision(i_revision); } else { if(!set_ids) set_ids = split->id() == 0; } if((i_version[0] < 1 || (i_version[0] == 1 && (i_version[1] < 3 || (i_version[1] == 3 && i_version[2] <= 2)))) && split->timestamp() > curtime) split->setTimestamp(split->timestamp() / 1000000L); if((i_version[0] < 1 || (i_version[0] == 1 && (i_version[1] < 3 || (i_version[1] == 3 && i_version[2] <= 4)))) && split->associatedFile().contains(",")) { split->setAssociatedFile(QString("\"") + split->associatedFile() + "\""); } splitTransactions.append(split); for(int i = 0; i < split->tagsCount(false); i++) { if(!tags.contains(split->getTag(i))) tags << split->getTag(i); } int c = split->count(); for(int i = 0; i < c; i++) { trans = split->at(i); if(merge) { qlonglong old_id = trans->id(); trans->setId(getNewId()); merge_transaction_ids[old_id] = trans->id(); if(trans->linksCount(false) > 0) update_links_list << trans; trans->setFirstRevision(i_revision); trans->setLastRevision(i_revision); } else { if(!set_ids && split->type() != SPLIT_TRANSACTION_TYPE_LOAN) set_ids = trans->id() == 0; } switch(trans->type()) { case TRANSACTION_TYPE_TRANSFER: { transfers.append((Transfer*) trans); break; } case TRANSACTION_TYPE_INCOME: { incomes.append((Income*) trans); if(((Income*) trans)->security()) ((Income*) trans)->security()->dividends.append((Income*) trans); break; } case TRANSACTION_TYPE_EXPENSE: { expenses.append((Expense*) trans); break; } case TRANSACTION_TYPE_SECURITY_BUY: { securityTransactions.append((SecurityBuy*) trans); ((SecurityBuy*) trans)->security()->transactions.append((SecurityBuy*) trans); break; } case TRANSACTION_TYPE_SECURITY_SELL: { securityTransactions.append((SecuritySell*) trans); ((SecuritySell*) trans)->security()->transactions.append((SecuritySell*) trans); break; } default: {} } if((i_version[0] < 1 || (i_version[0] == 1 && (i_version[1] < 3 || (i_version[1] == 3 && i_version[2] <= 4)))) && trans->associatedFile().contains(",")) { trans->setAssociatedFile(QString("\"") + trans->associatedFile() + "\""); } transactions.append(trans); for(int i2 = 0; i2 < trans->tagsCount(false); i2++) { if(!tags.contains(trans->getTag(i2))) { tags << trans->getTag(i2); } else if(split->hasTag(trans->getTag(i2), false)) { trans->removeTag(trans->getTag(i2)); } } } } } else if(trans) { if(merge) { qlonglong old_id = trans->id(); trans->setId(getNewId()); merge_transaction_ids[old_id] = trans->id(); if(trans->linksCount(false) > 0) update_links_list << trans; trans->setFirstRevision(i_revision); trans->setLastRevision(i_revision); } else { if(!set_ids) set_ids = trans->id() == 0; } if((i_version[0] < 1 || (i_version[0] == 1 && (i_version[1] < 3 || (i_version[1] == 3 && i_version[2] <= 2)))) && trans->timestamp() > curtime) trans->setTimestamp(trans->timestamp() / 1000000L); if((i_version[0] < 1 || (i_version[0] == 1 && (i_version[1] < 3 || (i_version[1] == 3 && i_version[2] <= 4)))) && trans->associatedFile().contains(",")) { trans->setAssociatedFile(QString("\"") + trans->associatedFile() + "\""); } transactions.append(trans); for(int i2 = 0; i2 < trans->tagsCount(false); i2++) { if(!tags.contains(trans->getTag(i2))) tags << trans->getTag(i2); } } } else if(xml.name() == XML_COMPARE_CONST_CHAR("category")) { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) QStringView type = xml.attributes().value("type"); #else QStringRef type = xml.attributes().value("type"); #endif bool valid = true; if(type == XML_COMPARE_CONST_CHAR("expenses")) { ExpensesAccount *account = new ExpensesAccount(this, &xml, &valid); if(valid) { ExpensesAccount *old_account = NULL; if(merge) old_account = findExpensesAccount(account->name(), NULL); if(!rename_duplicate_categories && old_account) { expensesAccounts_id[account->id()] = old_account; for(AccountList::const_iterator it = account->subCategories.constBegin(); it != account->subCategories.constEnd();) { CategoryAccount *ca = *it; ExpensesAccount *old_sub = findExpensesAccount(ca->name(), old_account); if(old_sub) { expensesAccounts_id[ca->id()] = old_sub; removeAccount(ca, true); ++it; } else { old_account->addSubCategory(ca); } } delete account; } else { expensesAccounts_id[account->id()] = account; if(old_account) account->setName(QString("%1 (%2)").arg(account->name()).arg(tr("imported"))); if(merge) { account->setId(getNewId()); account->setFirstRevision(i_revision); account->setLastRevision(i_revision); } expensesAccounts.append(account); accounts.append(account); } } else { category_errors++; delete account; } } else if(type == XML_COMPARE_CONST_CHAR("incomes")) { IncomesAccount *account = new IncomesAccount(this, &xml, &valid); if(valid) { IncomesAccount *old_account = NULL; if(merge) old_account = findIncomesAccount(account->name(), NULL); if(!rename_duplicate_categories && old_account) { incomesAccounts_id[account->id()] = old_account; for(AccountList::const_iterator it = account->subCategories.constBegin(); it != account->subCategories.constEnd();) { CategoryAccount *ca = *it; IncomesAccount *old_sub = findIncomesAccount(ca->name(), old_account); if(old_sub) { incomesAccounts_id[ca->id()] = old_sub; removeAccount(ca, true); ++it; } else { old_account->addSubCategory(ca); } } delete account; } else { incomesAccounts_id[account->id()] = account; if(old_account) account->setName(QString("%1 (%2)").arg(account->name()).arg(tr("imported"))); if(merge) { account->setId(getNewId()); account->setFirstRevision(i_revision); account->setLastRevision(i_revision); } incomesAccounts.append(account); accounts.append(account); } } else { category_errors++; delete account; } } else { category_errors++; xml.skipCurrentElement(); } } else if(xml.name() == XML_COMPARE_CONST_CHAR("account")) { if(!cur) { if(merge) { cur = default_currency; } else { bool b = resetDefaultCurrency(); cur = default_currency; if(default_currency_created) *default_currency_created = b; } } bool valid = true; AssetsAccount *account = new AssetsAccount(this, &xml, &valid); if(valid) { AssetsAccount *old_account = NULL; if(merge) old_account = findAssetsAccount(account->name()); if(!rename_duplicate_accounts && old_account) { assetsAccounts_id[account->id()] = old_account; } else { assetsAccounts_id[account->id()] = account; if(old_account) account->setName(QString("%1 (%2)").arg(account->name()).arg(tr("imported"))); if(merge) { account->setId(getNewId()); account->setFirstRevision(i_revision); account->setLastRevision(i_revision); } assetsAccounts.append(account); accounts.append(account); } } else { account_errors++; delete account; } } else if(xml.name() == XML_COMPARE_CONST_CHAR("security")) { bool valid = true; Security *security = new Security(this, &xml, &valid); if(valid) { Security *old_security = NULL; if(merge) old_security = findSecurity(security->name()); if(!rename_duplicate_securities && old_security) { securities_id[security->id()] = old_security; } else { securities_id[security->id()] = security; if(old_security)security->setName(QString("%1 (%2)").arg(security->name()).arg(tr("imported"))); if(merge) { security->setId(getNewId()); security->setFirstRevision(i_revision); security->setLastRevision(i_revision); } securities.append(security); i_quotation_decimals = security->quotationDecimals(); i_share_decimals = security->decimals(); } } else { security_errors++; delete security; } } else { if(!errors.isEmpty()) errors += '\n'; errors += tr("Unknown XML element: \"%1\" at line %2, col %3").arg(xml.name().toString()).arg(xml.lineNumber()).arg(xml.columnNumber()); xml.skipCurrentElement(); } } if(!cur && !merge) { bool b = resetDefaultCurrency(); cur = defaultCurrency(); if(default_currency_created) *default_currency_created = b; } if(merge) default_currency = prev_default_cur; if (xml.hasError()) { if(!errors.isEmpty()) errors += '\n'; errors += tr("XML parse error: \"%1\" at line %2, col %3").arg(xml.errorString()).arg(xml.lineNumber()).arg(xml.columnNumber()); } incomesAccounts_id.clear(); expensesAccounts_id.clear(); assetsAccounts_id.clear(); securities_id.clear(); if(set_ids) { std::sort(transactions.begin(), transactions.end(), transaction_list_less_than_stamp); std::sort(scheduledTransactions.begin(), scheduledTransactions.end(), schedule_list_less_than_stamp); std::sort(splitTransactions.begin(), splitTransactions.end(), split_list_less_than_stamp); std::sort(securityTrades.begin(), securityTrades.end(), trade_list_less_than_stamp); TransactionList::const_iterator it1 = transactions.constBegin(); ScheduledTransactionList::const_iterator it2 = scheduledTransactions.constBegin(); SplitTransactionList::const_iterator it3 = splitTransactions.constBegin(); SecurityTradeList::const_iterator it4 = securityTrades.constBegin(); int it_i = 0; while(true) { while((it_i == 0 || it_i == 1) && it1 != transactions.constEnd() && ((*it1)->id() != 0 || ((*it1)->parentSplit() && (*it1)->parentSplit()->type() == SPLIT_TRANSACTION_TYPE_LOAN))) ++it1; while((it_i == 0 || it_i == 2) && it2 != scheduledTransactions.constEnd() && (*it2)->id() != 0) ++it2; while((it_i == 0 || it_i == 3) && it3 != splitTransactions.constEnd() && (*it3)->id() != 0) ++it3; while((it_i == 0 || it_i == 4) && it4 != securityTrades.constEnd() && (*it4)->id != 0) ++it4; it_i = 4; if(it1 != transactions.constEnd() && (it2 == scheduledTransactions.constEnd() || transactions_less_than_stamp(*it1, *it2))) { if(it3 == splitTransactions.constEnd() || transactions_less_than_stamp(*it1, *it3)) { if(it4 == securityTrades.constEnd() || transactions_less_than_trade_stamp(*it1, *it4)) it_i = 1; } else if(it4 == securityTrades.constEnd() || transactions_less_than_trade_stamp(*it3, *it4)) it_i = 3; } else if(it2 != scheduledTransactions.constEnd() && (it3 == splitTransactions.constEnd() || transactions_less_than_stamp(*it2, *it3))) { if(it4 == securityTrades.constEnd() || transactions_less_than_trade_stamp(*it2, *it4)) it_i = 2; } else if(it3 != splitTransactions.constEnd() && (it4 == securityTrades.constEnd() || transactions_less_than_trade_stamp(*it3, *it4))) it_i = 3; else if(it4 == securityTrades.constEnd()) break; last_id++; if(it_i == 1) { (*it1)->setId(last_id); ++it1; } else if(it_i == 2) { (*it2)->setId(last_id); if((*it2)->transaction()->id() == 0) { last_id++; (*it2)->transaction()->setId(last_id); } ++it2; } else if(it_i == 3) { (*it3)->setId(last_id); ++it3; } else if(it_i == 4) { (*it4)->id = last_id; ++it4; } } } for(int i = 0; i < update_links_list.count(); i++) { Transactions *trans = update_links_list.at(i); int n = trans->linksCount(false); for(int i2 = 0; i2 < n; i2++) { qlonglong new_id = merge_transaction_ids[trans->getLinkId(0, false)]; trans->removeLink(0); trans->addLinkId(new_id); } } i_revision++; expenses.sort(); incomes.sort(); transfers.sort(); securityTransactions.sort(); securityTrades.sort(); for(SecurityList::const_iterator it = securities.constBegin(); it != securities.constEnd(); ++it) { Security *security = *it; security->dividends.sort(); security->transactions.sort(); security->scheduledTransactions.sort(); security->scheduledDividends.sort(); security->scheduledReinvestedDividends.sort(); security->reinvestedDividends.sort(); security->tradedShares.sort(); } transactions.sort(); scheduledTransactions.sort(); splitTransactions.sort(); expensesAccounts.sort(); incomesAccounts.sort(); assetsAccounts.sort(); accounts.sort(); securities.sort(); tags.sort(Qt::CaseInsensitive); if(account_errors > 0) { if(!errors.isEmpty()) errors += '\n'; errors += tr("Unable to load %n account(s).", "", account_errors); } if(category_errors > 0) { if(!errors.isEmpty()) errors += '\n'; errors += tr("Unable to load %n category/categories.", "", category_errors); } if(security_errors > 0) { if(!errors.isEmpty()) errors += '\n'; errors += tr("Unable to load %n security/securities.", "Financial security (e.g. stock, mutual fund)", security_errors); } if(transaction_errors > 0) { if(!errors.isEmpty()) errors += '\n'; errors += tr("Unable to load %n transaction(s).", "", transaction_errors); } file.close(); resetDefaultCurrencyChanged(); return QString(); } int Budget::fileRevision(QString filename, QString &error) const { QFile file(filename); if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) { error = tr("Couldn't open %1 for reading").arg(filename); return -1; } else if(!file.size()) { return -1; } QXmlStreamReader xml(&file); if(!xml.readNextStartElement()) { error = tr("Not a valid Eqonomize! file (XML parse error: \"%1\" at line %2, col %3)").arg(xml.errorString()).arg(xml.lineNumber()).arg(xml.columnNumber()); return -1; } if(xml.name() != XML_COMPARE_CONST_CHAR("EqonomizeDoc")) { error = tr("Invalid root element %1 in XML document").arg(xml.name().toString()); return -1; } int file_revision = xml.attributes().value("revision").toInt(); if(file_revision <= 0) file_revision = 1; file.close(); error = QString(); return file_revision; } bool Budget::isUnsynced(QString filename, QString &error, int synced_revision) const { if(synced_revision < 0) synced_revision = i_opened_revision; QFile file(filename); if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) { error = tr("Couldn't open %1 for reading").arg(filename); return false; } else if(!file.size()) { return false; } QXmlStreamReader xml(&file); if(!xml.readNextStartElement()) { error = tr("Not a valid Eqonomize! file (XML parse error: \"%1\" at line %2, col %3)").arg(xml.errorString()).arg(xml.lineNumber()).arg(xml.columnNumber()); return false; } if(xml.name() != XML_COMPARE_CONST_CHAR("EqonomizeDoc")) { error = tr("Invalid root element %1 in XML document").arg(xml.name().toString()); return false; } int file_revision = xml.attributes().value("revision").toInt(); if(file_revision <= 0) file_revision = 1; file.close(); error = QString(); return file_revision > synced_revision; } void Budget::cancelSync() { if(syncReply) syncReply->abort(); if(syncProcess) syncProcess->terminate(); } bool Budget::sync(QString &error, QString &errors, bool do_upload, bool on_load) { if(!o_sync->isComplete()) { return false; } syncProcess = NULL; syncReply = NULL; QTemporaryFile file; file.open(); QString perror; if(!o_sync->download.isEmpty()) { file.close(); QString command = o_sync->download; command.replace("%f", file.fileName()); command.replace("%u", o_sync->url); QEventLoop loop; syncProcess = new QProcess(); #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) QStringList list = QProcess::splitCommand(command); if(list.isEmpty()) return "Empty command"; syncProcess->start(list.takeFirst(), list); #else syncProcess->start(command); #endif QObject::connect(syncProcess, SIGNAL(finished(int, QProcess::ExitStatus)), &loop, SLOT(quit())); loop.exec(); if(syncProcess->exitStatus() != QProcess::NormalExit || syncProcess->exitCode() != 0) { error = tr("Download command (%1) failed: %2.").arg(command).arg(syncProcess->errorString()); syncProcess->deleteLater(); syncProcess = NULL; return false; } perror = syncProcess->errorString(); syncProcess->deleteLater(); syncProcess = NULL; } else { QEventLoop loop; syncReply = nam.get(QNetworkRequest(QUrl(o_sync->url))); QObject::connect(syncReply, SIGNAL(finished()), &loop, SLOT(quit())); loop.exec(); if(syncReply->error() == QNetworkReply::OperationCanceledError) { //canceled by user syncReply->deleteLater(); syncReply = NULL; return false; } else if(syncReply->error() != QNetworkReply::NoError) { syncReply->abort(); error = tr("Failed to download file from %1: %2.").arg(o_sync->url).arg(syncReply->errorString()); syncReply->deleteLater(); syncReply = NULL; return false; } else { file.write(syncReply->readAll()); file.close(); } syncReply->deleteLater(); syncReply = NULL; } int file_revision = fileRevision(file.fileName(), error); if(!error.isNull() || file_revision <= o_sync->revision) { if(error.isNull() && file_revision < (on_load ? i_revision : i_opened_revision)) { int saved_revision = i_revision; if(on_load) i_revision = i_opened_revision; error = syncUpload(file.fileName()); i_revision = saved_revision; } if(!error.isNull() && !perror.isEmpty()) {error += "\n\n"; error += perror;} return false; } error = syncFile(file.fileName(), errors, o_sync->revision); if(!error.isNull()) { if(!perror.isEmpty()) {error += "\n\n"; error += perror;} return false; } o_sync->revision = file_revision; //upload if(do_upload) { error = syncUpload(file.fileName()); if(!error.isNull()) return true; } return true; } QString Budget::syncUpload(QString filename) { int rev_bak = o_sync->revision; o_sync->revision = i_revision; QString error = saveFile(filename, QFile::ReadUser | QFile::WriteUser, true); o_sync->revision = rev_bak; if(!error.isNull()) { return error; } QString command = o_sync->upload; command.replace("%f", filename); command.replace("%u", o_sync->url); QEventLoop loop; syncProcess = new QProcess(); #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) QStringList list = QProcess::splitCommand(command); if(list.isEmpty()) return "Empty command"; syncProcess->start(list.takeFirst(), list); #else syncProcess->start(command); #endif QObject::connect(syncProcess, SIGNAL(finished(int, QProcess::ExitStatus)), &loop, SLOT(quit())); loop.exec(); if(syncProcess->exitStatus() != QProcess::NormalExit || syncProcess->exitCode() != 0) { error = tr("Upload command (%1) failed: %2.").arg(command).arg(syncProcess->errorString()); } else { o_sync->revision = i_revision; } syncProcess->deleteLater(); syncProcess = NULL; return error; } bool Budget::autosyncEnabled() const {return o_sync->autosync && o_sync->isComplete();} QString Budget::syncFile(QString filename, QString &errors, int synced_revision) { if(synced_revision < 0) synced_revision = i_opened_revision; QFile file(filename); if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) { return tr("Couldn't open %1 for reading").arg(filename); } else if(!file.size()) { return QString(); } QXmlStreamReader xml(&file); if(!xml.readNextStartElement()) return tr("Not a valid Eqonomize! file (XML parse error: \"%1\" at line %2, col %3)").arg(xml.errorString()).arg(xml.lineNumber()).arg(xml.columnNumber()); if(xml.name() != XML_COMPARE_CONST_CHAR("EqonomizeDoc")) return tr("Invalid root element %1 in XML document").arg(xml.name().toString()); /*QString s_version = xml.attributes().value("version").toString(); float f_version = s_version.toFloat();*/ int file_revision = xml.attributes().value("revision").toInt(); if(file_revision <= 0) file_revision = 1; qlonglong file_last_id = xml.attributes().value("lastid").toLongLong(); if(file_last_id < 0) file_last_id = 0; int revision_diff = file_revision - synced_revision; if(revision_diff <= 0) { file.close(); return QString(); } last_id = file_last_id; i_revision += revision_diff; i_opened_revision = i_revision; errors = QString(); int category_errors = 0, account_errors = 0, transaction_errors = 0, security_errors = 0; assetsAccounts_id[balancingAccount->id()] = balancingAccount; QList update_ids_list; QHash old_incomesAccounts_id; QHash old_expensesAccounts_id; QHash old_assetsAccounts_id; QHash old_securities_id; for(AccountList::const_iterator it = assetsAccounts.constBegin(); it != assetsAccounts.constEnd(); ++it) { if((*it)->lastRevision() > synced_revision) (*it)->setLastRevision((*it)->lastRevision() + revision_diff); if((*it)->firstRevision() > synced_revision) { (*it)->setFirstRevision((*it)->firstRevision() + revision_diff); last_id++; (*it)->setId(last_id); } else { old_assetsAccounts_id[(*it)->id()] = *it; } } for(AccountList::const_iterator it = incomesAccounts.constBegin(); it != incomesAccounts.constEnd(); ++it) { if((*it)->lastRevision() > synced_revision) (*it)->setLastRevision((*it)->lastRevision() + revision_diff); if((*it)->firstRevision() > synced_revision) { (*it)->setFirstRevision((*it)->firstRevision() + revision_diff); last_id++; (*it)->setId(last_id); } else { old_incomesAccounts_id[(*it)->id()] = *it; } } for(AccountList::const_iterator it = expensesAccounts.constBegin(); it != expensesAccounts.constEnd(); ++it) { if((*it)->lastRevision() > synced_revision) (*it)->setLastRevision((*it)->lastRevision() + revision_diff); if((*it)->firstRevision() > synced_revision) { (*it)->setFirstRevision((*it)->firstRevision() + revision_diff); last_id++; (*it)->setId(last_id); } else { old_expensesAccounts_id[(*it)->id()] = *it; } } for(SecurityList::const_iterator it = securities.constBegin(); it != securities.constEnd(); ++it) { if((*it)->lastRevision() > synced_revision) (*it)->setLastRevision((*it)->lastRevision() + revision_diff); if((*it)->firstRevision() > synced_revision) { (*it)->setFirstRevision((*it)->firstRevision() + revision_diff); last_id++; (*it)->setId(last_id); } else { old_securities_id[(*it)->id()] = *it; } } QHash scheduleds_id, file_scheduleds_id; QHash scheduleds_trans_id, file_scheduleds_trans_id; QHash linked_transactions; for(ScheduledTransactionList::const_iterator it = scheduledTransactions.constBegin(); it != scheduledTransactions.constEnd(); ++it) { if((*it)->lastRevision() > synced_revision) (*it)->setLastRevision((*it)->lastRevision() + revision_diff); if((*it)->linksCount(false) > 0) linked_transactions[(*it)->id()] = *it; if((*it)->firstRevision() > synced_revision) { update_ids_list << (*it); } else { scheduleds_id[(*it)->id()] = *it; } if((*it)->transaction()->lastRevision() > synced_revision) (*it)->transaction()->setLastRevision((*it)->transaction()->lastRevision() + revision_diff); if((*it)->transaction()->linksCount(false) > 0) linked_transactions[(*it)->transaction()->id()] = (*it)->transaction(); if((*it)->transaction()->firstRevision() > synced_revision) { update_ids_list << (*it)->transaction(); } if((*it)->lastRevision() > synced_revision && (*it)->transaction()->firstRevision() <= synced_revision) scheduleds_trans_id[(*it)->transaction()->id()] = (*it)->transaction(); } QHash splits_id, file_splits_id; for(SplitTransactionList::const_iterator it = splitTransactions.constBegin(); it != splitTransactions.constEnd(); ++it) { if((*it)->lastRevision() > synced_revision) (*it)->setLastRevision((*it)->lastRevision() + revision_diff); if((*it)->linksCount(false) > 0) linked_transactions[(*it)->id()] = *it; if((*it)->firstRevision() > synced_revision) { update_ids_list << (*it); } splits_id[(*it)->id()] = *it; } QHash securitytrades_id, file_securitytrades_id; for(SecurityTradeList::const_iterator it = securityTrades.constBegin(); it != securityTrades.constEnd(); ++it) { if((*it)->last_revision > synced_revision) (*it)->last_revision += revision_diff; if((*it)->first_revision > synced_revision) { (*it)->first_revision = (*it)->first_revision + revision_diff; last_id++; (*it)->id = last_id; } else { securitytrades_id[(*it)->id] = *it; } } QHash transactions_id, file_transactions_id; for(TransactionList::const_iterator it = transactions.constBegin(); it != transactions.constEnd(); ++it) { if((*it)->lastRevision() > synced_revision) (*it)->setLastRevision((*it)->lastRevision() + revision_diff); bool b_loan = (*it)->parentSplit() && (*it)->parentSplit()->type() == SPLIT_TRANSACTION_TYPE_LOAN; if(!b_loan && (*it)->linksCount(false)) linked_transactions[(*it)->id()] = *it; if((*it)->firstRevision() > synced_revision) { if(!b_loan) { update_ids_list << (*it); } else { (*it)->setFirstRevision((*it)->firstRevision() + revision_diff); } } else if(!b_loan) { transactions_id[(*it)->id()] = *it; } } for(int i = 0; i < update_ids_list.count(); i++) { Transactions *trans = update_ids_list.at(i); trans->setFirstRevision(trans->firstRevision() + revision_diff); last_id++; qlonglong old_id = trans->id(); if(old_id > 0 && trans->linksCount(false) > 0) { for(int i = 0; i < trans->linksCount(); i++) { qlonglong lid = trans->getLinkId(i, false); QHash::iterator it = linked_transactions.find(lid); if(it != linked_transactions.end()) { (*it)->removeLink(trans); (*it)->addLinkId(last_id); } } } trans->setId(last_id); } QList deleted_accounts; QList deleted_securities; while(xml.readNextStartElement()) { if(xml.name() == XML_COMPARE_CONST_CHAR("budget_period")) { xml.skipCurrentElement(); } else if(xml.name() == XML_COMPARE_CONST_CHAR("currency")) { xml.skipCurrentElement(); } else if(xml.name() == XML_COMPARE_CONST_CHAR("synchronization")) { xml.skipCurrentElement(); } else if(xml.name() == XML_COMPARE_CONST_CHAR("schedule")) { bool valid = true; ScheduledTransaction *strans = new ScheduledTransaction(this, &xml, &valid); if(valid && strans) { QHash::iterator it = scheduleds_id.find(strans->id()); if(it == scheduleds_id.end()) { if(strans->lastRevision() > synced_revision) { QHash::iterator it2 = transactions_id.find(strans->transaction()->id()); if(it2 != transactions_id.end() && (*it2)->lastRevision() > strans->lastRevision()) { delete strans; } else { QHash::iterator it3 = splits_id.find(strans->transaction()->id()); if(it3 != splits_id.end() && (*it3)->lastRevision() > strans->lastRevision()) { delete strans; } else { addScheduledTransaction(strans); for(int i = 0; i < strans->linksCount(false); i++) { Transactions *ltrans = strans->getLink(i, false); if(ltrans) ltrans->addLink(strans->transaction()); } } } } else delete strans; } else { if((*it)->lastRevision() >= strans->lastRevision()) { delete strans; } else { for(int i = 0; i < (*it)->linksCount(false); i++) { Transactions *ltrans = (*it)->getLink(i, false); if(ltrans) ltrans->removeLink((*it)->transaction()); } removeScheduledTransaction(*it); addScheduledTransaction(strans); for(int i = 0; i < strans->linksCount(false); i++) { Transactions *ltrans = strans->getLink(i, false); if(ltrans) ltrans->addLink(strans->transaction()); } } scheduleds_id.remove(it.key()); } } else if(!valid) { transaction_errors++; if(strans) delete strans; } } else if(xml.name() == XML_COMPARE_CONST_CHAR("transaction")) { SplitTransaction *split = NULL; Transaction *trans = NULL; #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) QStringView type = xml.attributes().value("type"); #else QStringRef type = xml.attributes().value("type"); #endif bool valid = true; if(type == XML_COMPARE_CONST_CHAR("expense") || type == XML_COMPARE_CONST_CHAR("refund")) { trans = new Expense(this, &xml, &valid); } else if(type == XML_COMPARE_CONST_CHAR("income") || type == XML_COMPARE_CONST_CHAR("repayment")) { trans = new Income(this, &xml, &valid); } else if(type == XML_COMPARE_CONST_CHAR("dividend")) { trans = new Income(this, &xml, &valid); if(!((Income*) trans)->security()) valid = false; } else if(type == XML_COMPARE_CONST_CHAR("reinvested_dividend")) { trans = new ReinvestedDividend(this, &xml, &valid); } else if(type == XML_COMPARE_CONST_CHAR("security_trade")) { SecurityTrade *ts = new SecurityTrade(this, &xml, &valid); if(valid && ts) { QHash::iterator it = securitytrades_id.find(ts->id); if(it == securitytrades_id.end()) { if(ts->last_revision > synced_revision) addSecurityTrade(ts); else delete ts; } else { if((*it)->last_revision >= ts->last_revision) { delete ts; } else { removeSecurityTrade(*it); addSecurityTrade(ts); } securitytrades_id.remove(it.key()); } } else { transaction_errors++; if(ts) delete ts; } xml.skipCurrentElement(); } else if(type == XML_COMPARE_CONST_CHAR("transfer")) { trans = new Transfer(this, &xml, &valid); } else if(type == XML_COMPARE_CONST_CHAR("balancing")) { trans = new Balancing(this, &xml, &valid); } else if(type == XML_COMPARE_CONST_CHAR("security_buy")) { trans = new SecurityBuy(this, &xml, &valid); } else if(type == XML_COMPARE_CONST_CHAR("security_sell")) { trans = new SecuritySell(this, &xml, &valid); } else if(type == XML_COMPARE_CONST_CHAR("multiitem") || type == XML_COMPARE_CONST_CHAR("split")) { split = new MultiItemTransaction(this, &xml, &valid); } else if(type == XML_COMPARE_CONST_CHAR("multiaccount")) { split = new MultiAccountTransaction(this, &xml, &valid); } else if(type == XML_COMPARE_CONST_CHAR("debtpayment")) { split = new DebtPayment(this, &xml, &valid); } if(split) { if(!valid || !split) { transaction_errors++; if(split) delete split; split = NULL; } else { if(split) { QHash::iterator it = splits_id.find(split->id()); if(it == splits_id.end()) { if(split->lastRevision() > synced_revision && !scheduleds_trans_id.contains(split->id())) { addSplitTransaction(split); for(int i = 0; i < split->linksCount(false); i++) { Transactions *ltrans = split->getLink(i, false); if(ltrans) ltrans->addLink(split); } if(split->type() != SPLIT_TRANSACTION_TYPE_LOAN) { int c = split->count(); for(int i = 0; i < c; i++) { trans = split->at(i); for(int i2 = 0; i2 < trans->linksCount(false); i2++) { Transactions *ltrans = trans->getLink(i2, false); if(ltrans) ltrans->addLink(trans); } } } } else { if(split->type() != SPLIT_TRANSACTION_TYPE_LOAN) split->clear(true); delete split; } } else { if((*it)->lastRevision() >= split->lastRevision()) { if(split->type() != SPLIT_TRANSACTION_TYPE_LOAN) split->clear(true); delete split; transactions_id.remove(it.key()); } else { if((*it)->type() != SPLIT_TRANSACTION_TYPE_LOAN) (*it)->clear(true); removeSplitTransaction(*it); if(split->type() != SPLIT_TRANSACTION_TYPE_LOAN) { int c = split->count(); for(int i = 0; i < c; i++) { trans = split->at(i); QHash::iterator it = transactions_id.find(trans->id()); if(it == transactions_id.end()) { if(trans->lastRevision() > synced_revision && !scheduleds_trans_id.contains(trans->id())) { addTransaction(trans); for(int i2 = 0; i2 < trans->linksCount(false); i2++) { Transactions *ltrans = trans->getLink(i2, false); if(ltrans) ltrans->addLink(trans); } } else { split->removeTransaction(trans); i--; c--; } } else { if((*it)->lastRevision() > synced_revision && (*it)->lastRevision() >= trans->lastRevision()) { split->removeTransaction(trans); i--; c--; } else { for(int i2 = 0; i2 < (*it)->linksCount(false); i2++) { Transactions *ltrans = (*it)->getLink(i2, false); if(ltrans) ltrans->removeLink(*it); } removeTransaction(*it); addTransaction(trans); for(int i2 = 0; i2 < trans->linksCount(false); i2++) { Transactions *ltrans = trans->getLink(i2, false); if(ltrans) ltrans->addLink(trans); } } transactions_id.remove(it.key()); } } if(c <= 1) { split->clear(true); delete split; split = NULL; } } if(split) splitTransactions.inSort(split); } splits_id.remove(it.key()); } } } } else if(trans) { if(!valid) { transaction_errors++; } else { QHash::iterator it = transactions_id.find(trans->id()); if(it == transactions_id.end()) { if(trans->lastRevision() > synced_revision && !scheduleds_trans_id.contains(trans->id())) { addTransaction(trans); for(int i = 0; i < trans->linksCount(false); i++) { Transactions *ltrans = trans->getLink(i, false); if(ltrans) ltrans->addLink(trans); } } else { delete trans; } } else { if((*it)->lastRevision() >= trans->lastRevision()) { delete trans; } else { for(int i = 0; i < (*it)->linksCount(false); i++) { Transactions *ltrans = (*it)->getLink(i, false); if(ltrans) ltrans->removeLink(*it); } removeTransaction(*it); addTransaction(trans); for(int i = 0; i < trans->linksCount(false); i++) { Transactions *ltrans = trans->getLink(i, false); if(ltrans) ltrans->addLink(trans); } } transactions_id.remove(it.key()); } } } } else if(xml.name() == XML_COMPARE_CONST_CHAR("category")) { #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) QStringView type = xml.attributes().value("type"); #else QStringRef type = xml.attributes().value("type"); #endif bool valid = true; if(type == XML_COMPARE_CONST_CHAR("expenses")) { ExpensesAccount *account = new ExpensesAccount(this, &xml, &valid); if(valid) { QHash::iterator it = old_expensesAccounts_id.find(account->id()); if(it != old_expensesAccounts_id.end()) { if(account->lastRevision() > (*it)->lastRevision()) { if((*it)->lastRevision() > synced_revision) (*it)->setMergeBudgets(account); else (*it)->set(account); } else if(account->lastRevision() > synced_revision) { (*it)->mergeBudgets(account, true); } expensesAccounts_id[account->id()] = *it; QList delete_subs; for(AccountList::const_iterator it2 = account->subCategories.constBegin(); it2 != account->subCategories.constEnd(); ++it2) { QHash::iterator it3 = old_expensesAccounts_id.find((*it2)->id()); if(it3 != old_expensesAccounts_id.end()) { if((*it2)->lastRevision() > (*it3)->lastRevision()) { if((*it2)->lastRevision() > synced_revision) (*it3)->setMergeBudgets(*it2); else (*it3)->set(*it2); } else if((*it2)->lastRevision() > synced_revision) { (*it3)->mergeBudgets(*it2, true); } expensesAccounts_id[(*it2)->id()] = *it3; delete_subs << *it2; } else { if(!(*it)->subCategories.contains(*it2)) (*it)->addSubCategory(*it2); if((*it2)->lastRevision() <= synced_revision) { deleted_accounts.append(*it2); } } } for(QList::const_iterator it2 = delete_subs.constBegin(); it2 != delete_subs.constEnd(); ++it2) { removeAccount(*it2); } (*it)->subCategories.sort(); delete account; } else { expensesAccounts_id[account->id()] = account; expensesAccounts.append(account); accounts.append(account); if(account->lastRevision() <= synced_revision) { deleted_accounts.append(account); } QList delete_subs; for(AccountList::const_iterator it2 = account->subCategories.constBegin(); it2 != account->subCategories.constEnd(); ++it2) { QHash::iterator it3 = old_expensesAccounts_id.find((*it2)->id()); if(it3 != old_expensesAccounts_id.end()) { if((*it2)->lastRevision() > (*it3)->lastRevision()) { if((*it2)->lastRevision() > synced_revision) (*it3)->setMergeBudgets(*it2); else (*it3)->set(*it2); } else if((*it2)->lastRevision() > synced_revision) { (*it3)->mergeBudgets(*it2, true); } expensesAccounts_id[(*it2)->id()] = *it3; delete_subs << *it2; } } for(QList::const_iterator it2 = delete_subs.constBegin(); it2 != delete_subs.constEnd(); ++it2) { removeAccount(*it2); } account->subCategories.sort(); } } else if(!valid) { category_errors++; delete account; } } else if(type == XML_COMPARE_CONST_CHAR("incomes")) { IncomesAccount *account = new IncomesAccount(this, &xml, &valid); if(valid) { QHash::iterator it = old_incomesAccounts_id.find(account->id()); if(it != old_incomesAccounts_id.end()) { if(account->lastRevision() > (*it)->lastRevision()) { if((*it)->lastRevision() > synced_revision) (*it)->setMergeBudgets(account); else (*it)->set(account); } else if(account->lastRevision() > synced_revision) { (*it)->mergeBudgets(account, true); } incomesAccounts_id[account->id()] = *it; QList delete_subs; for(AccountList::const_iterator it2 = account->subCategories.constBegin(); it2 != account->subCategories.constEnd(); ++it2) { QHash::iterator it3 = old_incomesAccounts_id.find((*it2)->id()); if(it3 != old_incomesAccounts_id.end()) { if((*it2)->lastRevision() > (*it3)->lastRevision()) { if((*it2)->lastRevision() > synced_revision) (*it3)->setMergeBudgets(*it2); else (*it3)->set(*it2); } else if((*it2)->lastRevision() > synced_revision) { (*it3)->mergeBudgets(*it2, true); } delete_subs << *it2; } else { if(!(*it)->subCategories.contains(*it2)) (*it)->addSubCategory(*it2); if((*it2)->lastRevision() <= synced_revision) { deleted_accounts.append(*it2); } } } for(QList::const_iterator it2 = delete_subs.constBegin(); it2 != delete_subs.constEnd(); ++it2) { removeAccount(*it2); } (*it)->subCategories.sort(); delete account; } else { incomesAccounts_id[account->id()] = account; if(account->lastRevision() <= synced_revision) { deleted_accounts.append(account); } incomesAccounts.append(account); accounts.append(account); QList delete_subs; for(AccountList::const_iterator it2 = account->subCategories.constBegin(); it2 != account->subCategories.constEnd(); ++it2) { QHash::iterator it3 = old_incomesAccounts_id.find((*it2)->id()); if(it3 != old_incomesAccounts_id.end()) { if((*it2)->lastRevision() > (*it3)->lastRevision()) { if((*it2)->lastRevision() > synced_revision) (*it3)->setMergeBudgets(*it2); else (*it3)->set(*it2); } else if((*it2)->lastRevision() > synced_revision) { (*it3)->mergeBudgets(*it2, true); } delete_subs << *it2; } } for(QList::const_iterator it2 = delete_subs.constBegin(); it2 != delete_subs.constEnd(); ++it2) { removeAccount(*it2); } account->subCategories.sort(); } } else if(!valid) { category_errors++; delete account; } } } else if(xml.name() == XML_COMPARE_CONST_CHAR("account")) { bool valid = true; AssetsAccount *account = new AssetsAccount(this, &xml, &valid); if(valid) { QHash::iterator it = old_assetsAccounts_id.find(account->id()); if(it != old_assetsAccounts_id.end()) { if(account->lastRevision() > (*it)->lastRevision()) { (*it)->set(account); } assetsAccounts_id[account->id()] = *it; delete account; } else { assetsAccounts_id[account->id()] = account; if(account->lastRevision() <= synced_revision) { deleted_accounts.append(account); } assetsAccounts.append(account); accounts.append(account); } } else if(!valid) { category_errors++; delete account; } } else if(xml.name() == XML_COMPARE_CONST_CHAR("security")) { bool valid = true; Security *security = new Security(this, &xml, &valid); if(valid) { QHash::iterator it = old_securities_id.find(security->id()); if(it != old_securities_id.end()) { if(security->lastRevision() > (*it)->lastRevision()) { if((*it)->lastRevision() > synced_revision) (*it)->setMergeQuotes(security); else (*it)->set(security); } else if(security->lastRevision() > synced_revision) { (*it)->mergeQuotes(security, true); } securities_id[security->id()] = *it; delete security; } else { securities_id[security->id()] = security; if(security->lastRevision() <= synced_revision) { deleted_securities.append(security); } securities.append(security); i_quotation_decimals = security->quotationDecimals(); i_share_decimals = security->decimals(); } } else { security_errors++; delete security; } } else { if(!errors.isEmpty()) errors += '\n'; errors += tr("Unknown XML element: \"%1\" at line %2, col %3").arg(xml.name().toString()).arg(xml.lineNumber()).arg(xml.columnNumber()); xml.skipCurrentElement(); } } if(xml.hasError()) { if(!errors.isEmpty()) errors += '\n'; errors += tr("XML parse error: \"%1\" at line %2, col %3").arg(xml.errorString()).arg(xml.lineNumber()).arg(xml.columnNumber()); } for(QHash::iterator it = scheduleds_id.begin(); it != scheduleds_id.end(); ++it) { if((*it)->lastRevision() <= synced_revision) removeScheduledTransaction(*it); } for(QHash::iterator it = splits_id.begin(); it != splits_id.end(); ++it) { if((*it)->lastRevision() <= synced_revision || ((*it)->type() != SPLIT_TRANSACTION_TYPE_LOAN && (*it)->count() <= 1)) { (*it)->clear(true); removeSplitTransaction(*it); } } for(QHash::iterator it = securitytrades_id.begin(); it != securitytrades_id.end(); ++it) { if((*it)->last_revision <= synced_revision) removeSecurityTrade(*it); } for(QHash::iterator it = transactions_id.begin(); it != transactions_id.end(); ++it) { if(!(*it)->parentSplit() && (*it)->lastRevision() <= synced_revision) removeTransaction(*it); } for(QHash::iterator it = old_securities_id.begin(); it != old_securities_id.end(); ++it) { if((*it)->lastRevision() <= synced_revision) { QHash::iterator it2 = securities_id.find((*it)->id()); if(it2 == securities_id.end() && !securityHasTransactions(*it)) removeSecurity(*it); } } for(QList::const_iterator it = deleted_securities.constBegin(); it != deleted_securities.constEnd(); ++it) { if(!securityHasTransactions(*it)) { removeSecurity(*it); } } for(QHash::iterator it = old_expensesAccounts_id.begin(); it != old_expensesAccounts_id.end(); ++it) { if((*it)->lastRevision() <= synced_revision) { QHash::iterator it2 = expensesAccounts_id.find((*it)->id()); if(it2 == expensesAccounts_id.end() && !accountHasTransactions(*it)) removeAccount(*it); } } for(QHash::iterator it = old_incomesAccounts_id.begin(); it != old_incomesAccounts_id.end(); ++it) { if((*it)->lastRevision() <= synced_revision) { QHash::iterator it2 = incomesAccounts_id.find((*it)->id()); if(it2 == incomesAccounts_id.end() && !accountHasTransactions(*it)) removeAccount(*it); } } for(QHash::iterator it = old_assetsAccounts_id.begin(); it != old_assetsAccounts_id.end(); ++it) { if((*it)->lastRevision() <= synced_revision) { QHash::iterator it2 = assetsAccounts_id.find((*it)->id()); if(it2 == assetsAccounts_id.end() && !accountHasTransactions(*it)) removeAccount(*it); } } for(QList::const_iterator it = deleted_accounts.constBegin(); it != deleted_accounts.constEnd(); ++it) { if(!accountHasTransactions(*it)) removeAccount(*it); } incomesAccounts_id.clear(); expensesAccounts_id.clear(); assetsAccounts_id.clear(); securities_id.clear(); expenses.sort(); incomes.sort(); transfers.sort(); securityTransactions.sort(); securityTrades.sort(); for(SecurityList::const_iterator it = securities.constBegin(); it != securities.constEnd(); ++it) { Security *security = *it; security->dividends.sort(); security->transactions.sort(); security->scheduledTransactions.sort(); security->scheduledDividends.sort(); security->scheduledReinvestedDividends.sort(); security->reinvestedDividends.sort(); security->tradedShares.sort(); } transactions.sort(); scheduledTransactions.sort(); splitTransactions.sort(); expensesAccounts.sort(); incomesAccounts.sort(); assetsAccounts.sort(); accounts.sort(); securities.sort(); if(account_errors > 0) { if(!errors.isEmpty()) errors += '\n'; errors += tr("Unable to load %n account(s).", "", account_errors); } if(category_errors > 0) { if(!errors.isEmpty()) errors += '\n'; errors += tr("Unable to load %n category/categories.", "", category_errors); } if(security_errors > 0) { if(!errors.isEmpty()) errors += '\n'; errors += tr("Unable to load %n security/securities.", "Financial security (e.g. stock, mutual fund)", security_errors); } if(transaction_errors > 0) { if(!errors.isEmpty()) errors += '\n'; errors += tr("Unable to load %n transaction(s).", "", transaction_errors); } file.close(); return QString(); } QString Budget::saveFile(QString filename, QFile::Permissions permissions, bool is_backup) { QFileInfo info(filename); if(info.isDir()) { return tr("File is a directory"); } QSaveFile ofile(filename); ofile.open(QIODevice::WriteOnly); ofile.setPermissions(permissions); if(!ofile.isOpen()) { ofile.cancelWriting(); return tr("Couldn't open file for writing"); } if(!is_backup) i_opened_revision = i_revision; QXmlStreamWriter xml(&ofile); #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) xml.setCodec("UTF-8"); #endif xml.setAutoFormatting(true); xml.setAutoFormattingIndent(-1); xml.writeStartDocument(); xml.writeDTD(""); xml.writeStartElement("EqonomizeDoc"); xml.writeAttribute("version", VERSION); xml.writeAttribute("revision", QString::number(i_revision)); xml.writeAttribute("lastid", QString::number(last_id)); if(o_sync->isComplete()) { xml.writeStartElement("synchronization"); xml.writeAttribute("type", "url"); if(o_sync->autosync) xml.writeAttribute("autosync", QString::number(o_sync->autosync)); xml.writeAttribute("revision", QString::number(o_sync->revision)); if(!o_sync->url.isEmpty()) xml.writeTextElement("url", o_sync->url); if(!o_sync->download.isEmpty()) xml.writeTextElement("download", o_sync->download); if(!o_sync->upload.isEmpty()) xml.writeTextElement("upload", o_sync->upload); xml.writeEndElement(); } xml.writeStartElement("budget_period"); xml.writeTextElement("first_day_of_month", QString::number(i_budget_day)); xml.writeTextElement("first_month_of_year", QString::number(i_budget_month)); xml.writeEndElement(); xml.writeStartElement("currency"); xml.writeAttribute("code", default_currency->code()); xml.writeEndElement(); for(AccountList::const_iterator it = accounts.constBegin(); it != accounts.constEnd(); ++it) { Account *account = *it; if(account != balancingAccount && account->topAccount() == account) { switch(account->type()) { case ACCOUNT_TYPE_ASSETS: { xml.writeStartElement("account"); account->save(&xml); xml.writeEndElement(); break; } case ACCOUNT_TYPE_INCOMES: { xml.writeStartElement("category"); xml.writeAttribute("type", "incomes"); account->save(&xml); xml.writeEndElement(); break; } case ACCOUNT_TYPE_EXPENSES: { xml.writeStartElement("category"); xml.writeAttribute("type", "expenses"); account->save(&xml); xml.writeEndElement(); break; } } } } for(SecurityList::const_iterator it = securities.constBegin(); it != securities.constEnd(); ++it) { Security *security = *it; xml.writeStartElement("security"); security->save(&xml); xml.writeEndElement(); } for(ScheduledTransactionList::const_iterator it = scheduledTransactions.constBegin(); it != scheduledTransactions.constEnd(); ++it) { ScheduledTransaction *strans = *it; xml.writeStartElement("schedule"); strans->save(&xml); xml.writeEndElement(); } for(SplitTransactionList::const_iterator it = splitTransactions.constBegin(); it != splitTransactions.constEnd(); ++it) { SplitTransaction *split = *it; if(split->count() > 0) { xml.writeStartElement("transaction"); switch(split->type()) { case SPLIT_TRANSACTION_TYPE_MULTIPLE_ITEMS: { xml.writeAttribute("type", "multiitem"); break; } case SPLIT_TRANSACTION_TYPE_MULTIPLE_ACCOUNTS: { xml.writeAttribute("type", "multiaccount"); break; } case SPLIT_TRANSACTION_TYPE_LOAN: { xml.writeAttribute("type", "debtpayment"); break; } } split->save(&xml); xml.writeEndElement(); } } for(SecurityTradeList::const_iterator it = securityTrades.constBegin(); it != securityTrades.constEnd(); ++it) { SecurityTrade *ts = *it; xml.writeStartElement("transaction"); xml.writeAttribute("type", "security_trade"); ts->save(&xml); xml.writeEndElement(); } for(TransactionList::const_iterator it = transactions.constBegin(); it != transactions.constEnd(); ++it) { Transaction *trans = *it; if(!trans->parentSplit()) { xml.writeStartElement("transaction"); switch(trans->type()) { case TRANSACTION_TYPE_TRANSFER: { if(trans->fromAccount() == balancingAccount || trans->toAccount() == balancingAccount) xml.writeAttribute("type", "balancing"); else xml.writeAttribute("type", "transfer"); break; } case TRANSACTION_TYPE_INCOME: { if(trans->subtype() == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND) xml.writeAttribute("type", "reinvested_dividend"); else if(((Income*) trans)->security()) xml.writeAttribute("type", "dividend"); else if(trans->value() < 0.0) xml.writeAttribute("type", "repayment"); else xml.writeAttribute("type", "income"); break; } case TRANSACTION_TYPE_EXPENSE: { if(trans->value() < 0.0) xml.writeAttribute("type", "refund"); else xml.writeAttribute("type", "expense"); break; } case TRANSACTION_TYPE_SECURITY_BUY: { xml.writeAttribute("type", "security_buy"); break; } case TRANSACTION_TYPE_SECURITY_SELL: { xml.writeAttribute("type", "security_sell"); break; } } trans->save(&xml); xml.writeEndElement(); } } xml.writeEndElement(); if(ofile.error() != QFile::NoError) { ofile.cancelWriting(); return tr("Error while writing file; file was not saved"); } if(!ofile.commit()) { return tr("Error while writing file; file was not saved"); } return QString(); } void Budget::addTransactions(Transactions *trans) { switch(trans->generaltype()) { case GENERAL_TRANSACTION_TYPE_SINGLE: {addTransaction((Transaction*) trans); break;} case GENERAL_TRANSACTION_TYPE_SPLIT: {addSplitTransaction((SplitTransaction*) trans); break;} case GENERAL_TRANSACTION_TYPE_SCHEDULE: {addScheduledTransaction((ScheduledTransaction*) trans); break;} } } void Budget::removeTransactions(Transactions *trans, bool keep) { switch(trans->generaltype()) { case GENERAL_TRANSACTION_TYPE_SINGLE: {removeTransaction((Transaction*) trans, keep); break;} case GENERAL_TRANSACTION_TYPE_SPLIT: {removeSplitTransaction((SplitTransaction*) trans, keep); break;} case GENERAL_TRANSACTION_TYPE_SCHEDULE: {removeScheduledTransaction((ScheduledTransaction*) trans, keep); break;} } } void Budget::addTransaction(Transaction *trans) { if(trans->id() == 0) trans->setId(getNewId()); if(trans->firstRevision() == 0) trans->setFirstRevision(i_revision); if(trans->lastRevision() == 0) trans->setLastRevision(i_revision); switch(trans->type()) { case TRANSACTION_TYPE_EXPENSE: {expenses.inSort((Expense*) trans); break;} case TRANSACTION_TYPE_INCOME: { incomes.inSort((Income*) trans); if(((Income*) trans)->security()) { if(trans->subtype() == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND) ((Income*) trans)->security()->reinvestedDividends.inSort((ReinvestedDividend*) trans); else ((Income*) trans)->security()->dividends.inSort((Income*) trans); } break; } case TRANSACTION_TYPE_TRANSFER: {transfers.inSort((Transfer*) trans); break;} case TRANSACTION_TYPE_SECURITY_BUY: {} case TRANSACTION_TYPE_SECURITY_SELL: { SecurityTransaction *sectrans = (SecurityTransaction*) trans; securityTransactions.inSort(sectrans); sectrans->security()->transactions.inSort(sectrans); //if(sectrans->shareValue() > 0.0) sectrans->security()->setQuotation(sectrans->date(), sectrans->shareValue(), true); break; } } transactions.inSort(trans); } void Budget::removeTransaction(Transaction *trans, bool keep) { if(trans->parentSplit()) { trans->parentSplit()->removeTransaction(trans, keep); return; } transactions.removeRef(trans); switch(trans->type()) { case TRANSACTION_TYPE_EXPENSE: { expenses.setAutoDelete(false); expenses.removeRef((Expense*) trans); expenses.setAutoDelete(true); if(!keep) delete trans; break; } case TRANSACTION_TYPE_INCOME: { incomes.setAutoDelete(false); if(((Income*) trans)->security()) { if(trans->subtype() == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND) ((Income*) trans)->security()->reinvestedDividends.removeRef((ReinvestedDividend*) trans); else ((Income*) trans)->security()->dividends.removeRef((Income*) trans); } incomes.removeRef((Income*) trans); incomes.setAutoDelete(true); if(!keep) delete trans; break; } case TRANSACTION_TYPE_TRANSFER: { transfers.setAutoDelete(false); transfers.removeRef((Transfer*) trans); transfers.setAutoDelete(true); if(!keep) delete trans; break; } case TRANSACTION_TYPE_SECURITY_BUY: {} case TRANSACTION_TYPE_SECURITY_SELL: { SecurityTransaction *sectrans = (SecurityTransaction*) trans; sectrans->security()->removeQuotation(sectrans->date(), true); securityTransactions.setAutoDelete(false); sectrans->security()->transactions.removeRef(sectrans); securityTransactions.removeRef(sectrans); securityTransactions.setAutoDelete(true); if(!keep) delete trans; break; } } } void Budget::addSplitTransaction(SplitTransaction *split) { if(split->id() == 0) split->setId(getNewId()); if(split->firstRevision() == 0) split->setFirstRevision(i_revision); if(split->lastRevision() == 0) split->setLastRevision(i_revision); splitTransactions.inSort(split); int c = split->count(); for(int i = 0; i < c; i++) { addTransaction(split->at(i)); } } void Budget::removeSplitTransaction(SplitTransaction *split, bool keep) { int c = split->count(); for(int i = 0; i < c; i++) { Transaction *trans = split->at(i); transactions.removeRef(trans); switch(trans->type()) { case TRANSACTION_TYPE_EXPENSE: { expenses.setAutoDelete(false); expenses.removeRef((Expense*) trans); expenses.setAutoDelete(true); break; } case TRANSACTION_TYPE_INCOME: { incomes.setAutoDelete(false); incomes.removeRef((Income*) trans); if(trans->subtype() == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND) ((Income*) trans)->security()->reinvestedDividends.removeRef((ReinvestedDividend*) trans); else if(((Income*) trans)->security()) ((Income*) trans)->security()->dividends.removeRef((Income*) trans); incomes.setAutoDelete(true); break; } case TRANSACTION_TYPE_TRANSFER: { transfers.setAutoDelete(false); transfers.removeRef((Transfer*) trans); transfers.setAutoDelete(true); break; } case TRANSACTION_TYPE_SECURITY_BUY: {} case TRANSACTION_TYPE_SECURITY_SELL: { SecurityTransaction *sectrans = (SecurityTransaction*) trans; sectrans->security()->removeQuotation(sectrans->date(), true); securityTransactions.setAutoDelete(false); sectrans->security()->transactions.removeRef(sectrans); securityTransactions.removeRef(sectrans); securityTransactions.setAutoDelete(true); break; } } } if(keep) splitTransactions.setAutoDelete(false); splitTransactions.removeRef(split); if(keep) splitTransactions.setAutoDelete(true); } void Budget::addScheduledTransaction(ScheduledTransaction *strans) { if(strans->id() == 0) strans->setId(getNewId()); if(strans->firstRevision() == 0) strans->setFirstRevision(i_revision); if(strans->lastRevision() == 0) strans->setLastRevision(i_revision); scheduledTransactions.inSort(strans); if(strans->transactiontype() == TRANSACTION_TYPE_SECURITY_BUY || strans->transactiontype() == TRANSACTION_TYPE_SECURITY_SELL) { ((SecurityTransaction*) strans->transaction())->security()->scheduledTransactions.inSort(strans); } else if(strans->transactiontype() == TRANSACTION_TYPE_INCOME && ((Income*) strans->transaction())->security()) { if(strans->transactionsubtype() == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND) ((Income*) strans->transaction())->security()->scheduledReinvestedDividends.inSort(strans); else ((Income*) strans->transaction())->security()->scheduledDividends.inSort(strans); } } void Budget::removeScheduledTransaction(ScheduledTransaction *strans, bool keep) { if(strans->transactiontype() == TRANSACTION_TYPE_SECURITY_BUY || strans->transactiontype() == TRANSACTION_TYPE_SECURITY_SELL) { ((SecurityTransaction*) strans->transaction())->security()->scheduledTransactions.removeRef(strans); } else if(strans->transactiontype() == TRANSACTION_TYPE_INCOME && ((Income*) strans->transaction())->security()) { if(strans->transactionsubtype() == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND) ((Income*) strans->transaction())->security()->scheduledReinvestedDividends.removeRef(strans); else ((Income*) strans->transaction())->security()->scheduledDividends.removeRef(strans); } if(keep) scheduledTransactions.setAutoDelete(false); scheduledTransactions.removeRef(strans); if(keep) scheduledTransactions.setAutoDelete(true); } void Budget::addAccount(Account *account) { if(account->id() == 0) account->setId(getNewId()); if(account->firstRevision() == 0) account->setFirstRevision(i_revision); if(account->lastRevision() == 0) account->setLastRevision(i_revision); switch(account->type()) { case ACCOUNT_TYPE_EXPENSES: {expensesAccounts.inSort((ExpensesAccount*) account); break;} case ACCOUNT_TYPE_INCOMES: {incomesAccounts.inSort((IncomesAccount*) account); break;} case ACCOUNT_TYPE_ASSETS: {assetsAccounts.inSort((AssetsAccount*) account); break;} } accounts.inSort(account); if(b_record_new_accounts) newAccounts << account; } void Budget::setRecordNewAccounts(bool rna) {b_record_new_accounts = rna;} void Budget::accountModified(Account *account) { switch(account->type()) { case ACCOUNT_TYPE_EXPENSES: {expensesAccounts.sort(); break;} case ACCOUNT_TYPE_INCOMES: {incomesAccounts.sort(); break;} case ACCOUNT_TYPE_ASSETS: {assetsAccounts.sort(); break;} } accounts.sort(); } void Budget::removeAccount(Account *account, bool keep) { if(account->type() == ACCOUNT_TYPE_INCOMES || account->type() == ACCOUNT_TYPE_EXPENSES) { for(AccountList::const_iterator it = ((CategoryAccount*) account)->subCategories.constBegin(); it != ((CategoryAccount*) account)->subCategories.constEnd(); ++it) { CategoryAccount *subcat = *it; if(!keep) subcat->o_parent = NULL; removeAccount(subcat, keep); } if(!keep) ((CategoryAccount*) account)->subCategories.clear(); } if(accountHasTransactions(account, false)) { for(int i = 0; i < securities.size(); ++i) { Security *security = securities.at(i); if(security->account() == account) { removeSecurity(security); --i; } } for(int i = 0; i < splitTransactions.size(); ++i) { SplitTransaction *split = splitTransactions.at(i); if(split->relatesToAccount(account, true, true)) { removeSplitTransaction(split); --i; } } for(int i = 0; i < transactions.size(); ++i) { Transaction *trans = transactions.at(i); if(trans->relatesToAccount(account, true, true)) { removeTransaction(trans); --i; } } for(int i = 0; i < scheduledTransactions.size(); ++i) { ScheduledTransaction *strans = scheduledTransactions.at(i); if(strans->relatesToAccount(account, true, true)) { removeScheduledTransaction(strans); --i; } } } accounts.removeRef(account); switch(account->type()) { case ACCOUNT_TYPE_EXPENSES: { if(keep) expensesAccounts.setAutoDelete(false); expensesAccounts.removeRef((ExpensesAccount*) account); if(keep) expensesAccounts.setAutoDelete(true); break; } case ACCOUNT_TYPE_INCOMES: { if(keep) incomesAccounts.setAutoDelete(false); incomesAccounts.removeRef((IncomesAccount*) account); if(keep) incomesAccounts.setAutoDelete(true); break; } case ACCOUNT_TYPE_ASSETS: { if(keep) assetsAccounts.setAutoDelete(false); assetsAccounts.removeRef((AssetsAccount*) account); if(keep) assetsAccounts.setAutoDelete(true); break; } } } bool Budget::accountHasTransactions(Account *account, bool check_subs) { for(SecurityList::const_iterator it = securities.constBegin(); it != securities.constEnd(); ++it) { Security *security = *it; if(security->account() == account) return true; } for(SplitTransactionList::const_iterator it = splitTransactions.constBegin(); it != splitTransactions.constEnd(); ++it) { SplitTransaction *split = *it; if(split->relatesToAccount(account, true, true)) return true; } for(TransactionList::const_iterator it = transactions.constBegin(); it != transactions.constEnd(); ++it) { Transaction *trans = *it; if(trans->relatesToAccount(account, true, true)) return true; } for(ScheduledTransactionList::const_iterator it = scheduledTransactions.constBegin(); it != scheduledTransactions.constEnd(); ++it) { ScheduledTransaction *strans = *it; if(strans->relatesToAccount(account, true, true)) return true; } if(check_subs && (account->type() == ACCOUNT_TYPE_INCOMES || account->type() == ACCOUNT_TYPE_EXPENSES)) { for(AccountList::const_iterator it = ((CategoryAccount*) account)->subCategories.constBegin(); it != ((CategoryAccount*) account)->subCategories.constEnd(); ++it) { CategoryAccount *subcat = *it; if(accountHasTransactions(subcat, true)) return true; } } return false; } void Budget::moveTransactions(Account *account, Account *new_account, bool move_from_subs) { if(move_from_subs && (account->type() == ACCOUNT_TYPE_INCOMES || account->type() == ACCOUNT_TYPE_EXPENSES)) { for(AccountList::const_iterator it = ((CategoryAccount*) account)->subCategories.constBegin(); it != ((CategoryAccount*) account)->subCategories.constEnd(); ++it) { CategoryAccount *subcat = *it; moveTransactions(subcat, new_account); } } if(account->type() == ACCOUNT_TYPE_ASSETS && new_account->type() == ACCOUNT_TYPE_ASSETS) { for(SecurityList::const_iterator it = securities.constBegin(); it != securities.constEnd(); ++it) { Security *security = *it; if(security->account() == account) security->setAccount((AssetsAccount*) new_account); } } for(SplitTransactionList::const_iterator it = splitTransactions.constBegin(); it != splitTransactions.constEnd(); ++it) { SplitTransaction *split = *it; split->replaceAccount(account, new_account); } for(TransactionList::const_iterator it = transactions.constBegin(); it != transactions.constEnd(); ++it) { Transaction *trans = *it; trans->replaceAccount(account, new_account); } for(ScheduledTransactionList::const_iterator it = scheduledTransactions.constBegin(); it != scheduledTransactions.constEnd(); ++it) { ScheduledTransaction *strans = *it; strans->replaceAccount(account, new_account); } } void Budget::transactionsSortModified(Transactions *trans) { switch(trans->generaltype()) { case GENERAL_TRANSACTION_TYPE_SINGLE: {transactionSortModified((Transaction*) trans); break;} case GENERAL_TRANSACTION_TYPE_SPLIT: {splitTransactionSortModified((SplitTransaction*) trans); break;} case GENERAL_TRANSACTION_TYPE_SCHEDULE: {scheduledTransactionSortModified((ScheduledTransaction*) trans); break;} } } void Budget::transactionSortModified(Transaction *t) { if(transactions.removeRef(t)) transactions.inSort(t); switch(t->type()) { case TRANSACTION_TYPE_EXPENSE: { Expense *e = (Expense*) t; expenses.setAutoDelete(false); if(expenses.removeRef(e)) expenses.inSort(e); expenses.setAutoDelete(true); break; } case TRANSACTION_TYPE_INCOME: { Income *i = (Income*) t; if(i->security()) { if(i->subtype() == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND && i->security()->reinvestedDividends.removeRef((ReinvestedDividend*) i)) i->security()->reinvestedDividends.inSort((ReinvestedDividend*) i); else if(i->security()->dividends.removeRef(i)) i->security()->dividends.inSort(i); } incomes.setAutoDelete(false); if(incomes.removeRef(i)) incomes.inSort(i); incomes.setAutoDelete(true); break; } case TRANSACTION_TYPE_TRANSFER: { Transfer *tr = (Transfer*) t; transfers.setAutoDelete(false); if(transfers.removeRef(tr)) transfers.inSort(tr); transfers.setAutoDelete(true); break; } case TRANSACTION_TYPE_SECURITY_BUY: {} case TRANSACTION_TYPE_SECURITY_SELL: { SecurityTransaction *tr = (SecurityTransaction*) t; if(tr->security()->transactions.removeRef(tr)) tr->security()->transactions.inSort(tr); securityTransactions.setAutoDelete(false); if(securityTransactions.removeRef(tr)) securityTransactions.inSort(tr); securityTransactions.setAutoDelete(true); break; } } } void Budget::transactionDateModified(Transaction*, const QDate&) { /* switch(t->type()) { case TRANSACTION_TYPE_SECURITY_BUY: {} case TRANSACTION_TYPE_SECURITY_SELL: { SecurityTransaction *tr = (SecurityTransaction*) t; if(tr->shareValue() > 0.0) { tr->security()->removeQuotation(olddate, true); tr->security()->setQuotation(tr->date(), tr->shareValue(), true); } break; } default: { break; } }*/ } void Budget::scheduledTransactionDateModified(ScheduledTransaction*) { } void Budget::scheduledTransactionSortModified(ScheduledTransaction *strans) { if(strans->transactiontype() == TRANSACTION_TYPE_SECURITY_BUY || strans->transactiontype() == TRANSACTION_TYPE_SECURITY_SELL) { if(((SecurityTransaction*) strans->transaction())->security()->scheduledTransactions.removeRef(strans)) ((SecurityTransaction*) strans->transaction())->security()->scheduledTransactions.inSort(strans); } else if(strans->transactiontype() == TRANSACTION_TYPE_INCOME && ((Income*) strans->transaction())->security()) { if(strans->transactionsubtype() == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND && ((Income*) strans->transaction())->security()->scheduledReinvestedDividends.removeRef(strans)) ((Income*) strans->transaction())->security()->scheduledReinvestedDividends.inSort(strans); if(((Income*) strans->transaction())->security()->scheduledDividends.removeRef(strans)) ((Income*) strans->transaction())->security()->scheduledDividends.inSort(strans); } scheduledTransactions.setAutoDelete(false); if(scheduledTransactions.removeRef(strans)) scheduledTransactions.inSort(strans); scheduledTransactions.setAutoDelete(true); } void Budget::splitTransactionSortModified(SplitTransaction *split) { splitTransactions.setAutoDelete(false); if(splitTransactions.removeRef(split)) splitTransactions.inSort(split); splitTransactions.setAutoDelete(true); } void Budget::splitTransactionDateModified(SplitTransaction*, const QDate&) {} Transaction *Budget::findDuplicateTransaction(Transaction *trans) { TransactionList::const_iterator it = std::lower_bound(transactions.constBegin(), transactions.constEnd(), trans, transaction_list_less_than); while(it != transactions.constEnd()) { if((*it)->date() > trans->date()) return NULL; if(trans->equals(*it, false)) return *it; ++it; } return NULL; } void Budget::accountNameModified(Account *account) { if(accounts.removeRef(account)) accounts.inSort(account); switch(account->type()) { case ACCOUNT_TYPE_EXPENSES: { ExpensesAccount *eaccount = (ExpensesAccount*) account; expensesAccounts.setAutoDelete(false); if(expensesAccounts.removeRef(eaccount)) expensesAccounts.inSort(eaccount); expensesAccounts.setAutoDelete(true); break; } case ACCOUNT_TYPE_INCOMES: { IncomesAccount *iaccount = (IncomesAccount*) account; incomesAccounts.setAutoDelete(false); if(incomesAccounts.removeRef(iaccount)) incomesAccounts.inSort(iaccount); incomesAccounts.setAutoDelete(true); break; } case ACCOUNT_TYPE_ASSETS: { AssetsAccount *aaccount = (AssetsAccount*) account; assetsAccounts.setAutoDelete(false); if(assetsAccounts.removeRef(aaccount)) assetsAccounts.inSort(aaccount); assetsAccounts.setAutoDelete(true); break; } } } void Budget::addSecurity(Security *security) { if(security->id() == 0) security->setId(getNewId()); if(security->firstRevision() == 0) security->setFirstRevision(i_revision); if(security->lastRevision() == 0) security->setLastRevision(i_revision); securities.inSort(security); i_quotation_decimals = security->quotationDecimals(); i_share_decimals = security->decimals(); if(b_record_new_securities) newSecurities << security; } void Budget::setRecordNewSecurities(bool rns) {b_record_new_securities = rns;} void Budget::removeSecurity(Security *security, bool keep) { if(securityHasTransactions(security)) { for(SecurityTransactionList::const_iterator it = security->transactions.constBegin(); it != security->transactions.constEnd(); ++it) { SecurityTransaction *trans = *it; transactions.removeRef(trans); securityTransactions.removeRef(trans); } for(SecurityTransactionList::const_iterator it = security->dividends.constBegin(); it != security->dividends.constEnd(); ++it) { Income *i = *it; transactions.removeRef(i); incomes.removeRef(i); } for(SecurityTransactionList::const_iterator it = security->reinvestedDividends.constBegin(); it != security->reinvestedDividends.constEnd(); ++it) { Income *i = *it; transactions.removeRef(i); incomes.removeRef(i); } for(ScheduledSecurityTransactionList::const_iterator it = security->scheduledTransactions.constBegin(); it != security->scheduledTransactions.constEnd(); ++it) { ScheduledTransaction *strans = *it; scheduledTransactions.removeRef(strans); } for(ScheduledSecurityTransactionList::const_iterator it = security->scheduledDividends.constBegin(); it != security->scheduledDividends.constEnd(); ++it) { ScheduledTransaction *strans = *it; scheduledTransactions.removeRef(strans); } for(ScheduledSecurityTransactionList::const_iterator it = security->scheduledReinvestedDividends.constBegin(); it != security->scheduledReinvestedDividends.constEnd(); ++it) { ScheduledTransaction *strans = *it; scheduledTransactions.removeRef(strans); } for(TradedSharesList::const_iterator it = security->tradedShares.constBegin(); it != security->tradedShares.constEnd(); ++it) { SecurityTrade *ts = *it; if(ts->to_security == security) ts->from_security->tradedShares.removeRef(ts); else ts->to_security->tradedShares.removeRef(ts); securityTrades.removeRef(ts); } } if(keep) securities.setAutoDelete(false); securities.removeRef(security); if(keep) securities.setAutoDelete(true); } bool Budget::securityHasTransactions(Security *security) { return security->reinvestedDividends.count() > 0 || security->scheduledReinvestedDividends.count() > 0 || security->tradedShares.count() > 0 || security->transactions.count() > 0 || security->dividends.count() > 0 || security->scheduledTransactions.count() > 0 || security->scheduledDividends.count() > 0; } void Budget::securityNameModified(Security *security) { securities.setAutoDelete(false); if(securities.removeRef(security)) { securities.inSort(security); } securities.setAutoDelete(true); } Security *Budget::findSecurity(QString name) { for(SecurityList::const_iterator it = securities.constBegin(); it != securities.constEnd(); ++it) { Security *sec = *it; if(sec->name() == name) return sec; } return NULL; } int Budget::defaultShareDecimals() const {return i_share_decimals;} int Budget::defaultQuotationDecimals() const {return i_quotation_decimals;} void Budget::setDefaultShareDecimals(int new_decimals) {i_share_decimals = new_decimals;} void Budget::setDefaultQuotationDecimals(int new_decimals) {i_quotation_decimals = new_decimals;} void Budget::addSecurityTrade(SecurityTrade *ts) { if(ts->id == 0) ts->id = getNewId(); if(ts->first_revision == 0) ts->first_revision = i_revision; if(ts->last_revision == 0) ts->last_revision = i_revision; securityTrades.inSort(ts); ts->from_security->tradedShares.inSort(ts); ts->to_security->tradedShares.inSort(ts); } void Budget::removeSecurityTrade(SecurityTrade *ts, bool keep) { ts->from_security->tradedShares.removeRef(ts); ts->to_security->tradedShares.removeRef(ts); ts->from_security->removeQuotation(ts->date, true); ts->to_security->removeQuotation(ts->date, true); if(keep) securityTrades.setAutoDelete(false); securityTrades.removeRef(ts); if(keep) securityTrades.setAutoDelete(true); } void Budget::securityTradeDateModified(SecurityTrade *ts, const QDate &olddate) { securityTrades.setAutoDelete(false); if(securityTrades.removeRef(ts)) { securityTrades.inSort(ts); } securityTrades.setAutoDelete(true); if(ts->from_security->tradedShares.removeRef(ts)) { ts->from_security->tradedShares.inSort(ts); } if(ts->to_security->tradedShares.removeRef(ts)) { ts->to_security->tradedShares.inSort(ts); } ts->from_security->removeQuotation(olddate, true); ts->to_security->removeQuotation(olddate, true); } Account *Budget::findAccount(QString name) { for(AccountList::const_iterator it = accounts.constBegin(); it != accounts.constEnd(); ++it) { Account *account = *it; if(account->name() == name) return account; } return NULL; } AssetsAccount *Budget::findAssetsAccount(QString name) { for(AccountList::const_iterator it = assetsAccounts.constBegin(); it != assetsAccounts.constEnd(); ++it) { AssetsAccount *account = *it; if(account->name() == name) return account; } return NULL; } IncomesAccount *Budget::findIncomesAccount(QString name) { for(AccountList::const_iterator it = incomesAccounts.constBegin(); it != incomesAccounts.constEnd(); ++it) { IncomesAccount *account = *it; if(account->name() == name) return account; } return NULL; } ExpensesAccount *Budget::findExpensesAccount(QString name) { for(AccountList::const_iterator it = expensesAccounts.constBegin(); it != expensesAccounts.constEnd(); ++it) { ExpensesAccount *account = *it; if(account->name() == name) return account; } return NULL; } IncomesAccount *Budget::findIncomesAccount(QString name, CategoryAccount *parent_acc) { for(AccountList::const_iterator it = incomesAccounts.constBegin(); it != incomesAccounts.constEnd(); ++it) { IncomesAccount *account = *it; if(account->name() == name && account->parentCategory() == parent_acc) return account; } return NULL; } ExpensesAccount *Budget::findExpensesAccount(QString name, CategoryAccount *parent_acc) { for(AccountList::const_iterator it = expensesAccounts.constBegin(); it != expensesAccounts.constEnd(); ++it) { ExpensesAccount *account = *it; if(account->name() == name && account->parentCategory() == parent_acc) return account; } return NULL; } Currency *Budget::defaultCurrency() { return default_currency; } void Budget::setDefaultCurrency(Currency *cur) { Currency *prev_default = default_currency; if(!cur) default_currency = currency_euro; else default_currency = cur; if(prev_default != default_currency) b_default_currency_changed = true; } bool Budget::resetDefaultCurrency() { Currency *prev_default = default_currency; QString default_code = QLocale().currencySymbol(QLocale::CurrencyIsoCode); if(default_code.isEmpty()) default_code = "USD"; default_currency = findCurrency(default_code); if(!default_currency) { default_currency = new Currency(this, default_code, QLocale().currencySymbol(QLocale::CurrencySymbol), QLocale().currencySymbol(QLocale::CurrencyDisplayName)); b_default_currency_changed = true; addCurrency(default_currency); return true; } if(prev_default != default_currency) b_default_currency_changed = true; return false; } bool Budget::defaultCurrencyChanged() {return b_default_currency_changed;} void Budget::resetDefaultCurrencyChanged() {b_default_currency_changed = false;} bool Budget::currenciesModified() {return b_currency_modified;} void Budget::resetCurrenciesModified() {b_currency_modified = false;} void Budget::addCurrency(Currency *cur) { currencies.inSort(cur); } void Budget::currencyModified(Currency*) { b_currency_modified = true; } void Budget::removeCurrency(Currency *cur) { currencies.removeRef(cur); } Currency *Budget::findCurrency(QString code) { for(CurrencyList::const_iterator it = currencies.constBegin(); it != currencies.constEnd(); ++it) { Currency *cur = *it; if(cur->code() == code) return cur; } return NULL; } Currency *Budget::findCurrencySymbol(QString symbol, bool require_unique) { Currency *found_cur = NULL; bool found_multiple = false; for(CurrencyList::const_iterator it = currencies.constBegin(); it != currencies.constEnd(); ++it) { Currency *cur = *it; if(cur->symbol(false) == symbol) { if(!require_unique || cur == defaultCurrency() || (defaultCurrency()->symbol(false) != symbol && (cur->code() == QLocale().currencySymbol(QLocale::CurrencyIsoCode) || (symbol != QLocale().currencySymbol(QLocale::CurrencySymbol) && (cur->code() == "USD" || cur->code() == "GBP" || cur->code() == "EUR" || cur->code() == "JPY"))))) return cur; else if(found_cur) found_multiple = true; else found_cur = cur; } } if(found_multiple) return NULL; return found_cur; } bool Budget::usesMultipleCurrencies() { for(AccountList::const_iterator it = assetsAccounts.constBegin(); it != assetsAccounts.constEnd(); ++it) { AssetsAccount *acc = *it; if(acc->currency() != NULL && acc->currency() != default_currency) { return true; } } return false; } void Budget::setBudgetDay(int day_of_month) {if(day_of_month <= 28 && day_of_month >= -26) i_budget_day = day_of_month;} int Budget::budgetDay() const {return i_budget_day;} void Budget::setBudgetMonth(int month_of_year) {if(month_of_year <= 12 && month_of_year >= 1) i_budget_month = month_of_year;} int Budget::budgetMonth() const {return i_budget_month;} bool isLeapYear(long int year) { return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); } int daysPerYear(long int year, int basis = 1) { switch(basis) { case 0: { return 360; } case 1: { if(isLeapYear(year)) { return 366; } else { return 365; } } case 2: { return 360; } case 3: { return 365; } case 4: { return 360; } } return -1; } int daysPerMonth(int month, long int year) { switch(month) { case 1: {} case 3: {} case 5: {} case 7: {} case 8: {} case 10: {} case 12: { return 31; } case 2: { if(isLeapYear(year)) return 29; else return 28; } default: { return 30; } } } bool Budget::isSameBudgetMonth(const QDate &date1, const QDate &date2) const { return budgetYear(date1) == budgetYear(date2) && budgetMonth(date1) == budgetMonth(date2); } int Budget::daysInBudgetMonth(const QDate &date) const { if(i_budget_day == 1) { return date.daysInMonth(); } else if(i_budget_day > 0) { if(date.day() >= i_budget_day) return date.daysInMonth(); return date.addMonths(-1).daysInMonth(); } else { return firstBudgetDay(date).daysTo(lastBudgetDay(date)) + 1; } } int Budget::daysInBudgetYear(const QDate &date) const { if(i_budget_day == 1 && i_budget_month == 1) return date.daysInYear(); int i_year = budgetYear(date); if(i_budget_month > 3 || (i_budget_month == 3 && (i_budget_day <= 15 || i_budget_day >= 29) && (i_budget_day >= 0 || i_budget_day < -15))) i_year++; return daysPerYear(i_year); } int Budget::dayOfBudgetYear(const QDate &date) const { if(i_budget_day == 1 && i_budget_month == 1) return date.dayOfYear(); return firstBudgetDayOfYear(date).daysTo(date) + 1; } int Budget::dayOfBudgetMonth(const QDate &date) const { if(i_budget_day == 1) return date.day(); return firstBudgetDay(date).daysTo(date) + 1; } int Budget::budgetMonth(const QDate &date) const { int i_month = 1; if(i_budget_day == 1) { i_month = date.month(); } else { int ibd = i_budget_day; if(i_budget_day <= 0) ibd = date.daysInMonth() + i_budget_day; if(i_budget_day > 15 || (i_budget_day < 1 && i_budget_day >= -15)) { if(date.day() < ibd) i_month = date.month(); else if(date.month() == 12) i_month = 1; else i_month = date.month() + 1; } else { if(date.day() >= ibd) i_month = date.month(); else if(date.month() == 1) i_month = 12; else i_month = date.month() - 1; } } return i_month; } int Budget::budgetYear(const QDate &date) const { if(i_budget_day == 1 && i_budget_month == 1) return date.year(); int ibd = i_budget_day; int year = date.year(); if(i_budget_day <= 0) ibd = daysPerMonth(i_budget_month == 1 ? 12 : i_budget_month - 1, year) + i_budget_day; if(i_budget_month > 1 && date.month() < i_budget_month) year--; if(i_budget_day > 15 || (i_budget_day < 1 && i_budget_day >= -15)) { if(date.month() == (i_budget_month == 1 ? 12 : i_budget_month - 1) && date.day() >= ibd) year++; } else { if(date.month() == i_budget_month && date.day() < ibd) year--; } return year; } QString Budget::budgetYearString(const QDate &date, bool short_format) const { return budgetYearString(budgetYear(date), short_format); } QString Budget::budgetYearString(int year, bool short_format) const { if(i_budget_month == 1) return QString::number(year); //: Financial year when first month is not January (e.g. 2018-19). QString str = tr("yyyy-yy"); int y1 = -1, y2 = -1, y3 = -1; y1 = str.indexOf("yyyy"); if(y1 >= 0) y2 = str.indexOf("yyyy", y1 + 4); if(y2 <= 0) y3 = str.indexOf("yy", y1 >= 0 ? y2 + 4 : 0); if(y1 < 0 && y3 < 0) return str; if(y1 < 0) { str.replace(y3, 2, year % 100 <= 9 ? QString("0") + QString::number(year % 100) : QString::number(year % 100)); str.replace("yy", year % 100 < 9 ? QString("0") + QString::number((year + 1) % 100) : QString::number((year + 1) % 100)); } else if(y3 < 0) { str.replace(y1, 4, short_format ? (year % 100 <= 9 ? QString("0") + QString::number((year) % 100) : QString::number((year) % 100)) : QString::number(year)); str.replace("yyyy", short_format ? (year % 100 < 9 ? QString("0") + QString::number((year + 1) % 100) : QString::number((year + 1) % 100)) : QString::number(year + 1)); } else if(y3 < y1) { str.replace(y3, 2, year % 100 <= 9 ? QString("0") + QString::number(year % 100) : QString::number(year % 100)); str.replace("yyyy", short_format ? (year % 100 < 9 ? QString("0") + QString::number((year + 1) % 100) : QString::number((year + 1) % 100)) : QString::number(year + 1)); } else { str.replace(y1, 4, short_format ? (year % 100 <= 9 ? QString("0") + QString::number((year) % 100) : QString::number((year) % 100)) : QString::number(year)); str.replace("yy", (short_format && year % 100 == 99) ? QString::number(year + 1) : (year % 100 < 9 ? QString("0") + QString::number((year + 1) % 100) : QString::number((year + 1) % 100))); } return str; } QDate Budget::firstBudgetDayOfYear(QDate date) const { if(i_budget_month == 1 && i_budget_day == 1) return QDate(date.year(), 1, 1); int i_year = budgetYear(date); if(i_budget_month == 1 && (i_budget_day > 15 || (i_budget_day < 1 && i_budget_day >= -15))) i_year--; int ibd = i_budget_day; if(i_budget_day <= 0) ibd = daysPerMonth(i_budget_month == 1 ? 12 : i_budget_month - 1, i_year) + i_budget_day; return QDate(i_year, ibd > 15 ? (i_budget_month == 1 ? 12 : i_budget_month - 1) : i_budget_month, ibd); } QDate Budget::lastBudgetDayOfYear(QDate date) const { if(i_budget_month == 1 && i_budget_day == 1) return QDate(date.year(), 12, 31); int i_year = budgetYear(date); if(i_budget_month == 1 && (i_budget_day > 15 || (i_budget_day < 1 && i_budget_day >= -15))) i_year--; int ibd = i_budget_day; if(i_budget_day <= 0) ibd = daysPerMonth(i_budget_month == 1 ? 12 : i_budget_month - 1, i_year + 1) + i_budget_day; return QDate(i_year + 1, ibd > 15 ? (i_budget_month == 1 ? 12 : i_budget_month - 1) : i_budget_month, ibd).addDays(-1); } bool Budget::isFirstBudgetDay(const QDate &date) const { return ((i_budget_day > 0 && date.day() == i_budget_day) || (i_budget_day <= 0 && date.day() == date.daysInMonth() + i_budget_day)); } bool Budget::isLastBudgetDay(const QDate &date) const { return ((i_budget_day == 1 && date.day() == date.daysInMonth()) || (i_budget_day > 1 && date.day() == i_budget_day - 1) || (i_budget_day <= 0 && date.day() == date.daysInMonth() + i_budget_day - 1)); } void Budget::addBudgetMonthsSetLast(QDate &date, int months) const { if(i_budget_day <= 0) { int dfl = date.daysInMonth() - date.day(); date = date.addMonths(months); if(date.daysInMonth() > dfl) date.setDate(date.year(), date.month(), date.daysInMonth() - dfl); } else { date = date.addMonths(months); } date = lastBudgetDay(date); } void Budget::addBudgetMonthsSetFirst(QDate &date, int months) const { if(i_budget_day <= 0) { int dfl = date.daysInMonth() - date.day(); date = date.addMonths(months); if(date.daysInMonth() > dfl) date.setDate(date.year(), date.month(), date.daysInMonth() - dfl); } else { date = date.addMonths(months); } date = firstBudgetDay(date); } QDate Budget::budgetDateToMonth(QDate date) const { if(i_budget_day == 1 && i_budget_month == 1) return date; int ibd = i_budget_day; int year = date.year(); int month = date.month(); if(i_budget_day <= 0) ibd = daysPerMonth(12, year) + i_budget_day; if(i_budget_day > 15 || (i_budget_day < 1 && i_budget_day >= -15)) { if(date.day() >= ibd) { if(date.month() == 12) {year++; month = 1;} else month++; } } else if(date.day() < ibd) { if(date.month() == 1) {year--; month = 12;} else month--; } date.setDate(year, month, 1); return date; } QDate Budget::firstBudgetDay(QDate date) const { int ibd = i_budget_day; if(i_budget_day < 1) ibd = date.daysInMonth() + i_budget_day; if(date.day() < ibd) { date = date.addMonths(-1); if(i_budget_day < 1) ibd = date.daysInMonth() + i_budget_day; } date.setDate(date.year(), date.month(), ibd); return date; } QDate Budget::lastBudgetDay(QDate date) const { int ibd = i_budget_day; if(i_budget_day < 1) ibd = date.daysInMonth() + i_budget_day; if(ibd == 1) { date.setDate(date.year(), date.month(), date.daysInMonth()); } else { if(date.day() >= ibd) { date = date.addMonths(1); if(i_budget_day < 1) ibd = date.daysInMonth() + i_budget_day; } date.setDate(date.year(), date.month(), ibd - 1); } return date; } QDate Budget::monthToBudgetMonth(QDate date) const { int ibd = i_budget_day; if(i_budget_day < 1) ibd = date.daysInMonth() + i_budget_day; if(date.day() == ibd) return date; if(date.day() < ibd && (i_budget_day > 15 || (i_budget_day < 1 && i_budget_day >= -15))) { date = date.addMonths(-1); if(i_budget_day < 1) ibd = date.daysInMonth() + i_budget_day; } date.setDate(date.year(), date.month(), ibd); return date; } void Budget::goForwardBudgetMonths(QDate &from_date, QDate &to_date, int months) const { if(isFirstBudgetDay(from_date)) addBudgetMonthsSetFirst(from_date, months); else from_date = from_date.addMonths(months); if((to_date == QDate::currentDate() && isFirstBudgetDay(from_date))) { to_date = lastBudgetDay(to_date); addBudgetMonthsSetLast(to_date, months); } else if(isLastBudgetDay(to_date)) { addBudgetMonthsSetLast(to_date, months); } else if(to_date.day() == to_date.daysInMonth()) { to_date = to_date.addMonths(months); to_date.setDate(to_date.year(), to_date.month(), to_date.daysInMonth()); } else { to_date = to_date.addMonths(months); } } double Budget::averageMonth(const QDate &date1, const QDate &date2, bool use_budget_months) { int saved_i_budget_day = i_budget_day; if(!use_budget_months) i_budget_day = 1; double average_month = (double) daysInBudgetYear(date1) / (double) 12; int years = 1; QDate ydate = firstBudgetDayOfYear(date1); addBudgetMonthsSetFirst(ydate, 12); while(budgetYear(ydate) <= budgetYear(date2)) { average_month += (double) daysInBudgetYear(ydate) / (double) 12; years++; addBudgetMonthsSetFirst(ydate, 12); } i_budget_day = saved_i_budget_day; return average_month / years; } double Budget::averageYear(const QDate &date1, const QDate &date2, bool use_budget_months) { int saved_i_budget_day = i_budget_day; if(!use_budget_months) i_budget_day = 1; double average_year = daysInBudgetYear(date1); int years = 1; QDate ydate = firstBudgetDayOfYear(date1); addBudgetMonthsSetFirst(ydate, 12); while(budgetYear(ydate) <= budgetYear(date2)) { average_year += daysInBudgetYear(ydate); years++; addBudgetMonthsSetFirst(ydate, 12); } i_budget_day = saved_i_budget_day; return average_year / years; } double Budget::yearsBetweenDates(const QDate &date1, const QDate &date2, bool use_budget_months) { int saved_i_budget_day = i_budget_day; if(!use_budget_months) i_budget_day = 1; double years = 0.0; if(budgetYear(date1) == budgetYear(date2)) { int days = date1.daysTo(date2) + 1; years = (double) days / (double) daysInBudgetYear(date2); } else { years += (1.0 - (dayOfBudgetYear(date1) - 1.0) / (double) daysInBudgetYear(date1)); years += budgetYear(date2) - (budgetYear(date1) + 1); years += (double) dayOfBudgetYear(date2) / (double) daysInBudgetYear(date2); } i_budget_day = saved_i_budget_day; return years; } double Budget::monthsBetweenDates(const QDate &date1, const QDate &date2, bool use_budget_months) { int saved_i_budget_day = i_budget_day; if(!use_budget_months) i_budget_day = 1; double months = 0.0; if(budgetYear(date1) == budgetYear(date2)) { if(budgetMonth(date1) == budgetMonth(date2)) { int days = date1.daysTo(date2) + 1; months = (double) days / (double) daysInBudgetMonth(date2); } else { months += (1.0 - ((dayOfBudgetMonth(date1) - 1.0) / (double) daysInBudgetMonth(date1))); months += (budgetMonth(date2) - budgetMonth(date1) - 1); months += (double) dayOfBudgetMonth(date2) / (double) daysInBudgetMonth(date2); } } else { months += (1.0 - ((dayOfBudgetMonth(date1) - 1.0) / (double) daysInBudgetMonth(date1))); months += (12 - budgetMonth(date1)); months += (budgetYear(date2) - (budgetYear(date1) + 1)) * 12; months += (double) dayOfBudgetMonth(date2) / (double) daysInBudgetMonth(date2); months += budgetMonth(date2) - 1; } i_budget_day = saved_i_budget_day; return months; } int Budget::calendarMonthsBetweenDates(const QDate &date1, const QDate &date2, bool use_budget_months) { int saved_i_budget_day = i_budget_day; if(!use_budget_months) i_budget_day = 1; if(budgetYear(date1) == budgetYear(date2)) { return budgetMonth(date2) - budgetMonth(date1); } int months = 12 - budgetMonth(date1); months += (budgetYear(date2) - (budgetYear(date1) + 1)) * 12; months += budgetMonth(date2); i_budget_day = saved_i_budget_day; return months; } int Budget::getAccountType(const QString &type, bool localized, bool plural) { if(plural && localized) { if(type == tr("Transaction Accounts")) { return ASSETS_TYPE_CURRENT; } else if(type == tr("Savings Accounts")) { return ASSETS_TYPE_SAVINGS; } else if(type == tr("Credit Cards")) { return ASSETS_TYPE_CREDIT_CARD; } else if(type == tr("Debts")) { return ASSETS_TYPE_LIABILITIES; } else if(type == tr("Securities", "Financial security (e.g. stock, mutual fund)")) { return ASSETS_TYPE_SECURITIES; } else if(type == tr("Cash")) { return ASSETS_TYPE_CASH; } } else if(localized) { if(type == tr("Transaction Account")) { return ASSETS_TYPE_CURRENT; } else if(type == tr("Savings Account")) { return ASSETS_TYPE_SAVINGS; } else if(type == tr("Credit Card")) { return ASSETS_TYPE_CREDIT_CARD; } else if(type == tr("Debt")) { return ASSETS_TYPE_LIABILITIES; } else if(type == tr("Securities", "Financial security (e.g. stock, mutual fund)")) { return ASSETS_TYPE_SECURITIES; } else if(type == tr("Cash")) { return ASSETS_TYPE_CASH; } } else { if(type == "current") { return ASSETS_TYPE_CURRENT; } else if(type == "savings") { return ASSETS_TYPE_SAVINGS; } else if(type == "credit card") { return ASSETS_TYPE_CREDIT_CARD; } else if(type == "liabilities") { return ASSETS_TYPE_LIABILITIES; } else if(type == "securities") { return ASSETS_TYPE_SECURITIES; } else if(type == "balancing") { return ASSETS_TYPE_BALANCING; } else if(type == "cash") { return ASSETS_TYPE_CASH; } } return ASSETS_TYPE_OTHER; } QString Budget::getAccountTypeName(int at_type, bool localized, bool plural) { if(plural && localized) { switch(at_type) { case ASSETS_TYPE_CASH: return tr("Cash"); case ASSETS_TYPE_CURRENT: return tr("Transaction Accounts"); case ASSETS_TYPE_SAVINGS: return tr("Savings Accounts"); case ASSETS_TYPE_CREDIT_CARD: return tr("Credit Cards"); case ASSETS_TYPE_LIABILITIES: return tr("Debts"); case ASSETS_TYPE_SECURITIES: return tr("Securities", "Financial security (e.g. stock, mutual fund)"); default: return ""; } } else if(localized) { switch(at_type) { case ASSETS_TYPE_CASH: return tr("Cash"); case ASSETS_TYPE_CURRENT: return tr("Transaction Account"); case ASSETS_TYPE_SAVINGS: return tr("Savings Account"); case ASSETS_TYPE_CREDIT_CARD: return tr("Credit Card"); case ASSETS_TYPE_LIABILITIES: return tr("Debt"); case ASSETS_TYPE_SECURITIES: return tr("Securities", "Financial security (e.g. stock, mutual fund)"); default: return tr("Other"); } } else { switch(at_type) { case ASSETS_TYPE_CURRENT: return "current"; case ASSETS_TYPE_SAVINGS: return "savings"; case ASSETS_TYPE_CREDIT_CARD: return "credit card"; case ASSETS_TYPE_LIABILITIES: return "liabilities"; case ASSETS_TYPE_SECURITIES: return "securities"; case ASSETS_TYPE_BALANCING: return "balancing"; case ASSETS_TYPE_CASH: return "cash"; default: return "other"; } } return "other"; } bool Budget::accountTypeIsDebt(int at_type) { return at_type == ASSETS_TYPE_LIABILITIES; } bool Budget::accountTypeIsSecurities(int at_type) { return at_type == ASSETS_TYPE_SECURITIES; } bool Budget::accountTypeIsLiabilities(int at_type) { return at_type == ASSETS_TYPE_LIABILITIES || at_type == ASSETS_TYPE_CREDIT_CARD; } bool Budget::accountTypeIsCreditCard(int at_type) { return at_type == ASSETS_TYPE_CREDIT_CARD; } bool Budget::accountTypeIsOther(int at_type) { return at_type == ASSETS_TYPE_OTHER; } void Budget::tagAdded(const QString &tag) { tags << tag; tags.sort(Qt::CaseInsensitive); if(b_record_new_tags) newTags << tag; } void Budget::tagRemoved(const QString &tag) { tags.removeAll(tag); } QString Budget::findTag(const QString &tag) { for(int i = 0; i < tags.count(); i++) { int c = tags[i].compare(tag, Qt::CaseInsensitive); if(c > 0) break; if(c == 0) return tags[i]; } return QString(); } void Budget::setRecordNewTags(bool rnt) {b_record_new_tags = rnt;} Transactions *Budget::getTransaction(qlonglong lid) { for(TransactionList::const_iterator it = transactions.constBegin(); it != transactions.constEnd(); ++it) { if((*it)->id() == lid) return *it; } for(TransactionList::const_iterator it = splitTransactions.constBegin(); it != splitTransactions.constEnd(); ++it) { if((*it)->id() == lid) return *it; } for(TransactionList::const_iterator it = scheduledTransactions.constBegin(); it != scheduledTransactions.constEnd(); ++it) { if((*it)->id() == lid) return *it; if((*it)->transaction() && (*it)->transaction()->id() == lid) return *it; } return NULL; } Eqonomize-1.5.3/src/budget.h000066400000000000000000000333371416454732000157170ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016-2020 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifndef BUDGET_H #define BUDGET_H #include #include #include #include #include #include #include #include #include #include "eqonomizelist.h" #include "account.h" #include "transaction.h" #include "security.h" #include "currency.h" #define MONETARY_DECIMAL_PLACES 2 #define SAVE_MONETARY_DECIMAL_PLACES 4 #define QUANTITY_DECIMAL_PLACES 2 #define IS_GREGORIAN_CALENDAR true #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) # define XML_COMPARE_CONST_CHAR(x) QLatin1String(x) #else # define XML_COMPARE_CONST_CHAR(x) x #endif class QProcess; class QNetworkReply; typedef enum { TRANSACTION_CONVERSION_RATE_AT_DATE, TRANSACTION_CONVERSION_LATEST_RATE } TransactionConversionRateDate; bool is_zero(double); void read_id(QXmlStreamAttributes *attr, qlonglong &id, int &rev1, int &rev2); void write_id(QXmlStreamAttributes *attr, qlonglong &id, int &rev1, int &rev2); void write_id(QXmlStreamWriter *writer, qlonglong &id, int &rev1, int &rev2); bool transaction_list_less_than(Transaction *t1, Transaction *t2); bool split_list_less_than(SplitTransaction *t1, SplitTransaction *t2); bool schedule_list_less_than(ScheduledTransaction *t1, ScheduledTransaction *t2); bool trade_list_less_than(SecurityTrade *t1, SecurityTrade *t2); bool security_list_less_than(Security *t1, Security *t2); template class TransactionList : public EqonomizeList { public: TransactionList() : EqonomizeList() {}; void sort() { std::sort(QList::begin(), QList::end(), transaction_list_less_than); } void inSort(type value) { QList::insert(std::lower_bound(QList::begin(), QList::end(), value, transaction_list_less_than), value); } }; template class SplitTransactionList : public EqonomizeList { public: SplitTransactionList() : EqonomizeList() {}; void sort() { std::sort(QList::begin(), QList::end(), split_list_less_than); } void inSort(type value) { QList::insert(std::lower_bound(QList::begin(), QList::end(), value, split_list_less_than), value); } }; template class ScheduledTransactionList : public EqonomizeList { public: ScheduledTransactionList() : EqonomizeList() {}; void sort() { std::sort(QList::begin(), QList::end(), schedule_list_less_than); } void inSort(type value) { QList::insert(std::lower_bound(QList::begin(), QList::end(), value, schedule_list_less_than), value); } }; template class SecurityList : public EqonomizeList { public: SecurityList() : EqonomizeList() {}; void sort() { std::sort(QList::begin(), QList::end(), security_list_less_than); } void inSort(type value) { QList::insert(std::lower_bound(QList::begin(), QList::end(), value, security_list_less_than), value); } }; template class SecurityTradeList : public EqonomizeList { public: SecurityTradeList() : EqonomizeList() {}; void sort() { std::sort(QList::begin(), QList::end(), trade_list_less_than); } void inSort(type value) { QList::insert(std::lower_bound(QList::begin(), QList::end(), value, trade_list_less_than), value); } }; struct BudgetSynchronization { QString url, download, upload; bool autosync; int revision; void clear() { autosync = false; url = QString(); download = QString(); upload = QString(); revision = 0; } bool isComplete() { return !upload.isEmpty() && (!download.isEmpty() || !url.isEmpty()); } }; class Budget { Q_DECLARE_TR_FUNCTIONS(Budget) protected: int i_quotation_decimals, i_share_decimals, i_budget_day, i_budget_month, i_opened_revision, i_revision; bool b_record_new_tags, b_record_new_accounts, b_record_new_securities, b_default_currency_changed, b_currency_modified; TransactionConversionRateDate i_tcrd; qlonglong last_id; Currency *default_currency; QNetworkReply *syncReply; QProcess *syncProcess; public: BudgetSynchronization *o_sync; Currency *currency_euro; QNetworkAccessManager nam; QString monetary_decimal_separator, monetary_group_separator, monetary_positive_sign, monetary_negative_sign; QByteArray monetary_group_format; bool currency_symbol_precedes, currency_symbol_precedes_neg, currency_code_precedes, currency_code_precedes_neg, currency_symbol_space, currency_code_space, currency_symbol_space_neg, currency_code_space_neg; int monetary_sign_p_symbol_neg, monetary_sign_p_symbol_pos, monetary_sign_p_code_neg, monetary_sign_p_code_pos, monetary_decimal_places; QString decimal_separator, group_separator, positive_sign, negative_sign; QByteArray group_format; Budget(); ~Budget(); void loadCurrencies(); void loadGlobalCurrencies(); void loadLocalCurrencies(); void loadCurrenciesFile(QString filename, bool is_local); QString loadECBData(QByteArray data); QString loadMyCurrencyNetData(QByteArray data); QString loadMyCurrencyNetHtml(QByteArray data); QString saveCurrencies(); TransactionConversionRateDate defaultTransactionConversionRateDate() const; void setDefaultTransactionConversionRateDate(TransactionConversionRateDate tcrd); QString loadFile(QString filename, QString &errors, bool *default_currency_created = NULL, bool merge = false, bool rename_duplicate_accounts = false, bool rename_duplicate_categories = false, bool rename_duplicate_securities = false, bool ignore_duplicate_transactions = false); QString saveFile(QString filename, QFile::Permissions permissions = QFile::ReadUser | QFile::WriteUser, bool is_backup = false); int fileRevision(QString filename, QString &error) const; bool isUnsynced(QString filename, QString &error, int synced_revision = -1) const; QString syncFile(QString filename, QString &errors, int revision_synced = -1); void cancelSync(); bool sync(QString &error, QString &errors, bool do_upload = true, bool on_load = false); QString syncUpload(QString filename); bool autosyncEnabled() const; void clear(); QString formatMoney(double v, int precision = -1, bool show_currency = true); QString formatValue(double v, int precision = 2, bool always_show_sign = false); QString formatValue(int v, int precision = 0, bool always_show_sign = false); void addTransaction(Transaction*); void removeTransactions(Transactions*, bool keep = false); void addTransactions(Transactions*); void removeTransaction(Transaction*, bool keep = false); void addScheduledTransaction(ScheduledTransaction*); void removeScheduledTransaction(ScheduledTransaction*, bool keep = false); void addSplitTransaction(SplitTransaction*); void removeSplitTransaction(SplitTransaction*, bool keep = false); void addAccount(Account*); void removeAccount(Account*, bool keep = false); void accountModified(Account*); bool accountHasTransactions(Account*, bool check_subs = true); void moveTransactions(Account*, Account*, bool move_from_subs = true); Transaction *findDuplicateTransaction(Transaction *trans); void addSecurity(Security*); void removeSecurity(Security*, bool keep = false); Security *findSecurity(QString name); int defaultQuotationDecimals() const; int defaultShareDecimals() const; void setDefaultQuotationDecimals(int new_decimals); void setDefaultShareDecimals(int new_decimals); bool securityHasTransactions(Security*); void scheduledTransactionDateModified(ScheduledTransaction*); void transactionDateModified(Transaction*, const QDate &olddate); void splitTransactionDateModified(SplitTransaction*, const QDate &olddate); void transactionsSortModified(Transactions*); void scheduledTransactionSortModified(ScheduledTransaction*); void transactionSortModified(Transaction*); void splitTransactionSortModified(SplitTransaction*); void accountNameModified(Account*); void securityNameModified(Security*); void securityTradeDateModified(SecurityTrade*, const QDate &olddate); void addSecurityTrade(SecurityTrade*); void removeSecurityTrade(SecurityTrade*, bool keep = false); Account *findAccount(QString name); AssetsAccount *findAssetsAccount(QString name); IncomesAccount *findIncomesAccount(QString name); ExpensesAccount *findExpensesAccount(QString name); IncomesAccount *findIncomesAccount(QString name, CategoryAccount *parent_acc); ExpensesAccount *findExpensesAccount(QString name, CategoryAccount *parent_acc); Currency *defaultCurrency(); void setDefaultCurrency(Currency*); bool resetDefaultCurrency(); void addCurrency(Currency*); void removeCurrency(Currency*); Currency *findCurrency(QString code); Currency *findCurrencySymbol(QString symbol, bool require_unique = false); bool usesMultipleCurrencies(); bool defaultCurrencyChanged(); void resetDefaultCurrencyChanged(); bool currenciesModified(); void resetCurrenciesModified(); void currencyModified(Currency*); qlonglong getNewId(); int revision(); AccountList incomesAccounts; AccountList expensesAccounts; AccountList assetsAccounts; AccountList accounts; AssetsAccount *balancingAccount, *budgetAccount; TransactionList expenses; TransactionList incomes; TransactionList transfers; TransactionList transactions; TransactionList securityTransactions; ScheduledTransactionList scheduledTransactions; SplitTransactionList splitTransactions; SecurityList securities; SecurityTradeList securityTrades; CurrencyList currencies; IncomesAccount *null_incomes_account; void setRecordNewAccounts(bool rna); QVector newAccounts; void setRecordNewSecurities(bool rns); QVector newSecurities; QHash incomesAccounts_id; QHash expensesAccounts_id; QHash assetsAccounts_id; QHash securities_id; Transactions *getTransaction(qlonglong tid); void setBudgetDay(int day_of_month); int budgetDay() const; void setBudgetMonth(int month_of_year); int budgetMonth() const; bool isSameBudgetMonth(const QDate &date1, const QDate &date2) const; int daysInBudgetMonth(const QDate &date) const; int daysInBudgetYear(const QDate &date) const; int dayOfBudgetYear(const QDate &date) const; int dayOfBudgetMonth(const QDate &date) const; int budgetMonth(const QDate &date) const; int budgetYear(const QDate &date) const; QString budgetYearString(const QDate &date, bool short_format = false) const; QString budgetYearString(int year, bool short_format = false) const; bool isFirstBudgetDay(const QDate &date) const; bool isLastBudgetDay(const QDate &date) const; void addBudgetMonthsSetLast(QDate &date, int months) const; void addBudgetMonthsSetFirst(QDate &date, int months) const; QDate budgetDateToMonth(QDate date) const; QDate firstBudgetDay(QDate date) const; QDate lastBudgetDay(QDate date) const; QDate firstBudgetDayOfYear(QDate date) const; QDate lastBudgetDayOfYear(QDate date) const; QDate monthToBudgetMonth(QDate date) const; void goForwardBudgetMonths(QDate &from_date, QDate &to_date, int months) const; double averageYear(const QDate &date1, const QDate &date2, bool use_budget_months = true); double averageMonth(const QDate &date1, const QDate &date2, bool use_budget_months = true); double yearsBetweenDates(const QDate &date1, const QDate &date2, bool use_budget_months = true); double monthsBetweenDates(const QDate &date1, const QDate &date2, bool use_budget_months = true); int calendarMonthsBetweenDates(const QDate &date1, const QDate &date2, bool use_budget_months = true); int getAccountType(const QString &type, bool localized = false, bool plural = false); QString getAccountTypeName(int at_type, bool localized = false, bool plural = false); bool accountTypeIsDebt(int at_type); bool accountTypeIsCreditCard(int at_type); bool accountTypeIsSecurities(int at_type); bool accountTypeIsLiabilities(int at_type); bool accountTypeIsOther(int at_type); void tagAdded(const QString &tag); void tagRemoved(const QString &tag); QString findTag(const QString &tag); void setRecordNewTags(bool rnt); QVector newTags; QStringList tags; }; #endif Eqonomize-1.5.3/src/categoriescomparisonchart.cpp000066400000000000000000001677321416454732000222510ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016-2020 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include "categoriescomparisonchart.h" #include "budget.h" #include "account.h" #include "transaction.h" #include "recurrence.h" #include "eqonomize.h" #include "eqonomizevalueedit.h" #include "overtimereport.h" #ifdef QT_CHARTS_LIB #include #include #include #include #include #include #include #include #else #include #include #include #include #include #include #endif #include #include #include #include #include #include #include #include #include #include #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern QString last_picture_directory; extern void calculate_minmax_lines(double &maxvalue, double &minvalue, int &y_lines, int &y_minor, bool minmaxequal = false, bool use_deciminor = true); CategoriesComparisonChart::CategoriesComparisonChart(Budget *budg, QWidget *parent) : QWidget(parent), budget(budg) { QVBoxLayout *layout = new QVBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); QHBoxLayout *buttons = new QHBoxLayout(); #ifdef QT_CHARTS_LIB point_label = NULL; buttons->addWidget(new QLabel(tr("Chart type:"), this)); typeCombo = new QComboBox(this); typeCombo->addItem(tr("Pie Chart")); typeCombo->addItem(tr("Bar Chart")); buttons->addWidget(typeCombo); buttons->addWidget(new QLabel(tr("Theme:"), this)); themeCombo = new QComboBox(this); themeCombo->addItem(tr("Default"), -1); themeCombo->addItem("Light", QChart::ChartThemeLight); themeCombo->addItem("Blue Cerulean", QChart::ChartThemeBlueCerulean); themeCombo->addItem("Dark", QChart::ChartThemeDark); themeCombo->addItem("Brown Sand", QChart::ChartThemeBrownSand); themeCombo->addItem("Blue NCS", QChart::ChartThemeBlueNcs); themeCombo->addItem("High Contrast", QChart::ChartThemeHighContrast); themeCombo->addItem("Blue Icy", QChart::ChartThemeBlueIcy); themeCombo->addItem("Qt", QChart::ChartThemeQt); buttons->addWidget(themeCombo); #endif QButtonGroup *group = new QButtonGroup(this); percentButton = new QRadioButton("%", this); percentButton->setChecked(true); group->addButton(percentButton, 1); buttons->addWidget(percentButton); valueButton = new QRadioButton(budget->defaultCurrency()->symbol(true), this); group->addButton(valueButton, 2); buttons->addWidget(valueButton); buttons->addStretch(); saveButton = new QPushButton(tr("Save As…"), this); saveButton->setAutoDefault(false); buttons->addWidget(saveButton); printButton = new QPushButton(tr("Print…"), this); printButton->setAutoDefault(false); buttons->addWidget(printButton); layout->addLayout(buttons); #ifdef QT_CHARTS_LIB chart = new QChart(); view = new QChartView(chart, this); series = NULL; axis_x = NULL; axis_y = NULL; #else scene = NULL; view = new QGraphicsView(this); #endif view->setRenderHint(QPainter::Antialiasing, true); layout->addWidget(view); QWidget *settingsWidget = new QWidget(this); QHBoxLayout *settingsLayout = new QHBoxLayout(settingsWidget); QHBoxLayout *choicesLayout = new QHBoxLayout(); settingsLayout->addLayout(choicesLayout); fromButton = new QCheckBox(tr("From"), settingsWidget); fromButton->setChecked(true); choicesLayout->addWidget(fromButton); fromEdit = new EqonomizeDateEdit(settingsWidget); fromEdit->setCalendarPopup(true); choicesLayout->addWidget(fromEdit); choicesLayout->setStretchFactor(fromEdit, 1); choicesLayout->addWidget(new QLabel(tr("To"), settingsWidget)); toEdit = new EqonomizeDateEdit(settingsWidget); toEdit->setCalendarPopup(true); choicesLayout->addWidget(toEdit); choicesLayout->setStretchFactor(toEdit, 1); prevYearButton = new QPushButton(LOAD_ICON("eqz-previous-year"), "", settingsWidget); choicesLayout->addWidget(prevYearButton); prevMonthButton = new QPushButton(LOAD_ICON("eqz-previous-month"), "", settingsWidget); choicesLayout->addWidget(prevMonthButton); nextMonthButton = new QPushButton(LOAD_ICON("eqz-next-month"), "", settingsWidget); choicesLayout->addWidget(nextMonthButton); nextYearButton = new QPushButton(LOAD_ICON("eqz-next-year"), "", settingsWidget); choicesLayout->addWidget(nextYearButton); settingsLayout->addSpacing(12); settingsLayout->setStretchFactor(choicesLayout, 1); QHBoxLayout *typeLayout = new QHBoxLayout(); settingsLayout->addLayout(typeLayout); typeLayout->addWidget(new QLabel(tr("Source:"), settingsWidget)); sourceCombo = new QComboBox(settingsWidget); sourceCombo->setEditable(false); sourceCombo->addItem(tr("All Expenses, without subcategories")); sourceCombo->addItem(tr("All Expenses, with subcategories")); sourceCombo->addItem(tr("All Incomes, without subcategories")); sourceCombo->addItem(tr("All Incomes, with subcategories")); sourceCombo->addItem(tr("All Accounts")); for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) { Account *account = *it; sourceCombo->addItem(tr("Expenses: %1").arg(account->nameWithParent())); } for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) { Account *account = *it; sourceCombo->addItem(tr("Incomes: %1").arg(account->nameWithParent())); } typeLayout->addWidget(sourceCombo); typeLayout->setStretchFactor(sourceCombo, 1); accountCombo = new AccountsCombo(budget, settingsWidget, true); accountCombo->updateAccounts(ACCOUNT_TYPE_ASSETS); typeLayout->addWidget(accountCombo); typeLayout->setStretchFactor(accountCombo, 1); settingsLayout->setStretchFactor(typeLayout, 2); current_account = NULL; layout->addWidget(settingsWidget); resetOptions(); #ifdef QT_CHARTS_LIB connect(themeCombo, SIGNAL(activated(int)), this, SLOT(themeChanged(int))); connect(typeCombo, SIGNAL(activated(int)), this, SLOT(typeChanged(int))); #endif connect(sourceCombo, SIGNAL(activated(int)), this, SLOT(sourceChanged(int))); connect(accountCombo, SIGNAL(selectedAccountsChanged()), this, SLOT(updateDisplay())); connect(prevMonthButton, SIGNAL(clicked()), this, SLOT(prevMonth())); connect(nextMonthButton, SIGNAL(clicked()), this, SLOT(nextMonth())); connect(prevYearButton, SIGNAL(clicked()), this, SLOT(prevYear())); connect(nextYearButton, SIGNAL(clicked()), this, SLOT(nextYear())); connect(fromButton, SIGNAL(toggled(bool)), fromEdit, SLOT(setEnabled(bool))); connect(fromButton, SIGNAL(toggled(bool)), this, SLOT(updateDisplay())); connect(fromEdit, SIGNAL(dateChanged(const QDate&)), this, SLOT(fromChanged(const QDate&))); connect(toEdit, SIGNAL(dateChanged(const QDate&)), this, SLOT(toChanged(const QDate&))); connect(saveButton, SIGNAL(clicked()), this, SLOT(save())); connect(printButton, SIGNAL(clicked()), this, SLOT(print())); #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) connect(group, SIGNAL(idToggled(int, bool)), this, SLOT(valueTypeToggled(int, bool))); #else connect(group, SIGNAL(buttonToggled(int, bool)), this, SLOT(valueTypeToggled(int, bool))); #endif } CategoriesComparisonChart::~CategoriesComparisonChart() { } void CategoriesComparisonChart::resetOptions() { QSettings settings; settings.beginGroup("CategoriesComparisonChart"); #ifdef QT_CHARTS_LIB int theme = settings.value("theme", -1).toInt(); int index = themeCombo->findData(QVariant::fromValue(theme)); if(index < 0) index = 0; themeCombo->setCurrentIndex(index); typeCombo->setCurrentIndex(0); chart->setTheme(theme >= 0 ? (QChart::ChartTheme) theme : QChart::ChartThemeBlueNcs); #endif int value_type = settings.value("valueType", 2).toInt(); settings.endGroup(); valueButton->blockSignals(true); percentButton->blockSignals(true); if(value_type == 2) valueButton->setChecked(true); else percentButton->setChecked(true); valueButton->blockSignals(false); percentButton->blockSignals(false); QDate first_date; for(TransactionList::const_iterator it = budget->transactions.constBegin(); it != budget->transactions.constEnd(); ++it) { Transaction *trans = *it; if(trans->fromAccount()->type() != ACCOUNT_TYPE_ASSETS || trans->toAccount()->type() != ACCOUNT_TYPE_ASSETS) { first_date = trans->date(); break; } } to_date = QDate::currentDate(); from_date = to_date.addYears(-1).addDays(1); if(first_date.isNull()) { from_date = to_date; } else if(from_date < first_date) { from_date = first_date; } fromEdit->blockSignals(true); toEdit->blockSignals(true); fromEdit->setDate(from_date); toEdit->setDate(to_date); fromEdit->blockSignals(false); toEdit->blockSignals(false); accountCombo->blockSignals(true); accountCombo->deselectAll(); accountCombo->blockSignals(false); sourceCombo->setCurrentIndex(0); sourceChanged(0); } void CategoriesComparisonChart::sourceChanged(int index) { fromButton->setEnabled(index != 4); fromEdit->setEnabled(index != 4); accountCombo->setEnabled(index != 4); updateDisplay(); } void CategoriesComparisonChart::saveConfig() { QSettings settings; settings.beginGroup("CategoriesComparisonChart"); settings.setValue("size", ((QDialog*) parent())->size()); settings.endGroup(); } void CategoriesComparisonChart::toChanged(const QDate &date) { bool error = false; if(!date.isValid()) { QMessageBox::critical(this, tr("Error"), tr("Invalid date.")); error = true; } if(!error && fromEdit->date() > date) { /*if(fromButton->isChecked() && fromButton->isEnabled()) { QMessageBox::critical(this, tr("Error"), tr("To date is before from date.")); }*/ if(budget->isFirstBudgetDay(to_date)) { from_date = budget->firstBudgetDay(date); } else { from_date = date.addDays(-from_date.daysTo(to_date)); } from_date = date; fromEdit->blockSignals(true); fromEdit->setDate(from_date); fromEdit->blockSignals(false); } if(error) { toEdit->setFocus(); toEdit->blockSignals(true); toEdit->setDate(to_date); toEdit->blockSignals(false); toEdit->selectAll(); return; } to_date = date; updateDisplay(); } void CategoriesComparisonChart::fromChanged(const QDate &date) { bool error = false; if(!date.isValid()) { QMessageBox::critical(this, tr("Error"), tr("Invalid date.")); error = true; } if(!error && date > toEdit->date()) { //QMessageBox::critical(this, tr("Error"), tr("From date is after to date.")); if(budget->isLastBudgetDay(to_date)) { to_date = budget->lastBudgetDay(date); } else { to_date = date.addDays(from_date.daysTo(to_date)); } if(to_date > QDate::currentDate() && from_date <= QDate::currentDate()) to_date = QDate::currentDate(); toEdit->blockSignals(true); toEdit->setDate(to_date); toEdit->blockSignals(false); } if(error) { fromEdit->setFocus(); fromEdit->blockSignals(true); fromEdit->setDate(from_date); fromEdit->blockSignals(false); fromEdit->selectAll(); return; } from_date = date; if(fromButton->isChecked()) updateDisplay(); } void CategoriesComparisonChart::prevMonth() { fromEdit->blockSignals(true); toEdit->blockSignals(true); budget->goForwardBudgetMonths(from_date, to_date, -1); fromEdit->setDate(from_date); toEdit->setDate(to_date); fromEdit->blockSignals(false); toEdit->blockSignals(false); updateDisplay(); } void CategoriesComparisonChart::nextMonth() { fromEdit->blockSignals(true); toEdit->blockSignals(true); budget->goForwardBudgetMonths(from_date, to_date, 1); fromEdit->setDate(from_date); toEdit->setDate(to_date); fromEdit->blockSignals(false); toEdit->blockSignals(false); updateDisplay(); } void CategoriesComparisonChart::prevYear() { fromEdit->blockSignals(true); toEdit->blockSignals(true); budget->goForwardBudgetMonths(from_date, to_date, -12); fromEdit->setDate(from_date); toEdit->setDate(to_date); fromEdit->blockSignals(false); toEdit->blockSignals(false); updateDisplay(); } void CategoriesComparisonChart::nextYear() { fromEdit->blockSignals(true); toEdit->blockSignals(true); budget->goForwardBudgetMonths(from_date, to_date, 12); fromEdit->setDate(from_date); toEdit->setDate(to_date); fromEdit->blockSignals(false); toEdit->blockSignals(false); updateDisplay(); } void CategoriesComparisonChart::onFilterSelected(QString filter) { QMimeDatabase db; QFileDialog *fileDialog = qobject_cast(sender()); if(filter == db.mimeTypeForName("image/gif").filterString()) { fileDialog->setDefaultSuffix(db.mimeTypeForName("image/gif").preferredSuffix()); } else if(filter == db.mimeTypeForName("image/jpeg").filterString()) { fileDialog->setDefaultSuffix(db.mimeTypeForName("image/jpeg").preferredSuffix()); } else if(filter == db.mimeTypeForName("image/tiff").filterString()) { fileDialog->setDefaultSuffix(db.mimeTypeForName("image/tiff").preferredSuffix()); } else if(filter == db.mimeTypeForName("image/x-bmp").filterString()) { fileDialog->setDefaultSuffix(db.mimeTypeForName("image/x-bmp").preferredSuffix()); } else if(filter == db.mimeTypeForName("image/x-eps").filterString()) { fileDialog->setDefaultSuffix(db.mimeTypeForName("image/x-eps").preferredSuffix()); } else { fileDialog->setDefaultSuffix(db.mimeTypeForName("image/png").preferredSuffix()); } } void CategoriesComparisonChart::save() { #ifdef QT_CHARTS_LIB QGraphicsScene *scene = chart->scene(); #endif if(!scene) return; QMimeDatabase db; QMimeType image_mime = db.mimeTypeForName("image/*"); QMimeType png_mime = db.mimeTypeForName("image/png"); QMimeType gif_mime = db.mimeTypeForName("image/gif"); QMimeType jpeg_mime = db.mimeTypeForName("image/jpeg"); QMimeType tiff_mime = db.mimeTypeForName("image/tiff"); QMimeType bmp_mime = db.mimeTypeForName("image/x-bmp"); QMimeType eps_mime = db.mimeTypeForName("image/x-eps"); QString png_filter = png_mime.filterString(); QString gif_filter = gif_mime.filterString(); QString jpeg_filter = jpeg_mime.filterString(); QString tiff_filter = tiff_mime.filterString(); QString bmp_filter = bmp_mime.filterString(); QString eps_filter = eps_mime.filterString(); QStringList filter(png_filter); QList image_formats = QImageWriter::supportedImageFormats(); if(image_formats.contains("gif")) { filter << gif_filter; } if(image_formats.contains("jpeg")) { filter << jpeg_filter; } if(image_formats.contains("tiff")) { filter << tiff_filter; } if(image_formats.contains("bmp")) { filter << bmp_filter; } if(image_formats.contains("eps")) { filter << eps_filter; } QFileDialog fileDialog(this); fileDialog.setNameFilters(filter); fileDialog.selectNameFilter(png_filter); fileDialog.setDefaultSuffix(png_mime.preferredSuffix()); fileDialog.setAcceptMode(QFileDialog::AcceptSave); #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) fileDialog.setSupportedSchemes(QStringList("file")); #endif fileDialog.setDirectory(last_picture_directory); connect(&fileDialog, SIGNAL(filterSelected(QString)), this, SLOT(onFilterSelected(QString))); QString url; if(!fileDialog.exec()) return; QStringList urls = fileDialog.selectedFiles(); if(urls.isEmpty()) return; url = urls[0]; QString selected_filter = fileDialog.selectedNameFilter(); QMimeType url_mime = db.mimeTypeForFile(url, QMimeDatabase::MatchExtension); QSaveFile ofile(url); ofile.open(QIODevice::WriteOnly); ofile.setPermissions((QFile::Permissions) 0x0660); if(!ofile.isOpen()) { ofile.cancelWriting(); QMessageBox::critical(this, tr("Error"), tr("Couldn't open file for writing.")); return; } last_picture_directory = fileDialog.directory().absolutePath(); QRectF rect = scene->sceneRect(); QPixmap pixmap((int) ceil(rect.width()), (int) ceil(rect.height())); QPainter p(&pixmap); #ifdef QT_CHARTS_LIB bool drop_shadow_save = chart->isDropShadowEnabled(); chart->setDropShadowEnabled(false); p.fillRect(pixmap.rect(), chart->backgroundBrush()); #endif p.setRenderHint(QPainter::Antialiasing, true); scene->render(&p); #ifdef QT_CHARTS_LIB chart->setDropShadowEnabled(drop_shadow_save); #endif if(url_mime == png_mime) {pixmap.save(&ofile, "PNG");} else if(url_mime == bmp_mime) {pixmap.save(&ofile, "BMP");} else if(url_mime == eps_mime) {pixmap.save(&ofile, "EPS");} else if(url_mime == tiff_mime) {pixmap.save(&ofile, "TIF");} else if(url_mime == gif_mime) {pixmap.save(&ofile, "GIF");} else if(url_mime == jpeg_mime) {pixmap.save(&ofile, "JPEG");} else if(selected_filter == png_filter) {pixmap.save(&ofile, "PNG");} else if(selected_filter == bmp_filter) {pixmap.save(&ofile, "BMP");} else if(selected_filter == eps_filter) {pixmap.save(&ofile, "EPS");} else if(selected_filter == tiff_filter) {pixmap.save(&ofile, "TIF");} else if(selected_filter == gif_filter) {pixmap.save(&ofile, "GIF");} else if(selected_filter == jpeg_filter) {pixmap.save(&ofile, "JPEG");} else pixmap.save(&ofile); if(!ofile.commit()) { QMessageBox::critical(this, tr("Error"), tr("Error while writing file; file was not saved.")); return; } } void CategoriesComparisonChart::print() { #ifdef QT_CHARTS_LIB QGraphicsScene *scene = view->scene(); #endif if(!scene) return; QPrinter pr; QPrintDialog dialog(&pr, this); if(dialog.exec() == QDialog::Accepted) { QPainter p(&pr); p.setRenderHint(QPainter::Antialiasing, true); scene->render(&p); p.end(); } } QColor getPieColor(int index, int total) { if(total > 8) { switch(index % 9) { case 0: return QRgb(0x4d004b); case 1: return QRgb(0x810f7c); case 2: return QRgb(0x88419d); case 3: return QRgb(0x8c6bb1); case 4: return QRgb(0x8c96c6); case 5: return QRgb(0x9ebcda); case 6: return QRgb(0xbfd3e6); case 7: return QRgb(0xe0ecf4); case 8: return QRgb(0xf7fcfd); } } else if(total == 8) { switch(index % 8) { case 0: return QRgb(0x6e016b); case 1: return QRgb(0x88419d); case 2: return QRgb(0x8c6bb1); case 3: return QRgb(0x8c96c6); case 4: return QRgb(0x9ebcda); case 5: return QRgb(0xbfd3e6); case 6: return QRgb(0xe0ecf4); case 7: return QRgb(0xf7fcfd); } } else if(total == 7) { switch(index % 7) { case 0: return QRgb(0x6e016b); case 1: return QRgb(0x88419d); case 2: return QRgb(0x8c6bb1); case 3: return QRgb(0x8c96c6); case 4: return QRgb(0x9ebcda); case 5: return QRgb(0xbfd3e6); case 6: return QRgb(0xedf8fb); } } else if(total == 6) { switch(index % 6) { case 0: return QRgb(0x810f7c); case 1: return QRgb(0x8856a7); case 2: return QRgb(0x8c96c6); case 3: return QRgb(0x9ebcda); case 4: return QRgb(0xbfd3e6); case 5: return QRgb(0xedf8fb); } } else if(total == 5) { switch(index % 5) { case 0: return QRgb(0x810f7c); case 1: return QRgb(0x8856a7); case 2: return QRgb(0x8c96c6); case 3: return QRgb(0xb3cde3); case 4: return QRgb(0xedf8fb); } } else if(total == 4) { switch(index % 4) { case 0: return QRgb(0x88419d); case 1: return QRgb(0x8c96c6); case 2: return QRgb(0xb3cde3); case 3: return QRgb(0xedf8fb); } } else { switch(index % 3) { case 0: return QRgb(0x8856a7); case 1: return QRgb(0x9ebcda); case 2: return QRgb(0xe0ecf4); } } return Qt::black; } extern QBrush getBarBrush(int index, int total); QBrush getPieBrush(int index, int total) { QBrush brush; if(total > 9) total = 9; else if(total <= 0) total = 1; switch(index / total) { case 0: {brush.setStyle(Qt::SolidPattern); break;} case 1: {brush.setStyle(Qt::Dense3Pattern); break;} case 2: {brush.setStyle(Qt::DiagCrossPattern); break;} case 3: {brush.setStyle(Qt::HorPattern); break;} case 4: {brush.setStyle(Qt::VerPattern); break;} default: {} } brush.setColor(getPieColor(index, total)); return brush; } void CategoriesComparisonChart::updateDisplay() { if(!isVisible()) return; QMap values; QMap counts; QMap desc_map; QMap desc_values; QMap desc_counts; QStringList desc_order; current_account = NULL; bool assets_selected = accountCombo->isEnabled() && !accountCombo->allAccountsSelected(); bool single_assets = assets_selected && accountCombo->selectedAccounts().count() == 1; bool include_subs = false; QString title_string = tr("Expenses"); QDate first_date; bool first_date_reached = false; if(sourceCombo->currentIndex() == 4) { first_date_reached = true; } else if(fromButton->isChecked()) { first_date = from_date; } else { for(TransactionList::const_iterator it = budget->transactions.constBegin(); it != budget->transactions.constEnd(); ++it) { Transaction *trans = *it; if(trans->fromAccount()->type() != ACCOUNT_TYPE_ASSETS || trans->toAccount()->type() != ACCOUNT_TYPE_ASSETS) { first_date = trans->date(); break; } } if(first_date.isNull()) first_date = QDate::currentDate(); if(first_date > to_date) first_date = to_date; } AccountType type; switch(sourceCombo->currentIndex()) { case 1: { include_subs = true; } case 0: { type = ACCOUNT_TYPE_EXPENSES; if(assets_selected) title_string = tr("Expenses, %1").arg(accountCombo->selectedAccountsText(2)); for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) { CategoryAccount *account = *it; if(include_subs || !account->parentCategory()) { values[account] = 0.0; counts[account] = 0.0; } } break; } case 3: { include_subs = true; } case 2: { if(assets_selected) title_string = tr("Incomes, %1").arg(accountCombo->selectedAccountsText(2)); else title_string = tr("Incomes"); type = ACCOUNT_TYPE_INCOMES; for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) { CategoryAccount *account = *it; if(include_subs || !account->parentCategory()) { values[account] = 0.0; counts[account] = 0.0; } } break; } case 4: { title_string = tr("Accounts"); type = ACCOUNT_TYPE_ASSETS; for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { AssetsAccount *account = *it; if(account != budget->balancingAccount) { if(account->accountType() == ASSETS_TYPE_SECURITIES) { values[account] = 0.0; } else { values[account] = account->initialBalance(); } counts[account] = 0.0; } } break; } default: { type = ACCOUNT_TYPE_EXPENSES; int i = sourceCombo->currentIndex() - 5; if(i < (int) budget->expensesAccounts.count()) current_account = budget->expensesAccounts.at(i); else current_account = budget->incomesAccounts.at(i - budget->expensesAccounts.count()); if(current_account) { type = current_account->type(); if(assets_selected) { if(type == ACCOUNT_TYPE_EXPENSES) title_string = tr("Expenses, %2: %1").arg(current_account->nameWithParent()).arg(accountCombo->selectedAccountsText(2)); else title_string = tr("Incomes, %2: %1").arg(current_account->nameWithParent()).arg(accountCombo->selectedAccountsText(2)); } else { if(type == ACCOUNT_TYPE_EXPENSES) title_string = tr("Expenses: %1").arg(current_account->nameWithParent()); else title_string = tr("Incomes: %1").arg(current_account->nameWithParent()); } include_subs = !current_account->subCategories.isEmpty(); if(include_subs) { values[current_account] = 0.0; counts[current_account] = 0.0; for(AccountList::const_iterator it = current_account->subCategories.constBegin(); it != current_account->subCategories.constEnd(); ++it) { Account *account = *it; values[account] = 0.0; counts[account] = 0.0; } } else { for(TransactionList::const_iterator it = budget->transactions.constEnd(); it != budget->transactions.constBegin();) { --it; Transaction *trans = *it; if(trans->date() <= to_date && (!assets_selected || accountCombo->testTransactionRelation(trans))) { if(trans->date() < first_date) break; if((trans->fromAccount() == current_account || trans->toAccount() == current_account) && !desc_map.contains(trans->description().toLower())) { desc_map[trans->description().toLower()] = trans->description(); desc_values[trans->description().toLower()] = 0.0; desc_counts[trans->description().toLower()] = 0.0; } } } } } } } Currency *currency = budget->defaultCurrency(); if(single_assets) currency = ((AssetsAccount*) accountCombo->selectedAccounts()[0])->currency(); for(TransactionList::const_iterator it = budget->transactions.constBegin(); it != budget->transactions.constEnd(); ++it) { Transaction *trans = *it; if(!first_date_reached && trans->date() >= first_date) first_date_reached = true; else if(first_date_reached && trans->date() > to_date) break; if(first_date_reached && (!assets_selected || accountCombo->testTransactionRelation(trans))) { if(current_account && !include_subs) { if(trans->fromAccount() == current_account) { if(type == ACCOUNT_TYPE_EXPENSES) {desc_values[trans->description().toLower()] -= trans->value(!single_assets);} else {desc_values[trans->description().toLower()] += trans->value(!single_assets);} desc_counts[trans->description().toLower()] += trans->quantity(); } else if(trans->toAccount() == current_account) { if(type == ACCOUNT_TYPE_EXPENSES) {desc_values[trans->description().toLower()] += trans->value(!single_assets);} else {desc_values[trans->description().toLower()] -= trans->value(!single_assets);} desc_counts[trans->description().toLower()] += trans->quantity(); } } else if(type == ACCOUNT_TYPE_ASSETS) { if(trans->fromAccount()->type() == ACCOUNT_TYPE_ASSETS && trans->fromAccount() != budget->balancingAccount) { if(((AssetsAccount*) trans->fromAccount())->accountType() != ASSETS_TYPE_SECURITIES) { values[trans->fromAccount()] -= trans->fromValue(!single_assets); } if(trans->toAccount() != budget->balancingAccount) { counts[trans->fromAccount()] += trans->quantity(); } } if(trans->toAccount()->type() == ACCOUNT_TYPE_ASSETS && trans->toAccount() != budget->balancingAccount) { if(((AssetsAccount*) trans->toAccount())->accountType() != ASSETS_TYPE_SECURITIES) { values[trans->toAccount()] += trans->toValue(!single_assets); } if(trans->fromAccount() != budget->balancingAccount) { counts[trans->toAccount()] += trans->quantity(); } } } else { Account *from_account = trans->fromAccount(); if(!include_subs) from_account = from_account->topAccount(); Account *to_account = trans->toAccount(); if(!include_subs) to_account = to_account->topAccount(); if((!current_account || to_account->topAccount() == current_account || from_account->topAccount() == current_account) && (to_account->type() == type || from_account->type() == type)) { if(from_account->type() == ACCOUNT_TYPE_EXPENSES) { values[from_account] -= trans->value(!single_assets); counts[from_account] += trans->quantity(); } else if(from_account->type() == ACCOUNT_TYPE_INCOMES) { values[from_account] += trans->value(!single_assets); counts[from_account] += trans->quantity(); } else if(to_account->type() == ACCOUNT_TYPE_EXPENSES) { values[to_account] += trans->value(!single_assets); counts[to_account] += trans->quantity(); } else if(to_account->type() == ACCOUNT_TYPE_INCOMES) { values[to_account] -= trans->value(!single_assets); counts[to_account] += trans->quantity(); } } } } } first_date_reached = false; int split_i = 0; Transaction *trans = NULL; for(ScheduledTransactionList::const_iterator it = budget->scheduledTransactions.constBegin(); it != budget->scheduledTransactions.constEnd();) { ScheduledTransaction *strans = *it; while(split_i == 0 && strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT && ((SplitTransaction*) strans->transaction())->count() == 0) { ++it; if(it == budget->scheduledTransactions.constEnd()) break; strans = *it; } if(strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { trans = ((SplitTransaction*) strans->transaction())->at(split_i); split_i++; } else { trans = (Transaction*) strans->transaction(); } if(!first_date_reached && trans->date() >= first_date) first_date_reached = true; if(first_date_reached && trans->date() > to_date) break; if(first_date_reached && (!assets_selected || accountCombo->testTransactionRelation(trans))) { if(current_account && !include_subs) { if(trans->fromAccount() == current_account) { int count = strans->recurrence() ? strans->recurrence()->countOccurrences(first_date, to_date) : 1; if(type == ACCOUNT_TYPE_EXPENSES) {desc_values[trans->description().toLower()] -= trans->value(!single_assets) * count;} else {desc_values[trans->description().toLower()] += trans->value(!single_assets) * count;} desc_counts[trans->description().toLower()] += count * trans->quantity(); } else if(trans->toAccount() == current_account) { int count = strans->recurrence() ? strans->recurrence()->countOccurrences(first_date, to_date) : 1; if(type == ACCOUNT_TYPE_EXPENSES) {desc_values[trans->description().toLower()] += trans->value(!single_assets) * count;} else {desc_values[trans->description().toLower()] -= trans->value(!single_assets) * count;} desc_counts[trans->description().toLower()] += count * trans->quantity(); } } else if(type == ACCOUNT_TYPE_ASSETS) { if(trans->fromAccount()->type() == ACCOUNT_TYPE_ASSETS && trans->fromAccount() != budget->balancingAccount) { int count = strans->recurrence() ? strans->recurrence()->countOccurrences(to_date) : 1; if(trans->toAccount() != budget->balancingAccount) { counts[trans->fromAccount()] += count * trans->quantity(); } if(((AssetsAccount*) trans->fromAccount())->accountType() != ASSETS_TYPE_SECURITIES) { values[trans->fromAccount()] -= trans->fromValue(!single_assets) * count; } } if(trans->toAccount()->type() == ACCOUNT_TYPE_ASSETS && trans->toAccount() != budget->balancingAccount) { int count = strans->recurrence() ? strans->recurrence()->countOccurrences(to_date) : 1; if(trans->fromAccount() != budget->balancingAccount) { counts[trans->toAccount()] += count * trans->quantity(); } if(((AssetsAccount*) trans->toAccount())->accountType() != ASSETS_TYPE_SECURITIES) { values[trans->toAccount()] += trans->toValue(!single_assets) * count; } } } else { Account *from_account = trans->fromAccount(); if(!include_subs) from_account = from_account->topAccount(); Account *to_account = trans->toAccount(); if(!include_subs) to_account = to_account->topAccount(); if((!current_account || to_account->topAccount() == current_account || from_account->topAccount() == current_account) && (to_account->type() == type || from_account->type() == type)) { if(from_account->type() == ACCOUNT_TYPE_EXPENSES) { int count = strans->recurrence() ? strans->recurrence()->countOccurrences(first_date, to_date) : 1; counts[trans->fromAccount()] += count * trans->quantity(); values[trans->fromAccount()] -= trans->value(!single_assets) * count; } else if(from_account->type() == ACCOUNT_TYPE_INCOMES) { int count = strans->recurrence() ? strans->recurrence()->countOccurrences(first_date, to_date) : 1; counts[trans->fromAccount()] += count; values[trans->fromAccount()] += trans->value(!single_assets) * count; } else if(to_account->type() == ACCOUNT_TYPE_EXPENSES) { int count = strans->recurrence() ? strans->recurrence()->countOccurrences(first_date, to_date) : 1; counts[trans->toAccount()] += count * trans->quantity(); values[trans->toAccount()] += trans->value(!single_assets) * count; } else if(to_account->type() == ACCOUNT_TYPE_INCOMES) { int count = strans->recurrence() ? strans->recurrence()->countOccurrences(first_date, to_date) : 1; counts[trans->toAccount()] += count; values[trans->toAccount()] -= trans->value(!single_assets) * count; } } } } if(strans->transaction()->generaltype() != GENERAL_TRANSACTION_TYPE_SPLIT || split_i >= ((SplitTransaction*) strans->transaction())->count()) { ++it; split_i = 0; } } if(type == ACCOUNT_TYPE_ASSETS) { for(SecurityList::const_iterator it = budget->securities.constBegin(); it != budget->securities.constEnd(); ++it) { Security *security = *it; double val = security->value(to_date, -1); values[security->account()] += val; } } /*int days = first_date.daysTo(to_date) + 1; double months = budget->monthsBetweenDates(first_date, to_date, true), years = budget->yearsBetweenDates(first_date, to_date, true);*/ #ifdef QT_CHARTS_LIB int chart_type = typeCombo->currentIndex() + 1; #else int chart_type = 1; #endif Account *account = NULL; QMap::iterator it_desc = desc_values.begin(); QMap::iterator it_desc_end = desc_values.end(); double value = 0.0; double vmax = 0.0; double remaining_value = 0.0; if(current_account && !include_subs) { while(it_desc != it_desc_end) { if(it_desc.value() >= 0.0) value += it_desc.value(); if(it_desc.value() >= 0.01 || (chart_type != 1 && it_desc.value() <= -0.01)) { bool b = false; if(abs(it_desc.value()) > vmax) vmax = abs(it_desc.value()); for(int i = 0; i < desc_order.count(); i++) { if(it_desc.value() > desc_values[desc_order.at(i)]) { desc_order.insert(i, it_desc.key()); b = true; break; } } if(!b) desc_order.push_back(it_desc.key()); } ++it_desc; } } if((chart_type == 1 && desc_order.size() > 9) || (chart_type == 2 && desc_order.size() > 12)) { while((chart_type == 1 && desc_order.size() > 8) || (chart_type == 2 && desc_order.size() > 11)) { remaining_value += desc_values[desc_order.back()]; desc_order.pop_back(); } } else if(desc_order.size() > 5 && chart_type == 1) { int n = 0; for(int i = desc_order.size() - 1; i > 0; i--) { double v = abs(desc_values[desc_order[i]]); if((v / value) < 0.01 && v < (vmax / 10)) { n++; } } if(n > 1) { for(int i = desc_order.size() - 1; i > 0; i--) { double v = abs(desc_values[desc_order[i]]); if((v / value) < 0.01 && v < (vmax / 10)) { remaining_value += desc_values[desc_order[i]]; desc_order.removeAt(i); } } } } if(desc_order.count() > 0 && remaining_value != 0.0) { desc_order.push_back(tr("Other descriptions", "Referring to the transaction description property (transaction title/generic article name)")); desc_values[tr("Other descriptions", "Referring to the transaction description property (transaction title/generic article name)")] = remaining_value; desc_map[desc_order.last()] = desc_order.last(); } QList account_order; int account_index = 0; account = NULL; if(current_account) { if(include_subs) { if(account_index < current_account->subCategories.size()) account = current_account->subCategories.at(account_index); } } else if(type == ACCOUNT_TYPE_ASSETS) { if(account_index < budget->assetsAccounts.size()) { account = budget->assetsAccounts.at(account_index); if(account == budget->balancingAccount) { ++account_index; if(account_index < budget->assetsAccounts.size()) { account = budget->assetsAccounts.at(account_index); } } } } else if(type == ACCOUNT_TYPE_EXPENSES) { if(account_index < budget->expensesAccounts.size()) account = budget->expensesAccounts.at(account_index); } else { if(account_index < budget->incomesAccounts.size()) account = budget->incomesAccounts.at(account_index); } while(account) { if(!current_account && include_subs) { while(account && ((CategoryAccount*) account)->subCategories.size() > 0) { if(values[account] != 0.0) break; ++account_index; account = NULL; if(type == ACCOUNT_TYPE_EXPENSES && account_index < budget->expensesAccounts.size()) account = budget->expensesAccounts.at(account_index); else if(type == ACCOUNT_TYPE_INCOMES && account_index < budget->incomesAccounts.size()) account = budget->incomesAccounts.at(account_index); } if(!account) break; } else if(!current_account && type != ACCOUNT_TYPE_ASSETS) { while(account && account->topAccount() != account) { ++account_index; account = NULL; if(type == ACCOUNT_TYPE_EXPENSES && account_index < budget->expensesAccounts.size()) account = budget->expensesAccounts.at(account_index); else if(type == ACCOUNT_TYPE_INCOMES && account_index < budget->incomesAccounts.size()) account = budget->incomesAccounts.at(account_index); } if(!account) break; } if(values[account] > 0.0) value += values[account]; if(values[account] >= 0.01 || (chart_type != 1 && values[account] <= -0.01)) { bool b = false; if(abs(values[account]) > vmax) vmax = abs(values[account]); for(int i = 0; i < account_order.count(); i++) { if(values[account] > values[account_order.at(i)]) { account_order.insert(i, account); b = true; break; } } if(!b) account_order.push_back(account); } ++account_index; if(current_account) { if(include_subs && account != current_account) { if(account_index < current_account->subCategories.size()) account = current_account->subCategories.at(account_index); else if(values[current_account] >= 0.01 || values[current_account] <= -0.01) account = current_account; else account = NULL; } else { account = NULL; } } else if(type == ACCOUNT_TYPE_ASSETS) { account = NULL; if(account_index < budget->assetsAccounts.size()) { account = budget->assetsAccounts.at(account_index); if(account == budget->balancingAccount) { ++account_index; if(account_index < budget->assetsAccounts.size()) { account = budget->assetsAccounts.at(account_index); } } } } else if(type == ACCOUNT_TYPE_EXPENSES) { account = NULL; if(account_index < budget->expensesAccounts.size()) account = budget->expensesAccounts.at(account_index); } else { account = NULL; if(account_index < budget->incomesAccounts.size()) account = budget->incomesAccounts.at(account_index); } } if(account_order.size() > 5 && chart_type == 1) { if(account_order.size() > 9) { values[NULL] = 0.0; while(account_order.size() > 8) { values[NULL] += values[account_order.back()]; account_order.pop_back(); } account_order.push_back(NULL); } else { int n = 0; for(int i = account_order.size() - 1; i > 0; i--) { double v = abs(values[account_order[i]]); if((v / value) < 0.01 && v < (vmax / 10)) { n++; } } if(n > 1) { values[NULL] = 0.0; for(int i = account_order.size() - 1; i > 0; i--) { double v = abs(values[account_order[i]]); if((v / value) < 0.01 && v < (vmax / 10)) { values[NULL] += values[account_order[i]]; account_order.removeAt(i); } } account_order.push_back(NULL); } } } #ifdef QT_CHARTS_LIB int theme = themeCombo->currentData().toInt(); QPieSeries *pie_series = NULL; QAbstractBarSeries *bar_series = NULL; double maxvalue = 0.0, minvalue = 0.0; if(chart_type == 1) { pie_series = new QPieSeries(); } else if(chart_type == 3) { bar_series = new QBarSeries(); } else { bar_series = new QHorizontalBarSeries(); } QBarSet *bar_set = NULL; QBarCategoryAxis *b_axis = NULL; if(chart_type != 1) { bar_set = new QBarSet(""); if(theme < 0) bar_set->setBrush(getBarBrush(0, 1)); b_axis = new QBarCategoryAxis(); } account = NULL; int index = 0; bool show_legend = false; if(chart_type == 2) { index = account_order.size() - 1; if(index < 0) index = desc_order.size() - 1; } while((chart_type == 2 && index >= 0) || (chart_type != 2 && (index < account_order.count() || (current_account && index < desc_order.size())))) { QString legend_string; double legend_value = 0.0; double current_value = 0.0; if(account_order.isEmpty()) { if(desc_order[index].isEmpty()) { legend_string = tr("No description", "Referring to the transaction description property (transaction title/generic article name)"); } else { legend_string = desc_map[desc_order[index]]; } current_value = desc_values[desc_order[index]]; } else { account = account_order.at(index); if(!account) { if(type == ACCOUNT_TYPE_ASSETS) legend_string = tr("Other accounts"); else legend_string = tr("Other categories"); } else if(current_account) legend_string = account->name(); else legend_string = account->nameWithParent(); current_value = values[account]; } if(chart_type == 1) { int deci = 0; if(valueButton->isChecked()) { legend_value = current_value; if(legend_value < 100.0) deci = currency->fractionalDigits(); } else { legend_value = (current_value * 100) / value; if(legend_value < 10.0 && legend_value > -10.0) { legend_value = round(legend_value * 10.0) / 10.0; deci = 1; } } QPieSlice *slice = pie_series->append(QString("%1 (%2)").arg(legend_string).arg(valueButton->isChecked() ? currency->formatValue(legend_value, deci) : budget->formatValue(legend_value, deci) + "%"), current_value); if(theme < 0) { slice->setBrush(getPieBrush(index, account_order.size() > 0 ? account_order.size() : desc_order.size())); slice->setLabelColor(Qt::black); slice->setBorderColor(Qt::white); slice->setBorderWidth(1); } slice->setLabelArmLengthFactor(0.1); slice->setExplodeDistanceFactor(0.1); if((current_value * 100) / value >= 8.0) { slice->setLabelVisible(true); } else { show_legend = true; } } else { b_axis->append(legend_string); bar_set->append(current_value); if(current_value > maxvalue) maxvalue = current_value; if(current_value < minvalue) minvalue = current_value; show_legend = true; } if(chart_type == 2) index--; else index++; } chart->removeAllSeries(); foreach(QAbstractAxis* axis, chart->axes()) { chart->removeAxis(axis); } axis_x = NULL; axis_y = NULL; if(theme < 0) { chart->setBackgroundBrush(Qt::white); chart->setTitleBrush(Qt::black); chart->setPlotAreaBackgroundVisible(false); chart->legend()->setBackgroundVisible(false); chart->legend()->setColor(Qt::white); chart->legend()->setLabelColor(Qt::black); } chart->setLocalizeNumbers((chart_type == 1 && (budget->decimal_separator != "." || budget->decimal_separator == QLocale().decimalPoint())) || (chart_type != 1 && (budget->monetary_decimal_separator != "." || budget->monetary_decimal_separator == QLocale().decimalPoint() || ((maxvalue - minvalue) >= 50.0 && (budget->monetary_group_separator == QLocale().groupSeparator() || QLocale().groupSeparator() == ' ' || QLocale().groupSeparator() == QChar(0x202F) || QLocale().groupSeparator() == QChar(0x2009)))))); if(chart_type == 1) { series = pie_series; pie_series->setPieSize(0.78); pie_series->setVerticalPosition(0.52); connect(pie_series, SIGNAL(hovered(QPieSlice*, bool)), this, SLOT(sliceHovered(QPieSlice*, bool))); connect(pie_series, SIGNAL(clicked(QPieSlice*)), this, SLOT(sliceClicked(QPieSlice*))); chart->addSeries(series); } else { series = bar_series; bar_series->append(bar_set); bar_series->setBarWidth(2.0 / 3.0); chart->addSeries(series); int y_lines = 5, y_minor = 0; calculate_minmax_lines(maxvalue, minvalue, y_lines, y_minor); QValueAxis *v_axis = new QValueAxis(); //v_axis->setAlignment(Qt::AlignTop | Qt::AlignBottom); v_axis->setRange(minvalue, maxvalue); v_axis->setTickCount(y_lines + 1); v_axis->setMinorTickCount(chart_type == 2 ? 0 : y_minor); if((maxvalue - minvalue) >= 50.0) v_axis->setLabelFormat(QString("%.0f")); else v_axis->setLabelFormat(QString("%.%1f").arg(QString::number(currency->fractionalDigits()))); if(type == ACCOUNT_TYPE_ASSETS) v_axis->setTitleText(tr("Value") + QString(" (%1)").arg(currency->symbol(true))); else if(type == ACCOUNT_TYPE_INCOMES) v_axis->setTitleText(tr("Income") + QString(" (%1)").arg(currency->symbol(true))); else v_axis->setTitleText(tr("Cost") + QString(" (%1)").arg(currency->symbol(true))); if(theme < 0) { v_axis->setLinePen(QPen(Qt::darkGray, 1)); v_axis->setLabelsColor(Qt::black); b_axis->setLinePen(QPen(Qt::darkGray, 1)); b_axis->setLabelsColor(Qt::black); v_axis->setTitleBrush(Qt::black); b_axis->setTitleBrush(Qt::black); b_axis->setGridLineVisible(false); v_axis->setGridLinePen(QPen(Qt::darkGray, 1, Qt::DotLine)); v_axis->setShadesVisible(false); b_axis->setShadesVisible(false); } if(chart_type == 3) { axis_x = b_axis; axis_y = v_axis; } else { axis_x = v_axis; axis_y = b_axis; } chart->addAxis(axis_x, Qt::AlignBottom); chart->addAxis(axis_y, Qt::AlignLeft); connect(bar_series, SIGNAL(hovered(bool, int, QBarSet*)), this, SLOT(onSeriesHovered(bool, int, QBarSet*))); show_legend = false; } chart->setTitle(QString("
    %1
    ").arg(title_string)); if(show_legend) { #if (QT_CHARTS_VERSION >= QT_CHARTS_VERSION_CHECK(5, 7, 0)) chart->legend()->setShowToolTips(true); #endif chart->legend()->setAlignment(Qt::AlignRight); chart->legend()->show(); foreach(QLegendMarker* marker, chart->legend()->markers()) { QObject::connect(marker, SIGNAL(clicked()), this, SLOT(legendClicked())); } } else { chart->legend()->hide(); } #else QGraphicsScene *oldscene = scene; scene = new QGraphicsScene(this); scene->setBackgroundBrush(Qt::white); QFont legend_font = font(); QFontMetrics fm(legend_font); int fh = fm.height(); int margin = 15 + fh; QVector legend_texts; account = NULL; int index = 0; int text_width = 0; while((index < account_order.count()) || (current_account && index < desc_order.size())) { QString legend_string; double legend_value = 0.0; double current_value = 0.0; if(account_order.isEmpty()) { if(desc_order[index].isEmpty()) { legend_string = tr("No description", "Referring to the transaction description property (transaction title/generic article name)"); } else { legend_string = desc_map[desc_order[index]]; } legend_value = desc_values[desc_order[index]]; } else { account = account_order.at(index); if(!account) { if(type == ACCOUNT_TYPE_ASSETS) legend_string = tr("Other accounts"); else legend_string = tr("Other categories"); } else if(current_account) legend_string = account->name(); else legend_string = account->nameWithParent(); legend_value = values[account]; } int deci = 0; if(valueButton->isChecked()) { legend_value = current_value; if(legend_value < 100.0) deci = currency->fractionalDigits(); } else { legend_value = (current_value * 100) / value; if(legend_value < 10.0 && legend_value > -10.0) { legend_value = round(legend_value * 10.0) / 10.0; deci = 1; } } QGraphicsSimpleTextItem *legend_text = new QGraphicsSimpleTextItem(QString("%1 (%2%)").arg(legend_string).arg(valueButton->isChecked() ? currency->formatValue(legend_value, deci) : budget->formatValue(legend_value, deci) + "%")); legend_text->setFont(legend_font); legend_text->setBrush(Qt::black); if(legend_text->boundingRect().width() > text_width) text_width = legend_text->boundingRect().width(); legend_texts << legend_text; index++; } QGraphicsTextItem *title_text = new QGraphicsTextItem(); title_text->setHtml(QString("
    %1
    ").arg(title_string)); title_text->setDefaultTextColor(Qt::black); title_text->setFont(legend_font); title_text->setPos(view->height() / 2 - title_text->boundingRect().width() / 2, margin); scene->addItem(title_text); int diameter = view->height() - margin * 3 - title_text->boundingRect().height(); if(diameter + margin * 2 + fh * 1.3 + text_width + margin > view->width()) diameter = view->width() - (margin * 2 + fh * 1.3 + text_width + margin); int legend_x = diameter + margin * 2; int chart_y = margin * 2 + title_text->boundingRect().height(); int legend_y = chart_y; index = 0; while((index < account_order.count()) || (current_account && index < desc_order.size())) { QString legend_string; double legend_value = 0.0; if(account_order.isEmpty()) { if(desc_order[index].isEmpty()) { legend_string = tr("No description", "Referring to the transaction description property (transaction title/generic article name)"); } else { legend_string = desc_map[desc_order[index]]; } legend_value = desc_values[desc_order[index]]; } else { account = account_order.at(index); if(!account) { if(type == ACCOUNT_TYPE_ASSETS) legend_string = tr("Other accounts"); else legend_string = tr("Other categories"); } else if(current_account) legend_string = account->name(); else legend_string = account->nameWithParent(); legend_value = values[account]; } legend_value = (legend_value * 100) / value; if(legend_value < 10.0 && legend_value > -10.0) { legend_value = round(legend_value * 10.0) / 10.0; } else { legend_value = round(legend_value); } legend_texts[index]->setPos(legend_x + fh * 1.3, legend_y + (fh * 1.5) * index); scene->addItem(legend_texts[index]); index++; } account = NULL; double current_value = 0.0, current_value_1 = 0.0; int prev_end = 90 * 16; index = account_order.size() - 1; if(index < 0) index = desc_order.size() - 1; while(index >= 0) { if(account_order.isEmpty()) current_value_1 = desc_values[desc_order[index]]; else current_value_1 = values[account_order[index]]; current_value += current_value_1; int next_end = (int) lround((current_value * 360 * 16) / value) + 90 * 16; if(next_end > 360 * 16 && next_end - 360 * 16 > prev_end) next_end -= 360 * 16; int length = (next_end - prev_end); QGraphicsEllipseItem *ellipse = new QGraphicsEllipseItem(-diameter/ 2.0, -diameter/ 2.0, diameter, diameter); ellipse->setStartAngle(prev_end); ellipse->setSpanAngle(length); prev_end = next_end; if(prev_end > 360 * 16) prev_end -= 360 * 16; ellipse->setPen(QPen(Qt::white, 1)); ellipse->setBrush(getPieBrush(index, account_order.size() > 0 ? account_order.size() : desc_order.size())); ellipse->setPos(diameter / 2 + margin, diameter / 2 + chart_y); scene->addItem(ellipse); QGraphicsRectItem *legend_box = new QGraphicsRectItem(legend_x, legend_y + (fh * 1.5) * index, fh, fh); legend_box->setPen(QPen(Qt::black)); legend_box->setBrush(getPieBrush(index, account_order.size() > 0 ? account_order.size() : desc_order.size())); scene->addItem(legend_box); index--; } QRectF rect = scene->sceneRect(); rect.setX(0); rect.setY(0); rect.setRight(rect.right() + 20); rect.setBottom(rect.bottom() + 20); scene->setSceneRect(rect); scene->update(); view->setScene(scene); view->fitInView(scene->sceneRect(), Qt::KeepAspectRatio); if(oldscene) { delete oldscene; } #endif } #ifndef QT_CHARTS_LIB void CategoriesComparisonChart::resizeEvent(QResizeEvent *e) { QWidget::resizeEvent(e); if(scene) { view->fitInView(scene->sceneRect(), Qt::KeepAspectRatio); } } #endif void CategoriesComparisonChart::updateTransactions() { updateDisplay(); } void CategoriesComparisonChart::updateAccounts() { int curindex = sourceCombo->currentIndex(); if(curindex > 2) { curindex = 0; } sourceCombo->blockSignals(true); sourceCombo->clear(); sourceCombo->addItem(tr("All Expenses, without subcategories")); sourceCombo->addItem(tr("All Expenses, with subcategories")); sourceCombo->addItem(tr("All Incomes, without subcategories")); sourceCombo->addItem(tr("All Incomes, with subcategories")); sourceCombo->addItem(tr("All Accounts")); int i = 3; for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) { Account *account = *it; sourceCombo->addItem(tr("Expenses: %1").arg(account->nameWithParent())); if(account == current_account) curindex = i; i++; } for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) { Account *account = *it; sourceCombo->addItem(tr("Incomes: %1").arg(account->nameWithParent())); if(account == current_account) curindex = i; i++; } if(curindex < sourceCombo->count()) sourceCombo->setCurrentIndex(curindex); sourceCombo->blockSignals(false); accountCombo->blockSignals(true); accountCombo->updateAccounts(ACCOUNT_TYPE_ASSETS); accountCombo->blockSignals(false); updateDisplay(); } void CategoriesComparisonChart::valueTypeToggled(int i, bool b) { if(!b) return; QSettings settings; settings.beginGroup("CategoriesComparisonChart"); settings.setValue("valueType", i); settings.endGroup(); updateDisplay(); } #ifdef QT_CHARTS_LIB void CategoriesComparisonChart::themeChanged(int index) { int theme = themeCombo->itemData(index).toInt(); chart->setTheme(theme >= 0 ? (QChart::ChartTheme) theme : QChart::ChartThemeBlueNcs); QSettings settings; settings.beginGroup("CategoriesComparisonChart"); settings.setValue("theme", theme); settings.endGroup(); updateDisplay(); } void CategoriesComparisonChart::typeChanged(int type) { percentButton->setEnabled(type == 0); valueButton->setEnabled(type == 0); updateDisplay(); } void CategoriesComparisonChart::sliceHovered(QPieSlice *slice, bool state) { if(!slice || slice->isExploded() || slice->percentage() >= 0.08) return; slice->setLabelVisible(state); } void CategoriesComparisonChart::sliceClicked(QPieSlice *slice) { if(!slice) return; if(slice->isExploded()) { slice->setLabelVisible(slice->percentage() >= 0.08); slice->setExploded(false); } else { slice->setLabelVisible(true); slice->setExploded(true); } } void CategoriesComparisonChart::legendClicked() { if(typeCombo->currentIndex() == 0) { QPieLegendMarker* marker = qobject_cast(sender()); sliceClicked(marker->slice()); } else { QBarLegendMarker* marker = qobject_cast(sender()); if(marker->series()->count() == 1) updateDisplay(); else marker->series()->remove(marker->barset()); } } class PointLabel2 : public QGraphicsItem { public: PointLabel2(QChart *c, QAbstractAxis *axis_x) : QGraphicsItem(c), chart(c), axis(axis_x) {} void setAxis(QAbstractAxis *axis_x) {axis = axis_x;} void setText(const QString &text) { m_text = text; QFontMetrics metrics(chart->font()); m_textRect = metrics.boundingRect(QRect(0, 0, 150, 150), Qt::AlignLeft, m_text); m_textRect.translate(5, 5); prepareGeometryChange(); m_rect = m_textRect.adjusted(-5, -5, 5, 5); } void setAnchor(QPointF point) { m_anchor = point; } QRectF boundingRect() const { QPointF anchor = mapFromParent(m_anchor); QRectF rect; rect.setLeft(qMin(m_rect.left(), anchor.x())); rect.setRight(qMax(m_rect.right(), anchor.x())); rect.setTop(qMin(m_rect.top(), anchor.y())); rect.setBottom(qMax(m_rect.bottom(), anchor.y())); return rect; } void paint(QPainter *painter, const QStyleOptionGraphicsItem*, QWidget*){ QPainterPath path; path.addRoundedRect(m_rect, 5, 5); QPointF anchor = mapFromParent(m_anchor); if (!m_rect.contains(anchor)) { QPointF point1, point2; // establish the position of the anchor point in relation to m_rect bool above = anchor.y() <= m_rect.top(); bool aboveCenter = anchor.y() > m_rect.top() && anchor.y() <= m_rect.center().y(); bool belowCenter = anchor.y() > m_rect.center().y() && anchor.y() <= m_rect.bottom(); bool below = anchor.y() > m_rect.bottom(); bool onLeft = anchor.x() <= m_rect.left(); bool leftOfCenter = anchor.x() > m_rect.left() && anchor.x() <= m_rect.center().x(); bool rightOfCenter = anchor.x() > m_rect.center().x() && anchor.x() <= m_rect.right(); bool onRight = anchor.x() > m_rect.right(); // get the nearest m_rect corner. qreal x = (onRight + rightOfCenter) * m_rect.width(); qreal y = (below + belowCenter) * m_rect.height(); bool cornerCase = (above && onLeft) || (above && onRight) || (below && onLeft) || (below && onRight); bool vertical = qAbs(anchor.x() - x) > qAbs(anchor.y() - y); qreal x1 = x + leftOfCenter * 10 - rightOfCenter * 20 + cornerCase * !vertical * (onLeft * 10 - onRight * 20); qreal y1 = y + aboveCenter * 10 - belowCenter * 20 + cornerCase * vertical * (above * 10 - below * 20);; point1.setX(x1); point1.setY(y1); qreal x2 = x + leftOfCenter * 20 - rightOfCenter * 10 + cornerCase * !vertical * (onLeft * 20 - onRight * 10);; qreal y2 = y + aboveCenter * 20 - belowCenter * 10 + cornerCase * vertical * (above * 20 - below * 10);; point2.setX(x2); point2.setY(y2); path.moveTo(point1); path.lineTo(mapFromParent(m_anchor)); path.lineTo(point2); path = path.simplified(); } painter->setBrush(chart->backgroundBrush()); QPen pen = axis->linePen(); pen.setWidth(1); painter->setPen(pen); painter->drawPath(path); painter->setPen(QPen(axis->labelsBrush().color())); painter->setBrush(axis->labelsBrush()); painter->drawText(m_textRect, m_text); } private: QString m_text; QRectF m_textRect; QRectF m_rect; QPointF m_anchor; QChart *chart; QAbstractAxis *axis; }; void CategoriesComparisonChart::onSeriesHovered(bool state, int index, QBarSet *set) { if(state) { QAbstractBarSeries *series = qobject_cast(sender()); PointLabel2 *item; if(!point_label) { item = new PointLabel2(chart, axis_x); point_label = item; } else { item = (PointLabel2*) point_label; item->setAxis(axis_x); } QList barsets = series->barSets(); int set_index = barsets.indexOf(set); QPointF pos; qreal bar_width = 0.0; pos = chart->mapToPosition(QPointF(set->at(index), index), series); QPointF pos_next = chart->mapToPosition(QPointF(set->at(index), index + 1), series); bar_width = (pos_next.y() - pos.y()) * series->barWidth(); qreal pos_y = pos.y() - (bar_width / 2); pos_y += (set_index + 0.5) * (bar_width / barsets.count()); pos.setY(pos_y); Currency *currency = budget->defaultCurrency(); if(accountCombo->isEnabled() && accountCombo->selectedAccounts().count() == 1) currency = ((AssetsAccount*) accountCombo->selectedAccounts()[0])->currency(); item->setText(tr("%1\nValue: %2").arg(((QBarCategoryAxis*) axis_y)->at(index)).arg(currency->formatValue(set->at(index)))); item->setAnchor(pos); item->setPos(pos + QPoint(10, -50)); item->setZValue(11); if(pos.x() + item->boundingRect().width() + 10 > chart->size().width()) { item->setPos(pos + QPoint(-10 - item->boundingRect().width(), -50)); } item->show(); } else if(point_label) { point_label->hide(); } } #endif Eqonomize-1.5.3/src/categoriescomparisonchart.h000066400000000000000000000071171416454732000217040ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016-2020 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifndef CATEGORIES_COMPARISON_CHART_H #define CATEGORIES_COMPARISON_CHART_H #include #include #include #ifdef QT_CHARTS_LIB #include #include #include #include #include #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) QT_CHARTS_USE_NAMESPACE #endif class QGraphicsItem; #else class QGraphicsScene; class QGraphicsView; #endif class QButtonGroup; class QCheckBox; class QComboBox; class QPushButton; class QRadioButton; class QDateEdit; class AccountsCombo; class CategoryAccount; class AssetsAccount; class Budget; class CategoriesComparisonChart : public QWidget { Q_OBJECT public: CategoriesComparisonChart(Budget *budg, QWidget *parent); ~CategoriesComparisonChart(); protected: Budget *budget; QDate from_date, to_date; CategoryAccount *current_account; QCheckBox *fromButton; QDateEdit *fromEdit, *toEdit; QPushButton *nextYearButton, *prevYearButton, *nextMonthButton, *prevMonthButton; QPushButton *saveButton, *printButton; QRadioButton *percentButton, *valueButton; #ifdef QT_CHARTS_LIB QChartView *view; QChart *chart; QAbstractSeries *series; QAbstractAxis *axis_x, *axis_y; QComboBox *themeCombo; QComboBox *typeCombo; QGraphicsItem *point_label; #else QGraphicsScene *scene; QGraphicsView *view; #endif QButtonGroup *typeGroup; QComboBox *sourceCombo; AccountsCombo *accountCombo; #ifndef QT_CHARTS_LIB void resizeEvent(QResizeEvent*); #endif public slots: void resetOptions(); void updateTransactions(); void updateAccounts(); void updateDisplay(); void onFilterSelected(QString); void save(); void print(); void saveConfig(); void fromChanged(const QDate&); void toChanged(const QDate&); void prevMonth(); void nextMonth(); void prevYear(); void nextYear(); void sourceChanged(int); void valueTypeToggled(int, bool); #ifdef QT_CHARTS_LIB void themeChanged(int); void typeChanged(int); void onSeriesHovered(bool, int, QBarSet*); void sliceHovered(QPieSlice*, bool); void sliceClicked(QPieSlice*); void legendClicked(); #endif }; #endif Eqonomize-1.5.3/src/categoriescomparisonreport.cpp000066400000000000000000003101271416454732000224470ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016-2020 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include "categoriescomparisonreport.h" #include "eqonomize.h" #include "eqonomizevalueedit.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "account.h" #include "budget.h" #include "recurrence.h" #include "transaction.h" #include "overtimereport.h" #include extern QString htmlize_string(QString str); extern QString last_document_directory; CategoriesComparisonReport::CategoriesComparisonReport(Budget *budg, QWidget *parent, bool extra_parameters) : QWidget(parent), budget(budg), b_extra(extra_parameters) { QVBoxLayout *layout = new QVBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); QDialogButtonBox *buttons = new QDialogButtonBox(this); saveButton = buttons->addButton(tr("Save As…"), QDialogButtonBox::ActionRole); saveButton->setAutoDefault(false); printButton = buttons->addButton(tr("Print…"), QDialogButtonBox::ActionRole); printButton->setAutoDefault(false); layout->addWidget(buttons); htmlview = new QTextEdit(this); htmlview->setReadOnly(true); layout->addWidget(htmlview); QSettings settings; settings.beginGroup("CategoriesComparisonReport"); QWidget *settingsWidget = new QWidget(this); QGridLayout *settingsLayout = new QGridLayout(settingsWidget); settingsLayout->addWidget(new QLabel(tr("Source:"), settingsWidget), 0, 0); QHBoxLayout *sourceLayout = new QHBoxLayout(); settingsLayout->addLayout(sourceLayout, 0, 1); sourceCombo = new QComboBox(settingsWidget); sourceCombo->setEditable(false); sourceCombo->addItem(tr("All Categories, excluding subcategories")); sourceCombo->addItem(tr("All Categories, including subcategories")); sourceCombo->addItem(tr("All Tags")); if(b_extra) { sourceCombo->addItem(tr("All Payees and Payers")); first_source_account_index = 4; } else { first_source_account_index = 3; } for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) { Account *account = *it; sourceCombo->addItem(tr("Expenses: %1").arg(account->nameWithParent())); } for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) { Account *account = *it; sourceCombo->addItem(tr("Incomes: %1").arg(account->nameWithParent())); } for(int i2 = 0; i2 < budget->tags.count(); i2++) { sourceCombo->addItem(tr("Tag: %1").arg(budget->tags[i2])); } sourceLayout->addWidget(sourceCombo); sourceLayout->setStretchFactor(sourceCombo, 2); accountCombo = new AccountsCombo(budget, settingsWidget, true); accountCombo->updateAccounts(ACCOUNT_TYPE_ASSETS); payeeDescriptionWidget = new QWidget(settingsWidget); QHBoxLayout *payeeLayout = new QHBoxLayout(payeeDescriptionWidget); QButtonGroup *group = new QButtonGroup(this); subsButton = new QRadioButton(tr("Subcategories"), payeeDescriptionWidget); subsButton->setChecked(true); group->addButton(subsButton); payeeLayout->addWidget(subsButton); descriptionButton = new QRadioButton(b_extra ? tr("Descriptions for", "Referring to the transaction description property (transaction title/generic article name)") : tr("Descriptions", "Referring to the transaction description property (transaction title/generic article name)"), payeeDescriptionWidget); group->addButton(descriptionButton); payeeLayout->addWidget(descriptionButton); if(b_extra) { sourceLayout->addWidget(accountCombo); payeeCombo = new DescriptionsCombo(4, budget, payeeDescriptionWidget); payeeLayout->addWidget(payeeCombo); payeeLayout->setStretchFactor(payeeCombo, 1); payeeButton = new QRadioButton(tr("Payees/payers for"), payeeDescriptionWidget); group->addButton(payeeButton); payeeLayout->addWidget(payeeButton); descriptionCombo = new DescriptionsCombo(0, budget, payeeDescriptionWidget); payeeLayout->addWidget(descriptionCombo); payeeLayout->setStretchFactor(descriptionCombo, 1); settingsLayout->addWidget(payeeDescriptionWidget, 1, 1); payeeDescriptionWidget->setEnabled(false); } else { sourceLayout->addWidget(payeeDescriptionWidget); sourceLayout->addWidget(accountCombo); } sourceLayout->setStretchFactor(accountCombo, 1); current_account = NULL; settingsLayout->addWidget(new QLabel(tr("Period:"), settingsWidget), b_extra ? 2 : 1, 0); QHBoxLayout *choicesLayout = new QHBoxLayout(); settingsLayout->addLayout(choicesLayout, b_extra ? 2 : 1, 1); fromButton = new QCheckBox(tr("From"), settingsWidget); fromButton->setChecked(true); choicesLayout->addWidget(fromButton); fromEdit = new EqonomizeDateEdit(settingsWidget); fromEdit->setCalendarPopup(true); choicesLayout->addWidget(fromEdit); choicesLayout->setStretchFactor(fromEdit, 1); choicesLayout->addWidget(new QLabel(tr("To"), settingsWidget)); toEdit = new EqonomizeDateEdit(settingsWidget); toEdit->setCalendarPopup(true); choicesLayout->addWidget(toEdit); choicesLayout->setStretchFactor(toEdit, 1); prevYearButton = new QPushButton(LOAD_ICON("eqz-previous-year"), "", settingsWidget); choicesLayout->addWidget(prevYearButton); prevMonthButton = new QPushButton(LOAD_ICON("eqz-previous-month"), "", settingsWidget); choicesLayout->addWidget(prevMonthButton); nextMonthButton = new QPushButton(LOAD_ICON("eqz-next-month"), "", settingsWidget); choicesLayout->addWidget(nextMonthButton); nextYearButton = new QPushButton(LOAD_ICON("eqz-next-year"), "", settingsWidget); choicesLayout->addWidget(nextYearButton); choicesLayout->addStretch(1); settingsLayout->addWidget(new QLabel(tr("Columns:"), settingsWidget), b_extra ? 3 : 2, 0); QHBoxLayout *enabledLayout = new QHBoxLayout(); group = new QButtonGroup(this); monthsButton = new QRadioButton(tr("Months"), settingsWidget); group->addButton(monthsButton, 1); enabledLayout->addWidget(monthsButton); yearsButton = new QRadioButton(tr("Years"), settingsWidget); group->addButton(yearsButton, 2); enabledLayout->addWidget(yearsButton); tagsButton = new QRadioButton(tr("Tags"), settingsWidget); group->addButton(tagsButton, 3); enabledLayout->addWidget(tagsButton); totalButton = new QRadioButton(tr("Total:"), settingsWidget); group->addButton(totalButton, 0); enabledLayout->addWidget(totalButton); switch(settings.value("columns", 0).toInt()) { case 1: {monthsButton->setChecked(true); break;} case 2: {yearsButton->setChecked(true); break;} case 3: {tagsButton->setChecked(true); break;} default: {totalButton->setChecked(true); break;} } settingsLayout->addLayout(enabledLayout, b_extra ? 3 : 2, 1); valueButton = new QCheckBox(tr("Value"), settingsWidget); valueButton->setChecked(settings.value("valueEnabled", true).toBool()); enabledLayout->addWidget(valueButton); dailyButton = new QCheckBox(tr("Daily"), settingsWidget); dailyButton->setChecked(settings.value("dailyAverageEnabled", true).toBool()); enabledLayout->addWidget(dailyButton); monthlyButton = new QCheckBox(tr("Monthly"), settingsWidget); monthlyButton->setChecked(settings.value("monthlyAverageEnabled", true).toBool()); enabledLayout->addWidget(monthlyButton); yearlyButton = new QCheckBox(tr("Yearly"), settingsWidget); yearlyButton->setChecked(settings.value("yearlyEnabled", false).toBool()); enabledLayout->addWidget(yearlyButton); countButton = new QCheckBox(tr("Quantity"), settingsWidget); countButton->setChecked(settings.value("transactionCountEnabled", true).toBool()); enabledLayout->addWidget(countButton); perButton = new QCheckBox(tr("Average value"), settingsWidget); perButton->setChecked(settings.value("valuePerTransactionEnabled", false).toBool()); enabledLayout->addWidget(perButton); enabledLayout->addStretch(1); valueButton->setEnabled(totalButton->isChecked()); dailyButton->setEnabled(totalButton->isChecked()); monthlyButton->setEnabled(totalButton->isChecked()); yearlyButton->setEnabled(totalButton->isChecked()); countButton->setEnabled(totalButton->isChecked()); perButton->setEnabled(totalButton->isChecked()); settings.endGroup(); layout->addWidget(settingsWidget); resetOptions(); #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) connect(group, SIGNAL(idToggled(int, bool)), this, SLOT(columnsToggled(int, bool))); #else connect(group, SIGNAL(buttonToggled(int, bool)), this, SLOT(columnsToggled(int, bool))); #endif connect(subsButton, SIGNAL(toggled(bool)), this, SLOT(subsToggled(bool))); connect(descriptionButton, SIGNAL(toggled(bool)), this, SLOT(descriptionToggled(bool))); if(b_extra) { connect(payeeButton, SIGNAL(toggled(bool)), this, SLOT(payeeToggled(bool))); connect(payeeCombo, SIGNAL(selectedItemsChanged()), this, SLOT(payeeChanged())); connect(descriptionCombo, SIGNAL(selectedItemsChanged()), this, SLOT(descriptionChanged())); } connect(sourceCombo, SIGNAL(activated(int)), this, SLOT(sourceChanged(int))); connect(accountCombo, SIGNAL(selectedAccountsChanged()), this, SLOT(updateDisplay())); connect(valueButton, SIGNAL(toggled(bool)), this, SLOT(updateDisplay())); connect(dailyButton, SIGNAL(toggled(bool)), this, SLOT(updateDisplay())); connect(monthlyButton, SIGNAL(toggled(bool)), this, SLOT(updateDisplay())); connect(yearlyButton, SIGNAL(toggled(bool)), this, SLOT(updateDisplay())); connect(countButton, SIGNAL(toggled(bool)), this, SLOT(updateDisplay())); connect(perButton, SIGNAL(toggled(bool)), this, SLOT(updateDisplay())); connect(prevMonthButton, SIGNAL(clicked()), this, SLOT(prevMonth())); connect(nextMonthButton, SIGNAL(clicked()), this, SLOT(nextMonth())); connect(prevYearButton, SIGNAL(clicked()), this, SLOT(prevYear())); connect(nextYearButton, SIGNAL(clicked()), this, SLOT(nextYear())); connect(fromButton, SIGNAL(toggled(bool)), fromEdit, SLOT(setEnabled(bool))); connect(fromButton, SIGNAL(toggled(bool)), this, SLOT(updateDisplay())); connect(fromEdit, SIGNAL(dateChanged(const QDate&)), this, SLOT(fromChanged(const QDate&))); connect(toEdit, SIGNAL(dateChanged(const QDate&)), this, SLOT(toChanged(const QDate&))); connect(saveButton, SIGNAL(clicked()), this, SLOT(save())); connect(printButton, SIGNAL(clicked()), this, SLOT(print())); } void CategoriesComparisonReport::resetOptions() { block_display_update = true; QDate first_date; for(TransactionList::const_iterator it = budget->transactions.constBegin(); it != budget->transactions.constEnd(); ++it) { Transaction *trans = *it; if(trans->fromAccount()->type() != ACCOUNT_TYPE_ASSETS || trans->toAccount()->type() != ACCOUNT_TYPE_ASSETS) { first_date = trans->date(); break; } } to_date = QDate::currentDate(); from_date = to_date.addYears(-1).addDays(1); if(first_date.isNull()) { from_date = to_date; } else if(from_date < first_date) { from_date = first_date; } subsButton->setChecked(false); fromEdit->setDate(from_date); toEdit->setDate(to_date); fromButton->setChecked(true); columnsToggled(tagsButton->isChecked() ? 3 : (yearsButton->isChecked() ? 2 : (monthsButton->isChecked() ? 1 : 0)), true); sourceCombo->setCurrentIndex(0); accountCombo->blockSignals(true); accountCombo->deselectAll(); accountCombo->blockSignals(false); block_display_update = false; sourceChanged(0); } void CategoriesComparisonReport::payeeToggled(bool b) { if(b) updateDisplay(); } void CategoriesComparisonReport::descriptionToggled(bool b) { if(b) updateDisplay(); } void CategoriesComparisonReport::subsToggled(bool b) { if(b) updateDisplay(); } void CategoriesComparisonReport::columnsToggled(int id, bool b) { if(!b) return; valueButton->setEnabled(id == 0); dailyButton->setEnabled(id == 0); monthlyButton->setEnabled(id == 0); yearlyButton->setEnabled(id == 0); countButton->setEnabled(id == 0); perButton->setEnabled(id == 0); if(id == 1) { QDate first_date = budget->firstBudgetDay(from_date); if(!budget->isLastBudgetDay(to_date)) budget->addBudgetMonthsSetLast(to_date, -1); from_date = budget->firstBudgetDay(to_date); if(to_date < first_date) { budget->addBudgetMonthsSetLast(to_date, 1); from_date = first_date; } else { for(int i = 1; i < 12 && from_date > first_date; i++) { budget->addBudgetMonthsSetFirst(from_date, -1); } } fromButton->blockSignals(true); fromButton->setChecked(true); fromButton->blockSignals(false); toEdit->blockSignals(true); toEdit->setDate(to_date); toEdit->blockSignals(false); fromEdit->blockSignals(true); fromEdit->setDate(from_date); fromEdit->blockSignals(false); } else if(id == 2) { if(to_date != budget->lastBudgetDayOfYear(to_date)) { budget->addBudgetMonthsSetLast(to_date, -12); to_date = budget->lastBudgetDayOfYear(to_date); } QDate first_date; for(TransactionList::const_iterator it = budget->transactions.constBegin(); it != budget->transactions.constEnd(); ++it) { Transaction *trans = *it; if(trans->fromAccount()->type() != ACCOUNT_TYPE_ASSETS || trans->toAccount()->type() != ACCOUNT_TYPE_ASSETS) { first_date = trans->date(); break; } } if(first_date.isNull()) { first_date = QDate::currentDate(); to_date = QDate::currentDate(); } else { if(budget->dayOfBudgetYear(first_date) > 15) { budget->addBudgetMonthsSetFirst(first_date, 12); first_date = budget->firstBudgetDayOfYear(first_date); } int year1 = budget->budgetYear(first_date); int year2 = budget->budgetYear(to_date); if(year2 - year1 < 1) to_date = QDate::currentDate(); } fromButton->blockSignals(true); fromButton->setChecked(false); fromButton->blockSignals(false); toEdit->blockSignals(true); toEdit->setDate(to_date); toEdit->blockSignals(false); } else { fromButton->blockSignals(true); fromButton->setChecked(true); fromButton->blockSignals(false); } fromEdit->setEnabled(fromButton->isChecked()); updateDisplay(); } void CategoriesComparisonReport::payeeChanged() { payeeButton->blockSignals(true); descriptionButton->blockSignals(true); descriptionButton->setChecked(true); payeeButton->setChecked(false); payeeButton->blockSignals(false); descriptionButton->blockSignals(false); updateDisplay(); } void CategoriesComparisonReport::descriptionChanged() { payeeButton->blockSignals(true); descriptionButton->blockSignals(true); payeeButton->setChecked(true); descriptionButton->setChecked(false); payeeButton->blockSignals(false); descriptionButton->blockSignals(false); updateDisplay(); } void CategoriesComparisonReport::sourceChanged(int i) { if(first_source_account_index == 3 && i >= 3) i++; i -= 3; current_account = NULL; current_tag = ""; if(i > 0) { if(i - 1 < budget->expensesAccounts.count()) current_account = budget->expensesAccounts.at(i - 1); else if(i - 1 - budget->expensesAccounts.count() < budget->incomesAccounts.count()) current_account = budget->incomesAccounts.at(i - 1 - budget->expensesAccounts.count()); else if(i - 1 - budget->expensesAccounts.count() - budget->incomesAccounts.count() < budget->tags.count()) current_tag = budget->tags.at(i - 1 - budget->expensesAccounts.count() - budget->incomesAccounts.count()); i++; } if((current_account && current_account->subCategories.isEmpty()) || !current_tag.isEmpty()) { subsButton->setEnabled(false); if(subsButton->isChecked()) { descriptionButton->blockSignals(true); descriptionButton->setChecked(true); descriptionButton->blockSignals(false); } } else { subsButton->setEnabled(true); } payeeDescriptionWidget->setEnabled(i > 0 && (current_account || !current_tag.isEmpty())); if(b_extra) { payeeCombo->blockSignals(true); descriptionCombo->blockSignals(true); if(i <= 0) { current_account = NULL; current_tag = ""; payeeCombo->clear(); descriptionCombo->clear(); } else { if(current_account || !current_tag.isEmpty()) { descriptionCombo->addItem(tr("All descriptions", "Referring to the transaction description property (transaction title/generic article name)")); QMap descriptions, payees; bool b_income, b_expense; for(TransactionList::const_iterator it = budget->transactions.constEnd(); it != budget->transactions.constBegin();) { --it; Transaction *trans = *it; if((!current_account && trans->hasTag(current_tag, true) && ((trans->type() == TRANSACTION_TYPE_EXPENSE || trans->type() == TRANSACTION_TYPE_INCOME))) || (current_account && (trans->fromAccount() == current_account || trans->toAccount() == current_account))) { if(!descriptions.contains(trans->description().toLower())) descriptions[trans->description().toLower()] = trans->description(); if(trans->type() == TRANSACTION_TYPE_EXPENSE) { b_expense = true; if(!payees.contains(((Expense*) trans)->payee().toLower())) payees[((Expense*) trans)->payee().toLower()] = ((Expense*) trans)->payee(); } else if(trans->type() == TRANSACTION_TYPE_INCOME) { b_income = true; if(!payees.contains(((Income*) trans)->payer().toLower())) payees[((Income*) trans)->payer().toLower()] = ((Income*) trans)->payer(); } } } if((!current_account && b_expense && !b_income) || (current_account && current_account->type() == ACCOUNT_TYPE_EXPENSES)) payeeCombo->setItemType(2); else if(current_account || (!b_expense && b_income)) payeeCombo->setItemType(3); else payeeCombo->setItemType(4); QStringList dlist; QMap::iterator it_e = descriptions.end(); for(QMap::iterator it = descriptions.begin(); it != it_e; ++it) { dlist << *it; } descriptionCombo->updateItems(dlist); QStringList plist; QMap::iterator it2_e = payees.end(); for(QMap::iterator it2 = payees.begin(); it2 != it2_e; ++it2) { plist << it2.value(); } payeeCombo->updateItems(plist); } } payeeCombo->blockSignals(false); descriptionCombo->blockSignals(false); } updateDisplay(); } void CategoriesComparisonReport::saveConfig() { QSettings settings; settings.beginGroup("CategoriesComparisonReport"); settings.setValue("size", ((QDialog*) parent())->size()); settings.setValue("columns", tagsButton->isChecked() ? 3 : (yearsButton->isChecked() ? 2 : (monthsButton->isChecked() ? 1 : 0))); settings.setValue("valueEnabled", valueButton->isChecked()); settings.setValue("dailyAverageEnabled", dailyButton->isChecked()); settings.setValue("monthlyAverageEnabled", monthlyButton->isChecked()); settings.setValue("yearlyAverageEnabled", yearlyButton->isChecked()); settings.setValue("transactionCountEnabled", countButton->isChecked()); settings.setValue("valuePerTransactionEnabled", perButton->isChecked()); settings.endGroup(); } void CategoriesComparisonReport::toChanged(const QDate &date) { bool error = false; if(!date.isValid()) { QMessageBox::critical(this, tr("Error"), tr("Invalid date.")); error = true; } if(!error && fromEdit->date() > date) { /*if(fromButton->isChecked()) { QMessageBox::critical(this, tr("Error"), tr("To date is before from date.")); }*/ if(budget->isFirstBudgetDay(to_date)) { from_date = budget->firstBudgetDay(date); } else { from_date = date.addDays(-from_date.daysTo(to_date)); } from_date = date; fromEdit->blockSignals(true); fromEdit->setDate(from_date); fromEdit->blockSignals(false); } if(error) { toEdit->setFocus(); toEdit->blockSignals(true); toEdit->setDate(to_date); toEdit->blockSignals(false); toEdit->selectAll(); return; } to_date = date; updateDisplay(); } void CategoriesComparisonReport::fromChanged(const QDate &date) { bool error = false; if(!date.isValid()) { QMessageBox::critical(this, tr("Error"), tr("Invalid date.")); error = true; } if(!error && date > toEdit->date()) { //QMessageBox::critical(this, tr("Error"), tr("From date is after to date.")); if(budget->isLastBudgetDay(to_date)) { to_date = budget->lastBudgetDay(date); } else { to_date = date.addDays(from_date.daysTo(to_date)); } if(to_date > QDate::currentDate() && from_date <= QDate::currentDate()) to_date = QDate::currentDate(); toEdit->blockSignals(true); toEdit->setDate(to_date); toEdit->blockSignals(false); } if(error) { fromEdit->setFocus(); fromEdit->blockSignals(true); fromEdit->setDate(from_date); fromEdit->blockSignals(false); fromEdit->selectAll(); return; } from_date = date; if(fromButton->isChecked()) updateDisplay(); } void CategoriesComparisonReport::prevMonth() { fromEdit->blockSignals(true); toEdit->blockSignals(true); budget->goForwardBudgetMonths(from_date, to_date, -1); fromEdit->setDate(from_date); toEdit->setDate(to_date); fromEdit->blockSignals(false); toEdit->blockSignals(false); updateDisplay(); } void CategoriesComparisonReport::nextMonth() { fromEdit->blockSignals(true); toEdit->blockSignals(true); budget->goForwardBudgetMonths(from_date, to_date, 1); fromEdit->setDate(from_date); toEdit->setDate(to_date); fromEdit->blockSignals(false); toEdit->blockSignals(false); updateDisplay(); } void CategoriesComparisonReport::prevYear() { fromEdit->blockSignals(true); toEdit->blockSignals(true); budget->goForwardBudgetMonths(from_date, to_date, -12); fromEdit->setDate(from_date); toEdit->setDate(to_date); fromEdit->blockSignals(false); toEdit->blockSignals(false); updateDisplay(); } void CategoriesComparisonReport::nextYear() { fromEdit->blockSignals(true); toEdit->blockSignals(true); budget->goForwardBudgetMonths(from_date, to_date, 12); fromEdit->setDate(from_date); toEdit->setDate(to_date); fromEdit->blockSignals(false); toEdit->blockSignals(false); updateDisplay(); } void CategoriesComparisonReport::save() { QMimeDatabase db; QFileDialog fileDialog(this); fileDialog.setNameFilter(db.mimeTypeForName("text/html").filterString()); fileDialog.setDefaultSuffix(db.mimeTypeForName("text/html").preferredSuffix()); fileDialog.setAcceptMode(QFileDialog::AcceptSave); #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) fileDialog.setSupportedSchemes(QStringList("file")); #endif fileDialog.setDirectory(last_document_directory); QString url; if(!fileDialog.exec()) return; QStringList urls = fileDialog.selectedFiles(); if(urls.isEmpty()) return; url = urls[0]; QSaveFile ofile(url); ofile.open(QIODevice::WriteOnly); ofile.setPermissions((QFile::Permissions) 0x0660); if(!ofile.isOpen()) { ofile.cancelWriting(); QMessageBox::critical(this, tr("Error"), tr("Couldn't open file for writing.")); return; } last_document_directory = fileDialog.directory().absolutePath(); QTextStream outf(&ofile); #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) outf.setCodec("UTF-8"); #endif outf << source; if(!ofile.commit()) { QMessageBox::critical(this, tr("Error"), tr("Error while writing file; file was not saved.")); return; } } void CategoriesComparisonReport::print() { QPrinter printer; QPrintDialog print_dialog(&printer, this); if(print_dialog.exec() == QDialog::Accepted) { htmlview->print(&printer); } } void CategoriesComparisonReport::updateDisplay() { if(!isVisible() || block_display_update) return; int columns = 1; bool enabled[6]; enabled[0] = valueButton->isChecked(); enabled[1] = dailyButton->isChecked(); enabled[2] = monthlyButton->isChecked(); enabled[3] = yearlyButton->isChecked(); enabled[4] = countButton->isChecked(); enabled[5] = perButton->isChecked(); for(size_t i = 0; i < 6; i++) { if(enabled[i]) columns++; } QMap > month_values; QMap > desc_month_values; QMap > tag_month_values; QMap > tag_values; QMap > desc_tag_values; QMap values; QMap counts; QMap desc_map; QMap desc_values; QMap desc_counts; QMap tag_value, tag_incomes, tag_costs, tag_counts; double incomes = 0.0, costs = 0.0; QVector month_incomes, month_costs, month_value; double incomes_count = 0.0, costs_count = 0.0; double value_count = 0.0; double value = 0.0; current_account = NULL; current_tag = ""; bool b_expense = false, b_income = false; bool assets_selected = accountCombo->isEnabled() && !accountCombo->allAccountsSelected(); bool description_selected = b_extra && payeeButton->isChecked() && descriptionCombo->isEnabled() && !descriptionCombo->allItemsSelected(); bool payee_selected = b_extra && descriptionButton->isChecked() && payeeCombo->isEnabled() && !payeeCombo->allItemsSelected(); bool include_subs = false; int i_source = sourceCombo->currentIndex(); if(first_source_account_index == 3 && i_source >= 3) i_source++; if(i_source == 1) { i_source = 0; include_subs = true; } else if(i_source == 2) { i_source = -2; } else if(i_source == 3) { i_source = -1; } else if(i_source > 3) { i_source -= 3; if(i_source - 1 < budget->expensesAccounts.count()) current_account = budget->expensesAccounts.at(i_source - 1); else if(i_source - 1 - budget->expensesAccounts.count() < budget->incomesAccounts.count()) current_account = budget->incomesAccounts.at(i_source - 1 - budget->expensesAccounts.count()); else if(i_source - 1 - budget->expensesAccounts.count() - budget->incomesAccounts.count() < budget->tags.count()) current_tag = budget->tags.at(i_source - 1 - budget->expensesAccounts.count() - budget->incomesAccounts.count()); if(!current_account && current_tag.isEmpty()) return; if(b_extra) { if(current_account && subsButton->isChecked()) { i_source = 1; include_subs = !current_account->subCategories.isEmpty(); } else if(descriptionButton->isChecked()) { if(!payee_selected) { i_source = 1; } else { i_source = 3; } } else { if(!description_selected) { i_source = 2; } else { i_source = 4; } } } else { i_source = 1; include_subs = current_account && subsButton->isChecked() && !current_account->subCategories.isEmpty(); } } QDate first_date, last_date, curmonth; if(fromButton->isChecked()) { first_date = from_date; } else { for(TransactionList::const_iterator it = budget->transactions.constBegin(); it != budget->transactions.constEnd(); ++it) { Transaction *trans = *it; if(trans->fromAccount()->type() != ACCOUNT_TYPE_ASSETS || trans->toAccount()->type() != ACCOUNT_TYPE_ASSETS) { first_date = trans->date(); break; } } if(first_date.isNull()) first_date = QDate::currentDate(); if(first_date > to_date) first_date = to_date; } last_date = to_date; int i_months = 0; bool b_years = false; if(monthsButton->isChecked()) { curmonth = budget->lastBudgetDay(first_date); i_months = 1; while(curmonth < last_date) { budget->addBudgetMonthsSetLast(curmonth, 1); i_months++; } } else if(yearsButton->isChecked()) { if(!fromButton->isChecked()) { int year1 = budget->budgetYear(first_date); int year2 = budget->budgetYear(last_date); if(year2 - year1 > 1 && budget->dayOfBudgetYear(first_date) > 15) { budget->addBudgetMonthsSetFirst(first_date, 12); first_date = budget->firstBudgetDayOfYear(first_date); } } b_years = true; curmonth = budget->lastBudgetDayOfYear(first_date); i_months = 1; while(curmonth < last_date) { budget->addBudgetMonthsSetLast(curmonth, 12); i_months++; } } bool b_tags = tagsButton->isChecked(); if(b_tags) { columns = budget->tags.count() + 2; for(size_t i = 0; i < 6; i++) { enabled[i] = false; } for(int i = 0; i < budget->tags.count(); i++) { tag_value[budget->tags[i]] = 0.0; tag_costs[budget->tags[i]] = 0.0; tag_incomes[budget->tags[i]] = 0.0; } } if(i_months > 0) { columns = i_months + 2; for(size_t i = 0; i < 6; i++) { enabled[i] = false; } month_value.fill(0.0, i_months); month_costs.fill(0.0, i_months); month_incomes.fill(0.0, i_months); } AccountType type = ACCOUNT_TYPE_EXPENSES; if(current_account) type = current_account->type(); switch(i_source) { case -2: { for(int i = 0; i < budget->tags.count(); i++) { desc_values[budget->tags[i]] = 0.0; desc_counts[budget->tags[i]] = 0.0; desc_map[budget->tags[i]] = budget->tags[i]; if(i_months > 0) desc_month_values[budget->tags[i]].fill(0.0, i_months); if(b_tags) { for(int i2 = 0; i2 < budget->tags.count(); i2++) desc_tag_values[budget->tags[i]][budget->tags[i2]] = 0.0; } } break; } case -1: { for(TransactionList::const_iterator it = budget->transactions.constEnd(); it != budget->transactions.constBegin();) { --it; Transaction *trans = *it; if(trans->date() <= last_date && (!assets_selected || accountCombo->testTransactionRelation(trans))) { if(trans->date() < first_date) break; if(trans->type() == TRANSACTION_TYPE_EXPENSE && !desc_map.contains(((Expense*) trans)->payee().toLower())) { QString desc = ((Expense*) trans)->payee().toLower(); desc_map[desc] = ((Expense*) trans)->payee(); desc_values[desc] = 0.0; desc_counts[desc] = 0.0; if(i_months > 0) desc_month_values[desc].fill(0.0, i_months); if(b_tags) { for(int i = 0; i < budget->tags.count(); i++) desc_tag_values[desc][budget->tags[i]] = 0.0; } } else if(trans->type() == TRANSACTION_TYPE_INCOME && !desc_map.contains(((Income*) trans)->payer().toLower())) { QString desc = ((Income*) trans)->payer().toLower(); desc_map[desc] = ((Income*) trans)->payer(); desc_values[desc] = 0.0; desc_counts[desc] = 0.0; if(i_months > 0) desc_month_values[desc].fill(0.0, i_months); if(b_tags) { for(int i = 0; i < budget->tags.count(); i++) desc_tag_values[desc][budget->tags[i]] = 0.0; } } } } Transaction *trans = NULL; int split_i = 0; for(ScheduledTransactionList::const_iterator it = budget->scheduledTransactions.constBegin(); it != budget->scheduledTransactions.constEnd();) { ScheduledTransaction *strans = *it; while(split_i == 0 && strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT && ((SplitTransaction*) strans->transaction())->count() == 0) { ++it; if(it == budget->scheduledTransactions.constEnd()) break; strans = *it; } if(strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { trans = ((SplitTransaction*) strans->transaction())->at(split_i); split_i++; } else { trans = (Transaction*) strans->transaction(); } if(trans->date() >= first_date && (!assets_selected || accountCombo->testTransactionRelation(trans))) { if(trans->date() > last_date) break; if(trans->type() == TRANSACTION_TYPE_EXPENSE && !desc_map.contains(((Expense*) trans)->payee().toLower())) { QString desc = ((Expense*) trans)->payee().toLower(); desc_map[desc] = ((Expense*) trans)->payee(); desc_values[desc] = 0.0; desc_counts[desc] = 0.0; if(i_months > 0) desc_month_values[desc].fill(0.0, i_months); if(b_tags) { for(int i = 0; i < budget->tags.count(); i++) desc_tag_values[desc][budget->tags[i]] = 0.0; } } else if(trans->type() == TRANSACTION_TYPE_INCOME && !desc_map.contains(((Income*) trans)->payer().toLower())) { QString desc = ((Income*) trans)->payer().toLower(); desc_map[desc] = ((Income*) trans)->payer(); desc_values[desc] = 0.0; desc_counts[desc] = 0.0; if(i_months > 0) desc_month_values[desc].fill(0.0, i_months); if(b_tags) { for(int i = 0; i < budget->tags.count(); i++) desc_tag_values[desc][budget->tags[i]] = 0.0; } } } if(strans->transaction()->generaltype() != GENERAL_TRANSACTION_TYPE_SPLIT || split_i >= ((SplitTransaction*) strans->transaction())->count()) { ++it; split_i = 0; } } } case 0: { for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) { CategoryAccount *account = *it; if(include_subs || !account->parentCategory()) { values[account] = 0.0; counts[account] = 0.0; if(i_months > 0) month_values[account].fill(0.0, i_months); if(b_tags) { for(int i = 0; i < budget->tags.count(); i++) tag_values[account][budget->tags[i]] = 0.0; } } } for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) { CategoryAccount *account = *it; if(include_subs || !account->parentCategory()) { values[account] = 0.0; counts[account] = 0.0; if(i_months > 0) month_values[account].fill(0.0, i_months); if(b_tags) { for(int i = 0; i < budget->tags.count(); i++) tag_values[account][budget->tags[i]] = 0.0; } } } if(i_months > 0) month_values[budget->null_incomes_account].fill(0.0, i_months); if(b_tags) { for(int i = 0; i < budget->tags.count(); i++) tag_values[budget->null_incomes_account][budget->tags[i]] = 0.0; } break; } default: { if(include_subs) { values[current_account] = 0.0; counts[current_account] = 0.0; if(i_months > 0) month_values[current_account].fill(0.0, i_months); if(b_tags) { for(int i = 0; i < budget->tags.count(); i++) tag_values[current_account][budget->tags[i]] = 0.0; } for(AccountList::const_iterator it = current_account->subCategories.constBegin(); it != current_account->subCategories.constEnd(); ++it) { CategoryAccount *account = *it; values[account] = 0.0; counts[account] = 0.0; if(i_months > 0) month_values[account].fill(0.0, i_months); if(b_tags) { for(int i = 0; i < budget->tags.count(); i++) tag_values[account][budget->tags[i]] = 0.0; } } } else { for(TransactionList::const_iterator it = budget->transactions.constEnd(); it != budget->transactions.constBegin();) { --it; Transaction *trans = *it; if(trans->date() <= last_date && (!assets_selected || accountCombo->testTransactionRelation(trans))) { if(trans->date() < first_date) break; if(((current_account && (trans->fromAccount() == current_account || trans->toAccount() == current_account)) || (!current_account && trans->hasTag(current_tag, true) && (trans->type() == TRANSACTION_TYPE_EXPENSE || trans->type() == TRANSACTION_TYPE_INCOME))) && (i_source <= 2 || (i_source == 4 && descriptionCombo->testTransaction(trans)) || (i_source == 3 && ((trans->type() == TRANSACTION_TYPE_EXPENSE && payeeCombo->testTransaction(trans)) || (trans->type() == TRANSACTION_TYPE_INCOME && payeeCombo->testTransaction(trans)))))) { if(i_source == 2 || i_source == 4) { if(trans->type() == TRANSACTION_TYPE_EXPENSE && !desc_map.contains(((Expense*) trans)->payee().toLower())) { QString desc = ((Expense*) trans)->payee().toLower(); desc_map[desc] = ((Expense*) trans)->payee(); desc_values[desc] = 0.0; desc_counts[desc] = 0.0; if(i_months > 0) desc_month_values[desc].fill(0.0, i_months); if(b_tags) { for(int i = 0; i < budget->tags.count(); i++) desc_tag_values[desc][budget->tags[i]] = 0.0; } } else if(trans->type() == TRANSACTION_TYPE_INCOME && !desc_map.contains(((Income*) trans)->payer().toLower())) { QString desc = ((Income*) trans)->payer().toLower(); desc_map[desc] = ((Income*) trans)->payer(); desc_values[desc] = 0.0; desc_counts[desc] = 0.0; if(i_months > 0) desc_month_values[desc].fill(0.0, i_months); if(b_tags) { for(int i = 0; i < budget->tags.count(); i++) desc_tag_values[desc][budget->tags[i]] = 0.0; } } } else if(!desc_map.contains(trans->description().toLower())) { QString desc = trans->description().toLower(); desc_map[desc] = trans->description(); desc_values[desc] = 0.0; desc_counts[desc] = 0.0; if(i_months > 0) desc_month_values[desc].fill(0.0, i_months); if(b_tags) { for(int i = 0; i < budget->tags.count(); i++) desc_tag_values[desc][budget->tags[i]] = 0.0; } } } } } Transaction *trans = NULL; int split_i = 0; for(ScheduledTransactionList::const_iterator it = budget->scheduledTransactions.constBegin(); it != budget->scheduledTransactions.constEnd();) { ScheduledTransaction *strans = *it; while(split_i == 0 && strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT && ((SplitTransaction*) strans->transaction())->count() == 0) { ++it; if(it == budget->scheduledTransactions.constEnd()) break; strans = *it; } if(strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { trans = ((SplitTransaction*) strans->transaction())->at(split_i); split_i++; } else { trans = (Transaction*) strans->transaction(); } if(trans->date() >= first_date && (!assets_selected || accountCombo->testTransactionRelation(trans))) { if(trans->date() > last_date) break; if(((current_account && (trans->fromAccount() == current_account || trans->toAccount() == current_account)) || (!current_account && trans->hasTag(current_tag, true) && (trans->type() == TRANSACTION_TYPE_EXPENSE || trans->type() == TRANSACTION_TYPE_INCOME))) && (i_source <= 2 || (i_source == 4 && descriptionCombo->testTransaction(trans)) || (i_source == 3 && ((trans->type() == TRANSACTION_TYPE_EXPENSE && payeeCombo->testTransaction(trans)) || (trans->type() == TRANSACTION_TYPE_INCOME && payeeCombo->testTransaction(trans)))))) { if(i_source == 2 || i_source == 4) { if(trans->type() == TRANSACTION_TYPE_EXPENSE && !desc_map.contains(((Expense*) trans)->payee().toLower())) { QString desc = ((Expense*) trans)->payee().toLower(); desc_map[desc] = ((Expense*) trans)->payee(); desc_values[desc] = 0.0; desc_counts[desc] = 0.0; if(i_months > 0) desc_month_values[desc].fill(0.0, i_months); if(b_tags) { for(int i = 0; i < budget->tags.count(); i++) desc_tag_values[desc][budget->tags[i]] = 0.0; } } else if(trans->type() == TRANSACTION_TYPE_INCOME && !desc_map.contains(((Income*) trans)->payer().toLower())) { QString desc = ((Income*) trans)->payer().toLower(); desc_map[desc] = ((Income*) trans)->payer(); desc_values[desc] = 0.0; desc_counts[desc] = 0.0; if(i_months > 0) desc_month_values[desc].fill(0.0, i_months); if(b_tags) { for(int i = 0; i < budget->tags.count(); i++) desc_tag_values[desc][budget->tags[i]] = 0.0; } } } else if(!desc_map.contains(trans->description().toLower())) { QString desc = trans->description().toLower(); desc_map[desc] = trans->description(); desc_values[desc] = 0.0; desc_counts[desc] = 0.0; if(i_months > 0) desc_month_values[desc].fill(0.0, i_months); if(b_tags) { for(int i = 0; i < budget->tags.count(); i++) desc_tag_values[desc][budget->tags[i]] = 0.0; } } } } if(strans->transaction()->generaltype() != GENERAL_TRANSACTION_TYPE_SPLIT || split_i >= ((SplitTransaction*) strans->transaction())->count()) { ++it; split_i = 0; } } } } } int month_index = 0; if(i_months <= 0) month_index = -1; bool first_date_reached = false; for(TransactionList::const_iterator it = budget->transactions.constBegin(); it != budget->transactions.constEnd(); ++it) { Transaction *trans = *it; if(!first_date_reached && trans->date() >= first_date) { first_date_reached = true; if(trans->date() > last_date) break; if(i_months > 0) { curmonth = (b_years ? budget->lastBudgetDayOfYear(first_date) : budget->lastBudgetDay(first_date)); while(curmonth < trans->date()) { budget->addBudgetMonthsSetLast(curmonth, b_years ? 12 : 1); month_index++; } } } else if(first_date_reached && trans->date() > last_date) { break; } else if(first_date_reached && i_months > 0 && trans->date() > curmonth) { while(curmonth < trans->date()) { budget->addBudgetMonthsSetLast(curmonth, b_years ? 12 : 1); month_index++; } } if(first_date_reached && (!assets_selected || accountCombo->testTransactionRelation(trans))) { if((current_account && !include_subs) || !current_tag.isEmpty()) { int sign = 1; bool include = false; if(current_account) { if(trans->fromAccount() == current_account && (i_source <= 2 || (i_source == 4 && descriptionCombo->testTransaction(trans)) || (i_source == 3 && ((trans->type() == TRANSACTION_TYPE_EXPENSE && payeeCombo->testTransaction(trans)) || (trans->type() == TRANSACTION_TYPE_INCOME && payeeCombo->testTransaction(trans)))))) { include = true; if(type == ACCOUNT_TYPE_INCOMES) sign = 1; else sign = -1; } else if(trans->toAccount() == current_account && (i_source <= 2 || (i_source == 4 && descriptionCombo->testTransaction(trans)) || (i_source == 3 && ((trans->type() == TRANSACTION_TYPE_EXPENSE && payeeCombo->testTransaction(trans)) || (trans->type() == TRANSACTION_TYPE_INCOME && payeeCombo->testTransaction(trans)))))) { include = true; if(type == ACCOUNT_TYPE_EXPENSES) sign = 1; else sign = -1; } } else if(trans->hasTag(current_tag, true)) { if(i_source <= 2 || (i_source == 4 && descriptionCombo->testTransaction(trans)) || (i_source == 3 && ((trans->type() == TRANSACTION_TYPE_EXPENSE && payeeCombo->testTransaction(trans)) || (trans->type() == TRANSACTION_TYPE_INCOME && payeeCombo->testTransaction(trans))))) { include = true; if(trans->type() == TRANSACTION_TYPE_EXPENSE) {b_expense = true; sign = -1;} else if(trans->type() == TRANSACTION_TYPE_INCOME) {b_income = true; sign = 1;} else include = false; } } if(include) { double v = trans->value(true) * sign; if(i_source == 2 || i_source == 4) { if(trans->type() == TRANSACTION_TYPE_EXPENSE) { value += v; value_count += trans->quantity(); QString desc = ((Expense*) trans)->payee().toLower(); desc_values[desc] += v; if(month_index >= 0) desc_month_values[desc][month_index] += v; if(month_index >= 0) month_value[month_index] += v; desc_counts[desc] += trans->quantity(); if(b_tags) { for(int i = 0; i < trans->tagsCount(true); i++) { desc_tag_values[desc][trans->getTag(i, true)] += v; tag_value[trans->getTag(i, true)] += v; } } } else if(trans->type() == TRANSACTION_TYPE_INCOME) { value += v; value_count += trans->quantity(); QString desc = ((Income*) trans)->payer().toLower(); desc_values[desc] += v; if(month_index >= 0) desc_month_values[desc][month_index] += v; if(month_index >= 0) month_value[month_index] += v; desc_counts[desc] += trans->quantity(); if(b_tags) { for(int i = 0; i < trans->tagsCount(true); i++) { desc_tag_values[desc][trans->getTag(i, true)] += v; tag_value[trans->getTag(i, true)] += v; } } } } else { value += v; value_count += trans->quantity(); QString desc = trans->description().toLower(); desc_values[desc] += v; if(month_index >= 0) desc_month_values[desc][month_index] += v; if(month_index >= 0) month_value[month_index] += v; desc_counts[desc] += trans->quantity(); if(b_tags) { for(int i = 0; i < trans->tagsCount(true); i++) { desc_tag_values[desc][trans->getTag(i, true)] += v; tag_value[trans->getTag(i, true)] += v; } } } } } else if(i_source == -1) { double v = trans->value(true); if(trans->type() == TRANSACTION_TYPE_EXPENSE) { value -= v; value_count += trans->quantity(); QString desc = ((Expense*) trans)->payee().toLower(); desc_values[desc] -= v; if(month_index >= 0) desc_month_values[desc][month_index] -= v; if(month_index >= 0) month_value[month_index] -= v; desc_counts[desc] += trans->quantity(); if(b_tags) { for(int i = 0; i < trans->tagsCount(true); i++) { desc_tag_values[desc][trans->getTag(i, true)] -= v; tag_value[trans->getTag(i, true)] -= v; } } } else if(trans->type() == TRANSACTION_TYPE_INCOME) { value += v; value_count += trans->quantity(); QString desc = ((Income*) trans)->payer().toLower(); desc_values[desc] += v; if(month_index >= 0) desc_month_values[desc][month_index] += v; if(month_index >= 0) month_value[month_index] += v; desc_counts[desc] += trans->quantity(); if(b_tags) { for(int i = 0; i < trans->tagsCount(true); i++) { desc_tag_values[desc][trans->getTag(i, true)] += v; tag_value[trans->getTag(i, true)] += v; } } } } else if(i_source == -2) { if(trans->tagsCount(true) > 0) { double v = trans->value(true); if(trans->type() == TRANSACTION_TYPE_EXPENSE) { b_expense = true; value -= v; value_count += trans->quantity(); for(int i2 = 0; i2 < trans->tagsCount(true); i2++) { QString desc = trans->getTag(i2, true); desc_values[desc] -= v; if(month_index >= 0) desc_month_values[desc][month_index] -= v; if(month_index >= 0) month_value[month_index] -= v; desc_counts[desc] += trans->quantity(); if(b_tags) { for(int i = 0; i < trans->tagsCount(true); i++) { desc_tag_values[desc][trans->getTag(i, true)] -= v; } } } } else if(trans->type() == TRANSACTION_TYPE_INCOME) { b_income = true; value += v; value_count += trans->quantity(); for(int i2 = 0; i2 < trans->tagsCount(true); i2++) { QString desc = trans->getTag(i2, true); desc_values[desc] += v; if(month_index >= 0) desc_month_values[desc][month_index] += v; if(month_index >= 0) month_value[month_index] += v; desc_counts[desc] += trans->quantity(); if(b_tags) { for(int i = 0; i < trans->tagsCount(true); i++) { desc_tag_values[desc][trans->getTag(i, true)] += v; } } } } } } else { double v = trans->value(true); Account *from_account = trans->fromAccount(); if(!include_subs) from_account = from_account->topAccount(); Account *to_account = trans->toAccount(); if(!include_subs) to_account = to_account->topAccount(); while(true) { bool b_top = (current_account || !include_subs) || (from_account == from_account->topAccount() && to_account == to_account->topAccount()); if(!current_account || to_account->topAccount() == current_account || from_account->topAccount() == current_account) { if(from_account->type() == ACCOUNT_TYPE_EXPENSES) { values[from_account] -= v; if(month_index >= 0) month_values[from_account][month_index] -= v; if(b_top) costs -= v; if(b_top && month_index >= 0) month_costs[month_index] -= v; counts[from_account] += trans->quantity(); if(b_top) costs_count += trans->quantity(); if(b_tags) { for(int i = 0; i < trans->tagsCount(true); i++) { tag_values[from_account][trans->getTag(i, true)] -= v; if(b_top) tag_costs[trans->getTag(i, true)] -= v; } } } else if(from_account->type() == ACCOUNT_TYPE_INCOMES) { values[from_account] += v; if(month_index >= 0) month_values[from_account][month_index] += v; if(b_top) incomes += v; if(b_top && month_index >= 0) month_incomes[month_index] += v; counts[from_account] += trans->quantity(); if(b_top) incomes_count += trans->quantity(); if(b_tags) { for(int i = 0; i < trans->tagsCount(true); i++) { tag_values[from_account][trans->getTag(i, true)] += v; if(b_top) tag_incomes[trans->getTag(i, true)] += v; } } } else if(to_account->type() == ACCOUNT_TYPE_EXPENSES) { values[to_account] += v; if(month_index >= 0) month_values[to_account][month_index] += v; if(b_top) costs += v; if(b_top && month_index >= 0) month_costs[month_index] += v; counts[to_account] += trans->quantity(); if(b_top) costs_count += trans->quantity(); if(b_tags) { for(int i = 0; i < trans->tagsCount(true); i++) { tag_values[to_account][trans->getTag(i, true)] += v; if(b_top) tag_costs[trans->getTag(i, true)] += v; } } } else if(to_account->type() == ACCOUNT_TYPE_INCOMES) { values[to_account] -= v; if(month_index >= 0) month_values[to_account][month_index] -= v; if(b_top) incomes -= v; if(b_top && month_index >= 0) month_incomes[month_index] -= v; counts[to_account] += trans->quantity(); if(b_top) incomes_count += trans->quantity(); if(b_tags) { for(int i = 0; i < trans->tagsCount(true); i++) { tag_values[to_account][trans->getTag(i, true)] -= v; if(b_top) tag_incomes[trans->getTag(i, true)] -= v; } } } } if(b_top) break; from_account = from_account->topAccount(); to_account = to_account->topAccount(); } } } } first_date_reached = false; if(i_months > 0) month_index = 0; Transaction *trans = NULL; int split_i = 0; for(ScheduledTransactionList::const_iterator it = budget->scheduledTransactions.constBegin(); it != budget->scheduledTransactions.constEnd();) { ScheduledTransaction *strans = *it; while(split_i == 0 && strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT && ((SplitTransaction*) strans->transaction())->count() == 0) { ++it; if(it == budget->scheduledTransactions.constEnd()) break; strans = *it; } if(strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { trans = ((SplitTransaction*) strans->transaction())->at(split_i); split_i++; } else { trans = (Transaction*) strans->transaction(); } if(!first_date_reached && trans->date() >= first_date) { first_date_reached = true; if(trans->date() > last_date) break; if(i_months > 0) { curmonth = (b_years ? budget->lastBudgetDayOfYear(first_date) : budget->lastBudgetDay(first_date)); while(curmonth < trans->date()) { budget->addBudgetMonthsSetLast(curmonth, b_years ? 12 : 1); month_index++; } } } else if(first_date_reached && trans->date() > last_date) { break; } else if(first_date_reached && i_months > 0 && trans->date() > curmonth) { while(curmonth < trans->date()) { budget->addBudgetMonthsSetLast(curmonth, b_years ? 12 : 1); month_index++; } } if(first_date_reached && (!assets_selected || accountCombo->testTransactionRelation(trans))) { QDate last_month_date, first_month_date; int month_index2 = month_index; if(i_months > 0) { first_month_date = (b_years ? budget->firstBudgetDayOfYear(curmonth) : budget->firstBudgetDay(curmonth)); last_month_date = curmonth; } else { first_month_date = first_date; last_month_date = last_date; } do { if((current_account && !include_subs) || !current_tag.isEmpty()) { int sign = 1; bool include = false; if(current_account) { if(trans->fromAccount() == current_account && (i_source <= 2 || (i_source == 4 && descriptionCombo->testTransaction(trans)) || (i_source == 3 && ((trans->type() == TRANSACTION_TYPE_EXPENSE && payeeCombo->testTransaction(trans)) || (trans->type() == TRANSACTION_TYPE_INCOME && payeeCombo->testTransaction(trans)))))) { include = true; if(type == ACCOUNT_TYPE_INCOMES) sign = 1; else sign = -1; } else if(trans->toAccount() == current_account && (i_source <= 2 || (i_source == 4 && descriptionCombo->testTransaction(trans)) || (i_source == 3 && ((trans->type() == TRANSACTION_TYPE_EXPENSE && payeeCombo->testTransaction(trans)) || (trans->type() == TRANSACTION_TYPE_INCOME && payeeCombo->testTransaction(trans)))))) { include = true; if(type == ACCOUNT_TYPE_EXPENSES) sign = 1; else sign = -1; } } else if(trans->hasTag(current_tag, true)) { if(i_source <= 2 || (i_source == 4 && descriptionCombo->testTransaction(trans)) || (i_source == 3 && ((trans->type() == TRANSACTION_TYPE_EXPENSE && payeeCombo->testTransaction(trans)) || (trans->type() == TRANSACTION_TYPE_INCOME && payeeCombo->testTransaction(trans))))) { include = true; if(trans->type() == TRANSACTION_TYPE_EXPENSE) {b_expense = true; sign = -1;} else if(trans->type() == TRANSACTION_TYPE_INCOME) {b_income = true; sign = 1;} else include = false; } } if(include) { int count = strans->recurrence() ? strans->recurrence()->countOccurrences(first_month_date, last_month_date) : 1; double v = trans->value(true) * sign; if(i_source == 2 || i_source == 4) { if(trans->type() == TRANSACTION_TYPE_EXPENSE) { QString desc = ((Expense*) trans)->payee().toLower(); desc_values[desc] += v * count; value += v * count; if(month_index >= 0) desc_month_values[desc][month_index2] += v * count; if(month_index >= 0) month_value[month_index2] += v * count; desc_counts[desc] += count * trans->quantity(); value_count += count * trans->quantity(); if(b_tags) { for(int i = 0; i < trans->tagsCount(true); i++) { desc_tag_values[desc][trans->getTag(i, true)] += v * count; tag_value[trans->getTag(i, true)] += v * count; } } } else if(trans->type() == TRANSACTION_TYPE_INCOME) { QString desc = ((Income*) trans)->payer().toLower(); desc_values[desc] += v * count; value += v * count; if(month_index >= 0) desc_month_values[desc][month_index2] += v * count; if(month_index >= 0) month_value[month_index2] += v * count; desc_counts[desc] += count * trans->quantity(); value_count += count * trans->quantity(); if(b_tags) { for(int i = 0; i < trans->tagsCount(true); i++) { desc_tag_values[desc][trans->getTag(i, true)] += v * count; tag_value[trans->getTag(i, true)] += v * count; } } } } else { QString desc = trans->description().toLower(); desc_values[desc] += v * count; value += v * count; if(month_index >= 0) desc_month_values[desc][month_index2] += v * count; if(month_index >= 0) month_value[month_index2] += v * count; desc_counts[desc] += count * trans->quantity(); value_count += count * trans->quantity(); if(b_tags) { for(int i = 0; i < trans->tagsCount(true); i++) { desc_tag_values[desc][trans->getTag(i, true)] += v * count; tag_value[trans->getTag(i, true)] += v * count; } } } } } else if(i_source == -1) { int count = strans->recurrence() ? strans->recurrence()->countOccurrences(first_month_date, last_month_date) : 1; double v = trans->value(true); if(trans->type() == TRANSACTION_TYPE_EXPENSE) { QString desc = ((Expense*) trans)->payee().toLower(); desc_values[desc] -= v * count; value -= v * count; if(month_index >= 0) desc_month_values[desc][month_index2] -= v * count; if(month_index >= 0) month_value[month_index2] -= v * count; desc_counts[desc] += count * trans->quantity(); value_count += count * trans->quantity(); if(b_tags) { for(int i = 0; i < trans->tagsCount(true); i++) { desc_tag_values[desc][trans->getTag(i, true)] -= v * count; tag_value[trans->getTag(i, true)] -= v * count; } } } else if(trans->type() == TRANSACTION_TYPE_INCOME) { QString desc = ((Income*) trans)->payer().toLower(); desc_values[desc] += v * count; value += v * count; if(month_index >= 0) desc_month_values[desc][month_index2] += v * count; if(month_index >= 0) month_value[month_index2] += v * count; desc_counts[desc] += count * trans->quantity(); value_count += count * trans->quantity(); if(b_tags) { for(int i = 0; i < trans->tagsCount(true); i++) { desc_tag_values[desc][trans->getTag(i, true)] += v * count; tag_value[trans->getTag(i, true)] += v * count; } } } } else if(i_source == -2) { if(trans->tagsCount(true) > 0) { int count = strans->recurrence() ? strans->recurrence()->countOccurrences(first_month_date, last_month_date) : 1; double v = trans->value(true); if(trans->type() == TRANSACTION_TYPE_EXPENSE) { b_expense = true; value -= v; value_count += trans->quantity(); for(int i2 = 0; i2 < trans->tagsCount(true); i2++) { QString desc = trans->getTag(i2, true); tag_value[desc] -= v * count; if(month_index >= 0) tag_month_values[desc][month_index] -= v * count; if(month_index >= 0) month_value[month_index] -= v * count; tag_counts[desc] += trans->quantity() * count; if(b_tags) { for(int i = 0; i < trans->tagsCount(true); i++) { desc_tag_values[desc][trans->getTag(i, true)] -= v * count; } } } } else if(trans->type() == TRANSACTION_TYPE_INCOME) { b_income = true; value += v; value_count += trans->quantity(); for(int i2 = 0; i2 < trans->tagsCount(true); i2++) { QString desc = trans->getTag(i2, true); desc_values[desc] += v * count; if(month_index >= 0) desc_month_values[desc][month_index] += v * count; if(month_index >= 0) month_value[month_index] += v * count; desc_counts[desc] += trans->quantity() * count; if(b_tags) { for(int i = 0; i < trans->tagsCount(true); i++) { desc_tag_values[desc][trans->getTag(i, true)] += v * count; } } } } } } else { Account *from_account = trans->fromAccount(); if(!include_subs) from_account = from_account->topAccount(); Account *to_account = trans->toAccount(); if(!include_subs) to_account = to_account->topAccount(); double v = trans->value(true); while(true) { bool b_top = (current_account || !include_subs) || (from_account == from_account->topAccount() && to_account == to_account->topAccount()); if(!current_account || to_account->topAccount() == current_account || from_account->topAccount() == current_account) { if(from_account->type() == ACCOUNT_TYPE_EXPENSES) { int count = strans->recurrence() ? strans->recurrence()->countOccurrences(first_month_date, last_month_date) : 1; counts[from_account] += count * trans->quantity(); values[from_account] -= v * count; if(month_index2 >= 0) month_values[from_account][month_index2] -= v * count; if(b_top && month_index2 >= 0) month_costs[month_index2] -= v * count; if(b_top) costs_count += count * trans->quantity(); if(b_top) costs -= v * count; if(b_tags) { for(int i = 0; i < trans->tagsCount(true); i++) { tag_values[from_account][trans->getTag(i, true)] -= v * count; if(b_top) tag_costs[trans->getTag(i, true)] -= v * count; } } } else if(from_account->type() == ACCOUNT_TYPE_INCOMES) { int count = strans->recurrence() ? strans->recurrence()->countOccurrences(first_month_date, last_month_date) : 1; counts[from_account] += count * trans->quantity(); values[from_account] += v * count; if(month_index2 >= 0) month_values[from_account][month_index2] += v * count; if(b_top && month_index2 >= 0) month_incomes[month_index2] += v * count; if(b_top) incomes_count += count * trans->quantity(); if(b_top) incomes += v * count; if(b_tags) { for(int i = 0; i < trans->tagsCount(true); i++) { tag_values[from_account][trans->getTag(i, true)] += v * count; if(b_top) tag_incomes[trans->getTag(i, true)] += v * count; } } } else if(to_account->type() == ACCOUNT_TYPE_EXPENSES) { int count = strans->recurrence() ? strans->recurrence()->countOccurrences(first_month_date, last_month_date) : 1; counts[to_account] += count * trans->quantity(); values[to_account] += v * count; if(month_index2 >= 0) month_values[to_account][month_index2] += v * count; if(b_top && month_index2 >= 0) month_costs[month_index2] += v * count; if(b_top) costs_count += count * trans->quantity(); if(b_top) costs += v * count; if(b_tags) { for(int i = 0; i < trans->tagsCount(true); i++) { tag_values[to_account][trans->getTag(i, true)] += v * count; if(b_top) tag_costs[trans->getTag(i, true)] += v * count; } } } else if(to_account->type() == ACCOUNT_TYPE_INCOMES) { int count = strans->recurrence() ? strans->recurrence()->countOccurrences(first_month_date, last_month_date) : 1; counts[to_account] += count * trans->quantity(); values[to_account] -= v * count; if(month_index2 >= 0) month_values[to_account][month_index2] -= v * count; if(b_top && month_index2 >= 0) month_incomes[month_index2] -= v * count; if(b_top) incomes_count += count * trans->quantity(); if(b_top) incomes -= v * count; if(b_tags) { for(int i = 0; i < trans->tagsCount(true); i++) { tag_values[to_account][trans->getTag(i, true)] -= v * count; if(b_top) tag_incomes[trans->getTag(i, true)] -= v * count; } } } } if(b_top) break; from_account = from_account->topAccount(); to_account = to_account->topAccount(); } } if(i_months > 0) { month_index2++; budget->addBudgetMonthsSetFirst(first_month_date, b_years ? 12 : 1); budget->addBudgetMonthsSetLast(last_month_date, b_years ? 12 : 1); } } while(i_months > 0 && month_index2 < i_months && strans->recurrence()); } if(strans->transaction()->generaltype() != GENERAL_TRANSACTION_TYPE_SPLIT || split_i >= ((SplitTransaction*) strans->transaction())->count()) { ++it; split_i = 0; } } if(current_account && include_subs) { if(type == ACCOUNT_TYPE_EXPENSES) { value = costs - incomes; value_count = costs_count + incomes_count; } else { value = incomes - costs; value_count = incomes_count + costs_count; } } bool b_negate = false; if(!b_income && b_expense) {type = ACCOUNT_TYPE_EXPENSES; b_negate = true;} else if(b_income && !b_expense) type = ACCOUNT_TYPE_INCOMES; else if(!current_tag.isEmpty() || i_source == -2) type = ACCOUNT_TYPE_ASSETS; source = ""; QString title; int ptype = b_extra ? payeeCombo->itemType() : 0; if(assets_selected) { if((current_account || !current_tag.isEmpty()) && type == ACCOUNT_TYPE_EXPENSES) { if(b_extra) payeeCombo->setItemType(2); if(include_subs) title = tr("Expenses, %2: %1").arg(current_account ? current_account->name() : current_tag).arg(accountCombo->selectedAccountsText(2)); else if(i_source == 4) title = tr("Expenses, %3: %2, %1").arg(current_account ? current_account->nameWithParent() : current_tag).arg(descriptionCombo->selectedItemsText(2)).arg(accountCombo->selectedAccountsText(2)); else if(i_source == 3) title = tr("Expenses, %3: %2, %1").arg(current_account ? current_account->nameWithParent() : current_tag).arg(payeeCombo->selectedItemsText(2)).arg(accountCombo->selectedAccountsText(2)); else title = tr("Expenses, %2: %1").arg(current_account ? current_account->nameWithParent() : current_tag).arg(accountCombo->selectedAccountsText(2)); } else if((current_account || !current_tag.isEmpty()) && type == ACCOUNT_TYPE_INCOMES) { if(b_extra) payeeCombo->setItemType(3); if(include_subs) title = tr("Incomes, %2: %1").arg(current_account ? current_account->name() : current_tag).arg(accountCombo->selectedAccountsText(2)); else if(i_source == 4) title = tr("Incomes, %3: %2, %1").arg(current_account ? current_account->nameWithParent() : current_tag).arg(descriptionCombo->selectedItemsText(2)).arg(accountCombo->selectedAccountsText(2)); else if(i_source == 3) title = tr("Incomes, %3: %2, %1").arg(current_account ? current_account->nameWithParent() : current_tag).arg(payeeCombo->selectedItemsText(2)).arg(accountCombo->selectedAccountsText(2)); else title = tr("Incomes, %2: %1").arg(current_account ? current_account->nameWithParent() : current_tag).arg(accountCombo->selectedAccountsText(2)); } else if(!current_tag.isEmpty()) { if(b_extra) payeeCombo->setItemType((b_income && !b_expense) ? 3 : 2); if(i_source == 4) title = tr("%3: %2, %1").arg(current_tag).arg(descriptionCombo->selectedItemsText(2)).arg(accountCombo->selectedAccountsText(2)); else if(i_source == 3) title = tr("%3: %2, %1").arg(current_tag).arg(payeeCombo->selectedItemsText(2)).arg(accountCombo->selectedAccountsText(2)); else title = tr("%2: %1").arg(current_tag).arg(accountCombo->selectedAccountsText(2)); } else if(i_source == -2) { if(type == ACCOUNT_TYPE_EXPENSES) title = tr("Expenses, %2: %1").arg(tr("Tags")).arg(accountCombo->selectedAccountsText(2)); else if(type == ACCOUNT_TYPE_INCOMES) title = tr("Incomes, %2: %1").arg(tr("Tags")).arg(accountCombo->selectedAccountsText(2)); else title = tr("Tags, %1").arg(accountCombo->selectedAccountsText(2)); } else { title = tr("Incomes & Expenses, %1").arg(accountCombo->selectedAccountsText(2)); } } else { if((current_account || !current_tag.isEmpty()) && type == ACCOUNT_TYPE_EXPENSES) { if(b_extra) payeeCombo->setItemType(2); if(include_subs) title = tr("Expenses: %1").arg(current_account ? current_account->name() : current_tag); else if(i_source == 4) title = tr("Expenses: %2, %1").arg(current_account ? current_account->nameWithParent() : current_tag).arg(descriptionCombo->selectedItemsText(2)); else if(i_source == 3) title = tr("Expenses: %2, %1").arg(current_account ? current_account->nameWithParent() : current_tag).arg(payeeCombo->selectedItemsText(2)); else title = tr("Expenses: %1").arg(current_account ? current_account->nameWithParent() : current_tag); } else if((current_account || !current_tag.isEmpty()) && type == ACCOUNT_TYPE_INCOMES) { if(b_extra) payeeCombo->setItemType(3); if(include_subs) title = tr("Incomes: %1").arg(current_account ? current_account->name() : current_tag); else if(i_source == 4) title = tr("Incomes: %2, %1").arg(current_account ? current_account->nameWithParent() : current_tag).arg(descriptionCombo->selectedItemsText(2)); else if(i_source == 3) title = tr("Incomes: %2, %1").arg(current_account ? current_account->nameWithParent() : current_tag).arg(payeeCombo->selectedItemsText(2)); else title = tr("Incomes: %1").arg(current_account ? current_account->nameWithParent() : current_tag); } else if(!current_tag.isEmpty()) { if(b_extra) payeeCombo->setItemType((b_income && !b_expense) ? 3 : 2); if(i_source == 4) title = tr("%2, %1").arg(current_tag).arg(descriptionCombo->selectedItemsText(2)); else if(i_source == 3) title = tr("%2, %1").arg(current_tag).arg(payeeCombo->selectedItemsText(2)); else title = current_tag; } else if(i_source == -2) { if(type == ACCOUNT_TYPE_EXPENSES) title = tr("Expenses: %1").arg(tr("Tags")); else if(type == ACCOUNT_TYPE_INCOMES) title = tr("Incomes: %1").arg(tr("Tags")); else title = tr("Tags"); } else { title = tr("Incomes & Expenses"); } } if(b_extra) payeeCombo->setItemType(ptype); QStringList tags; bool b_incomes = !b_tags, b_expenses = !b_tags; if(b_tags) { for(int i = 0; i < budget->tags.count(); i++) { if(!b_incomes && tag_incomes[budget->tags[i]] != 0.0) b_incomes = true; if(!b_expenses && tag_costs[budget->tags[i]] != 0.0) b_expenses = true; if(tag_value[budget->tags[i]] != 0.0 || tag_incomes[budget->tags[i]] != 0.0 || tag_costs[budget->tags[i]] != 0.0) { tags << budget->tags[i]; } } if(tags.isEmpty()) tags = budget->tags; } if(!b_incomes && !b_expenses) {b_incomes = true; b_expenses = true;} QTextStream outf(&source, QIODevice::WriteOnly); outf << "" << '\n'; outf << "" << '\n'; outf << "\t" << '\n'; outf << "\t\t"; outf << htmlize_string(title); outf << "" << '\n'; outf << "\t\t" << '\n'; outf << "\t\tapplicationDisplayName() << "\">" << '\n'; outf << "\t" << '\n'; outf << "\t" << '\n'; if(fromButton->isChecked()) outf << "\t\t

    " << tr("%1 (%2–%3)", "html format; %1: title; %2: from date; %3: to date").arg(htmlize_string(title)).arg(htmlize_string(QLocale().toString(first_date, QLocale::ShortFormat))).arg(htmlize_string(QLocale().toString(last_date, QLocale::ShortFormat))) << "

    " << '\n' << "\t\t
    "; else outf << "\t\t

    " << tr("%1 (to %2)", "html format; %1: title; %2: to date").arg(htmlize_string(title)).arg(htmlize_string(QLocale().toString(last_date, QLocale::ShortFormat))) << "

    " << '\n' << "\t\t
    "; outf << "\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t\t" << '\n'; #define FIRST_COL "\t\t\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; int days = first_date.daysTo(last_date) + 1; double months = budget->monthsBetweenDates(first_date, last_date, true), years = budget->yearsBetweenDates(first_date, last_date, true); int i_count_frac = 0; double intpart = 0.0; if((current_account && !include_subs) || !current_tag.isEmpty() || i_source == -1 || i_source == -2) { QMap::iterator it_e = desc_counts.end(); for(QMap::iterator it = desc_counts.begin(); it != it_e; ++it) { if(modf(it.value(), &intpart) != 0.0) { i_count_frac = 2; break; } } } else if(current_account) { if(modf(counts[current_account], &intpart) != 0.0) { i_count_frac = 2; } else { for(AccountList::const_iterator it = current_account->subCategories.constBegin(); it != current_account->subCategories.constEnd(); ++it) { CategoryAccount *account = *it; if(modf(counts[account], &intpart) != 0.0) { i_count_frac = 2; break; } } } } else { for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) { CategoryAccount *account = *it; if((include_subs || !account->parentCategory()) && modf(counts[account], &intpart) != 0.0) { i_count_frac = 2; break; } } if(i_count_frac == 0) { for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) { CategoryAccount *account = *it; if((include_subs || !account->parentCategory()) && modf(counts[account], &intpart) != 0.0) { i_count_frac = 2; break; } } } } if(current_account || i_source == -1 || i_source == -2 || !current_tag.isEmpty()) { if(include_subs) { CategoryAccount *account = NULL; for(AccountList::const_iterator it = current_account->subCategories.constBegin();;) { if(account == current_account) break; if(it != current_account->subCategories.constEnd()) { account = *it; ++it; } else { account = current_account; } outf << "\t\t\t\t" << '\n'; outf << FIRST_COL << htmlize_string(account->name()) << ""; col = 1; if(enabled[0]) {outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatMoney(values[account])) << ""; col++;} if(enabled[1]) {outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatMoney(values[account] / days)) << ""; col++;} if(enabled[2]) {outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatMoney(values[account] / months)) << ""; col++;} if(enabled[3]) {outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatMoney(values[account] / years)) << ""; col++;} if(enabled[4]) {outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatValue(counts[account], i_count_frac)) << ""; col++;} if(enabled[5]) outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatMoney(counts[account] == 0.0 ? 0.0 : (values[account] / counts[account]))) << ""; if(i_months > 0) { for(int i = i_months - 1; i >= 0; i--) { outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatMoney(month_values[account][i])) << ""; col++; } outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatMoney(values[account])) << ""; col++; } else if(b_tags) { for(int i = 0; i < tags.count(); i++) { outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatMoney(tag_values[account][tags[i]])) << ""; col++; } } outf << "\n"; outf << "\t\t\t\t" << '\n'; } } else { QMap::iterator it_e = desc_values.end(); QMap::iterator itc = desc_counts.begin(); QMap::iterator it = desc_values.begin(); QMap >::iterator mit = desc_month_values.begin(); QMap >::iterator tit = desc_tag_values.begin(); while(it != it_e) { outf << "\t\t\t\t" << '\n'; if(it.key().isEmpty()) { if((i_source == 4 || i_source == 2) && type == ACCOUNT_TYPE_EXPENSES) outf << FIRST_COL << htmlize_string(tr("No payee")) << ""; else if((i_source == 4 || i_source == 2) && type == ACCOUNT_TYPE_INCOMES) outf << FIRST_COL << htmlize_string(tr("No payer")) << ""; else if(i_source == -1 || i_source == 4 || i_source == 2) outf << FIRST_COL << htmlize_string(tr("No payee/payer")) << ""; else outf << FIRST_COL << htmlize_string(tr("No description", "Referring to the transaction description property (transaction title/generic article name)")) << ""; } else { outf << FIRST_COL << htmlize_string(desc_map[it.key()]) << ""; } col = 1; if(b_negate) it.value() = -it.value(); if(enabled[0]) {outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatMoney(it.value())) << ""; col++;} if(enabled[1]) {outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatMoney(it.value() / days)) << ""; col++;} if(enabled[2]) {outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatMoney(it.value() / months)) << ""; col++;} if(enabled[3]) {outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatMoney(it.value() / years)) << ""; col++;} if(enabled[4]) {outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatValue(itc.value(), i_count_frac)) << ""; col++;} if(enabled[5]) outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatMoney(itc.value() == 0.0 ? 0.0 : (it.value() / itc.value()))) << ""; if(i_months > 0) { for(int i = i_months - 1; i >= 0; i--) { outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatMoney(b_negate ? -mit.value()[i] : mit.value()[i])) << ""; col++; } outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatMoney(it.value())) << ""; col++; } else if(b_tags) { for(int i = 0; i < tags.count(); i++) { outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatMoney(b_negate ? -tit.value()[tags[i]] : tit.value()[tags[i]])) << ""; col++; } } outf << "\n"; outf << "\t\t\t\t" << '\n'; ++it; ++itc; if(i_months > 0) ++mit; else if(b_tags) ++tit; } } if(!b_tags && i_source != -2) { outf << "\t\t\t\t" << '\n'; outf << FIRST_COL_BOTTOM << htmlize_string(tr("Total")) << ""; col = 1; if(b_negate) value = -value; if(enabled[0]) {outf << (col % 2 == 1 ? ODD_COL_BOTTOM : EVEN_COL_BOTTOM) << htmlize_string(budget->formatMoney(value)) << ""; col++;} if(enabled[1]) {outf << (col % 2 == 1 ? ODD_COL_BOTTOM : EVEN_COL_BOTTOM) << htmlize_string(budget->formatMoney(value / days)) << ""; col++;} if(enabled[2]) {outf << (col % 2 == 1 ? ODD_COL_BOTTOM : EVEN_COL_BOTTOM) << htmlize_string(budget->formatMoney(value / months)) << ""; col++;} if(enabled[3]) {outf << (col % 2 == 1 ? ODD_COL_BOTTOM : EVEN_COL_BOTTOM) << htmlize_string(budget->formatMoney(value / years)) << ""; col++;} if(enabled[4]) {outf << (col % 2 == 1 ? ODD_COL_BOTTOM : EVEN_COL_BOTTOM) << htmlize_string(budget->formatValue(value_count, i_count_frac)) << ""; col++;} if(enabled[5]) outf << (col % 2 == 1 ? ODD_COL_BOTTOM : EVEN_COL_BOTTOM) << htmlize_string(budget->formatMoney(value_count == 0.0 ? 0.0 : (value / value_count))) << ""; if(i_months > 0) { for(int i = i_months - 1; i >= 0; i--) { outf << (col % 2 == 1 ? ODD_COL_BOTTOM : EVEN_COL_BOTTOM) << htmlize_string(budget->formatMoney(b_negate ? -month_value[i] : month_value[i])) << ""; col++; } outf << (col % 2 == 1 ? ODD_COL_BOTTOM : EVEN_COL_BOTTOM) << htmlize_string(budget->formatMoney(value)) << ""; col++; } else if(b_tags) { for(int i = 0; i < tags.count(); i++) { outf << (col % 2 == 1 ? ODD_COL_BOTTOM : EVEN_COL_BOTTOM) << htmlize_string(budget->formatMoney(b_negate ? -tag_value[tags[i]] : tag_value[tags[i]])) << ""; col++; } } outf << "\n"; outf << "\t\t\t\t" << '\n'; } } else { if(b_incomes) { for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) { CategoryAccount *account = *it; if(include_subs || !account->parentCategory()) { outf << "\t\t\t\t" << '\n'; if(account->parentCategory()) { outf << FIRST_COL << "" << htmlize_string(account->nameWithParent()) << ""; col = 1; if(enabled[0]) {outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << "" << htmlize_string(budget->formatMoney(values[account])) << ""; col++;} if(enabled[1]) {outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << "" << htmlize_string(budget->formatMoney(values[account] / days)) << ""; col++;} if(enabled[2]) {outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << "" << htmlize_string(budget->formatMoney(values[account] / months)) << ""; col++;} if(enabled[3]) {outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << "" << htmlize_string(budget->formatMoney(values[account] / years)) << ""; col++;} if(enabled[4]) {outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << "" << htmlize_string(budget->formatValue(counts[account], i_count_frac)) << ""; col++;} if(enabled[5]) outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << "" << htmlize_string(budget->formatMoney(counts[account] == 0.0 ? 0.0 : (values[account] / counts[account]))) << ""; if(i_months > 0) { for(int i = i_months - 1; i >= 0; i--) { outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << "" << htmlize_string(budget->formatMoney(month_values[account][i])) << ""; col++; } outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << "" << htmlize_string(budget->formatMoney(values[account])) << ""; col++; } else if(b_tags) { for(int i = 0; i < tags.count(); i++) { outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << "" << htmlize_string(budget->formatMoney(tag_values[account][tags[i]])) << ""; col++; } } } else { outf << FIRST_COL << htmlize_string(account->nameWithParent()) << ""; col = 1; if(enabled[0]) {outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatMoney(values[account])) << ""; col++;} if(enabled[1]) {outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatMoney(values[account] / days)) << ""; col++;} if(enabled[2]) {outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatMoney(values[account] / months)) << ""; col++;} if(enabled[3]) {outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatMoney(values[account] / years)) << ""; col++;} if(enabled[4]) {outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatValue(counts[account], i_count_frac)) << ""; col++;} if(enabled[5]) outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatMoney(counts[account] == 0.0 ? 0.0 : (values[account] / counts[account]))) << ""; if(i_months > 0) { for(int i = i_months - 1; i >= 0; i--) { outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatMoney(month_values[account][i])) << ""; col++; } outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatMoney(values[account])) << ""; col++; } else if(b_tags) { for(int i = 0; i < tags.count(); i++) { outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatMoney(tag_values[account][tags[i]])) << ""; col++; } } } outf << "\n"; outf << "\t\t\t\t" << '\n'; } } outf << "\t\t\t\t" << '\n'; outf << FIRST_COL_DIV << htmlize_string(b_expenses ? tr("Total incomes") : tr("Total")) << ""; col = 1; if(enabled[0]) {outf << (col % 2 == 1 ? ODD_COL_DIV : EVEN_COL_DIV) << htmlize_string(budget->formatMoney(incomes)) << ""; col++;} if(enabled[1]) {outf << (col % 2 == 1 ? ODD_COL_DIV : EVEN_COL_DIV) << htmlize_string(budget->formatMoney(incomes / days)) << ""; col++;} if(enabled[2]) {outf << (col % 2 == 1 ? ODD_COL_DIV : EVEN_COL_DIV) << htmlize_string(budget->formatMoney(incomes / months)) << ""; col++;} if(enabled[3]) {outf << (col % 2 == 1 ? ODD_COL_DIV : EVEN_COL_DIV) << htmlize_string(budget->formatMoney(incomes / years)) << ""; col++;} if(enabled[4]) {outf << (col % 2 == 1 ? ODD_COL_DIV : EVEN_COL_DIV) << htmlize_string(budget->formatValue(incomes_count, i_count_frac)) << ""; col++;} if(enabled[5]) outf << (col % 2 == 1 ? ODD_COL_DIV : EVEN_COL_DIV) << htmlize_string(budget->formatMoney(incomes_count == 0.0 ? 0.0 : (incomes / incomes_count))) << ""; if(i_months > 0) { for(int i = i_months - 1; i >= 0; i--) { outf << (col % 2 == 1 ? ODD_COL_DIV : EVEN_COL_DIV) << htmlize_string(budget->formatMoney(month_incomes[i])) << ""; col++; } outf << (col % 2 == 1 ? ODD_COL_DIV : EVEN_COL_DIV) << htmlize_string(budget->formatMoney(incomes)) << ""; col++; } else if(b_tags) { for(int i = 0; i < tags.count(); i++) { outf << (col % 2 == 1 ? ODD_COL_DIV : EVEN_COL_DIV) << htmlize_string(budget->formatMoney(tag_incomes[tags[i]])) << ""; col++; } } outf << "\n"; outf << "\t\t\t\t" << '\n'; } if(b_expenses) { for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) { CategoryAccount *account = *it; if(include_subs || !account->parentCategory()) { outf << "\t\t\t\t" << '\n'; if(account->parentCategory()) { outf << FIRST_COL << "" << htmlize_string(account->nameWithParent()) << ""; col = 1; if(enabled[0]) {outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << "" << htmlize_string(budget->formatMoney(-values[account])) << ""; col++;} if(enabled[1]) {outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << "" << htmlize_string(budget->formatMoney(-values[account] / days)) << ""; col++;} if(enabled[2]) {outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << "" << htmlize_string(budget->formatMoney(-values[account] / months)) << ""; col++;} if(enabled[3]) {outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << "" << htmlize_string(budget->formatMoney(-values[account] / years)) << ""; col++;} if(enabled[4]) {outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << "" << htmlize_string(budget->formatValue(counts[account], i_count_frac)) << ""; col++;} if(enabled[5]) outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << "" << htmlize_string(budget->formatMoney(counts[account] == 0.0 ? 0.0 : (-values[account] / counts[account]))) << ""; if(i_months > 0) { for(int i = i_months - 1; i >= 0; i--) { outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << "" << htmlize_string(budget->formatMoney(-month_values[account][i])) << ""; col++; } outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << "" << htmlize_string(budget->formatMoney(-values[account])) << ""; col++; } else if(b_tags) { for(int i = 0; i < tags.count(); i++) { outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << "" << htmlize_string(budget->formatMoney(-tag_values[account][tags[i]])) << ""; col++; } } } else { outf << FIRST_COL << htmlize_string(account->nameWithParent()) << ""; col = 1; if(enabled[0]) {outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatMoney(-values[account])) << ""; col++;} if(enabled[1]) {outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatMoney(-values[account] / days)) << ""; col++;} if(enabled[2]) {outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatMoney(-values[account] / months)) << ""; col++;} if(enabled[3]) {outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatMoney(-values[account] / years)) << ""; col++;} if(enabled[4]) {outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatValue(counts[account], i_count_frac)) << ""; col++;} if(enabled[5]) outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatMoney(counts[account] == 0.0 ? 0.0 : (-values[account] / counts[account]))) << ""; if(i_months > 0) { for(int i = i_months - 1; i >= 0; i--) { outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatMoney(-month_values[account][i])) << ""; col++; } outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatMoney(-values[account])) << ""; col++; } else if(b_tags) { for(int i = 0; i < tags.count(); i++) { outf << (col % 2 == 1 ? ODD_COL : EVEN_COL) << htmlize_string(budget->formatMoney(-tag_values[account][tags[i]])) << ""; col++; } } } outf << "\n"; outf << "\t\t\t\t" << '\n'; } } outf << "\t\t\t\t" << '\n'; outf << FIRST_COL_BOTTOM << htmlize_string(b_incomes ? tr("Total expenses") : tr("Total")) << ""; col = 1; if(enabled[0]) {outf << (col % 2 == 1 ? ODD_COL_DIV : EVEN_COL_DIV) << htmlize_string(budget->formatMoney(-costs)) << ""; col++;} if(enabled[1]) {outf << (col % 2 == 1 ? ODD_COL_DIV : EVEN_COL_DIV) << htmlize_string(budget->formatMoney(-costs / days)) << ""; col++;} if(enabled[2]) {outf << (col % 2 == 1 ? ODD_COL_DIV : EVEN_COL_DIV) << htmlize_string(budget->formatMoney(-costs / months)) << ""; col++;} if(enabled[3]) {outf << (col % 2 == 1 ? ODD_COL_DIV : EVEN_COL_DIV) << htmlize_string(budget->formatMoney(-costs / years)) << ""; col++;} if(enabled[4]) {outf << (col % 2 == 1 ? ODD_COL_DIV : EVEN_COL_DIV) << htmlize_string(budget->formatValue(costs_count, i_count_frac)) << ""; col++;} if(enabled[5]) outf << (col % 2 == 1 ? ODD_COL_DIV : EVEN_COL_DIV) << htmlize_string(budget->formatMoney(costs_count == 0.0 ? 0.0 : (-costs / costs_count))) << ""; if(i_months > 0) { for(int i = i_months - 1; i >= 0; i--) { outf << (col % 2 == 1 ? ODD_COL_DIV : EVEN_COL_DIV) << htmlize_string(budget->formatMoney(-month_costs[i])) << ""; col++; } outf << (col % 2 == 1 ? ODD_COL_DIV : EVEN_COL_DIV) << htmlize_string(budget->formatMoney(-costs)) << ""; col++; } else if(b_tags) { for(int i = 0; i < tags.count(); i++) { outf << (col % 2 == 1 ? ODD_COL_DIV : EVEN_COL_DIV) << htmlize_string(budget->formatMoney(-tag_costs[tags[i]])) << ""; col++; } } outf << "\n"; outf << "\t\t\t\t" << '\n'; } if(b_incomes && b_expenses) { outf << "\t\t\t\t" << '\n'; outf << FIRST_COL_BOTTOM << htmlize_string(tr("Total (Profits)")) << ""; col = 1; if(enabled[0]) {outf << (col % 2 == 1 ? ODD_COL_BOTTOM : EVEN_COL_BOTTOM) << htmlize_string(budget->formatMoney(incomes - costs)) << ""; col++;} if(enabled[1]) {outf << (col % 2 == 1 ? ODD_COL_BOTTOM : EVEN_COL_BOTTOM) << htmlize_string(budget->formatMoney((incomes - costs) / days)) << ""; col++;} if(enabled[2]) {outf << (col % 2 == 1 ? ODD_COL_BOTTOM : EVEN_COL_BOTTOM) << htmlize_string(budget->formatMoney((incomes - costs) / months)) << ""; col++;} if(enabled[3]) {outf << (col % 2 == 1 ? ODD_COL_BOTTOM : EVEN_COL_BOTTOM) << htmlize_string(budget->formatMoney((incomes - costs) / years)) << ""; col++;} if(enabled[4]) {outf << (col % 2 == 1 ? ODD_COL_BOTTOM : EVEN_COL_BOTTOM) << htmlize_string(budget->formatValue(incomes_count + costs_count, i_count_frac)) << ""; col++;} if(enabled[5]) outf << (col % 2 == 1 ? ODD_COL_BOTTOM : EVEN_COL_BOTTOM) << htmlize_string(budget->formatMoney((incomes_count + costs_count) == 0.0 ? 0.0 : ((incomes - costs) / (incomes_count + costs_count)))) << ""; if(i_months > 0) { for(int i = i_months - 1; i >= 0; i--) { outf << (col % 2 == 1 ? ODD_COL_BOTTOM : EVEN_COL_BOTTOM) << htmlize_string(budget->formatMoney(month_incomes[i] - month_costs[i])) << ""; col++; } outf << (col % 2 == 1 ? ODD_COL_BOTTOM : EVEN_COL_BOTTOM) << htmlize_string(budget->formatMoney(incomes - costs)) << ""; col++; } else if(b_tags) { for(int i = 0; i < tags.count(); i++) { outf << (col % 2 == 1 ? ODD_COL_BOTTOM : EVEN_COL_BOTTOM) << htmlize_string(budget->formatMoney(tag_incomes[tags[i]] - tag_costs[tags[i]])) << ""; col++; } } outf << "\n"; outf << "\t\t\t\t" << '\n'; } } outf << "\t\t\t" << '\n'; outf << "\t\t
    " #define EVEN_COL "" #define ODD_COL "" #define FIRST_COL_TOP "\t\t\t\t\t" #define EVEN_COL_TOP "\t\t\t\t\t" #define ODD_COL_TOP "\t\t\t\t\t" #define FIRST_COL_DIV "\t\t\t\t\t" #define EVEN_COL_DIV "" #define ODD_COL_DIV "" #define FIRST_COL_BOTTOM "\t\t\t\t\t" #define EVEN_COL_BOTTOM "\t\t\t\t\t" #define ODD_COL_BOTTOM "\t\t\t\t\t" int col = 1; if((current_account || !current_tag.isEmpty() || i_source == -2) && type == ACCOUNT_TYPE_EXPENSES) { if(i_source == -2) outf << FIRST_COL_TOP << htmlize_string(tr("Tag")) << ""; else if(include_subs) outf << FIRST_COL_TOP << htmlize_string(tr("Category")) << ""; else if(i_source == 2 || i_source == 4) outf << FIRST_COL_TOP << htmlize_string(tr("Payee")) << ""; else outf << FIRST_COL_TOP << htmlize_string(tr("Description", "Referring to the transaction description property (transaction title/generic article name)")) << ""; if(enabled[0]) {outf << (col % 2 == 1 ? ODD_COL_TOP : EVEN_COL_TOP) << htmlize_string(tr("Cost")) << ""; col++;} } else if((current_account || !current_tag.isEmpty() || i_source == -2) && type == ACCOUNT_TYPE_INCOMES) { if(i_source == -2) outf << FIRST_COL_TOP << htmlize_string(tr("Tag")) << ""; else if(include_subs) outf << FIRST_COL_TOP << htmlize_string(tr("Category")) << ""; else if(i_source == 2 || i_source == 4) outf << FIRST_COL_TOP << htmlize_string(tr("Payer")) << ""; else outf << FIRST_COL_TOP << htmlize_string(tr("Description", "Referring to the transaction description property (transaction title/generic article name)")) << ""; if(enabled[0]) {outf << (col % 2 == 1 ? ODD_COL_TOP : EVEN_COL_TOP) << htmlize_string(tr("Income")) << ""; col++;} } else if(!current_tag.isEmpty()) { if(i_source == 2 || i_source == 4) { if(b_expense && !b_income) outf << FIRST_COL_TOP << htmlize_string(tr("Payee")) << ""; else if(!b_expense && b_income) outf << FIRST_COL_TOP << htmlize_string(tr("Payer")) << ""; else outf << FIRST_COL_TOP << htmlize_string(tr("Payee/Payer")) << ""; } else outf << FIRST_COL_TOP << htmlize_string(tr("Description", "Referring to the transaction description property (transaction title/generic article name)")) << ""; if(enabled[0]) {outf << (col % 2 == 1 ? ODD_COL_TOP : EVEN_COL_TOP) << htmlize_string(tr("Value")) << ""; col++;} } else { if(i_source == -1) outf << FIRST_COL_TOP << htmlize_string(tr("Payee/Payer")) << ""; else if(i_source == -2) outf << FIRST_COL_TOP << htmlize_string(tr("Tag")) << ""; else outf << FIRST_COL_TOP << htmlize_string(tr("Category")) << ""; if(enabled[0]) {outf << (col % 2 == 1 ? ODD_COL_TOP : EVEN_COL_TOP) << htmlize_string(tr("Value")) << ""; col++;} } if(enabled[1]) {outf << (col % 2 == 1 ? ODD_COL_TOP : EVEN_COL_TOP) << htmlize_string(tr("Daily Average")) << ""; col++;} if(enabled[2]) {outf << (col % 2 == 1 ? ODD_COL_TOP : EVEN_COL_TOP) << htmlize_string(tr("Monthly Average")) << ""; col++;} if(enabled[3]) {outf << (col % 2 == 1 ? ODD_COL_TOP : EVEN_COL_TOP) << htmlize_string(tr("Yearly Average")) << ""; col++;} if(enabled[4]) {outf << (col % 2 == 1 ? ODD_COL_TOP : EVEN_COL_TOP) << htmlize_string(tr("Quantity")) << ""; col++;} if((current_account || !current_tag.isEmpty() || i_source == -2) && type == ACCOUNT_TYPE_EXPENSES) { if(enabled[5]) outf << (col % 2 == 1 ? ODD_COL_TOP : EVEN_COL_TOP) << htmlize_string(tr("Average Cost")) << ""; } else if((current_account || !current_tag.isEmpty() || i_source == -2) && type == ACCOUNT_TYPE_INCOMES) { if(enabled[5]) outf << (col % 2 == 1 ? ODD_COL_TOP : EVEN_COL_TOP) << htmlize_string(tr("Average Income")) << ""; } else { if(enabled[5]) outf << (col % 2 == 1 ? ODD_COL_TOP : EVEN_COL_TOP) << htmlize_string(tr("Average Value")) << ""; } if(i_months > 0) { curmonth = last_date; for(int i = i_months - 1; i >= 0; i--) { outf << (col % 2 == 1 ? ODD_COL_TOP : EVEN_COL_TOP) << htmlize_string(b_years ? budget->budgetYearString(curmonth, false) : ((i_months > 12 && curmonth.month() == 12) ? QLocale().toString(curmonth, "MMM yyyy") : QLocale().toString(curmonth, "MMM"))) << ""; col++; budget->addBudgetMonthsSetFirst(curmonth, b_years ? -12 : -1); } outf << (col % 2 == 1 ? ODD_COL_TOP : EVEN_COL_TOP) << htmlize_string(tr("Total")) << ""; col++; } else if(b_tags) { for(int i = 0; i < tags.count(); i++) { outf << (col % 2 == 1 ? ODD_COL_TOP : EVEN_COL_TOP) << htmlize_string(tags[i]) << ""; col++; } } outf << "\t\t\t\t
    " << '\n'; outf << "\t" << '\n'; outf << "" << '\n'; htmlview->setLineWrapMode(QTextEdit::NoWrap); htmlview->setHtml(source); if(htmlview->document()->size().width() < htmlview->width()) htmlview->setLineWrapMode(QTextEdit::WidgetWidth); } void CategoriesComparisonReport::updateTransactions() { if(b_extra && (current_account || !current_tag.isEmpty())) { payeeCombo->blockSignals(true); descriptionCombo->blockSignals(true); QMap descriptions, payees; bool b_income, b_expense; for(TransactionList::const_iterator it = budget->transactions.constEnd(); it != budget->transactions.constBegin();) { --it; Transaction *trans = *it; if((!current_account && trans->hasTag(current_tag, true) && ((trans->type() == TRANSACTION_TYPE_EXPENSE || trans->type() == TRANSACTION_TYPE_INCOME))) || (current_account && (trans->fromAccount() == current_account || trans->toAccount() == current_account))) { if(!descriptions.contains(trans->description().toLower())) descriptions[trans->description().toLower()] = trans->description(); if(trans->type() == TRANSACTION_TYPE_EXPENSE) { b_expense = true; if(!payees.contains(((Expense*) trans)->payee().toLower())) payees[((Expense*) trans)->payee().toLower()] = ((Expense*) trans)->payee(); } else if(trans->type() == TRANSACTION_TYPE_INCOME) { b_income = true; if(!payees.contains(((Income*) trans)->payer().toLower())) payees[((Income*) trans)->payer().toLower()] = ((Income*) trans)->payer(); } } } if((!current_account && b_expense && !b_income) || (current_account && current_account->type() == ACCOUNT_TYPE_EXPENSES)) payeeCombo->setItemType(2); else if(current_account || (!b_expense && b_income)) payeeCombo->setItemType(3); else payeeCombo->setItemType(4); QStringList dlist; QMap::iterator it_e = descriptions.end(); for(QMap::iterator it = descriptions.begin(); it != it_e; ++it) { dlist << it.value(); } descriptionCombo->updateItems(dlist); QStringList plist; QMap::iterator it2_e = payees.end(); for(QMap::iterator it2 = payees.begin(); it2 != it2_e; ++it2) { plist << it2.value(); } payeeCombo->updateItems(plist); payeeCombo->blockSignals(false); descriptionCombo->blockSignals(false); } updateDisplay(); } void CategoriesComparisonReport::updateTags() { updateAccounts(); } void CategoriesComparisonReport::updateAccounts() { int curindex = 0; sourceCombo->blockSignals(true); accountCombo->blockSignals(true); sourceCombo->clear(); sourceCombo->addItem(tr("All Categories, excluding subcategories")); sourceCombo->addItem(tr("All Categories, including subcategories")); sourceCombo->addItem(tr("All Tags")); if(b_extra) { sourceCombo->addItem(tr("All Payees and Payers")); first_source_account_index = 4; } else { first_source_account_index = 3; } for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) { Account *account = *it; sourceCombo->addItem(tr("Expenses: %1").arg(account->nameWithParent())); if(account == current_account) curindex = sourceCombo->count() - 1; } for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) { Account *account = *it; sourceCombo->addItem(tr("Incomes: %1").arg(account->nameWithParent())); if(account == current_account) curindex = sourceCombo->count() - 1; } for(int i2 = 0; i2 < budget->tags.count(); i2++) { sourceCombo->addItem(tr("Tag: %1").arg(budget->tags[i2])); if(!current_account && current_tag == budget->tags[i2]) curindex = sourceCombo->count() - 1; } if(curindex < sourceCombo->count()) sourceCombo->setCurrentIndex(curindex); accountCombo->updateAccounts(ACCOUNT_TYPE_ASSETS); sourceCombo->blockSignals(false); accountCombo->blockSignals(false); if(curindex == 0 && b_extra) { sourceChanged(curindex); } else { updateDisplay(); } } Eqonomize-1.5.3/src/categoriescomparisonreport.h000066400000000000000000000063421416454732000221150ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016-2020 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifndef CATEGORIES_COMPARISON_REPORT_H #define CATEGORIES_COMPARISON_REPORT_H #include #include class QCheckBox; class QComboBox; class QPushButton; class QRadioButton; class QDateEdit; class QTextEdit; class AccountsCombo; class DescriptionsCombo; class CategoryAccount; class AssetsAccount; class Budget; class CategoriesComparisonReport : public QWidget { Q_OBJECT public: CategoriesComparisonReport(Budget *budg, QWidget *parent, bool extra_parameters); protected: Budget *budget; QString source; QDate from_date, to_date; CategoryAccount *current_account; QString current_tag; bool b_extra; bool block_display_update; int first_source_account_index; QTextEdit *htmlview; QCheckBox *fromButton; QDateEdit *fromEdit, *toEdit; QPushButton *nextYearButton, *prevYearButton, *nextMonthButton, *prevMonthButton; QPushButton *saveButton, *printButton; QCheckBox *valueButton, *dailyButton, *monthlyButton, *yearlyButton, *countButton, *perButton; QComboBox *sourceCombo; DescriptionsCombo *descriptionCombo, *payeeCombo; AccountsCombo *accountCombo; QRadioButton *descriptionButton, *payeeButton, *subsButton; QRadioButton *monthsButton, *yearsButton, *tagsButton, *totalButton; QWidget *payeeDescriptionWidget; public slots: void resetOptions(); void updateTransactions(); void updateAccounts(); void updateTags(); void updateDisplay(); void save(); void print(); void saveConfig(); void fromChanged(const QDate&); void toChanged(const QDate&); void prevMonth(); void nextMonth(); void prevYear(); void nextYear(); void sourceChanged(int); void descriptionChanged(); void payeeChanged(); void descriptionToggled(bool); void payeeToggled(bool); void subsToggled(bool); void columnsToggled(int, bool); }; #endif Eqonomize-1.5.3/src/currencies.xml.h000066400000000000000000000032321416454732000173750ustar00rootroot00000000000000QT_TRANSLATE_NOOP("currencies.xml", "U.S. Dollar") QT_TRANSLATE_NOOP("currencies.xml", "Japansese Yen") QT_TRANSLATE_NOOP("currencies.xml", "Bulgarian Lev") QT_TRANSLATE_NOOP("currencies.xml", "Czech Koruna") QT_TRANSLATE_NOOP("currencies.xml", "Danish Krone") QT_TRANSLATE_NOOP("currencies.xml", "British Pound") QT_TRANSLATE_NOOP("currencies.xml", "Hungarian Forint") QT_TRANSLATE_NOOP("currencies.xml", "Polish Zloty") QT_TRANSLATE_NOOP("currencies.xml", "Romanian New Leu") QT_TRANSLATE_NOOP("currencies.xml", "Swedish Krona") QT_TRANSLATE_NOOP("currencies.xml", "Swiss Franc") QT_TRANSLATE_NOOP("currencies.xml", "Norwegian Krone") QT_TRANSLATE_NOOP("currencies.xml", "Croatian Kuna") QT_TRANSLATE_NOOP("currencies.xml", "Russian Ruble") QT_TRANSLATE_NOOP("currencies.xml", "Turkish New Lira") QT_TRANSLATE_NOOP("currencies.xml", "Australian Dollar") QT_TRANSLATE_NOOP("currencies.xml", "Brazilian Real") QT_TRANSLATE_NOOP("currencies.xml", "Canadian Dollar") QT_TRANSLATE_NOOP("currencies.xml", "Chinese Yuan Renminbi") QT_TRANSLATE_NOOP("currencies.xml", "Hong Kong Dollar") QT_TRANSLATE_NOOP("currencies.xml", "Indonesian Rupiah") QT_TRANSLATE_NOOP("currencies.xml", "Israeli New Sheqel") QT_TRANSLATE_NOOP("currencies.xml", "Indian Rupee") QT_TRANSLATE_NOOP("currencies.xml", "South Korean Won") QT_TRANSLATE_NOOP("currencies.xml", "Mexican Peso") QT_TRANSLATE_NOOP("currencies.xml", "Malaysian Ringgit") QT_TRANSLATE_NOOP("currencies.xml", "New Zeeland Dollar") QT_TRANSLATE_NOOP("currencies.xml", "Philippine Peso") QT_TRANSLATE_NOOP("currencies.xml", "Singapore Dollar") QT_TRANSLATE_NOOP("currencies.xml", "Thai Baht") QT_TRANSLATE_NOOP("currencies.xml", "South African Rand") Eqonomize-1.5.3/src/currency.cpp000066400000000000000000000400171416454732000166230ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2017 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include "budget.h" #include "currency.h" Currency::Currency(Budget *parent_budget) { o_budget = parent_budget; i_decimals = -1; b_precedes = -1; r_source = EXCHANGE_RATE_SOURCE_NONE; b_local_rate = true; b_local_name = true; b_local_symbol = true; b_local_format = true; } Currency::Currency() { o_budget = NULL; i_decimals = -1; b_precedes = -1; r_source = EXCHANGE_RATE_SOURCE_NONE; b_local_rate = true; b_local_name = true; b_local_symbol = true; b_local_format = true; } Currency::Currency(Budget *parent_budget, QString initial_code, QString initial_symbol, QString initial_name, double initial_rate, QDate date, int initial_decimals, int initial_precedes) { o_budget = parent_budget; s_code = initial_code; s_symbol = initial_symbol; s_name = initial_name; if(!date.isValid() && initial_rate != 1.0) date = QDate::currentDate(); if(date.isValid()) rates[date] = initial_rate; i_decimals = initial_decimals; b_precedes = initial_precedes; if(i_decimals < 0) i_decimals = -1; b_local_rate = true; b_local_name = true; b_local_symbol = true; b_local_format = true; r_source = EXCHANGE_RATE_SOURCE_NONE; } Currency::Currency(Budget *parent_budget, QXmlStreamReader *xml, bool *valid) { o_budget = parent_budget; i_decimals = -1; b_precedes = -1; b_local_rate = false; b_local_name = false; b_local_symbol = false; b_local_format = false; QXmlStreamAttributes attr = xml->attributes(); readAttributes(&attr, valid); readElements(xml, valid); } Currency::~Currency() {} Currency *Currency::copy() const { Currency *this_copy = new Currency(o_budget, s_code, s_symbol, s_name, 1.0, QDate(), b_precedes, i_decimals); this_copy->rates = rates; this_copy->setExchangeRateIsUpdated(b_local_rate); this_copy->setNameHasChanged(b_local_name); this_copy->setSymbolHasChanged(b_local_symbol); this_copy->setFormatHasChanged(b_local_format); return this_copy; } bool Currency::merge(Currency *currency, bool keep_rates) { bool has_changed = false; if(!currency->name().isEmpty() && currency->name() != s_name) { has_changed = true; b_local_name = true; s_name = currency->name(); } if(!currency->symbol().isEmpty() && currency->symbol() != s_symbol) { has_changed = true; b_local_symbol = true; s_symbol = currency->symbol(); } if(this != o_budget->currency_euro) { if(!keep_rates) rates.clear(); QMap::const_iterator it = currency->rates.constBegin(); while (it != currency->rates.constEnd()) { rates[it.key()] = it.value(); ++it; } } b_local_rate = true; has_changed = true; if(currency->fractionalDigits(false) >= 0 && currency->fractionalDigits(false) != i_decimals) { has_changed = true; b_local_format = true; i_decimals = currency->fractionalDigits(false); } if(currency->symbolPrecedes(false) >= 0 && currency->symbolPrecedes(false) != b_precedes) { has_changed = true; b_local_format = true; b_precedes = currency->symbolPrecedes(false); } return has_changed; } void Currency::readAttributes(QXmlStreamAttributes *attr, bool *valid) { s_name = attr->value("name").trimmed().toString(); s_code = attr->value("code").trimmed().toString(); if(s_code.isEmpty() && valid) *valid = false; s_symbol = attr->value("symbol").trimmed().toString(); QString s_source = attr->value("source").trimmed().toString(); if(s_source == "ECB") r_source = EXCHANGE_RATE_SOURCE_ECB; else if(s_source == "mycurrency.net") r_source = EXCHANGE_RATE_SOURCE_MYCURRENCY_NET; else r_source = EXCHANGE_RATE_SOURCE_NONE; if(attr->hasAttribute("decimals")) i_decimals = attr->value("decimals").toInt(); if(attr->hasAttribute("precedes")) b_precedes = attr->value("precedes").toInt(); if(i_decimals < 0) i_decimals = -1; } bool Currency::readElement(QXmlStreamReader *xml, bool*) { if(xml->name() == XML_COMPARE_CONST_CHAR("rate")) { QXmlStreamAttributes attr = xml->attributes(); QDate date = QDate::fromString(attr.value("date").toString(), Qt::ISODate); if(date.isValid()) rates[date] = attr.value("value").toDouble(); return false; } return false; } bool Currency::readElements(QXmlStreamReader *xml, bool *valid) { while(xml->readNextStartElement()) { if(!readElement(xml, valid)) xml->skipCurrentElement(); } return true; } void Currency::save(QXmlStreamWriter *xml, bool local_save) { QXmlStreamAttributes attr; writeAttributes(&attr, local_save); xml->writeAttributes(attr); writeElements(xml, local_save); } void Currency::writeAttributes(QXmlStreamAttributes *attr, bool local_save) { attr->append("code", s_code); if((!local_save || b_local_symbol) && !s_symbol.isEmpty()) attr->append("symbol", s_symbol); if((!local_save || b_local_name) && !s_name.isEmpty()) attr->append("name", s_name); if((!local_save || b_local_format) && i_decimals >= 0) attr->append("decimals", QString::number(i_decimals)); if((!local_save || b_local_format) && b_precedes >= 0) attr->append("precedes", QString::number(b_precedes)); if(!local_save && r_source == EXCHANGE_RATE_SOURCE_ECB) attr->append("source", "ECB"); if(!local_save && r_source == EXCHANGE_RATE_SOURCE_MYCURRENCY_NET) attr->append("source", "mycurrency.net"); } void Currency::writeElements(QXmlStreamWriter *xml, bool local_save) { if(local_save) { QMap::const_iterator it = rates.constBegin(); while(it != rates.constEnd()) { xml->writeStartElement("rate"); xml->writeAttribute("value", QString::number(it.value(), 'f', 5)); xml->writeAttribute("date", it.key().toString(Qt::ISODate)); xml->writeEndElement(); ++it; } } else if(!rates.isEmpty()) { xml->writeStartElement("rate"); xml->writeAttribute("value", QString::number(rates.last(), 'f', 5)); xml->writeAttribute("date", rates.lastKey().toString(Qt::ISODate)); xml->writeEndElement(); } } double Currency::exchangeRate(QDate date, bool exact_match) const { if(exact_match) { QMap::const_iterator it = rates.find(date); if(it == rates.constEnd()) return -1.0; return it.value(); } if(rates.isEmpty()) return 1.0; if(!date.isValid()) return rates.last(); QMap::const_iterator it = rates.lowerBound(date); if(it == rates.constEnd()) return rates.last(); if(it.key() != date && it != rates.constBegin()) { QMap::const_iterator it2 = it; --it2; if(date.daysTo(it.key()) >= it2.key().daysTo(date)) it = it2; } return it.value(); } QDate Currency::lastExchangeRateDate() const { if(rates.isEmpty()) return QDate(); return rates.lastKey(); } void Currency::setExchangeRate(double new_rate, QDate date) { if(!date.isValid()) date = QDate::currentDate(); rates[date] = new_rate; b_local_rate = true; } ExchangeRateSource Currency::exchangeRateSource() const { return r_source; } void Currency::setExchangeRateSource(ExchangeRateSource source) { r_source = source; } double Currency::convertTo(double value, const Currency *to_currency) const { if(to_currency == this) return value; if(rates.isEmpty()) return value * to_currency->exchangeRate(); return value / rates.last() * to_currency->exchangeRate(); } double Currency::convertFrom(double value, const Currency *from_currency) const { if(from_currency == this) return value; return from_currency->convertTo(value, this); } double Currency::convertTo(double value, const Currency *to_currency, const QDate &date) const { if(to_currency == this) return value; if(rates.isEmpty()) return value * to_currency->exchangeRate(date); if(!date.isValid()) return value / rates.last() * to_currency->exchangeRate(date); QMap::const_iterator it = rates.lowerBound(date); if(it == rates.constEnd()) return value / rates.last() * to_currency->exchangeRate(date); if(it.key() != date && it != rates.constBegin()) { QMap::const_iterator it2 = it; --it2; if(date.daysTo(it.key()) >= it2.key().daysTo(date)) it = it2; } return value / it.value() * to_currency->exchangeRate(date); } double Currency::convertFrom(double value, const Currency *from_currency, const QDate &date) const { if(from_currency == this) return value; return from_currency->convertTo(value, this, date); } QString Currency::formatValue(double value, int nr_of_decimals, bool show_currency, bool always_show_sign, bool conventional_sign_placement) const { if(nr_of_decimals < 0) { if(i_decimals < 0) nr_of_decimals = MONETARY_DECIMAL_PLACES; else nr_of_decimals = i_decimals; } if(is_zero(value)) value = 0.0; QString s; bool neg = false; if(value == 0.0) { s = "0"; if(nr_of_decimals > 0) { s += o_budget->monetary_decimal_separator; while(nr_of_decimals > 0) { s += '0'; nr_of_decimals--; } } } else { neg = value < 0; s = QString::number(neg ? -value : value, 'f', nr_of_decimals); int i = s.indexOf('.'); if(o_budget->monetary_decimal_separator != ".") s.replace(i, 1, o_budget->monetary_decimal_separator); if(!o_budget->monetary_group_separator.isEmpty() && !o_budget->monetary_group_format.isEmpty()) { int group_size = 3, i_format = 0; group_size = o_budget->monetary_group_format[i_format]; while(i > group_size) { i -= group_size; s.insert(i, o_budget->monetary_group_separator); if(o_budget->monetary_group_format.length() > i_format) { i_format++; if(o_budget->monetary_group_format[i_format] == (char) CHAR_MAX) break; if(o_budget->monetary_group_format[i_format] > (char) 0) group_size = o_budget->monetary_group_format[i_format]; } } } } bool use_symbol = show_currency && (this == o_budget->defaultCurrency()) && !s_symbol.isEmpty(); bool prefix = (use_symbol && ((b_precedes < 0 && ((neg && !conventional_sign_placement && o_budget->currency_symbol_precedes_neg) || ((!neg || conventional_sign_placement) && o_budget->currency_symbol_precedes))) || b_precedes > 0)) || (show_currency && !use_symbol && ((neg && !conventional_sign_placement && o_budget->currency_code_precedes_neg) || ((!neg || conventional_sign_placement) && o_budget->currency_code_precedes))); bool use_space = show_currency && ((use_symbol && useSymbolSpace(neg)) || (!use_symbol && useCodeSpace(neg))); int sign_place = 1; if(conventional_sign_placement || !show_currency) { sign_place = -1; } else if(always_show_sign) { sign_place = 1; } else if(use_symbol && neg) { sign_place = o_budget->monetary_sign_p_symbol_neg; } else if(use_symbol && !neg) { sign_place = o_budget->monetary_sign_p_symbol_pos; } else if(!use_symbol && neg) { sign_place = o_budget->monetary_sign_p_code_neg; } else if(!use_symbol && !neg) { sign_place = o_budget->monetary_sign_p_code_pos; } if(sign_place == 0 && always_show_sign) sign_place = -1; QString sgn; if(always_show_sign && value == 0.0) { sgn = "±"; } else if(neg) { if(!always_show_sign && !o_budget->monetary_negative_sign.isEmpty()) sgn = o_budget->monetary_negative_sign; else sgn = QLocale().negativeSign(); } else { if(!always_show_sign && !o_budget->monetary_positive_sign.isEmpty()) sgn = o_budget->monetary_positive_sign; else if(always_show_sign) sgn = QLocale().positiveSign(); } if(!sgn.isEmpty()) { if(sign_place < 0 || (!prefix && sign_place == 1) || (prefix && sign_place == 4)) { s.insert(0, sgn); sgn.clear(); } else if((!prefix && sign_place == 3) || (prefix && sign_place == 2)) { s += sgn; sgn.clear(); } } if(show_currency) { if(use_symbol) { if(prefix) { if(use_space) s = s_symbol + " " + s; else s = s_symbol + s; } else { if(use_space) s = s + " " + s_symbol; else s = s + s_symbol; } } else { if(prefix) { if(use_space) s = s_code + " " + s; else s = s_code + s; } else { if(use_space) s = s + " " + s_code; else s = s + s_code; } } } if(!sgn.isEmpty()) { if((prefix && sign_place == 1) || (prefix && sign_place == 3)) { s.insert(0, sgn); } else if((!prefix && sign_place == 2) || (!prefix && sign_place == 4)) { s += sgn; } else if(sign_place == 0 && neg) { s.insert(0, '('); s += ')'; } } return s; } const QString &Currency::code() const { return s_code; } const QString &Currency::symbol(bool return_code_if_empty) const { if(return_code_if_empty && s_symbol.isEmpty()) return s_code; return s_symbol; } const QString &Currency::name(bool return_code_if_empty) const { if(return_code_if_empty && s_name.isEmpty()) return s_code; return s_name; } void Currency::setCode(QString new_code) { s_code = new_code; } void Currency::setSymbol(QString new_symbol) { s_symbol = new_symbol; b_local_symbol = true; } void Currency::setName(QString new_name) { s_name = new_name; b_local_name = true; } int Currency::symbolPrecedes(bool return_default_if_unset) const { if(return_default_if_unset && b_precedes < 0) return o_budget->currency_symbol_precedes; return b_precedes; } void Currency::setSymbolPrecedes(int new_precedes) { b_precedes = new_precedes; b_local_format = true; } bool Currency::codePrecedes() const { return o_budget->currency_code_precedes; } bool Currency::useSymbolSpace(bool neg) const { if(b_precedes < 0 || ((b_precedes > 0) == o_budget->currency_symbol_precedes)) { if(neg) return o_budget->currency_symbol_space_neg; else return o_budget->currency_symbol_space; } return !b_precedes; } bool Currency::useCodeSpace(bool neg) const { if(neg) return o_budget->currency_code_space_neg; else return o_budget->currency_code_space; } int Currency::fractionalDigits(bool return_default_if_unset) const { if(return_default_if_unset && i_decimals < 0) return o_budget->monetary_decimal_places; return i_decimals; } void Currency::setFractionalDigits(int new_frac_digits) { i_decimals = new_frac_digits; if(i_decimals < 0) i_decimals = -1; b_local_format = true; } bool Currency::hasLocalChanges() const {return b_local_format || b_local_rate || b_local_name || b_local_symbol;} void Currency::setAsLocal(bool b_local) {b_local_format = b_local; b_local_rate = b_local; b_local_name = b_local; b_local_symbol = b_local;} bool Currency::exchangeRateIsUpdated() const {return b_local_rate;} void Currency::setExchangeRateIsUpdated(bool exchange_rate_is_updated) {b_local_rate = exchange_rate_is_updated;} bool Currency::formatHasChanged() const {return b_local_format;} void Currency::setFormatHasChanged(bool format_has_changed) {b_local_format = format_has_changed;} bool Currency::nameHasChanged() const {return b_local_name;} void Currency::setNameHasChanged(bool name_has_changed) {b_local_name = name_has_changed;} bool Currency::symbolHasChanged() const {return b_local_symbol;} void Currency::setSymbolHasChanged(bool symbol_has_changed) {b_local_symbol = symbol_has_changed;} bool currency_list_less_than(Currency *c1, Currency *c2) { return QString::localeAwareCompare(c1->code(), c2->code()) < 0; } Eqonomize-1.5.3/src/currency.h000066400000000000000000000122351416454732000162710ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2017 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifndef CURRENCY_H #define CURRENCY_H #include #include #include #include #include "eqonomizelist.h" class QXmlStreamReader; class QXmlStreamWriter; class QXmlStreamAttributes; class Budget; typedef enum { EXCHANGE_RATE_SOURCE_NONE, EXCHANGE_RATE_SOURCE_ECB, EXCHANGE_RATE_SOURCE_MYCURRENCY_NET } ExchangeRateSource; class Currency { Q_DECLARE_TR_FUNCTIONS(Currency) protected: int i_decimals; int b_precedes; QString s_code, s_symbol, s_name; ExchangeRateSource r_source; Budget *o_budget; bool b_local_rate, b_local_name, b_local_symbol, b_local_format; public: QMap rates; Currency(); Currency(Budget *parent_budget); Currency(Budget *parent_budget, QString initial_code, QString initial_symbol = QString(), QString initial_name = QString(), double initial_rate = 1.0, QDate date = QDate(), int initial_decimals = -1, int initial_precedes = -1); Currency(Budget *parent_budget, QXmlStreamReader *xml, bool *valid); ~Currency(); Currency *copy() const; bool merge(Currency *currency, bool keep_rates = true); void readAttributes(QXmlStreamAttributes *attr, bool *valid); bool readElement(QXmlStreamReader *xml, bool *valid); bool readElements(QXmlStreamReader *xml, bool *valid); void save(QXmlStreamWriter *xml, bool local_save = true); void writeAttributes(QXmlStreamAttributes *attr, bool local_save = true); void writeElements(QXmlStreamWriter *xml, bool local_save = true); double exchangeRate(QDate date = QDate(), bool exact_match = false) const; QDate lastExchangeRateDate() const; void setExchangeRate(double new_rate, QDate date = QDate()); ExchangeRateSource exchangeRateSource() const; void setExchangeRateSource(ExchangeRateSource source); double convertTo(double value, const Currency *to_currency) const; double convertFrom(double value, const Currency *from_currency) const; double convertTo(double value, const Currency *to_currency, const QDate &date) const; double convertFrom(double value, const Currency *from_currency, const QDate &date) const; QString formatValue(double value, int nr_of_decimals = -1, bool show_currency = true, bool always_show_sign = false, bool conventional_sign_placement = false) const; const QString &code() const; const QString &symbol(bool return_code_if_empty = false) const; const QString &name(bool return_code_if_empty = false) const; void setCode(QString new_code); void setSymbol(QString new_symbol); void setName(QString new_name); int symbolPrecedes(bool return_default_if_unset = true) const; void setSymbolPrecedes(int new_precedes); bool codePrecedes() const; bool useSymbolSpace(bool neg = false) const; bool useCodeSpace(bool neg = false) const; int fractionalDigits(bool return_default_if_unset = true) const; void setFractionalDigits(int new_frac_digits); bool hasLocalChanges() const; void setAsLocal(bool is_local = true); bool exchangeRateIsUpdated() const; void setExchangeRateIsUpdated(bool exchange_rate_is_updated = true); bool formatHasChanged() const; void setFormatHasChanged(bool format_has_changed = true); bool nameHasChanged() const; void setNameHasChanged(bool name_has_changed = true); bool symbolHasChanged() const; void setSymbolHasChanged(bool symbol_has_changed = true); }; bool currency_list_less_than(Currency *c1, Currency *c2); template class CurrencyList : public EqonomizeList { public: CurrencyList() : EqonomizeList() {}; void sort() { std::sort(QList::begin(), QList::end(), currency_list_less_than); } void inSort(type value) { QList::insert(std::lower_bound(QList::begin(), QList::end(), value, currency_list_less_than), value); } }; #endif Eqonomize-1.5.3/src/currencyconversiondialog.cpp000066400000000000000000000141031416454732000221060ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2017 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include "budget.h" #include "eqonomizevalueedit.h" #include "currencyconversiondialog.h" CurrencyConversionDialog::CurrencyConversionDialog(Budget *budg, QWidget *parent) : QDialog(parent), budget(budg) { setWindowTitle(tr("Currency Converter")); setModal(false); QVBoxLayout *box1 = new QVBoxLayout(this); QGridLayout *grid = new QGridLayout(); box1->addLayout(grid); fromEdit = new EqonomizeValueEdit(1.0, false, false, this, budget); grid->addWidget(fromEdit, 0, 0); fromCombo = new QComboBox(this); fromCombo->setEditable(false); grid->addWidget(fromCombo, 0, 1); toEdit = new EqonomizeValueEdit(1.0, false, false, this, budget); grid->addWidget(toEdit, 1, 0); toCombo = new QComboBox(this); toCombo->setEditable(false); grid->addWidget(toCombo, 1, 1); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); buttonBox->button(QDialogButtonBox::Close)->setAutoDefault(false); connect(buttonBox->button(QDialogButtonBox::Close), SIGNAL(clicked()), this, SLOT(reject())); box1->addWidget(buttonBox); updateCurrencies(); convert_from = true; connect(fromEdit, SIGNAL(valueChanged(double)), this, SLOT(convertFrom())); connect(toEdit, SIGNAL(valueChanged(double)), this, SLOT(convertTo())); connect(fromCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(convert())); connect(toCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(convert())); } void CurrencyConversionDialog::updateCurrencies() { Currency *fromCur = NULL, *prev_fromCur = NULL; Currency *toCur = NULL, *prev_toCur = NULL; if(fromCombo->count() > 0) { fromCur = (Currency*) fromCombo->currentData().value(); if(!budget->currencies.contains(fromCur)) fromCur = NULL; toCur = (Currency*) toCombo->currentData().value(); if(!budget->currencies.contains(toCur)) toCur = NULL; prev_fromCur = fromCur; prev_toCur = toCur; } if(!toCur) toCur = budget->defaultCurrency(); if(!fromCur) { fromCur = budget->defaultCurrency(); if(toCur == fromCur) { for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { AssetsAccount *acc = *it; if(acc->currency() != NULL && acc->currency() != toCur) { fromCur = acc->currency(); break; } } } if(toCur == fromCur) fromCur = budget->currency_euro; if(toCur == fromCur) { fromCur = budget->findCurrency("USD"); if(!fromCur) fromCur = toCur; } } fromCombo->clear(); toCombo->clear(); int i = 0; for(CurrencyList::const_iterator it = budget->currencies.constBegin(); it != budget->currencies.constEnd(); ++it) { Currency *currency = *it; if(!currency->name(false).isEmpty()) { fromCombo->addItem(QIcon(":/data/flags/" + currency->code() + ".png"), QString("%2 (%1)").arg(qApp->translate("currencies.xml", qPrintable(currency->name()))).arg(currency->code())); toCombo->addItem(QIcon(":/data/flags/" + currency->code() + ".png"), QString("%2 (%1)").arg(qApp->translate("currencies.xml", qPrintable(currency->name()))).arg(currency->code())); } else { fromCombo->addItem(currency->code()); toCombo->addItem(currency->code()); } fromCombo->setItemData(i, QVariant::fromValue((void*) currency)); toCombo->setItemData(i, QVariant::fromValue((void*) currency)); if(currency == fromCur) fromCombo->setCurrentIndex(i); if(currency == toCur) toCombo->setCurrentIndex(i); i++; } if(prev_fromCur != fromCur || prev_toCur != toCur) convertFrom(); } void CurrencyConversionDialog::convertFrom() { if(!fromCombo->currentData().isValid() || !toCombo->currentData().isValid()) return; Currency *fromCur = (Currency*) fromCombo->currentData().value(); Currency *toCur = (Currency*) toCombo->currentData().value(); if(!fromCur || !toCur) return; toEdit->blockSignals(true); toEdit->setValue(fromCur->convertTo(fromEdit->value(), toCur)); toEdit->blockSignals(false); convert_from = true; } void CurrencyConversionDialog::convertTo() { if(!fromCombo->currentData().isValid() || !toCombo->currentData().isValid()) return; Currency *fromCur = (Currency*) fromCombo->currentData().value(); Currency *toCur = (Currency*) toCombo->currentData().value(); if(!fromCur || !toCur) return; fromEdit->blockSignals(true); fromEdit->setValue(toCur->convertTo(toEdit->value(), fromCur)); fromEdit->blockSignals(false); convert_from = false; } void CurrencyConversionDialog::convert() { if(convert_from) convertFrom(); else convertTo(); } Eqonomize-1.5.3/src/currencyconversiondialog.h000066400000000000000000000037141416454732000215610ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2017 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifndef CURRENCY_CONVERSION_DIALOG_H #define CURRENCY_CONVERSION_DIALOG_H #include class QComboBox; class Budget; class EqonomizeValueEdit; class CurrencyConversionDialog : public QDialog { Q_OBJECT protected: EqonomizeValueEdit *fromEdit, *toEdit; QComboBox *fromCombo, *toCombo; Budget *budget; bool convert_from; public: CurrencyConversionDialog(Budget *budg, QWidget *parent); void updateCurrencies(); public slots: void convertFrom(); void convertTo(); void convert(); }; #endif Eqonomize-1.5.3/src/editaccountdialogs.cpp000066400000000000000000000637401416454732000206460ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "budget.h" #include "accountcombobox.h" #include "editaccountdialogs.h" #include "editcurrencydialog.h" #include "eqonomizevalueedit.h" EditAssetsAccountDialog::EditAssetsAccountDialog(Budget *budg, QWidget *parent, QString title, bool new_loan, int default_type, bool force_type, QString default_group) : QDialog(parent), budget(budg) { setWindowTitle(title); setModal(true); int row = 0; prev_currency_index = 1; QVBoxLayout *box1 = new QVBoxLayout(this); QGridLayout *grid = new QGridLayout(); box1->addLayout(grid); if(new_loan) { typeCombo = NULL; } else { grid->addWidget(new QLabel(tr("Type:"), this), row, 0); typeCombo = new QComboBox(this); typeCombo->setEditable(false); typeCombo->addItem(budget->getAccountTypeName(ASSETS_TYPE_CASH, true)); typeCombo->addItem(budget->getAccountTypeName(ASSETS_TYPE_CURRENT, true)); typeCombo->addItem(budget->getAccountTypeName(ASSETS_TYPE_SAVINGS, true)); typeCombo->addItem(budget->getAccountTypeName(ASSETS_TYPE_CREDIT_CARD, true)); typeCombo->addItem(budget->getAccountTypeName(ASSETS_TYPE_LIABILITIES, true)); typeCombo->addItem(budget->getAccountTypeName(ASSETS_TYPE_SECURITIES, true)); typeCombo->addItem(budget->getAccountTypeName(ASSETS_TYPE_OTHER, true)); grid->addWidget(typeCombo, row, 1); row++; } grid->addWidget(new QLabel(tr("Group:"), this), row, 0); groupCombo = new QComboBox(this); groupCombo->setEditable(true); QStringList groups; if(!new_loan) { groups << budget->getAccountTypeName(ASSETS_TYPE_CASH, true, true); groups << budget->getAccountTypeName(ASSETS_TYPE_CURRENT, true, true); groups << budget->getAccountTypeName(ASSETS_TYPE_SAVINGS, true, true); groups << budget->getAccountTypeName(ASSETS_TYPE_SECURITIES, true, true); } groups << budget->getAccountTypeName(ASSETS_TYPE_CREDIT_CARD, true, true); groups << budget->getAccountTypeName(ASSETS_TYPE_LIABILITIES, true, true); for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { AssetsAccount *aaccount = *it; if(!new_loan || aaccount->isLiabilities()) { if(!aaccount->group().isEmpty()) groups << aaccount->group(); } } groups.removeDuplicates(); groups.sort(Qt::CaseInsensitive); groupCombo->addItems(groups); groupCombo->lineEdit()->setPlaceholderText(tr("no group")); grid->addWidget(groupCombo, row, 1); row++; if(!default_group.isEmpty()) groupCombo->setCurrentText(default_group); else if(default_type >= 0 && !budget->getAccountTypeName(default_type, true, true).isEmpty()) groupCombo->setCurrentText(budget->getAccountTypeName(default_type, true, true)); if(default_type >= 0) { switch(default_type) { case ASSETS_TYPE_CASH: {typeCombo->setCurrentIndex(0); break;} case ASSETS_TYPE_CURRENT: {typeCombo->setCurrentIndex(1); break;} case ASSETS_TYPE_SAVINGS: {typeCombo->setCurrentIndex(2); break;} case ASSETS_TYPE_CREDIT_CARD: {typeCombo->setCurrentIndex(3); break;} case ASSETS_TYPE_LIABILITIES: {typeCombo->setCurrentIndex(4); break;} case ASSETS_TYPE_SECURITIES: {typeCombo->setCurrentIndex(5); break;} case ASSETS_TYPE_OTHER: {typeCombo->setCurrentIndex(6); break;} } if(force_type) typeCombo->setEnabled(false); } grid->addWidget(new QLabel(tr("Currency:"), this), row, 0); currencyCombo = new QComboBox(this); currencyCombo->setEditable(false); grid->addWidget(currencyCombo, row, 1); row++; editCurrencyButton = new QPushButton(tr("Edit"), this); grid->addWidget(editCurrencyButton, row, 1, Qt::AlignRight); row++; grid->addWidget(new QLabel(tr("Name:"), this), row, 0); nameEdit = new QLineEdit(this); grid->addWidget(nameEdit, row, 1); row++; maintainerLabel = new QLabel(tr("Bank:")); grid->addWidget(maintainerLabel, row, 0); maintainerEdit = new QLineEdit(this); grid->addWidget(maintainerEdit, row, 1); row++; valueLabel = new QLabel(new_loan ? tr("Debt:") : tr("Opening balance:", "Account balance"), this); grid->addWidget(valueLabel, row, 0); valueEdit = new EqonomizeValueEdit(!new_loan, this, budget); grid->addWidget(valueEdit, row, 1); row++; if(new_loan) { initialButton = new QRadioButton(tr("Opening balance", "Account balance"), this); initialButton->setChecked(true); grid->addWidget(initialButton, row, 0, 1, 2); row++; transferButton = new QRadioButton(tr("Transferred to:"), this); grid->addWidget(transferButton, row, 0); accountCombo = new AccountComboBox(ACCOUNT_TYPE_ASSETS, budget, false, false, false, true, true, this); accountCombo->updateAccounts(); grid->addWidget(accountCombo, row, 1); row++; grid->addWidget(new QLabel(tr("Date:")), row, 0); dateEdit = new EqonomizeDateEdit(QDate::currentDate()); dateEdit->setCalendarPopup(true); grid->addWidget(dateEdit, row, 1); row++; budgetButton = NULL; if(!accountCombo->hasAccount()) { transferButton->setEnabled(false); } transferToggled(false); maintainerLabel->setText(tr("Lender:")); } else { accountCombo = NULL; dateEdit = NULL; initialButton = NULL; transferButton = NULL; budgetButton = new QCheckBox(tr("Default account for budgeted transactions"), this); budgetButton->setChecked(false); grid->addWidget(budgetButton, row, 0, 1, 2); row++; maintainerEdit->setEnabled(typeCombo->currentIndex() != 0); maintainerLabel->setEnabled(typeCombo->currentIndex() != 0); } grid->addWidget(new QLabel(tr("Description:"), this), row, 0); row++; descriptionEdit = new QTextEdit(this); grid->addWidget(descriptionEdit, row, 0, 1, 2); row++; if(new_loan) { closedButton = NULL; } else { closedButton = new QCheckBox(tr("Account is closed"), this); closedButton->setChecked(false); closedButton->hide(); grid->addWidget(closedButton, row, 0, 1, 2); row++; } nameEdit->setFocus(); current_account = NULL; updateCurrencyList(budget->defaultCurrency()); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, this); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept())); box1->addWidget(buttonBox); if(typeCombo) connect(typeCombo, SIGNAL(activated(int)), this, SLOT(typeActivated(int))); if(currencyCombo) connect(currencyCombo, SIGNAL(activated(int)), this, SLOT(currencyActivated(int))); if(closedButton) connect(closedButton, SIGNAL(toggled(bool)), this, SLOT(closedToggled(bool))); if(transferButton) connect(transferButton, SIGNAL(toggled(bool)), this, SLOT(transferToggled(bool))); connect(editCurrencyButton, SIGNAL(clicked()), this, SLOT(editCurrency())); } void EditAssetsAccountDialog::updateCurrencyList(Currency *select_currency) { currencyCombo->clear(); currencyCombo->addItem(tr("New currency…")); int i = 1; for(CurrencyList::const_iterator it = budget->currencies.constBegin(); it != budget->currencies.constEnd(); ++it) { Currency *currency = *it; if(!currency->name(false).isEmpty()) { currencyCombo->addItem(QIcon(":/data/flags/" + currency->code() + ".png"), QString("%2 (%1)").arg(qApp->translate("currencies.xml", qPrintable(currency->name()))).arg(currency->code())); } else { currencyCombo->addItem(currency->code()); } currencyCombo->setItemData(i, QVariant::fromValue((void*) currency)); if(currency == select_currency) { prev_currency_index = i; currencyCombo->setCurrentIndex(i); valueEdit->setCurrency((Currency*) currencyCombo->itemData(i).value()); } i++; } } void EditAssetsAccountDialog::transferToggled(bool b) { dateEdit->setEnabled(b); accountCombo->setEnabled(b); } void EditAssetsAccountDialog::closedToggled(bool b) { if(b) budgetButton->setChecked(false); int index = typeCombo->currentIndex(); budgetButton->setEnabled(!b && index != 5 && index != 4 && index != 3); } void EditAssetsAccountDialog::currencyActivated(int index) { Currency *cur = NULL; if(index > 0) cur = (Currency*) currencyCombo->itemData(index).value(); if(index != prev_currency_index && current_account && cur != current_account->currency() && budget->accountHasTransactions(current_account) && QMessageBox::question(this, tr("Warning"), tr("If you change the currency of an account, the currency of all associated transactions will also change, without any conversion. Do do wish to continue anyway?")) != QMessageBox::Yes) { currencyCombo->setCurrentIndex(prev_currency_index); return; } if(index == 0) { EditCurrencyDialog *dialog = new EditCurrencyDialog(budget, NULL, true, this); if(dialog->exec() == QDialog::Accepted) { cur = dialog->createCurrency(); updateCurrencyList(cur); } else { currencyCombo->setCurrentIndex(prev_currency_index); } dialog->deleteLater(); } else { valueEdit->setCurrency(cur); prev_currency_index = index; } } void EditAssetsAccountDialog::editCurrency() { int i = currencyCombo->currentIndex(); if(i == 0) return; Currency *cur = (Currency*) currencyCombo->itemData(i).value(); EditCurrencyDialog *dialog = new EditCurrencyDialog(budget, cur, true, this); if(dialog->exec() == QDialog::Accepted) { dialog->modifyCurrency(cur); } dialog->deleteLater(); } void EditAssetsAccountDialog::typeActivated(int index) { if(index == 5 && current_account && current_account->accountType() != ASSETS_TYPE_SECURITIES && budget->accountHasTransactions(current_account)) { QMessageBox::critical(this, tr("Error"), tr("Type cannot be changed to securities for accounts with transactions.")); switch(current_account->accountType()) { case ASSETS_TYPE_CASH: {typeCombo->setCurrentIndex(0); break;} case ASSETS_TYPE_CURRENT: {typeCombo->setCurrentIndex(1); break;} case ASSETS_TYPE_SAVINGS: {typeCombo->setCurrentIndex(2); break;} case ASSETS_TYPE_CREDIT_CARD: {typeCombo->setCurrentIndex(3); break;} case ASSETS_TYPE_LIABILITIES: {typeCombo->setCurrentIndex(4); break;} default: {typeCombo->setCurrentIndex(6); break;} } return; } int i_type = -1; switch(typeCombo->currentIndex()) { case 0: {i_type = ASSETS_TYPE_CASH; break;} case 1: {i_type = ASSETS_TYPE_CURRENT; break;} case 2: {i_type = ASSETS_TYPE_SAVINGS; break;} case 3: {i_type = ASSETS_TYPE_CREDIT_CARD; break;} case 4: {i_type = ASSETS_TYPE_LIABILITIES; break;} case 5: {i_type = ASSETS_TYPE_SECURITIES; break;} default: {i_type = ASSETS_TYPE_OTHER; break;} } if(budget->getAccountType(groupCombo->currentText(), true, true) != ASSETS_TYPE_OTHER) groupCombo->setCurrentText(budget->getAccountTypeName(i_type, true, true)); valueEdit->setEnabled(index != 5); budgetButton->setEnabled(index != 5 && index != 4 && index != 3); closedButton->setEnabled(index != 4); if(index == 4) closedButton->setChecked(false); if(index == 5 || index == 4 || index == 3) budgetButton->setChecked(false); if(index == 5) valueEdit->setValue(0.0); maintainerEdit->setEnabled(index != 0); maintainerLabel->setEnabled(index != 0); if(index == 3) maintainerLabel->setText(tr("Issuer:")); else if(index == 4) maintainerLabel->setText(tr("Lender:")); else maintainerLabel->setText(tr("Bank:")); } AssetsAccount *EditAssetsAccountDialog::newAccount(Transaction **transfer) { AssetsType type; if(typeCombo) { switch(typeCombo->currentIndex()) { case 0: {type = ASSETS_TYPE_CASH; break;} case 1: {type = ASSETS_TYPE_CURRENT; break;} case 2: {type = ASSETS_TYPE_SAVINGS; break;} case 3: {type = ASSETS_TYPE_CREDIT_CARD; break;} case 4: {type = ASSETS_TYPE_LIABILITIES; break;} case 5: {type = ASSETS_TYPE_SECURITIES; break;} default: {type = ASSETS_TYPE_OTHER; break;} } } else { type = ASSETS_TYPE_LIABILITIES; } AssetsAccount *account = new AssetsAccount(budget, type, nameEdit->text(), 0.0, descriptionEdit->toPlainText()); int i = currencyCombo->currentIndex(); account->setCurrency((Currency*) currencyCombo->itemData(i).value()); if(maintainerEdit->isEnabled()) account->setMaintainer(maintainerEdit->text()); else account->setMaintainer(""); account->setGroup(groupCombo->currentText()); if(transfer && transferButton && transferButton->isChecked()) { Transaction *trans = new Transfer(budget, valueEdit->value(), dateEdit->date(), account, (AssetsAccount*) accountCombo->currentAccount(), nameEdit->text()); *transfer = trans; } else if(type == ASSETS_TYPE_LIABILITIES && transferButton) { account->setInitialBalance(-valueEdit->value()); } else { account->setInitialBalance(valueEdit->value()); } if(budgetButton) account->setAsBudgetAccount(budgetButton->isChecked()); return account; } void EditAssetsAccountDialog::modifyAccount(AssetsAccount *account) { account->setName(nameEdit->text()); if(maintainerEdit->isEnabled()) account->setMaintainer(maintainerEdit->text()); else account->setMaintainer(""); account->setInitialBalance(valueEdit->value()); account->setDescription(descriptionEdit->toPlainText()); account->setAsBudgetAccount(budgetButton->isChecked()); account->setClosed(closedButton->isChecked()); account->setGroup(groupCombo->currentText()); switch(typeCombo->currentIndex()) { case 0: {account->setAccountType(ASSETS_TYPE_CASH); break;} case 1: {account->setAccountType(ASSETS_TYPE_CURRENT); break;} case 2: {account->setAccountType(ASSETS_TYPE_SAVINGS); break;} case 3: {account->setAccountType(ASSETS_TYPE_CREDIT_CARD); break;} case 4: {account->setAccountType(ASSETS_TYPE_LIABILITIES); break;} case 5: {account->setAccountType(ASSETS_TYPE_SECURITIES); break;} default: {account->setAccountType(ASSETS_TYPE_OTHER); break;} } int i = currencyCombo->currentIndex(); account->setCurrency((Currency*) currencyCombo->itemData(i).value()); } void EditAssetsAccountDialog::setAccount(AssetsAccount *account) { current_account = account; if(account->isClosed() || budget->accountHasTransactions(account)) { closedButton->show(); closedButton->setChecked(account->isClosed()); } else { closedButton->hide(); closedButton->setChecked(false); } nameEdit->setText(account->name()); maintainerEdit->setText(account->maintainer()); valueEdit->setValue(account->initialBalance()); valueEdit->setCurrency(account->currency()); descriptionEdit->setPlainText(account->description()); budgetButton->setChecked(account->isBudgetAccount()); typeCombo->setEnabled(true); switch(account->accountType()) { case ASSETS_TYPE_CASH: {typeCombo->setCurrentIndex(0); break;} case ASSETS_TYPE_CURRENT: {typeCombo->setCurrentIndex(1); break;} case ASSETS_TYPE_SAVINGS: {typeCombo->setCurrentIndex(2); break;} case ASSETS_TYPE_CREDIT_CARD: {typeCombo->setCurrentIndex(3); break;} case ASSETS_TYPE_LIABILITIES: {typeCombo->setCurrentIndex(4); break;} case ASSETS_TYPE_SECURITIES: { typeCombo->setCurrentIndex(5); for(SecurityList::const_iterator it = budget->securities.constBegin(); it != budget->securities.constEnd(); ++it) { Security *sec = *it; if(sec->account() == account) { typeCombo->setEnabled(false); break; } } break; } default: {typeCombo->setCurrentIndex(6); break;} } for(int i = 0; i < currencyCombo->count(); i++) { if(currencyCombo->itemData(i).value() == account->currency()) { currencyCombo->setCurrentIndex(i); prev_currency_index = i; break; } } typeActivated(typeCombo->currentIndex()); groupCombo->setCurrentText(account->group()); } void EditAssetsAccountDialog::accept() { QString sname = nameEdit->text().trimmed(); if(sname.isEmpty()) { nameEdit->setFocus(); QMessageBox::critical(this, tr("Error"), tr("Empty name.")); return; } AssetsAccount *aaccount = budget->findAssetsAccount(sname); if(aaccount && aaccount != current_account) { nameEdit->setFocus(); QMessageBox::critical(this, tr("Error"), tr("The entered name is used by another account.")); return; } if(transferButton && valueEdit->value() <= 0.0) { valueEdit->setFocus(); QMessageBox::critical(this, tr("Error"), tr("Zero value not allowed.")); return; } QDialog::accept(); } EditIncomesAccountDialog::EditIncomesAccountDialog(Budget *budg, IncomesAccount *default_parent, QWidget *parent, QString title) : QDialog(parent), budget(budg) { setWindowTitle(title); setModal(true); if(default_parent && default_parent->parentCategory()) default_parent = (IncomesAccount*) default_parent->parentCategory(); QVBoxLayout *box1 = new QVBoxLayout(this); QGridLayout *grid = new QGridLayout(); box1->addLayout(grid); grid->addWidget(new QLabel(tr("Name:"), this), 0, 0); nameEdit = new QLineEdit(this); grid->addWidget(nameEdit, 0, 1); grid->addWidget(new QLabel(tr("Parent category:"), this), 1, 0); parentCombo = new QComboBox(this); parentCombo->setEditable(false); grid->addWidget(parentCombo, 1, 1); parentCombo->addItem(tr("None")); parentCombo->setCurrentIndex(0); int i = 1; for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) { IncomesAccount *account = *it; if(!account->parentCategory()) { parentCombo->addItem(account->name()); parentCombo->setItemData(i, QVariant::fromValue((void*) account)); if(account == default_parent) parentCombo->setCurrentIndex(i); i++; } } budgetButton = new QCheckBox(tr("Monthly budget:"), this); budgetButton->setChecked(false); grid->addWidget(budgetButton, 2, 0); budgetEdit = new EqonomizeValueEdit(false, this, budget); budgetEdit->setEnabled(false); grid->addWidget(budgetEdit, 2, 1); grid->addWidget(new QLabel(tr("Description:"), this), 3, 0); descriptionEdit = new QTextEdit(this); grid->addWidget(descriptionEdit, 4, 0, 1, 2); nameEdit->setFocus(); current_account = NULL; QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, this); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept())); box1->addWidget(buttonBox); connect(budgetButton, SIGNAL(toggled(bool)), this, SLOT(budgetEnabled(bool))); } IncomesAccount *EditIncomesAccountDialog::newAccount() { IncomesAccount *account = new IncomesAccount(budget, nameEdit->text(), descriptionEdit->toPlainText()); if(budgetButton->isChecked()) { account->setMonthlyBudget(QDate::currentDate().year(), QDate::currentDate().month(), budgetEdit->value()); } int i = parentCombo->currentIndex(); if(i > 0) { account->setParentCategory((IncomesAccount*) parentCombo->itemData(i).value()); } return account; } void EditIncomesAccountDialog::modifyAccount(IncomesAccount *account) { account->setName(nameEdit->text()); account->setDescription(descriptionEdit->toPlainText()); int i = parentCombo->currentIndex(); account->setParentCategory((IncomesAccount*) parentCombo->itemData(i).value()); } void EditIncomesAccountDialog::setAccount(IncomesAccount *account) { current_account = account; nameEdit->setText(account->name()); if(!account->subCategories.isEmpty()) { parentCombo->setEnabled(false); } for(int i = 1; i < parentCombo->count(); i++) { if(parentCombo->itemData(i).value() == account) { parentCombo->removeItem(i); break; } else if(parentCombo->itemData(i).value() == account->parentCategory()) { parentCombo->setCurrentIndex(i); break; } } budgetEdit->hide(); budgetButton->hide(); descriptionEdit->setPlainText(account->description()); } void EditIncomesAccountDialog::budgetEnabled(bool b) { budgetEdit->setEnabled(b); } void EditIncomesAccountDialog::accept() { QString sname = nameEdit->text().trimmed(); if(sname.isEmpty()) { nameEdit->setFocus(); QMessageBox::critical(this, tr("Error"), tr("Empty name.")); return; } IncomesAccount *iaccount = budget->findIncomesAccount(sname); if(iaccount && iaccount != current_account) { nameEdit->setFocus(); QMessageBox::critical(this, tr("Error"), tr("The entered name is used by another income category.")); return; } QDialog::accept(); } EditExpensesAccountDialog::EditExpensesAccountDialog(Budget *budg, ExpensesAccount *default_parent, QWidget *parent, QString title) : QDialog(parent), budget(budg) { setWindowTitle(title); setModal(true); if(default_parent && default_parent->parentCategory()) default_parent = (ExpensesAccount*) default_parent->parentCategory(); QVBoxLayout *box1 = new QVBoxLayout(this); QGridLayout *grid = new QGridLayout(); box1->addLayout(grid); grid->addWidget(new QLabel(tr("Name:"), this), 0, 0); nameEdit = new QLineEdit(this); grid->addWidget(nameEdit, 0, 1); grid->addWidget(new QLabel(tr("Parent category:"), this), 1, 0); parentCombo = new QComboBox(this); parentCombo->setEditable(false); grid->addWidget(parentCombo, 1, 1); parentCombo->addItem(tr("None")); parentCombo->setCurrentIndex(0); int i = 1; for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) { ExpensesAccount *account = *it; if(!account->parentCategory()) { parentCombo->addItem(account->name()); parentCombo->setItemData(i, QVariant::fromValue((void*) account)); if(account == default_parent) parentCombo->setCurrentIndex(i); i++; } } budgetButton = new QCheckBox(tr("Monthly budget:"), this); budgetButton->setChecked(false); grid->addWidget(budgetButton, 2, 0); budgetEdit = new EqonomizeValueEdit(false, this, budget); budgetEdit->setEnabled(false); grid->addWidget(budgetEdit, 2, 1); grid->addWidget(new QLabel(tr("Description:"), this), 3, 0); descriptionEdit = new QTextEdit(this); grid->addWidget(descriptionEdit, 4, 0, 1, 2); nameEdit->setFocus(); current_account = NULL; QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, this); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept())); box1->addWidget(buttonBox); connect(budgetButton, SIGNAL(toggled(bool)), this, SLOT(budgetEnabled(bool))); } ExpensesAccount *EditExpensesAccountDialog::newAccount() { ExpensesAccount *account = new ExpensesAccount(budget, nameEdit->text(), descriptionEdit->toPlainText()); if(budgetButton->isChecked()) { account->setMonthlyBudget(QDate::currentDate().year(), QDate::currentDate().month(), budgetEdit->value()); } int i = parentCombo->currentIndex(); if(i > 0) { account->setParentCategory((ExpensesAccount*) parentCombo->itemData(i).value()); } return account; } void EditExpensesAccountDialog::modifyAccount(ExpensesAccount *account) { account->setName(nameEdit->text()); account->setDescription(descriptionEdit->toPlainText()); int i = parentCombo->currentIndex(); account->setParentCategory((ExpensesAccount*) parentCombo->itemData(i).value()); } void EditExpensesAccountDialog::setAccount(ExpensesAccount *account) { current_account = account; nameEdit->setText(account->name()); if(!account->subCategories.isEmpty()) { parentCombo->setEnabled(false); } for(int i = 1; i < parentCombo->count(); i++) { if(parentCombo->itemData(i).value() == account) { parentCombo->removeItem(i); break; } else if(parentCombo->itemData(i).value() == account->parentCategory()) { parentCombo->setCurrentIndex(i); break; } } budgetEdit->hide(); budgetButton->hide(); descriptionEdit->setPlainText(account->description()); } void EditExpensesAccountDialog::budgetEnabled(bool b) { budgetEdit->setEnabled(b); } void EditExpensesAccountDialog::accept() { QString sname = nameEdit->text().trimmed(); if(sname.isEmpty()) { nameEdit->setFocus(); QMessageBox::critical(this, tr("Error"), tr("Empty name.")); return; } ExpensesAccount *eaccount = budget->findExpensesAccount(sname); if(eaccount && eaccount != current_account) { nameEdit->setFocus(); QMessageBox::critical(this, tr("Error"), tr("The entered name is used by another expense category.")); return; } QDialog::accept(); } Eqonomize-1.5.3/src/editaccountdialogs.h000066400000000000000000000100111416454732000202720ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifndef EDIT_ACCOUNT_DIALOGS_H #define EDIT_ACCOUNT_DIALOGS_H #include class QCheckBox; class QComboBox; class QDateEdit; class QLabel; class QLineEdit; class QPushButton; class QRadioButton; class QTextEdit; class Account; class AccountComboBox; class AssetsAccount; class Budget; class Currency; class EqonomizeValueEdit; class ExpensesAccount; class IncomesAccount; class Transaction; class EditAssetsAccountDialog : public QDialog { Q_OBJECT protected: QLineEdit *nameEdit, *maintainerEdit; QLabel *valueLabel, *maintainerLabel; QDateEdit *dateEdit; QRadioButton *initialButton, *transferButton; EqonomizeValueEdit *valueEdit; QTextEdit *descriptionEdit; QComboBox *typeCombo, *groupCombo, *currencyCombo; QPushButton *editCurrencyButton; AccountComboBox *accountCombo; QCheckBox *budgetButton, *closedButton; Budget *budget; AssetsAccount *current_account; int prev_currency_index; public: EditAssetsAccountDialog(Budget *budg, QWidget *parent, QString title, bool new_loan = false, int default_type = -1, bool force_type = false, QString default_group = ""); AssetsAccount *newAccount(Transaction **transfer = NULL); void modifyAccount(AssetsAccount *account); void setAccount(AssetsAccount *account); void updateCurrencyList(Currency*); protected slots: void typeActivated(int); void currencyActivated(int); void accept(); void closedToggled(bool); void transferToggled(bool); void editCurrency(); }; class EditExpensesAccountDialog : public QDialog { Q_OBJECT protected: QLineEdit *nameEdit; QComboBox *parentCombo; EqonomizeValueEdit *budgetEdit; QTextEdit *descriptionEdit; QCheckBox *budgetButton; Budget *budget; Account *current_account; public: EditExpensesAccountDialog(Budget *budg, ExpensesAccount *default_parent, QWidget *parent, QString title); ExpensesAccount *newAccount(); void modifyAccount(ExpensesAccount *account); void setAccount(ExpensesAccount *account); protected slots: void budgetEnabled(bool); void accept(); }; class EditIncomesAccountDialog : public QDialog { Q_OBJECT protected: QLineEdit *nameEdit; QComboBox *parentCombo; EqonomizeValueEdit *budgetEdit; QTextEdit *descriptionEdit; QCheckBox *budgetButton; Budget *budget; Account *current_account; public: EditIncomesAccountDialog(Budget *budg, IncomesAccount *default_parent, QWidget *parent, QString title); IncomesAccount *newAccount(); void modifyAccount(IncomesAccount *account); void setAccount(IncomesAccount *account); protected slots: void budgetEnabled(bool); void accept(); }; #endif Eqonomize-1.5.3/src/editcurrencydialog.cpp000066400000000000000000000217631416454732000206600ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2017 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) # include #else # include #endif #include #include "budget.h" #include "eqonomizevalueedit.h" #include "editcurrencydialog.h" EditCurrencyDialog::EditCurrencyDialog(Budget *budg, Currency *cur, bool enable_set_as_default, QWidget *parent) : QDialog(parent), budget(budg), currency(cur) { if(currency) setWindowTitle(tr("Edit Currency")); else setWindowTitle(tr("New Currency")); setModal(true); int row = 0; QVBoxLayout *box1 = new QVBoxLayout(this); QGridLayout *grid = new QGridLayout(); box1->addLayout(grid); grid->addWidget(new QLabel(tr("Code:"), this), row, 0); codeEdit = new QLineEdit(this); if(currency) { codeEdit->setText(currency->code()); codeEdit->setEnabled(false); } else { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) codeEdit->setValidator(new QRegularExpressionValidator(QRegularExpression("^[^\\d\\s\\.\\,\\+\\-\\*\\^]+$"))); #else codeEdit->setValidator(new QRegExpValidator(QRegExp("^[^\\d\\s\\.\\,\\+\\-\\*\\^]+$"))); #endif } grid->addWidget(codeEdit, row, 1); row++; grid->addWidget(new QLabel(tr("Symbol:"), this), row, 0); symbolEdit = new QLineEdit(this); if(currency) symbolEdit->setText(currency->symbol(false)); grid->addWidget(symbolEdit, row, 1); row++; QHBoxLayout *box2 = new QHBoxLayout(); QButtonGroup *precedesGroup = new QButtonGroup(this); prefixButton = new QRadioButton(tr("Prefix"), this); suffixButton = new QRadioButton(tr("Suffix"), this); psDefaultButton = new QRadioButton(tr("Default"), this); precedesGroup->addButton(prefixButton); precedesGroup->addButton(suffixButton); precedesGroup->addButton(psDefaultButton); if(currency && currency->symbolPrecedes(false) > 0) prefixButton->setChecked(true); else if(currency && currency->symbolPrecedes(false) == 0) suffixButton->setChecked(true); else psDefaultButton->setChecked(true); box2->addWidget(prefixButton); box2->addWidget(suffixButton); box2->addWidget(psDefaultButton); grid->addLayout(box2, row, 0, 1, 2, Qt::AlignRight); row++; grid->addWidget(new QLabel(tr("Name:"), this), row, 0); nameEdit = new QLineEdit(this); if(currency) nameEdit->setText(currency->name(false)); grid->addWidget(nameEdit, row, 1); row++; grid->addWidget(new QLabel(tr("Decimals:"), this), row, 0); decimalsEdit = new QSpinBox(this); decimalsEdit->setRange(-1, 4); if(currency) decimalsEdit->setValue(currency->fractionalDigits(false)); else decimalsEdit->setValue(-1); decimalsEdit->setSpecialValueText(tr("Default")); grid->addWidget(decimalsEdit, row, 1); row++; QLabel *label = new QLabel(budget->currency_euro->formatValue(1.0) + " =", this); label->setAlignment(Qt::AlignRight); grid->addWidget(label, row, 0); rateEdit = new EqonomizeValueEdit(0.00001, 1.0, currency ? currency->exchangeRate() : 1.0, 5, false, this, budget); if(currency) rateEdit->setCurrency(currency, true); if(currency == budget->currency_euro) rateEdit->setEnabled(false); grid->addWidget(rateEdit, row, 1); row++; grid->addWidget(new QLabel(tr("Date:"), this), row, 0); dateEdit = new EqonomizeDateEdit(this); dateEdit->setMaximumDate(QDate::currentDate()); dateEdit->setCalendarPopup(true); if(currency == budget->currency_euro) dateEdit->setEnabled(false); QDate date; if(currency) date = currency->lastExchangeRateDate(); if(date.isValid()) dateEdit->setDate(date); else dateEdit->setDate(QDate::currentDate()); grid->addWidget(dateEdit, row, 1); row++; if(enable_set_as_default) { defaultButton = new QCheckBox(tr("Main currency"), this); defaultButton->setChecked(currency == budget->defaultCurrency()); defaultButton->setEnabled(currency != budget->defaultCurrency()); grid->addWidget(defaultButton, row, 0, 1, 2); row++; } else { defaultButton = NULL; } QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, this); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept())); box1->addWidget(buttonBox); if(currency == budget->defaultCurrency()) { connect(symbolEdit, SIGNAL(textChanged(const QString&)), this, SLOT(currencyChanged())); } if(!currency) { connect(codeEdit, SIGNAL(textChanged(const QString&)), this, SLOT(currencyChanged())); } connect(prefixButton, SIGNAL(toggled(bool)), this, SLOT(currencyChanged())); connect(suffixButton, SIGNAL(toggled(bool)), this, SLOT(currencyChanged())); connect(psDefaultButton, SIGNAL(toggled(bool)), this, SLOT(currencyChanged())); connect(decimalsEdit, SIGNAL(valueChanged(int)), this, SLOT(currencyChanged())); if(defaultButton) connect(defaultButton, SIGNAL(toggled(bool)), this, SLOT(currencyChanged())); } void EditCurrencyDialog::currencyChanged() { Currency *cur = new Currency(budget, codeEdit->text().trimmed(), symbolEdit->text().trimmed(), nameEdit->text().trimmed(), 1.0, QDate::currentDate(), decimalsEdit->value(), prefixButton->isChecked() ? 1 : (suffixButton->isChecked() ? 0 : - 1)); rateEdit->setCurrency(cur, true, defaultButton && defaultButton->isChecked(), true); delete cur; } Currency *EditCurrencyDialog::createCurrency() { Currency *cur = new Currency(budget, codeEdit->text().trimmed(), symbolEdit->text().trimmed(), nameEdit->text().trimmed(), rateEdit->value(), (rateEdit->value() == 1.0 && dateEdit->date() == QDate::currentDate()) ? QDate() : dateEdit->date(), decimalsEdit->value(), prefixButton->isChecked() ? 1 : (suffixButton->isChecked() ? 0 : - 1)); budget->addCurrency(cur); QString error = budget->saveCurrencies(); if(!error.isNull()) QMessageBox::critical(isVisible() ? this : parentWidget(), tr("Error"), tr("Error saving currencies: %1.").arg(error)); if(defaultButton && defaultButton->isChecked()) budget->setDefaultCurrency(cur); return cur; } void EditCurrencyDialog::modifyCurrency(Currency *cur) { cur->setName(nameEdit->text().trimmed()); cur->setSymbol(symbolEdit->text().trimmed()); if(cur != budget->currency_euro && (!cur->rates.isEmpty() || rateEdit->value() != 1.0 || dateEdit->date() != QDate::currentDate())) { cur->setExchangeRate(rateEdit->value(), dateEdit->date()); } cur->setFractionalDigits(decimalsEdit->value()); if(prefixButton->isChecked()) { cur->setSymbolPrecedes(1); } else if(suffixButton->isChecked()) { cur->setSymbolPrecedes(0); } else { cur->setSymbolPrecedes(-1); } budget->currencyModified(cur); QString error = budget->saveCurrencies(); if(!error.isNull()) QMessageBox::critical(isVisible() ? this : parentWidget(), tr("Error"), tr("Error saving currencies: %1.").arg(error)); if(defaultButton && defaultButton->isChecked()) budget->setDefaultCurrency(cur); } void EditCurrencyDialog::accept() { if(!currency) { QString scode = codeEdit->text().trimmed(); if(scode.isEmpty()) { codeEdit->setFocus(); QMessageBox::critical(this, tr("Error"), tr("Empty code.")); return; } if(budget->findCurrency(scode)) { codeEdit->setFocus(); QMessageBox::critical(this, tr("Error"), tr("Code already exists.")); return; } } QDialog::accept(); } Eqonomize-1.5.3/src/editcurrencydialog.h000066400000000000000000000043741416454732000203240ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2017 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifndef EDIT_CURRENCY_DIALOG_H #define EDIT_CURRENCY_DIALOG_H #include class QCheckBox; class QComboBox; class QDateEdit; class QLabel; class QLineEdit; class QRadioButton; class QSpinBox; class Currency; class Budget; class EqonomizeValueEdit; class EditCurrencyDialog : public QDialog { Q_OBJECT protected: QLineEdit *codeEdit, *symbolEdit, *nameEdit; QDateEdit *dateEdit; EqonomizeValueEdit *rateEdit; QCheckBox *defaultButton; QRadioButton *prefixButton, *suffixButton, *psDefaultButton; QSpinBox *decimalsEdit; Budget *budget; Currency *currency; public: EditCurrencyDialog(Budget *budg, Currency *cur, bool enable_set_as_default, QWidget *parent); void modifyCurrency(Currency*); Currency *createCurrency(); protected slots: void accept(); void currencyChanged(); }; #endif Eqonomize-1.5.3/src/editscheduledtransactiondialog.cpp000066400000000000000000001132401416454732000232240ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016-2020 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include "budget.h" #include "editscheduledtransactiondialog.h" #include "recurrence.h" #include "recurrenceeditwidget.h" #include "transactioneditwidget.h" #include "editsplitdialog.h" EditScheduledTransactionDialog::EditScheduledTransactionDialog(bool extra_parameters, int transaction_type, Security *security, bool select_security, Budget *budg, QWidget *parent, QString title, Account *account, bool allow_account_creation, bool withloan) : QDialog(parent), budget(budg), b_extra(extra_parameters), b_loan(withloan) { setWindowTitle(title); setModal(true); QVBoxLayout *box1 = new QVBoxLayout(this); tabs = new QTabWidget(); switch(transaction_type) { case TRANSACTION_TYPE_EXPENSE: { transactionEditWidget = new TransactionEditWidget(false, b_extra, transaction_type, NULL, false, security, SECURITY_ALL_VALUES, select_security, budget, NULL, allow_account_creation, false, withloan); tabs->addTab(transactionEditWidget, tr("Expense")); break; } case TRANSACTION_TYPE_INCOME: { transactionEditWidget = new TransactionEditWidget(false, b_extra, transaction_type, NULL, false, security, SECURITY_ALL_VALUES, select_security, budget, NULL, allow_account_creation); if(security) tabs->addTab(transactionEditWidget, tr("Dividend")); else tabs->addTab(transactionEditWidget, tr("Income")); break; } case TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND: { transactionEditWidget = new TransactionEditWidget(false, b_extra, transaction_type, NULL, false, security, SECURITY_ALL_VALUES, select_security, budget, NULL, allow_account_creation); tabs->addTab(transactionEditWidget, tr("Reinvested Dividend")); break; } case TRANSACTION_TYPE_TRANSFER: { transactionEditWidget = new TransactionEditWidget(false, b_extra, transaction_type, NULL, false, security, SECURITY_ALL_VALUES, select_security, budget, NULL, allow_account_creation); tabs->addTab(transactionEditWidget, tr("Transfer")); break; } case TRANSACTION_TYPE_SECURITY_BUY: { transactionEditWidget = new TransactionEditWidget(false, b_extra, transaction_type, NULL, false, security, SECURITY_ALL_VALUES, select_security, budget, NULL, allow_account_creation); tabs->addTab(transactionEditWidget, tr("Securities Purchase", "Financial security (e.g. stock, mutual fund)")); break; } case TRANSACTION_TYPE_SECURITY_SELL: { transactionEditWidget = new TransactionEditWidget(false, b_extra, transaction_type, NULL, false, security, SECURITY_ALL_VALUES, select_security, budget, NULL, allow_account_creation); tabs->addTab(transactionEditWidget, tr("Securities Sale", "Financial security (e.g. stock, mutual fund)")); break; } } transactionEditWidget->updateAccounts(NULL, NULL, true); transactionEditWidget->transactionsReset(); if(account) transactionEditWidget->setAccount(account); recurrenceEditWidget = new RecurrenceEditWidget(transactionEditWidget->date(), budget); tabs->addTab(recurrenceEditWidget, tr("Recurrence")); box1->addWidget(tabs); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, this); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept())); box1->addWidget(buttonBox); connect(transactionEditWidget, SIGNAL(dateChanged(const QDate&)), recurrenceEditWidget, SLOT(setStartDate(const QDate&))); connect(transactionEditWidget, SIGNAL(addmodify()), this, SLOT(accept())); transactionEditWidget->focusFirst(); } void EditScheduledTransactionDialog::keyPressEvent(QKeyEvent *e) { if(e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) return; QDialog::keyPressEvent(e); } bool EditScheduledTransactionDialog::checkAccounts() { return transactionEditWidget->checkAccounts(); } void EditScheduledTransactionDialog::accept() { if(!transactionEditWidget->validValues(true)) {tabs->setCurrentIndex(0); return;} recurrenceEditWidget->setStartDate(transactionEditWidget->date()); if(!recurrenceEditWidget->validValues()) {tabs->setCurrentIndex(1); return;} QDialog::accept(); } void EditScheduledTransactionDialog::setTransaction(Transaction *trans) { transactionEditWidget->setTransaction(trans); recurrenceEditWidget->setRecurrence(NULL); } void EditScheduledTransactionDialog::setValues(QString description_value, double value_value, double quantity_value, QDate date_value, Account *from_account_value, Account *to_account_value, QString payee_value, QString comment_value) { transactionEditWidget->setValues(description_value, value_value, quantity_value, date_value, from_account_value, to_account_value, payee_value, comment_value); } void EditScheduledTransactionDialog::setScheduledTransaction(ScheduledTransaction *strans) { transactionEditWidget->setTransaction((Transaction*) strans->transaction()); recurrenceEditWidget->setRecurrence(strans->recurrence()); } ScheduledTransaction *EditScheduledTransactionDialog::createScheduledTransaction() { Transactions *trans = NULL; if(b_loan) trans = transactionEditWidget->createTransactionWithLoan(); else trans = transactionEditWidget->createTransaction(); if(!trans) {tabs->setCurrentIndex(0); return NULL;} recurrenceEditWidget->setStartDate(trans->date()); return new ScheduledTransaction(budget, trans, recurrenceEditWidget->createRecurrence()); } bool EditScheduledTransactionDialog::modifyScheduledTransaction(ScheduledTransaction *strans) { Transaction *trans = transactionEditWidget->createTransaction(); if(!trans) {tabs->setCurrentIndex(0); return false;} trans->setId(strans->transaction()->id()); trans->setFirstRevision(strans->transaction()->firstRevision()); trans->setModified(); recurrenceEditWidget->setStartDate(trans->date()); strans->setRecurrence(recurrenceEditWidget->createRecurrence()); strans->setTransaction(trans); strans->setModified(); return true; } bool EditScheduledTransactionDialog::modifyTransaction(Transaction *trans, Recurrence *&rec) { if(!transactionEditWidget->modifyTransaction(trans)) {tabs->setCurrentIndex(0); return false;} recurrenceEditWidget->setStartDate(trans->date()); rec = recurrenceEditWidget->createRecurrence(); return true; } ScheduledTransaction *EditScheduledTransactionDialog::newScheduledTransaction(QString description_value, double value_value, double quantity_value, QDate date_value, Account *from_account_value, Account *to_account_value, QString payee_value, QString comment_value, int transaction_type, Budget *budg, QWidget *parent, Security *security, bool select_security, Account *account, bool extra_parameters, bool allow_account_creation, bool withloan) { EditScheduledTransactionDialog *dialog = NULL; switch(transaction_type) { case TRANSACTION_TYPE_EXPENSE: {dialog = new EditScheduledTransactionDialog(extra_parameters, transaction_type, security, select_security, budg, parent, withloan ? tr("New Expense Paid with Loan") : tr("New Expense"), account, allow_account_creation, withloan); break;} case TRANSACTION_TYPE_INCOME: { if(security || select_security) dialog = new EditScheduledTransactionDialog(extra_parameters, transaction_type, security, select_security, budg, parent, tr("New Dividend"), account, allow_account_creation); else dialog = new EditScheduledTransactionDialog(extra_parameters, transaction_type, security, select_security, budg, parent, tr("New Income"), account, allow_account_creation); break; } case TRANSACTION_TYPE_TRANSFER: {dialog = new EditScheduledTransactionDialog(extra_parameters, transaction_type, security, select_security, budg, parent, tr("New Transfer"), account, allow_account_creation); break;} case TRANSACTION_TYPE_SECURITY_BUY: {dialog = new EditScheduledTransactionDialog(extra_parameters, transaction_type, security, select_security, budg, parent, tr("New Securities Purchase", "Financial security (e.g. stock, mutual fund)"), account, allow_account_creation); break;} case TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND: {dialog = new EditScheduledTransactionDialog(extra_parameters, transaction_type, security, select_security, budg, parent, tr("New Reinvested Dividend"), account, allow_account_creation); break;} case TRANSACTION_TYPE_SECURITY_SELL: { dialog = new EditScheduledTransactionDialog(extra_parameters, transaction_type, security, select_security, budg, parent, tr("New Securities Sale", "Financial security (e.g. stock, mutual fund)"), account, allow_account_creation); //dialog->transactionEditWidget->setMaxSharesDate(QDate::currentDate()); break; } } dialog->setValues(description_value, value_value, quantity_value, date_value, from_account_value, to_account_value, payee_value, comment_value); ScheduledTransaction *strans = NULL; if((allow_account_creation || dialog->checkAccounts()) && dialog->exec() == QDialog::Accepted) { strans = dialog->createScheduledTransaction(); } dialog->deleteLater(); return strans; } ScheduledTransaction *EditScheduledTransactionDialog::newScheduledTransaction(int transaction_type, Budget *budg, QWidget *parent, Security *security, bool select_security, Account *account, bool extra_parameters, bool allow_account_creation, bool withloan) { EditScheduledTransactionDialog *dialog = NULL; switch(transaction_type) { case TRANSACTION_TYPE_EXPENSE: {dialog = new EditScheduledTransactionDialog(extra_parameters, transaction_type, security, select_security, budg, parent, withloan ? tr("New Expense Paid with Loan") : tr("New Expense"), account, allow_account_creation, withloan); break;} case TRANSACTION_TYPE_INCOME: { if(security || select_security) dialog = new EditScheduledTransactionDialog(extra_parameters, transaction_type, security, select_security, budg, parent, tr("New Dividend"), account, allow_account_creation); else dialog = new EditScheduledTransactionDialog(extra_parameters, transaction_type, security, select_security, budg, parent, tr("New Income"), account, allow_account_creation); break; } case TRANSACTION_TYPE_TRANSFER: {dialog = new EditScheduledTransactionDialog(extra_parameters, transaction_type, security, select_security, budg, parent, tr("New Transfer"), account, allow_account_creation); break;} case TRANSACTION_TYPE_SECURITY_BUY: {dialog = new EditScheduledTransactionDialog(extra_parameters, transaction_type, security, select_security, budg, parent, tr("New Securities Purchase", "Financial security (e.g. stock, mutual fund)"), account, allow_account_creation); break;} case TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND: {dialog = new EditScheduledTransactionDialog(extra_parameters, transaction_type, security, select_security, budg, parent, tr("New Reinvested Dividend"), account, allow_account_creation); break;} case TRANSACTION_TYPE_SECURITY_SELL: { dialog = new EditScheduledTransactionDialog(extra_parameters, transaction_type, security, select_security, budg, parent, tr("New Securities Sale", "Financial security (e.g. stock, mutual fund)"), account, allow_account_creation); //dialog->transactionEditWidget->setMaxSharesDate(QDate::currentDate()); break; } } ScheduledTransaction *strans = NULL; if((allow_account_creation || dialog->checkAccounts()) && dialog->exec() == QDialog::Accepted) { strans = dialog->createScheduledTransaction(); } dialog->deleteLater(); return strans; } bool EditScheduledTransactionDialog::editScheduledTransaction(ScheduledTransaction *strans, QWidget *parent, bool select_security, bool extra_parameters, bool allow_account_creation, bool clone_trans) { EditScheduledTransactionDialog *dialog = NULL; switch(strans->transactiontype()) { case TRANSACTION_TYPE_EXPENSE: {dialog = new EditScheduledTransactionDialog(extra_parameters, strans->transactiontype(), NULL, false, strans->budget(), parent, clone_trans ? tr("New Expense") : tr("Edit Expense"), NULL, allow_account_creation); break;} case TRANSACTION_TYPE_INCOME: { if(((Income*) strans->transaction())->subtype() == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND) dialog = new EditScheduledTransactionDialog(extra_parameters, TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND, ((Income*) strans->transaction())->security(), select_security, strans->budget(), parent, clone_trans ? tr("New Reinvested Dividend") : tr("Edit Reinvested Dividend"), NULL, allow_account_creation); if(((Income*) strans->transaction())->security()) dialog = new EditScheduledTransactionDialog(extra_parameters, strans->transactiontype(), ((Income*) strans->transaction())->security(), select_security, strans->budget(), parent, clone_trans ? tr("New Dividend") : tr("Edit Dividend"), NULL, allow_account_creation); else dialog = new EditScheduledTransactionDialog(extra_parameters, strans->transactiontype(), NULL, false, strans->budget(), parent, clone_trans ? tr("New Income") : tr("Edit Income"), NULL, allow_account_creation); break; } case TRANSACTION_TYPE_TRANSFER: {dialog = new EditScheduledTransactionDialog(extra_parameters, strans->transactiontype(), NULL, false, strans->budget(), parent, clone_trans ? tr("New Transfer") : tr("Edit Transfer"), NULL, allow_account_creation); break;} case TRANSACTION_TYPE_SECURITY_BUY: {dialog = new EditScheduledTransactionDialog(extra_parameters, strans->transactiontype(), ((SecurityTransaction*) strans->transaction())->security(), select_security, strans->budget(), parent, clone_trans ? tr("New Securities Purchase", "Financial security (e.g. stock, mutual fund)") : tr("Edit Securities Purchase", "Financial security (e.g. stock, mutual fund)"), NULL, allow_account_creation); break;} case TRANSACTION_TYPE_SECURITY_SELL: {dialog = new EditScheduledTransactionDialog(extra_parameters, strans->transactiontype(), ((SecurityTransaction*) strans->transaction())->security(), select_security, strans->budget(), parent, clone_trans ? tr("New Securities Sale", "Financial security (e.g. stock, mutual fund)") : tr("Edit Securities Sale", "Financial security (e.g. stock, mutual fund)"), NULL, allow_account_creation); break;} } dialog->setScheduledTransaction(strans); bool b = false; if((allow_account_creation || dialog->checkAccounts()) && dialog->exec() == QDialog::Accepted) { b = dialog->modifyScheduledTransaction(strans); } dialog->deleteLater(); return b; } bool EditScheduledTransactionDialog::editTransaction(Transaction *trans, Recurrence *&rec, QWidget *parent, bool select_security, bool extra_parameters, bool allow_account_creation, bool clone_trans) { EditScheduledTransactionDialog *dialog = NULL; switch(trans->type()) { case TRANSACTION_TYPE_EXPENSE: {dialog = new EditScheduledTransactionDialog(extra_parameters, trans->type(), NULL, false, trans->budget(), parent, clone_trans ? tr("New Expense") : tr("Edit Expense"), NULL, allow_account_creation); break;} case TRANSACTION_TYPE_INCOME: { if(trans->subtype() == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND) dialog = new EditScheduledTransactionDialog(extra_parameters, TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND, ((SecurityTransaction*) trans)->security(), select_security, trans->budget(), parent, clone_trans ? tr("New Dividend") : clone_trans ? tr("New Reinvested Dividend") : tr("Edit Reinvested Dividend"), NULL, allow_account_creation); else if(((Income*) trans)->security()) dialog = new EditScheduledTransactionDialog(extra_parameters, trans->type(), ((Income*) trans)->security(), select_security, trans->budget(), parent, tr("Edit Dividend"), NULL, allow_account_creation); else dialog = new EditScheduledTransactionDialog(extra_parameters, trans->type(), NULL, false, trans->budget(), parent, clone_trans ? tr("New Income") : tr("Edit Income"), NULL, allow_account_creation); break; } case TRANSACTION_TYPE_TRANSFER: {dialog = new EditScheduledTransactionDialog(extra_parameters, trans->type(), NULL, false, trans->budget(), parent, clone_trans ? tr("New Transfer") : tr("Edit Transfer"), NULL, allow_account_creation); break;} case TRANSACTION_TYPE_SECURITY_BUY: {dialog = new EditScheduledTransactionDialog(extra_parameters, trans->type(), ((SecurityTransaction*) trans)->security(), select_security, trans->budget(), parent, clone_trans ? tr("New Securities Purchase", "Financial security (e.g. stock, mutual fund)") : tr("Edit Securities Purchase", "Financial security (e.g. stock, mutual fund)"), NULL, allow_account_creation); break;} case TRANSACTION_TYPE_SECURITY_SELL: {dialog = new EditScheduledTransactionDialog(extra_parameters, trans->type(), ((SecurityTransaction*) trans)->security(), select_security, trans->budget(), parent, clone_trans ? tr("New Securities Sale", "Financial security (e.g. stock, mutual fund)") : tr("Edit Securities Sale", "Financial security (e.g. stock, mutual fund)"), NULL, allow_account_creation); break;} } dialog->setTransaction(trans); bool b = false; if((allow_account_creation || dialog->checkAccounts()) && dialog->exec() == QDialog::Accepted) { b = dialog->modifyTransaction(trans, rec); } dialog->deleteLater(); return b; } EditScheduledMultiItemDialog::EditScheduledMultiItemDialog(bool extra_parameters, Budget *budg, QWidget *parent, QString title, AssetsAccount *account, bool allow_account_creation) : QDialog(parent), budget(budg), b_extra(extra_parameters) { setWindowTitle(title); setModal(true); QVBoxLayout *box1 = new QVBoxLayout(this); tabs = new QTabWidget(); transactionEditWidget = new EditMultiItemWidget(budget, NULL, account, b_extra, allow_account_creation); tabs->addTab(transactionEditWidget, tr("Transactions")); recurrenceEditWidget = new RecurrenceEditWidget(transactionEditWidget->date(), budget); tabs->addTab(recurrenceEditWidget, tr("Recurrence")); box1->addWidget(tabs); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, this); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept())); box1->addWidget(buttonBox); connect(transactionEditWidget, SIGNAL(dateChanged(const QDate&)), recurrenceEditWidget, SLOT(setStartDate(const QDate&))); transactionEditWidget->focusFirst(); } void EditScheduledMultiItemDialog::keyPressEvent(QKeyEvent *e) { if(e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) return; QDialog::keyPressEvent(e); } bool EditScheduledMultiItemDialog::checkAccounts() { return transactionEditWidget->checkAccounts(); } void EditScheduledMultiItemDialog::accept() { if(!transactionEditWidget->validValues()) {tabs->setCurrentIndex(0); return;} recurrenceEditWidget->setStartDate(transactionEditWidget->date()); if(!recurrenceEditWidget->validValues()) {tabs->setCurrentIndex(1); return;} QDialog::accept(); } void EditScheduledMultiItemDialog::reject() { transactionEditWidget->reject(); QDialog::reject(); } void EditScheduledMultiItemDialog::setTransaction(MultiItemTransaction *split) { transactionEditWidget->setTransaction(split); recurrenceEditWidget->setRecurrence(NULL); } void EditScheduledMultiItemDialog::setScheduledTransaction(ScheduledTransaction *strans) { transactionEditWidget->setTransaction((MultiItemTransaction*) strans->transaction()); recurrenceEditWidget->setRecurrence(strans->recurrence()); } ScheduledTransaction *EditScheduledMultiItemDialog::createScheduledTransaction() { MultiItemTransaction *split = transactionEditWidget->createTransaction(); if(!split) {tabs->setCurrentIndex(0); return NULL;} recurrenceEditWidget->setStartDate(split->date()); return new ScheduledTransaction(budget, split, recurrenceEditWidget->createRecurrence()); } MultiItemTransaction *EditScheduledMultiItemDialog::createTransaction(Recurrence *&rec) { MultiItemTransaction *split = transactionEditWidget->createTransaction(); if(!split) {tabs->setCurrentIndex(0); return NULL;} recurrenceEditWidget->setStartDate(split->date()); rec = recurrenceEditWidget->createRecurrence(); return split; } ScheduledTransaction *EditScheduledMultiItemDialog::newScheduledTransaction(Budget *budg, QWidget *parent, AssetsAccount *account, bool extra_parameters, bool allow_account_creation) { if(!account) { for(SplitTransactionList::const_iterator it = budg->splitTransactions.constEnd(); it != budg->splitTransactions.constBegin();) { --it; if((*it)->type() == SPLIT_TRANSACTION_TYPE_MULTIPLE_ITEMS) { account = ((MultiItemTransaction*) (*it))->account(); break; } } } EditScheduledMultiItemDialog *dialog = new EditScheduledMultiItemDialog(extra_parameters, budg, parent, tr("New Split Transaction"), account, allow_account_creation); ScheduledTransaction *strans = NULL; if((allow_account_creation || dialog->checkAccounts()) && dialog->exec() == QDialog::Accepted) { strans = dialog->createScheduledTransaction(); } dialog->deleteLater(); return strans; } ScheduledTransaction *EditScheduledMultiItemDialog::editScheduledTransaction(ScheduledTransaction *strans, QWidget *parent, bool extra_parameters, bool allow_account_creation, bool clone_trans) { EditScheduledMultiItemDialog *dialog = new EditScheduledMultiItemDialog(extra_parameters, strans->budget(), parent, clone_trans ? tr("New Split Transaction") : tr("Edit Split Transaction"), NULL, allow_account_creation); dialog->setScheduledTransaction(strans); ScheduledTransaction *strans_new = NULL; if((allow_account_creation || dialog->checkAccounts()) && dialog->exec() == QDialog::Accepted) { strans_new = dialog->createScheduledTransaction(); if(!clone_trans) { strans_new->setTimestamp(strans->timestamp()); strans_new->setId(strans->id()); strans_new->setFirstRevision(strans->firstRevision()); strans_new->setModified(); strans_new->transaction()->setTimestamp(strans->transaction()->timestamp()); strans_new->transaction()->setId(strans->transaction()->id()); strans_new->transaction()->setFirstRevision(strans->transaction()->firstRevision()); strans_new->transaction()->setModified(); } } dialog->deleteLater(); return strans_new; } MultiItemTransaction *EditScheduledMultiItemDialog::editTransaction(MultiItemTransaction *split, Recurrence *&rec, QWidget *parent, bool extra_parameters, bool allow_account_creation, bool clone_trans) { EditScheduledMultiItemDialog *dialog = new EditScheduledMultiItemDialog(extra_parameters, split->budget(), parent, clone_trans ? tr("New Split Transaction") : tr("Edit Split Transaction"), NULL, allow_account_creation); dialog->setTransaction(split); MultiItemTransaction *split_new = NULL; if((allow_account_creation || dialog->checkAccounts()) && dialog->exec() == QDialog::Accepted) { split_new = dialog->createTransaction(rec); if(!clone_trans) { split_new->setTimestamp(split->timestamp()); split_new->setId(split->id()); split_new->setFirstRevision(split->firstRevision()); split_new->setModified(); } } dialog->deleteLater(); return split_new; } EditScheduledMultiAccountDialog::EditScheduledMultiAccountDialog(bool extra_parameters, Budget *budg, QWidget *parent, QString title, bool create_expenses, bool allow_account_creation) : QDialog(parent), budget(budg), b_extra(extra_parameters) { setWindowTitle(title); setModal(true); QVBoxLayout *box1 = new QVBoxLayout(this); tabs = new QTabWidget(); transactionEditWidget = new EditMultiAccountWidget(budget, NULL, create_expenses, b_extra, allow_account_creation); tabs->addTab(transactionEditWidget, tr("Transactions")); recurrenceEditWidget = new RecurrenceEditWidget(transactionEditWidget->date(), budget); tabs->addTab(recurrenceEditWidget, tr("Recurrence")); box1->addWidget(tabs); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, this); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept())); box1->addWidget(buttonBox); connect(transactionEditWidget, SIGNAL(dateChanged(const QDate&)), recurrenceEditWidget, SLOT(setStartDate(const QDate&))); transactionEditWidget->focusFirst(); } void EditScheduledMultiAccountDialog::keyPressEvent(QKeyEvent *e) { if(e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) return; QDialog::keyPressEvent(e); } bool EditScheduledMultiAccountDialog::checkAccounts() { return transactionEditWidget->checkAccounts(); } void EditScheduledMultiAccountDialog::accept() { if(!transactionEditWidget->validValues()) {tabs->setCurrentIndex(0); return;} recurrenceEditWidget->setStartDate(transactionEditWidget->date()); if(!recurrenceEditWidget->validValues()) {tabs->setCurrentIndex(1); return;} QDialog::accept(); } void EditScheduledMultiAccountDialog::reject() { transactionEditWidget->reject(); QDialog::reject(); } void EditScheduledMultiAccountDialog::setTransaction(MultiAccountTransaction *split) { transactionEditWidget->setTransaction(split); recurrenceEditWidget->setRecurrence(NULL); } void EditScheduledMultiAccountDialog::setValues(QString description_string, CategoryAccount *category_account, double quantity_value, QString comment_string) { transactionEditWidget->setValues(description_string, category_account, quantity_value, comment_string); recurrenceEditWidget->setRecurrence(NULL); } void EditScheduledMultiAccountDialog::setScheduledTransaction(ScheduledTransaction *strans) { transactionEditWidget->setTransaction((MultiAccountTransaction*) strans->transaction()); recurrenceEditWidget->setRecurrence(strans->recurrence()); } ScheduledTransaction *EditScheduledMultiAccountDialog::createScheduledTransaction() { MultiAccountTransaction *split = transactionEditWidget->createTransaction(); if(!split) {tabs->setCurrentIndex(0); return NULL;} recurrenceEditWidget->setStartDate(split->date()); return new ScheduledTransaction(budget, split, recurrenceEditWidget->createRecurrence()); } MultiAccountTransaction *EditScheduledMultiAccountDialog::createTransaction(Recurrence *&rec) { MultiAccountTransaction *split = transactionEditWidget->createTransaction(); if(!split) {tabs->setCurrentIndex(0); return NULL;} recurrenceEditWidget->setStartDate(split->date()); rec = recurrenceEditWidget->createRecurrence(); return split; } ScheduledTransaction *EditScheduledMultiAccountDialog::newScheduledTransaction(Budget *budg, QWidget *parent, bool create_expenses, bool extra_parameters, bool allow_account_creation) { EditScheduledMultiAccountDialog *dialog = new EditScheduledMultiAccountDialog(extra_parameters, budg, parent, create_expenses ? tr("New Expense with Multiple Payments") : tr("New Income with Multiple Payments"), create_expenses, allow_account_creation); ScheduledTransaction *strans = NULL; if((allow_account_creation || dialog->checkAccounts()) && dialog->exec() == QDialog::Accepted) { strans = dialog->createScheduledTransaction(); } dialog->deleteLater(); return strans; } ScheduledTransaction *EditScheduledMultiAccountDialog::newScheduledTransaction(QString description_string, CategoryAccount *category_account, double quantity_value, QString comment_string, Budget *budg, QWidget *parent, bool create_expenses, bool extra_parameters, bool allow_account_creation) { EditScheduledMultiAccountDialog *dialog = new EditScheduledMultiAccountDialog(extra_parameters, budg, parent, create_expenses ? tr("New Expense with Multiple Payments") : tr("New Income with Multiple Payments"), create_expenses, allow_account_creation); dialog->setValues(description_string, category_account, quantity_value, comment_string); ScheduledTransaction *strans = NULL; if((allow_account_creation || dialog->checkAccounts()) && dialog->exec() == QDialog::Accepted) { strans = dialog->createScheduledTransaction(); } dialog->deleteLater(); return strans; } ScheduledTransaction *EditScheduledMultiAccountDialog::editScheduledTransaction(ScheduledTransaction *strans, QWidget *parent, bool extra_parameters, bool allow_account_creation, bool clone_trans) { EditScheduledMultiAccountDialog *dialog = new EditScheduledMultiAccountDialog(extra_parameters, strans->budget(), parent, ((MultiAccountTransaction*) strans->transaction())->transactiontype() == TRANSACTION_TYPE_EXPENSE ? (clone_trans ? tr("New Expense with Multiple Payments") : tr("Edit Expense with Multiple Payments")) : (clone_trans ? tr("New Income with Multiple Payments") : tr("Edit Income with Multiple Payments")), ((MultiAccountTransaction*) strans->transaction())->transactiontype() == TRANSACTION_TYPE_EXPENSE, allow_account_creation); dialog->setScheduledTransaction(strans); ScheduledTransaction *strans_new = NULL; if((allow_account_creation || dialog->checkAccounts()) && dialog->exec() == QDialog::Accepted) { strans_new = dialog->createScheduledTransaction(); if(!clone_trans) { strans_new->setTimestamp(strans->timestamp()); strans_new->setId(strans->id()); strans_new->setFirstRevision(strans->firstRevision()); strans_new->setModified(); strans_new->transaction()->setTimestamp(strans->transaction()->timestamp()); strans_new->transaction()->setId(strans->transaction()->id()); strans_new->transaction()->setFirstRevision(strans->transaction()->firstRevision()); strans_new->transaction()->setModified(); } } dialog->deleteLater(); return strans_new; } MultiAccountTransaction *EditScheduledMultiAccountDialog::editTransaction(MultiAccountTransaction *split, Recurrence *&rec, QWidget *parent, bool extra_parameters, bool allow_account_creation, bool clone_trans) { EditScheduledMultiAccountDialog *dialog = new EditScheduledMultiAccountDialog(extra_parameters, split->budget(), parent, split->transactiontype() == TRANSACTION_TYPE_EXPENSE ? (clone_trans ? tr("New Expense with Multiple Payments") : tr("Edit Expense with Multiple Payments")) : (clone_trans ? tr("New Income with Multiple Payments") : tr("Edit Income with Multiple Payments")), split->transactiontype() == TRANSACTION_TYPE_EXPENSE, allow_account_creation); dialog->setTransaction(split); MultiAccountTransaction *split_new = NULL; if((allow_account_creation || dialog->checkAccounts()) && dialog->exec() == QDialog::Accepted) { split_new = dialog->createTransaction(rec); if(!clone_trans) { split_new->setTimestamp(split->timestamp()); split_new->setId(split->id()); split_new->setFirstRevision(split->firstRevision()); split_new->setModified(); } } dialog->deleteLater(); return split_new; } EditScheduledDebtPaymentDialog::EditScheduledDebtPaymentDialog(bool extra_parameters, Budget *budg, QWidget *parent, QString title, AssetsAccount *loan, bool allow_account_creation, bool only_interest) : QDialog(parent), budget(budg), b_extra(extra_parameters) { setWindowTitle(title); setModal(true); QVBoxLayout *box1 = new QVBoxLayout(this); tabs = new QTabWidget(); transactionEditWidget = new EditDebtPaymentWidget(budget, NULL, loan, allow_account_creation, only_interest); tabs->addTab(transactionEditWidget, tr("Transaction")); recurrenceEditWidget = new RecurrenceEditWidget(transactionEditWidget->date(), budget); tabs->addTab(recurrenceEditWidget, tr("Recurrence")); box1->addWidget(tabs); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, this); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept())); box1->addWidget(buttonBox); connect(transactionEditWidget, SIGNAL(dateChanged(const QDate&)), recurrenceEditWidget, SLOT(setStartDate(const QDate&))); connect(transactionEditWidget, SIGNAL(addmodify()), this, SLOT(accept())); transactionEditWidget->focusFirst(); } void EditScheduledDebtPaymentDialog::keyPressEvent(QKeyEvent *e) { if(e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) return; QDialog::keyPressEvent(e); } bool EditScheduledDebtPaymentDialog::checkAccounts() { return transactionEditWidget->checkAccounts(); } void EditScheduledDebtPaymentDialog::accept() { if(!transactionEditWidget->validValues()) {tabs->setCurrentIndex(0); return;} recurrenceEditWidget->setStartDate(transactionEditWidget->date()); if(!recurrenceEditWidget->validValues()) {tabs->setCurrentIndex(1); return;} QDialog::accept(); } void EditScheduledDebtPaymentDialog::reject() { QDialog::reject(); } void EditScheduledDebtPaymentDialog::setTransaction(DebtPayment *split) { transactionEditWidget->setTransaction(split); recurrenceEditWidget->setRecurrence(NULL); } void EditScheduledDebtPaymentDialog::setScheduledTransaction(ScheduledTransaction *strans) { transactionEditWidget->setTransaction((DebtPayment*) strans->transaction()); recurrenceEditWidget->setRecurrence(strans->recurrence()); } ScheduledTransaction *EditScheduledDebtPaymentDialog::createScheduledTransaction() { DebtPayment *split = transactionEditWidget->createTransaction(); if(!split) {tabs->setCurrentIndex(0); return NULL;} recurrenceEditWidget->setStartDate(split->date()); return new ScheduledTransaction(budget, split, recurrenceEditWidget->createRecurrence()); } DebtPayment *EditScheduledDebtPaymentDialog::createTransaction(Recurrence *&rec) { DebtPayment *split = transactionEditWidget->createTransaction(); if(!split) {tabs->setCurrentIndex(0); return NULL;} recurrenceEditWidget->setStartDate(split->date()); rec = recurrenceEditWidget->createRecurrence(); return split; } ScheduledTransaction *EditScheduledDebtPaymentDialog::newScheduledTransaction(Budget *budg, QWidget *parent, AssetsAccount *account, bool extra_parameters, bool allow_account_creation, bool only_interest) { EditScheduledDebtPaymentDialog *dialog = new EditScheduledDebtPaymentDialog(extra_parameters, budg, parent, tr("New Debt Payment"), account, allow_account_creation, only_interest); ScheduledTransaction *strans = NULL; if((allow_account_creation || dialog->checkAccounts()) && dialog->exec() == QDialog::Accepted) { strans = dialog->createScheduledTransaction(); } dialog->deleteLater(); return strans; } ScheduledTransaction *EditScheduledDebtPaymentDialog::editScheduledTransaction(ScheduledTransaction *strans, QWidget *parent, bool extra_parameters, bool allow_account_creation, bool clone_trans) { EditScheduledDebtPaymentDialog *dialog = new EditScheduledDebtPaymentDialog(extra_parameters, strans->budget(), parent, clone_trans ? tr("New Debt Payment") : tr("Edit Debt Payment"), NULL, allow_account_creation); dialog->setScheduledTransaction(strans); ScheduledTransaction *strans_new = NULL; if((allow_account_creation || dialog->checkAccounts()) && dialog->exec() == QDialog::Accepted) { strans_new = dialog->createScheduledTransaction(); if(!clone_trans) { strans_new->setTimestamp(strans->timestamp()); strans_new->setId(strans->id()); strans_new->setFirstRevision(strans->firstRevision()); strans_new->setModified(); strans_new->transaction()->setTimestamp(strans->transaction()->timestamp()); strans_new->transaction()->setId(strans->transaction()->id()); strans_new->transaction()->setFirstRevision(strans->transaction()->firstRevision()); strans_new->transaction()->setModified(); } } dialog->deleteLater(); return strans_new; } DebtPayment *EditScheduledDebtPaymentDialog::editTransaction(DebtPayment *split, Recurrence *&rec, QWidget *parent, bool extra_parameters, bool allow_account_creation, bool clone_trans) { EditScheduledDebtPaymentDialog *dialog = new EditScheduledDebtPaymentDialog(extra_parameters, split->budget(), parent, clone_trans ? tr("New Debt Payment") : tr("Edit Debt Payment"), NULL, allow_account_creation); dialog->setTransaction(split); DebtPayment *split_new = NULL; if((allow_account_creation || dialog->checkAccounts()) && dialog->exec() == QDialog::Accepted) { split_new = dialog->createTransaction(rec); if(!clone_trans) { split_new->setTimestamp(split->timestamp()); split_new->setId(split->id()); split_new->setFirstRevision(split->firstRevision()); split_new->setModified(); } } dialog->deleteLater(); return split_new; } Eqonomize-1.5.3/src/editscheduledtransactiondialog.h000066400000000000000000000210371416454732000226730ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016-2020 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifndef EDIT_SCHEDULED_TRANSACTION_DIALOG_H #define EDIT_SCHEDULED_TRANSACTION_DIALOG_H #include class Account; class AssetsAccount; class CategoryAccount; class Budget; class Recurrence; class RecurrenceEditWidget; class ScheduledTransaction; class Security; class Transaction; class MultiItemTransaction; class MultiAccountTransaction; class DebtPayment; class TransactionEditWidget; class EditMultiItemWidget; class EditMultiAccountWidget; class EditDebtPaymentWidget; class QTabWidget; class EditScheduledTransactionDialog : public QDialog { Q_OBJECT protected: Budget *budget; bool b_extra, b_loan; RecurrenceEditWidget *recurrenceEditWidget; TransactionEditWidget *transactionEditWidget; QTabWidget *tabs; void keyPressEvent(QKeyEvent*); public: EditScheduledTransactionDialog(bool extra_parameters, int transaction_type, Security *security, bool select_security, Budget *budg, QWidget *parent, QString title, Account *account = NULL, bool allow_account_creation = false, bool withloan = false); bool checkAccounts(); void setTransaction(Transaction *trans); void setValues(QString description_value, double value_value, double quantity_value, QDate date_value, Account *from_account_value, Account *to_account_value, QString payee_value, QString comment_value); void setScheduledTransaction(ScheduledTransaction *strans); ScheduledTransaction *createScheduledTransaction(); bool modifyScheduledTransaction(ScheduledTransaction *strans); bool modifyTransaction(Transaction *trans, Recurrence *&rec); static ScheduledTransaction *newScheduledTransaction(QString description_value, double value_value, double quantity_value, QDate date_value, Account *from_account_value, Account *to_account_value, QString payee_value, QString comment_value, int transaction_type, Budget *budg, QWidget *parent, Security *security = NULL, bool select_security = false, Account *account = NULL, bool extra_parameters = false, bool allow_account_creation = false, bool withloan = false); static ScheduledTransaction *newScheduledTransaction(int transaction_type, Budget *budg, QWidget *parent, Security *security = NULL, bool select_security = false, Account *account = NULL, bool extra_parameters = false, bool allow_account_creation = false, bool withloan = false); static bool editScheduledTransaction(ScheduledTransaction *strans, QWidget *parent, bool select_security = true, bool extra_parameters = false, bool allow_account_creation = false, bool clone_trans = false); static bool editTransaction(Transaction *trans, Recurrence *&rec, QWidget *parent, bool select_security = true, bool extra_parameters = false, bool allow_account_creation = false, bool clone_trans = false); protected slots: void accept(); }; class EditScheduledMultiItemDialog : public QDialog { Q_OBJECT protected: Budget *budget; bool b_extra; RecurrenceEditWidget *recurrenceEditWidget; EditMultiItemWidget *transactionEditWidget; QTabWidget *tabs; void keyPressEvent(QKeyEvent*); public: EditScheduledMultiItemDialog(bool extra_parameters, Budget *budg, QWidget *parent, QString title, AssetsAccount *account = NULL, bool allow_account_creation = false); bool checkAccounts(); void setTransaction(MultiItemTransaction *split); void setScheduledTransaction(ScheduledTransaction *strans); ScheduledTransaction *createScheduledTransaction(); MultiItemTransaction *createTransaction(Recurrence *&rec); static ScheduledTransaction *newScheduledTransaction(Budget *budg, QWidget *parent, AssetsAccount *account = NULL, bool extra_parameters = false, bool allow_account_creation = false); static ScheduledTransaction *editScheduledTransaction(ScheduledTransaction *strans, QWidget *parent, bool extra_parameters = false, bool allow_account_creation = false, bool clone_trans = false); static MultiItemTransaction *editTransaction(MultiItemTransaction *trans, Recurrence *&rec, QWidget *parent, bool extra_parameters = false, bool allow_account_creation = false, bool clone_trans = false); protected slots: void accept(); void reject(); }; class EditScheduledMultiAccountDialog : public QDialog { Q_OBJECT protected: Budget *budget; bool b_extra; RecurrenceEditWidget *recurrenceEditWidget; EditMultiAccountWidget *transactionEditWidget; QTabWidget *tabs; void keyPressEvent(QKeyEvent*); public: EditScheduledMultiAccountDialog(bool extra_parameters, Budget *budg, QWidget *parent, QString title, bool create_expenses = true, bool allow_account_creation = false); bool checkAccounts(); void setTransaction(MultiAccountTransaction *split); void setValues(QString description_string, CategoryAccount *category_account, double quantity_value, QString comment_string); void setScheduledTransaction(ScheduledTransaction *strans); ScheduledTransaction *createScheduledTransaction(); MultiAccountTransaction *createTransaction(Recurrence *&rec); static ScheduledTransaction *newScheduledTransaction(Budget *budg, QWidget *parent, bool create_expenses = true, bool extra_parameters = false, bool allow_account_creation = false); static ScheduledTransaction *newScheduledTransaction(QString description_string, CategoryAccount *category_account, double quantity_value, QString comment_string, Budget *budg, QWidget *parent, bool create_expenses = true, bool extra_parameters = false, bool allow_account_creation = false); static ScheduledTransaction *editScheduledTransaction(ScheduledTransaction *strans, QWidget *parent, bool extra_parameters = false, bool allow_account_creation = false, bool clone_trans = false); static MultiAccountTransaction *editTransaction(MultiAccountTransaction *trans, Recurrence *&rec, QWidget *parent, bool extra_parameters = false, bool allow_account_creation = false, bool clone_trans = false); protected slots: void accept(); void reject(); }; class EditScheduledDebtPaymentDialog : public QDialog { Q_OBJECT protected: Budget *budget; bool b_extra; RecurrenceEditWidget *recurrenceEditWidget; EditDebtPaymentWidget *transactionEditWidget; QTabWidget *tabs; void keyPressEvent(QKeyEvent*); public: EditScheduledDebtPaymentDialog(bool extra_parameters, Budget *budg, QWidget *parent, QString title, AssetsAccount *loan = NULL, bool allow_account_creation = false, bool only_interest = false); bool checkAccounts(); void setTransaction(DebtPayment *split); void setScheduledTransaction(ScheduledTransaction *strans); ScheduledTransaction *createScheduledTransaction(); DebtPayment *createTransaction(Recurrence *&rec); static ScheduledTransaction *newScheduledTransaction(Budget *budg, QWidget *parent, AssetsAccount *loan = NULL, bool extra_parameters = false, bool allow_account_creation = false, bool only_interest = false); static ScheduledTransaction *editScheduledTransaction(ScheduledTransaction *strans, QWidget *parent, bool extra_parameters = false, bool allow_account_creation = false, bool clone_trans = false); static DebtPayment *editTransaction(DebtPayment *trans, Recurrence *&rec, QWidget *parent, bool extra_parameters = false, bool allow_account_creation = false, bool clone_trans = false); protected slots: void accept(); void reject(); }; #endif Eqonomize-1.5.3/src/editsplitdialog.cpp000066400000000000000000002055231416454732000201570ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016-2020 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "accountcombobox.h" #include "budget.h" #include "editsplitdialog.h" #include "editaccountdialogs.h" #include "eqonomize.h" #include "eqonomizevalueedit.h" #include "transactioneditwidget.h" #include extern QString last_associated_file_directory; extern void setColumnTextWidth(QTreeWidget *w, int i, QString str); extern void setColumnDateWidth(QTreeWidget *w, int i); extern void setColumnMoneyWidth(QTreeWidget *w, int i, Budget *budget, double v = 9999999.99, int d = -1); extern void setColumnStrlenWidth(QTreeWidget *w, int i, int l); EqonomizeRadioButton::EqonomizeRadioButton(const QString &text, QWidget *parent) : QRadioButton(text, parent) {} void EqonomizeRadioButton::keyPressEvent(QKeyEvent *event) { QRadioButton::keyPressEvent(event); if(event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) { emit returnPressed(); } } class MultiItemListViewItem : public QTreeWidgetItem { Q_DECLARE_TR_FUNCTIONS(MultiItemListViewItem) protected: Transaction *o_trans; bool b_deposit; public: MultiItemListViewItem(Transaction *trans, Currency *cur, bool deposit); bool operator<(const QTreeWidgetItem&) const; Transaction *transaction() const; bool isDeposit() const; void setTransaction(Transaction *trans, Currency *cur, bool deposit); void currencyChanged(Currency *cur); }; MultiItemListViewItem::MultiItemListViewItem(Transaction *trans, Currency *cur, bool deposit) : QTreeWidgetItem() { setTransaction(trans, cur, deposit); setTextAlignment(3, Qt::AlignRight | Qt::AlignVCenter); } bool MultiItemListViewItem::operator<(const QTreeWidgetItem &i_pre) const { int col = 0; if(treeWidget()) col = treeWidget()->sortColumn(); MultiItemListViewItem *i = (MultiItemListViewItem*) &i_pre; if(col == 3) { double value1 = 0.0; double value2 = 0.0; if(!b_deposit && o_trans->value() < 0.0) value1 = -o_trans->value(); else if(b_deposit && o_trans->value() >= 0.0) value1 = o_trans->value(); if(!i->isDeposit() && i->transaction()->value() < 0.0) value2 = -i->transaction()->value(); else if(i->isDeposit() && i->transaction()->value() >= 0.0) value2 = i->transaction()->value(); return value1 < value2; } return QTreeWidgetItem::operator<(i_pre); } Transaction *MultiItemListViewItem::transaction() const { return o_trans; } bool MultiItemListViewItem::isDeposit() const { return b_deposit; } void MultiItemListViewItem::setTransaction(Transaction *trans, Currency *cur, bool deposit) { o_trans = trans; b_deposit = deposit; Budget *budget = trans->budget(); if(!cur) cur = budget->defaultCurrency(); double value = 0.0; if(deposit) value = trans->toValue(); else value = trans->fromValue(); setText(1, trans->description()); setText(2, deposit ? trans->fromAccount()->nameWithParent() : trans->toAccount()->nameWithParent()); setText(3, cur->formatValue(deposit ? value : -value)); if(trans->type() == TRANSACTION_TYPE_INCOME) { if(((Income*) trans)->security()) setText(0, tr("Dividend")); else if(value >= 0) setText(0, tr("Income")); else setText(0, tr("Repayment")); } else if(trans->type() == TRANSACTION_TYPE_EXPENSE) { if(value >= 0) setText(0, tr("Expense")); else setText(0, tr("Refund")); } else if(trans->type() == TRANSACTION_TYPE_SECURITY_BUY) { setText(0, tr("Securities Purchase", "Financial security (e.g. stock, mutual fund)")); } else if(trans->type() == TRANSACTION_TYPE_SECURITY_SELL) { setText(0, tr("Securities Sale", "Financial security (e.g. stock, mutual fund)")); } else if(trans->toAccount() == budget->balancingAccount || trans->fromAccount() == budget->balancingAccount) { setText(0, tr("Account Balance Adjustment")); } else { setText(0, tr("Transfer")); } } void MultiItemListViewItem::currencyChanged(Currency *cur) { setTransaction(o_trans, cur, b_deposit); } class MultiAccountListViewItem : public QTreeWidgetItem { Q_DECLARE_TR_FUNCTIONS(MultiAccountListViewItem) protected: Transaction *o_trans; bool b_extra; public: MultiAccountListViewItem(Transaction *trans, bool extra_parameters); Transaction *transaction() const; void setTransaction(Transaction *trans); }; MultiAccountListViewItem::MultiAccountListViewItem(Transaction *trans, bool extra_parameters) : QTreeWidgetItem(), b_extra(extra_parameters) { setTransaction(trans); setTextAlignment(b_extra ? 3 : 2, Qt::AlignRight | Qt::AlignVCenter); } Transaction *MultiAccountListViewItem::transaction() const { return o_trans; } void MultiAccountListViewItem::setTransaction(Transaction *trans) { o_trans = trans; setText(0, QLocale().toString(trans->date(), QLocale::ShortFormat)); if(trans->type() == TRANSACTION_TYPE_INCOME) { setText(1, trans->toAccount()->nameWithParent()); } else { setText(1, trans->fromAccount()->nameWithParent()); } if(b_extra) { setText(2, trans->payeeText()); } setText(b_extra ? 3 : 2, trans->valueString()); } EditDebtPaymentDialog::EditDebtPaymentDialog(Budget *budg, QWidget *parent, AssetsAccount *default_loan, bool allow_account_creation, bool only_interest) : QDialog(parent) { setWindowTitle(tr("Debt Payment")); setModal(true); QVBoxLayout *box1 = new QVBoxLayout(this); editWidget = new EditDebtPaymentWidget(budg, this, default_loan, allow_account_creation, only_interest); box1->addWidget(editWidget); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, this); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Cancel)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept())); box1->addWidget(buttonBox); connect(editWidget, SIGNAL(addmodify()), this, SLOT(accept())); editWidget->focusFirst(); } EditDebtPaymentDialog::~EditDebtPaymentDialog() {} void EditDebtPaymentDialog::accept() { if(!editWidget->validValues()) return; QDialog::accept(); } void EditDebtPaymentDialog::keyPressEvent(QKeyEvent *e) { if(e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) return; QDialog::keyPressEvent(e); } EditMultiAccountDialog::EditMultiAccountDialog(Budget *budg, QWidget *parent, bool create_expenses, bool extra_parameters, bool allow_account_creation) : QDialog(parent) { if(create_expenses) setWindowTitle(tr("Expense with Multiple Payments")); else setWindowTitle(tr("Income with Multiple Payments")); setModal(true); QVBoxLayout *box1 = new QVBoxLayout(this); editWidget = new EditMultiAccountWidget(budg, this, create_expenses, extra_parameters, allow_account_creation); box1->addWidget(editWidget); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, this); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Cancel)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept())); box1->addWidget(buttonBox); editWidget->focusFirst(); } EditMultiAccountDialog::~EditMultiAccountDialog() {} void EditMultiAccountDialog::accept() { if(!editWidget->validValues()) return; QDialog::accept(); } void EditMultiAccountDialog::reject() { editWidget->reject(); QDialog::reject(); } void EditMultiAccountDialog::keyPressEvent(QKeyEvent *e) { if(e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) return; QDialog::keyPressEvent(e); } EditMultiItemDialog::EditMultiItemDialog(Budget *budg, QWidget *parent, AssetsAccount *default_account, bool extra_parameters, bool allow_account_creation) : QDialog(parent) { setWindowTitle(tr("Split Transaction")); setModal(true); QVBoxLayout *box1 = new QVBoxLayout(this); editWidget = new EditMultiItemWidget(budg, this, default_account, extra_parameters, allow_account_creation); box1->addWidget(editWidget); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, this); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Cancel)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept())); box1->addWidget(buttonBox); editWidget->focusFirst(); } EditMultiItemDialog::~EditMultiItemDialog() {} void EditMultiItemDialog::accept() { if(!editWidget->validValues()) return; QDialog::accept(); } void EditMultiItemDialog::reject() { editWidget->reject(); QDialog::reject(); } void EditMultiItemDialog::keyPressEvent(QKeyEvent *e) { if(e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) return; QDialog::keyPressEvent(e); } EditMultiItemWidget::EditMultiItemWidget(Budget *budg, QWidget *parent, AssetsAccount *default_account, bool extra_parameters, bool allow_account_creation) : QWidget(parent), budget(budg), b_extra(extra_parameters), b_create_accounts(allow_account_creation) { QVBoxLayout *box1 = new QVBoxLayout(this); QGridLayout *grid = new QGridLayout(); box1->addLayout(grid); grid->addWidget(new QLabel(tr("Description:", "Transaction description property (transaction title/generic article name)")), 0, 0); descriptionEdit = new QLineEdit(); grid->addWidget(descriptionEdit, 0, 1); descriptionEdit->setFocus(); descriptionEdit->setCompleter(new QCompleter(this)); descriptionEdit->completer()->setModel(new QStandardItemModel(this)); descriptionEdit->completer()->setModelSorting(QCompleter::CaseInsensitivelySortedModel); descriptionEdit->completer()->setCaseSensitivity(Qt::CaseInsensitive); QStringList descr_list; QString descr; for(SplitTransactionList::const_iterator it = budget->splitTransactions.constEnd(); it != budget->splitTransactions.constBegin();) { --it; SplitTransaction *split = *it; descr = split->description(); if(split->type() == SPLIT_TRANSACTION_TYPE_MULTIPLE_ITEMS && !descr.isEmpty() && !descr_list.contains(descr, Qt::CaseInsensitive)) { QList row; row << new QStandardItem(descr); row << new QStandardItem(descr.toLower()); ((QStandardItemModel*) descriptionEdit->completer()->model())->appendRow(row); descr_list << descr.toLower(); } } ((QStandardItemModel*) descriptionEdit->completer()->model())->sort(1); grid->addWidget(new QLabel(tr("Date:")), 1, 0); dateEdit = new EqonomizeDateEdit(this); dateEdit->setCalendarPopup(true); grid->addWidget(dateEdit, 1, 1); grid->addWidget(new QLabel(tr("Account:")), 2, 0); accountCombo = new AccountComboBox(ACCOUNT_TYPE_ASSETS, budget, b_create_accounts, false); accountCombo->updateAccounts(); accountCombo->setCurrentAccount(default_account); grid->addWidget(accountCombo, 2, 1); if(b_extra) { grid->addWidget(new QLabel(tr("Payee/Payer:")), 3, 0); payeeEdit = new QLineEdit(); grid->addWidget(payeeEdit, 3, 1); payeeEdit->setCompleter(new QCompleter(this)); payeeEdit->completer()->setModel(new QStandardItemModel(this)); payeeEdit->completer()->setModelSorting(QCompleter::CaseInsensitivelySortedModel); payeeEdit->completer()->setCaseSensitivity(Qt::CaseInsensitive); QStringList payee_list; for(TransactionList::const_iterator it = budget->expenses.constEnd(); it != budget->expenses.constBegin();) { --it; Expense *expense = *it; if(expense->subtype() != TRANSACTION_SUBTYPE_DEBT_FEE && expense->subtype() != TRANSACTION_SUBTYPE_DEBT_INTEREST) { if(!expense->payee().isEmpty() && !payee_list.contains(expense->payee(), Qt::CaseInsensitive)) { QList row; row << new QStandardItem(expense->payee()); row << new QStandardItem(expense->payee().toLower()); ((QStandardItemModel*) payeeEdit->completer()->model())->appendRow(row); payee_list << expense->payee().toLower(); } } } for(TransactionList::const_iterator it = budget->incomes.constEnd(); it != budget->incomes.constBegin();) { --it; Income *income = *it; if(!income->security()) { if(!income->payer().isEmpty() && !payee_list.contains(income->payer(), Qt::CaseInsensitive)) { QList row; row << new QStandardItem(income->payer()); row << new QStandardItem(income->payer().toLower()); ((QStandardItemModel*) payeeEdit->completer()->model())->appendRow(row); payee_list << income->payer().toLower(); } } } ((QStandardItemModel*) payeeEdit->completer()->model())->sort(1); } else { payeeEdit = NULL; } grid->addWidget(new QLabel(tr("Tags:")), b_extra ? 4 : 3, 0); tagButton = new TagButton(false, allow_account_creation, budget, this); grid->addWidget(tagButton, b_extra ? 4 : 3, 1); tagButton->updateTags(); connect(tagButton, SIGNAL(newTagRequested()), this, SLOT(newTag())); grid->addWidget(new QLabel(tr("Associated file:"), this), b_extra ? 5 : 4, 0); QHBoxLayout *fileLayout = new QHBoxLayout(); fileEdit = new QLineEdit(this); QCompleter *completer = new QCompleter(this); QFileSystemModel *fsModel = new QFileSystemModel(completer); fsModel->setRootPath(QString()); completer->setModel(fsModel); fileEdit->setCompleter(completer); fileLayout->addWidget(fileEdit); QPushButton *selectFileButton = new QPushButton(LOAD_ICON("document-open"), QString(), this); selectFileButton->setToolTip(tr("Select a file")); selectFileButton->setAutoDefault(false); fileLayout->addWidget(selectFileButton); QPushButton *openFileButton = new QPushButton(LOAD_ICON("system-run"), QString(), this); openFileButton->setToolTip(tr("Open the file")); openFileButton->setAutoDefault(false); fileLayout->addWidget(openFileButton); openFileButton->setFocusPolicy(Qt::ClickFocus); grid->addLayout(fileLayout, b_extra ? 5 : 4, 1); QLabel *commentLabel = new QLabel(tr("Comments:")); commentLabel->setMinimumHeight(descriptionEdit->sizeHint().height()); grid->addWidget(commentLabel, b_extra ? 6 : 5, 0, Qt::AlignTop | Qt::AlignLeft); commentEdit = new CommentsTextEdit(this); commentEdit->setFixedHeight(commentEdit->sizeHint().height()); grid->addWidget(commentEdit, b_extra ? 6 : 5, 1); linksWidget = new LinksWidget(this, b_create_accounts); linksWidget->hide(); //: Label for linked transactions linksLabelLabel = new QLabel(tr("Related to:"), this); linksLabelLabel->hide(); grid->addWidget(linksLabelLabel, b_extra ? 7 : 6, 0); grid->addWidget(linksWidget, b_extra ? 7 : 6, 1); box1->addWidget(new QLabel(tr("Transactions:"))); QHBoxLayout *box2 = new QHBoxLayout(); box1->addLayout(box2); transactionsView = new EqonomizeTreeWidget(this); transactionsView->setSortingEnabled(true); transactionsView->sortByColumn(0, Qt::AscendingOrder); transactionsView->setAllColumnsShowFocus(true); transactionsView->setColumnCount(4); QStringList headers; headers << tr("Type"); headers << tr("Description", "Transaction description property (transaction title/generic article name)"); headers << tr("Account/Category"); headers << tr("Value"); transactionsView->setHeaderLabels(headers); transactionsView->setRootIsDecorated(false); QFontMetrics fm(transactionsView->font()); int w1 = fm.boundingRect(tr("Type")).width() + 26; int w2 = fm.boundingRect(tr("Income")).width() + 10; int w3 = fm.boundingRect(tr("Expense")).width() + 10; if(w2 > w1) w1 = w2; if(w3 > w1) w1 = w3; transactionsView->setColumnWidth(0, w1); setColumnStrlenWidth(transactionsView, 1, 15); w1 = fm.boundingRect(tr("Account/Category")).width() + 26; transactionsView->setColumnWidth(2, w1); setColumnMoneyWidth(transactionsView, 3, budget); transactionsView->setMinimumWidth(transactionsView->columnWidth(0) + transactionsView->columnWidth(1) + transactionsView->columnWidth(2) + transactionsView->columnWidth(3) + 10); box2->addWidget(transactionsView); QVBoxLayout *buttons = new QVBoxLayout(); newButton = new QPushButton(tr("New")); buttons->addWidget(newButton); QMenu *newMenu = new QMenu(this); newButton->setMenu(newMenu); connect(newMenu->addAction(LOAD_ICON("document-new"), tr("New Expense…")), SIGNAL(triggered()), this, SLOT(newExpense())); connect(newMenu->addAction(LOAD_ICON("document-new"), tr("New Income…")), SIGNAL(triggered()), this, SLOT(newIncome())); connect(newMenu->addAction(LOAD_ICON("document-new"), tr("New Deposit…")), SIGNAL(triggered()), this, SLOT(newTransferTo())); connect(newMenu->addAction(LOAD_ICON("document-new"), tr("New Withdrawal…")), SIGNAL(triggered()), this, SLOT(newTransferFrom())); connect(newMenu->addAction(LOAD_ICON("document-new"), tr("New Securities Purchase…", "Financial security (e.g. stock, mutual fund)")), SIGNAL(triggered()), this, SLOT(newSecurityBuy())); connect(newMenu->addAction(LOAD_ICON("document-new"), tr("New Securities Sale…", "Financial security (e.g. stock, mutual fund)")), SIGNAL(triggered()), this, SLOT(newSecuritySell())); connect(newMenu->addAction(LOAD_ICON("document-new"), tr("New Dividend…")), SIGNAL(triggered()), this, SLOT(newDividend())); editButton = new QPushButton(tr("Edit…")); buttons->addWidget(editButton); editButton->setEnabled(false); removeButton = new QPushButton(tr("Delete")); buttons->addWidget(removeButton); buttons->addStretch(1); removeButton->setEnabled(false); box2->addLayout(buttons); totalLabel = new QLabel(); updateTotalValue(); box1->addWidget(totalLabel); connect(descriptionEdit, SIGNAL(returnPressed()), this, SLOT(focusDate())); connect(dateEdit, SIGNAL(returnPressed()), accountCombo, SLOT(focusAndSelectAll())); if(payeeEdit) { connect(accountCombo, SIGNAL(accountSelected(Account*)), payeeEdit, SLOT(setFocus())); connect(accountCombo, SIGNAL(returnPressed()), payeeEdit, SLOT(setFocus())); connect(payeeEdit, SIGNAL(returnPressed()), tagButton, SLOT(setFocus())); } else { connect(accountCombo, SIGNAL(accountSelected(Account*)), tagButton, SLOT(setFocus())); connect(accountCombo, SIGNAL(returnPressed()), tagButton, SLOT(setFocus())); } connect(tagButton, SIGNAL(returnPressed()), fileEdit, SLOT(setFocus())); connect(fileEdit, SIGNAL(returnPressed()), commentEdit, SLOT(setFocus())); connect(selectFileButton, SIGNAL(clicked()), this, SLOT(selectFile())); connect(openFileButton, SIGNAL(clicked()), this, SLOT(openFile())); connect(transactionsView, SIGNAL(itemSelectionChanged()), this, SLOT(transactionSelectionChanged())); connect(transactionsView, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(edit(QTreeWidgetItem*))); connect(removeButton, SIGNAL(clicked()), this, SLOT(remove())); connect(editButton, SIGNAL(clicked()), this, SLOT(edit())); connect(dateEdit, SIGNAL(dateChanged(const QDate&)), this, SIGNAL(dateChanged(const QDate&))); connect(accountCombo, SIGNAL(newAccountRequested()), this, SLOT(newAccount())); connect(accountCombo, SIGNAL(currentAccountChanged(Account*)), this, SLOT(accountChanged())); } EditMultiItemWidget::~EditMultiItemWidget() {} void EditMultiItemWidget::selectFile() { QStringList urls = QFileDialog::getOpenFileNames(this, QString(), (fileEdit->text().isEmpty() || fileEdit->text().contains(",")) ? last_associated_file_directory : fileEdit->text()); if(!urls.isEmpty()) { QFileInfo fileInfo(urls[0]); last_associated_file_directory = fileInfo.absoluteDir().absolutePath(); if(urls.size() == 1) { fileEdit->setText(urls[0]); } else { QString url; for(int i = 0; i < urls.size(); i++) { if(i > 0) url += ", "; if(urls[i].contains("\"")) {url += "\'"; url += urls[i]; url += "\'";} else {url += "\""; url += urls[i]; url += "\"";} } fileEdit->setText(url); } } } void EditMultiItemWidget::openFile() { open_file_list(fileEdit->text()); } void EditMultiItemWidget::newAccount() { accountCombo->createAccount(); } void EditMultiItemWidget::newTag() { tagButton->createTag(); } void EditMultiItemWidget::accountChanged() { Account *account = selectedAccount(); if(account) { updateTotalValue(); QTreeWidgetItemIterator it(transactionsView); QTreeWidgetItem *i = *it; while(i) { ((MultiItemListViewItem*) i)->currencyChanged(account->currency()); ++it; i = *it; } } } void EditMultiItemWidget::focusDate() { if(!dateEdit) return; dateEdit->setFocus(); dateEdit->setCurrentSection(QDateTimeEdit::DaySection); } void EditMultiItemWidget::updateTotalValue() { double total_value = 0.0; QTreeWidgetItemIterator it(transactionsView); QTreeWidgetItem *i = *it; while(i) { Transaction *trans = ((MultiItemListViewItem*) i)->transaction(); if(trans) { if(trans->fromAccount()) total_value += trans->toValue(); else total_value -= trans->fromValue(); } ++it; i = *it; } Currency *cur = budget->defaultCurrency(); if(selectedAccount()) cur = selectedAccount()->currency(); totalLabel->setText(QString("
    %1 %2
    ").arg(tr("Total value:"), cur->formatValue(total_value))); } AssetsAccount *EditMultiItemWidget::selectedAccount() { return (AssetsAccount*) accountCombo->currentAccount(); } void EditMultiItemWidget::transactionSelectionChanged() { QList list = transactionsView->selectedItems(); MultiItemListViewItem *i = NULL; if(!list.isEmpty()) i = (MultiItemListViewItem*) list.first(); editButton->setEnabled(i && i->transaction()); removeButton->setEnabled(i && i->transaction()); } void EditMultiItemWidget::newTransaction(int transtype, bool select_security, bool transfer_to, Account *exclude_account) { Currency *cur = budget->defaultCurrency(); if(selectedAccount()) cur = selectedAccount()->currency(); TransactionEditDialog *dialog = new TransactionEditDialog(b_extra, transtype, cur, transfer_to, NULL, SECURITY_ALL_VALUES, select_security, budget, this, b_create_accounts); dialog->editWidget->focusFirst(); dialog->editWidget->updateAccounts(exclude_account); if(dialog->editWidget->checkAccounts() && dialog->exec() == QDialog::Accepted) { Transaction *trans = dialog->editWidget->createTransaction(); if(trans) { appendTransaction(trans, (trans->toAccount() == NULL)); } updateTotalValue(); } dialog->deleteLater(); } void EditMultiItemWidget::newExpense() { newTransaction(TRANSACTION_TYPE_EXPENSE); } void EditMultiItemWidget::newDividend() { newTransaction(TRANSACTION_TYPE_INCOME, true); } void EditMultiItemWidget::newSecurityBuy() { newTransaction(TRANSACTION_TYPE_SECURITY_BUY, true); } void EditMultiItemWidget::newSecuritySell() { newTransaction(TRANSACTION_TYPE_SECURITY_SELL, true); } void EditMultiItemWidget::newIncome() { newTransaction(TRANSACTION_TYPE_INCOME); } void EditMultiItemWidget::newTransferFrom() { newTransaction(TRANSACTION_TYPE_TRANSFER, false, false, selectedAccount()); } void EditMultiItemWidget::newTransferTo() { newTransaction(TRANSACTION_TYPE_TRANSFER, false, true, selectedAccount()); } void EditMultiItemWidget::remove() { QList list = transactionsView->selectedItems(); if(list.isEmpty()) return; MultiItemListViewItem *i = (MultiItemListViewItem*) list.first(); if(i->transaction()) { delete i->transaction(); } delete i; updateTotalValue(); } void EditMultiItemWidget::edit() { QList list = transactionsView->selectedItems(); if(list.isEmpty()) return; edit(list.first()); } void EditMultiItemWidget::edit(QTreeWidgetItem *i_pre) { if(i_pre == NULL) return; MultiItemListViewItem *i = (MultiItemListViewItem*) i_pre; Transaction *trans = i->transaction(); if(trans) { AssetsAccount *account = selectedAccount(); Currency *cur = budget->defaultCurrency(); if(account) cur = account->currency(); Security *security = NULL; if(trans->type() == TRANSACTION_TYPE_SECURITY_BUY || trans->type() == TRANSACTION_TYPE_SECURITY_SELL) { security = ((SecurityTransaction*) trans)->security(); } else if(trans->type() == TRANSACTION_TYPE_INCOME && ((Income*) trans)->security()) { security = ((Income*) trans)->security(); } TransactionEditDialog *dialog = new TransactionEditDialog(b_extra, trans->type(), cur, trans->toAccount() == NULL, security, SECURITY_ALL_VALUES, security != NULL, budget, this, b_create_accounts); dialog->editWidget->updateAccounts(account); dialog->editWidget->setTransaction(trans); if((trans->type() == TRANSACTION_TYPE_EXPENSE && ((Expense*) trans)->payee() == payeeEdit->text().trimmed()) || (trans->type() == TRANSACTION_TYPE_INCOME && ((Income*) trans)->payer() == payeeEdit->text().trimmed())) dialog->editWidget->setPayee(""); if(dialog->exec() == QDialog::Accepted) { if(dialog->editWidget->modifyTransaction(trans)) { i->setTransaction(trans, cur, trans->toAccount() == NULL); } updateTotalValue(); } dialog->deleteLater(); } } MultiItemTransaction *EditMultiItemWidget::createTransaction() { if(!validValues()) return NULL; AssetsAccount *account = selectedAccount(); MultiItemTransaction *split = new MultiItemTransaction(budget, dateEdit->date(), account, descriptionEdit->text()); linksWidget->updateTransaction(split); if(payeeEdit) split->setPayee(payeeEdit->text()); if(fileEdit) split->setAssociatedFile(fileEdit->text()); split->setComment(commentEdit->toPlainText()); QTreeWidgetItemIterator it(transactionsView); QTreeWidgetItem *i = *it; if(tagButton) tagButton->modifyTransaction(split); while(i) { Transaction *trans = ((MultiItemListViewItem*) i)->transaction(); if(trans) split->addTransaction(trans); ++it; i = *it; } split->joinTags(); split->joinLinks(); return split; } void EditMultiItemWidget::setTransaction(MultiItemTransaction *split) { linksWidget->setTransaction(split); if(linksWidget->isEmpty()) { linksWidget->hide(); linksLabelLabel->hide(); } else { linksWidget->show(); linksLabelLabel->show(); } descriptionEdit->setText(split->description()); dateEdit->setDate(split->date()); accountCombo->setCurrentAccount(split->account()); if(payeeEdit) payeeEdit->setText(split->payee()); if(fileEdit) fileEdit->setText(split->associatedFile()); commentEdit->setPlainText(split->comment()); transactionsView->clear(); QList items; tagButton->setTransaction(split); int c = split->count(); QStringList tags; for(int i = 0; i < c; i++) { Transaction *trans = split->at(i); if(i == 0) { for(int i2 = 0; i2 < trans->tagsCount(false); i2++) { tags << trans->getTag(i2, false); } } else { for(int i2 = 0; i2 < tags.count();) { if(!trans->hasTag(tags[i2], false)) { tags.removeAt(i2); } else { i2++; } } } } for(int i = 0; i < tags.count(); i++) { tagButton->setTagSelected(tags[i], true); } for(int i = 0; i < c; i++) { Transaction *trans = split->at(i)->copy(); for(int i2 = 0; i2 < tags.count(); i2++) { trans->removeTag(tags[i2]); } trans->setAssociatedFile(QString()); trans->setDate(QDate()); items.append(new MultiItemListViewItem(trans, split->currency(), (trans->toAccount() == split->account()))); switch(trans->type()) { case TRANSACTION_TYPE_EXPENSE: { ((Expense*) trans)->setFrom(NULL); break; } case TRANSACTION_TYPE_INCOME: { ((Income*) trans)->setTo(NULL); break; } case TRANSACTION_TYPE_TRANSFER: { if(((Transfer*) trans)->from() == split->account()) { ((Transfer*) trans)->setFrom(NULL); } else { ((Transfer*) trans)->setTo(NULL); } break; } case TRANSACTION_TYPE_SECURITY_BUY: {} case TRANSACTION_TYPE_SECURITY_SELL: { ((SecurityTransaction*) trans)->setAccount(NULL); break; } } } transactionsView->addTopLevelItems(items); updateTotalValue(); transactionsView->setSortingEnabled(true); emit dateChanged(split->date()); } void EditMultiItemWidget::setTransaction(MultiItemTransaction *split, const QDate &date) { setTransaction(split); if(dateEdit) dateEdit->setDate(date); } void EditMultiItemWidget::appendTransaction(Transaction *trans, bool deposit) { Currency *cur = budget->defaultCurrency(); if(selectedAccount()) cur = selectedAccount()->currency(); MultiItemListViewItem *i = new MultiItemListViewItem(trans, cur, deposit); transactionsView->insertTopLevelItem(transactionsView->topLevelItemCount(), i); transactionsView->setSortingEnabled(true); } void EditMultiItemWidget::reject() { QTreeWidgetItemIterator it(transactionsView); QTreeWidgetItem *i = *it; while(i) { Transaction *trans = ((MultiItemListViewItem*) i)->transaction(); if(trans) delete trans; ++it; i = *it; } } void EditMultiItemWidget::focusFirst() { descriptionEdit->setFocus(); } QDate EditMultiItemWidget::date() { return dateEdit->date(); } bool EditMultiItemWidget::checkAccounts() { if(!accountCombo->hasAccount()) { QMessageBox::critical(this, tr("Error"), tr("No suitable account available.")); return false; } return true; } bool EditMultiItemWidget::validValues() { if(!checkAccounts()) return false; if(!dateEdit->date().isValid()) { QMessageBox::critical(this, tr("Error"), tr("Invalid date.")); return false; } if(transactionsView->topLevelItemCount() < 2) { QMessageBox::critical(this, tr("Error"), tr("A split must contain at least two transactions.")); return false; } AssetsAccount *account = selectedAccount(); if(!account) return false; QTreeWidgetItemIterator it(transactionsView); QTreeWidgetItem *i = *it; while(i) { Transaction *trans = ((MultiItemListViewItem*) i)->transaction(); if(trans && (trans->fromAccount() == account || trans->toAccount() == account)) { QMessageBox::critical(this, tr("Error"), tr("Cannot transfer money to and from the same account.")); return false; } ++it; i = *it; } return true; } EditMultiAccountWidget::EditMultiAccountWidget(Budget *budg, QWidget *parent, bool create_expenses, bool extra_parameters, bool allow_account_creation) : QWidget(parent), budget(budg), b_expense(create_expenses), b_extra(extra_parameters), b_create_accounts(allow_account_creation) { QVBoxLayout *box1 = new QVBoxLayout(this); QGridLayout *grid = new QGridLayout(); box1->addLayout(grid); box1->addStretch(1); grid->addWidget(new QLabel(tr("Description:", "Transaction description property (transaction title/generic article name)")), 0, 0); descriptionEdit = new QLineEdit(); grid->addWidget(descriptionEdit, 0, 1); descriptionEdit->setFocus(); if(b_extra) { grid->addWidget(new QLabel(tr("Quantity:")), 1, 0); quantityEdit = new EqonomizeValueEdit(1.0, QUANTITY_DECIMAL_PLACES, true, false, this, budget); grid->addWidget(quantityEdit, 1, 1); } else { quantityEdit = NULL; } grid->addWidget(new QLabel(tr("Category:")), b_extra ? 2 : 1, 0); categoryCombo = new AccountComboBox(b_expense ? ACCOUNT_TYPE_EXPENSES : ACCOUNT_TYPE_INCOMES, budget, b_create_accounts); categoryCombo->updateAccounts(); grid->addWidget(categoryCombo, b_extra ? 2 : 1, 1); grid->addWidget(new QLabel(tr("Tags:")), b_extra ? 3 : 2, 0); tagButton = new TagButton(false, allow_account_creation, budget, this); grid->addWidget(tagButton, b_extra ? 3 : 2, 1); tagButton->updateTags(); connect(tagButton, SIGNAL(newTagRequested()), this, SLOT(newTag())); grid->addWidget(new QLabel(tr("Associated file:"), this), b_extra ? 4 : 3, 0); QHBoxLayout *fileLayout = new QHBoxLayout(); fileEdit = new QLineEdit(this); QCompleter *completer = new QCompleter(this); QFileSystemModel *fsModel = new QFileSystemModel(completer); fsModel->setRootPath(QString()); completer->setModel(fsModel); fileEdit->setCompleter(completer); fileLayout->addWidget(fileEdit); QPushButton *selectFileButton = new QPushButton(LOAD_ICON("document-open"), QString(), this); selectFileButton->setToolTip(tr("Select a file")); selectFileButton->setAutoDefault(false); fileLayout->addWidget(selectFileButton); QPushButton *openFileButton = new QPushButton(LOAD_ICON("system-run"), QString(), this); openFileButton->setToolTip(tr("Open the file")); openFileButton->setAutoDefault(false); fileLayout->addWidget(openFileButton); openFileButton->setFocusPolicy(Qt::ClickFocus); grid->addLayout(fileLayout, b_extra ? 4 : 3, 1); QLabel *commentLabel = new QLabel(tr("Comments:")); commentLabel->setMinimumHeight(descriptionEdit->sizeHint().height()); grid->addWidget(commentLabel, b_extra ? 5 : 4, 0, Qt::AlignTop | Qt::AlignLeft); commentEdit = new CommentsTextEdit(this); commentEdit->setFixedHeight(commentEdit->sizeHint().height()); grid->addWidget(commentEdit, b_extra ? 5 : 4, 1); linksWidget = new LinksWidget(this, b_create_accounts); linksWidget->hide(); //: Label for linked transactions linksLabelLabel = new QLabel(tr("Related to:"), this); linksLabelLabel->hide(); grid->addWidget(linksLabelLabel, b_extra ? 6 : 5, 0); grid->addWidget(linksWidget, b_extra ? 6 : 5, 1); box1->addWidget(new QLabel(tr("Transactions:"))); QHBoxLayout *box2 = new QHBoxLayout(); box1->addLayout(box2); transactionsView = new EqonomizeTreeWidget(this); transactionsView->setSortingEnabled(true); transactionsView->sortByColumn(0, Qt::AscendingOrder); transactionsView->setAllColumnsShowFocus(true); transactionsView->setColumnCount(3); QStringList headers; headers << tr("Date"); headers << tr("Account"); if(b_extra) { if(b_expense) headers << tr("Payee"); else headers << tr("Payer"); } if(b_expense) headers << tr("Cost"); else headers << tr("Income"); transactionsView->setHeaderLabels(headers); transactionsView->setRootIsDecorated(false); setColumnDateWidth(transactionsView, 0); setColumnStrlenWidth(transactionsView, 1, 10); if(b_extra) setColumnStrlenWidth(transactionsView, 2, 10); setColumnMoneyWidth(transactionsView, b_extra ? 3 : 2, budget); transactionsView->setMinimumWidth(transactionsView->columnWidth(0) + transactionsView->columnWidth(1) + transactionsView->columnWidth(2) + (b_extra ? transactionsView->columnWidth(3) : 0) + 10); box2->addWidget(transactionsView); QVBoxLayout *buttons = new QVBoxLayout(); newButton = new QPushButton(tr("New")); buttons->addWidget(newButton); editButton = new QPushButton(tr("Edit…")); buttons->addWidget(editButton); editButton->setEnabled(false); removeButton = new QPushButton(tr("Delete")); buttons->addWidget(removeButton); buttons->addStretch(1); removeButton->setEnabled(false); box2->addLayout(buttons); totalLabel = new QLabel(); updateTotalValue(); box1->addWidget(totalLabel); if(quantityEdit) { connect(descriptionEdit, SIGNAL(returnPressed()), quantityEdit, SLOT(enterFocus())); connect(quantityEdit, SIGNAL(returnPressed()), categoryCombo, SLOT(focusAndSelectAll())); } else { connect(descriptionEdit, SIGNAL(returnPressed()), categoryCombo, SLOT(focusAndSelectAll())); } connect(categoryCombo, SIGNAL(accountSelected(Account*)), fileEdit, SLOT(setFocus())); connect(categoryCombo, SIGNAL(returnPressed()), tagButton, SLOT(setFocus())); connect(tagButton, SIGNAL(returnPressed()), fileEdit, SLOT(setFocus())); connect(fileEdit, SIGNAL(returnPressed()), commentEdit, SLOT(setFocus())); connect(selectFileButton, SIGNAL(clicked()), this, SLOT(selectFile())); connect(openFileButton, SIGNAL(clicked()), this, SLOT(openFile())); connect(transactionsView, SIGNAL(itemSelectionChanged()), this, SLOT(transactionSelectionChanged())); connect(transactionsView, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(edit(QTreeWidgetItem*))); connect(newButton, SIGNAL(clicked()), this, SLOT(newTransaction())); connect(removeButton, SIGNAL(clicked()), this, SLOT(remove())); connect(editButton, SIGNAL(clicked()), this, SLOT(edit())); connect(categoryCombo, SIGNAL(newAccountRequested()), this, SLOT(newCategory())); } EditMultiAccountWidget::~EditMultiAccountWidget() {} void EditMultiAccountWidget::selectFile() { QStringList urls = QFileDialog::getOpenFileNames(this, QString(), (fileEdit->text().isEmpty() || fileEdit->text().contains(",")) ? last_associated_file_directory : fileEdit->text()); if(!urls.isEmpty()) { QFileInfo fileInfo(urls[0]); last_associated_file_directory = fileInfo.absoluteDir().absolutePath(); if(urls.size() == 1) { fileEdit->setText(urls[0]); } else { QString url; for(int i = 0; i < urls.size(); i++) { if(i > 0) url += ", "; if(urls[i].contains("\"")) {url += "\'"; url += urls[i]; url += "\'";} else {url += "\""; url += urls[i]; url += "\"";} } fileEdit->setText(url); } } } void EditMultiAccountWidget::openFile() { open_file_list(fileEdit->text()); } void EditMultiAccountWidget::newCategory() { categoryCombo->createAccount(); } void EditMultiAccountWidget::updateTotalValue() { double total_value = 0.0, highest_value = 0.0; QTreeWidgetItemIterator it(transactionsView); QTreeWidgetItem *i = *it; Currency *cur = NULL; while(i) { Transaction *trans = ((MultiAccountListViewItem*) i)->transaction(); if(!cur || trans->currency() == budget->defaultCurrency() || trans->value(true) > highest_value) { cur = trans->currency(); if(cur == budget->defaultCurrency()) break; highest_value = trans->value(true); } ++it; i = *it; } if(!cur) cur = budget->defaultCurrency(); QTreeWidgetItemIterator it2(transactionsView); i = *it2; while(i) { Transaction *trans = ((MultiAccountListViewItem*) i)->transaction(); if(trans) { if(budget->defaultTransactionConversionRateDate() == TRANSACTION_CONVERSION_RATE_AT_DATE) total_value += trans->currency()->convertTo(trans->value(), cur, trans->date()); else total_value += trans->currency()->convertTo(trans->value(), cur); } ++it2; i = *it2; } totalLabel->setText(QString("
    %1 %2
    ").arg(tr("Total cost:"), cur->formatValue(total_value))); } CategoryAccount *EditMultiAccountWidget::selectedCategory() { return (CategoryAccount*) categoryCombo->currentAccount(); } void EditMultiAccountWidget::transactionSelectionChanged() { QList list = transactionsView->selectedItems(); MultiAccountListViewItem *i = NULL; if(!list.isEmpty()) i = (MultiAccountListViewItem*) list.first(); editButton->setEnabled(i && i->transaction()); removeButton->setEnabled(i && i->transaction()); } void EditMultiAccountWidget::newTransaction() { TransactionEditDialog *dialog = new TransactionEditDialog(b_extra, b_expense ? TRANSACTION_TYPE_EXPENSE : TRANSACTION_TYPE_INCOME, NULL, false, NULL, SECURITY_ALL_VALUES, false, budget, this, b_create_accounts, true); dialog->editWidget->focusFirst(); dialog->editWidget->updateAccounts(); if(dialog->editWidget->checkAccounts() && dialog->exec() == QDialog::Accepted) { Transaction *trans = dialog->editWidget->createTransaction(); if(trans) { appendTransaction(trans); } updateTotalValue(); } dialog->deleteLater(); } void EditMultiAccountWidget::remove() { QDate d_date = date(); QList list = transactionsView->selectedItems(); if(list.isEmpty()) return; MultiAccountListViewItem *i = (MultiAccountListViewItem*) list.first(); if(i->transaction()) { delete i->transaction(); } delete i; updateTotalValue(); QDate d_date_new = date(); if(d_date != d_date_new) emit dateChanged(d_date_new); } void EditMultiAccountWidget::edit() { QList list = transactionsView->selectedItems(); if(list.isEmpty()) return; edit(list.first()); } void EditMultiAccountWidget::edit(QTreeWidgetItem *i_pre) { if(i_pre == NULL) return; MultiAccountListViewItem *i = (MultiAccountListViewItem*) i_pre; Transaction *trans = i->transaction(); if(trans) { TransactionEditDialog *dialog = new TransactionEditDialog(b_extra, trans->type(), NULL, false, NULL, SECURITY_ALL_VALUES, false, budget, this, b_create_accounts, true); dialog->editWidget->updateAccounts(); dialog->editWidget->setTransaction(trans); if(dialog->exec() == QDialog::Accepted) { QDate d_date = date(); if(dialog->editWidget->modifyTransaction(trans)) { i->setTransaction(trans); } updateTotalValue(); QDate d_date_new = date(); if(d_date != d_date_new) emit dateChanged(d_date_new); } dialog->deleteLater(); } } void EditMultiAccountWidget::newTag() { tagButton->createTag(); } MultiAccountTransaction *EditMultiAccountWidget::createTransaction() { if(!validValues()) return NULL; CategoryAccount *account = selectedCategory(); MultiAccountTransaction *split = new MultiAccountTransaction(budget, account, descriptionEdit->text()); linksWidget->updateTransaction(split); split->setComment(commentEdit->toPlainText()); split->setAssociatedFile(fileEdit->text()); tagButton->modifyTransaction(split); QTreeWidgetItemIterator it(transactionsView); QTreeWidgetItem *i = *it; while(i) { Transaction *trans = ((MultiAccountListViewItem*) i)->transaction(); if(trans) split->addTransaction(trans); ++it; i = *it; } return split; } void EditMultiAccountWidget::setValues(QString description_string, CategoryAccount *category_account, double quantity_value, QString comment_string) { descriptionEdit->setText(description_string); commentEdit->setPlainText(comment_string); if(quantityEdit) quantityEdit->setValue(quantity_value); categoryCombo->setCurrentAccount(category_account); } void EditMultiAccountWidget::setTransaction(Transactions *transs) { if(transs->generaltype() == GENERAL_TRANSACTION_TYPE_SCHEDULE) { setTransaction(((ScheduledTransaction*) transs)->transaction()); return; } linksWidget->setTransaction(transs); if(linksWidget->isEmpty()) { linksWidget->hide(); linksLabelLabel->hide(); } else { linksWidget->show(); linksLabelLabel->show(); } descriptionEdit->setText(transs->description()); commentEdit->setPlainText(transs->comment()); fileEdit->setText(transs->associatedFile()); if(quantityEdit) quantityEdit->setValue(transs->quantity()); transactionsView->clear(); if(transs->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT && ((SplitTransaction*) transs)->type() == SPLIT_TRANSACTION_TYPE_MULTIPLE_ACCOUNTS) { MultiAccountTransaction *split = (MultiAccountTransaction*) transs; categoryCombo->setCurrentAccount(split->category()); QList items; int c = split->count(); for(int i = 0; i < c; i++) { Transaction *trans = split->at(i)->copy(); if(trans->comment() == split->comment()) trans->setComment(QString()); trans->setAssociatedFile(QString()); items.append(new MultiAccountListViewItem(trans, b_extra)); } transactionsView->addTopLevelItems(items); } else if(transs->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE) { Transaction *trans = (Transaction*) transs; if(trans->type() == TRANSACTION_TYPE_EXPENSE) { categoryCombo->setCurrentAccount(((Expense*) trans)->category()); } else if(trans->type() == TRANSACTION_TYPE_INCOME) { categoryCombo->setCurrentAccount(((Income*) trans)->category()); } } tagButton->setTransaction(transs); updateTotalValue(); transactionsView->setSortingEnabled(true); emit dateChanged(transs->date()); } void EditMultiAccountWidget::setTransaction(MultiAccountTransaction *split, const QDate &date) { linksWidget->setTransaction(split); if(linksWidget->isEmpty()) { linksWidget->hide(); linksLabelLabel->hide(); } else { linksWidget->show(); linksLabelLabel->show(); } descriptionEdit->setText(split->description()); categoryCombo->setCurrentAccount(split->category()); if(quantityEdit) quantityEdit->setValue(split->quantity()); commentEdit->setPlainText(split->comment()); fileEdit->setText(split->associatedFile()); transactionsView->clear(); QList items; int c = split->count(); for(int i = 0; i < c; i++) { Transaction *trans = split->at(i)->copy(); if(trans->comment() == split->comment()) trans->setComment(QString()); trans->setAssociatedFile(QString()); if(date != split->date()) trans->setDate(date); items.append(new MultiAccountListViewItem(trans, b_extra)); } tagButton->setTransaction(split); transactionsView->addTopLevelItems(items); updateTotalValue(); transactionsView->setSortingEnabled(true); emit dateChanged(split->date()); } void EditMultiAccountWidget::appendTransaction(Transaction *trans) { QDate d_date = date(); MultiAccountListViewItem *i = new MultiAccountListViewItem(trans, b_extra); transactionsView->insertTopLevelItem(transactionsView->topLevelItemCount(), i); transactionsView->setSortingEnabled(true); QDate d_date_new = date(); if(d_date != d_date_new) emit dateChanged(d_date_new); } QDate EditMultiAccountWidget::date() { QDate d_date; QTreeWidgetItemIterator it(transactionsView); QTreeWidgetItem *i = *it; while(i) { Transaction *trans = ((MultiAccountListViewItem*) i)->transaction(); if(trans && (d_date.isNull() || trans->date() < d_date)) d_date = trans->date(); ++it; i = *it; } if(d_date.isNull()) d_date = QDate::currentDate(); return d_date; } void EditMultiAccountWidget::reject() { QTreeWidgetItemIterator it(transactionsView); QTreeWidgetItem *i = *it; while(i) { Transaction *trans = ((MultiAccountListViewItem*) i)->transaction(); if(trans) delete trans; ++it; i = *it; } } void EditMultiAccountWidget::focusFirst() { return descriptionEdit->setFocus(); } bool EditMultiAccountWidget::checkAccounts() { if(!categoryCombo->hasAccount()) { QMessageBox::critical(this, tr("Error"), tr("No suitable expense categories available.")); return false; } return true; } bool EditMultiAccountWidget::validValues() { if(!checkAccounts()) return false; if(transactionsView->topLevelItemCount() < 2) { QMessageBox::critical(this, tr("Error"), tr("A split must contain at least two transactions.")); return false; } if(!selectedCategory()) return false; return true; } EditDebtPaymentWidget::EditDebtPaymentWidget(Budget *budg, QWidget *parent, AssetsAccount *default_loan, bool allow_account_creation, bool only_interest) : QWidget(parent), budget(budg), b_create_accounts(allow_account_creation) { b_search = true; QVBoxLayout *box1 = new QVBoxLayout(this); QGridLayout *grid = new QGridLayout(); box1->addLayout(grid); if(only_interest) box1->addStretch(1); int row = 0; grid->addWidget(new QLabel(tr("Debt:")), row, 0); loanCombo = new AccountComboBox(-3, budget, b_create_accounts); loanCombo->updateAccounts(); grid->addWidget(loanCombo, row, 1); row++; grid->addWidget(new QLabel(tr("Date:")), row, 0); dateEdit = new EqonomizeDateEdit(this); dateEdit->setCalendarPopup(true); grid->addWidget(dateEdit, row, 1); row++; if(only_interest) { reductionEdit = NULL; paymentEdit = NULL; } else { grid->addWidget(new QLabel(tr("Debt reduction:")), row, 0); reductionEdit = new EqonomizeValueEdit(false, this, budget); grid->addWidget(reductionEdit, row, 1); row++; paymentLabel = new QLabel(tr("Reduction payment:")); grid->addWidget(paymentLabel, row, 0); paymentEdit = new EqonomizeValueEdit(false, this, budget); grid->addWidget(paymentEdit, row, 1); row++; if(!budget->usesMultipleCurrencies()) { paymentLabel->setVisible(false); paymentEdit->setVisible(false); } } grid->addWidget(new QLabel(tr("Interest:")), row, 0); interestEdit = new EqonomizeValueEdit(false, this, budget); grid->addWidget(interestEdit, row, 1); row++; if(only_interest) { feeEdit = NULL; totalLabel = NULL; accountCombo = NULL; addedInterestButton = NULL; paidInterestButton = NULL; } else { QHBoxLayout *paidAddedLayout = new QHBoxLayout(); paidAddedLayout->addStretch(1); paidInterestButton = new EqonomizeRadioButton(tr("Paid"), this); paidAddedLayout->addWidget(paidInterestButton); addedInterestButton = new EqonomizeRadioButton(tr("Added to debt"), this); paidAddedLayout->addWidget(addedInterestButton); paidInterestButton->setChecked(true); grid->addLayout(paidAddedLayout, row, 0, 1, 2); row++; grid->addWidget(new QLabel(tr("Fee:")), row, 0); feeEdit = new EqonomizeValueEdit(false, this, budget); grid->addWidget(feeEdit, row, 1); row++; totalLabel = new QLabel(); grid->addWidget(totalLabel, row, 0, 1, 2); row++; grid->addWidget(new QLabel(tr("Account:")), row, 0); accountCombo = new AccountComboBox(ACCOUNT_TYPE_ASSETS, budget, b_create_accounts); accountCombo->updateAccounts(); grid->addWidget(accountCombo, row, 1); row++; } grid->addWidget(new QLabel(tr("Expense category:")), row, 0); categoryCombo = new AccountComboBox(ACCOUNT_TYPE_EXPENSES, budget, b_create_accounts); categoryCombo->updateAccounts(); grid->addWidget(categoryCombo, row, 1); row++; if(only_interest) { commentEdit = NULL; fileEdit = NULL; } else { grid->addWidget(new QLabel(tr("Associated file:"), this), row, 0); QHBoxLayout *fileLayout = new QHBoxLayout(); fileEdit = new QLineEdit(this); QCompleter *completer = new QCompleter(this); QFileSystemModel *fsModel = new QFileSystemModel(completer); fsModel->setRootPath(QString()); completer->setModel(fsModel); fileEdit->setCompleter(completer); fileLayout->addWidget(fileEdit); QPushButton *selectFileButton = new QPushButton(LOAD_ICON("document-open"), QString(), this); selectFileButton->setToolTip(tr("Select a file")); selectFileButton->setAutoDefault(false); fileLayout->addWidget(selectFileButton); QPushButton *openFileButton = new QPushButton(LOAD_ICON("system-run"), QString(), this); openFileButton->setToolTip(tr("Open the file")); openFileButton->setAutoDefault(false); fileLayout->addWidget(openFileButton); openFileButton->setFocusPolicy(Qt::ClickFocus); grid->addLayout(fileLayout, row, 1); row++; connect(selectFileButton, SIGNAL(clicked()), this, SLOT(selectFile())); connect(openFileButton, SIGNAL(clicked()), this, SLOT(openFile())); QLabel *commentLabel = new QLabel(tr("Comments:")); commentLabel->setMinimumHeight(fileEdit->sizeHint().height()); grid->addWidget(commentLabel, row, 0, Qt::AlignTop | Qt::AlignLeft); commentEdit = new CommentsTextEdit(this); grid->addWidget(commentEdit, row, 1); row++; } linksWidget = new LinksWidget(this, b_create_accounts); linksWidget->hide(); //: Label for linked transactions linksLabelLabel = new QLabel(tr("Related to:"), this); linksLabelLabel->hide(); grid->addWidget(linksLabelLabel, row, 0); grid->addWidget(linksWidget, row, 1); row++; loanCombo->focusAndSelectAll(); if(default_loan) loanCombo->setCurrentAccount(default_loan); b_search = true; loanActivated(loanCombo->currentAccount()); accountChanged(); valueChanged(); interestSourceChanged(); b_search = true; connect(loanCombo, SIGNAL(returnPressed()), this, SLOT(focusDate())); connect(loanCombo, SIGNAL(accountSelected(Account*)), this, SLOT(focusDate())); if(only_interest) { connect(dateEdit, SIGNAL(returnPressed()), interestEdit, SLOT(enterFocus())); connect(interestEdit, SIGNAL(returnPressed()), categoryCombo, SLOT(focusAndSelectAll())); connect(categoryCombo, SIGNAL(returnPressed()), this, SIGNAL(addmodify())); } else { connect(dateEdit, SIGNAL(returnPressed()), reductionEdit, SLOT(enterFocus())); connect(reductionEdit, SIGNAL(returnPressed()), this, SLOT(reductionFocusNext())); connect(paymentEdit, SIGNAL(returnPressed()), interestEdit, SLOT(enterFocus())); connect(interestEdit, SIGNAL(returnPressed()), paidInterestButton, SLOT(setFocus())); connect(paidInterestButton, SIGNAL(returnPressed()), feeEdit, SLOT(enterFocus())); connect(addedInterestButton, SIGNAL(returnPressed()), feeEdit, SLOT(enterFocus())); connect(feeEdit, SIGNAL(returnPressed()), this, SLOT(feeFocusNext())); connect(accountCombo, SIGNAL(accountSelected(Account*)), this, SLOT(accountFocusNext())); connect(accountCombo, SIGNAL(returnPressed()), this, SLOT(accountFocusNext())); connect(categoryCombo, SIGNAL(accountSelected(Account*)), fileEdit, SLOT(setFocus())); connect(categoryCombo, SIGNAL(returnPressed()), fileEdit, SLOT(setFocus())); connect(fileEdit, SIGNAL(returnPressed()), commentEdit, SLOT(setFocus())); } if(dateEdit) connect(dateEdit, SIGNAL(dateChanged(const QDate&)), this, SIGNAL(dateChanged(const QDate&))); if(dateEdit) connect(dateEdit, SIGNAL(dateChanged(const QDate&)), this, SLOT(hasBeenModified())); if(commentEdit) connect(commentEdit, SIGNAL(textChanged()), this, SLOT(hasBeenModified())); if(fileEdit) connect(fileEdit, SIGNAL(textChanged(const QString&)), this, SLOT(hasBeenModified())); if(feeEdit) connect(feeEdit, SIGNAL(valueChanged(double)), this, SLOT(valueChanged())); if(paymentEdit) connect(paymentEdit, SIGNAL(valueChanged(double)), this, SLOT(valueChanged())); if(reductionEdit && paymentEdit) connect(reductionEdit, SIGNAL(editingFinished()), this, SLOT(reductionEditingFinished())); if(reductionEdit) connect(reductionEdit, SIGNAL(valueChanged(double)), this, SLOT(valueChanged())); if(interestEdit) connect(interestEdit, SIGNAL(valueChanged(double)), this, SLOT(valueChanged())); if(paidInterestButton) connect(paidInterestButton, SIGNAL(toggled(bool)), this, SLOT(interestSourceChanged())); if(addedInterestButton) connect(addedInterestButton, SIGNAL(toggled(bool)), this, SLOT(interestSourceChanged())); if(loanCombo) connect(loanCombo, SIGNAL(accountSelected(Account*)), this, SLOT(loanActivated(Account*))); if(accountCombo) connect(accountCombo, SIGNAL(newAccountRequested()), this, SLOT(newAccount())); if(loanCombo) connect(loanCombo, SIGNAL(newAccountRequested()), this, SLOT(newLoan())); if(categoryCombo) connect(categoryCombo, SIGNAL(newAccountRequested()), this, SLOT(newCategory())); if(accountCombo) connect(accountCombo, SIGNAL(currentAccountChanged(Account*)), this, SLOT(accountChanged())); } EditDebtPaymentWidget::~EditDebtPaymentWidget() {} void EditDebtPaymentWidget::focusFirst() { loanCombo->focusAndSelectAll(); } void EditDebtPaymentWidget::focusDate() { if(!dateEdit) return; dateEdit->setFocus(); dateEdit->setCurrentSection(QDateTimeEdit::DaySection); } void EditDebtPaymentWidget::reductionFocusNext() { if(paymentEdit->isVisible() && paymentEdit->isEnabled()) paymentEdit->enterFocus(); else interestEdit->enterFocus(); } void EditDebtPaymentWidget::accountFocusNext() { if(categoryCombo->isEnabled()) categoryCombo->focusAndSelectAll(); else fileEdit->setFocus(); } void EditDebtPaymentWidget::feeFocusNext() { if(accountCombo->isEnabled()) accountCombo->focusAndSelectAll(); else if(categoryCombo->isEnabled()) categoryCombo->focusAndSelectAll(); else fileEdit->setFocus(); } void EditDebtPaymentWidget::selectFile() { QStringList urls = QFileDialog::getOpenFileNames(this, QString(), (fileEdit->text().isEmpty() || fileEdit->text().contains(",")) ? last_associated_file_directory : fileEdit->text()); if(!urls.isEmpty()) { QFileInfo fileInfo(urls[0]); last_associated_file_directory = fileInfo.absoluteDir().absolutePath(); if(urls.size() == 1) { fileEdit->setText(urls[0]); } else { QString url; for(int i = 0; i < urls.size(); i++) { if(i > 0) url += ", "; if(urls[i].contains("\"")) {url += "\'"; url += urls[i]; url += "\'";} else {url += "\""; url += urls[i]; url += "\"";} } fileEdit->setText(url); } } } void EditDebtPaymentWidget::openFile() { open_file_list(fileEdit->text()); } void EditDebtPaymentWidget::newAccount() { accountCombo->createAccount(); loanCombo->updateAccounts(); bool b = budget->usesMultipleCurrencies(); paymentLabel->setVisible(b); paymentEdit->setVisible(b); } void EditDebtPaymentWidget::newCategory() { categoryCombo->createAccount(); } void EditDebtPaymentWidget::newLoan() { loanCombo->createAccount(); accountCombo->updateAccounts(); bool b = budget->usesMultipleCurrencies(); paymentLabel->setVisible(b); paymentEdit->setVisible(b); } void EditDebtPaymentWidget::accountChanged() { valueChanged(); } void EditDebtPaymentWidget::loanActivated(Account *account) { if(!account) return; AssetsAccount *loan = (AssetsAccount*) account; if(b_search) { DebtPayment *trans = NULL; SplitTransactionList::const_iterator it = budget->splitTransactions.constEnd(); while(it != budget->splitTransactions.constBegin()) { --it; SplitTransaction *split = *it; if(split->type() == SPLIT_TRANSACTION_TYPE_LOAN && ((DebtPayment*) split)->loan() == loan) { trans = (DebtPayment*) split; break; } } if(trans) { if(paymentEdit) paymentEdit->setValue(trans->payment()); if(reductionEdit) reductionEdit->setValue(trans->reduction()); if(feeEdit) feeEdit->setValue(trans->fee()); if(interestEdit) interestEdit->setValue(trans->interest()); if(accountCombo) accountCombo->setCurrentAccount(trans->account()); } if(categoryCombo) { if(trans && trans->expenseCategory()) { categoryCombo->setCurrentAccount(trans->expenseCategory()); } else { ExpensesAccount *cat = NULL; while(it != budget->splitTransactions.constBegin()) { --it; SplitTransaction *split = *it; if(split->type() == SPLIT_TRANSACTION_TYPE_LOAN && ((DebtPayment*) split)->loan() == loan) { cat = ((DebtPayment*) split)->expenseCategory(); if(cat) break; } } if(cat) { categoryCombo->setCurrentAccount(cat); } else { for(TransactionList::const_iterator it = budget->expenses.constEnd(); it != budget->expenses.constBegin();) { --it; Expense *etrans = *it; if(etrans->from() == loan) { categoryCombo->setCurrentAccount(etrans->category()); break; } } } } } valueChanged(); b_search = true; } else { valueChanged(); } } void EditDebtPaymentWidget::reductionEditingFinished() { if(paymentEdit && paymentEdit->isEnabled() && paymentEdit->value() == 0.0 && paymentEdit->currency() && reductionEdit->currency()) { paymentEdit->setValue(reductionEdit->currency()->convertTo(reductionEdit->value(), paymentEdit->currency())); } } void EditDebtPaymentWidget::valueChanged() { if(categoryCombo) categoryCombo->setEnabled((!paymentEdit && !reductionEdit) || (interestEdit && interestEdit->value() > 0.0) || (feeEdit && feeEdit->value() > 0.0)); if(accountCombo && interestEdit && paidInterestButton) { accountCombo->setEnabled(interestEdit->value() == 0.0 || (feeEdit && feeEdit->value() > 0.0) || (paymentEdit && paymentEdit->value() > 0.0) || (reductionEdit && reductionEdit->value() > 0.0) || paidInterestButton->isChecked()); } Account *acc = selectedAccount(); AssetsAccount *loan = selectedLoan(); if(!acc || !loan) return; if(feeEdit && feeEdit->currency() != acc->currency()) feeEdit->setCurrency(acc->currency()); if(reductionEdit && reductionEdit->currency() != loan->currency()) reductionEdit->setCurrency(loan->currency()); if((!addedInterestButton || addedInterestButton->isChecked()) && interestEdit) interestEdit->setCurrency(loan->currency()); if(addedInterestButton && addedInterestButton->isChecked()) { if(selectedLoan() && interestEdit->currency() != loan->currency()) interestEdit->setCurrency(loan->currency()); } else if(interestEdit) { if(selectedAccount() && interestEdit->currency() != acc->currency()) interestEdit->setCurrency(acc->currency()); } if(paymentEdit) { if(paymentEdit->currency() != acc->currency()) paymentEdit->setCurrency(acc->currency()); if(loan && loan->currency() == acc->currency()) { paymentEdit->setEnabled(false); } else { paymentEdit->setEnabled(true); } } if(paymentEdit && !paymentEdit->isEnabled() && paymentEdit->value() != reductionEdit->value()) { paymentEdit->setValue(reductionEdit->value()); } updateTotalValue(); hasBeenModified(); } void EditDebtPaymentWidget::interestSourceChanged() { valueChanged(); } void EditDebtPaymentWidget::updateTotalValue() { if(!totalLabel) return; double value = 0.0, v1 = 0.0, v2 = 0.0, v3 = 0.0; Currency *cur = budget->defaultCurrency(); Currency *cur3 = cur; QDate date; if(budget->defaultTransactionConversionRateDate() == TRANSACTION_CONVERSION_RATE_AT_DATE) { if(dateEdit) date = dateEdit->date(); if(!date.isValid()) date = QDate::currentDate(); } if((!feeEdit || feeEdit->currency() != cur) && (!interestEdit || interestEdit->currency() != cur) && (!paymentEdit || paymentEdit->currency() != cur) && (!reductionEdit || reductionEdit->currency() != cur)) { if(feeEdit && feeEdit->currency()) feeEdit->currency()->convertTo(feeEdit->value(), cur, date); if(interestEdit && interestEdit->currency()) { v2 = interestEdit->currency()->convertTo(interestEdit->value(), cur, date); if(feeEdit && feeEdit->currency() == interestEdit->currency()) v1 += v2; } if(paymentEdit && paymentEdit->currency() && (paymentEdit->value() > 0.0 || (!reductionEdit || !reductionEdit->currency() || reductionEdit->value() <= 0.0))) { cur3 = paymentEdit->currency(); v3 = cur3->convertTo(paymentEdit->value(), cur, date); if(feeEdit && feeEdit->currency() == paymentEdit->currency()) v1 += v3; else if(interestEdit && interestEdit->currency() == paymentEdit->currency()) v2 += v3; } else if(reductionEdit && reductionEdit->currency()) { cur3 = reductionEdit->currency(); v3 = cur3->convertTo(reductionEdit->value(), cur, date); if(feeEdit && feeEdit->currency() == reductionEdit->currency()) v1 += v3; else if(interestEdit && interestEdit->currency() == reductionEdit->currency()) v2 += v3; } if(v3 >= v1 && v3 >= v2 && cur3) { cur = cur3; } else if(v2 >= v1 && interestEdit && interestEdit->currency()) { cur = interestEdit->currency(); } else if(v1 > 0.0 && feeEdit && feeEdit->currency()) { cur = feeEdit->currency(); } } if(feeEdit) { value += feeEdit->currency()->convertTo(feeEdit->value(), cur, date); } if(interestEdit) { value += interestEdit->currency()->convertTo(interestEdit->value(), cur, date); } if(paymentEdit && paymentEdit->currency() && (paymentEdit->value() > 0.0 || (!reductionEdit || !reductionEdit->currency() || reductionEdit->value() <= 0.0))) { value += paymentEdit->currency()->convertTo(paymentEdit->value(), cur, date); } else if(reductionEdit && reductionEdit->currency()) { value += reductionEdit->currency()->convertTo(reductionEdit->value(), cur, date); } totalLabel->setText(QString("
    %1 %2
    ").arg(tr("Total value:"), cur->formatValue(value))); } AssetsAccount *EditDebtPaymentWidget::selectedLoan() { if(!loanCombo) return NULL; return (AssetsAccount*) loanCombo->currentAccount(); } AssetsAccount *EditDebtPaymentWidget::selectedAccount() { if(!accountCombo) return NULL; return (AssetsAccount*) accountCombo->currentAccount(); } ExpensesAccount *EditDebtPaymentWidget::selectedCategory() { if(!categoryCombo) return NULL; return (ExpensesAccount*) categoryCombo->currentAccount(); } DebtPayment *EditDebtPaymentWidget::createTransaction() { if(!validValues()) return NULL; AssetsAccount *loan = selectedLoan(); AssetsAccount *account = selectedAccount(); ExpensesAccount *category = selectedCategory(); DebtPayment *split = new DebtPayment(budget, dateEdit->date(), loan, account ? account : loan); linksWidget->updateTransaction(split); if((reductionEdit && reductionEdit->value() > 0.0) || (paymentEdit && paymentEdit->value() > 0.0)) split->setPayment(paymentEdit->value(), reductionEdit->value()); if(feeEdit && feeEdit->value() > 0.0) split->setFee(feeEdit->value()); if(interestEdit && interestEdit->value() > 0.0) split->setInterest(interestEdit->value(), !(addedInterestButton && addedInterestButton->isChecked())); if((feeEdit && feeEdit->value() > 0.0) || (interestEdit && interestEdit->value() > 0.0)) split->setExpenseCategory(category); if(commentEdit) split->setComment(commentEdit->toPlainText()); if(fileEdit) split->setAssociatedFile(fileEdit->text()); return split; } void EditDebtPaymentWidget::setTransaction(DebtPayment *split) { linksWidget->setTransaction(split); if(linksWidget->isEmpty()) { linksWidget->hide(); linksLabelLabel->hide(); } else { linksWidget->show(); linksLabelLabel->show(); } if(dateEdit) dateEdit->setDate(split->date()); if(commentEdit) commentEdit->setPlainText(split->comment()); if(fileEdit) fileEdit->setText(split->associatedFile()); if(loanCombo) loanCombo->setCurrentAccount(split->loan()); if(accountCombo) accountCombo->setCurrentAccount(split->account()); if(categoryCombo && split->expenseCategory()) categoryCombo->setCurrentAccount(split->expenseCategory()); if(paymentEdit) paymentEdit->setValue(split->payment()); if(reductionEdit) reductionEdit->setValue(split->reduction()); if(interestEdit) interestEdit->setValue(split->interest()); if(paidInterestButton && split->interestPaid()) paidInterestButton->setChecked(true); else if(addedInterestButton) addedInterestButton->setChecked(true); if(feeEdit) feeEdit->setValue(split->fee()); valueChanged(); emit dateChanged(split->date()); } void EditDebtPaymentWidget::setTransaction(DebtPayment *split, const QDate &date) { setTransaction(split); if(dateEdit) dateEdit->setDate(date); } QDate EditDebtPaymentWidget::date() { if(!dateEdit) return QDate::currentDate(); return dateEdit->date(); } void EditDebtPaymentWidget::hasBeenModified() { b_search = false; } bool EditDebtPaymentWidget::checkAccounts() { if((loanCombo && !loanCombo->hasAccount()) || (accountCombo && !accountCombo->hasAccount()) || (categoryCombo && !categoryCombo->hasAccount())) { QMessageBox::critical(this, tr("Error"), tr("No suitable account available.")); return false; } return true; } bool EditDebtPaymentWidget::validValues() { if(!checkAccounts()) return false; if(dateEdit && !dateEdit->date().isValid()) { QMessageBox::critical(this, tr("Error"), tr("Invalid date.")); return false; } if((!feeEdit || feeEdit->value() <= 0.0) && (!interestEdit || interestEdit->value() <= 0.0) && (!paymentEdit || paymentEdit->value() <= 0.0) && (!reductionEdit || reductionEdit->value() <= 0.0)) { if(!feeEdit && !reductionEdit) { QMessageBox::critical(this, tr("Error"), tr("Interest must not be zero.")); interestEdit->setFocus(); } else { QMessageBox::critical(this, tr("Error"), tr("At least one value must non-zero.")); if(reductionEdit) reductionEdit->setFocus(); } return false; } if((accountCombo && !selectedAccount()) || (categoryCombo && !selectedCategory()) || (loanCombo && !selectedLoan())) return false; return true; } Eqonomize-1.5.3/src/editsplitdialog.h000066400000000000000000000175361416454732000176310ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016-2020 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifndef EDIT_SPLIT_DIALOG_H #define EDIT_SPLIT_DIALOG_H #include #include #include class QLabel; class QPushButton; class QTreeWidget; class QTreeWidgetItem; class QLineEdit; class QPlainTextEdit; class QComboBox; class QDateEdit; class EqonomizeValueEdit; class TagButton; class LinksWidget; class Account; class AccountComboBox; class AssetsAccount; class CategoryAccount; class ExpensesAccount; class Budget; class MultiItemTransaction; class MultiAccountTransaction; class DebtPayment; class Transaction; class Transactions; class EditMultiAccountWidget : public QWidget { Q_OBJECT protected: Budget *budget; bool b_expense, b_extra, b_create_accounts; EqonomizeValueEdit *quantityEdit; AccountComboBox *categoryCombo; QLineEdit *descriptionEdit, *fileEdit; QPlainTextEdit *commentEdit; QTreeWidget *transactionsView; QPushButton *newButton, *editButton, *removeButton; QLabel *totalLabel, *linksLabelLabel; LinksWidget *linksWidget; TagButton *tagButton; void appendTransaction(Transaction *trans); void updateTotalValue(); CategoryAccount *selectedCategory(); public: EditMultiAccountWidget(Budget *budg, QWidget *parent, bool create_expenses = true, bool extra_parameters = false, bool allow_account_creation = false); ~EditMultiAccountWidget(); MultiAccountTransaction *createTransaction(); void setValues(QString description_string, CategoryAccount *category_account, double quantity_value, QString comment_string); void setTransaction(Transactions *transs); void setTransaction(MultiAccountTransaction *split, const QDate &date); bool validValues(); bool checkAccounts(); void focusFirst(); void reject(); QDate date(); signals: void dateChanged(const QDate &date); protected slots: void selectFile(); void openFile(); void remove(); void edit(); void edit(QTreeWidgetItem*); void transactionSelectionChanged(); void newTransaction(); void newCategory(); void newTag(); }; class EditDebtPaymentWidget : public QWidget { Q_OBJECT protected: Budget *budget; bool b_create_accounts, b_search; QDateEdit *dateEdit; EqonomizeValueEdit *reductionEdit, *paymentEdit, *interestEdit, *feeEdit; QRadioButton *paidInterestButton, *addedInterestButton; AccountComboBox *accountCombo, *categoryCombo, *loanCombo; QLineEdit *fileEdit; QPlainTextEdit *commentEdit; QLabel *paymentLabel, *totalLabel, *linksLabelLabel; LinksWidget *linksWidget; void updateTotalValue(); AssetsAccount *selectedLoan(); ExpensesAccount *selectedCategory(); AssetsAccount *selectedAccount(); public: EditDebtPaymentWidget(Budget *budg, QWidget *parent, AssetsAccount *default_loan = NULL, bool allow_account_creation = false, bool only_interest = false); ~EditDebtPaymentWidget(); DebtPayment *createTransaction(); void setTransaction(DebtPayment *split); void setTransaction(DebtPayment *split, const QDate &date); bool validValues(); bool checkAccounts(); QDate date(); void focusFirst(); signals: void dateChanged(const QDate &d); void addmodify(); protected slots: void selectFile(); void openFile(); void accountChanged(); void loanActivated(Account*); void newAccount(); void newCategory(); void newLoan(); void valueChanged(); void reductionEditingFinished(); void interestSourceChanged(); void hasBeenModified(); void focusDate(); void reductionFocusNext(); void accountFocusNext(); void feeFocusNext(); }; class EditMultiItemWidget : public QWidget { Q_OBJECT protected: Budget *budget; bool b_extra, b_create_accounts; QDateEdit *dateEdit; AccountComboBox *accountCombo; QLineEdit *descriptionEdit, *payeeEdit, *fileEdit; QPlainTextEdit *commentEdit; QTreeWidget *transactionsView; QPushButton *newButton, *editButton, *removeButton; QLabel *totalLabel, *linksLabelLabel; LinksWidget *linksWidget; TagButton *tagButton; void appendTransaction(Transaction *trans, bool deposit); void newTransaction(int transtype, bool select_security = false, bool transfer_to = false, Account *exclude_account = NULL); void updateTotalValue(); AssetsAccount *selectedAccount(); public: EditMultiItemWidget(Budget *budg, QWidget *parent, AssetsAccount *default_account = NULL, bool extra_parameters = false, bool allow_account_creation = false); ~EditMultiItemWidget(); MultiItemTransaction *createTransaction(); void setTransaction(MultiItemTransaction *split); void setTransaction(MultiItemTransaction *split, const QDate &date); bool validValues(); bool checkAccounts(); void reject(); void focusFirst(); QDate date(); signals: void dateChanged(const QDate &date); protected slots: void selectFile(); void openFile(); void accountChanged(); void remove(); void edit(); void edit(QTreeWidgetItem*); void transactionSelectionChanged(); void newExpense(); void newIncome(); void newDividend(); void newSecurityBuy(); void newSecuritySell(); void newTransferFrom(); void newTransferTo(); void newAccount(); void focusDate(); void newTag(); }; class EditMultiItemDialog : public QDialog { Q_OBJECT public: EditMultiItemDialog(Budget *budg, QWidget *parent, AssetsAccount *default_account = NULL, bool extra_parameters = false, bool allow_account_creation = false); ~EditMultiItemDialog(); EditMultiItemWidget *editWidget; protected: void keyPressEvent(QKeyEvent*); protected slots: void accept(); void reject(); }; class EditMultiAccountDialog : public QDialog { Q_OBJECT public: EditMultiAccountDialog(Budget *budg, QWidget *parent, bool create_expenses = true, bool extra_parameters = false, bool allow_account_creation = false); ~EditMultiAccountDialog(); EditMultiAccountWidget *editWidget; protected: void keyPressEvent(QKeyEvent*); protected slots: void accept(); void reject(); }; class EditDebtPaymentDialog : public QDialog { Q_OBJECT public: EditDebtPaymentDialog(Budget *budg, QWidget *parent, AssetsAccount *default_loan = NULL, bool allow_account_creation = false, bool only_interest = false); ~EditDebtPaymentDialog(); EditDebtPaymentWidget *editWidget; protected: void keyPressEvent(QKeyEvent*); protected slots: void accept(); }; class EqonomizeRadioButton : public QRadioButton { Q_OBJECT public: EqonomizeRadioButton(const QString &text, QWidget *parent); protected slots: void keyPressEvent(QKeyEvent *event); signals: void returnPressed(); }; #endif Eqonomize-1.5.3/src/eqonomize.cpp000066400000000000000000017261711416454732000170140ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016-2020 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) # include #else # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "accountcombobox.h" #include "budget.h" #include "editaccountdialogs.h" #include "editcurrencydialog.h" #include "categoriescomparisonchart.h" #include "categoriescomparisonreport.h" #include "currencyconversiondialog.h" #include "editscheduledtransactiondialog.h" #include "editsplitdialog.h" #include "eqonomize.h" #include "eqonomizemonthselector.h" #include "eqonomizevalueedit.h" #include "importcsvdialog.h" #include "ledgerdialog.h" #include "overtimechart.h" #include "overtimereport.h" #include "qifimportexport.h" #include "recurrence.h" #include "recurrenceeditwidget.h" #include "security.h" #include "transactionlistwidget.h" #include "transactioneditwidget.h" #include #define ACCOUNTS_PAGE_INDEX 0 #define EXPENSES_PAGE_INDEX 1 #define INCOMES_PAGE_INDEX 2 #define TRANSFERS_PAGE_INDEX 3 #define SECURITIES_PAGE_INDEX 4 #define SCHEDULE_PAGE_INDEX 5 #define MAX_RECENT_FILES 10 #define NEW_ACCOUNT_TREE_WIDGET_ITEM(i, parent, s1, s2, s3, s4) QTreeWidgetItem *i = new QTreeWidgetItem(parent); i->setText(0, s1); i->setText(1, s2); i->setText(2, s3); i->setText(3, s4); i->setTextAlignment(BUDGET_COLUMN, Qt::AlignRight | Qt::AlignVCenter); i->setTextAlignment(CHANGE_COLUMN, Qt::AlignRight | Qt::AlignVCenter); i->setTextAlignment(VALUE_COLUMN, Qt::AlignRight | Qt::AlignVCenter); enum { BACKUP_NEVER, BACKUP_DAILY, BACKUP_WEEKLY, BACKUP_FORTNIGHTLY, BACKUP_MONTHLY }; #define CHANGE_COLUMN 2 #define BUDGET_COLUMN 1 #define VALUE_COLUMN 3 #define IS_DEBT(account) (account)->isLiabilities() Eqonomize *mainwin; QString last_document_directory, last_associated_file_directory, last_picture_directory; QColor createExpenseColor(QColor base_color) { #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) float r, g, b; #else qreal r, g, b; #endif base_color.getRgbF(&r, &g, &b); if(r >= 0.8) { g /= 1.5; b /= 1.5; r = 1.0; } else { if(r >= 0.6) r = 1.0; else r += 0.4; } base_color.setRgbF(r, g, b); return base_color; } QColor createIncomeColor(QColor base_color) { #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) float r, g, b; #else qreal r, g, b; #endif base_color.getRgbF(&r, &g, &b); if(g >= 0.8) { r /= 1.5; b /= 1.5; g = 1.0; } else { if(g >= 0.7) g = 1.0; else g += 0.3; } base_color.setRgbF(r, g, b); return base_color; } QColor createTransferColor(QColor base_color) { #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) float r, g, b; #else qreal r, g, b; #endif base_color.getRgbF(&r, &g, &b); if(b >= 0.8) { g /= 1.5; r /= 1.5; b = 1.0; } else { if(b >= 0.7) b = 1.0; else b += 0.3; } base_color.setRgbF(r, g, b); return base_color; } QColor createExpenseColor(QTreeWidgetItem *i, int = 0) {return createExpenseColor(i->treeWidget()->viewport()->palette().color(i->treeWidget()->viewport()->foregroundRole()));} QColor createIncomeColor(QTreeWidgetItem *i, int = 0) {return createIncomeColor(i->treeWidget()->viewport()->palette().color(i->treeWidget()->viewport()->foregroundRole()));} QColor createTransferColor(QTreeWidgetItem *i, int = 0) {return createTransferColor(i->treeWidget()->viewport()->palette().color(i->treeWidget()->viewport()->foregroundRole()));} QColor createExpenseColor(QWidget *w) {return createExpenseColor(w->palette().color(w->foregroundRole()));} QColor createIncomeColor(QWidget *w) {return createIncomeColor(w->palette().color(w->foregroundRole()));} QColor createTransferColor(QWidget *w) {return createTransferColor(w->palette().color(w->foregroundRole()));} void setAccountChangeColor(QTreeWidgetItem *i, double change, bool is_expense) { //QColor fg = i->foreground(VALUE_COLUMN).color(); if((!is_expense && change < 0.0) || (is_expense && change > 0.0)) { i->setForeground(CHANGE_COLUMN, createExpenseColor(i, VALUE_COLUMN)); } else if((is_expense && change < 0.0) || (!is_expense && change > 0.0)) { i->setForeground(CHANGE_COLUMN, createIncomeColor(i, VALUE_COLUMN)); } else { i->setForeground(CHANGE_COLUMN, i->treeWidget()->palette().color(i->treeWidget()->foregroundRole())); } } void setAccountBudgetColor(QTreeWidgetItem *i, double budget_rem, bool is_expense) { if(!is_expense) return; //QColor fg = i->foreground(VALUE_COLUMN).color(); if(budget_rem < 0.0) i->setForeground(BUDGET_COLUMN, createExpenseColor(i, VALUE_COLUMN)); else i->setForeground(BUDGET_COLUMN, createIncomeColor(i, VALUE_COLUMN)); } void setColumnTextWidth(QTreeWidget *w, int i, QString str) { QFontMetrics fm(w->font()); int tw = fm.boundingRect(str).width() + 10; int hw = fm.boundingRect(w->headerItem()->text(i)).width() + 10; if(w->columnWidth(i) < tw) w->setColumnWidth(i, tw); if(w->columnWidth(i) < hw) w->setColumnWidth(i, hw); } void setColumnDateWidth(QTreeWidget *w, int i) { setColumnTextWidth(w, i, QLocale().toString(QDate::currentDate(), QLocale::ShortFormat)); } void setColumnMoneyWidth(QTreeWidget *w, int i, Budget *budget, double v = 9999999.99, int d = -1) { setColumnTextWidth(w, i, budget->formatMoney(v, d, false) + " XXX"); } void setColumnValueWidth(QTreeWidget *w, int i, double v, int d, Budget *budget) { setColumnTextWidth(w, i, budget->formatValue(v, d)); } void setColumnStrlenWidth(QTreeWidget *w, int i, int l) { setColumnTextWidth(w, i, QString(l, 'h')); } void open_file_list(QString url) { if(url.isEmpty()) return; if(!url.contains(",")) { QDesktopServices::openUrl(QUrl::fromLocalFile(url)); return; } QStringList urls; while(!url.isEmpty()) { while(url[0] == '\"' || url[0] == '\'') { int i = url.indexOf(url[0], 1); if(i == url.length() - 1) { urls << url.mid(1, i - 1); url = ""; break; } else if(i > 0) { int i2 = url.indexOf(",", i + 1); if(i2 < 0) { break; } else if(i2 == i + 1) { urls << url.mid(1, i - 1); url.remove(0, i2 + 1); url = url.trimmed(); } else { QString str = url.mid(i + 1, i2 - (i + 1)).trimmed(); if(url.isEmpty()) { urls << url.mid(1, i - 1); url.remove(0, i2 + 1); url = url.trimmed(); } else { break; } } } else { break; } } if(url.isEmpty()) break; int i = url.indexOf(",", 1); if(i < 0) { urls << url; break; } else { urls << url.left(i).trimmed(); url.remove(0, i + 1); url = url.trimmed(); } } for(int i = 0; i < urls.size(); i++) { if(!urls[i].isEmpty()) QDesktopServices::openUrl(QUrl::fromLocalFile(urls[i])); } } QTreeWidgetItem *selectedItem(QTreeWidget *w) { QList list = w->selectedItems(); if(list.isEmpty()) return NULL; return list.first(); } EqonomizeComboBox::EqonomizeComboBox(QWidget *parent) : QComboBox(parent) { block_selected = false; connect(this, SIGNAL(activated(int)), this, SLOT(itemActivated(int))); } void EqonomizeComboBox::keyPressEvent(QKeyEvent *event) { block_selected = true; QComboBox::keyPressEvent(event); block_selected = false; if(!event->isAccepted() && (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter)) { emit returnPressed(); } } void EqonomizeComboBox::itemActivated(int index) { if(!block_selected) { emit itemSelected(index); } } EqonomizeItemDelegate::EqonomizeItemDelegate(QObject* parent) : QStyledItemDelegate(parent) {} void EqonomizeItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { if((option.state | QStyle::State_Active) && (option.state & QStyle::State_Selected)) { QStyleOptionViewItem itemOption(option); itemOption.state = itemOption.state | QStyle::State_Active; QStyledItemDelegate::paint(painter, itemOption, index); } else { QStyledItemDelegate::paint(painter, option, index); } } bool EqonomizeItemDelegate::helpEvent(QHelpEvent* e, QAbstractItemView* view, const QStyleOptionViewItem& option, const QModelIndex& index) { if(!e || !view) return false; if(e->type() == QEvent::ToolTip) { QRect rect = view->visualRect(index); QSize size = sizeHint(option, index); if(rect.width() < size.width()) { QVariant tooltip = index.data(Qt::DisplayRole); if(tooltip.canConvert()) { QToolTip::showText(e->globalPos(), QString("
    %1
    ").arg(tooltip.toString().toHtmlEscaped()), view); return true; } } if(!QStyledItemDelegate::helpEvent(e, view, option, index)) QToolTip::hideText(); return true; } return QStyledItemDelegate::helpEvent(e, view, option, index); } class SecurityListViewItem : public QTreeWidgetItem { protected: Security *o_security; public: SecurityListViewItem(Security *sec, QString s1, QString s2 = QString(), QString s3 = QString(), QString s4 = QString(), QString s5 = QString(), QString s6 = QString(), QString s7 = QString(), QString s8 = QString(), QString s9 = QString(), bool right_align_values = true) : QTreeWidgetItem(UserType), o_security(sec) { setText(0, s1); setText(1, s2); setText(2, s3); setText(3, s4); setText(4, s5); setText(5, s6); setText(6, s7); setText(7, s8); setText(8, s9); if(right_align_values) { setTextAlignment(1, Qt::AlignRight | Qt::AlignVCenter); setTextAlignment(2, Qt::AlignRight | Qt::AlignVCenter); setTextAlignment(3, Qt::AlignRight | Qt::AlignVCenter); setTextAlignment(4, Qt::AlignRight | Qt::AlignVCenter); setTextAlignment(5, Qt::AlignRight | Qt::AlignVCenter); setTextAlignment(6, Qt::AlignRight | Qt::AlignVCenter); } } bool operator<(const QTreeWidgetItem &i_pre) const { int col = 0; if(treeWidget()) col = treeWidget()->sortColumn(); SecurityListViewItem *i = (SecurityListViewItem*) &i_pre; switch(col) { case 1: { if(value < i->value) return true; if(value > i->value) return false; break; } case 2: { if(shares < i->shares) return true; if(shares > i->shares) return false; break; } case 3: { if(quote < i->quote) return true; if(quote > i->quote) return false; break; } case 4: { if(cost < i->cost) return true; if(cost > i->cost) return false; break; } case 5: { if(profit < i->profit) return true; if(profit > i->profit) return false; break; } case 6: { if(rate < i->rate) return true; if(rate > i->rate) return false; break; } default: {break;} } return QTreeWidgetItem::operator<(i_pre); } Security* security() const {return o_security;} double cost, value, rate, profit, shares, quote, scost, sprofit; }; class ScheduleListViewItem : public QTreeWidgetItem { Q_DECLARE_TR_FUNCTIONS(ScheduleListViewItem) protected: ScheduledTransaction *o_strans; QDate d_date; QColor expenseColor, incomeColor, transferColor; public: ScheduleListViewItem(QTreeWidget *parent, ScheduledTransaction *strans, const QDate &trans_date, bool right_align_values); bool operator<(const QTreeWidgetItem &i_pre) const; ScheduledTransaction *scheduledTransaction() const; void setScheduledTransaction(ScheduledTransaction *strans); const QDate &date() const; void setDate(const QDate &newdate); }; ScheduleListViewItem::ScheduleListViewItem(QTreeWidget *parent, ScheduledTransaction *strans, const QDate &trans_date, bool right_align_values) : QTreeWidgetItem(parent, UserType) { if(right_align_values) setTextAlignment(3, Qt::AlignRight | Qt::AlignVCenter); setScheduledTransaction(strans); setDate(trans_date); } bool ScheduleListViewItem::operator<(const QTreeWidgetItem &i_pre) const { int col = 0; if(treeWidget()) col = treeWidget()->sortColumn(); ScheduleListViewItem *i = (ScheduleListViewItem*) &i_pre; if(col == 0) { if(d_date < i->date()) return true; if(d_date > i->date()) return false; return o_strans->description().localeAwareCompare(i->scheduledTransaction()->description()) < 0; } else if(col == 3) { double d1 = o_strans->value(true), d2 = i->scheduledTransaction()->value(true); if(d1 < d2) return true; if(d1 > d2) return false; } return QTreeWidgetItem::operator<(i_pre); } ScheduledTransaction *ScheduleListViewItem::scheduledTransaction() const { return o_strans; } const QDate &ScheduleListViewItem::date() const { return d_date; } void ScheduleListViewItem::setDate(const QDate &newdate) { d_date = newdate; setText(0, QLocale().toString(d_date, QLocale::ShortFormat)); } void ScheduleListViewItem::setScheduledTransaction(ScheduledTransaction *strans) { o_strans = strans; setText(2, strans->description()); if(strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE) { Transaction *trans = (Transaction*) strans->transaction(); setText(3, textAlignment(3) & Qt::AlignRight ? trans->valueString() + " " : trans->valueString()); setText(4, trans->fromAccount()->name()); setText(5, trans->toAccount()->name()); if((trans->type() == TRANSACTION_TYPE_EXPENSE && trans->value() > 0.0) || (trans->type() == TRANSACTION_TYPE_INCOME && trans->value() < 0.0)) { if(!expenseColor.isValid()) expenseColor = createExpenseColor(this, 3); setForeground(3, expenseColor); } else if((trans->type() == TRANSACTION_TYPE_EXPENSE && trans->value() < 0.0) || (trans->type() == TRANSACTION_TYPE_INCOME && trans->value() > 0.0)) { if(!incomeColor.isValid()) incomeColor = createIncomeColor(this, 3); setForeground(3, incomeColor); } else { if(!transferColor.isValid()) transferColor = createTransferColor(this, 3); setForeground(3, transferColor); } switch(trans->type()) { case TRANSACTION_TYPE_TRANSFER: {setText(1, QObject::tr("Transfer")); break;} case TRANSACTION_TYPE_INCOME: { if(((Income*) trans)->security()) setText(1, QObject::tr("Dividend")); else setText(1, QObject::tr("Income")); break; } case TRANSACTION_TYPE_EXPENSE: { setText(1, QObject::tr("Expense")); break; } case TRANSACTION_TYPE_SECURITY_BUY: {setText(1, QObject::tr("Securities Purchase", "Financial security (e.g. stock, mutual fund)")); break;} case TRANSACTION_TYPE_SECURITY_SELL: {setText(1, QObject::tr("Securities Sale", "Financial security (e.g. stock, mutual fund)")); break;} } } else { SplitTransaction *split = (SplitTransaction*) strans->transaction(); if(split->type() == SPLIT_TRANSACTION_TYPE_LOAN) { setText(1, QObject::tr("Debt Payment")); setText(3, split->valueString(-split->value())); if(!expenseColor.isValid()) expenseColor = createExpenseColor(this, 3); setForeground(3, expenseColor); setText(4, ((DebtPayment*) split)->account()->name()); setText(5, ((DebtPayment*) split)->loan()->name()); } else { bool b_reverse = false; if(split->isIncomesAndExpenses()) { if(split->cost() > 0.0) { if(!expenseColor.isValid()) expenseColor = createExpenseColor(this, 3); setForeground(3, expenseColor); setText(3, split->valueString(split->cost())); b_reverse = true; } else { if(!incomeColor.isValid()) incomeColor = createIncomeColor(this, 3); setForeground(3, incomeColor); setText(3, split->valueString(split->income())); } } else { if(!transferColor.isValid()) transferColor = createTransferColor(this, 3); setForeground(3, transferColor); setText(3, split->valueString()); } if(split->type() == SPLIT_TRANSACTION_TYPE_MULTIPLE_ITEMS) { setText(b_reverse ? 4 : 5, ((MultiItemTransaction*) split)->account()->name()); setText(b_reverse ? 5 : 4, ((MultiItemTransaction*) split)->fromAccountsString()); if(((MultiItemTransaction*) split)->transactiontype() == TRANSACTION_TYPE_INCOME) setText(1, QObject::tr("Income")); else if(((MultiItemTransaction*) split)->transactiontype() == TRANSACTION_TYPE_EXPENSE) setText(1, QObject::tr("Expense")); else setText(1, QObject::tr("Split Transaction")); } else { setText(b_reverse ? 4 : 5, ((MultiAccountTransaction*) split)->category()->name()); setText(b_reverse ? 5 : 4, ((MultiAccountTransaction*) split)->accountsString()); if(((MultiAccountTransaction*) split)->transactiontype() == TRANSACTION_TYPE_INCOME) setText(1, QObject::tr("Income")); else setText(1, QObject::tr("Expense")); } } } if(!strans->associatedFile().isEmpty()) setIcon(3, LOAD_ICON_STATUS("mail-attachment")); else setIcon(3, QIcon()); setText(6, strans->payeeText()); setText(7, strans->tagsText(true)); setText(8, strans->comment()); if(strans->linksCount() > 0) setIcon(8, LOAD_ICON_STATUS("go-jump")); else setIcon(8, QIcon()); } class ConfirmScheduleListViewItem : public QTreeWidgetItem { Q_DECLARE_TR_FUNCTIONS(ConfirmScheduleListViewItem) protected: Transactions *o_trans; QColor expenseColor, incomeColor, transferColor; public: ConfirmScheduleListViewItem(QTreeWidget *parent, Transactions *trans); bool operator<(const QTreeWidgetItem &i_pre) const; Transactions *transaction() const; void setTransaction(Transactions *trans); }; ConfirmScheduleListViewItem::ConfirmScheduleListViewItem(QTreeWidget *parent, Transactions *trans) : QTreeWidgetItem(parent, UserType) { setTransaction(trans); setTextAlignment(3, Qt::AlignRight | Qt::AlignVCenter); } bool ConfirmScheduleListViewItem::operator<(const QTreeWidgetItem &i_pre) const { int col = 0; if(treeWidget()) col = treeWidget()->sortColumn(); ConfirmScheduleListViewItem *i = (ConfirmScheduleListViewItem*) &i_pre; if(col == 0) { return o_trans->date() < i->transaction()->date(); } else if(col == 3) { return o_trans->value(true) < i->transaction()->value(true); } return QTreeWidgetItem::operator<(i_pre); } Transactions *ConfirmScheduleListViewItem::transaction() const { return o_trans; } void ConfirmScheduleListViewItem::setTransaction(Transactions *transs) { o_trans = transs; setText(0, QLocale().toString(transs->date(), QLocale::ShortFormat)); if(transs->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE) { Transaction *trans = (Transaction*) transs; switch(trans->type()) { case TRANSACTION_TYPE_TRANSFER: {setText(1, tr("Transfer")); break;} case TRANSACTION_TYPE_INCOME: { if(((Income*) trans)->security()) setText(1, tr("Dividend")); else setText(1, tr("Income")); break; } case TRANSACTION_TYPE_EXPENSE: {setText(1, tr("Expense")); break;} case TRANSACTION_TYPE_SECURITY_BUY: {setText(1, tr("Securities Purchase", "Financial security (e.g. stock, mutual fund)")); break;} case TRANSACTION_TYPE_SECURITY_SELL: {setText(1, tr("Securities Sale", "Financial security (e.g. stock, mutual fund)")); break;} } if((trans->type() == TRANSACTION_TYPE_EXPENSE && trans->value() > 0.0) || (trans->type() == TRANSACTION_TYPE_INCOME && trans->value() < 0.0)) { if(!expenseColor.isValid()) expenseColor = createExpenseColor(this, 3); setForeground(3, expenseColor); } else if((trans->type() == TRANSACTION_TYPE_EXPENSE && trans->value() < 0.0) || (trans->type() == TRANSACTION_TYPE_INCOME && trans->value() > 0.0)) { if(!incomeColor.isValid()) incomeColor = createIncomeColor(this, 3); setForeground(3, incomeColor); } else { if(!transferColor.isValid()) transferColor = createTransferColor(this, 3); setForeground(3, transferColor); } setText(3, trans->valueString()); } else { SplitTransaction *split = (SplitTransaction*) transs; if(split->type() == SPLIT_TRANSACTION_TYPE_LOAN) { setText(3, split->valueString(-split->value())); if(!expenseColor.isValid()) expenseColor = createExpenseColor(this, 3); setForeground(3, expenseColor); setText(1, tr("Debt Payment")); } else { if(split->isIncomesAndExpenses()) { if(split->cost() > 0.0) { if(!expenseColor.isValid()) expenseColor = createExpenseColor(this, 3); setForeground(3, expenseColor); setText(3, split->valueString(split->cost())); } else { if(!incomeColor.isValid()) incomeColor = createIncomeColor(this, 3); setForeground(3, incomeColor); setText(3, split->valueString(split->income())); } } else { if(!transferColor.isValid()) transferColor = createTransferColor(this, 3); setForeground(3, transferColor); setText(3, split->valueString()); } if(split->type() == SPLIT_TRANSACTION_TYPE_MULTIPLE_ITEMS) { if(((MultiItemTransaction*) split)->transactiontype() == TRANSACTION_TYPE_INCOME) setText(1, QObject::tr("Income")); else if(((MultiItemTransaction*) split)->transactiontype() == TRANSACTION_TYPE_EXPENSE) setText(1, QObject::tr("Expense")); else setText(1, QObject::tr("Split Transaction")); } else { if(((MultiAccountTransaction*) split)->transactiontype() == TRANSACTION_TYPE_INCOME) setText(1, QObject::tr("Income")); else setText(1, QObject::tr("Expense")); } } } setText(2, transs->description()); } class SecurityTransactionListViewItem : public QTreeWidgetItem { public: SecurityTransactionListViewItem(QString, QString=QString(), QString=QString(), QString=QString()); bool operator<(const QTreeWidgetItem &i_pre) const; SecurityTransaction *trans; Income *div; ReinvestedDividend *rediv; ScheduledTransaction *strans, *sdiv, *srediv; SecurityTrade *ts; QDate date; double shares, value; }; SecurityTransactionListViewItem::SecurityTransactionListViewItem(QString s1, QString s2, QString s3, QString s4) : QTreeWidgetItem(UserType), trans(NULL), div(NULL), rediv(NULL), strans(NULL), sdiv(NULL), srediv(NULL), ts(NULL), shares(-1.0), value(-1.0) { setText(0, s1); setText(1, s2); setText(2, s3); setText(3, s4); setTextAlignment(0, Qt::AlignLeft | Qt::AlignVCenter); setTextAlignment(1, Qt::AlignLeft | Qt::AlignVCenter); setTextAlignment(2, Qt::AlignRight | Qt::AlignVCenter); setTextAlignment(3, Qt::AlignRight | Qt::AlignVCenter); } bool SecurityTransactionListViewItem::operator<(const QTreeWidgetItem &i_pre) const { int col = 0; if(treeWidget()) col = treeWidget()->sortColumn(); SecurityTransactionListViewItem *i = (SecurityTransactionListViewItem*) &i_pre; if(col == 0) { return date < i->date; } else if(col == 2) { return value < i->value; } else if(col == 2) { return shares < i->shares; } return QTreeWidgetItem::operator<(i_pre); } class QuotationListViewItem : public QTreeWidgetItem { public: QuotationListViewItem(const QDate &date_, double value_, int decimals_, Currency *currency); bool operator<(const QTreeWidgetItem &i_pre) const; QDate date; double value; int decimals; }; QuotationListViewItem::QuotationListViewItem(const QDate &date_, double value_, int decimals_, Currency *currency) : QTreeWidgetItem(UserType), date(date_), value(value_), decimals(decimals_) { setText(0, QLocale().toString(date, QLocale::ShortFormat)); setText(1, currency->formatValue(value, decimals)); setTextAlignment(0, Qt::AlignRight | Qt::AlignVCenter); setTextAlignment(1, Qt::AlignRight | Qt::AlignVCenter); } bool QuotationListViewItem::operator<(const QTreeWidgetItem &i_pre) const { QuotationListViewItem *i = (QuotationListViewItem*) &i_pre; if(!treeWidget() || treeWidget()->sortColumn() == 0) { return date < i->date; } else { return value < i->value; } return QTreeWidgetItem::operator<(i_pre); } RefundDialog::RefundDialog(Transactions *trans, QWidget *parent, bool extra_parameters) : QDialog(parent), transaction(trans) { setModal(true); QVBoxLayout *box1 = new QVBoxLayout(this); QGridLayout *layout = new QGridLayout(); box1->addLayout(layout); int i = 0; layout->addWidget(new QLabel(tr("Date:"), this), i, 0); dateEdit = new EqonomizeDateEdit(this); dateEdit->setCalendarPopup(true); layout->addWidget(dateEdit, i, 1); i++; TransactionType t_type = TRANSACTION_TYPE_EXPENSE; Transaction *curtrans = NULL; if(trans->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { if(((MultiAccountTransaction*) trans)->category()->type() == ACCOUNT_TYPE_INCOMES) t_type = TRANSACTION_TYPE_INCOME; curtrans = ((MultiAccountTransaction*) trans)->at(0); } else if(trans->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE) { t_type = ((Transaction*) trans)->type(); curtrans = (Transaction*) trans; } if(t_type == TRANSACTION_TYPE_INCOME) setWindowTitle(tr("Repayment")); else setWindowTitle(tr("Refund")); if(t_type == TRANSACTION_TYPE_INCOME) layout->addWidget(new QLabel(tr("Cost:"), this), i, 0); else layout->addWidget(new QLabel(tr("Income:"), this), i, 0); valueEdit = new EqonomizeValueEdit(trans->value(), false, true, this, trans->budget()); valueEdit->setCurrency(trans->currency()); layout->addWidget(valueEdit, i, 1); i++; layout->addWidget(new QLabel(tr("Quantity returned:"), this), i, 0); quantityEdit = new EqonomizeValueEdit(trans->quantity(), QUANTITY_DECIMAL_PLACES, false, false, this, trans->budget()); layout->addWidget(quantityEdit, i, 1); i++; layout->addWidget(new QLabel(tr("Account:"), this), i, 0); accountCombo = new AccountComboBox(ACCOUNT_TYPE_ASSETS, trans->budget()); accountCombo->updateAccounts(); if(t_type == TRANSACTION_TYPE_EXPENSE) accountCombo->setCurrentAccount(((Expense*) curtrans)->from()); else if(t_type == TRANSACTION_TYPE_INCOME) accountCombo->setCurrentAccount(((Income*) curtrans)->to()); layout->addWidget(accountCombo, i, 1); i++; if(extra_parameters) layout->addWidget(new QLabel(t_type == TRANSACTION_TYPE_INCOME ? tr("Payee:") : tr("Payer:"), this), i, 0); payeeEdit = new QLineEdit(this); payeeEdit->setText(trans->payeeText()); layout->addWidget(payeeEdit, i, 1); if(!extra_parameters) payeeEdit->hide(); i++; layout->addWidget(new QLabel(tr("Comments:"), this), i, 0); commentsEdit = new QLineEdit(this); if(t_type == TRANSACTION_TYPE_INCOME) commentsEdit->setText(tr("Repayment")); else commentsEdit->setText(tr("Refund")); layout->addWidget(commentsEdit, i, 1); i++; joinGroup = new QButtonGroup(this); joinGroup_layout = new QHBoxLayout(); bool b_join = false; if(trans->generaltype() == GENERAL_TRANSACTION_TYPE_SCHEDULE || (trans->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT && ((SplitTransaction*) trans)->type() != SPLIT_TRANSACTION_TYPE_MULTIPLE_ACCOUNTS) || (trans->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE && ((Transaction*) trans)->parentSplit() && ((Transaction*) trans)->parentSplit()->type() != SPLIT_TRANSACTION_TYPE_MULTIPLE_ACCOUNTS)) { joinGroup_layout->setEnabled(false); } else { QSettings settings; settings.beginGroup("GeneralOptions"); b_join = settings.value("joinRefunds", false).toBool(); settings.endGroup(); } //: Link the transactions together QRadioButton *rb = new QRadioButton(tr("Link")); rb->setChecked(!b_join); joinGroup_layout->addWidget(rb); joinGroup->addButton(rb, 0); //: Join the transactions together rb = new QRadioButton(tr("Join")); rb->setChecked(b_join); connect(rb, SIGNAL(toggled(bool)), this, SLOT(joinToggled(bool))); joinGroup->addButton(rb, 1); joinGroup_layout->addWidget(rb); layout->addLayout(joinGroup_layout, i, 0, 1, 2, Qt::AlignRight); i++; connect(dateEdit, SIGNAL(returnPressed()), valueEdit, SLOT(enterFocus())); if(quantityEdit) { connect(valueEdit, SIGNAL(returnPressed()), quantityEdit, SLOT(enterFocus())); connect(quantityEdit, SIGNAL(returnPressed()), accountCombo, SLOT(focusAndSelectAll())); } else { connect(valueEdit, SIGNAL(returnPressed()), accountCombo, SLOT(focusAndSelectAll())); } connect(accountCombo, SIGNAL(accountSelected(Account*)), commentsEdit, SLOT(setFocus())); connect(accountCombo, SIGNAL(returnPressed()), this, SLOT(accountNextFocus())); connect(commentsEdit, SIGNAL(returnPressed()), this, SLOT(accept())); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, this); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept())); connect(accountCombo, SIGNAL(currentAccountChanged(Account*)), this, SLOT(accountActivated(Account*))); box1->addWidget(buttonBox); dateEdit->setFocus(); dateEdit->setCurrentSection(QDateTimeEdit::DaySection); } void RefundDialog::keyPressEvent(QKeyEvent *e) { if(e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) return; QDialog::keyPressEvent(e); } void RefundDialog::accountActivated(Account *account) { if(account) valueEdit->setCurrency(((AssetsAccount*) account)->currency()); } Transaction *RefundDialog::createRefund() { if(!validValues()) return NULL; Transaction *trans = NULL; AssetsAccount *account = NULL; if(accountCombo->currentData().isValid()) account = (AssetsAccount*) accountCombo->currentData().value(); if(transaction->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { trans = ((MultiAccountTransaction*) transaction)->at(0)->copy(); } else if(transaction->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE) { trans = (Transaction*) transaction->copy(); } if(trans->type() == TRANSACTION_TYPE_EXPENSE) ((Expense*) trans)->setFrom(account); else ((Income*) trans)->setTo(account); trans->setId(trans->budget()->getNewId()); trans->setFirstRevision(trans->budget()->revision()); trans->setTimestamp(QDateTime::currentMSecsSinceEpoch() / 1000); if(quantityEdit) trans->setQuantity(-quantityEdit->value()); else trans->setQuantity(0.0); trans->setValue(-valueEdit->value()); trans->setDate(dateEdit->date()); if(payeeEdit) { if(trans->type() == TRANSACTION_TYPE_EXPENSE) ((Expense*) trans)->setPayee(payeeEdit->text()); else ((Income*) trans)->setPayer(payeeEdit->text()); } if(commentsEdit->isEnabled()) trans->setComment(commentsEdit->text()); return trans; } bool RefundDialog::joinIsChecked() {return joinGroup->checkedId() == 1;} void RefundDialog::joinToggled(bool) {} void RefundDialog::accountNextFocus() { if(commentsEdit->isEnabled()) commentsEdit->setFocus(); else accept(); } void RefundDialog::accept() { if(validValues()) { if(joinGroup_layout->isEnabled()) { QSettings settings; settings.beginGroup("GeneralOptions"); settings.setValue("joinRefunds", joinGroup->checkedId() == 1); settings.endGroup(); } QDialog::accept(); } } bool RefundDialog::validValues() { if(valueEdit->value() == 0.0) { valueEdit->setFocus(); QMessageBox::critical(this, tr("Error"), tr("Zero value not allowed.")); return false; } if(!dateEdit->date().isValid()) { QMessageBox::critical(this, tr("Error"), tr("Invalid date.")); dateEdit->setFocus(); return false; } return true; } EditSecurityTradeDialog::EditSecurityTradeDialog(Budget *budg, Security *sec, QWidget *parent) : QDialog(parent), budget(budg) { setWindowTitle(tr("Securities Exchange", "Shares of one security directly exchanged for shares of another; Financial security (e.g. stock, mutual fund)")); setModal(true); QVBoxLayout *box1 = new QVBoxLayout(this); QGridLayout *layout = new QGridLayout(); box1->addLayout(layout); layout->addWidget(new QLabel(tr("From security:", "Financial security (e.g. stock, mutual fund)"), this), 0, 0); fromSecurityCombo = new EqonomizeComboBox(this); fromSecurityCombo->setEditable(false); bool sel = false; int i = 0; for(SecurityList::const_iterator it = budget->securities.constBegin(); it != budget->securities.constEnd(); ++it) { Security *c_sec = *it; fromSecurityCombo->addItem(c_sec->name(), QVariant::fromValue((void*) c_sec)); if(c_sec == sec) { fromSecurityCombo->setCurrentIndex(i); } else if(!sel && !sec) { for(SecurityList::const_iterator it2 = budget->securities.constBegin(); it2 != budget->securities.constEnd(); ++it2) { Security *c_sec2 = *it2; if(c_sec2 != c_sec && c_sec2->account() == c_sec->account()) { fromSecurityCombo->setCurrentIndex(i); sel = true; break; } } } i++; } layout->addWidget(fromSecurityCombo, 0, 1); layout->addWidget(new QLabel(tr("Shares moved:", "Financial shares"), this), 1, 0); QHBoxLayout *sharesLayout = new QHBoxLayout(); fromSharesEdit = new EqonomizeValueEdit(0.0, sec ? sec->shares() : 10000.0, 1.0, 0.0, sec ? sec->decimals() : 4, false, this, budget); fromSharesEdit->setSizePolicy(QSizePolicy::Expanding, fromSharesEdit->sizePolicy().verticalPolicy()); sharesLayout->addWidget(fromSharesEdit); QPushButton *maxSharesButton = new QPushButton(tr("All"), this); maxSharesButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); sharesLayout->addWidget(maxSharesButton); layout->addLayout(sharesLayout, 1, 1); fromSharesEdit->setFocus(); layout->addWidget(new QLabel(tr("To security:", "Financial security (e.g. stock, mutual fund)"), this), 2, 0); toSecurityCombo = new EqonomizeComboBox(this); toSecurityCombo->setEditable(false); layout->addWidget(toSecurityCombo, 2, 1); layout->addWidget(new QLabel(tr("Shares received:", "Financial shares"), this), 3, 0); toSharesEdit = new EqonomizeValueEdit(0.0, sec ? sec->decimals() : 4, false, false, this, budget); layout->addWidget(toSharesEdit, 3, 1); layout->addWidget(new QLabel(tr("Date:"), this), 5, 0); dateEdit = new EqonomizeDateEdit(this); dateEdit->setCalendarPopup(true); layout->addWidget(dateEdit, 5, 1); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, this); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept())); box1->addWidget(buttonBox); fromSecurityChanged(true); toSecurityChanged(); connect(fromSecurityCombo, SIGNAL(returnPressed()), fromSharesEdit, SLOT(enterFocus())); connect(fromSecurityCombo, SIGNAL(itemSelected(int)), fromSharesEdit, SLOT(enterFocus())); connect(fromSharesEdit, SIGNAL(returnPressed()), toSecurityCombo, SLOT(setFocus())); connect(toSecurityCombo, SIGNAL(returnPressed()), toSharesEdit, SLOT(enterFocus())); connect(toSecurityCombo, SIGNAL(itemSelected(int)), toSharesEdit, SLOT(enterFocus())); connect(toSharesEdit, SIGNAL(returnPressed()), this, SLOT(focusDate())); connect(dateEdit, SIGNAL(returnPressed()), this, SLOT(accept())); connect(maxSharesButton, SIGNAL(clicked()), this, SLOT(maxShares())); connect(fromSecurityCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(fromSecurityChanged())); connect(toSecurityCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(toSecurityChanged())); } void EditSecurityTradeDialog::keyPressEvent(QKeyEvent *e) { if(e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) return; QDialog::keyPressEvent(e); } void EditSecurityTradeDialog::focusDate() { if(!dateEdit) return; dateEdit->setFocus(); dateEdit->setCurrentSection(QDateTimeEdit::DaySection); } void EditSecurityTradeDialog::maxShares() { fromSharesEdit->setValue(fromSharesEdit->maximum()); } Security *EditSecurityTradeDialog::selectedFromSecurity() { if(!fromSecurityCombo->currentData().isValid()) return NULL; return (Security*) fromSecurityCombo->currentData().value(); } Security *EditSecurityTradeDialog::selectedToSecurity() { if(!toSecurityCombo->currentData().isValid()) return NULL; return (Security*) toSecurityCombo->currentData().value(); } void EditSecurityTradeDialog::fromSecurityChanged(bool in_init) { Security *sec = selectedFromSecurity(); toSecurityCombo->clear(); if(sec) { fromSharesEdit->setPrecision(sec->decimals()); fromSharesEdit->setMaximum(sec->shares()); Security *to_sec = selectedToSecurity(); int i = 0; for(SecurityList::const_iterator it = budget->securities.constBegin(); it != budget->securities.constEnd(); ++it) { Security *c_sec = *it; if(c_sec != sec && c_sec->account() == sec->account()) { toSecurityCombo->addItem(c_sec->name(), QVariant::fromValue((void*) c_sec)); if(c_sec == to_sec) { toSecurityCombo->setCurrentIndex(i); } } i++; } if(!in_init && !checkSecurities()) { fromSecurityCombo->setCurrentIndex(prev_from_index); } else { prev_from_index = fromSecurityCombo->currentIndex(); } } } void EditSecurityTradeDialog::toSecurityChanged() { Security *sec = selectedToSecurity(); if(sec) { toSharesEdit->setPrecision(sec->decimals()); } } void EditSecurityTradeDialog::setSecurityTrade(SecurityTrade *ts) { dateEdit->setDate(ts->date); int index = fromSecurityCombo->findData(QVariant::fromValue((void*) ts->from_security)); if(index >= 0) fromSecurityCombo->setCurrentIndex(index); fromSharesEdit->setMaximum(ts->from_security->shares() + ts->from_shares); fromSharesEdit->setValue(ts->from_shares); toSharesEdit->setValue(ts->to_shares); index = fromSecurityCombo->findData(QVariant::fromValue((void*) ts->to_security)); if(index >= 0) toSecurityCombo->setCurrentIndex(index); } SecurityTrade *EditSecurityTradeDialog::createSecurityTrade() { if(!validValues()) return NULL; return new SecurityTrade(dateEdit->date(), fromSharesEdit->value(), selectedFromSecurity(), toSharesEdit->value(), selectedToSecurity(), budget->getNewId(), budget->revision(), budget->revision()); } bool EditSecurityTradeDialog::checkSecurities() { if(toSecurityCombo->count() == 0) { QMessageBox::critical(isVisible() ? this : parentWidget(), tr("Error"), tr("No other security available for exchange in the account.", "Shares of one security directly exchanged for shares of another; Financial security (e.g. stock, mutual fund)")); return false; } return true; } void EditSecurityTradeDialog::accept() { if(validValues()) { QDialog::accept(); } } bool EditSecurityTradeDialog::validValues() { if(selectedFromSecurity() == selectedToSecurity()) { QMessageBox::critical(this, tr("Error"), tr("Selected to and from securities are the same.", "Financial security (e.g. stock, mutual fund)")); return false; } if(!dateEdit->date().isValid()) { QMessageBox::critical(this, tr("Error"), tr("Invalid date.")); return false; } if(fromSharesEdit->value() == 0.0 || toSharesEdit->value() == 0.0) { QMessageBox::critical(this, tr("Error"), tr("Zero shares not allowed.", "Financial shares")); return false; } return true; } EditQuotationsDialog::EditQuotationsDialog(Security *sec, QWidget *parent) : QDialog(parent), budget(sec->budget()), security(sec) { setWindowTitle(tr("Quotes", "Financial quote")); setModal(true); i_quotation_decimals = budget->defaultQuotationDecimals(); QVBoxLayout *quotationsVLayout = new QVBoxLayout(this); titleLabel = new QLabel(tr("Quotes", "Financial quote"), this); quotationsVLayout->addWidget(titleLabel); QHBoxLayout *quotationsLayout = new QHBoxLayout(); quotationsVLayout->addLayout(quotationsLayout); quotationsView = new QTreeWidget(this); quotationsView->setSortingEnabled(true); quotationsView->sortByColumn(0, Qt::DescendingOrder); quotationsView->setAllColumnsShowFocus(true); quotationsView->setColumnCount(2); quotationsView->setAlternatingRowColors(true); QStringList headers; headers << tr("Date"); headers << tr("Price per Share", "Financial Shares"); quotationsView->header()->setStretchLastSection(true); quotationsView->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContentsOnFirstShow); quotationsView->setHeaderLabels(headers); setColumnDateWidth(quotationsView, 0); setColumnMoneyWidth(quotationsView, 1, budget); quotationsView->setRootIsDecorated(false); quotationsView->header()->setSectionsClickable(false); QSizePolicy sp = quotationsView->sizePolicy(); sp.setHorizontalPolicy(QSizePolicy::MinimumExpanding); quotationsView->setSizePolicy(sp); quotationsLayout->addWidget(quotationsView); QVBoxLayout *buttonsLayout = new QVBoxLayout(); quotationsLayout->addLayout(buttonsLayout); quotationEdit = new EqonomizeValueEdit(0.0, pow(10, -i_quotation_decimals), 0.0, i_quotation_decimals, true, this, budget); buttonsLayout->addWidget(quotationEdit); dateEdit = new EqonomizeDateEdit(this); dateEdit->setCalendarPopup(true); dateEdit->setDate(QDate::currentDate()); buttonsLayout->addWidget(dateEdit); addButton = new QPushButton(tr("Add"), this); buttonsLayout->addWidget(addButton); changeButton = new QPushButton(tr("Modify"), this); changeButton->setEnabled(false); buttonsLayout->addWidget(changeButton); deleteButton = new QPushButton(tr("Delete"), this); deleteButton->setEnabled(false); buttonsLayout->addWidget(deleteButton); buttonsLayout->addSpacing(12); QPushButton *importButton = new QPushButton(tr("Import…"), this); buttonsLayout->addWidget(importButton); QPushButton *exportButton = new QPushButton(tr("Export…"), this); buttonsLayout->addWidget(exportButton); buttonsLayout->addSpacing(18); buttonsLayout->addStretch(1); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, this); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept())); quotationsVLayout->addWidget(buttonBox); connect(quotationsView, SIGNAL(itemSelectionChanged()), this, SLOT(onSelectionChanged())); connect(addButton, SIGNAL(clicked()), this, SLOT(addQuotation())); connect(changeButton, SIGNAL(clicked()), this, SLOT(changeQuotation())); connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteQuotation())); connect(importButton, SIGNAL(clicked()), this, SLOT(importQuotations())); connect(exportButton, SIGNAL(clicked()), this, SLOT(exportQuotations())); setSecurity(security); } void EditQuotationsDialog::setSecurity(Security *sec) { security = sec; quotationsView->clear(); i_quotation_decimals = security->quotationDecimals(); QList items; QMap::const_iterator it_end = security->quotations.end(); for(QMap::const_iterator it = security->quotations.constBegin(); it != it_end; ++it) { items.append(new QuotationListViewItem(it.key(), it.value(), i_quotation_decimals, security->currency())); } quotationsView->addTopLevelItems(items); quotationsView->setSortingEnabled(true); titleLabel->setText(tr("Quotes for %1", "Financial quote").arg(security->name())); quotationEdit->setRange(0.0, pow(10, -i_quotation_decimals), i_quotation_decimals); quotationEdit->setCurrency(security->currency(), true); if(items.isEmpty()) quotationsView->setMinimumWidth(quotationsView->columnWidth(0) + quotationsView->columnWidth(1) + 10); } void EditQuotationsDialog::modifyQuotations() { security->quotations.clear(); QTreeWidgetItemIterator it(quotationsView); QuotationListViewItem *i = (QuotationListViewItem*) *it; while(i) { security->quotations[i->date] = i->value; security->quotations_auto[i->date] = false; ++it; i = (QuotationListViewItem*) *it; } } QString htmlize_string(QString str) { str.replace('<', "<"); str.replace('>', ">"); str.replace('&', "&"); str.replace('\"', """); return str; } struct q_csv_info { int value_format; char separator; bool p1, p2, p3, p4, ly; int lz; }; extern QDate readCSVDate(const QString &str, const QString &date_format, const QString &alt_date_format); extern double readCSVValue(const QString &str, int value_format, bool *ok); extern void testCSVDate(const QString &str, bool &p1, bool &p2, bool &p3, bool &p4, bool &ly, char &separator, int &lz); extern void testCSVValue(const QString &str, int &value_format); bool EditQuotationsDialog::import(QString url, bool test, q_csv_info *ci) { QString date_format, alt_date_format; if(test) { ci->p1 = true; ci->p2 = true; ci->p3 = true; ci->p4 = true; ci->ly = true; ci->lz = -1; ci->value_format = 0; ci->separator = -1; } else { if(ci->p1) { date_format += ci->lz == 0 ? "M" : "MM"; if(ci->separator > 0) date_format += ci->separator; date_format += ci->lz == 0 ? "d" : "dd"; if(ci->separator > 0) date_format += ci->separator; if(ci->ly) { date_format += "yyyy"; } else { if(ci->separator > 0) { alt_date_format = date_format; alt_date_format += '\''; alt_date_format += "yy"; } date_format += "yy"; } } else if(ci->p2) { date_format += ci->lz == 0 ? "d" : "dd"; if(ci->separator > 0) date_format += ci->separator; date_format += ci->lz == 0 ? "M" : "MM"; if(ci->separator > 0) date_format += ci->separator; if(ci->ly) { date_format += "yyyy"; } else { if(ci->separator > 0) { alt_date_format = date_format; alt_date_format += '\''; alt_date_format += "yy"; } date_format += "yy"; } } else if(ci->p3) { if(ci->ly) date_format += "yyyy"; else date_format += "yy"; if(ci->separator > 0) date_format += ci->separator; date_format += ci->lz == 0 ? "M" : "MM"; if(ci->separator > 0) date_format += ci->separator; date_format += ci->lz == 0 ? "d" : "dd"; } else if(ci->p4) { if(ci->ly) date_format += "yyyy"; else date_format += "yy"; if(ci->separator > 0) date_format += ci->separator; date_format += ci->lz == 0 ? "d" : "dd"; if(ci->separator > 0) date_format += ci->separator; date_format += ci->lz == 0 ? "M" : "MM"; } } int first_row = 0; QString delimiter = ","; int date_c = 1; int value_c = 2; int min_columns = 2; double value = 0.0; QDate date; QFile file(url); if(!file.open(QIODevice::ReadOnly) ) { QMessageBox::critical(this, tr("Error"), tr("Couldn't open %1 for reading.").arg(url)); return false; } else if(!file.size()) { QMessageBox::critical(this, tr("Error"), tr("Error reading %1.").arg(url)); return false; } QFileInfo fileInfo(url); last_document_directory = fileInfo.absoluteDir().absolutePath(); QTextStream fstream(&file); #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) fstream.setCodec("UTF-8"); #endif int row = 0; QString line = fstream.readLine(); int successes = 0; int failed = 0; bool missing_columns = false, value_error = false, date_error = false; while(!line.isNull()) { row++; if((first_row == 0 && !line.isEmpty() && line[0] != '#') || (first_row > 0 && row >= first_row && !line.isEmpty())) { #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) QStringList columns = line.split(delimiter, Qt::KeepEmptyParts); #else QStringList columns = line.split(delimiter, QString::KeepEmptyParts); #endif for(QStringList::Iterator it = columns.begin(); it != columns.end(); ++it) { int i = 0; while(i < (int) (*it).length() && ((*it)[i] == ' ' || (*it)[i] == '\t')) { i++; } if(!(*it).isEmpty() && (*it)[i] == '\"') { (*it).remove(0, i + 1); i = (*it).length() - 1; while(i > 0 && ((*it)[i] == ' ' || (*it)[i] == '\t')) { i--; } if(i >= 0 && (*it)[i] == '\"') { (*it).truncate(i); } else { QStringList::Iterator it2 = it; ++it2; while(it2 != columns.end()) { i = (*it2).length() - 1; while(i > 0 && ((*it2)[i] == ' ' || (*it2)[i] == '\t')) { i--; } if(i >= 0 && (*it2)[i] == '\"') { (*it2).truncate(i); *it += delimiter; *it += *it2; it2 = columns.erase(it2); it = it2; it--; break; } *it += delimiter; *it += *it2; it2 = columns.erase(it2); it = it2; it--; } } } *it = (*it).trimmed(); } if((int) columns.count() < min_columns) { if(first_row != 0) { missing_columns = true; failed++; } } else { bool success = true; if(success) { bool ok = true; if(first_row == 0) { ok = false; QString &str = columns[value_c - 1]; int l = (int) str.length(); for(int i = 0; i < l; i++) { if(str[i].isDigit()) { ok = true; break; } } } if(!ok) { failed--; success = false; } else if(test) { if(ci->value_format <= 0) testCSVValue(columns[value_c - 1], ci->value_format); } else { value = readCSVValue(columns[value_c - 1], ci->value_format, &ok); if(!ok) { if(first_row == 0) failed--; else value_error = true; success = false; } } } if(success) { bool ok = true; if(first_row == 0) { ok = false; QString &str = columns[date_c - 1]; for(int i = 0; i < (int) str.length(); i++) { if(str[i].isDigit()) { ok = true; break; } } } if(!ok) { failed--; success = false; } else if(test) { if(ci->p1 + ci->p2 + ci->p3 + ci->p4 > 1 || ci->lz < 0) testCSVDate(columns[date_c - 1], ci->p1, ci->p2, ci->p3, ci->p4, ci->ly, ci->separator, ci->lz); } else { date = readCSVDate(columns[date_c - 1], date_format, alt_date_format); if(!date.isValid()) { if(first_row == 0) failed--; else date_error = true; success = false; } } } if(success && first_row == 0) first_row = row; if(test && ci->p1 + ci->p2 + ci->p3 + ci->p4 < 2 && ci->lz >= 0 && ci->value_format > 0) break; if(test) success = false; if(success) { QTreeWidgetItemIterator it(quotationsView); QuotationListViewItem *i = (QuotationListViewItem*) *it; bool found = false; while(i) { if(i->date == date) { i->value = value; i->setText(1, security->currency()->formatValue(i->value, i->decimals)); found = true; break; } ++it; i = (QuotationListViewItem*) *it; } if(!found) quotationsView->insertTopLevelItem(0, new QuotationListViewItem(date, value, i_quotation_decimals, security->currency())); successes++; } else { failed++; } } } line = fstream.readLine(); } file.close(); if(test) { return true; } QString info = "", details = ""; if(successes > 0) { info = tr("Successfully imported %n quote(s).", "", successes); } else { info = tr("Unable to import any quotes."); } if(failed > 0) { info += '\n'; info += tr("Failed to import %n data row(s).", "", failed); if(missing_columns) {details += "\n-"; details += tr("Required columns missing.");} if(value_error) {details += "\n-"; details += tr("Invalid value.");} if(date_error) {details += "\n-"; details += tr("Invalid date.");} } else if(successes == 0) { info = tr("No data found."); } if(failed > 0 || successes == 0) { QMessageBox::critical(this, tr("Error"), info + details); } else { QMessageBox::information(this, tr("Information"), info); } quotationsView->setSortingEnabled(true); return successes > 0; } void EditQuotationsDialog::importQuotations() { QMimeDatabase db; QString url = QFileDialog::getOpenFileName(this, QString(), last_document_directory + "/", db.mimeTypeForName("text/csv").filterString()); if(url.isEmpty()) return; QFileInfo fileInfo(url); last_document_directory = fileInfo.absoluteDir().absolutePath(); q_csv_info ci; if(!import(url, true, &ci)) return; int ps = ci.p1 + ci.p2 + ci.p3 + ci.p4; if(ps == 0) { QMessageBox::critical(this, tr("Error"), tr("Unrecognized date format.")); return; } if(ci.value_format < 0 || ps > 1) { QDialog *dialog = new QDialog(this); dialog->setWindowTitle(tr("Specify Format")); dialog->setModal(true); QVBoxLayout *box1 = new QVBoxLayout(dialog); QGridLayout *grid = new QGridLayout(); box1->addLayout(grid); QLabel *label = new QLabel(tr("The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format."), dialog); label->setWordWrap(true); grid->addWidget(label, 0, 0, 1, 2); QComboBox *dateFormatCombo = NULL; if(ps > 1) { grid->addWidget(new QLabel(tr("Date format:"), dialog), 1, 0); dateFormatCombo = new QComboBox(dialog); dateFormatCombo->setEditable(false); if(ci.p1) { QString date_format = ci.lz == 0 ? "M" : "MM";; if(ci.separator > 0) date_format += ci.separator; date_format += ci.lz == 0 ? "D" : "DD"; if(ci.separator > 0) date_format += ci.separator; date_format += "YY"; if(ci.ly) date_format += "YY"; dateFormatCombo->addItem(date_format); } if(ci.p2) { QString date_format = ci.lz == 0 ? "D" : "DD"; if(ci.separator > 0) date_format += ci.separator; date_format += ci.lz == 0 ? "M" : "MM"; if(ci.separator > 0) date_format += ci.separator; date_format += "YY"; if(ci.ly) date_format += "YY"; dateFormatCombo->addItem(date_format); } if(ci.p3) { QString date_format = "YY"; if(ci.ly) date_format += "YY"; if(ci.separator > 0) date_format += ci.separator; date_format += ci.lz == 0 ? "M" : "MM"; if(ci.separator > 0) date_format += ci.separator; date_format += ci.lz == 0 ? "D" : "DD"; dateFormatCombo->addItem(date_format); } if(ci.p4) { QString date_format = "YY"; if(ci.ly) date_format += "YY"; if(ci.separator > 0) date_format += ci.separator; date_format += ci.lz == 0 ? "D" : "DD"; if(ci.separator > 0) date_format += ci.separator; date_format += ci.lz == 0 ? "M" : "MM"; dateFormatCombo->addItem(date_format); } grid->addWidget(dateFormatCombo, 1, 1); } QComboBox *valueFormatCombo = NULL; if(ci.value_format < 0) { grid->addWidget(new QLabel(tr("Value format:"), dialog), ps > 1 ? 2 : 1, 0); valueFormatCombo = new QComboBox(dialog); valueFormatCombo->setEditable(false); valueFormatCombo->addItem("1,000,000.00"); valueFormatCombo->addItem("1.000.000,00"); grid->addWidget(valueFormatCombo, ps > 1 ? 2 : 1, 1); } QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, dialog); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), dialog, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), dialog, SLOT(accept())); box1->addWidget(buttonBox); if(dialog->exec() != QDialog::Accepted) { return; } if(ps > 1) { bool p1 = false, p2 = false, p3 = false, p4 = false; int p[4]; int i = 0; if(ci.p1) {p[i] = 1; i++;} if(ci.p2) {p[i] = 2; i++;} if(ci.p3) {p[i] = 3; i++;} if(ci.p4) {p[i] = 4; i++;} switch(p[dateFormatCombo->currentIndex()]) { case 1: {p1 = true; break;} case 2: {p2 = true; break;} case 3: {p3 = true; break;} case 4: {p4 = true; break;} } ci.p1 = p1; ci.p2 = p2; ci.p3 = p3; ci.p4 = p4; if(ci.lz < 0) ci.lz = 1; } if(ci.value_format < 0) ci.value_format = valueFormatCombo->currentIndex() + 1; dialog->deleteLater(); } import(url, false, &ci); } void EditQuotationsDialog::onFilterSelected(QString filter) { QMimeDatabase db; QFileDialog *fileDialog = qobject_cast(sender()); if(filter == db.mimeTypeForName("text/csv").filterString()) { fileDialog->setDefaultSuffix(db.mimeTypeForName("text/csv").preferredSuffix()); } else { fileDialog->setDefaultSuffix(db.mimeTypeForName("text/html").preferredSuffix()); } } void EditQuotationsDialog::exportQuotations() { char filetype = 'h'; QMimeDatabase db; QString html_filter = db.mimeTypeForName("text/html").filterString(); QString csv_filter = db.mimeTypeForName("text/csv").filterString(); QFileDialog fileDialog(this); fileDialog.setNameFilters(QStringList(csv_filter) << html_filter); fileDialog.selectNameFilter(html_filter); fileDialog.setDefaultSuffix(db.mimeTypeForName("text/csv").preferredSuffix()); fileDialog.setAcceptMode(QFileDialog::AcceptSave); #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) fileDialog.setSupportedSchemes(QStringList("file")); #endif fileDialog.setDirectory(last_document_directory); connect(&fileDialog, SIGNAL(filterSelected(QString)), this, SLOT(onFilterSelected(QString))); QString url; if(!fileDialog.exec()) return; QStringList urls = fileDialog.selectedFiles(); if(urls.isEmpty()) return; url = urls[0]; if((fileDialog.selectedNameFilter() == csv_filter || db.mimeTypeForFile(url, QMimeDatabase::MatchExtension) == db.mimeTypeForName("text/csv")) && db.mimeTypeForFile(url, QMimeDatabase::MatchExtension) != db.mimeTypeForName("text/html")) filetype = 'c'; QSaveFile ofile(url); ofile.open(QIODevice::WriteOnly); if(!ofile.isOpen()) { ofile.cancelWriting(); QMessageBox::critical(this, tr("Error"), tr("Couldn't open file for writing.")); return; } last_document_directory = fileDialog.directory().absolutePath(); QTextStream outf(&ofile); switch(filetype) { case 'h': { #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) outf.setCodec("UTF-8"); #endif outf << "" << '\n'; outf << "" << '\n'; outf << "\t" << '\n'; outf << "\t\t"; outf << htmlize_string(tr("Quotes: %1").arg(security->name())); outf << "" << '\n'; outf << "\t\t" << '\n'; outf << "\t\tapplicationDisplayName() << "\">" << '\n'; outf << "\t" << '\n'; outf << "\t" << '\n'; outf << "\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t\t" << '\n'; QTreeWidgetItem *header = quotationsView->headerItem(); outf << "\t\t\t\t\t"; outf << ""; outf << ""; outf << "\n"; outf << "\t\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; QTreeWidgetItemIterator it(quotationsView); QuotationListViewItem *i = (QuotationListViewItem*) *it; while(i) { outf << "\t\t\t\t" << '\n'; outf << "\t\t\t\t\t"; outf << ""; outf << ""; outf << "\n"; outf << "\t\t\t\t" << '\n'; ++it; i = (QuotationListViewItem*) *it; } outf << "\t\t\t" << '\n'; outf << "\t\t
    "; outf << htmlize_string(tr("Quotes: %1").arg(security->name())); outf << "
    " << htmlize_string(header->text(0)) << "" << htmlize_string(header->text(1)) << "
    " << htmlize_string(QLocale().toString(i->date, QLocale::ShortFormat)) << "" << htmlize_string(security->currency()->formatValue(i->value, security->quotationDecimals())) << "
    " << '\n'; outf << "\t" << '\n'; outf << "" << '\n'; break; } case 'c': { //outf.setEncoding(Q3TextStream::Locale); QTreeWidgetItem *header = quotationsView->headerItem(); outf << "\"" << header->text(0) << "\",\"" << header->text(1); outf << "\"\n"; QTreeWidgetItemIterator it(quotationsView); QuotationListViewItem *i = (QuotationListViewItem*) *it; while(i) { outf << "\"" << QLocale().toString(i->date, QLocale::ShortFormat) << "\",\"" << budget->formatValue(i->value, security->quotationDecimals()) << "\"\n"; ++it; i = (QuotationListViewItem*) *it; } break; } } if(!ofile.commit()) { QMessageBox::critical(this, tr("Error"), tr("Error while writing file; file was not saved.")); return; } } void EditQuotationsDialog::onSelectionChanged() { QuotationListViewItem *i = (QuotationListViewItem*) selectedItem(quotationsView); if(i) { changeButton->setEnabled(true); deleteButton->setEnabled(true); dateEdit->setDate(i->date); quotationEdit->setValue(i->value); } else { changeButton->setEnabled(false); deleteButton->setEnabled(false); } } void EditQuotationsDialog::addQuotation() { QDate date = dateEdit->date(); if(!date.isValid()) { QMessageBox::critical(this, tr("Error"), tr("Invalid date.")); return; } QTreeWidgetItemIterator it(quotationsView); QuotationListViewItem *i = (QuotationListViewItem*) *it; while(i) { if(i->date == date) { i->value = quotationEdit->value(); i->setText(1, security->currency()->formatValue(i->value, i->decimals)); return; } ++it; i = (QuotationListViewItem*) *it; } quotationsView->insertTopLevelItem(0, new QuotationListViewItem(date, quotationEdit->value(), i_quotation_decimals, security->currency())); quotationsView->setSortingEnabled(true); } void EditQuotationsDialog::changeQuotation() { QuotationListViewItem *i = (QuotationListViewItem*) selectedItem(quotationsView); if(i == NULL) return; QDate date = dateEdit->date(); if(!date.isValid()) { QMessageBox::critical(this, tr("Error"), tr("Invalid date.")); return; } QTreeWidgetItemIterator it(quotationsView); QuotationListViewItem *i2 = (QuotationListViewItem*) *it; while(i2) { if(i2->date == date) { i2->value = quotationEdit->value(); i2->setText(1, security->currency()->formatValue(i2->value, i2->decimals)); return; } ++it; i2 = (QuotationListViewItem*) *it; } i->date = date; i->value = quotationEdit->value(); i->setText(0, QLocale().toString(date, QLocale::ShortFormat)); i->setText(1, security->currency()->formatValue(i->value, i->decimals)); } void EditQuotationsDialog::deleteQuotation() { QuotationListViewItem *i = (QuotationListViewItem*) selectedItem(quotationsView); if(i == NULL) return; delete i; } OverTimeReportDialog::OverTimeReportDialog(Budget *budg, QWidget *parent) : QDialog(parent, Qt::Window | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint) { setWindowTitle(tr("Report")); setModal(false); QVBoxLayout *box1 = new QVBoxLayout(this); report = new OverTimeReport(budg, this); box1->addWidget(report); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); buttonBox->button(QDialogButtonBox::Close)->setAutoDefault(false); connect(buttonBox->button(QDialogButtonBox::Close), SIGNAL(clicked()), this, SLOT(reject())); box1->addWidget(buttonBox); } void OverTimeReportDialog::reject() { report->saveConfig(); QDialog::reject(); } CategoriesComparisonReportDialog::CategoriesComparisonReportDialog(bool extra_parameters, Budget *budg, QWidget *parent) : QDialog(parent, Qt::Window | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint) { setWindowTitle(tr("Report")); setModal(false); QVBoxLayout *box1 = new QVBoxLayout(this); report = new CategoriesComparisonReport(budg, this, extra_parameters); box1->addWidget(report); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); buttonBox->button(QDialogButtonBox::Close)->setAutoDefault(false); connect(buttonBox->button(QDialogButtonBox::Close), SIGNAL(clicked()), this, SLOT(reject())); box1->addWidget(buttonBox); } void CategoriesComparisonReportDialog::reject() { report->saveConfig(); QDialog::reject(); } OverTimeChartDialog::OverTimeChartDialog(bool extra_parameters, Budget *budg, QWidget *parent) : QDialog(parent, Qt::Window | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint) { setWindowTitle(tr("Chart")); setModal(false); QVBoxLayout *box1 = new QVBoxLayout(this); chart = new OverTimeChart(budg, this, extra_parameters); box1->addWidget(chart); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); buttonBox->button(QDialogButtonBox::Close)->setAutoDefault(false); connect(buttonBox->button(QDialogButtonBox::Close), SIGNAL(clicked()), this, SLOT(reject())); box1->addWidget(buttonBox); } void OverTimeChartDialog::reject() { chart->saveConfig(); QDialog::reject(); } CategoriesComparisonChartDialog::CategoriesComparisonChartDialog(Budget *budg, QWidget *parent) : QDialog(parent, Qt::Window | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint) { setWindowTitle(tr("Chart")); setModal(false); QVBoxLayout *box1 = new QVBoxLayout(this); chart = new CategoriesComparisonChart(budg, this); box1->addWidget(chart); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); buttonBox->button(QDialogButtonBox::Close)->setAutoDefault(false); connect(buttonBox->button(QDialogButtonBox::Close), SIGNAL(clicked()), this, SLOT(reject())); box1->addWidget(buttonBox); } void CategoriesComparisonChartDialog::reject() { chart->saveConfig(); QDialog::reject(); } ConfirmScheduleDialog::ConfirmScheduleDialog(bool extra_parameters, Budget *budg, QWidget *parent, QString title, bool allow_account_creation) : QDialog(parent), budget(budg), b_extra(extra_parameters), b_create_accounts(allow_account_creation) { setWindowTitle(title); setModal(true); QVBoxLayout *box1 = new QVBoxLayout(this); //box1->setSizeConstraint(QLayout::SetFixedSize); QLabel *label = new QLabel(tr("The following transactions was scheduled to occur today or before today.\nConfirm that they have indeed occurred (or will occur today)."), this); box1->addWidget(label); QHBoxLayout *box2 = new QHBoxLayout(); box1->addLayout(box2); transactionsView = new EqonomizeTreeWidget(this); transactionsView->sortByColumn(0, Qt::AscendingOrder); transactionsView->setAllColumnsShowFocus(true); transactionsView->setColumnCount(4); QStringList headers; headers << tr("Date"); headers << tr("Type"); headers << tr("Description", "Transaction description property (transaction title/generic article name)"); headers << tr("Amount"); transactionsView->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContentsOnFirstShow); transactionsView->setHeaderLabels(headers); setColumnDateWidth(transactionsView, 0); setColumnStrlenWidth(transactionsView, 1, 15); setColumnStrlenWidth(transactionsView, 2, 25); setColumnMoneyWidth(transactionsView, 3, budget); transactionsView->setRootIsDecorated(false); QSizePolicy sp = transactionsView->sizePolicy(); sp.setHorizontalPolicy(QSizePolicy::MinimumExpanding); transactionsView->setSizePolicy(sp); box2->addWidget(transactionsView); QDialogButtonBox *buttons = new QDialogButtonBox(Qt::Vertical, this); editButton = buttons->addButton(tr("Edit…"), QDialogButtonBox::ActionRole); editButton->setEnabled(false); postponeButton = buttons->addButton(tr("Postpone…"), QDialogButtonBox::ActionRole); postponeButton->setEnabled(false); removeButton = buttons->addButton(tr("Delete"), QDialogButtonBox::ActionRole); removeButton->setEnabled(false); box2->addWidget(buttons); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept())); box1->addWidget(buttonBox); connect(transactionsView, SIGNAL(itemSelectionChanged()), this, SLOT(transactionSelectionChanged())); connect(removeButton, SIGNAL(clicked()), this, SLOT(remove())); connect(editButton, SIGNAL(clicked()), this, SLOT(edit())); connect(postponeButton, SIGNAL(clicked()), this, SLOT(postpone())); updateTransactions(); } void ConfirmScheduleDialog::transactionSelectionChanged() { QTreeWidgetItem *i = selectedItem(transactionsView); if(i == NULL) { editButton->setEnabled(false); removeButton->setEnabled(false); postponeButton->setEnabled(false); } else { editButton->setEnabled(true); removeButton->setEnabled(true); postponeButton->setEnabled(true); } } void ConfirmScheduleDialog::remove() { QTreeWidgetItem *i = selectedItem(transactionsView); if(i == NULL) return; Transactions *trans = ((ConfirmScheduleListViewItem*) i)->transaction(); delete trans; delete i; if(transactionsView->topLevelItemCount() == 0) reject(); } void ConfirmScheduleDialog::postpone() { QTreeWidgetItem *i = selectedItem(transactionsView); if(i == NULL) return; QDialog *dialog = new QDialog(this); dialog->setWindowTitle(tr("Date")); QVBoxLayout *box1 = new QVBoxLayout(dialog); QCalendarWidget *datePicker = new QCalendarWidget(dialog); datePicker->setSelectedDate(QDate::currentDate().addDays(1)); box1->addWidget(datePicker); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, dialog); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), dialog, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), dialog, SLOT(accept())); box1->addWidget(buttonBox); if(dialog->exec() == QDialog::Accepted) { if(datePicker->selectedDate() > QDate::currentDate()) { Transactions *trans = ((ConfirmScheduleListViewItem*) i)->transaction(); trans->setDate(datePicker->selectedDate()); budget->addScheduledTransaction(new ScheduledTransaction(budget, trans, NULL)); delete i; } else { QMessageBox::critical(this, tr("Error"), tr("Can only postpone to future dates.")); } } dialog->deleteLater(); if(transactionsView->topLevelItemCount() == 0) reject(); } void ConfirmScheduleDialog::edit() { QTreeWidgetItem *i = selectedItem(transactionsView); if(i == NULL) return; Transactions *transs = ((ConfirmScheduleListViewItem*) i)->transaction(); Security *security = NULL; if(transs->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE) { Transaction *trans = (Transaction*) transs; if(trans->type() == TRANSACTION_TYPE_SECURITY_BUY || trans->type() == TRANSACTION_TYPE_SECURITY_SELL) { security = ((SecurityTransaction*) trans)->security(); } else if(trans->type() == TRANSACTION_TYPE_INCOME && ((Income*) trans)->security()) { security = ((Income*) trans)->security(); } TransactionEditDialog *dialog = new TransactionEditDialog(b_extra, trans->type(), NULL, false, security, SECURITY_ALL_VALUES, security != NULL, budget, this, b_create_accounts); dialog->editWidget->updateAccounts(); dialog->editWidget->setTransaction(trans); //if(trans->type() == TRANSACTION_TYPE_SECURITY_SELL) dialog->editWidget->setMaxSharesDate(QDate::currentDate()); if(dialog->editWidget->checkAccounts() && dialog->exec() == QDialog::Accepted) { if(dialog->editWidget->modifyTransaction(trans)) { if(trans->date() > QDate::currentDate()) { budget->addScheduledTransaction(new ScheduledTransaction(budget, trans, NULL)); delete i; } else { ((ConfirmScheduleListViewItem*) i)->setTransaction(trans); } } } dialog->deleteLater(); } else if(transs->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { if(((SplitTransaction*) transs)->type() == SPLIT_TRANSACTION_TYPE_MULTIPLE_ITEMS) { MultiItemTransaction *split = (MultiItemTransaction*) transs; EditMultiItemDialog *dialog = new EditMultiItemDialog(budget, this, NULL, b_extra, b_create_accounts); dialog->editWidget->setTransaction(split); if(dialog->editWidget->checkAccounts() && dialog->exec() == QDialog::Accepted) { MultiItemTransaction *split_new = dialog->editWidget->createTransaction(); if(split_new) { delete split; if(split_new->date() > QDate::currentDate()) { budget->addScheduledTransaction(new ScheduledTransaction(budget, split_new, NULL)); delete i; } else { ((ConfirmScheduleListViewItem*) i)->setTransaction(split_new); } } } dialog->deleteLater(); } else if(((SplitTransaction*) transs)->type() == SPLIT_TRANSACTION_TYPE_MULTIPLE_ACCOUNTS) { MultiAccountTransaction *split = (MultiAccountTransaction*) transs; EditMultiAccountDialog *dialog = new EditMultiAccountDialog(budget, this, split->transactiontype() == TRANSACTION_TYPE_EXPENSE, b_extra, b_create_accounts); dialog->editWidget->setTransaction(split); if(dialog->editWidget->checkAccounts() && dialog->exec() == QDialog::Accepted) { MultiAccountTransaction *split_new = dialog->editWidget->createTransaction(); if(split_new) { delete split; if(split_new->date() > QDate::currentDate()) { budget->addScheduledTransaction(new ScheduledTransaction(budget, split_new, NULL)); delete i; } else { ((ConfirmScheduleListViewItem*) i)->setTransaction(split_new); } } } dialog->deleteLater(); } else if(((SplitTransaction*) transs)->type() == SPLIT_TRANSACTION_TYPE_LOAN) { DebtPayment *split = (DebtPayment*) transs; EditDebtPaymentDialog *dialog = new EditDebtPaymentDialog(budget, this, NULL, b_create_accounts); dialog->editWidget->setTransaction(split); if(dialog->editWidget->checkAccounts() && dialog->exec() == QDialog::Accepted) { DebtPayment *split_new = dialog->editWidget->createTransaction(); if(split_new) { delete split; if(split_new->date() > QDate::currentDate()) { budget->addScheduledTransaction(new ScheduledTransaction(budget, split_new, NULL)); delete i; } else { ((ConfirmScheduleListViewItem*) i)->setTransaction(split_new); } } } dialog->deleteLater(); } } if(transactionsView->topLevelItemCount() == 0) reject(); } void ConfirmScheduleDialog::updateTransactions() { QSettings settings; settings.beginGroup("GeneralOptions"); QTime confirm_time = settings.value("scheduleConfirmationTime", QTime(18, 0)).toTime(); settings.endGroup(); for(ScheduledTransactionList::iterator it = budget->scheduledTransactions.begin(); it != budget->scheduledTransactions.end();) { ScheduledTransaction *strans = *it; if(strans->firstOccurrence() < QDate::currentDate() || (QTime::currentTime() >= confirm_time && strans->firstOccurrence() == QDate::currentDate())) { bool b = strans->isOneTimeTransaction(); Transactions *trans = strans->realize(strans->firstOccurrence()); if(trans) { new ConfirmScheduleListViewItem(transactionsView, trans); } if(b) budget->removeScheduledTransaction(strans); else strans->setModified(); it = budget->scheduledTransactions.begin(); } else { ++it; } } transactionsView->setSortingEnabled(true); QTreeWidgetItemIterator qit(transactionsView); QTreeWidgetItem *i = *qit; if(i) i->setSelected(true); } Transactions *ConfirmScheduleDialog::firstTransaction() { current_index = 0; ConfirmScheduleListViewItem *current_item = (ConfirmScheduleListViewItem*) transactionsView->topLevelItem(current_index); if(current_item) return current_item->transaction(); return NULL; } Transactions *ConfirmScheduleDialog::nextTransaction() { current_index++; ConfirmScheduleListViewItem *current_item = (ConfirmScheduleListViewItem*) transactionsView->topLevelItem(current_index); if(current_item) return current_item->transaction(); return NULL; } SecurityTransactionsDialog::SecurityTransactionsDialog(Security *sec, Eqonomize *parent, QString title) : QDialog(parent), security(sec), mainWin(parent) { setWindowTitle(title); setModal(true); QVBoxLayout *box1 = new QVBoxLayout(this); box1->addWidget(new QLabel(tr("Transactions for %1").arg(security->name()), this)); QHBoxLayout *box2 = new QHBoxLayout(); box1->addLayout(box2); transactionsView = new EqonomizeTreeWidget(this); transactionsView->sortByColumn(0, Qt::DescendingOrder); transactionsView->setAllColumnsShowFocus(true); transactionsView->setColumnCount(4); QStringList headers; headers << tr("Date"); headers << tr("Type"); headers << tr("Value"); headers << tr("Shares", "Financial shares"); transactionsView->setHeaderLabels(headers); setColumnDateWidth(transactionsView, 0); setColumnStrlenWidth(transactionsView, 1, 25); setColumnMoneyWidth(transactionsView, 2, security->budget()); setColumnValueWidth(transactionsView, 3, 999999.99, 4, security->budget()); if(security->transactions.isEmpty()) transactionsView->setMinimumWidth(transactionsView->columnWidth(0) + transactionsView->columnWidth(1) + transactionsView->columnWidth(2) + transactionsView->columnWidth(3) + 10); else transactionsView->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContentsOnFirstShow); transactionsView->setRootIsDecorated(false); QSizePolicy sp = transactionsView->sizePolicy(); sp.setHorizontalPolicy(QSizePolicy::MinimumExpanding); transactionsView->setSizePolicy(sp); box2->addWidget(transactionsView); QDialogButtonBox *buttons = new QDialogButtonBox(Qt::Vertical, this); editButton = buttons->addButton(tr("Edit…"), QDialogButtonBox::ActionRole); editButton->setEnabled(false); removeButton = buttons->addButton(tr("Delete"), QDialogButtonBox::ActionRole); removeButton->setEnabled(false); box2->addWidget(buttons); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); buttonBox->button(QDialogButtonBox::Close)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Close), SIGNAL(clicked()), this, SLOT(reject())); box1->addWidget(buttonBox); connect(transactionsView, SIGNAL(itemSelectionChanged()), this, SLOT(transactionSelectionChanged())); connect(transactionsView, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(edit(QTreeWidgetItem*))); connect(removeButton, SIGNAL(clicked()), this, SLOT(remove())); connect(editButton, SIGNAL(clicked()), this, SLOT(edit())); updateTransactions(); } void SecurityTransactionsDialog::transactionSelectionChanged() { QTreeWidgetItem *i = selectedItem(transactionsView); if(i == NULL) { editButton->setEnabled(false); removeButton->setEnabled(false); } else { editButton->setEnabled(true); removeButton->setEnabled(true); } } void SecurityTransactionsDialog::remove() { SecurityTransactionListViewItem *i = (SecurityTransactionListViewItem*) selectedItem(transactionsView); if(i == NULL) return; if(i->trans) { SecurityTransaction *trans = i->trans; security->budget()->removeTransaction(trans, true); mainWin->transactionRemoved(trans, NULL, true); delete trans; } else if(i->div) { Income *div = i->div; security->budget()->removeTransaction(div, true); mainWin->transactionRemoved(div, NULL, true); delete div; } else if(i->rediv) { ReinvestedDividend *rediv = i->rediv; security->budget()->removeTransaction(rediv, true); mainWin->transactionRemoved(rediv, NULL, true); delete rediv; } else if(i->strans) { ScheduledTransaction *strans = i->strans; security->budget()->removeScheduledTransaction(strans, true); mainWin->transactionRemoved(strans, NULL, true); delete strans; } else if(i->sdiv) { ScheduledTransaction *sdiv = i->sdiv; security->budget()->removeScheduledTransaction(sdiv, true); mainWin->transactionRemoved(sdiv, NULL, true); delete sdiv; } else if(i->srediv) { ScheduledTransaction *srediv = i->srediv; security->budget()->removeScheduledTransaction(srediv, true); mainWin->transactionRemoved(srediv, NULL, true); delete srediv; } else if(i->ts) { SecurityTrade *ts = i->ts; security->budget()->removeSecurityTrade(ts, true); mainWin->updateSecurity(ts->from_security); mainWin->updateSecurity(ts->to_security); mainWin->updateSecurityAccount(ts->from_security->account()); if(ts->to_security->account() != ts->from_security->account()) { mainWin->updateSecurityAccount(ts->to_security->account()); } mainWin->setModified(true); delete ts; } delete i; } void SecurityTransactionsDialog::edit() { edit(selectedItem(transactionsView)); } void SecurityTransactionsDialog::edit(QTreeWidgetItem *i_pre) { if(i_pre == NULL) return; SecurityTransactionListViewItem *i = (SecurityTransactionListViewItem*) i_pre; bool b = false; if(i->trans) b = mainWin->editTransaction(i->trans, this); else if(i->div) b = mainWin->editTransaction(i->div, this); else if(i->rediv) b = mainWin->editTransaction(i->rediv, this); else if(i->strans) b = mainWin->editScheduledTransaction(i->strans, this); else if(i->sdiv) b = mainWin->editScheduledTransaction(i->sdiv, this); else if(i->srediv) b = mainWin->editScheduledTransaction(i->srediv, this); else if(i->ts) b = mainWin->editSecurityTrade(i->ts, this); if(b) updateTransactions(); } void SecurityTransactionsDialog::updateTransactions() { transactionsView->clear(); QList items; Budget *budget = security->budget(); for(SecurityTransactionList::const_iterator it = security->transactions.constBegin(); it != security->transactions.constEnd(); ++it) { SecurityTransaction *trans = *it; SecurityTransactionListViewItem *i = new SecurityTransactionListViewItem(QLocale().toString(trans->date(), QLocale::ShortFormat), QString(), trans->valueString(), budget->formatValue(trans->shares(), security->decimals())); i->trans = trans; i->date = trans->date(); i->value = trans->value(); i->shares = trans->shares(); if(trans->type() == TRANSACTION_TYPE_SECURITY_BUY) i->setText(1, tr("Shares Bought", "Financial shares")); else i->setText(1, tr("Shares Sold", "Financial shares")); items.append(i); } for(SecurityTransactionList::const_iterator it = security->dividends.constBegin(); it != security->dividends.constEnd(); ++it) { Income *div = *it; SecurityTransactionListViewItem *i = new SecurityTransactionListViewItem(QLocale().toString(div->date(), QLocale::ShortFormat), tr("Dividend"), div->valueString(), "-"); i->div = div; i->date = div->date(); i->value = div->value(); items.append(i); } for(SecurityTransactionList::const_iterator it = security->reinvestedDividends.constBegin(); it != security->reinvestedDividends.constEnd(); ++it) { ReinvestedDividend *rediv = *it; SecurityTransactionListViewItem *i = new SecurityTransactionListViewItem(QLocale().toString(rediv->date(), QLocale::ShortFormat), tr("Reinvested Dividend"), rediv->valueString(), budget->formatValue(rediv->shares(), security->decimals())); i->rediv = rediv; i->date = rediv->date(); i->shares = rediv->shares(); i->value = rediv->value(); items.append(i); } for(TradedSharesList::const_iterator it = security->tradedShares.constBegin(); it != security->tradedShares.constEnd(); ++it) { SecurityTrade *ts = *it; double shares; double ts_value; if(ts->from_security == security) { shares = ts->from_shares; } else { shares = ts->to_shares; } ts_value = shares * security->getQuotation(ts->date); SecurityTransactionListViewItem *i = new SecurityTransactionListViewItem(QLocale().toString(ts->date, QLocale::ShortFormat), ts->from_security == security ? tr("Shares Sold (Exchanged)", "Shares of one security directly exchanged for shares of another; Financial shares") : tr("Shares Bought (Exchanged)", "Shares of one security directly exchanged for shares of another; Financial shares"), security->currency()->formatValue(ts_value), budget->formatValue(shares, security->decimals())); i->ts = ts; i->date = ts->date; i->shares = shares; i->value = ts_value; items.append(i); } for(ScheduledSecurityTransactionList::const_iterator it = security->scheduledTransactions.constBegin(); it != security->scheduledTransactions.constEnd(); ++it) { ScheduledTransaction *strans = *it; SecurityTransactionListViewItem *i = new SecurityTransactionListViewItem(QLocale().toString(strans->date(), QLocale::ShortFormat), QString(), strans->transaction()->valueString(), budget->formatValue(((SecurityTransaction*) strans->transaction())->shares(), security->decimals())); i->strans = strans; i->date = strans->date(); i->value = strans->transaction()->value(); i->shares = ((SecurityTransaction*) strans->transaction())->shares(); if(strans->recurrence()) { if(strans->transactiontype() == TRANSACTION_TYPE_SECURITY_BUY) i->setText(1, tr("Shares Bought (Recurring)", "Financial shares")); else i->setText(1, tr("Shares Sold (Recurring)", "Financial shares")); } else { if(strans->transactiontype() == TRANSACTION_TYPE_SECURITY_BUY) i->setText(1, tr("Shares Bought (Scheduled)", "Financial shares")); else i->setText(1, tr("Shares Sold (Scheduled)", "Financial shares")); } items.append(i); } for(ScheduledSecurityTransactionList::const_iterator it = security->scheduledDividends.constBegin(); it != security->scheduledDividends.constEnd(); ++it) { ScheduledTransaction *strans = *it; SecurityTransactionListViewItem *i = new SecurityTransactionListViewItem(QLocale().toString(strans->date(), QLocale::ShortFormat), QString(), strans->transaction()->valueString(), "-"); i->srediv = strans; i->date = strans->date(); i->value = strans->transaction()->value(); if(strans->recurrence()) { i->setText(1, tr("Dividend (Recurring)")); } else { i->setText(1, tr("Dividend (Scheduled)")); } items.append(i); } for(ScheduledSecurityTransactionList::const_iterator it = security->scheduledReinvestedDividends.constBegin(); it != security->scheduledReinvestedDividends.constEnd(); ++it) { ScheduledTransaction *strans = *it; SecurityTransactionListViewItem *i = new SecurityTransactionListViewItem(QLocale().toString(strans->date(), QLocale::ShortFormat), QString(), strans->transaction()->valueString(), budget->formatValue(((ReinvestedDividend*) strans->transaction())->shares(), security->decimals())); i->sdiv = strans; i->date = strans->date(); i->value = strans->transaction()->value(); i->shares = ((ReinvestedDividend*) strans->transaction())->shares(); if(strans->recurrence()) { i->setText(1, tr("Reinvested Dividend (Recurring)")); } else { i->setText(1, tr("Reinvested Dividend (Scheduled)")); } items.append(i); } transactionsView->addTopLevelItems(items); transactionsView->setSortingEnabled(true); } EditSecurityDialog::EditSecurityDialog(Budget *budg, QWidget *parent, QString title, bool allow_account_creation) : QDialog(parent), budget(budg), b_create_accounts(allow_account_creation) { setWindowTitle(title); setModal(true); QVBoxLayout *box1 = new QVBoxLayout(this); QGridLayout *grid = new QGridLayout(); box1->addLayout(grid); grid->addWidget(new QLabel(tr("Type:"), this), 0, 0); typeCombo = new QComboBox(this); typeCombo->setEditable(false); typeCombo->addItem(tr("Mutual Fund")); typeCombo->addItem(tr("Stock", "Financial stock")); typeCombo->addItem(tr("Other")); grid->addWidget(typeCombo, 0, 1); typeCombo->setFocus(); grid->addWidget(new QLabel(tr("Name:"), this), 1, 0); nameEdit = new QLineEdit(this); grid->addWidget(nameEdit, 1, 1); grid->addWidget(new QLabel(tr("Account:"), this), 2, 0); accountCombo = new AccountComboBox(ASSETS_TYPE_SECURITIES, budget, b_create_accounts, false, false, false, true, this); accountCombo->updateAccounts(); grid->addWidget(accountCombo, 2, 1); grid->addWidget(new QLabel(tr("Decimals in shares:", "Financial shares"), this), 3, 0); decimalsEdit = new QSpinBox(this); decimalsEdit->setRange(0, 8); decimalsEdit->setSingleStep(1); decimalsEdit->setValue(budget->defaultShareDecimals()); grid->addWidget(decimalsEdit, 3, 1); grid->addWidget(new QLabel(tr("Initial shares:", "Financial shares"), this), 4, 0); sharesEdit = new EqonomizeValueEdit(0.0, budget->defaultShareDecimals(), false, false, this, budget); grid->addWidget(sharesEdit, 4, 1); grid->addWidget(new QLabel(tr("Decimals in quotes:", "Financial quote"), this), 5, 0); quotationDecimalsEdit = new QSpinBox(this); quotationDecimalsEdit->setRange(0, 8); quotationDecimalsEdit->setSingleStep(1); quotationDecimalsEdit->setValue(budget->defaultQuotationDecimals()); grid->addWidget(quotationDecimalsEdit, 5, 1); quotationLabel = new QLabel(tr("Initial quote:", "Financial quote"), this); grid->addWidget(quotationLabel, 6, 0); quotationEdit = new EqonomizeValueEdit(false, this, budget); quotationDecimalsChanged(budget->defaultQuotationDecimals()); grid->addWidget(quotationEdit, 6, 1); quotationDateLabel = new QLabel(tr("Date:"), this); grid->addWidget(quotationDateLabel, 7, 0); quotationDateEdit = new EqonomizeDateEdit(QDate::currentDate(), this); quotationDateEdit->setCalendarPopup(true); grid->addWidget(quotationDateEdit, 7, 1); grid->addWidget(new QLabel(tr("Description:"), this), 8, 0); descriptionEdit = new QTextEdit(this); grid->addWidget(descriptionEdit, 9, 0, 1, 2); nameEdit->setFocus(); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, this); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept())); box1->addWidget(buttonBox); if(accountCombo->currentAccount()) accountActivated(accountCombo->currentAccount()); connect(decimalsEdit, SIGNAL(valueChanged(int)), this, SLOT(decimalsChanged(int))); connect(quotationDecimalsEdit, SIGNAL(valueChanged(int)), this, SLOT(quotationDecimalsChanged(int))); connect(accountCombo, SIGNAL(currentAccountChanged(Account*)), this, SLOT(accountActivated(Account*))); connect(accountCombo, SIGNAL(newAccountRequested()), this, SLOT(newAccount())); } void EditSecurityDialog::accept() { if(!checkAccount()) return; if(!accountCombo->currentAccount()) return; if(nameEdit->text().trimmed().isEmpty()) { nameEdit->setFocus(); QMessageBox::critical(this, tr("Error"), tr("Empty name.")); return; } QDialog::accept(); } void EditSecurityDialog::newAccount() { accountCombo->createAccount(); } void EditSecurityDialog::accountActivated(Account *account) { quotationEdit->setCurrency(account ? ((AssetsAccount*) account)->currency() : budget->defaultCurrency(), true); } bool EditSecurityDialog::checkAccount() { if(!accountCombo->hasAccount()) { QMessageBox::critical(isVisible() ? this : parentWidget(), tr("Error"), tr("No suitable account available.")); return false; } return true; } void EditSecurityDialog::decimalsChanged(int i) { sharesEdit->setPrecision(i); } void EditSecurityDialog::quotationDecimalsChanged(int i) { quotationEdit->setRange(0.0, pow(10, -i), i); } Security *EditSecurityDialog::newSecurity() { if(!checkAccount()) return NULL; SecurityType type; switch(typeCombo->currentIndex()) { case 1: {type = SECURITY_TYPE_STOCK; break;} case 2: {type = SECURITY_TYPE_OTHER; break;} default: {type = SECURITY_TYPE_MUTUAL_FUND; break;} } Security *security = new Security(budget, (AssetsAccount*) accountCombo->currentAccount(), type, sharesEdit->value(), decimalsEdit->value(), quotationDecimalsEdit->value(), nameEdit->text(), descriptionEdit->toPlainText()); if(quotationEdit->value() > 0.0) { security->setQuotation(quotationDateEdit->date(), quotationEdit->value()); } return security; } bool EditSecurityDialog::modifySecurity(Security *security) { if(!checkAccount()) return false; security->setName(nameEdit->text()); security->setInitialShares(sharesEdit->value()); security->setDescription(descriptionEdit->toPlainText()); security->setAccount((AssetsAccount*) accountCombo->currentAccount()); security->setDecimals(decimalsEdit->value()); security->setQuotationDecimals(quotationDecimalsEdit->value()); switch(typeCombo->currentIndex()) { case 1: {security->setType(SECURITY_TYPE_STOCK); break;} case 2: {security->setType(SECURITY_TYPE_OTHER); break;} default: {security->setType(SECURITY_TYPE_MUTUAL_FUND); break;} } return true; } void EditSecurityDialog::setSecurity(Security *security) { nameEdit->setText(security->name()); quotationEdit->hide(); quotationDateEdit->hide(); quotationLabel->hide(); quotationDateLabel->hide(); descriptionEdit->setPlainText(security->description()); decimalsEdit->setValue(security->decimals()); decimalsChanged(security->decimals()); quotationDecimalsEdit->setValue(security->quotationDecimals()); quotationDecimalsChanged(security->quotationDecimals()); sharesEdit->setValue(security->initialShares()); accountCombo->setCurrentAccount(security->account()); switch(security->type()) { case SECURITY_TYPE_BOND: {typeCombo->setCurrentIndex(2); break;} case SECURITY_TYPE_STOCK: {typeCombo->setCurrentIndex(1); break;} case SECURITY_TYPE_OTHER: {typeCombo->setCurrentIndex(2); break;} default: {typeCombo->setCurrentIndex(0); break;} } } class TotalListViewItem : public QTreeWidgetItem { public: TotalListViewItem(QTreeWidget *parent, QString label1, QString label2 = QString(), QString label3 = QString(), QString label4 = QString()) : QTreeWidgetItem(parent, UserType) { setText(0, label1); setText(1, label2); setText(2, label3); setText(3, label4); setTextAlignment(BUDGET_COLUMN, Qt::AlignRight | Qt::AlignVCenter); setTextAlignment(CHANGE_COLUMN, Qt::AlignRight | Qt::AlignVCenter); setTextAlignment(VALUE_COLUMN, Qt::AlignRight | Qt::AlignVCenter); /*setBackground(0, parent->viewport()->palette().alternateBase()); setBackground(1, parent->viewport()->palette().alternateBase()); setBackground(2, parent->viewport()->palette().alternateBase()); setBackground(3, parent->viewport()->palette().alternateBase());*/ } TotalListViewItem(QTreeWidget *parent, QTreeWidgetItem *after, QString label1, QString label2 = QString(), QString label3 = QString(), QString label4 = QString()) : QTreeWidgetItem(parent, after, UserType) { setText(0, label1); setText(1, label2); setText(2, label3); setText(3, label4); setTextAlignment(BUDGET_COLUMN, Qt::AlignRight | Qt::AlignVCenter); setTextAlignment(CHANGE_COLUMN, Qt::AlignRight | Qt::AlignVCenter); setTextAlignment(VALUE_COLUMN, Qt::AlignRight | Qt::AlignVCenter); /*setBackground(0, parent->palette().alternateBase()); setBackground(1, parent->palette().alternateBase()); setBackground(2, parent->palette().alternateBase()); setBackground(3, parent->palette().alternateBase());*/ } }; class AccountsListView : public EqonomizeTreeWidget { public: AccountsListView(QWidget *parent) : EqonomizeTreeWidget(parent) { setContentsMargins(25, 25, 25, 25); } }; Eqonomize::Eqonomize() : QMainWindow() { mainwin = this; in_batch_edit = false; clicked_item = NULL; link_trans = NULL; expenses_budget = 0.0; expenses_budget_diff = 0.0; incomes_budget = 0.0; incomes_budget_diff = 0.0; incomes_accounts_value = 0.0; incomes_accounts_change = 0.0; expenses_accounts_value = 0.0; expenses_accounts_change = 0.0; assets_accounts_value = 0.0; assets_accounts_change = 0.0; total_value = 0.0; total_cost = 0.0; total_profit = 0.0; total_rate = 0.0; helpDialog = NULL; cccDialog = NULL; ccrDialog = NULL; otcDialog = NULL; otrDialog = NULL; syncDialog = NULL; currencyConversionWindow = NULL; last_picture_directory = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation); last_document_directory = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); last_associated_file_directory = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); partial_budget = false; modified = false; modified_auto_save = false; budget = new Budget(); setWindowTitle(tr("Untitled") + "[*]"); QSettings settings; settings.beginGroup("GeneralOptions"); if(settings.value("darkMode", false).toBool()) updatePalette(true); QString sfont = settings.value("font").toString(); if(!sfont.isEmpty()) { QFont font; font.fromString(sfont); qApp->processEvents(); if(font.family() == qApp->font().family() && font.pointSize() == qApp->font().pointSize() && font.pixelSize() == qApp->font().pixelSize() && font.overline() == qApp->font().overline() && font.stretch() == qApp->font().stretch() && font.letterSpacing() == qApp->font().letterSpacing() && font.underline() == qApp->font().underline() && font.style() == qApp->font().style() && font.weight() == qApp->font().weight()) { settings.remove("font"); } else { qApp->setFont(font); } } b_extra = settings.value("useExtraProperties", true).toBool(); int initial_period = settings.value("initialPeriod", int(0)).toInt(); if(initial_period < 0 || initial_period > 4) initial_period = 0; right_align_values = settings.value("GeneralOptions/rightAlignValues", true).toBool(); bool b_uerftd = settings.value("useExchangeRateForTransactionDate", false).toBool(); budget->setDefaultTransactionConversionRateDate(b_uerftd ? TRANSACTION_CONVERSION_RATE_AT_DATE : TRANSACTION_CONVERSION_LATEST_RATE); prev_cur_date = QDate::currentDate(); QDate curdate = prev_cur_date; bool from_enabled = true; switch(initial_period) { case 0: { from_date = budget->firstBudgetDay(curdate); to_date = curdate; break; } case 1: { from_date = budget->firstBudgetDayOfYear(curdate); to_date = curdate; break; } case 2: { from_date = budget->firstBudgetDay(curdate); to_date = budget->lastBudgetDay(curdate); break; } case 3: { from_date = budget->firstBudgetDayOfYear(curdate); to_date = from_date.addDays(curdate.daysInYear() - 1); break; } case 4: { from_date = QDate::fromString(settings.value("initialFromDate").toString(), Qt::ISODate); if(!from_date.isValid()) from_date = budget->firstBudgetDay(curdate); from_enabled = settings.value("initialFromDateEnabled", false).toBool(); to_date = QDate::fromString(settings.value("initialToDate").toString(), Qt::ISODate); if(!to_date.isValid()) to_date = from_date.addDays(from_date.daysInMonth() - 1); break; } } frommonth_begin = budget->firstBudgetDay(from_date); prevmonth_begin = budget->firstBudgetDay(to_date); budget->addBudgetMonthsSetFirst(prevmonth_begin, -1); setAcceptDrops(true); QWidget *w_top = new QWidget(this); setCentralWidget(w_top); QVBoxLayout *topLayout = new QVBoxLayout(w_top); tabs = new QTabWidget(w_top); topLayout->addWidget(tabs); tabs->setDocumentMode(true); tabs->setIconSize(tabs->iconSize() * 1.5); accounts_page = new QWidget(this); tabs->addTab(accounts_page, LOAD_ICON("eqz-account"), tr("Accounts && Categories")); expenses_page = new QWidget(this); tabs->addTab(expenses_page, LOAD_ICON("eqz-expense"), tr("Expenses")); incomes_page = new QWidget(this); tabs->addTab(incomes_page, LOAD_ICON("eqz-income"), tr("Incomes")); transfers_page = new QWidget(this); tabs->addTab(transfers_page, LOAD_ICON("eqz-transfer"), tr("Transfers")); securities_page = new QWidget(this); tabs->addTab(securities_page, LOAD_ICON("eqz-security"), tr("Securities", "Financial security (e.g. stock, mutual fund)")); schedule_page = new QWidget(this); tabs->addTab(schedule_page, LOAD_ICON("eqz-schedule"), tr("Schedule")); connect(tabs, SIGNAL(currentChanged(int)), this, SLOT(onPageChange(int))); QVBoxLayout *accountsLayout = new QVBoxLayout(accounts_page); accountsLayout->setContentsMargins(0, 0, 0, 0); QVBoxLayout *accountsLayoutView = new QVBoxLayout(); accountsLayout->addLayout(accountsLayoutView); accountsView = new AccountsListView(accounts_page); accountsView->setSortingEnabled(false); accountsView->setAllColumnsShowFocus(true); accountsView->setColumnCount(4); QStringList accountsViewHeaders; accountsViewHeaders << tr("Account / Category"); accountsViewHeaders << tr("Remaining Budget"); //: Noun, how much the account balance has changed accountsViewHeaders << tr("Change"); accountsViewHeaders << tr("Total"); accountsView->setHeaderLabels(accountsViewHeaders); accountsView->setRootIsDecorated(false); accountsView->header()->setSectionsClickable(false); accountsView->header()->setStretchLastSection(false); accountsView->setDragDropMode(QAbstractItemView::InternalMove); accountsView->setDragEnabled(true); QSizePolicy sp = accountsView->sizePolicy(); sp.setVerticalPolicy(QSizePolicy::MinimumExpanding); accountsView->setSizePolicy(sp); QFontMetrics fm(accountsView->font()); accountsView->header()->setSectionResizeMode(QHeaderView::Fixed); accountsView->header()->setSectionResizeMode(0, QHeaderView::Stretch); setColumnTextWidth(accountsView, BUDGET_COLUMN, tr("%2 of %1", "%1: budget; %2: remaining budget").arg(budget->formatMoney(99999999.99)).arg(budget->formatMoney(99999999.99))); setColumnMoneyWidth(accountsView, CHANGE_COLUMN, budget, 999999999999.99); setColumnMoneyWidth(accountsView, VALUE_COLUMN, budget, 999999999999.99); assetsItem = new TotalListViewItem(accountsView, tr("Assets"), QString(), budget->formatMoney(0.0), budget->formatMoney(0.0) + " "); assetsItem->setIcon(0, LOAD_ICON("eqz-account")); liabilitiesItem = new TotalListViewItem(accountsView, assetsItem, tr("Liabilities"), QString(), budget->formatMoney(0.0), budget->formatMoney(0.0) + " "); liabilitiesItem->setIcon(0, LOAD_ICON("eqz-liabilities")); incomesItem = new TotalListViewItem(accountsView, liabilitiesItem, tr("Incomes"), "-", budget->formatMoney(0.0), budget->formatMoney(0.0) + " "); incomesItem->setIcon(0, LOAD_ICON("eqz-income")); expensesItem = new TotalListViewItem(accountsView, incomesItem, tr("Expenses"), "-", budget->formatMoney(0.0), budget->formatMoney(0.0) + " "); expensesItem->setIcon(0, LOAD_ICON("eqz-expense")); tagsItem = new TotalListViewItem(accountsView, expensesItem, tr("Tags"), "", "", ""); tagsItem->setIcon(0, LOAD_ICON2("tag", "eqz-tag")); assetsItem->setFlags(assetsItem->flags() & ~Qt::ItemIsDragEnabled); assetsItem->setFlags(assetsItem->flags() & ~Qt::ItemIsDropEnabled); liabilitiesItem->setFlags(liabilitiesItem->flags() & ~Qt::ItemIsDragEnabled); liabilitiesItem->setFlags(liabilitiesItem->flags() & ~Qt::ItemIsDropEnabled); expensesItem->setFlags(expensesItem->flags() & ~Qt::ItemIsDragEnabled); incomesItem->setFlags(incomesItem->flags() & ~Qt::ItemIsDragEnabled); tagsItem->setFlags(tagsItem->flags() & ~Qt::ItemIsDropEnabled); QFont itemfont = assetsItem->font(0); itemfont.setWeight(QFont::DemiBold); assetsItem->setFont(0, itemfont); liabilitiesItem->setFont(0, itemfont); incomesItem->setFont(0, itemfont); expensesItem->setFont(0, itemfont); tagsItem->setFont(0, itemfont); assetsItem->setFont(1, itemfont); liabilitiesItem->setFont(1, itemfont); incomesItem->setFont(1, itemfont); expensesItem->setFont(1, itemfont); tagsItem->setFont(1, itemfont); assetsItem->setFont(2, itemfont); liabilitiesItem->setFont(2, itemfont); incomesItem->setFont(2, itemfont); expensesItem->setFont(2, itemfont); tagsItem->setFont(2, itemfont); assetsItem->setFont(3, itemfont); liabilitiesItem->setFont(3, itemfont); incomesItem->setFont(3, itemfont); expensesItem->setFont(3, itemfont); tagsItem->setFont(3, itemfont); accountsLayoutView->addWidget(accountsView); QHBoxLayout *accountsLayoutFooter = new QHBoxLayout(); accountsLayoutView->addLayout(accountsLayoutFooter); accountsLayoutFooter->addStretch(1); footer1 = new QLabel(QString("* ") + tr("Includes budgeted transactions"), accounts_page); accountsLayoutFooter->addWidget(footer1); footer1->hide(); accountsTabs = new QTabWidget(accounts_page); accountsTabs->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); QWidget *periodWidget = new QWidget(accounts_page); accountsTabs->addTab(periodWidget, tr("Period")); QVBoxLayout *accountsPeriodLayout = new QVBoxLayout(periodWidget); QHBoxLayout *accountsPeriodLayout2 = new QHBoxLayout(); accountsPeriodLayout->addLayout(accountsPeriodLayout2); accountsPeriodFromButton = new QCheckBox(tr("From"), periodWidget); accountsPeriodFromButton->setChecked(from_enabled); accountsPeriodLayout2->addWidget(accountsPeriodFromButton); accountsPeriodFromEdit = new EqonomizeDateEdit(periodWidget); accountsPeriodFromEdit->setCalendarPopup(true); accountsPeriodFromEdit->setDate(from_date); accountsPeriodFromEdit->setEnabled(true); sp = accountsPeriodFromEdit->sizePolicy(); sp.setHorizontalPolicy(QSizePolicy::Expanding); accountsPeriodFromEdit->setSizePolicy(sp); accountsPeriodLayout2->addWidget(accountsPeriodFromEdit); accountsPeriodLayout2->addWidget(new QLabel(tr("To"), periodWidget)); accountsPeriodToEdit = new EqonomizeDateEdit(periodWidget); accountsPeriodToEdit->setCalendarPopup(true); accountsPeriodToEdit->setDate(to_date); accountsPeriodToEdit->setEnabled(true); accountsPeriodToEdit->setSizePolicy(sp); accountsPeriodLayout2->addWidget(accountsPeriodToEdit); QHBoxLayout *accountsPeriodLayout3 = new QHBoxLayout(); accountsPeriodLayout->addLayout(accountsPeriodLayout3); QPushButton *prevYearButton = new QPushButton(LOAD_ICON("eqz-previous-year"), "", periodWidget); accountsPeriodLayout2->addWidget(prevYearButton); QPushButton *prevMonthButton = new QPushButton(LOAD_ICON("eqz-previous-month"), "", periodWidget); accountsPeriodLayout2->addWidget(prevMonthButton); QPushButton *nextMonthButton = new QPushButton(LOAD_ICON("eqz-next-month"), "", periodWidget); accountsPeriodLayout2->addWidget(nextMonthButton); QPushButton *nextYearButton = new QPushButton(LOAD_ICON("eqz-next-year"), "", periodWidget); accountsPeriodLayout2->addWidget(nextYearButton); QPushButton *accountsPeriodButton = new QPushButton(tr("Select Period"), periodWidget); QMenu *accountsPeriodMenu = new QMenu(this); ActionAP_1 = accountsPeriodMenu->addAction(tr("Current Month")); ActionAP_2 = accountsPeriodMenu->addAction(tr("Current Year")); ActionAP_3 = accountsPeriodMenu->addAction(tr("Current Whole Month")); ActionAP_4 = accountsPeriodMenu->addAction(tr("Current Whole Year")); ActionAP_5 = accountsPeriodMenu->addAction(tr("Whole Past Month")); ActionAP_6 = accountsPeriodMenu->addAction(tr("Whole Past Year")); ActionAP_7 = accountsPeriodMenu->addAction(tr("Previous Month")); ActionAP_8 = accountsPeriodMenu->addAction(tr("Previous Year")); accountsPeriodButton->setMenu(accountsPeriodMenu); accountsPeriodLayout3->addWidget(accountsPeriodButton); partialBudgetButton = new QCheckBox(tr("Show partial budget"), periodWidget); accountsPeriodLayout3->addWidget(partialBudgetButton); accountsPeriodLayout3->addStretch(1); QWidget *budgetWidget = new QWidget(accounts_page); accountsTabs->addTab(budgetWidget, tr("Edit Budget")); QVBoxLayout *budgetLayout = new QVBoxLayout(budgetWidget); QHBoxLayout *budgetLayout2 = new QHBoxLayout(); budgetLayout->addLayout(budgetLayout2); budgetButton = new QCheckBox(tr("Budget:"), budgetWidget); budgetButton->setChecked(false); budgetLayout2->addWidget(budgetButton); budgetEdit = new EqonomizeValueEdit(false, budgetWidget, budget); budgetEdit->setEnabled(false); sp = budgetEdit->sizePolicy(); sp.setHorizontalPolicy(QSizePolicy::Expanding); budgetEdit->setSizePolicy(sp); budgetEdit->setFocus(); budgetLayout2->addWidget(budgetEdit); budgetLayout2->addWidget(new QLabel(tr("Month:"), budgetWidget)); budgetMonthEdit = new EqonomizeMonthSelector(budgetWidget); sp = budgetMonthEdit->sizePolicy(); sp.setHorizontalPolicy(QSizePolicy::Expanding); budgetMonthEdit->setSizePolicy(sp); budgetLayout2->addWidget(budgetMonthEdit); QHBoxLayout *budgetLayout3 = new QHBoxLayout(); budgetLayout->addLayout(budgetLayout3); budgetLayout3->addWidget(new QLabel(tr("Result previous month:"), budgetWidget)); prevMonthBudgetLabel = new QLabel("-", budgetWidget); budgetLayout3->addWidget(prevMonthBudgetLabel); budgetLayout3->addStretch(1); accountsLayout->addWidget(accountsTabs); accountPopupMenu = NULL; assetsPopupMenu = NULL; tagPopupMenu = NULL; connect(budgetMonthEdit, SIGNAL(dateChanged(const QDate&)), this, SLOT(budgetMonthChanged(const QDate&))); connect(budgetEdit, SIGNAL(valueChanged(double)), this, SLOT(budgetChanged(double))); connect(budgetEdit, SIGNAL(returnPressed()), this, SLOT(budgetEditReturnPressed())); connect(budgetButton, SIGNAL(toggled(bool)), this, SLOT(budgetToggled(bool))); connect(budgetButton, SIGNAL(toggled(bool)), budgetEdit, SLOT(setEnabled(bool))); connect(partialBudgetButton, SIGNAL(toggled(bool)), this, SLOT(setPartialBudget(bool))); connect(accountsPeriodMenu, SIGNAL(triggered(QAction*)), this, SLOT(periodSelected(QAction*))); connect(prevMonthButton, SIGNAL(clicked()), this, SLOT(prevMonth())); connect(nextMonthButton, SIGNAL(clicked()), this, SLOT(nextMonth())); connect(prevYearButton, SIGNAL(clicked()), this, SLOT(prevYear())); connect(nextYearButton, SIGNAL(clicked()), this, SLOT(nextYear())); connect(accountsPeriodFromButton, SIGNAL(toggled(bool)), accountsPeriodFromEdit, SLOT(setEnabled(bool))); connect(accountsPeriodFromButton, SIGNAL(toggled(bool)), this, SLOT(filterAccounts())); connect(accountsPeriodFromEdit, SIGNAL(dateChanged(const QDate&)), this, SLOT(accountsPeriodFromChanged(const QDate&))); connect(accountsPeriodToEdit, SIGNAL(dateChanged(const QDate&)), this, SLOT(accountsPeriodToChanged(const QDate&))); connect(accountsView, SIGNAL(itemSelectionChanged()), this, SLOT(accountsSelectionChanged())); connect(accountsView, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT(accountClicked(QTreeWidgetItem*, int))); connect(accountsView, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(accountExecuted(QTreeWidgetItem*, int))); connect(accountsView, SIGNAL(returnPressed(QTreeWidgetItem*)), this, SLOT(accountExecuted(QTreeWidgetItem*))); connect(accountsView, SIGNAL(itemMoved(QTreeWidgetItem*, QTreeWidgetItem*)), this, SLOT(accountMoved(QTreeWidgetItem*, QTreeWidgetItem*))); accountsView->setContextMenuPolicy(Qt::CustomContextMenu); connect(accountsView, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(popupAccountsMenu(const QPoint&))); connect(accountsView, SIGNAL(itemExpanded(QTreeWidgetItem*)), this, SLOT(accountExpanded(QTreeWidgetItem*))); connect(accountsView, SIGNAL(itemCollapsed(QTreeWidgetItem*)), this, SLOT(accountCollapsed(QTreeWidgetItem*))); expensesLayout = new QVBoxLayout(expenses_page); expensesLayout->setContentsMargins(0, 0, 0, 0); expensesWidget = new TransactionListWidget(b_extra, TRANSACTION_TYPE_EXPENSE, budget, this, expenses_page); connect(expensesWidget, SIGNAL(accountAdded(Account*)), this, SLOT(accountAdded(Account*))); connect(expensesWidget, SIGNAL(currenciesModified()), this, SLOT(currenciesModified())); connect(expensesWidget, SIGNAL(valueAlignmentUpdated(bool)), this, SLOT(valueAlignmentUpdated(bool))); connect(expensesWidget, SIGNAL(tagAdded(QString)), this, SLOT(tagAdded(QString))); expensesLayout->addWidget(expensesWidget); incomesLayout = new QVBoxLayout(incomes_page); incomesLayout->setContentsMargins(0, 0, 0, 0); incomesWidget = new TransactionListWidget(b_extra, TRANSACTION_TYPE_INCOME, budget, this, incomes_page); connect(incomesWidget, SIGNAL(accountAdded(Account*)), this, SLOT(accountAdded(Account*))); connect(incomesWidget, SIGNAL(currenciesModified()), this, SLOT(currenciesModified())); connect(incomesWidget, SIGNAL(valueAlignmentUpdated(bool)), this, SLOT(valueAlignmentUpdated(bool))); connect(incomesWidget, SIGNAL(tagAdded(QString)), this, SLOT(tagAdded(QString))); incomesLayout->addWidget(incomesWidget); transfersLayout = new QVBoxLayout(transfers_page); transfersLayout->setContentsMargins(0, 0, 0, 0); transfersWidget = new TransactionListWidget(b_extra, TRANSACTION_TYPE_TRANSFER, budget, this, transfers_page); connect(transfersWidget, SIGNAL(accountAdded(Account*)), this, SLOT(accountAdded(Account*))); connect(transfersWidget, SIGNAL(currenciesModified()), this, SLOT(currenciesModified())); connect(transfersWidget, SIGNAL(valueAlignmentUpdated(bool)), this, SLOT(valueAlignmentUpdated(bool))); connect(transfersWidget, SIGNAL(tagAdded(QString)), this, SLOT(tagAdded(QString))); transfersLayout->addWidget(transfersWidget); QVBoxLayout *securitiesLayout = new QVBoxLayout(securities_page); securitiesLayout->setContentsMargins(0, securitiesLayout->contentsMargins().top(), 0, 0); QDialogButtonBox *securitiesButtons = new QDialogButtonBox(securities_page); newSecurityButton = securitiesButtons->addButton(tr("New Security…", "Financial security (e.g. stock, mutual fund)"), QDialogButtonBox::ActionRole); newSecurityButton->setEnabled(true); newSecurityTransactionButton = securitiesButtons->addButton(tr("New Transaction"), QDialogButtonBox::ActionRole); QMenu *newSecurityTransactionMenu = new QMenu(this); newSecurityTransactionButton->setMenu(newSecurityTransactionMenu); setQuotationButton = securitiesButtons->addButton(tr("Set Quote…", "Financial quote"), QDialogButtonBox::ActionRole); setQuotationButton->setEnabled(false); securitiesLayout->addWidget(securitiesButtons); QVBoxLayout *securitiesViewLayout = new QVBoxLayout(); securitiesLayout->addLayout(securitiesViewLayout); securitiesView = new EqonomizeTreeWidget(securities_page); securitiesView->setSortingEnabled(true); securitiesView->sortByColumn(0, Qt::AscendingOrder); securitiesView->setAllColumnsShowFocus(true); securitiesView->setColumnCount(9); QStringList securitiesViewHeaders; securitiesViewHeaders << tr("Name"); securitiesViewHeaders << tr("Value"); securitiesViewHeaders << tr("Shares", "Financial shares"); securitiesViewHeaders << tr("Quote", "Financial quote"); securitiesViewHeaders << tr("Cost"); securitiesViewHeaders << tr("Profit"); securitiesViewHeaders << tr("Yearly Rate"); securitiesViewHeaders << tr("Type"); securitiesViewHeaders << tr("Account"); securitiesView->setHeaderLabels(securitiesViewHeaders); securitiesView->setRootIsDecorated(false); securitiesView->header()->setStretchLastSection(false); setColumnStrlenWidth(securitiesView, 0, 25); setColumnMoneyWidth(securitiesView, 1, budget); setColumnValueWidth(securitiesView, 2, 999999.99, 4, budget); setColumnMoneyWidth(securitiesView, 2, budget, 9999999.99, 4); setColumnMoneyWidth(securitiesView, 4, budget); setColumnMoneyWidth(securitiesView, 5, budget); setColumnValueWidth(securitiesView, 6, 99.99, 2, budget); setColumnStrlenWidth(securitiesView, 7, 10); setColumnStrlenWidth(securitiesView, 8, 10); sp = securitiesView->sizePolicy(); sp.setVerticalPolicy(QSizePolicy::MinimumExpanding); securitiesView->setSizePolicy(sp); securitiesViewLayout->addWidget(securitiesView); securitiesStatLabel = new QLabel(securities_page); securitiesViewLayout->addWidget(securitiesStatLabel); QGroupBox *periodGroup = new QGroupBox(tr("Statistics Period"), securities_page); QVBoxLayout *securitiesPeriodLayout = new QVBoxLayout(periodGroup); QHBoxLayout *securitiesPeriodLayout2 = new QHBoxLayout(); securitiesPeriodLayout->addLayout(securitiesPeriodLayout2); securitiesPeriodFromButton = new QCheckBox(tr("From"), periodGroup); securitiesPeriodFromButton->setChecked(false); securitiesPeriodLayout2->addWidget(securitiesPeriodFromButton); securitiesPeriodFromEdit = new EqonomizeDateEdit(periodGroup); securitiesPeriodFromEdit->setCalendarPopup(true); securities_from_date.setDate(curdate.year(), 1, 1); securitiesPeriodFromEdit->setDate(securities_from_date); securitiesPeriodFromEdit->setEnabled(false); sp = securitiesPeriodFromEdit->sizePolicy(); sp.setHorizontalPolicy(QSizePolicy::Expanding); securitiesPeriodFromEdit->setSizePolicy(sp); securitiesPeriodLayout2->addWidget(securitiesPeriodFromEdit); securitiesPeriodLayout2->addWidget(new QLabel(tr("To"), periodGroup)); securitiesPeriodToEdit = new EqonomizeDateEdit(periodGroup); securitiesPeriodToEdit->setCalendarPopup(true); securities_to_date = curdate; securitiesPeriodToEdit->setDate(securities_to_date); securitiesPeriodToEdit->setEnabled(true); securitiesPeriodToEdit->setSizePolicy(sp); securitiesPeriodLayout2->addWidget(securitiesPeriodToEdit); securitiesLayout->addWidget(periodGroup); QHBoxLayout *securitiesPeriodLayout3 = new QHBoxLayout(); securitiesPeriodLayout2->addLayout(securitiesPeriodLayout3); QPushButton *securitiesPrevYearButton = new QPushButton(LOAD_ICON("eqz-previous-year"), "", periodGroup); securitiesPeriodLayout3->addWidget(securitiesPrevYearButton); QPushButton *securitiesPrevMonthButton = new QPushButton(LOAD_ICON("eqz-previous-month"), "", periodGroup); securitiesPeriodLayout3->addWidget(securitiesPrevMonthButton); QPushButton *securitiesNextMonthButton = new QPushButton(LOAD_ICON("eqz-next-month"), "", periodGroup); securitiesPeriodLayout3->addWidget(securitiesNextMonthButton); QPushButton *securitiesNextYearButton = new QPushButton(LOAD_ICON("eqz-next-year"), "", periodGroup); securitiesPeriodLayout3->addWidget(securitiesNextYearButton); securitiesPopupMenu = NULL; updateSecuritiesStatistics(); connect(securitiesPrevMonthButton, SIGNAL(clicked()), this, SLOT(securitiesPrevMonth())); connect(securitiesNextMonthButton, SIGNAL(clicked()), this, SLOT(securitiesNextMonth())); connect(securitiesPrevYearButton, SIGNAL(clicked()), this, SLOT(securitiesPrevYear())); connect(securitiesNextYearButton, SIGNAL(clicked()), this, SLOT(securitiesNextYear())); connect(securitiesPeriodFromButton, SIGNAL(toggled(bool)), securitiesPeriodFromEdit, SLOT(setEnabled(bool))); connect(securitiesPeriodFromButton, SIGNAL(toggled(bool)), this, SLOT(updateSecurities())); connect(securitiesPeriodFromEdit, SIGNAL(dateChanged(const QDate&)), this, SLOT(securitiesPeriodFromChanged(const QDate&))); connect(securitiesPeriodToEdit, SIGNAL(dateChanged(const QDate&)), this, SLOT(securitiesPeriodToChanged(const QDate&))); connect(newSecurityButton, SIGNAL(clicked()), this, SLOT(newSecurity())); connect(setQuotationButton, SIGNAL(clicked()), this, SLOT(setQuotation())); connect(securitiesView, SIGNAL(itemSelectionChanged()), this, SLOT(securitiesSelectionChanged())); connect(securitiesView, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(securitiesExecuted(QTreeWidgetItem*, int))); connect(securitiesView, SIGNAL(returnPressed(QTreeWidgetItem*)), this, SLOT(securitiesExecuted(QTreeWidgetItem*))); securitiesView->setContextMenuPolicy(Qt::CustomContextMenu); connect(securitiesView, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(popupSecuritiesMenu(const QPoint&))); QVBoxLayout *scheduleLayout = new QVBoxLayout(schedule_page); scheduleLayout->setContentsMargins(0, scheduleLayout->contentsMargins().top(), 0, 0); QDialogButtonBox *scheduleButtons = new QDialogButtonBox(schedule_page); newScheduleButton = scheduleButtons->addButton(tr("New Schedule"), QDialogButtonBox::ActionRole); QMenu *newScheduleMenu = new QMenu(this); newScheduleButton->setMenu(newScheduleMenu); editScheduleButton = scheduleButtons->addButton(tr("Edit"), QDialogButtonBox::ActionRole); editScheduleMenu = new QMenu(this); editScheduleButton->setMenu(editScheduleMenu); editScheduleButton->setEnabled(false); removeScheduleButton = scheduleButtons->addButton(tr("Remove"), QDialogButtonBox::ActionRole); removeScheduleMenu = new QMenu(this); removeScheduleButton->setMenu(removeScheduleMenu); removeScheduleButton->setEnabled(false); scheduleLayout->addWidget(scheduleButtons); scheduleView = new EqonomizeTreeWidget(schedule_page); scheduleView->setAllColumnsShowFocus(true); scheduleView->setColumnCount(9); QStringList scheduleViewHeaders; scheduleViewHeaders << tr("Next Occurrence"); scheduleViewHeaders << tr("Type"); scheduleViewHeaders << tr("Description", "Transaction description property (transaction title/generic article name)"); scheduleViewHeaders << tr("Amount"); scheduleViewHeaders << tr("From"); scheduleViewHeaders << tr("To"); scheduleViewHeaders << tr("Payee/Payer"); scheduleViewHeaders << tr("Tags"); scheduleViewHeaders << tr("Comments"); scheduleView->setHeaderLabels(scheduleViewHeaders); scheduleView->setColumnHidden(6, true); scheduleView->setColumnHidden(7, true); setColumnDateWidth(scheduleView, 0); setColumnStrlenWidth(scheduleView, 1, 15); setColumnStrlenWidth(scheduleView, 2, 25); setColumnMoneyWidth(scheduleView, 3, budget); setColumnStrlenWidth(scheduleView, 4, 15); setColumnStrlenWidth(scheduleView, 5, 15); setColumnStrlenWidth(scheduleView, 6, 15); setColumnStrlenWidth(scheduleView, 7, 15); scheduleView->setRootIsDecorated(false); sp = scheduleView->sizePolicy(); sp.setVerticalPolicy(QSizePolicy::MinimumExpanding); scheduleView->setSizePolicy(sp); scheduleLayout->addWidget(scheduleView); scheduleView->sortByColumn(0, Qt::AscendingOrder); scheduleView->setSortingEnabled(true); scheduleHeaderPopupMenu = NULL; schedulePopupMenu = NULL; connect(scheduleView, SIGNAL(itemSelectionChanged()), this, SLOT(scheduleSelectionChanged())); connect(scheduleView, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(scheduleExecuted(QTreeWidgetItem*))); connect(scheduleView, SIGNAL(returnPressed(QTreeWidgetItem*)), this, SLOT(scheduleExecuted(QTreeWidgetItem*))); scheduleView->header()->setContextMenuPolicy(Qt::CustomContextMenu); connect(scheduleView->header(), SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(popupScheduleHeaderMenu(const QPoint&))); scheduleView->setContextMenuPolicy(Qt::CustomContextMenu); connect(scheduleView, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(popupScheduleMenu(const QPoint&))); connect(scheduleView, SIGNAL(itemSelectionChanged()), this, SLOT(updateTransactionActions())); setupActions(); switch(initial_period) { case 0: {AIPCurrentMonth->setChecked(true); break;} case 1: {AIPCurrentYear->setChecked(true); break;} case 2: {AIPCurrentWholeMonth->setChecked(true); break;} case 3: {AIPCurrentWholeYear->setChecked(true); break;} case 4: {AIPRememberLastDates->setChecked(true); break;} } int i_backup_frequency = settings.value("backupFrequency", int(BACKUP_WEEKLY)).toInt(); switch(i_backup_frequency) { case BACKUP_NEVER: {ABFNever->setChecked(true); break;} case BACKUP_DAILY: {ABFDaily->setChecked(true); break;} case BACKUP_FORTNIGHTLY: {ABFFortnightly->setChecked(true); break;} case BACKUP_MONTHLY: {ABFMonthly->setChecked(true); break;} default: {ABFWeekly->setChecked(true); break;} } QString slang = settings.value("language", QString()).toString(); QList alangs = ActionSelectLang->actions(); for(int i = 0; i < alangs.size(); i++) { if(alangs[i]->data().toString() == slang) { alangs[i]->setChecked(true); break; } } newScheduleMenu->addAction(ActionNewExpense); newScheduleMenu->addAction(ActionNewIncome); newScheduleMenu->addAction(ActionNewTransfer); newScheduleMenu->addAction(ActionNewDebtPayment); newScheduleMenu->addAction(ActionNewMultiItemTransaction); editScheduleMenu->addAction(ActionEditSchedule); editScheduleMenu->addAction(ActionEditOccurrence); removeScheduleMenu->addAction(ActionDeleteSchedule); removeScheduleMenu->addAction(ActionDeleteOccurrence); newSecurityTransactionMenu->addAction(ActionBuyShares); newSecurityTransactionMenu->addAction(ActionSellShares); newSecurityTransactionMenu->addAction(ActionNewSecurityTrade); newSecurityTransactionMenu->addAction(ActionNewDividend); newSecurityTransactionMenu->addAction(ActionNewReinvestedDividend); settings.endGroup(); readOptions(); if(first_run) { QFontMetrics fm(accountsView->font()); int w = fm.boundingRect(accountsView->headerItem()->text(0)).width() + fm.boundingRect(QString(15, 'h')).width(); accountsView->setMinimumWidth(w + accountsView->columnWidth(BUDGET_COLUMN) + accountsView->columnWidth(CHANGE_COLUMN) + accountsView->columnWidth(VALUE_COLUMN)); } QTimer *scheduleTimer = new QTimer(); scheduleTimer->setTimerType(Qt::VeryCoarseTimer); connect(scheduleTimer, SIGNAL(timeout()), this, SLOT(checkSchedule())); scheduleTimer->start(1000 * 60 * 30); QTimer *updateExchangeRatesTimer = new QTimer(); updateExchangeRatesTimer->setTimerType(Qt::VeryCoarseTimer); connect(scheduleTimer, SIGNAL(timeout()), this, SLOT(checkExchangeRatesTimeOut())); updateExchangeRatesTimer->start(1000 * 60 * 60 * 6); auto_save_timeout = true; QTimer *autoSaveTimer = new QTimer(); autoSaveTimer->setTimerType(Qt::VeryCoarseTimer); connect(autoSaveTimer, SIGNAL(timeout()), this, SLOT(onAutoSaveTimeout())); autoSaveTimer->start(1000 * 60 * 1); QTimer *dateTimer = new QTimer(); dateTimer->setTimerType(Qt::VeryCoarseTimer); connect(dateTimer, SIGNAL(timeout()), this, SLOT(checkDate())); dateTimer->start(1000 * 60); QLocalServer::removeServer("eqonomize"); server = new QLocalServer(this); server->listen("eqonomize"); connect(server, SIGNAL(newConnection()), this, SLOT(serverNewConnection())); } Eqonomize::~Eqonomize() {} void Eqonomize::serverNewConnection() { socket = server->nextPendingConnection(); if(socket) { connect(socket, SIGNAL(readyRead()), this, SLOT(socketReadyRead())); } } void Eqonomize::socketReadyRead() { setWindowState((windowState() & ~Qt::WindowMinimized) | Qt::WindowActive); show(); raise(); activateWindow(); QString command = socket->readAll(); QChar c = command[0]; if(c == 'e') showExpenses(); else if(c == 'i') showIncomes(); else if(c == 't') showTransfers(); command.remove(0, 1); command = command.trimmed(); if(c == 's') { if(command.isEmpty() || QUrl::fromUserInput(command) == current_url) { fileSynchronize(); } else { QUrl url = QUrl::fromUserInput(command); Budget *budget2 = new Budget(); QString errors; QString error = budget2->loadFile(url.toLocalFile(), errors); if(!error.isNull()) {qWarning() << error; return;} if(!errors.isNull()) qWarning() << errors; errors = QString(); if(budget2->sync(error, errors, true, true)) { if(!errors.isNull()) qWarning() << errors; error = budget2->saveFile(url.toLocalFile()); if(!error.isNull()) {qWarning() << error; return;} } else { if(!error.isNull()) {qWarning() << error; return;} if(!errors.isNull()) qWarning() << errors; } } } if(!command.isEmpty()) openURL(QUrl::fromUserInput(command)); } void Eqonomize::useExtraProperties(bool b) { b_extra = b; delete expensesWidget; expensesWidget = new TransactionListWidget(b_extra, TRANSACTION_TYPE_EXPENSE, budget, this, expenses_page); connect(expensesWidget, SIGNAL(accountAdded(Account*)), this, SLOT(accountAdded(Account*))); connect(expensesWidget, SIGNAL(currenciesModified()), this, SLOT(currenciesModified())); expensesLayout->addWidget(expensesWidget); expensesWidget->updateAccounts(); expensesWidget->transactionsReset(); if(tabs->currentIndex() == EXPENSES_PAGE_INDEX) { expensesWidget->onDisplay(); updateTransactionActions(); } expensesWidget->show(); delete incomesWidget; incomesWidget = new TransactionListWidget(b_extra, TRANSACTION_TYPE_INCOME, budget, this, incomes_page); connect(incomesWidget, SIGNAL(accountAdded(Account*)), this, SLOT(accountAdded(Account*))); connect(incomesWidget, SIGNAL(currenciesModified()), this, SLOT(currenciesModified())); incomesLayout->addWidget(incomesWidget); incomesWidget->updateAccounts(); incomesWidget->transactionsReset(); if(tabs->currentIndex() == INCOMES_PAGE_INDEX) { incomesWidget->onDisplay(); updateTransactionActions(); } incomesWidget->show(); QSettings settings; settings.beginGroup("GeneralOptions"); settings.setValue("useExtraProperties", b_extra); settings.endGroup(); } void Eqonomize::useExchangeRateForTransactionDate(bool b) { if(b != (budget->defaultTransactionConversionRateDate() == TRANSACTION_CONVERSION_RATE_AT_DATE)) { if(b) budget->setDefaultTransactionConversionRateDate(TRANSACTION_CONVERSION_RATE_AT_DATE); else budget->setDefaultTransactionConversionRateDate(TRANSACTION_CONVERSION_LATEST_RATE); expensesWidget->filterTransactions(); incomesWidget->filterTransactions(); transfersWidget->filterTransactions(); filterAccounts(); updateScheduledTransactions(); updateSecurities(); emit transactionsModified(); QSettings settings; settings.beginGroup("GeneralOptions"); settings.setValue("useExchangeRateForTransactionDate", budget->defaultTransactionConversionRateDate() == TRANSACTION_CONVERSION_RATE_AT_DATE); settings.endGroup(); } } void Eqonomize::updateBudgetDay() { frommonth_begin = budget->firstBudgetDay(from_date); prevmonth_begin = budget->firstBudgetDay(to_date); budget->addBudgetMonthsSetFirst(prevmonth_begin, -1); budgetMonthEdit->blockSignals(true); budgetMonthEdit->setDate(budget->budgetDateToMonth(to_date)); budgetMonthEdit->blockSignals(false); if(ActionSelectInitialPeriod->checkedAction() == AIPCurrentMonth) periodSelected(ActionAP_1); else if(ActionSelectInitialPeriod->checkedAction() == AIPCurrentYear) periodSelected(ActionAP_2); else if(ActionSelectInitialPeriod->checkedAction() == AIPCurrentWholeMonth) periodSelected(ActionAP_3); else if(ActionSelectInitialPeriod->checkedAction() == AIPCurrentWholeYear) periodSelected(ActionAP_4); else filterAccounts(); if(otcDialog) ((OverTimeChartDialog*) otcDialog)->chart->resetOptions(); if(otrDialog) ((OverTimeReportDialog*) otrDialog)->report->resetOptions(); if(cccDialog) ((CategoriesComparisonChartDialog*) cccDialog)->chart->resetOptions(); if(ccrDialog) ((CategoriesComparisonReportDialog*) ccrDialog)->report->resetOptions(); } void Eqonomize::setScheduleConfirmationTime() { QSettings settings; settings.beginGroup("GeneralOptions"); QDialog *dialog = new QDialog(this); dialog->setWindowTitle(tr("Set Schedule Confirmation Time")); QVBoxLayout *box1 = new QVBoxLayout(dialog); QGridLayout *layout = new QGridLayout(); layout->addWidget(new QLabel(tr("Schedule confirmation time:"), dialog), 0, 0); QTimeEdit *timeEdit = new QTimeEdit(); timeEdit->setTime(settings.value("scheduleConfirmationTime", QTime(18, 0)).toTime()); layout->addWidget(timeEdit, 0, 1); box1->addLayout(layout); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, dialog); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), dialog, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), dialog, SLOT(accept())); box1->addWidget(buttonBox); if(dialog->exec() == QDialog::Accepted) { settings.setValue("scheduleConfirmationTime", timeEdit->time()); checkSchedule(); } settings.endGroup(); dialog->deleteLater(); } void Eqonomize::setBudgetPeriod() { QDialog *dialog = new QDialog(this); dialog->setWindowTitle(tr("Set Budget Period")); QVBoxLayout *box1 = new QVBoxLayout(dialog); QGridLayout *layout = new QGridLayout(); layout->addWidget(new QLabel(tr("First day in budget month:"), dialog), 0, 0); QComboBox *monthlyDayCombo = new QComboBox(dialog); monthlyDayCombo->addItem(tr("1st")); monthlyDayCombo->addItem(tr("2nd")); monthlyDayCombo->addItem(tr("3rd")); monthlyDayCombo->addItem(tr("4th")); monthlyDayCombo->addItem(tr("5th")); monthlyDayCombo->addItem(tr("6th")); monthlyDayCombo->addItem(tr("7th")); monthlyDayCombo->addItem(tr("8th")); monthlyDayCombo->addItem(tr("9th")); monthlyDayCombo->addItem(tr("10th")); monthlyDayCombo->addItem(tr("11th")); monthlyDayCombo->addItem(tr("12th")); monthlyDayCombo->addItem(tr("13th")); monthlyDayCombo->addItem(tr("14th")); monthlyDayCombo->addItem(tr("15th")); monthlyDayCombo->addItem(tr("16th")); monthlyDayCombo->addItem(tr("17th")); monthlyDayCombo->addItem(tr("18th")); monthlyDayCombo->addItem(tr("19th")); monthlyDayCombo->addItem(tr("20th")); monthlyDayCombo->addItem(tr("21st")); monthlyDayCombo->addItem(tr("22nd")); monthlyDayCombo->addItem(tr("23rd")); monthlyDayCombo->addItem(tr("24th")); monthlyDayCombo->addItem(tr("25th")); monthlyDayCombo->addItem(tr("26th")); monthlyDayCombo->addItem(tr("27th")); monthlyDayCombo->addItem(tr("28th")); monthlyDayCombo->addItem(tr("Last")); monthlyDayCombo->addItem(tr("2nd Last")); monthlyDayCombo->addItem(tr("3rd Last")); monthlyDayCombo->addItem(tr("4th Last")); monthlyDayCombo->addItem(tr("5th Last")); if(budget->budgetDay() > 0) monthlyDayCombo->setCurrentIndex(budget->budgetDay() - 1); else if(budget->budgetDay() > -5) monthlyDayCombo->setCurrentIndex(28 - budget->budgetDay()); layout->addWidget(monthlyDayCombo, 0, 1); layout->addWidget(new QLabel(tr("First month in budget year:"), dialog), 1, 0); QComboBox *yearlyMonthCombo = new QComboBox(dialog); for(int i = 1; i <= 12; i++) { yearlyMonthCombo->addItem(QLocale().monthName(i, QLocale::LongFormat)); } yearlyMonthCombo->setCurrentIndex(budget->budgetMonth() - 1); layout->addWidget(yearlyMonthCombo, 1, 1); box1->addLayout(layout); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, dialog); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), dialog, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), dialog, SLOT(accept())); box1->addWidget(buttonBox); if(dialog->exec() == QDialog::Accepted) { budget->setBudgetDay(monthlyDayCombo->currentIndex() >= 28 ? -(monthlyDayCombo->currentIndex() - 28) : monthlyDayCombo->currentIndex() + 1); budget->setBudgetMonth(yearlyMonthCombo->currentIndex() + 1); updateBudgetDay(); setModified(true); } dialog->deleteLater(); } void Eqonomize::selectFont() { bool b = false; QFont font = QFontDialog::getFont(&b, qApp->font(), this); if(b && font != qApp->font()) { qApp->setFont(font); QSettings settings; settings.beginGroup("GeneralOptions"); settings.setValue("font", font.toString()); settings.endGroup(); } } void Eqonomize::setDarkMode(bool b) { updatePalette(b); expensesWidget->filterTransactions(); incomesWidget->filterTransactions(); transfersWidget->filterTransactions(); filterAccounts(); updateScheduledTransactions(); updateSecurities(); emit transactionsModified(); QSettings settings; settings.beginGroup("GeneralOptions"); settings.setValue("darkMode", b); settings.endGroup(); } void Eqonomize::updatePalette(bool dark_mode) { if(dark_mode) { #ifdef _WIN32 QApplication::setStyle(QStyleFactory::create("Fusion")); #endif QPalette p; p.setColor(QPalette::Active, QPalette::Window, QColor(42, 46, 50)); p.setColor(QPalette::Active, QPalette::WindowText, QColor(252, 252, 252)); p.setColor(QPalette::Active, QPalette::Base, QColor(27, 30, 32)); p.setColor(QPalette::Active, QPalette::AlternateBase, QColor(35, 38, 41)); p.setColor(QPalette::Active, QPalette::ToolTipBase, QColor(49, 54, 59)); p.setColor(QPalette::Active, QPalette::ToolTipText, QColor(252, 252, 252)); #if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) p.setColor(QPalette::Active, QPalette::PlaceholderText, QColor(161, 169, 177)); #endif p.setColor(QPalette::Active, QPalette::Text, QColor(252, 252, 252)); p.setColor(QPalette::Active, QPalette::Button, QColor(49, 54, 59)); p.setColor(QPalette::Active, QPalette::ButtonText, QColor(252, 252, 252)); p.setColor(QPalette::Active, QPalette::BrightText, QColor(39, 174, 96)); p.setColor(QPalette::Inactive, QPalette::Window, QColor(42, 46, 50)); p.setColor(QPalette::Inactive, QPalette::WindowText, QColor(252, 252, 252)); p.setColor(QPalette::Inactive, QPalette::Base, QColor(27, 30, 32)); p.setColor(QPalette::Inactive, QPalette::AlternateBase, QColor(35, 38, 41)); p.setColor(QPalette::Inactive, QPalette::ToolTipBase, QColor(49, 54, 59)); p.setColor(QPalette::Inactive, QPalette::ToolTipText, QColor(252, 252, 252)); #if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) p.setColor(QPalette::Inactive, QPalette::PlaceholderText, QColor(161, 169, 177)); #endif p.setColor(QPalette::Inactive, QPalette::Text, QColor(252, 252, 252)); p.setColor(QPalette::Inactive, QPalette::Button, QColor(49, 54, 59)); p.setColor(QPalette::Inactive, QPalette::ButtonText, QColor(252, 252, 252)); p.setColor(QPalette::Inactive, QPalette::BrightText, QColor(39, 174, 96)); p.setColor(QPalette::Disabled, QPalette::Window, QColor(42, 46, 50)); p.setColor(QPalette::Disabled, QPalette::WindowText, QColor(101, 101, 101)); p.setColor(QPalette::Disabled, QPalette::Base, QColor(27, 30, 32)); p.setColor(QPalette::Disabled, QPalette::AlternateBase, QColor(35, 38, 41)); p.setColor(QPalette::Disabled, QPalette::ToolTipBase, QColor(49, 54, 59)); p.setColor(QPalette::Disabled, QPalette::ToolTipText, QColor(252, 252, 252)); #if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) p.setColor(QPalette::Disabled, QPalette::PlaceholderText, QColor(161, 169, 177)); #endif p.setColor(QPalette::Disabled, QPalette::Text, QColor(101, 101, 101)); p.setColor(QPalette::Disabled, QPalette::Button, QColor(47, 52, 56)); p.setColor(QPalette::Disabled, QPalette::ButtonText,QColor(101, 101, 101)); p.setColor(QPalette::Disabled, QPalette::BrightText, QColor(39, 174, 96)); QApplication::setPalette(p); } else { #ifdef _WIN32 QApplication::setStyle(QStyleFactory::create("windowsvista")); #endif QApplication::setPalette(QApplication::style()->standardPalette()); } } void Eqonomize::checkDate() { if(QDate::currentDate() != prev_cur_date) { QDate prev_cur_date_bak = prev_cur_date; prev_cur_date = QDate::currentDate(); if(to_date == prev_cur_date_bak) { accountsPeriodToEdit->setDate(prev_cur_date); accountsPeriodToChanged(prev_cur_date); } if(securities_to_date == prev_cur_date_bak) { securitiesPeriodToEdit->setDate(prev_cur_date); securitiesPeriodToChanged(prev_cur_date); } expensesWidget->currentDateChanged(prev_cur_date_bak, prev_cur_date); incomesWidget->currentDateChanged(prev_cur_date_bak, prev_cur_date); transfersWidget->currentDateChanged(prev_cur_date_bak, prev_cur_date); } } void Eqonomize::showExpenses() { tabs->setCurrentIndex(EXPENSES_PAGE_INDEX); } void Eqonomize::showIncomes() { tabs->setCurrentIndex(INCOMES_PAGE_INDEX); } void Eqonomize::showTransfers() { tabs->setCurrentIndex(TRANSFERS_PAGE_INDEX); } void Eqonomize::setPartialBudget(bool b) { partial_budget = b; filterAccounts(); } void Eqonomize::budgetEditReturnPressed() { QTreeWidgetItem *i = selectedItem(accountsView); if(!i) return; int index = accountsView->indexOfTopLevelItem(i); index++; i = accountsView->topLevelItem(index); if(!i && account_items.contains(i) && account_items[i]->type() == ACCOUNT_TYPE_INCOMES) i = expensesItem->child(0); if(i) { i->setSelected(true); if(budgetEdit->isEnabled()) budgetEdit->selectNumber(); else budgetButton->setFocus(); } } void Eqonomize::budgetMonthChanged(const QDate &date) { accountsPeriodFromEdit->blockSignals(true); accountsPeriodFromButton->blockSignals(true); accountsPeriodToEdit->blockSignals(true); from_date = budget->monthToBudgetMonth(date); to_date = budget->lastBudgetDay(from_date); accountsPeriodFromButton->setChecked(true); accountsPeriodFromEdit->setDate(from_date); accountsPeriodToEdit->setDate(to_date); accountsPeriodFromEdit->blockSignals(false); accountsPeriodFromButton->blockSignals(false); accountsPeriodToEdit->blockSignals(false); filterAccounts(); } void Eqonomize::budgetChanged(double value) { QTreeWidgetItem *i = selectedItem(accountsView); if(!account_items.contains(i)) return; Account *account = account_items[i]; if(account->type() == ACCOUNT_TYPE_ASSETS) return; CategoryAccount *ca = (CategoryAccount*) account; QDate month = budgetMonthEdit->date(); ca->mbudgets[month] = value; for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) { ca = *it; if(!ca->mbudgets.contains(month)) { value = ca->monthlyBudget(month); ca->mbudgets[month] = value; } } for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) { ca = *it; if(!ca->mbudgets.contains(month)) { value = ca->monthlyBudget(month); ca->mbudgets[month] = value; } } setModified(true); filterAccounts(); } void Eqonomize::budgetToggled(bool b) { QTreeWidgetItem *i = selectedItem(accountsView); if(!account_items.contains(i)) return; Account *account = account_items[i]; if(account->type() == ACCOUNT_TYPE_ASSETS) return; CategoryAccount *ca = (CategoryAccount*) account; QDate month = budgetMonthEdit->date(); if(b) ca->mbudgets[month] = budgetEdit->value(); else ca->mbudgets[month] = -1; for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) { ca = *it; if(!ca->mbudgets.contains(month)) { double value = ca->monthlyBudget(month); ca->mbudgets[month] = value; } } for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) { ca = *it; if(!ca->mbudgets.contains(month)) { double value = ca->monthlyBudget(month); ca->mbudgets[month] = value; } } setModified(true); filterAccounts(); } void Eqonomize::periodSelected(QAction *a) { accountsPeriodFromEdit->blockSignals(true); accountsPeriodFromButton->blockSignals(true); accountsPeriodToEdit->blockSignals(true); QDate curdate = QDate::currentDate(); if(a == ActionAP_1) { from_date = budget->firstBudgetDay(curdate); to_date = curdate; } else if(a == ActionAP_2) { from_date = budget->firstBudgetDayOfYear(curdate); to_date = curdate; } else if(a == ActionAP_3) { from_date = budget->firstBudgetDay(curdate); to_date = budget->lastBudgetDay(curdate); } else if(a == ActionAP_4) { from_date = budget->firstBudgetDayOfYear(curdate); to_date = budget->lastBudgetDayOfYear(curdate); } else if(a == ActionAP_5) { to_date = curdate; from_date = to_date.addMonths(-1).addDays(1); } else if(a == ActionAP_6) { to_date = curdate; from_date = to_date.addYears(-1).addDays(1); } else if(a == ActionAP_7) { from_date = budget->firstBudgetDay(curdate); budget->addBudgetMonthsSetFirst(from_date, -1); to_date = budget->lastBudgetDay(from_date); } else if(a == ActionAP_8) { from_date = budget->firstBudgetDayOfYear(curdate); budget->addBudgetMonthsSetFirst(from_date, -12); to_date = budget->lastBudgetDayOfYear(from_date); } accountsPeriodFromButton->setChecked(true); accountsPeriodFromEdit->setEnabled(true); accountsPeriodFromEdit->setDate(from_date); accountsPeriodToEdit->setDate(to_date); accountsPeriodFromEdit->blockSignals(false); accountsPeriodFromButton->blockSignals(false); accountsPeriodToEdit->blockSignals(false); filterAccounts(); } void Eqonomize::newSecurity() { budget->setRecordNewAccounts(true); budget->resetDefaultCurrencyChanged(); budget->resetCurrenciesModified(); budget->setRecordNewTags(true); EditSecurityDialog *dialog = new EditSecurityDialog(budget, this, tr("New Security", "Financial security (e.g. stock, mutual fund)"), true); if(dialog->exec() == QDialog::Accepted) { foreach(Account *acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(QString str, budget->newTags) tagAdded(str); budget->newTags.clear(); Security *security = dialog->newSecurity(); if(security) { budget->addSecurity(security); appendSecurity(security); updateSecurityAccount(security->account()); setModified(true); } } else { foreach(Account *acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(QString str, budget->newTags) tagAdded(str); budget->newTags.clear(); } dialog->deleteLater(); if(budget->currenciesModified() || budget->defaultCurrencyChanged()) currenciesModified(); budget->setRecordNewAccounts(false); budget->setRecordNewTags(false); } void Eqonomize::securityAdded(Security *security) { appendSecurity(security); updateSecurityAccount(security->account()); setModified(true); } void Eqonomize::editSecurity(QTreeWidgetItem *i) { if(!i) return; budget->setRecordNewAccounts(true); budget->resetDefaultCurrencyChanged(); budget->resetCurrenciesModified(); budget->setRecordNewTags(true); Security *security = ((SecurityListViewItem*) i)->security(); EditSecurityDialog *dialog = new EditSecurityDialog(budget, this, tr("Edit Security", "Financial security (e.g. stock, mutual fund)"), true); dialog->setSecurity(security); if(dialog->exec() == QDialog::Accepted) { foreach(Account *acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(QString str, budget->newTags) tagAdded(str); budget->newTags.clear(); AssetsAccount *prev_acc = security->account(); if(dialog->modifySecurity(security)) { updateSecurity(i); updateSecurityAccount(security->account()); if(prev_acc != security->account()) { updateSecurityAccount(prev_acc); } setModified(true); incomesWidget->filterTransactions(); transfersWidget->filterTransactions(); } } else { foreach(Account *acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(QString str, budget->newTags) tagAdded(str); budget->newTags.clear(); } dialog->deleteLater(); if(budget->currenciesModified() || budget->defaultCurrencyChanged()) currenciesModified(); budget->setRecordNewAccounts(false); budget->setRecordNewTags(false); } void Eqonomize::editSecurity() { QTreeWidgetItem *i = selectedItem(securitiesView); if(i == NULL) return; editSecurity(i); } void Eqonomize::updateSecuritiesStatistics() { securitiesStatLabel->setText(QString("
    %1 %4   %2 %5   %3 %6
    ").arg(tr("Total value:")).arg(tr("Cost:")).arg(tr("Profit:")).arg(budget->formatMoney(total_value), budget->formatMoney(total_cost)).arg(budget->formatMoney(total_profit))); } void Eqonomize::deleteSecurity() { SecurityListViewItem *i = (SecurityListViewItem*) selectedItem(securitiesView); if(i == NULL) return; Security *security = i->security(); bool has_trans = budget->securityHasTransactions(security); if(!has_trans || QMessageBox::warning(this, tr("Delete security?", "Financial security (e.g. stock, mutual fund)"), tr("Are you sure you want to delete the security \"%1\" and all associated transactions?", "Financial security (e.g. stock, mutual fund)").arg(security->name()), QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) { total_value -= i->value; total_rate *= total_cost; total_cost -= i->scost; total_rate -= i->scost * i->rate; if(is_zero(total_cost)) total_rate = 0.0; else total_rate /= total_cost; total_profit -= i->sprofit; updateSecuritiesStatistics(); delete i; budget->removeSecurity(security); if(has_trans) { filterAccounts(); updateScheduledTransactions(); expensesWidget->filterTransactions(); incomesWidget->filterTransactions(); transfersWidget->filterTransactions(); emit transactionsModified(); } else { updateSecurityAccount(security->account()); } setModified(true); } } void Eqonomize::buySecurities() { SecurityListViewItem *i = (SecurityListViewItem*) selectedItem(securitiesView); newScheduledTransaction(TRANSACTION_TYPE_SECURITY_BUY, i == NULL ? NULL : i->security(), true); } void Eqonomize::sellSecurities() { SecurityListViewItem *i = (SecurityListViewItem*) selectedItem(securitiesView); newScheduledTransaction(TRANSACTION_TYPE_SECURITY_SELL, i == NULL ? NULL : i->security(), true); } void Eqonomize::newDividend() { SecurityListViewItem *i = (SecurityListViewItem*) selectedItem(securitiesView); newScheduledTransaction(TRANSACTION_TYPE_INCOME, i == NULL ? NULL : i->security(), true); } void Eqonomize::newReinvestedDividend() { SecurityListViewItem *i = (SecurityListViewItem*) selectedItem(securitiesView); newScheduledTransaction(TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND, i == NULL ? NULL : i->security(), true); } void Eqonomize::editSecurityTrade(SecurityTrade *ts) { editSecurityTrade(ts, this); } bool Eqonomize::editSecurityTrade(SecurityTrade *ts, QWidget *parent) { EditSecurityTradeDialog *dialog = new EditSecurityTradeDialog(budget, ts->from_security, parent); dialog->setSecurityTrade(ts); if(dialog->exec() == QDialog::Accepted) { SecurityTrade *ts_new = dialog->createSecurityTrade(); if(ts_new) { ts_new->timestamp = ts->timestamp; ts_new->id = ts->id; ts_new->first_revision = ts->first_revision; ts_new->last_revision = budget->revision(); budget->removeSecurityTrade(ts, true); budget->addSecurityTrade(ts_new); updateSecurity(ts_new->from_security); updateSecurity(ts_new->to_security); if(ts->to_security != ts_new->to_security) updateSecurity(ts->to_security); if(ts->from_security != ts_new->from_security) updateSecurity(ts->from_security); updateSecurityAccount(ts_new->from_security->account()); if(ts_new->to_security->account() != ts_new->from_security->account()) { updateSecurityAccount(ts_new->to_security->account()); } if(ts->to_security->account() != ts_new->to_security->account() && ts->to_security->account() != ts_new->from_security->account()) { updateSecurityAccount(ts->to_security->account()); } setModified(true); delete ts; dialog->deleteLater(); return true; } } dialog->deleteLater(); return false; } void Eqonomize::newSecurityTrade() { SecurityListViewItem *i = (SecurityListViewItem*) selectedItem(securitiesView); EditSecurityTradeDialog *dialog = new EditSecurityTradeDialog(budget, i == NULL ? NULL : i->security(), this); if(dialog->checkSecurities() && dialog->exec() == QDialog::Accepted) { SecurityTrade *ts = dialog->createSecurityTrade(); if(ts) { budget->addSecurityTrade(ts); updateSecurity(ts->from_security); updateSecurity(ts->to_security); updateSecurityAccount(ts->from_security->account()); if(ts->to_security->account() != ts->from_security->account()) { updateSecurityAccount(ts->to_security->account()); } setModified(true); } } dialog->deleteLater(); } void Eqonomize::setQuotation() { SecurityListViewItem *i = (SecurityListViewItem*) selectedItem(securitiesView); if(i == NULL) return; QDialog *dialog = new QDialog(this); dialog->setWindowTitle(tr("Set Quote (%1)", "Financial quote").arg(i->security()->name())); dialog->setModal(true); QVBoxLayout *box1 = new QVBoxLayout(dialog); QGridLayout *grid = new QGridLayout(); box1->addLayout(grid); grid->addWidget(new QLabel(tr("Price per share:", "Financial shares"), dialog), 0, 0); EqonomizeValueEdit *quotationEdit = new EqonomizeValueEdit(0.0, pow(10, -i->security()->quotationDecimals()), i->security()->getQuotation(QDate::currentDate()), i->security()->quotationDecimals(), true, dialog, budget); quotationEdit->setFocus(); quotationEdit->setCurrency(i->security()->currency(), true); grid->addWidget(quotationEdit, 0, 1); grid->addWidget(new QLabel(tr("Date:"), dialog), 1, 0); EqonomizeDateEdit *dateEdit = new EqonomizeDateEdit(QDate::currentDate(), dialog); dateEdit->setCalendarPopup(true); grid->addWidget(dateEdit, 1, 1); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, dialog); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), dialog, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), dialog, SLOT(accept())); box1->addWidget(buttonBox); while(dialog->exec() == QDialog::Accepted) { QDate date = dateEdit->date(); if(!date.isValid()) { QMessageBox::critical(this, tr("Error"), tr("Invalid date.")); } else if(date > QDate::currentDate()) { QMessageBox::critical(this, tr("Error"), tr("Future dates are not allowed.")); } else { i->security()->setQuotation(date, quotationEdit->value()); updateSecurity(i); updateSecurityAccount(i->security()->account(), true); setModified(true); break; } } dialog->deleteLater(); } void Eqonomize::editQuotations() { SecurityListViewItem *i = (SecurityListViewItem*) selectedItem(securitiesView); if(!i) return; Security *security = i->security(); EditQuotationsDialog *dialog = new EditQuotationsDialog(security, this); if(dialog->exec() == QDialog::Accepted) { dialog->modifyQuotations(); updateSecurity(i); updateSecurityAccount(security->account()); setModified(true); } dialog->deleteLater(); } void Eqonomize::editSecurityTransactions() { SecurityListViewItem *i = (SecurityListViewItem*) selectedItem(securitiesView); if(!i) return; SecurityTransactionsDialog *dialog = new SecurityTransactionsDialog(i->security(), this, tr("Security Transactions", "Financial security (e.g. stock, mutual fund)")); dialog->exec(); dialog->deleteLater(); } void Eqonomize::securitiesSelectionChanged() { SecurityListViewItem *i = (SecurityListViewItem*) selectedItem(securitiesView); setQuotationButton->setEnabled(i != NULL); ActionEditSecurity->setEnabled(i != NULL); ActionDeleteSecurity->setEnabled(i != NULL); ActionSetQuotation->setEnabled(i != NULL); ActionEditQuotations->setEnabled(i != NULL); ActionEditSecurityTransactions->setEnabled(i != NULL); } void Eqonomize::securitiesExecuted(QTreeWidgetItem *i) { if(i == NULL) return; editSecurity(i); } void Eqonomize::securitiesExecuted(QTreeWidgetItem *i, int c) { if(i == NULL) return; switch(c) { case 4: {} case 5: {} case 6: {} case 1: {} case 2: { editSecurityTransactions(); break; } case 3: { setQuotation(); break; } case 8: { if(((SecurityListViewItem*) i)->security()) { editAccount(((SecurityListViewItem*) i)->security()->account()); } break; } default: { editSecurity(i); break; } } } void Eqonomize::popupSecuritiesMenu(const QPoint &p) { if(!securitiesPopupMenu) { securitiesPopupMenu = new QMenu(this); securitiesPopupMenu->addAction(ActionNewSecurity); securitiesPopupMenu->addAction(ActionEditSecurity); securitiesPopupMenu->addAction(ActionDeleteSecurity); securitiesPopupMenu->addSeparator(); securitiesPopupMenu->addAction(ActionBuyShares); securitiesPopupMenu->addAction(ActionSellShares); securitiesPopupMenu->addAction(ActionNewSecurityTrade); securitiesPopupMenu->addAction(ActionNewDividend); securitiesPopupMenu->addAction(ActionNewReinvestedDividend); securitiesPopupMenu->addSeparator(); securitiesPopupMenu->addAction(ActionEditSecurityTransactions); securitiesPopupMenu->addSeparator(); securitiesPopupMenu->addAction(ActionSetQuotation); securitiesPopupMenu->addAction(ActionEditQuotations); } securitiesPopupMenu->popup(securitiesView->viewport()->mapToGlobal(p)); } void Eqonomize::appendSecurity(Security *security) { double value = 0.0, cost = 0.0, rate = 0.0, profit = 0.0, quotation = 0.0, shares = 0.0; value = security->value(securities_to_date, 1); cost = security->cost(securities_to_date); if(securities_to_date > QDate::currentDate()) quotation = security->expectedQuotation(securities_to_date); else quotation = security->getQuotation(securities_to_date); shares = security->shares(securities_to_date, true); if(securitiesPeriodFromButton->isChecked()) { rate = security->yearlyRate(securities_from_date, securities_to_date); profit = security->profit(securities_from_date, securities_to_date, true); } else { rate = security->yearlyRate(securities_to_date); profit = security->profit(securities_to_date, true); } Currency *cur = security->currency(); if(!cur) cur = budget->defaultCurrency(); SecurityListViewItem *i = new SecurityListViewItem(security, security->name(), cur->formatValue(value), budget->formatValue(shares, security->decimals()), cur->formatValue(quotation, security->quotationDecimals()), cur->formatValue(cost), cur->formatValue(profit), right_align_values ? budget->formatValue(rate * 100, 2) + "% " : budget->formatValue(rate * 100, 2) + "%", QString(), security->account()->name(), right_align_values); i->rate = rate; i->shares = shares; if(cur != budget->defaultCurrency()) { i->sprofit = security->profit(securities_to_date, true, false, budget->defaultCurrency()); i->scost = security->cost(securities_to_date, false, budget->defaultCurrency()); i->profit = cur->convertTo(profit, budget->defaultCurrency()); i->quote = cur->convertTo(quotation, budget->defaultCurrency()); i->value = cur->convertTo(value, budget->defaultCurrency()); i->cost = cur->convertTo(cost, budget->defaultCurrency()); } else { i->sprofit = profit; i->scost = cost; i->profit = profit; i->quote = quotation; i->value = value; i->cost = cost; } switch(security->type()) { case SECURITY_TYPE_BOND: {i->setText(7, tr("Bond")); break;} case SECURITY_TYPE_STOCK: {i->setText(7, tr("Stock", "Financial stock")); break;} case SECURITY_TYPE_MUTUAL_FUND: {i->setText(7, tr("Mutual Fund")); break;} case SECURITY_TYPE_OTHER: {i->setText(7, tr("Other")); break;} } securitiesView->insertTopLevelItem(securitiesView->topLevelItemCount(), i); if(cost > 0.0) i->setForeground(4, createExpenseColor(i, 0)); else if(cost < 0.0) i->setForeground(4, createIncomeColor(i, 0)); else i->setForeground(4, createTransferColor(i, 0)); if(profit < 0.0) i->setForeground(5, createExpenseColor(i, 0)); else if(profit > 0.0) i->setForeground(5, createIncomeColor(i, 0)); else i->setForeground(5, createTransferColor(i, 0)); if(rate < 0.0) i->setForeground(6, createExpenseColor(i, 0)); else if(rate > 0.0) i->setForeground(6, createIncomeColor(i, 0)); else i->setForeground(6, createTransferColor(i, 0)); total_rate *= total_cost; total_value += i->value; total_cost += i->scost; total_rate += i->scost * rate; if(is_zero(total_cost)) total_rate = 0.0; else total_rate /= total_cost; total_profit += i->sprofit; updateSecuritiesStatistics(); securitiesView->setSortingEnabled(true); } void Eqonomize::updateSecurity(Security *security) { QTreeWidgetItemIterator it(securitiesView); QTreeWidgetItem *i = *it; while(i != NULL) { if(((SecurityListViewItem*) i)->security() == security) { updateSecurity(i); break; } ++it; i = *it; } } void Eqonomize::updateSecurity(QTreeWidgetItem *i_pre) { SecurityListViewItem* i = (SecurityListViewItem*) i_pre; Security *security = i->security(); Currency *cur = security->currency(); total_rate *= total_cost; total_value -= i->value; total_cost -= i->scost; total_rate += i->scost * i->rate; if(is_zero(total_cost)) total_rate = 0.0; else total_rate /= total_cost; total_profit -= ((SecurityListViewItem*) i)->sprofit; double value = 0.0, cost = 0.0, rate = 0.0, profit = 0.0, quotation = 0.0, shares = 0.0; value = security->value(securities_to_date, 1); cost = security->cost(securities_to_date); if(securities_to_date > QDate::currentDate()) quotation = security->expectedQuotation(securities_to_date); else quotation = security->getQuotation(securities_to_date); shares = security->shares(securities_to_date, true); if(securitiesPeriodFromButton->isChecked()) { rate = security->yearlyRate(securities_from_date, securities_to_date); profit = security->profit(securities_from_date, securities_to_date, true); } else { rate = security->yearlyRate(securities_to_date); profit = security->profit(securities_to_date, true); } i->rate = rate; i->shares = shares; if(cur != budget->defaultCurrency()) { i->sprofit = security->profit(securities_to_date, true, false, budget->defaultCurrency()); i->scost = security->cost(securities_to_date, false, budget->defaultCurrency()); i->profit = cur->convertTo(profit, budget->defaultCurrency()); i->quote = cur->convertTo(quotation, budget->defaultCurrency()); i->value = cur->convertTo(value, budget->defaultCurrency()); i->cost = cur->convertTo(cost, budget->defaultCurrency()); } else { i->sprofit = profit; i->scost = cost; i->profit = profit; i->quote = quotation; i->value = value; i->cost = cost; } total_rate *= total_cost; total_value += i->value; total_cost += i->scost; total_rate += i->scost * rate; if(is_zero(total_cost) != 0.0) total_rate = 0.0; else total_rate /= total_cost; total_profit += i->profit; i->setText(0, security->name()); switch(security->type()) { case SECURITY_TYPE_BOND: {i->setText(7, tr("Bond")); break;} case SECURITY_TYPE_STOCK: {i->setText(7, tr("Stock", "Financial stock")); break;} case SECURITY_TYPE_MUTUAL_FUND: {i->setText(7, tr("Mutual Fund")); break;} case SECURITY_TYPE_OTHER: {i->setText(7, tr("Other")); break;} } i->setText(1, cur->formatValue(value)); i->setText(2, budget->formatValue(shares, security->decimals())); i->setText(3, cur->formatValue(quotation, security->quotationDecimals())); i->setText(4, cur->formatValue(cost)); i->setText(5, cur->formatValue(profit)); i->setText(6, right_align_values ? budget->formatValue(rate * 100, 2) + "% " : budget->formatValue(rate * 100, 2) + "%"); i->setText(8, security->account()->name()); if(cost > 0.0) i->setForeground(4, createExpenseColor(i, 0)); else if(cost < 0.0) i->setForeground(4, createIncomeColor(i, 0)); else i->setForeground(4, createTransferColor(i, 0)); if(profit < 0.0) i->setForeground(5, createExpenseColor(i, 0)); else if(profit > 0.0) i->setForeground(5, createIncomeColor(i, 0)); else i->setForeground(5, createTransferColor(i, 0)); if(rate < 0.0) i->setForeground(6, createExpenseColor(i, 0)); else if(rate > 0.0) i->setForeground(6, createIncomeColor(i, 0)); else i->setForeground(6, createTransferColor(i, 0)); updateSecuritiesStatistics(); } void Eqonomize::updateSecurities() { securitiesView->clear(); total_value = 0.0; total_cost = 0.0; total_profit = 0.0; total_rate = 0.0; for(SecurityList::const_iterator it = budget->securities.constBegin(); it != budget->securities.constEnd(); ++it) { Security *security = *it; appendSecurity(security); } } void Eqonomize::addNewSchedule(ScheduledTransaction *strans, QWidget *parent) { QSettings settings; settings.beginGroup("GeneralOptions"); QTime confirm_time = settings.value("scheduleConfirmationTime", QTime(18, 0)).toTime(); settings.endGroup(); if(strans->isOneTimeTransaction() && strans->transaction()->date() <= QDate::currentDate()) { Transactions *trans = strans->transaction()->copy(); delete strans; budget->addTransactions(trans); transactionAdded(trans); } else if(strans->recurrence() && strans->date() <= QDate::currentDate() && ((QTime::currentTime() >= confirm_time && strans->recurrence()->nextOccurrence(strans->date(), false) > QDate::currentDate()) || (QTime::currentTime() < confirm_time && strans->recurrence()->nextOccurrence(strans->date(), false) >= QDate::currentDate()))) { Transactions *trans = strans->realize(strans->date()); addTransactionLinks(trans); budget->addTransactions(trans); transactionAdded(trans); budget->addScheduledTransaction(strans); transactionAdded(strans); } else { budget->addScheduledTransaction(strans); transactionAdded(strans); checkSchedule(true, parent); } } void Eqonomize::newExpenseWithLoan() { newExpenseWithLoan(this); } bool Eqonomize::newExpenseWithLoan(QString description_value, double value_value, double quantity_value, QDate date_value, ExpensesAccount *category_value, QString payee_value, QString comment_value) { budget->setRecordNewAccounts(true); budget->setRecordNewSecurities(true); budget->resetDefaultCurrencyChanged(); budget->resetCurrenciesModified(); budget->setRecordNewTags(true); TransactionEditDialog *dialog = new TransactionEditDialog(b_extra, TRANSACTION_TYPE_EXPENSE, NULL, false, NULL, SECURITY_ALL_VALUES, false, budget, this, true, false, true); dialog->editWidget->updateAccounts(); dialog->editWidget->setValues(description_value, value_value, quantity_value, date_value, NULL, category_value, payee_value, comment_value); if(dialog->editWidget->checkAccounts() && dialog->exec() == QDialog::Accepted) { Transactions *trans = dialog->editWidget->createTransactionWithLoan(); if(trans) { foreach(Account* acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(QString str, budget->newTags) tagAdded(str); budget->newTags.clear(); foreach(Security *sec, budget->newSecurities) securityAdded(sec); budget->newSecurities.clear(); if(trans->date() > QDate::currentDate()) { ScheduledTransaction *strans_new = new ScheduledTransaction(budget, trans, NULL); budget->addScheduledTransaction(strans_new); transactionAdded(strans_new); } else { budget->addTransactions(trans); transactionAdded(trans); } if(budget->currenciesModified() || budget->defaultCurrencyChanged()) currenciesModified(); budget->setRecordNewAccounts(false); budget->setRecordNewSecurities(false); budget->setRecordNewTags(false); dialog->deleteLater(); return true; } } foreach(Account *acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(QString str, budget->newTags) tagAdded(str); budget->newTags.clear(); foreach(Security *sec, budget->newSecurities) securityAdded(sec); budget->newSecurities.clear(); if(budget->currenciesModified() || budget->defaultCurrencyChanged()) currenciesModified(); budget->setRecordNewAccounts(false); budget->setRecordNewSecurities(false); budget->setRecordNewTags(false); dialog->deleteLater(); return false; } bool Eqonomize::newExpenseWithLoan(QWidget *parent) { budget->setRecordNewAccounts(true); budget->setRecordNewSecurities(true); budget->resetDefaultCurrencyChanged(); budget->resetCurrenciesModified(); budget->setRecordNewTags(true); TransactionEditDialog *dialog = new TransactionEditDialog(b_extra, TRANSACTION_TYPE_EXPENSE, NULL, false, NULL, SECURITY_ALL_VALUES, false, budget, parent, true, false, true); dialog->editWidget->updateAccounts(); if(dialog->editWidget->checkAccounts() && dialog->exec() == QDialog::Accepted) { Transactions *trans = dialog->editWidget->createTransactionWithLoan(); if(trans) { foreach(Account* acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(Security *sec, budget->newSecurities) securityAdded(sec); budget->newSecurities.clear(); foreach(QString str, budget->newTags) tagAdded(str); budget->newTags.clear(); if(trans->date() > QDate::currentDate()) { ScheduledTransaction *strans_new = new ScheduledTransaction(budget, trans, NULL); budget->addScheduledTransaction(strans_new); transactionAdded(strans_new); } else { budget->addTransactions(trans); transactionAdded(trans); } if(budget->currenciesModified() || budget->defaultCurrencyChanged()) currenciesModified(); budget->setRecordNewAccounts(false); budget->setRecordNewSecurities(false); budget->setRecordNewTags(false); dialog->deleteLater(); return true; } } foreach(Account *acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(Security *sec, budget->newSecurities) securityAdded(sec); budget->newSecurities.clear(); foreach(QString str, budget->newTags) tagAdded(str); budget->newTags.clear(); if(budget->currenciesModified() || budget->defaultCurrencyChanged()) currenciesModified(); budget->setRecordNewAccounts(false); budget->setRecordNewSecurities(false); budget->setRecordNewTags(false); dialog->deleteLater(); return false; } void Eqonomize::newMultiAccountExpense() { newMultiAccountTransaction(this, true); } void Eqonomize::newMultiAccountIncome() { newMultiAccountTransaction(this, false); } bool Eqonomize::newMultiAccountTransaction(bool create_expenses, QString description_string, CategoryAccount *category_account, double quantity_value, QString comment_string) { budget->setRecordNewAccounts(true); budget->setRecordNewSecurities(true); budget->resetDefaultCurrencyChanged(); budget->resetCurrenciesModified(); budget->setRecordNewTags(true); ScheduledTransaction *strans = EditScheduledMultiAccountDialog::newScheduledTransaction(description_string, category_account, quantity_value, comment_string, budget, this, create_expenses, b_extra, true); if(strans) { foreach(Account* acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(Security *sec, budget->newSecurities) securityAdded(sec); budget->newSecurities.clear(); foreach(QString str, budget->newTags) tagAdded(str); budget->newTags.clear(); addNewSchedule(strans, this); if(budget->currenciesModified() || budget->defaultCurrencyChanged()) currenciesModified(); budget->setRecordNewAccounts(false); budget->setRecordNewSecurities(false); budget->setRecordNewTags(false); return true; } foreach(Account* acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(Security *sec, budget->newSecurities) securityAdded(sec); budget->newSecurities.clear(); foreach(QString str, budget->newTags) tagAdded(str); budget->newTags.clear(); if(budget->currenciesModified() || budget->defaultCurrencyChanged()) currenciesModified(); budget->setRecordNewAccounts(false); budget->setRecordNewSecurities(false); budget->setRecordNewTags(false); return false; } bool Eqonomize::newMultiAccountTransaction(QWidget *parent, bool create_expenses) { budget->setRecordNewAccounts(true); budget->setRecordNewSecurities(true); budget->resetDefaultCurrencyChanged(); budget->resetCurrenciesModified(); budget->setRecordNewTags(true); ScheduledTransaction *strans = EditScheduledMultiAccountDialog::newScheduledTransaction(budget, parent, create_expenses, b_extra, true); if(strans) { foreach(Account* acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(Security *sec, budget->newSecurities) securityAdded(sec); budget->newSecurities.clear(); foreach(QString str, budget->newTags) tagAdded(str); budget->newTags.clear(); addNewSchedule(strans, parent); if(budget->currenciesModified() || budget->defaultCurrencyChanged()) currenciesModified(); budget->setRecordNewAccounts(false); budget->setRecordNewSecurities(false); budget->setRecordNewTags(false); return true; } foreach(Account* acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(Security *sec, budget->newSecurities) securityAdded(sec); budget->newSecurities.clear(); foreach(QString str, budget->newTags) tagAdded(str); budget->newTags.clear(); if(budget->currenciesModified() || budget->defaultCurrencyChanged()) currenciesModified(); budget->setRecordNewAccounts(false); budget->setRecordNewSecurities(false); budget->setRecordNewTags(false); return false; } void Eqonomize::newMultiItemTransaction() { newMultiItemTransaction(this); } bool Eqonomize::newMultiItemTransaction(QWidget *parent, AssetsAccount *account) { budget->setRecordNewAccounts(true); budget->setRecordNewSecurities(true); budget->resetDefaultCurrencyChanged(); budget->resetCurrenciesModified(); budget->setRecordNewTags(true); ScheduledTransaction *strans = EditScheduledMultiItemDialog::newScheduledTransaction(budget, parent, account, b_extra, true); if(strans) { foreach(Account* acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(Security *sec, budget->newSecurities) securityAdded(sec); budget->newSecurities.clear(); foreach(QString str, budget->newTags) tagAdded(str); budget->newTags.clear(); addNewSchedule(strans, parent); if(budget->currenciesModified() || budget->defaultCurrencyChanged()) currenciesModified(); budget->setRecordNewAccounts(false); budget->setRecordNewSecurities(false); budget->setRecordNewTags(false); return true; } foreach(Account* acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(Security *sec, budget->newSecurities) securityAdded(sec); budget->newSecurities.clear(); foreach(QString str, budget->newTags) tagAdded(str); budget->newTags.clear(); if(budget->currenciesModified() || budget->defaultCurrencyChanged()) currenciesModified(); budget->setRecordNewAccounts(false); budget->setRecordNewSecurities(false); budget->setRecordNewTags(false); return false; } void Eqonomize::newDebtPayment() { newDebtPayment(this); } void Eqonomize::newDebtInterest() { newDebtPayment(this, NULL, true); } bool Eqonomize::newDebtPayment(QWidget *parent, AssetsAccount *loan, bool only_interest) { budget->setRecordNewAccounts(true); budget->setRecordNewSecurities(true); budget->resetDefaultCurrencyChanged(); budget->resetCurrenciesModified(); budget->setRecordNewTags(true); ScheduledTransaction *strans = EditScheduledDebtPaymentDialog::newScheduledTransaction(budget, parent, loan, b_extra, true, only_interest); if(strans) { foreach(Account* acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(Security *sec, budget->newSecurities) securityAdded(sec); budget->newSecurities.clear(); foreach(QString str, budget->newTags) tagAdded(str); budget->newTags.clear(); addNewSchedule(strans, parent); if(budget->currenciesModified() || budget->defaultCurrencyChanged()) currenciesModified(); budget->setRecordNewAccounts(false); budget->setRecordNewSecurities(false); budget->setRecordNewTags(false); return true; } foreach(Account* acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(Security *sec, budget->newSecurities) securityAdded(sec); budget->newSecurities.clear(); foreach(QString str, budget->newTags) tagAdded(str); budget->newTags.clear(); if(budget->currenciesModified() || budget->defaultCurrencyChanged()) currenciesModified(); budget->setRecordNewAccounts(false); budget->setRecordNewSecurities(false); budget->setRecordNewTags(false); return false; } bool Eqonomize::editSplitTransaction(SplitTransaction *split) { return editSplitTransaction(split, this); } bool Eqonomize::editSplitTransaction(SplitTransaction *split, QWidget *parent, bool temporary_split, bool clone_trans, bool allow_account_creation) { Recurrence *rec = NULL; if(allow_account_creation) { budget->setRecordNewAccounts(true); budget->setRecordNewSecurities(true); budget->resetDefaultCurrencyChanged(); budget->resetCurrenciesModified(); budget->setRecordNewTags(true); } SplitTransaction *new_split = NULL; if(split->type() == SPLIT_TRANSACTION_TYPE_MULTIPLE_ITEMS) { new_split = EditScheduledMultiItemDialog::editTransaction((MultiItemTransaction*) split, rec, parent, b_extra, allow_account_creation, clone_trans); } else if(split->type() == SPLIT_TRANSACTION_TYPE_MULTIPLE_ACCOUNTS) { new_split = EditScheduledMultiAccountDialog::editTransaction((MultiAccountTransaction*) split, rec, parent, b_extra, allow_account_creation, clone_trans); } else if(split->type() == SPLIT_TRANSACTION_TYPE_LOAN) { new_split = EditScheduledDebtPaymentDialog::editTransaction((DebtPayment*) split, rec, parent, b_extra, allow_account_creation, clone_trans); } if(new_split) { if(!clone_trans) removeOldLinks(new_split, split); if(!temporary_split && !clone_trans) { budget->removeSplitTransaction(split, true); transactionRemoved(split); delete split; } split = new_split; if(allow_account_creation) { foreach(Account* acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(Security *sec, budget->newSecurities) securityAdded(sec); budget->newSecurities.clear(); foreach(QString str, budget->newTags) tagAdded(str); budget->newTags.clear(); } if((!rec || rec->firstOccurrence() == rec->lastOccurrence()) && split->date() <= QDate::currentDate()) { budget->addSplitTransaction(split); transactionAdded(split); } else { QSettings settings; settings.beginGroup("GeneralOptions"); QTime confirm_time = settings.value("scheduleConfirmationTime", QTime(18, 0)).toTime(); settings.endGroup(); ScheduledTransaction *strans = new ScheduledTransaction(budget, split, rec); if(strans->recurrence() && strans->date() <= QDate::currentDate() && ((QTime::currentTime() >= confirm_time && strans->recurrence()->nextOccurrence(strans->date(), false) > QDate::currentDate()) || (QTime::currentTime() < confirm_time && strans->recurrence()->nextOccurrence(strans->date(), false) >= QDate::currentDate()))) { Transactions *new_trans = strans->realize(strans->date()); addTransactionLinks(new_trans); budget->addTransactions(new_trans); transactionAdded(new_trans); budget->addScheduledTransaction(strans); transactionAdded(strans); } else { budget->addScheduledTransaction(strans); transactionAdded(strans); checkSchedule(true, parent, allow_account_creation); } } if(allow_account_creation) { if(budget->currenciesModified() || budget->defaultCurrencyChanged()) currenciesModified(); budget->setRecordNewAccounts(false); budget->setRecordNewSecurities(false); budget->setRecordNewTags(false); } return true; } if(allow_account_creation) { foreach(Account* acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(Security *sec, budget->newSecurities) securityAdded(sec); budget->newSecurities.clear(); foreach(QString str, budget->newTags) tagAdded(str); budget->newTags.clear(); if(budget->currenciesModified() || budget->defaultCurrencyChanged()) currenciesModified(); budget->setRecordNewAccounts(false); budget->setRecordNewSecurities(false); budget->setRecordNewTags(false); } return false; } void Eqonomize::editSelectedTimestamp() { TransactionListWidget *w = NULL; if(tabs->currentIndex() == EXPENSES_PAGE_INDEX) w = expensesWidget; else if(tabs->currentIndex() == INCOMES_PAGE_INDEX) w = incomesWidget; else if(tabs->currentIndex() == TRANSFERS_PAGE_INDEX) w = transfersWidget; else if(tabs->currentIndex() == SCHEDULE_PAGE_INDEX) { ScheduleListViewItem *i = (ScheduleListViewItem*) selectedItem(scheduleView); if(i) { QList trans; trans << i->scheduledTransaction(); editTimestamp(trans); } } if(!w) return; w->editTimestamp(); } bool Eqonomize::editTimestamp(QList trans, QWidget *parent) { if(trans.count() == 0) return false; for(int i = 0; i < trans.count(); i++) { if(trans[i]->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE && ((Transaction*) trans[i])->parentSplit() && ((Transaction*) trans[i])->parentSplit()->type() != SPLIT_TRANSACTION_TYPE_MULTIPLE_ACCOUNTS) trans[i] = ((Transaction*) trans[i])->parentSplit(); for(int i2 = 0; i2 < i; i2++) { if(trans[i2] == trans[i]) { trans.removeAt(i2); i--; break; } } } QDialog *dialog = new QDialog(parent == NULL ? this : parent); dialog->setWindowTitle(tr("Timestamp")); QVBoxLayout *box1 = new QVBoxLayout(dialog); QScrollArea *scroll = NULL; QGridLayout *grid = NULL; if(trans.count() > 5) { scroll = new QScrollArea(dialog); scroll->setFrameShape(QFrame::NoFrame); QWidget *widget = new QWidget(dialog); scroll->setWidget(widget); grid = new QGridLayout(widget); scroll->setWidgetResizable(true); box1->addWidget(scroll); widget->show(); } else { grid = new QGridLayout(); box1->addLayout(grid); } QList timeEdit; int row = 0; for(int i = 0; i < trans.count(); i++) { if(i > 0 || trans.count() > 1) { grid->addWidget(new QLabel(trans[i]->description() + ":", dialog), row, 0); } timeEdit << new QDateTimeEdit(QDateTime::fromMSecsSinceEpoch(trans[i]->timestamp() * 1000), dialog); if(timeEdit.last()->displayFormat().endsWith(":mm")) timeEdit.last()->setDisplayFormat(timeEdit.last()->displayFormat() + ":ss"); grid->addWidget(timeEdit.last(), row, (i > 0 || trans.count() > 1) ? 1 : 0); row++; } QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, dialog); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), dialog, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), dialog, SLOT(accept())); box1->addWidget(buttonBox); if(dialog->exec() == QDialog::Accepted) { if(trans.count() > 1) startBatchEdit(); for(int i = 0; i < trans.count(); i++) { trans[i]->setTimestamp(timeEdit[i]->dateTime().toMSecsSinceEpoch() / 1000); transactionModified(trans[i], trans[i]); } if(trans.count() > 1) endBatchEdit(); dialog->deleteLater(); return true; } dialog->deleteLater(); return false; } bool Eqonomize::splitUpTransaction(SplitTransaction *split) { expensesWidget->onTransactionSplitUp(split); incomesWidget->onTransactionSplitUp(split); transfersWidget->onTransactionSplitUp(split); int c = split->count(); for(int i = 0; i < c; i++) { Transaction *trans = split->at(i); for(int i2 = 0; i2 < split->tagsCount(); i2++) trans->addTag(split->getTag(i2)); for(int i2 = 0; i2 < split->linksCount(); i2++) { trans->addLinkId(split->getLinkId(i2)); Transactions *ltrans = split->getLink(i2); if(ltrans) ltrans->addLink(trans); } if(trans->comment().isEmpty()) trans->setComment(split->comment()); if(trans->associatedFile().isEmpty()) trans->setAssociatedFile(split->associatedFile()); } for(int i2 = 0; i2 < split->linksCount(); i2++) { Transactions *ltrans = split->getLink(i2); if(ltrans) { ltrans->removeLink(split); expensesWidget->onTransactionModified(ltrans, ltrans); incomesWidget->onTransactionModified(ltrans, ltrans); transfersWidget->onTransactionModified(ltrans, ltrans); } } split->clear(true); budget->removeSplitTransaction(split, true); transactionRemoved(split); delete split; setModified(true); return true; } bool Eqonomize::removeSplitTransaction(SplitTransaction *split) { budget->removeSplitTransaction(split, true); transactionRemoved(split); delete split; return true; } bool Eqonomize::newScheduledTransaction(int transaction_type, Security *security, bool select_security) { return newScheduledTransaction(transaction_type, security, select_security, this); } bool Eqonomize::newScheduledTransaction(int transaction_type, Security *security, bool select_security, QWidget *parent, Account *account) { budget->setRecordNewAccounts(true); budget->setRecordNewSecurities(true); budget->resetDefaultCurrencyChanged(); budget->resetCurrenciesModified(); budget->setRecordNewTags(true); ScheduledTransaction *strans = EditScheduledTransactionDialog::newScheduledTransaction(transaction_type, budget, parent, security, select_security, account, b_extra, true); if(strans) { foreach(Account* acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(Security *sec, budget->newSecurities) securityAdded(sec); budget->newSecurities.clear(); foreach(QString str, budget->newTags) tagAdded(str); budget->newTags.clear(); addNewSchedule(strans, parent); if(budget->currenciesModified() || budget->defaultCurrencyChanged()) currenciesModified(); budget->setRecordNewAccounts(false); budget->setRecordNewSecurities(false); budget->setRecordNewTags(false); return true; } foreach(Account* acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(Security *sec, budget->newSecurities) securityAdded(sec); budget->newSecurities.clear(); foreach(QString str, budget->newTags) tagAdded(str); budget->newTags.clear(); if(budget->currenciesModified() || budget->defaultCurrencyChanged()) currenciesModified(); budget->setRecordNewAccounts(false); budget->setRecordNewSecurities(false); budget->setRecordNewTags(false); return false; } void Eqonomize::newScheduledExpense() { newScheduledTransaction(TRANSACTION_TYPE_EXPENSE); } void Eqonomize::newScheduledIncome() { newScheduledTransaction(TRANSACTION_TYPE_INCOME); } void Eqonomize::newScheduledTransfer() { newScheduledTransaction(TRANSACTION_TYPE_TRANSFER); } bool Eqonomize::editScheduledTransaction(ScheduledTransaction *strans) { return editScheduledTransaction(strans, this); } bool Eqonomize::editScheduledTransaction(ScheduledTransaction *strans, QWidget *parent, bool clone_trans, bool allow_account_creation) { if(allow_account_creation) { budget->setRecordNewAccounts(true); budget->setRecordNewSecurities(true); budget->resetDefaultCurrencyChanged(); budget->resetCurrenciesModified(); budget->resetDefaultCurrencyChanged(); budget->resetCurrenciesModified(); budget->setRecordNewTags(true); } bool b = false; if(strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE) { ScheduledTransaction *old_strans = strans->copy(); if(EditScheduledTransactionDialog::editScheduledTransaction(clone_trans ? old_strans : strans, parent, true, b_extra, allow_account_creation, clone_trans)) { if(allow_account_creation) { foreach(Account* acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(Security *sec, budget->newSecurities) securityAdded(sec); budget->newSecurities.clear(); foreach(QString str, budget->newTags) tagAdded(str); budget->newTags.clear(); } if(clone_trans) { old_strans->setId(0); old_strans->setFirstRevision(budget->revision()); old_strans->transaction()->setId(0); old_strans->transaction()->setFirstRevision(budget->revision()); addNewSchedule(old_strans, parent); } else { removeOldLinks(strans, old_strans); if(!strans->recurrence() && strans->transaction()->date() <= QDate::currentDate()) { Transactions *trans = strans->transaction()->copy(); transactionRemoved(strans, old_strans); budget->removeScheduledTransaction(strans, true); delete strans; budget->addTransactions(trans); transactionAdded(trans); } else { transactionModified(strans, old_strans); checkSchedule(true, parent, allow_account_creation); } delete old_strans; } b = true; } else { if(allow_account_creation) { foreach(Account* acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(Security *sec, budget->newSecurities) securityAdded(sec); budget->newSecurities.clear(); } delete old_strans; } } else if(strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { ScheduledTransaction *strans_new = NULL; if(((SplitTransaction*) strans->transaction())->type() == SPLIT_TRANSACTION_TYPE_MULTIPLE_ITEMS) { strans_new = EditScheduledMultiItemDialog::editScheduledTransaction(strans, parent, b_extra, allow_account_creation, clone_trans); } else if(((SplitTransaction*) strans->transaction())->type() == SPLIT_TRANSACTION_TYPE_MULTIPLE_ACCOUNTS) { strans_new = EditScheduledMultiAccountDialog::editScheduledTransaction(strans, parent, b_extra, allow_account_creation, clone_trans); } else if(((SplitTransaction*) strans->transaction())->type() == SPLIT_TRANSACTION_TYPE_LOAN) { strans_new = EditScheduledDebtPaymentDialog::editScheduledTransaction(strans, parent, b_extra, allow_account_creation, clone_trans); } if(strans_new) { if(allow_account_creation) { foreach(Account* acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(Security *sec, budget->newSecurities) securityAdded(sec); budget->newSecurities.clear(); } budget->removeScheduledTransaction(strans, true); if(allow_account_creation) { foreach(QString str, budget->newTags) tagAdded(str); budget->newTags.clear(); } if(clone_trans) { addNewSchedule(strans_new, parent); } else { removeOldLinks(strans_new, strans); transactionRemoved(strans); delete strans; strans = strans_new; if(!strans->recurrence() && strans->transaction()->date() <= QDate::currentDate()) { Transactions *trans = strans->transaction()->copy(); delete strans; budget->addTransactions(trans); transactionAdded(trans); } else { budget->addScheduledTransaction(strans); transactionAdded(strans); checkSchedule(true, parent, allow_account_creation); } } b = true; } else if(allow_account_creation) { foreach(Account* acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(Security *sec, budget->newSecurities) securityAdded(sec); budget->newSecurities.clear(); foreach(QString str, budget->newTags) tagAdded(str); budget->newTags.clear(); } } if(allow_account_creation) { if(budget->currenciesModified() || budget->defaultCurrencyChanged()) currenciesModified(); budget->setRecordNewAccounts(false); budget->setRecordNewSecurities(false); budget->setRecordNewTags(false); } return b; } bool Eqonomize::editOccurrence(ScheduledTransaction *strans, const QDate &date) { return editOccurrence(strans, date, this); } bool Eqonomize::editOccurrence(ScheduledTransaction *strans, const QDate &date, QWidget *parent) { budget->setRecordNewAccounts(true); budget->setRecordNewSecurities(true); budget->resetDefaultCurrencyChanged(); budget->resetCurrenciesModified(); budget->setRecordNewTags(true); if(strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE) { Security *security = NULL; if(strans->transactiontype() == TRANSACTION_TYPE_SECURITY_BUY || strans->transactiontype() == TRANSACTION_TYPE_SECURITY_SELL) { security = ((SecurityTransaction*) strans->transaction())->security(); } else if(strans->transactiontype() == TRANSACTION_TYPE_INCOME && ((Income*) strans->transaction())->security()) { security = ((Income*) strans->transaction())->security(); } TransactionEditDialog *dialog = new TransactionEditDialog(b_extra, strans->transactionsubtype() == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND ? TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND : strans->transactiontype(), NULL, false, security, SECURITY_ALL_VALUES, security != NULL, budget, parent, true); dialog->editWidget->updateAccounts(); dialog->editWidget->setTransaction((Transaction*) strans->transaction(), date); if(dialog->editWidget->checkAccounts() && dialog->exec() == QDialog::Accepted) { foreach(Account* acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(Security *sec, budget->newSecurities) securityAdded(sec); budget->newSecurities.clear(); foreach(QString str, budget->newTags) tagAdded(str); budget->newTags.clear(); Transaction *trans = dialog->editWidget->createTransaction(); if(trans) { addTransactionLinks(trans); if(trans->date() > QDate::currentDate()) { ScheduledTransaction *strans_new = new ScheduledTransaction(budget, trans, NULL); budget->addScheduledTransaction(strans_new); transactionAdded(strans_new); } else { budget->addTransaction(trans); transactionAdded(trans); } ScheduledTransaction *old_strans = strans->copy(); strans->addException(date); transactionModified(strans, old_strans); delete old_strans; dialog->deleteLater(); if(budget->currenciesModified() || budget->defaultCurrencyChanged()) currenciesModified(); budget->setRecordNewAccounts(false); budget->setRecordNewSecurities(false); budget->setRecordNewTags(false); return true; } } dialog->deleteLater(); } else if(strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { if(((SplitTransaction*) strans->transaction())->type() == SPLIT_TRANSACTION_TYPE_MULTIPLE_ITEMS) { EditMultiItemDialog *dialog = new EditMultiItemDialog(budget, parent, NULL, b_extra, true); dialog->editWidget->setTransaction((MultiItemTransaction*) strans->transaction(), date); if(dialog->editWidget->checkAccounts() && dialog->exec() == QDialog::Accepted) { foreach(Account* acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(Security *sec, budget->newSecurities) securityAdded(sec); budget->newSecurities.clear(); foreach(QString str, budget->newTags) tagAdded(str); budget->newTags.clear(); MultiItemTransaction *split = dialog->editWidget->createTransaction(); if(split) { addTransactionLinks(split); if(split->date() > QDate::currentDate()) { ScheduledTransaction *strans_new = new ScheduledTransaction(budget, split, NULL); budget->addScheduledTransaction(strans_new); transactionAdded(strans_new); } else { budget->addSplitTransaction(split); transactionAdded(split); } transactionRemoved(strans); strans->addException(date); transactionAdded(strans); dialog->deleteLater(); if(budget->currenciesModified() || budget->defaultCurrencyChanged()) currenciesModified(); budget->setRecordNewAccounts(false); budget->setRecordNewSecurities(false); budget->setRecordNewTags(false); return true; } } dialog->deleteLater(); } else if(((SplitTransaction*) strans->transaction())->type() == SPLIT_TRANSACTION_TYPE_MULTIPLE_ACCOUNTS) { EditMultiAccountDialog *dialog = new EditMultiAccountDialog(budget, parent, ((MultiAccountTransaction*) strans->transaction())->transactiontype() == TRANSACTION_TYPE_EXPENSE, b_extra, true); dialog->editWidget->setTransaction((MultiAccountTransaction*) strans->transaction(), date); if(dialog->editWidget->checkAccounts() && dialog->exec() == QDialog::Accepted) { foreach(Account* acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(Security *sec, budget->newSecurities) securityAdded(sec); budget->newSecurities.clear(); foreach(QString str, budget->newTags) tagAdded(str); budget->newTags.clear(); MultiAccountTransaction *split = dialog->editWidget->createTransaction(); if(split) { addTransactionLinks(split); if(split->date() > QDate::currentDate()) { ScheduledTransaction *strans_new = new ScheduledTransaction(budget, split, NULL); budget->addScheduledTransaction(strans_new); transactionAdded(strans_new); } else { budget->addSplitTransaction(split); transactionAdded(split); } transactionRemoved(strans); strans->addException(date); transactionAdded(strans); dialog->deleteLater(); if(budget->currenciesModified() || budget->defaultCurrencyChanged()) currenciesModified(); budget->setRecordNewAccounts(false); budget->setRecordNewSecurities(false); budget->setRecordNewTags(false); return true; } } dialog->deleteLater(); } else if(((SplitTransaction*) strans->transaction())->type() == SPLIT_TRANSACTION_TYPE_LOAN) { EditDebtPaymentDialog *dialog = new EditDebtPaymentDialog(budget, parent, NULL, true); dialog->editWidget->setTransaction((DebtPayment*) strans->transaction(), date); if(dialog->editWidget->checkAccounts() && dialog->exec() == QDialog::Accepted) { foreach(Account* acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(Security *sec, budget->newSecurities) securityAdded(sec); budget->newSecurities.clear(); foreach(QString str, budget->newTags) tagAdded(str); budget->newTags.clear(); DebtPayment *split = dialog->editWidget->createTransaction(); if(split) { addTransactionLinks(split); if(split->date() > QDate::currentDate()) { ScheduledTransaction *strans_new = new ScheduledTransaction(budget, split, NULL); budget->addScheduledTransaction(strans_new); transactionAdded(strans_new); } else { budget->addSplitTransaction(split); transactionAdded(split); } transactionRemoved(strans); strans->addException(date); transactionAdded(strans); dialog->deleteLater(); if(budget->currenciesModified() || budget->defaultCurrencyChanged()) currenciesModified(); budget->setRecordNewAccounts(false); budget->setRecordNewSecurities(false); budget->setRecordNewTags(false); return true; } } dialog->deleteLater(); } } foreach(Account* acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(Security *sec, budget->newSecurities) securityAdded(sec); budget->newSecurities.clear(); foreach(QString str, budget->newTags) tagAdded(str); budget->newTags.clear(); if(budget->currenciesModified() || budget->defaultCurrencyChanged()) currenciesModified(); budget->setRecordNewAccounts(false); budget->setRecordNewSecurities(false); budget->setRecordNewTags(false); return false; } void Eqonomize::editScheduledTransaction() { ScheduleListViewItem *i = (ScheduleListViewItem*) selectedItem(scheduleView); if(i == NULL) return; editScheduledTransaction(i->scheduledTransaction()); } void Eqonomize::editOccurrence() { ScheduleListViewItem *i = (ScheduleListViewItem*) selectedItem(scheduleView); if(i == NULL) return; editOccurrence(i->scheduledTransaction(), i->date()); } void Eqonomize::cloneScheduledTransaction() { ScheduleListViewItem *i = (ScheduleListViewItem*) selectedItem(scheduleView); if(i == NULL) return; editScheduledTransaction(i->scheduledTransaction(), this, true); } bool Eqonomize::removeScheduledTransaction(ScheduledTransaction *strans) { budget->removeScheduledTransaction(strans, true); transactionRemoved(strans, strans, true); delete strans; return true; } void Eqonomize::removeScheduledTransaction() { ScheduleListViewItem *i = (ScheduleListViewItem*) selectedItem(scheduleView); if(i == NULL) return; removeScheduledTransaction(i->scheduledTransaction()); } bool Eqonomize::removeOccurrence(ScheduledTransaction *strans, const QDate &date) { if(strans->isOneTimeTransaction()) { removeScheduledTransaction(strans); } else if(strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE) { ScheduledTransaction *oldstrans = strans->copy(); strans->addException(date); transactionModified(strans, oldstrans); delete oldstrans; } else { transactionRemoved(strans); strans->addException(date); transactionAdded(strans); } return true; } void Eqonomize::removeOccurrence() { ScheduleListViewItem *i = (ScheduleListViewItem*) selectedItem(scheduleView); if(i == NULL) return; removeOccurrence(i->scheduledTransaction(), i->date()); } void Eqonomize::scheduleSelectionChanged() { ScheduleListViewItem *i = (ScheduleListViewItem*) selectedItem(scheduleView); if(i == NULL) { editScheduleButton->setEnabled(false); removeScheduleButton->setEnabled(false); } else { editScheduleButton->setEnabled(true); removeScheduleButton->setEnabled(true); ActionEditSchedule->setEnabled(true); ActionDeleteSchedule->setEnabled(true); ActionEditOccurrence->setEnabled(!i->scheduledTransaction()->isOneTimeTransaction()); ActionDeleteOccurrence->setEnabled(!i->scheduledTransaction()->isOneTimeTransaction()); } } void Eqonomize::scheduleExecuted(QTreeWidgetItem *i) { if(i == NULL) return; editScheduledTransaction(((ScheduleListViewItem*) i)->scheduledTransaction()); } void Eqonomize::hideScheduleColumn(bool do_show) { scheduleView->setColumnHidden(sender()->property("column_index").toInt(), !do_show); } void Eqonomize::popupScheduleHeaderMenu(const QPoint &p) { if(!scheduleHeaderPopupMenu) { scheduleHeaderPopupMenu = new QMenu(this); QTreeWidgetItem *header = scheduleView->headerItem(); QAction *a = NULL; for(int index = 1; index <= 8; index++) { if(index != 2 && index != 3) { a = scheduleHeaderPopupMenu->addAction(header->text(index)); a->setProperty("column_index", QVariant::fromValue(index)); a->setCheckable(true); a->setChecked(!scheduleView->isColumnHidden(index)); connect(a, SIGNAL(toggled(bool)), this, SLOT(hideScheduleColumn(bool))); } } SeparatorRightAlignValues = scheduleHeaderPopupMenu->addSeparator(); ActionRightAlignValues = scheduleHeaderPopupMenu->addAction(tr("Right align")); ActionRightAlignValues->setCheckable(true); connect(ActionRightAlignValues, SIGNAL(toggled(bool)), this, SLOT(valueAlignmentUpdated(bool))); } int c = scheduleView->columnAt(p.x()); SeparatorRightAlignValues->setVisible(c == 3); ActionRightAlignValues->setVisible(c == 3); if(c == 3) { ActionRightAlignValues->blockSignals(true); ActionRightAlignValues->setChecked(right_align_values); ActionRightAlignValues->blockSignals(false); } scheduleHeaderPopupMenu->popup(scheduleView->header()->viewport()->mapToGlobal(p)); } void Eqonomize::popupScheduleMenu(const QPoint &p) { if(!schedulePopupMenu) { schedulePopupMenu = new QMenu(this); schedulePopupMenu->addAction(ActionEditScheduledTransaction); schedulePopupMenu->addAction(ActionEditTransaction); schedulePopupMenu->addSeparator(); schedulePopupMenu->addAction(ActionDeleteScheduledTransaction); schedulePopupMenu->addAction(ActionDeleteTransaction); } schedulePopupMenu->popup(scheduleView->viewport()->mapToGlobal(p)); } void Eqonomize::editSelectedScheduledTransaction() { TransactionListWidget *w = NULL; if(tabs->currentIndex() == ACCOUNTS_PAGE_INDEX) return; else if(tabs->currentIndex() == EXPENSES_PAGE_INDEX) w = expensesWidget; else if(tabs->currentIndex() == INCOMES_PAGE_INDEX) w = incomesWidget; else if(tabs->currentIndex() == TRANSFERS_PAGE_INDEX) w = transfersWidget; else if(tabs->currentIndex() == SECURITIES_PAGE_INDEX) return; else if(tabs->currentIndex() == SCHEDULE_PAGE_INDEX) { editScheduledTransaction(); return; } if(!w) return; w->editScheduledTransaction(); } void Eqonomize::editSelectedSplitTransaction() { TransactionListWidget *w = NULL; if(tabs->currentIndex() == EXPENSES_PAGE_INDEX) w = expensesWidget; else if(tabs->currentIndex() == INCOMES_PAGE_INDEX) w = incomesWidget; else if(tabs->currentIndex() == TRANSFERS_PAGE_INDEX) w = transfersWidget; else return; if(!w) return; w->editSplitTransaction(); } void Eqonomize::joinSelectedTransactions() { TransactionListWidget *w = NULL; if(tabs->currentIndex() == EXPENSES_PAGE_INDEX) w = expensesWidget; else if(tabs->currentIndex() == INCOMES_PAGE_INDEX) w = incomesWidget; else if(tabs->currentIndex() == TRANSFERS_PAGE_INDEX) w = transfersWidget; else return; if(!w) return; w->joinTransactions(); } void Eqonomize::splitUpSelectedTransaction() { TransactionListWidget *w = NULL; if(tabs->currentIndex() == EXPENSES_PAGE_INDEX) w = expensesWidget; else if(tabs->currentIndex() == INCOMES_PAGE_INDEX) w = incomesWidget; else if(tabs->currentIndex() == TRANSFERS_PAGE_INDEX) w = transfersWidget; else return; if(!w) return; w->splitUpTransaction(); } bool Eqonomize::editTransaction(Transaction *trans) { return editTransaction(trans, this); } bool Eqonomize::editTransaction(Transaction *trans, QWidget *parent, bool clone_trans, bool allow_account_creation) { Transaction *oldtrans = trans->copy(); Recurrence *rec = NULL; if(allow_account_creation) { budget->setRecordNewAccounts(true); budget->setRecordNewSecurities(true); budget->resetDefaultCurrencyChanged(); budget->resetCurrenciesModified(); budget->setRecordNewTags(true); } if(trans->parentSplit() && !clone_trans) { SplitTransaction *split = trans->parentSplit(); if(split->type() == SPLIT_TRANSACTION_TYPE_MULTIPLE_ITEMS) { Security *security = NULL; if(trans->type() == TRANSACTION_TYPE_SECURITY_BUY || trans->type() == TRANSACTION_TYPE_SECURITY_SELL) { security = ((SecurityTransaction*) trans)->security(); } else if(trans->type() == TRANSACTION_TYPE_INCOME && ((Income*) trans)->security()) { security = ((Income*) trans)->security(); } TransactionEditDialog *dialog = new TransactionEditDialog(b_extra, trans->type(), split->currency(), trans->fromAccount() != ((MultiItemTransaction*) split)->account(), security, SECURITY_ALL_VALUES, security != NULL, budget, parent, allow_account_creation); dialog->editWidget->updateAccounts(((MultiItemTransaction*) split)->account()); dialog->editWidget->setTransaction(trans); if(dialog->exec() == QDialog::Accepted) { if(allow_account_creation) { foreach(Account* acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(Security *sec, budget->newSecurities) securityAdded(sec); foreach(QString str, budget->newTags) tagAdded(str); budget->newTags.clear(); budget->newSecurities.clear(); } if(dialog->editWidget->modifyTransaction(trans)) { removeOldLinks(trans, oldtrans); transactionModified(trans, oldtrans); delete oldtrans; if(allow_account_creation) { if(budget->currenciesModified() || budget->defaultCurrencyChanged()) currenciesModified(); budget->setRecordNewAccounts(false); budget->setRecordNewSecurities(false); budget->setRecordNewTags(false); } return true; } } dialog->deleteLater(); } else { if(allow_account_creation) { if(budget->currenciesModified() || budget->defaultCurrencyChanged()) currenciesModified(); budget->setRecordNewAccounts(false); budget->setRecordNewSecurities(false); budget->setRecordNewTags(false); } return editSplitTransaction(split, parent); } } else if(EditScheduledTransactionDialog::editTransaction(clone_trans ? oldtrans : trans, rec, parent, true, b_extra, allow_account_creation, clone_trans)) { if(allow_account_creation) { foreach(Account* acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(Security *sec, budget->newSecurities) securityAdded(sec); budget->newSecurities.clear(); foreach(QString str, budget->newTags) tagAdded(str); budget->newTags.clear(); } if(clone_trans) { oldtrans->setId(0); oldtrans->setFirstRevision(budget->revision()); ScheduledTransaction *strans = new ScheduledTransaction(budget, oldtrans, rec); addNewSchedule(strans, parent); } else { removeOldLinks(trans, oldtrans); if((!rec || rec->firstOccurrence() == rec->lastOccurrence()) && trans->date() <= QDate::currentDate()) { transactionModified(trans, oldtrans); } else { transactionRemoved(trans, oldtrans); budget->removeTransaction(trans, true); ScheduledTransaction *strans = new ScheduledTransaction(budget, trans, rec); QSettings settings; settings.beginGroup("GeneralOptions"); QTime confirm_time = settings.value("scheduleConfirmationTime", QTime(18, 0)).toTime(); settings.endGroup(); if(strans->recurrence() && strans->date() <= QDate::currentDate() && ((QTime::currentTime() >= confirm_time && strans->recurrence()->nextOccurrence(strans->date(), false) > QDate::currentDate()) || (QTime::currentTime() < confirm_time && strans->recurrence()->nextOccurrence(strans->date(), false) >= QDate::currentDate()))) { Transactions *new_trans = strans->realize(strans->date()); addTransactionLinks(new_trans); budget->addTransactions(new_trans); transactionAdded(new_trans); budget->addScheduledTransaction(strans); transactionAdded(strans); } else { budget->addScheduledTransaction(strans); transactionAdded(strans); checkSchedule(true, parent, allow_account_creation); } } delete oldtrans; } if(allow_account_creation) { if(budget->currenciesModified() || budget->defaultCurrencyChanged()) currenciesModified(); budget->setRecordNewAccounts(false); budget->setRecordNewSecurities(false); budget->setRecordNewTags(false); } return true; } if(allow_account_creation) { foreach(Account* acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(Security *sec, budget->newSecurities) securityAdded(sec); budget->newSecurities.clear(); foreach(QString str, budget->newTags) tagAdded(str); budget->newTags.clear(); if(budget->currenciesModified() || budget->defaultCurrencyChanged()) currenciesModified(); budget->setRecordNewAccounts(false); budget->setRecordNewSecurities(false); budget->setRecordNewTags(false); } delete oldtrans; return false; } void Eqonomize::newRefund() { if(tabs->currentIndex() == EXPENSES_PAGE_INDEX) expensesWidget->newRefundRepayment(); } void Eqonomize::newRepayment() { if(tabs->currentIndex() == INCOMES_PAGE_INDEX) incomesWidget->newRefundRepayment(); } void Eqonomize::newRefundRepayment() { if(tabs->currentIndex() == EXPENSES_PAGE_INDEX) expensesWidget->newRefundRepayment(); else if(tabs->currentIndex() == INCOMES_PAGE_INDEX) incomesWidget->newRefundRepayment(); } bool Eqonomize::newRefundRepayment(Transactions *trans) { if(!((trans->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT && ((SplitTransaction*) trans)->type() == SPLIT_TRANSACTION_TYPE_MULTIPLE_ACCOUNTS) || (trans->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE && (((Transaction*) trans)->type() == TRANSACTION_TYPE_EXPENSE || ((Transaction*) trans)->type() == TRANSACTION_TYPE_INCOME)))) return false; RefundDialog *dialog = new RefundDialog(trans, this, b_extra); if(dialog->exec() == QDialog::Accepted) { Transaction *new_trans = dialog->createRefund(); if(new_trans) { if(dialog->joinIsChecked()) { budget->removeTransactions(trans, true); transactionRemoved(trans); MultiAccountTransaction *split = NULL; double q = trans->quantity(); q += new_trans->quantity(); if(trans->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { split = (MultiAccountTransaction*) trans; } else { if(((Transaction*) trans)->fromAccount()->type() == ACCOUNT_TYPE_ASSETS) split = new MultiAccountTransaction(budget, (CategoryAccount*) ((Transaction*) trans)->toAccount(), trans->description()); else split = new MultiAccountTransaction(budget, (CategoryAccount*) ((Transaction*) trans)->fromAccount(), trans->description()); split->setTimestamp(trans->timestamp()); split->setAssociatedFile(trans->associatedFile()); split->setComment(trans->comment()); ((Transaction*) trans)->setComment(QString()); split->addTransaction((Transaction*) trans); } split->addTransaction(new_trans); split->setQuantity(q); budget->addSplitTransaction(split); transactionAdded(split); } else { new_trans->addLink(trans); trans->addLink(new_trans); if(new_trans->date() > QDate::currentDate()) { ScheduledTransaction *strans = new ScheduledTransaction(budget, new_trans, NULL); budget->addScheduledTransaction(strans); transactionAdded(strans); } else { budget->addTransaction(new_trans); transactionAdded(new_trans); } expensesWidget->onTransactionModified(trans, trans); incomesWidget->onTransactionModified(trans, trans); transfersWidget->onTransactionModified(trans, trans); updateTransactionActions(); dialog->deleteLater(); return true; } } } dialog->deleteLater(); return false; } void Eqonomize::editSelectedTransaction() { TransactionListWidget *w = NULL; if(tabs->currentIndex() == ACCOUNTS_PAGE_INDEX) return; else if(tabs->currentIndex() == EXPENSES_PAGE_INDEX) w = expensesWidget; else if(tabs->currentIndex() == INCOMES_PAGE_INDEX) w = incomesWidget; else if(tabs->currentIndex() == TRANSFERS_PAGE_INDEX) w = transfersWidget; else if(tabs->currentIndex() == SECURITIES_PAGE_INDEX) return; else if(tabs->currentIndex() == SCHEDULE_PAGE_INDEX) { editOccurrence(); return; } if(!w) return; w->editTransaction(); } void Eqonomize::cloneSelectedTransaction() { TransactionListWidget *w = NULL; if(tabs->currentIndex() == ACCOUNTS_PAGE_INDEX) return; else if(tabs->currentIndex() == EXPENSES_PAGE_INDEX) w = expensesWidget; else if(tabs->currentIndex() == INCOMES_PAGE_INDEX) w = incomesWidget; else if(tabs->currentIndex() == TRANSFERS_PAGE_INDEX) w = transfersWidget; else if(tabs->currentIndex() == SECURITIES_PAGE_INDEX) return; else if(tabs->currentIndex() == SCHEDULE_PAGE_INDEX) { cloneScheduledTransaction(); return; } if(!w) return; w->cloneTransaction(); } void Eqonomize::selectAssociatedFile() { TransactionListWidget *w = NULL; if(tabs->currentIndex() == ACCOUNTS_PAGE_INDEX) return; else if(tabs->currentIndex() == EXPENSES_PAGE_INDEX) w = expensesWidget; else if(tabs->currentIndex() == INCOMES_PAGE_INDEX) w = incomesWidget; else if(tabs->currentIndex() == TRANSFERS_PAGE_INDEX) w = transfersWidget; else if(tabs->currentIndex() == SECURITIES_PAGE_INDEX) return; else if(tabs->currentIndex() == SCHEDULE_PAGE_INDEX) { ScheduleListViewItem *i = (ScheduleListViewItem*) selectedItem(scheduleView); if(i == NULL) return; ScheduledTransaction *strans = i->scheduledTransaction(); QStringList urls = QFileDialog::getOpenFileNames(this, QString(), (strans->associatedFile().isEmpty() || strans->associatedFile().contains(",")) ? last_associated_file_directory : strans->associatedFile()); if(!urls.isEmpty()) { QFileInfo fileInfo(urls[0]); last_associated_file_directory = fileInfo.absoluteDir().absolutePath(); if(urls.size() == 1) { strans->setAssociatedFile(urls[0]); } else { QString url; for(int i = 0; i < urls.size(); i++) { if(i > 0) url += ", "; if(urls[i].contains("\"")) {url += "\'"; url += urls[i]; url += "\'";} else {url += "\""; url += urls[i]; url += "\"";} } strans->setAssociatedFile(url); } ActionOpenAssociatedFile->setEnabled(true); if(strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { transactionRemoved(strans); transactionAdded(strans); } else { transactionModified(strans, strans); } } return; } if(!w) return; w->selectAssociatedFile(); } void Eqonomize::openAssociatedFile() { TransactionListWidget *w = NULL; if(tabs->currentIndex() == ACCOUNTS_PAGE_INDEX) return; else if(tabs->currentIndex() == EXPENSES_PAGE_INDEX) w = expensesWidget; else if(tabs->currentIndex() == INCOMES_PAGE_INDEX) w = incomesWidget; else if(tabs->currentIndex() == TRANSFERS_PAGE_INDEX) w = transfersWidget; else if(tabs->currentIndex() == SECURITIES_PAGE_INDEX) return; else if(tabs->currentIndex() == SCHEDULE_PAGE_INDEX) { ScheduleListViewItem *i = (ScheduleListViewItem*) selectedItem(scheduleView); if(i == NULL) return; open_file_list(i->scheduledTransaction()->associatedFile()); return; } if(!w) return; w->openAssociatedFile(); } void Eqonomize::deleteSelectedScheduledTransaction() { TransactionListWidget *w = NULL; if(tabs->currentIndex() == ACCOUNTS_PAGE_INDEX) return; else if(tabs->currentIndex() == EXPENSES_PAGE_INDEX) w = expensesWidget; else if(tabs->currentIndex() == INCOMES_PAGE_INDEX) w = incomesWidget; else if(tabs->currentIndex() == TRANSFERS_PAGE_INDEX) w = transfersWidget; else if(tabs->currentIndex() == SECURITIES_PAGE_INDEX) return; else if(tabs->currentIndex() == SCHEDULE_PAGE_INDEX) { removeScheduledTransaction(); return; } if(!w) return; w->removeScheduledTransaction(); } void Eqonomize::deleteSelectedSplitTransaction() { TransactionListWidget *w = NULL; if(tabs->currentIndex() == EXPENSES_PAGE_INDEX) w = expensesWidget; else if(tabs->currentIndex() == INCOMES_PAGE_INDEX) w = incomesWidget; else if(tabs->currentIndex() == TRANSFERS_PAGE_INDEX) w = transfersWidget; else return; if(!w) return; w->removeSplitTransaction(); } void Eqonomize::deleteSelectedTransaction() { TransactionListWidget *w = NULL; if(tabs->currentIndex() == ACCOUNTS_PAGE_INDEX) return; else if(tabs->currentIndex() == EXPENSES_PAGE_INDEX) w = expensesWidget; else if(tabs->currentIndex() == INCOMES_PAGE_INDEX) w = incomesWidget; else if(tabs->currentIndex() == TRANSFERS_PAGE_INDEX) w = transfersWidget; else if(tabs->currentIndex() == SECURITIES_PAGE_INDEX) return; else if(tabs->currentIndex() == SCHEDULE_PAGE_INDEX) { removeOccurrence(); return; } if(!w) return; w->removeTransaction(); } void Eqonomize::onPageChange(int index) { if(index == EXPENSES_PAGE_INDEX) { expensesWidget->onDisplay(); } else if(index == INCOMES_PAGE_INDEX) { incomesWidget->onDisplay(); } else if(index == TRANSFERS_PAGE_INDEX) { transfersWidget->onDisplay(); } if(index == ACCOUNTS_PAGE_INDEX) { accountsSelectionChanged(); } else { ActionDeleteAccount->setEnabled(false); ActionCloseAccount->setEnabled(false); ActionEditAccount->setEnabled(false); ActionBalanceAccount->setEnabled(false); ActionReconcileAccount->setEnabled(false); ActionShowAccountTransactions->setEnabled(false); ActionRenameTag->setEnabled(false); ActionRemoveTag->setEnabled(false); } if(index == SECURITIES_PAGE_INDEX) { securitiesSelectionChanged(); } else { ActionEditSecurity->setEnabled(false); ActionDeleteSecurity->setEnabled(false); ActionSetQuotation->setEnabled(false); ActionEditQuotations->setEnabled(false); ActionEditSecurityTransactions->setEnabled(false); } updateTransactionActions(); } void Eqonomize::updateLinksAction(Transactions *trans, bool enable_remove) { linkMenu->clear(); if(trans) { if(trans->generaltype() == GENERAL_TRANSACTION_TYPE_SCHEDULE) trans = ((ScheduledTransaction*) trans)->transaction(); int n = trans->linksCount(true); QStringList descriptions; QList actions; QList dates; if(n == 0) { ActionLinks->setEnabled(false); ActionLinks->setText(tr("Links") + QString(" (0)")); } else { QList links; for(int i = 0; i < n; i++) { Transactions *tlink = trans->getLink(i, true); if(tlink) links << tlink; } ActionLinks->setText(tr("Links") + QString(" (") + QString::number(links.count()) + ")"); ActionLinks->setEnabled(links.count() > 0); for(int i = 0; i < links.count(); i++) { Transactions *tlink = links.at(i); if(tlink->description().isEmpty()) { linkMenu->addAction(LOAD_ICON("go-jump"), QLocale().toString(tlink->date(), QLocale::ShortFormat), this, SLOT(openLink()))->setData(QVariant::fromValue((void*) tlink)); } else { bool b_date = false; for(int i2 = 0; i2 < links.count(); i2++) { if(i != i2 && links.at(i2) && tlink->description().compare(links.at(i2)->description(), Qt::CaseInsensitive) == 0) { b_date = true; break; } } linkMenu->addAction(LOAD_ICON("go-jump"), b_date ? tlink->description() + "(" + QLocale().toString(tlink->date(), QLocale::ShortFormat) + ")" : tlink->description(), this, SLOT(openLink()))->setData(QVariant::fromValue((void*) tlink)); } } linkMenu->addSeparator(); QAction *action = linkMenu->addAction(LOAD_ICON("edit-delete"), tr("Remove Link"), this, SLOT(removeLink())); action->setData(QVariant::fromValue((void*) trans)); action->setEnabled(enable_remove); } } else { ActionLinks->setEnabled(false); ActionLinks->setText(tr("Links")); } } Transactions *Eqonomize::getLinkTransaction() {return link_trans;} QMenu *Eqonomize::createPopupMenu() { QMenu *menu = QMainWindow::createPopupMenu(); if(menu) { QList l = menu->actions(); for(int i = l.count() - 1; i >= 0; i--) { if(l.at(i)->text() == "Link") { menu->removeAction(l.at(i)); break; } } } return menu; } void Eqonomize::setLinkTransaction(Transactions *trans) { link_trans = trans; if(link_trans) { if(link_trans->generaltype() == GENERAL_TRANSACTION_TYPE_SCHEDULE) link_trans = ((ScheduledTransaction*) link_trans)->transaction(); if(link_trans->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE && ((Transaction*) link_trans)->parentSplit() && ((Transaction*) link_trans)->parentSplit()->type() == SPLIT_TRANSACTION_TYPE_LOAN) link_trans = ((Transaction*) link_trans)->parentSplit(); //: create link to transaction (link used as verb) ActionLinkTo->setText(tr("Link to \"%1\"").arg(link_trans->description().isEmpty() ? QString::number(link_trans->id()) : link_trans->description())); updateTransactionActions(); linkToolbar->show(); } else { linkToolbar->hide(); } } void Eqonomize::cancelLinkTo() { setLinkTransaction(NULL); } void Eqonomize::linkTo() { TransactionListWidget *w = NULL; if(tabs->currentIndex() == EXPENSES_PAGE_INDEX) w = expensesWidget; else if(tabs->currentIndex() == INCOMES_PAGE_INDEX) w = incomesWidget; else if(tabs->currentIndex() == TRANSFERS_PAGE_INDEX) w = transfersWidget; else if(tabs->currentIndex() == SCHEDULE_PAGE_INDEX) { ScheduleListViewItem *i = (ScheduleListViewItem*) selectedItem(scheduleView); if(i) { QList transactions; transactions << i->scheduledTransaction(); createLink(transactions, true); } } if(w) w->createLink(true); } void Eqonomize::createLink(QList transactions, bool link_to) { if(transactions.count() == 1 && !link_to) { Transactions *trans = transactions.first(); if(trans->generaltype() == GENERAL_TRANSACTION_TYPE_SCHEDULE) trans = ((ScheduledTransaction*) trans)->transaction(); if(trans->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE && ((Transaction*) trans)->parentSplit() && ((Transaction*) trans)->parentSplit()->type() == SPLIT_TRANSACTION_TYPE_LOAN) trans = ((Transaction*) trans)->parentSplit(); setLinkTransaction(trans); return; } if(link_trans && link_to && transactions.count() >= 1) { for(int i = 0; i < transactions.count(); i++) { Transactions *trans = transactions.at(i); if(trans->generaltype() == GENERAL_TRANSACTION_TYPE_SCHEDULE) trans = ((ScheduledTransaction*) trans)->transaction(); if(trans->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE && ((Transaction*) trans)->parentSplit() && ((Transaction*) trans)->parentSplit()->type() == SPLIT_TRANSACTION_TYPE_LOAN) trans = ((Transaction*) trans)->parentSplit(); if(trans != link_trans) { if(trans->generaltype() != GENERAL_TRANSACTION_TYPE_SINGLE || link_trans->generaltype() != GENERAL_TRANSACTION_TYPE_SINGLE || !((Transaction*) trans)->parentSplit() || ((Transaction*) trans)->parentSplit() != ((Transaction*) link_trans)->parentSplit()) { trans->addLink(link_trans); link_trans->addLink(trans); } if(trans->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE && ((Transaction*) trans)->parentSplit()) { ((Transaction*) trans)->parentSplit()->joinLinks(); } else if(trans->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { ((SplitTransaction*) trans)->joinLinks(); } } linksUpdated(trans); } if(link_trans->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE && ((Transaction*) link_trans)->parentSplit()) { ((Transaction*) link_trans)->parentSplit()->joinLinks(); } else if(link_trans->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { ((SplitTransaction*) link_trans)->joinLinks(); } linksUpdated(link_trans); setLinkTransaction(NULL); updateTransactionActions(); setModified(); } else if(transactions.count() >= 2) { for(int i = 0; i < transactions.count(); i++) { Transactions *trans = transactions.at(i); if(trans->generaltype() == GENERAL_TRANSACTION_TYPE_SCHEDULE) trans = ((ScheduledTransaction*) trans)->transaction(); if(trans->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE && ((Transaction*) trans)->parentSplit() && ((Transaction*) trans)->parentSplit()->type() == SPLIT_TRANSACTION_TYPE_LOAN) trans = ((Transaction*) trans)->parentSplit(); for(int i2 = 0; i2 < transactions.count(); i2++) { if(i2 != i) { Transactions *trans2 = transactions.at(i2); if(trans2->generaltype() == GENERAL_TRANSACTION_TYPE_SCHEDULE) trans2 = ((ScheduledTransaction*) trans2)->transaction(); if(trans->generaltype() != GENERAL_TRANSACTION_TYPE_SINGLE || trans2->generaltype() != GENERAL_TRANSACTION_TYPE_SINGLE || !((Transaction*) trans)->parentSplit() || ((Transaction*) trans)->parentSplit() != ((Transaction*) trans2)->parentSplit()) { trans->addLink(trans2); } } } linksUpdated(trans); } for(int i = 0; i < transactions.count(); i++) { Transactions *trans = transactions.at(i); if(trans->generaltype() == GENERAL_TRANSACTION_TYPE_SCHEDULE) trans = ((ScheduledTransaction*) trans)->transaction(); if(trans->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE && ((Transaction*) trans)->parentSplit()) { ((Transaction*) trans)->parentSplit()->joinLinks(); } else if(trans->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { ((SplitTransaction*) trans)->joinLinks(); } } setLinkTransaction(NULL); updateTransactionActions(); setModified(); } } void Eqonomize::createLink() { TransactionListWidget *w = NULL; if(tabs->currentIndex() == EXPENSES_PAGE_INDEX) w = expensesWidget; else if(tabs->currentIndex() == INCOMES_PAGE_INDEX) w = incomesWidget; else if(tabs->currentIndex() == TRANSFERS_PAGE_INDEX) w = transfersWidget; else if(tabs->currentIndex() == SCHEDULE_PAGE_INDEX) { ScheduleListViewItem *i = (ScheduleListViewItem*) selectedItem(scheduleView); if(i) { QList transactions; transactions << i->scheduledTransaction(); createLink(transactions, false); } } if(w) w->createLink(false); } void Eqonomize::openLink(Transactions *trans, QWidget *parent) { if(trans) { if(trans->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE) mainwin->editTransaction((Transaction*) trans, parent ? parent : mainwin, false, false); else if(trans->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) mainwin->editSplitTransaction((SplitTransaction*) trans, parent ? parent : mainwin, false, false, false); else if(trans->generaltype() == GENERAL_TRANSACTION_TYPE_SCHEDULE) mainwin->editScheduledTransaction((ScheduledTransaction*) trans, parent ? parent : mainwin, false, false); } } void Eqonomize::openLink() { QAction *action = qobject_cast(sender()); Transactions *trans = (Transactions*) action->data().value(); if(trans) { if(trans->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE) editTransaction((Transaction*) trans); else if(trans->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) editSplitTransaction((SplitTransaction*) trans); else if(trans->generaltype() == GENERAL_TRANSACTION_TYPE_SCHEDULE) editScheduledTransaction((ScheduledTransaction*) trans); } } void Eqonomize::removeOldLinks(Transactions *trans, Transactions *oldtrans) { if(trans->generaltype() == GENERAL_TRANSACTION_TYPE_SCHEDULE) trans = ((ScheduledTransaction*) trans)->transaction(); if(trans->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { bool b = trans->linksCount(false) > 0 || oldtrans->linksCount(false); int n = ((SplitTransaction*) trans)->count(); for(int i = 0; !b && i < n; i++) { if(((SplitTransaction*) trans)->at(i)->linksCount(false) > 0) b = true; } if(!b && oldtrans->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { n = ((SplitTransaction*) oldtrans)->count(); for(int i = 0; !b && i < n; i++) { if(((SplitTransaction*) oldtrans)->at(i)->linksCount(false) > 0) b = true; } } if(b) { removeTransactionLinks(oldtrans); addTransactionLinks(trans); updateTransactionActions(); } return; } bool b = false; for(int i = trans->linksCount(false); i < oldtrans->linksCount(false); i++) { Transactions *ltrans = oldtrans->getLink(i, false); if(ltrans) { if(ltrans->removeLink(trans)) { linksUpdated(ltrans); b = true; } } } if(b) updateTransactionActions(); } void Eqonomize::addTransactionLinks(Transactions *trans, bool update_display) { if(trans->generaltype() == GENERAL_TRANSACTION_TYPE_SCHEDULE) trans = ((ScheduledTransaction*) trans)->transaction(); for(int i = 0; i < trans->linksCount(false); i++) { Transactions *ltrans = trans->getLink(i, false); if(ltrans) { ltrans->addLink(trans); if(update_display) linksUpdated(ltrans); } } if(trans->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { int n = ((SplitTransaction*) trans)->count(); for(int i = 0; i < n; i++) { addTransactionLinks(((SplitTransaction*) trans)->at(i), update_display); } } } void Eqonomize::linksUpdated(Transactions *trans) { QTreeWidgetItemIterator it(scheduleView); ScheduleListViewItem *i = (ScheduleListViewItem*) *it; while(i) { if(i->scheduledTransaction() == trans || i->scheduledTransaction()->transaction() == trans) { if(i->scheduledTransaction() != trans) trans = i->scheduledTransaction(); i->setScheduledTransaction(i->scheduledTransaction()); if(i->isSelected()) { scheduleSelectionChanged(); if(tabs->currentIndex() == SCHEDULE_PAGE_INDEX) updateTransactionActions(); } break; } ++it; i = (ScheduleListViewItem*) *it; } expensesWidget->onTransactionModified(trans, trans); incomesWidget->onTransactionModified(trans, trans); transfersWidget->onTransactionModified(trans, trans); } void Eqonomize::removeLink() { QAction *action = qobject_cast(sender()); Transactions *trans = (Transactions*) action->data().value(); if(!trans || trans->linksCount(true) == 0) return; SplitTransaction *split = NULL; if(trans->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE) split = ((Transaction*) trans)->parentSplit(); int index = 0; QList links; int n = trans->linksCount(true); for(int i = 0; i < n; i++) { Transactions *tlink = trans->getLink(i, true); if(tlink) links << tlink; } if(links.empty()) return; if(links.count() == 1) { index = 0; } else { QDialog *dialog = new QDialog(this); dialog->setWindowTitle(tr("Remove Link")); dialog->setModal(true); QVBoxLayout *box1 = new QVBoxLayout(dialog); QComboBox *combo = new QComboBox(dialog); combo->addItem(tr("All")); for(int i = 0; i < links.count(); i++) { Transactions *tlink = links.at(i); if(tlink->description().isEmpty()) { combo->addItem(QLocale().toString(tlink->date(), QLocale::ShortFormat)); } else { bool b_date = false; for(int i2 = 0; i2 < links.count(); i2++) { if(i != i2 && links.at(i2) && tlink->description().compare(links.at(i2)->description(), Qt::CaseInsensitive) == 0) { b_date = true; break; } } combo->addItem(b_date ? tlink->description() + " (" + QLocale().toString(tlink->date(), QLocale::ShortFormat) + ")" : tlink->description()); } } combo->setCurrentIndex(0); box1->addWidget(combo); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel); QPushButton *delButton = new QPushButton(LOAD_ICON("edit-delete"), tr("Remove")); buttonBox->addButton(delButton, QDialogButtonBox::AcceptRole); delButton->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), dialog, SLOT(reject())); connect(delButton, SIGNAL(clicked()), dialog, SLOT(accept())); box1->addWidget(buttonBox); if(dialog->exec() != QDialog::Accepted) { dialog->deleteLater(); return; } index = combo->currentIndex() - 1; dialog->deleteLater(); } while(trans->linksCount(true)) { Transactions *tlink = trans->getLink(index < 0 ? 0 : index, true); if(tlink) { if(split && !trans->linksCount(false)) { split->removeLink(tlink); bool b = tlink->removeLink(split); if(!b) tlink->removeLink(trans); int n = split->count(); for(int i = 0; i < n; i++) { Transaction *tsplit = split->at(i); if(tsplit != trans) { tsplit->addLink(tlink); if(b) tlink->addLink(tsplit); } } } else { trans->removeLink(index < 0 ? 0 : index); tlink->removeLink(trans); } linksUpdated(tlink); } if(index >= 0) break; } linksUpdated(trans); updateTransactionActions(); setModified(); } void Eqonomize::updateTransactionActions() { TransactionListWidget *w = NULL; bool b_transaction = false, b_scheduledtransaction = false, b_attachment = false; if(tabs->currentIndex() == EXPENSES_PAGE_INDEX) w = expensesWidget; else if(tabs->currentIndex() == INCOMES_PAGE_INDEX) w = incomesWidget; else if(tabs->currentIndex() == TRANSFERS_PAGE_INDEX) w = transfersWidget; else if(tabs->currentIndex() == SCHEDULE_PAGE_INDEX) { ScheduleListViewItem *i = (ScheduleListViewItem*) selectedItem(scheduleView); b_transaction = i && !i->scheduledTransaction()->isOneTimeTransaction(); b_attachment = i && !i->scheduledTransaction()->associatedFile().isEmpty(); b_scheduledtransaction = (i != NULL); if(i) { tagMenu->setTransaction(i->scheduledTransaction()); ActionTags->setText(tr("Tags") + QString(" (") + QString::number(tagMenu->selectedTagsCount()) + ")"); updateLinksAction(i->scheduledTransaction()); ActionLinkTo->setEnabled(link_trans && i->scheduledTransaction() && i->scheduledTransaction()->transaction() != link_trans && !i->scheduledTransaction()->hasLink(link_trans)); } } else {} if(w) { w->updateTransactionActions(); } else { ActionCloneTransaction->setEnabled(b_scheduledtransaction); ActionJoinTransactions->setEnabled(false); ActionSplitUpTransaction->setEnabled(false); ActionEditTimestamp->setEnabled(b_scheduledtransaction); ActionTags->setEnabled(b_scheduledtransaction); ActionCreateLink->setEnabled(b_scheduledtransaction); if(!b_scheduledtransaction) { ActionTags->setText(tr("Tags")); updateLinksAction(NULL); ActionCreateLink->setEnabled(false); ActionLinkTo->setEnabled(false); } ActionEditSplitTransaction->setEnabled(false); ActionDeleteSplitTransaction->setEnabled(false); ActionEditTransaction->setEnabled(b_transaction); ActionDeleteTransaction->setEnabled(b_transaction); ActionSelectAssociatedFile->setEnabled(b_transaction); ActionOpenAssociatedFile->setEnabled(b_attachment); ActionEditScheduledTransaction->setEnabled(b_scheduledtransaction); ActionDeleteScheduledTransaction->setEnabled(b_scheduledtransaction); ActionNewRefund->setEnabled(false); ActionNewRepayment->setEnabled(false); ActionNewRefundRepayment->setEnabled(false); } } void Eqonomize::popupAccountsMenu(const QPoint &p) { QTreeWidgetItem *i = accountsView->itemAt(p); if(i == NULL) return; if(i == liabilitiesItem || (account_items.contains(i) && (account_items[i]->type() == ACCOUNT_TYPE_ASSETS) && (((AssetsAccount*) account_items[i])->isDebt())) || (liabilities_group_items.contains(i) && liabilities_group_items[i] == budget->getAccountTypeName(ASSETS_TYPE_LIABILITIES, true, true))) { ActionAddAccount->setText(tr("Add Loan")); } else if(i == assetsItem || (account_items.contains(i) && (account_items[i]->type() == ACCOUNT_TYPE_ASSETS)) || assets_group_items.contains(i) || liabilities_group_items.contains(i)) { ActionAddAccount->setText(tr("Add Account")); } else { ActionAddAccount->setText(tr("Add Category")); } if(i == liabilitiesItem || i == assetsItem || (account_items.contains(i) && account_items[i]->type() == ACCOUNT_TYPE_ASSETS) || assets_group_items.contains(i) || liabilities_group_items.contains(i)) { if(!assetsPopupMenu) { assetsPopupMenu = new QMenu(this); assetsPopupMenu->addAction(ActionAddAccount); assetsPopupMenu->addAction(ActionEditAccount); assetsPopupMenu->addAction(ActionReconcileAccount); assetsPopupMenu->addAction(ActionBalanceAccount); assetsPopupMenu->addAction(ActionCloseAccount); assetsPopupMenu->addAction(ActionDeleteAccount); assetsPopupMenu->addSeparator(); assetsPopupMenu->addAction(ActionShowAccountTransactions); } assetsPopupMenu->popup(accountsView->viewport()->mapToGlobal(p)); } else if(i == tagsItem || tag_items.contains(i)) { if(!tagPopupMenu) { tagPopupMenu = new QMenu(this); tagPopupMenu->addAction(ActionNewTag); tagPopupMenu->addAction(ActionRenameTag); tagPopupMenu->addAction(ActionRemoveTag); tagPopupMenu->addSeparator(); tagPopupMenu->addAction(ActionShowAccountTransactions); } tagPopupMenu->popup(accountsView->viewport()->mapToGlobal(p)); } else { if(!accountPopupMenu) { accountPopupMenu = new QMenu(this); accountPopupMenu->addAction(ActionAddAccount); accountPopupMenu->addAction(ActionEditAccount); accountPopupMenu->addAction(ActionDeleteAccount); accountPopupMenu->addSeparator(); accountPopupMenu->addAction(ActionShowAccountTransactions); } accountPopupMenu->popup(accountsView->viewport()->mapToGlobal(p)); } } void Eqonomize::showLedger() { QTreeWidgetItem *i = selectedItem(accountsView); Account *account = NULL; if(i && account_items.contains(i)) { account = account_items[i]; if(account && account->type() != ACCOUNT_TYPE_ASSETS) account = NULL; } LedgerDialog *dialog = new LedgerDialog((AssetsAccount*) account, budget, this, tr("Ledger"), b_extra); dialog->show(); connect(this, SIGNAL(timeToSaveConfig()), dialog, SLOT(saveConfig())); } void Eqonomize::reconcileAccount() { QTreeWidgetItem *i = selectedItem(accountsView); Account *account = NULL; if(i && account_items.contains(i)) { account = account_items[i]; if(account && account->type() != ACCOUNT_TYPE_ASSETS) account = NULL; } LedgerDialog *dialog = new LedgerDialog((AssetsAccount*) account, budget, this, tr("Ledger"), b_extra, true); dialog->show(); connect(this, SIGNAL(timeToSaveConfig()), dialog, SLOT(saveConfig())); } void Eqonomize::showAccountTransactions(bool b) { QTreeWidgetItem *i = selectedItem(accountsView); if(i == NULL) return; if(i == incomesItem) { if(b) incomesWidget->setFilter(QDate(), to_date, -1.0, -1.0, NULL, NULL); else incomesWidget->setFilter(accountsPeriodFromButton->isChecked() ? from_date : QDate(), to_date, -1.0, -1.0, NULL, NULL); incomesWidget->showFilter(); tabs->setCurrentIndex(INCOMES_PAGE_INDEX); } else if(i == expensesItem || i == tagsItem) { if(b) expensesWidget->setFilter(QDate(), to_date, -1.0, -1.0, NULL, NULL); else expensesWidget->setFilter(accountsPeriodFromButton->isChecked() ? from_date : QDate(), to_date, -1.0, -1.0, NULL, NULL); expensesWidget->showFilter(); tabs->setCurrentIndex(EXPENSES_PAGE_INDEX); } else if(tag_items.contains(i)) { TransactionListWidget *w = expensesWidget; QString tag = tag_items[i]; bool b_from = !b && accountsPeriodFromButton->isChecked(); if((b && tag_value[tag] > 0.0) || (!b && (tag_change[tag] > 0.0 || (tag_change[tag] == 0.0 && tag_value[tag] > 0.0)))) { w = incomesWidget; bool b = false; for(TransactionList::const_iterator it = budget->incomes.constEnd(); it != budget->incomes.constBegin();) { --it; if(b_from && (*it)->date() < from_date) break; if((b || (*it)->date() <= to_date) && (*it)->hasTag(tag, true)) { b = true; break; } } if(!b) { for(TransactionList::const_iterator it = budget->expenses.constEnd(); it != budget->expenses.constBegin();) { --it; if(b_from && (*it)->date() < from_date) break; if((b || (*it)->date() <= to_date) && (*it)->hasTag(tag, true)) { w = expensesWidget; break; } } } } else { bool b = false; for(TransactionList::const_iterator it = budget->expenses.constEnd(); it != budget->expenses.constBegin();) { --it; if(b_from && (*it)->date() < from_date) break; if((b || (*it)->date() <= to_date) && (*it)->hasTag(tag, true)) { b = true; break; } } if(!b) { for(TransactionList::const_iterator it = budget->incomes.constEnd(); it != budget->incomes.constBegin();) { --it; if(b_from && (*it)->date() < from_date) break; if((b || (*it)->date() <= to_date) && (*it)->hasTag(tag, true)) { w = incomesWidget; break; } } } } if(b) w->setFilter(QDate(), to_date, -1.0, -1.0, NULL, NULL, QString(), tag); else w->setFilter(accountsPeriodFromButton->isChecked() ? from_date : QDate(), to_date, -1.0, -1.0, NULL, NULL, QString(), tag); w->showFilter(); tabs->setCurrentIndex(w == incomesWidget ? INCOMES_PAGE_INDEX : EXPENSES_PAGE_INDEX); } else { if(!account_items.contains(i)) return; Account *account = account_items[i]; AccountType type = account->type(); if(type == ACCOUNT_TYPE_INCOMES) { if(b) incomesWidget->setFilter(QDate(), to_date, -1.0, -1.0, account, NULL); else incomesWidget->setFilter(accountsPeriodFromButton->isChecked() ? from_date : QDate(), to_date, -1.0, -1.0, account, NULL); incomesWidget->showFilter(); tabs->setCurrentIndex(INCOMES_PAGE_INDEX); } else if(type == ACCOUNT_TYPE_EXPENSES) { if(b) expensesWidget->setFilter(QDate(), to_date, -1.0, -1.0, NULL, account); else expensesWidget->setFilter(accountsPeriodFromButton->isChecked() ? from_date : QDate(), to_date, -1.0, -1.0, NULL, account); expensesWidget->showFilter(); tabs->setCurrentIndex(EXPENSES_PAGE_INDEX); } else if(((AssetsAccount*) account)->isSecurities()) { tabs->setCurrentIndex(SECURITIES_PAGE_INDEX); } else { LedgerDialog *dialog = new LedgerDialog((AssetsAccount*) account, budget, this, tr("Ledger"), b_extra); dialog->show(); connect(this, SIGNAL(timeToSaveConfig()), dialog, SLOT(saveConfig())); } } } void Eqonomize::accountsPeriodToChanged(const QDate &date) { bool error = false; if(!date.isValid()) { QMessageBox::critical(this, tr("Error"), tr("Invalid date.")); error = true; } if(!error && accountsPeriodFromEdit->date() > date) { /*if(accountsPeriodFromButton->isChecked()) { QMessageBox::critical(this, tr("Error"), tr("To date is before from date.")); }*/ if(budget->isFirstBudgetDay(to_date)) { from_date = budget->firstBudgetDay(date); } else { from_date = date.addDays(-from_date.daysTo(to_date)); } accountsPeriodFromEdit->blockSignals(true); accountsPeriodFromEdit->setDate(from_date); accountsPeriodFromEdit->blockSignals(false); } if(error) { accountsPeriodToEdit->setFocus(); accountsPeriodToEdit->blockSignals(true); accountsPeriodToEdit->setDate(to_date); accountsPeriodToEdit->blockSignals(false); accountsPeriodToEdit->selectAll(); return; } to_date = date; filterAccounts(); } void Eqonomize::accountsPeriodFromChanged(const QDate &date) { bool error = false; if(!date.isValid()) { QMessageBox::critical(this, tr("Error"), tr("Invalid date.")); error = true; } if(!error && date > accountsPeriodToEdit->date()) { //QMessageBox::critical(this, tr("Error"), tr("From date is after to date.")); if(budget->isLastBudgetDay(to_date)) { to_date = budget->lastBudgetDay(date); } else { to_date = date.addDays(from_date.daysTo(to_date)); } accountsPeriodToEdit->blockSignals(true); accountsPeriodToEdit->setDate(to_date); accountsPeriodToEdit->blockSignals(false); } if(error) { accountsPeriodFromEdit->setFocus(); accountsPeriodFromEdit->blockSignals(true); accountsPeriodFromEdit->setDate(from_date); accountsPeriodFromEdit->blockSignals(false); accountsPeriodFromEdit->selectAll(); return; } from_date = date; if(accountsPeriodFromButton->isChecked()) filterAccounts(); } void Eqonomize::prevMonth() { accountsPeriodFromEdit->blockSignals(true); accountsPeriodToEdit->blockSignals(true); budget->goForwardBudgetMonths(from_date, to_date, -1); accountsPeriodFromEdit->setDate(from_date); accountsPeriodToEdit->setDate(to_date); accountsPeriodFromEdit->blockSignals(false); accountsPeriodToEdit->blockSignals(false); filterAccounts(); } void Eqonomize::nextMonth() { accountsPeriodFromEdit->blockSignals(true); accountsPeriodToEdit->blockSignals(true); budget->goForwardBudgetMonths(from_date, to_date, 1); accountsPeriodFromEdit->setDate(from_date); accountsPeriodToEdit->setDate(to_date); accountsPeriodFromEdit->blockSignals(false); accountsPeriodToEdit->blockSignals(false); filterAccounts(); } void Eqonomize::currentMonth() { accountsPeriodFromEdit->blockSignals(true); accountsPeriodToEdit->blockSignals(true); QDate curdate = QDate::currentDate(); from_date == budget->firstBudgetDay(curdate); accountsPeriodFromEdit->setDate(from_date); to_date = curdate; accountsPeriodToEdit->setDate(to_date); accountsPeriodFromEdit->blockSignals(false); accountsPeriodToEdit->blockSignals(false); filterAccounts(); } void Eqonomize::prevYear() { accountsPeriodFromEdit->blockSignals(true); accountsPeriodToEdit->blockSignals(true); budget->goForwardBudgetMonths(from_date, to_date, -12); accountsPeriodFromEdit->setDate(from_date); accountsPeriodToEdit->setDate(to_date); accountsPeriodFromEdit->blockSignals(false); accountsPeriodToEdit->blockSignals(false); filterAccounts(); } void Eqonomize::nextYear() { accountsPeriodFromEdit->blockSignals(true); accountsPeriodToEdit->blockSignals(true); budget->goForwardBudgetMonths(from_date, to_date, 12); accountsPeriodFromEdit->setDate(from_date); accountsPeriodToEdit->setDate(to_date); accountsPeriodFromEdit->blockSignals(false); accountsPeriodToEdit->blockSignals(false); filterAccounts(); } void Eqonomize::currentYear() { accountsPeriodFromEdit->blockSignals(true); accountsPeriodToEdit->blockSignals(true); QDate curdate = QDate::currentDate(); from_date = budget->firstBudgetDayOfYear(curdate); accountsPeriodFromEdit->setDate(from_date); to_date = curdate; accountsPeriodToEdit->setDate(to_date); accountsPeriodFromEdit->blockSignals(false); accountsPeriodToEdit->blockSignals(false); filterAccounts(); } void Eqonomize::securitiesPeriodToChanged(const QDate &date) { bool error = false; if(!date.isValid()) { QMessageBox::critical(this, tr("Error"), tr("Invalid date.")); error = true; } if(!error && securitiesPeriodFromEdit->date() > date) { /*if(securitiesPeriodFromButton->isChecked()) { QMessageBox::critical(this, tr("Error"), tr("To date is before from date.")); }*/ if(budget->isFirstBudgetDay(to_date)) { securities_from_date = budget->firstBudgetDay(date); } else { securities_from_date = date.addDays(-securities_from_date.daysTo(securities_to_date)); } securities_from_date = date; securitiesPeriodFromEdit->blockSignals(true); securitiesPeriodFromEdit->setDate(securities_from_date); securitiesPeriodFromEdit->blockSignals(false); } if(error) { securitiesPeriodToEdit->setFocus(); securitiesPeriodToEdit->blockSignals(true); securitiesPeriodToEdit->setDate(securities_to_date); securitiesPeriodToEdit->blockSignals(false); securitiesPeriodToEdit->selectAll(); return; } securities_to_date = date; updateSecurities(); } void Eqonomize::securitiesPeriodFromChanged(const QDate &date) { bool error = false; if(!date.isValid()) { QMessageBox::critical(this, tr("Error"), tr("Invalid date.")); error = true; } if(!error && date > securitiesPeriodToEdit->date()) { //QMessageBox::critical(this, tr("Error"), tr("From date is after to date.")); if(budget->isLastBudgetDay(to_date)) { securities_to_date = budget->lastBudgetDay(date); } else { securities_to_date = date.addDays(securities_from_date.daysTo(to_date)); } if(securities_to_date > QDate::currentDate() && securities_from_date <= QDate::currentDate()) securities_to_date = QDate::currentDate(); securitiesPeriodToEdit->blockSignals(true); securitiesPeriodToEdit->setDate(securities_to_date); securitiesPeriodToEdit->blockSignals(false); } if(error) { securitiesPeriodFromEdit->setFocus(); securitiesPeriodFromEdit->blockSignals(true); securitiesPeriodFromEdit->setDate(securities_from_date); securitiesPeriodFromEdit->blockSignals(false); securitiesPeriodFromEdit->selectAll(); return; } securities_from_date = date; if(securitiesPeriodFromButton->isChecked()) updateSecurities(); } void Eqonomize::securitiesPrevMonth() { securitiesPeriodFromEdit->blockSignals(true); securitiesPeriodToEdit->blockSignals(true); budget->goForwardBudgetMonths(securities_from_date, securities_to_date, -1); securitiesPeriodFromEdit->setDate(securities_from_date); securitiesPeriodToEdit->setDate(securities_to_date); securitiesPeriodFromEdit->blockSignals(false); securitiesPeriodToEdit->blockSignals(false); updateSecurities(); } void Eqonomize::securitiesNextMonth() { securitiesPeriodFromEdit->blockSignals(true); securitiesPeriodToEdit->blockSignals(true); budget->goForwardBudgetMonths(securities_from_date, securities_to_date, 1); securitiesPeriodFromEdit->setDate(securities_from_date); securitiesPeriodToEdit->setDate(securities_to_date); securitiesPeriodFromEdit->blockSignals(false); securitiesPeriodToEdit->blockSignals(false); updateSecurities(); } void Eqonomize::securitiesCurrentMonth() { securitiesPeriodFromEdit->blockSignals(true); securitiesPeriodToEdit->blockSignals(true); QDate curdate = QDate::currentDate(); securities_from_date == budget->firstBudgetDay(curdate); securitiesPeriodFromEdit->setDate(securities_from_date); securities_to_date = curdate; securitiesPeriodToEdit->setDate(securities_to_date); securitiesPeriodFromEdit->blockSignals(false); securitiesPeriodToEdit->blockSignals(false); updateSecurities(); } void Eqonomize::securitiesPrevYear() { securitiesPeriodFromEdit->blockSignals(true); securitiesPeriodToEdit->blockSignals(true); budget->goForwardBudgetMonths(securities_from_date, securities_to_date, -12); securitiesPeriodFromEdit->setDate(securities_from_date); securitiesPeriodToEdit->setDate(securities_to_date); securitiesPeriodFromEdit->blockSignals(false); securitiesPeriodToEdit->blockSignals(false); updateSecurities(); } void Eqonomize::securitiesNextYear() { securitiesPeriodFromEdit->blockSignals(true); securitiesPeriodToEdit->blockSignals(true); budget->goForwardBudgetMonths(securities_from_date, securities_to_date, 12); securitiesPeriodFromEdit->setDate(securities_from_date); securitiesPeriodToEdit->setDate(securities_to_date); securitiesPeriodFromEdit->blockSignals(false); securitiesPeriodToEdit->blockSignals(false); updateSecurities(); } void Eqonomize::securitiesCurrentYear() { securitiesPeriodFromEdit->blockSignals(true); securitiesPeriodToEdit->blockSignals(true); QDate curdate = QDate::currentDate(); securities_from_date = budget->firstBudgetDayOfYear(curdate); securitiesPeriodFromEdit->setDate(securities_from_date); securities_to_date = curdate; securitiesPeriodToEdit->setDate(securities_to_date); securitiesPeriodFromEdit->blockSignals(false); securitiesPeriodToEdit->blockSignals(false); updateSecurities(); } void Eqonomize::setModified(bool has_been_modified) { modified_auto_save = has_been_modified; if(has_been_modified) autoSave(); if(modified == has_been_modified) return; modified = has_been_modified; ActionFileSave->setEnabled(modified || !current_url.isValid()); setWindowModified(has_been_modified); if(modified) { if(!in_batch_edit) emit budgetUpdated(); } else { auto_save_timeout = true; } } void Eqonomize::createDefaultBudget() { if(!askSave()) return; budget->clear(); bool new_currency = false, adjust_contents = false; if(current_url.isEmpty()) { new_currency = budget->resetDefaultCurrency(); if(first_run) adjust_contents = true; } current_url = ""; setWindowTitle(tr("Untitled") + "[*]"); ActionFileReload->setEnabled(false); QSettings settings; settings.beginGroup("GeneralOptions"); settings.setValue("lastURL", current_url.url()); if(!cr_tmp_file.isEmpty()) { QFile autosaveFile(cr_tmp_file); autosaveFile.remove(); cr_tmp_file = ""; } settings.endGroup(); settings.sync(); budget->addAccount(new AssetsAccount(budget, ASSETS_TYPE_CASH, tr("Cash"))); budget->addAccount(new AssetsAccount(budget, ASSETS_TYPE_CURRENT, tr("Checking Account", "Transactional account"))); budget->addAccount(new AssetsAccount(budget, ASSETS_TYPE_SAVINGS, tr("Savings Account"))); budget->addAccount(new IncomesAccount(budget, tr("Salary"))); budget->addAccount(new IncomesAccount(budget, tr("Other"))); budget->addAccount(new ExpensesAccount(budget, tr("Bills"))); budget->addAccount(new ExpensesAccount(budget, tr("Clothing"))); budget->addAccount(new ExpensesAccount(budget, tr("Groceries"))); budget->addAccount(new ExpensesAccount(budget, tr("Leisure"))); budget->addAccount(new ExpensesAccount(budget, tr("Other"))); if(new_currency) warnAndAskForExchangeRate(); reloadBudget(); if(adjust_contents) { accountsView->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContentsOnFirstShow); } setModified(false); ActionFileSave->setEnabled(true); emit accountsModified(); emit transactionsModified(); emit budgetUpdated(); } void Eqonomize::reloadBudget() { setLinkTransaction(NULL); incomes_accounts_value = 0.0; incomes_accounts_change = 0.0; expenses_accounts_value = 0.0; expenses_accounts_change = 0.0; assets_accounts_value = 0.0; assets_accounts_change = 0.0; liabilities_accounts_value = 0.0; liabilities_accounts_change = 0.0; expenses_budget = 0.0; expenses_budget_diff = 0.0; incomes_budget = 0.0; incomes_budget_diff = 0.0; account_value.clear(); account_change.clear(); assets_group_value.clear(); assets_group_change.clear(); assets_group_value[""] = 0.0; assets_group_change[""] = 0.0; liabilities_group_value.clear(); liabilities_group_change.clear(); liabilities_group_value[""] = 0.0; liabilities_group_change[""] = 0.0; account_items.clear(); assets_group_items.clear(); liabilities_group_items.clear(); tag_items.clear(); item_accounts.clear(); item_assets_groups.clear(); item_liabilities_groups.clear(); item_tags.clear(); while(assetsItem->childCount() > 0) { delete assetsItem->child(0); } while(liabilitiesItem->childCount() > 0) { delete liabilitiesItem->child(0); } while(incomesItem->childCount() > 0) { delete incomesItem->child(0); } while(expensesItem->childCount() > 0) { delete expensesItem->child(0); } while(tagsItem->childCount() > 0) { delete tagsItem->child(0); } for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { AssetsAccount *aaccount = *it; if(aaccount != budget->balancingAccount) { appendAssetsAccount(aaccount); } } for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) { IncomesAccount *iaccount = *it; if(!iaccount->parentCategory()) appendIncomesAccount(iaccount, incomesItem); } for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) { ExpensesAccount *eaccount = *it; if(!eaccount->parentCategory()) appendExpensesAccount(eaccount, expensesItem); } for(QStringList::const_iterator it = budget->tags.constBegin(); it != budget->tags.constEnd(); ++it) { NEW_ACCOUNT_TREE_WIDGET_ITEM(i, tagsItem, *it, "", budget->formatMoney(0.0), budget->formatMoney(0.0) + " "); tag_items[i] = *it; item_tags[*it] = i; tag_value[*it] = 0.0; tag_change[*it] = 0.0; } tagsItem->setHidden(tag_items.isEmpty()); tagsItem->sortChildren(0, Qt::AscendingOrder); account_value[budget->balancingAccount] = 0.0; account_change[budget->balancingAccount] = 0.0; expensesWidget->updateAccounts(); incomesWidget->updateAccounts(); transfersWidget->updateAccounts(); expensesWidget->tagsModified(); incomesWidget->tagsModified(); transfersWidget->tagsModified(); tagMenu->updateTags(); assetsItem->setExpanded(true); liabilitiesItem->setExpanded(true); incomesItem->setExpanded(true); expensesItem->setExpanded(true); expensesWidget->transactionsReset(); incomesWidget->transactionsReset(); transfersWidget->transactionsReset(); updateBudgetDay(); updateScheduledTransactions(); updateSecurities(); updateUsesMultipleCurrencies(); budgetEdit->setCurrency(budget->defaultCurrency()); } bool Eqonomize::openURL(const QUrl& url, bool merge) { if(!merge && url != current_url && crashRecovery(QUrl(url))) return true; bool ignore_duplicate_transactions = false, rename_duplicate_accounts = false, rename_duplicate_categories = false, rename_duplicate_securities = false; if(merge) { QDialog *dialog = new QDialog(this); dialog->setWindowTitle(tr("Import Options")); dialog->setModal(true); QVBoxLayout *box1 = new QVBoxLayout(dialog); QCheckBox *idtButton = new QCheckBox(tr("Ignore duplicate transactions"), dialog); box1->addWidget(idtButton); QCheckBox *rdaButton = new QCheckBox(tr("Rename duplicate accounts"), dialog); box1->addWidget(rdaButton); QCheckBox *rdcButton = new QCheckBox(tr("Rename duplicate categories"), dialog); box1->addWidget(rdcButton); QCheckBox *rdsButton = new QCheckBox(tr("Rename duplicate securities"), dialog); box1->addWidget(rdsButton); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, dialog); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), dialog, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), dialog, SLOT(accept())); box1->addWidget(buttonBox); if(dialog->exec() != QDialog::Accepted) return false; ignore_duplicate_transactions = idtButton->isChecked(); rename_duplicate_accounts = rdaButton->isChecked(); rename_duplicate_categories = rdcButton->isChecked(); rename_duplicate_securities = rdsButton->isChecked(); dialog->deleteLater(); } QString errors; bool new_currency = false; QString error = budget->loadFile(url.toLocalFile(), errors, &new_currency, merge, rename_duplicate_accounts, rename_duplicate_categories, rename_duplicate_securities, ignore_duplicate_transactions); if(!error.isNull()) { QMessageBox::critical(this, tr("Couldn't open file"), tr("Error loading %1: %2.").arg(url.toString()).arg(error)); return false; } if(!errors.isEmpty()) { QMessageBox::critical(this, tr("Error"), errors); } if(!merge) { setWindowTitle(url.fileName() + "[*]"); current_url = url; ActionFileReload->setEnabled(true); QSettings settings; settings.beginGroup("GeneralOptions"); settings.setValue("lastURL", current_url.url()); if(!cr_tmp_file.isEmpty()) { QFile autosaveFile(cr_tmp_file); autosaveFile.remove(); cr_tmp_file = ""; } settings.endGroup(); settings.sync(); updateRecentFiles(url.toLocalFile()); if(budget->autosyncEnabled()) { sync(true, true); } if(new_currency) warnAndAskForExchangeRate(); } Currency *cur = budget->defaultCurrency(); if(cur != budget->currency_euro && cur->exchangeRateSource() == EXCHANGE_RATE_SOURCE_NONE) cur = NULL; for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { AssetsAccount *acc = *it; if(acc->currency() != NULL && acc->currency() != cur && (acc->currency() == budget->currency_euro || acc->currency()->exchangeRateSource() != EXCHANGE_RATE_SOURCE_NONE)) { if(cur) { if(timeToUpdateExchangeRates()) updateExchangeRates(false); break; } cur = acc->currency(); } } reloadBudget(); if(!merge) { expensesWidget->setDefaultAccounts(); incomesWidget->setDefaultAccounts(); transfersWidget->setDefaultAccounts(); } emit accountsModified(); emit transactionsModified(); emit budgetUpdated(); setModified(false); ActionFileSave->setEnabled(false); checkSchedule(true, this); return true; } void Eqonomize::openSynchronizationSettings() { syncDialog = new QDialog(this); syncDialog->setWindowTitle(tr("Synchronization Settings")); QVBoxLayout *box1 = new QVBoxLayout(syncDialog); QGridLayout *grid = new QGridLayout(); grid->addWidget(new QLabel(tr("Web address:"), syncDialog), 0, 0); syncUrlEdit = new QLineEdit(budget->o_sync->url, syncDialog); syncUrlEdit->setPlaceholderText(tr("optional")); grid->addWidget(syncUrlEdit, 0, 1); grid->addWidget(new QLabel(tr("Download command:"), syncDialog), 1, 0); syncDownloadEdit = new QLineEdit(budget->o_sync->download, syncDialog); syncDownloadEdit->setPlaceholderText(tr("optional")); grid->addWidget(syncDownloadEdit, 1, 1); grid->addWidget(new QLabel(tr("Upload command:"), syncDialog), 2, 0); syncUploadEdit = new QLineEdit(budget->o_sync->upload, syncDialog); syncUploadEdit->setPlaceholderText(tr("mandatory")); grid->addWidget(syncUploadEdit, 2, 1); grid->addWidget(new QLabel(tr("%f = local file (temporary), %u = url"), syncDialog), 3, 1); syncAutoBox = new QCheckBox(tr("Automatic synchronization"), syncDialog); syncAutoBox->setChecked(budget->o_sync->autosync); grid->addWidget(syncAutoBox, 4, 0, 1, 2); box1->addLayout(grid); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, syncDialog); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); uploadButton = buttonBox->addButton(tr("Upload"), QDialogButtonBox::ActionRole); uploadButton->setEnabled(!budget->o_sync->upload.isEmpty()); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), syncDialog, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), syncDialog, SLOT(accept())); connect(uploadButton, SIGNAL(clicked()), this, SLOT(uploadClicked())); connect(syncUploadEdit, SIGNAL(textChanged(const QString&)), this, SLOT(syncUploadChanged(const QString&))); box1->addWidget(buttonBox); if(syncDialog->exec() == QDialog::Accepted) { budget->o_sync->url = syncUrlEdit->text().trimmed(); budget->o_sync->download = syncDownloadEdit->text().trimmed(); budget->o_sync->upload = syncUploadEdit->text().trimmed(); budget->o_sync->autosync = syncAutoBox->isChecked(); setModified(true); } syncDialog->deleteLater(); syncDialog = NULL; } void Eqonomize::syncUploadChanged(const QString &text) { uploadButton->setEnabled(!text.trimmed().isEmpty()); } void Eqonomize::uploadClicked() { if(modified) { if(!current_url.isValid()) { if(saveAs(true, false, syncDialog)) return; } else { if(!saveURL(current_url, true, false, syncDialog)) return; } } QString upload_bak = budget->o_sync->upload; QString download_bak = budget->o_sync->download; QString url_bak = budget->o_sync->url; bool autosync_bak = budget->o_sync->autosync; budget->o_sync->url = syncUrlEdit->text().trimmed(); budget->o_sync->download = syncDownloadEdit->text().trimmed(); budget->o_sync->upload = syncUploadEdit->text().trimmed(); budget->o_sync->autosync = syncAutoBox->isChecked(); QTemporaryFile file; file.open(); QProgressDialog *syncProgressDialog = new QProgressDialog(tr("Uploading…"), tr("Abort"), 0, 1, syncDialog); syncProgressDialog->setWindowModality(Qt::WindowModal); syncProgressDialog->setMinimumDuration(200); syncProgressDialog->setMaximum(1); connect(syncProgressDialog, SIGNAL(canceled()), this, SLOT(cancelSync())); syncProgressDialog->setValue(0); file.close(); QString error = budget->syncUpload(file.fileName()); if(!error.isEmpty()) { syncProgressDialog->reset(); syncProgressDialog->deleteLater(); QMessageBox::critical(syncDialog, tr("Error uploading file"), tr("Error uploading %1: %2.").arg(current_url.toString()).arg(error)); } else { syncProgressDialog->setValue(1); syncProgressDialog->deleteLater(); setModified(true); } budget->o_sync->url = url_bak; budget->o_sync->upload = upload_bak; budget->o_sync->download = download_bak; budget->o_sync->autosync = autosync_bak; } void Eqonomize::fileSynchronize() { if(budget->o_sync->isComplete()) { bool b = true; if(modified) { if(!current_url.isValid()) { b = saveAs(true, false, syncDialog); } else { b = saveURL(current_url, true, false, syncDialog); } } if(b) sync(true, true, syncDialog); } else { openSynchronizationSettings(); } } void Eqonomize::cancelSync() { budget->cancelSync(); } void Eqonomize::sync(bool do_save, bool on_load, QWidget *parent) { if(!parent) parent = this; QProgressDialog *syncProgressDialog = new QProgressDialog(tr("Synchronizing…"), tr("Abort"), 0, 1, parent); syncProgressDialog->setWindowModality(Qt::WindowModal); syncProgressDialog->setMinimumDuration(200); syncProgressDialog->setMaximum(1); connect(syncProgressDialog, SIGNAL(canceled()), this, SLOT(cancelSync())); syncProgressDialog->setValue(0); QString error, errors; int rev_bak = budget->o_sync->revision; if(budget->sync(error, errors, true, on_load)) { syncProgressDialog->setValue(1); syncProgressDialog->deleteLater(); if(!error.isEmpty()) QMessageBox::critical(parent, tr("Error synchronizing file"), tr("Error synchronizing %1: %2.").arg(current_url.toString()).arg(error)); else if(!errors.isEmpty()) QMessageBox::critical(parent, tr("Synchronization error"), errors); if(do_save) { saveURL(current_url, false, false, parent); } reloadBudget(); } else { syncProgressDialog->reset(); syncProgressDialog->deleteLater(); if(!error.isEmpty()) QMessageBox::critical(parent, tr("Error synchronizing file"), tr("Error synchronizing %1: %2.").arg(current_url.toString()).arg(error)); if(rev_bak != budget->o_sync->revision) { if(do_save) { QString error = budget->saveFile(current_url.toLocalFile(), QFile::ReadUser | QFile::WriteUser, true); if(!error.isNull()) { QMessageBox::critical(parent, tr("Couldn't save file"), tr("Error saving %1: %2.").arg(current_url.toString()).arg(error)); } } else { setModified(true); } } } } bool Eqonomize::saveURL(const QUrl& url, bool do_local_sync, bool do_cloud_sync, QWidget *parent) { if(!parent) parent = this; bool exists = QFile::exists(url.toLocalFile()); if(exists) { if(do_local_sync && url == current_url) { QString error; if(budget->isUnsynced(url.toLocalFile(), error)) { switch(QMessageBox::question(parent, tr("Synchronize file?"), tr("The file has been modified by a different user or program. Do you wish to merge changes?"), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, QMessageBox::Yes)) { case QMessageBox::Yes: { QString errors; error = budget->syncFile(url.toLocalFile(), errors); if(!error.isNull()) { QMessageBox::critical(parent, tr("Couldn't open file"), tr("Error loading %1: %2.").arg(url.toString()).arg(error)); return false; } if(!errors.isEmpty()) { QMessageBox::critical(parent, tr("Error"), errors); return false; } reloadBudget(); break; } case QMessageBox::No: {break;} default: { return false; } } } else if(!error.isNull()) { QMessageBox::critical(parent, tr("Couldn't save file"), tr("Error saving %1: %2.").arg(url.toString()).arg(error)); return false; } } if(!QFile::exists(url.toLocalFile() + "~") || QFile::remove(url.toLocalFile() + "~")) { QFile::copy(url.toLocalFile(), url.toLocalFile() + "~"); } QFileInfo urlinfo(url.toLocalFile()); QDir urldir(urlinfo.absolutePath()); int i_backup_frequency = BACKUP_WEEKLY; if(ActionSelectBackupFrequency->checkedAction() == ABFNever) {i_backup_frequency = BACKUP_NEVER;} else if(ActionSelectBackupFrequency->checkedAction() == ABFDaily) {i_backup_frequency = BACKUP_DAILY;} else if(ActionSelectBackupFrequency->checkedAction() == ABFFortnightly) {i_backup_frequency = BACKUP_FORTNIGHTLY;} else if(ActionSelectBackupFrequency->checkedAction() == ABFMonthly) {i_backup_frequency = BACKUP_MONTHLY;} if(i_backup_frequency > BACKUP_NEVER && (urldir.exists(urlinfo.baseName() + "-backup") || urldir.mkdir(urlinfo.baseName() + "-backup"))) { QDir backupdir(urldir.absolutePath() + QString("/") + urlinfo.baseName() + "-backup"); QStringList backup_files; if(urlinfo.suffix().isEmpty()) backup_files = backupdir.entryList(QStringList(urlinfo.baseName() + QString("_\?\?\?\?-\?\?-\?\?")), QDir::Files, QDir::Time); else backup_files = backupdir.entryList(QStringList(urlinfo.baseName() + QString("_\?\?\?\?-\?\?-\?\?.") + urlinfo.suffix()), QDir::Files, QDir::Time); bool save_backup = backup_files.isEmpty(); if(!save_backup) { QString last_backup = backup_files.first(); int suffix_length = 0; if(!urlinfo.suffix().isEmpty()) suffix_length += urlinfo.suffix().length() + 1; QDate last_backup_date = QDate::fromString(last_backup.mid(last_backup.length() - 10 - suffix_length, 10), "yyyy-MM-dd"); switch(i_backup_frequency) { case BACKUP_DAILY: {last_backup_date = last_backup_date.addDays(1); break;} case BACKUP_WEEKLY: {last_backup_date = last_backup_date.addDays(7); break;} case BACKUP_FORTNIGHTLY: {last_backup_date = last_backup_date.addDays(14); break;} default: {last_backup_date = last_backup_date.addMonths(1); break;} } save_backup = (last_backup_date <= QDate::currentDate()); } if(save_backup) { if(urlinfo.suffix().isEmpty()) QFile::copy(url.toLocalFile(), backupdir.absolutePath() + QString("/") + urlinfo.baseName() + QString("_") + QDate::currentDate().toString("yyyy-MM-dd")); else QFile::copy(url.toLocalFile(), backupdir.absolutePath() + QString("/") + urlinfo.baseName() + QString("_") + QDate::currentDate().toString("yyyy-MM-dd") + QString(".") + urlinfo.suffix()); } } } if(do_cloud_sync && budget->autosyncEnabled()) { sync(false); } QString error = budget->saveFile(url.toLocalFile(), QFile::ReadUser | QFile::WriteUser); if(!error.isNull()) { QMessageBox::critical(parent, tr("Couldn't save file"), tr("Error saving %1: %2.").arg(url.toString()).arg(error)); return false; } setWindowTitle(url.fileName() + "[*]"); current_url = url; ActionFileReload->setEnabled(true); QSettings settings; settings.beginGroup("GeneralOptions"); settings.setValue("lastURL", current_url.url()); settings.endGroup(); if(!cr_tmp_file.isEmpty()) { QFile autosaveFile(cr_tmp_file); autosaveFile.remove(); cr_tmp_file = ""; } settings.sync(); updateRecentFiles(url.toLocalFile()); setModified(false); return true; } void Eqonomize::importCSV() { ImportCSVDialog *dialog = new ImportCSVDialog(b_extra, budget, this); if(dialog->exec() == QDialog::Accepted) { reloadBudget(); emit accountsModified(); emit transactionsModified(); setModified(true); } dialog->deleteLater(); } void Eqonomize::importQIF() { if(importQIFFile(budget, this, b_extra)) { reloadBudget(); emit accountsModified(); emit transactionsModified(); setModified(true); } } void Eqonomize::importEQZ() { QMimeDatabase db; QMimeType mime = db.mimeTypeForName("application/x-eqonomize"); QString filter_string; if(mime.isValid()) filter_string = mime.filterString(); if(filter_string.isEmpty()) filter_string = tr("Eqonomize! Accounting File") + "(*.eqz)"; QString url = QFileDialog::getOpenFileName(this, QString(), current_url.isValid() ? current_url.adjusted(QUrl::RemoveFilename).toLocalFile() : QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + QString("/"), filter_string); if(!url.isEmpty()) { if(openURL(QUrl::fromLocalFile(url), true)) setModified(true); } } void Eqonomize::exportQIF() { exportQIFFile(budget, this, b_extra); } void Eqonomize::checkAvailableVersion_readdata() { QByteArray ssystem; #if defined (Q_OS_WIN32) ssystem = "Windows"; #elif defined(Q_OS_ANDROID) return; #elif defined(Q_OS_LINUX) ssystem = "Linux"; #else return; #endif if(checkVersionReply->error() != QNetworkReply::NoError) { checkVersionReply->abort(); return; } QByteArray sbuffer = checkVersionReply->readAll(); int i = sbuffer.indexOf(ssystem); if(i < 0) return; i = sbuffer.indexOf(':', i); if(i < 0) return; int i2 = sbuffer.indexOf('\n', i); if(i2 > 0) sbuffer = sbuffer.left(i2); sbuffer = sbuffer.right(sbuffer.length() - (i + 1)).trimmed(); QSettings settings; settings.beginGroup("GeneralOptions"); QByteArray old_version = settings.value("lastVersionFound").toByteArray(); if(old_version.isEmpty()) old_version = VERSION; bool b = false; while(sbuffer != old_version) { QList version_parts_new = sbuffer.split('.'); if(version_parts_new.isEmpty()) break; QList version_parts_old = old_version.split('.'); if(version_parts_old.isEmpty()) break; if(version_parts_new.last().size() > 0) { char c = version_parts_new.last().at(version_parts_new.last().size() - 1); if(c < '0' || c > '9') { version_parts_new.last().chop(1); version_parts_new.append(QByteArray(1, c)); } } if(version_parts_old.last().size() > 0) { char c = version_parts_old.last().at(version_parts_old.last().size() - 1); if(c < '0' || c > '9') { version_parts_old.last().chop(1); version_parts_old.append(QByteArray(1, c)); } } for(i = 0; i < version_parts_new.size(); i++) { if(i == version_parts_old.size() || version_parts_new[i].toInt() > version_parts_old[i].toInt()) {b = true; break;} else if(version_parts_new[i].toInt() < version_parts_old[i].toInt()) break; } if(b && old_version != VERSION) { b = false; settings.setValue("lastVersionFound", sbuffer); old_version = VERSION; } else { break; } } if(b) { QMessageBox::information(this, tr("New version available"), tr("A new version of %1 is available.

    You can get version %2 at %3.").arg("Eqonomize!").arg(QString(sbuffer)).arg("eqonomize.github.io")); settings.setValue("lastVersionFound", sbuffer); } } void Eqonomize::checkAvailableVersion() { #if defined (Q_OS_WIN32) #elif defined(Q_OS_ANDROID) return; #elif defined(Q_OS_LINUX) #else return; #endif QSettings settings; settings.beginGroup("GeneralOptions"); settings.setValue("lastVersionCheck", QDate::currentDate().toString(Qt::ISODate)); checkVersionReply = budget->nam.get(QNetworkRequest(QUrl("https://eqonomize.github.io/CURRENT_VERSIONS"))); connect(checkVersionReply, SIGNAL(finished()), this, SLOT(checkAvailableVersion_readdata())); } void Eqonomize::checkExchangeRatesTimeOut() { Currency *cur = budget->defaultCurrency(); if(cur != budget->currency_euro && cur->exchangeRateSource() == EXCHANGE_RATE_SOURCE_NONE) cur = NULL; for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { AssetsAccount *acc = *it; if(acc->currency() != NULL && acc->currency() != cur && (acc->currency() == budget->currency_euro || acc->currency()->exchangeRateSource() != EXCHANGE_RATE_SOURCE_NONE)) { if(cur) { if(timeToUpdateExchangeRates()) updateExchangeRates(true); break; } cur = acc->currency(); } } } bool Eqonomize::timeToUpdateExchangeRates() { QSettings settings; settings.beginGroup("GeneralOptions"); QDate last_update = QDate::fromString(settings.value("lastExchangeRatesUpdate").toString(), Qt::ISODate); QDate last_update_try = QDate::fromString(settings.value("lastExchangeRatesUpdateTry").toString(), Qt::ISODate); settings.endGroup(); QDate curdate = QDate::currentDate(); if(!last_update_try.isValid() || curdate > last_update_try) { if(!last_update.isValid() || curdate >= last_update.addDays(7)) { return true; } } return false; } void Eqonomize::updateExchangeRates(bool do_currencies_modified) { QProgressDialog *updateExchangeRatesProgressDialog = new QProgressDialog(tr("Updating exchange rates…"), tr("Abort"), 0, 1, this); updateExchangeRatesProgressDialog->setWindowModality(Qt::WindowModal); updateExchangeRatesProgressDialog->setMinimumDuration(200); updateExchangeRatesProgressDialog->setMaximum(2); connect(updateExchangeRatesProgressDialog, SIGNAL(canceled()), this, SLOT(cancelUpdateExchangeRates())); updateExchangeRatesProgressDialog->setValue(0); QEventLoop loop; updateExchangeRatesReply = budget->nam.get(QNetworkRequest(QUrl("https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml"))); connect(updateExchangeRatesReply, SIGNAL(finished()), &loop, SLOT(quit())); loop.exec(); QSettings settings; settings.beginGroup("GeneralOptions"); if(updateExchangeRatesReply->error() == QNetworkReply::OperationCanceledError) { //canceled by user updateExchangeRatesProgressDialog->reset(); } else if(updateExchangeRatesReply->error() != QNetworkReply::NoError) { updateExchangeRatesProgressDialog->reset(); QMessageBox::critical(this, tr("Error"), tr("Failed to download exchange rates from %1: %2.").arg("https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml").arg(updateExchangeRatesReply->errorString())); updateExchangeRatesReply->abort(); } else { QString errors = budget->loadECBData(updateExchangeRatesReply->readAll()); if(!errors.isEmpty()) { QMessageBox::critical(this, tr("Error"), tr("Error reading data from %1: %2.").arg("https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml").arg(errors)); } else { settings.setValue("lastExchangeRatesUpdate", QDate::currentDate().toString(Qt::ISODate)); updateExchangeRatesProgressDialog->setValue(1); QEventLoop loop2; //updateExchangeRatesReply = budget->nam.get(QNetworkRequest(QUrl("http://www.mycurrency.net/service/rates"))); updateExchangeRatesReply = budget->nam.get(QNetworkRequest(QUrl("https://www.mycurrency.net/=EU"))); connect(updateExchangeRatesReply, SIGNAL(finished()), &loop2, SLOT(quit())); loop2.exec(); if(updateExchangeRatesReply->error() == QNetworkReply::OperationCanceledError) { //canceled by user updateExchangeRatesProgressDialog->reset(); } else if(updateExchangeRatesReply->error() != QNetworkReply::NoError) { updateExchangeRatesProgressDialog->reset(); //QMessageBox::critical(this, tr("Error"), tr("Failed to download exchange rates from %1: %2.").arg("http://www.mycurrency.net/service/rates").arg(updateExchangeRatesReply->errorString())); QMessageBox::critical(this, tr("Error"), tr("Failed to download exchange rates from %1: %2.").arg("https://www.mycurrency.net").arg(updateExchangeRatesReply->errorString())); updateExchangeRatesReply->abort(); } else { //QString errors = budget->loadMyCurrencyNetData(updateExchangeRatesReply->readAll()); QString errors = budget->loadMyCurrencyNetHtml(updateExchangeRatesReply->readAll()); if(!errors.isEmpty()) { QMessageBox::critical(this, tr("Error"), tr("Error reading data from %1: %2.").arg("http://www.mycurrency.net/service/rates").arg(errors)); } } QString error = budget->saveCurrencies(); if(!error.isNull()) QMessageBox::critical(this, tr("Error"), tr("Error saving currencies: %1.").arg(error)); if(do_currencies_modified) { budget->resetDefaultCurrencyChanged(); currenciesModified(); } else { if(currencyConversionWindow && currencyConversionWindow->isVisible()) { currencyConversionWindow->convertFrom(); } } updateExchangeRatesProgressDialog->setValue(2); } } settings.setValue("lastExchangeRatesUpdateTry", QDate::currentDate().toString(Qt::ISODate)); settings.endGroup(); updateExchangeRatesProgressDialog->deleteLater(); updateExchangeRatesReply->deleteLater(); } void Eqonomize::cancelUpdateExchangeRates() { updateExchangeRatesReply->abort(); } void Eqonomize::valueAlignmentUpdated(bool b) { QSettings settings; settings.setValue("GeneralOptions/rightAlignValues", b); right_align_values = b; updateSecurities(); updateScheduledTransactions(); expensesWidget->filterTransactions(); incomesWidget->filterTransactions(); transfersWidget->filterTransactions(); } void Eqonomize::currenciesModified() { expensesWidget->updateFromAccounts(); incomesWidget->updateToAccounts(); transfersWidget->updateAccounts(); expensesWidget->filterTransactions(); incomesWidget->filterTransactions(); transfersWidget->filterTransactions(); filterAccounts(); updateScheduledTransactions(); updateSecurities(); if(budget->defaultCurrencyChanged()) { setModified(true); budget->resetDefaultCurrencyChanged(); } emit transactionsModified(); updateUsesMultipleCurrencies(); if(currencyConversionWindow) { currencyConversionWindow->updateCurrencies(); if(currencyConversionWindow->isVisible()) currencyConversionWindow->convertFrom(); } } void Eqonomize::warnAndAskForExchangeRate() { QDialog *dialog = new QDialog(this); Currency *cur = budget->defaultCurrency(); dialog->setWindowTitle(tr("Unrecognized Currency")); dialog->setModal(true); QVBoxLayout *box1 = new QVBoxLayout(dialog); QGridLayout *grid = new QGridLayout(); box1->addLayout(grid); QLabel *label = new QLabel(tr("No exchange rate is available for the default currency (%1). If you wish to use multiple currencies you should set the exchange rate manually.").arg(cur->code()), dialog); label->setWordWrap(true); grid->addWidget(label, 0, 0, 1, 2); label = new QLabel(budget->currency_euro->formatValue(1.0) + " =", dialog); label->setAlignment(Qt::AlignRight); grid->addWidget(label, 1, 0); EqonomizeValueEdit *rateEdit = new EqonomizeValueEdit(0.00001, 1.0, 1.0, 5, true, this, budget); grid->addWidget(rateEdit, 1, 1); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), dialog, SLOT(accept())); box1->addWidget(buttonBox); dialog->exec(); if(rateEdit->value() != 1.0) { cur->setExchangeRate(rateEdit->value()); budget->currencyModified(cur); } QString error = budget->saveCurrencies(); if(!error.isNull()) QMessageBox::critical(this, tr("Error"), tr("Error saving currencies: %1.").arg(error)); dialog->deleteLater(); } void Eqonomize::setMainCurrency() { QDialog *dialog = new QDialog(this); dialog->setWindowTitle(tr("Set Main Currency")); dialog->setModal(true); QVBoxLayout *box1 = new QVBoxLayout(dialog); QGridLayout *grid = new QGridLayout(); box1->addLayout(grid); grid->addWidget(new QLabel(tr("Currency:"), dialog), 0, 0); setMainCurrencyCombo = new QComboBox(this); setMainCurrencyCombo->setEditable(false); grid->addWidget(setMainCurrencyCombo, 0, 1); setMainCurrencyCombo->addItem(tr("New currency…")); int i = 1; for(CurrencyList::const_iterator it = budget->currencies.constBegin(); it != budget->currencies.constEnd(); ++it) { Currency *currency = *it; if(!currency->name(false).isEmpty()) { setMainCurrencyCombo->addItem(QIcon(":/data/flags/" + currency->code() + ".png"), QString("%2 (%1)").arg(qApp->translate("currencies.xml", qPrintable(currency->name()))).arg(currency->code())); } else { setMainCurrencyCombo->addItem(currency->code()); } setMainCurrencyCombo->setItemData(i, QVariant::fromValue((void*) currency)); if(currency == budget->defaultCurrency()) { setMainCurrencyCombo->setCurrentIndex(i); prev_set_main_currency_index = i; } i++; } QCheckBox *replaceButton = new QCheckBox(tr("Replace all occurrences of the former main currency"), dialog); replaceButton->setChecked(false); grid->addWidget(replaceButton, 1, 0, 1, 2); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, dialog); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), dialog, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), dialog, SLOT(accept())); box1->addWidget(buttonBox); connect(setMainCurrencyCombo, SIGNAL(activated(int)), this, SLOT(setMainCurrencyIndexChanged(int))); if(dialog->exec() == QDialog::Accepted) { Currency *cur = NULL; int index = setMainCurrencyCombo->currentIndex(); if(index > 0) cur = (Currency*) setMainCurrencyCombo->itemData(index).value(); if(cur && cur != budget->defaultCurrency()) { if(replaceButton->isChecked()) { for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { AssetsAccount *acc = *it; if(acc->currency() == budget->defaultCurrency()) { acc->setCurrency(cur); } } } budget->setDefaultCurrency(cur); budgetEdit->setCurrency(cur); currenciesModified(); setModified(true); } } dialog->deleteLater(); } void Eqonomize::setMainCurrencyIndexChanged(int index) { if(index == 0) { EditCurrencyDialog *dialog = new EditCurrencyDialog(budget, NULL, false, this); if(dialog->exec() == QDialog::Accepted) { Currency *cur = dialog->createCurrency(); if(currencyConversionWindow) currencyConversionWindow->updateCurrencies(); setMainCurrencyCombo->clear(); setMainCurrencyCombo->addItem(tr("New currency…")); int i = 1; for(CurrencyList::const_iterator it = budget->currencies.constBegin(); it != budget->currencies.constEnd(); ++it) { Currency *currency = *it; setMainCurrencyCombo->addItem(QIcon(":/data/flags/" + currency->code() + ".png"), currency->code()); setMainCurrencyCombo->setItemData(i, QVariant::fromValue((void*) currency)); if(currency == cur) { setMainCurrencyCombo->setCurrentIndex(i); prev_set_main_currency_index = i; } i++; } } else { setMainCurrencyCombo->setCurrentIndex(prev_set_main_currency_index); } dialog->deleteLater(); } else { prev_set_main_currency_index = index; } } void Eqonomize::updateUsesMultipleCurrencies() { bool b = budget->usesMultipleCurrencies(); transfersWidget->useMultipleCurrencies(b); incomesWidget->useMultipleCurrencies(b); expensesWidget->useMultipleCurrencies(b); } void Eqonomize::openCurrencyConversion() { if(timeToUpdateExchangeRates()) { updateExchangeRates(true); } if(!currencyConversionWindow) { currencyConversionWindow = new CurrencyConversionDialog(budget, this); } bool b = currencyConversionWindow->isVisible(); currencyConversionWindow->show(); if(!b) currencyConversionWindow->convertFrom(); currencyConversionWindow->raise(); currencyConversionWindow->activateWindow(); } void Eqonomize::showOverTimeReport() { if(!otrDialog) { otrDialog = new OverTimeReportDialog(budget, NULL); QSettings settings; QSize dialog_size = settings.value("OverTimeReport/size", QSize()).toSize(); if(!dialog_size.isValid()) { #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) # if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) QScreen *scr = screen(); # else QScreen *scr = QGuiApplication::screenAt(pos); # endif if(!scr) scr = QGuiApplication::primaryScreen(); QRect rect = scr->availableGeometry(); #else QRect rect = QApplication::desktop()->availableGeometry(this); #endif dialog_size = QSize(750, 650).boundedTo(rect.size()); } otrDialog->resize(dialog_size); connect(this, SIGNAL(tagsModified()), ((OverTimeReportDialog*) otrDialog)->report, SLOT(updateTags())); connect(this, SIGNAL(accountsModified()), ((OverTimeReportDialog*) otrDialog)->report, SLOT(updateAccounts())); connect(this, SIGNAL(transactionsModified()), ((OverTimeReportDialog*) otrDialog)->report, SLOT(updateTransactions())); connect(this, SIGNAL(timeToSaveConfig()), ((OverTimeReportDialog*) otrDialog)->report, SLOT(saveConfig())); } else if(!otrDialog->isVisible()) { ((OverTimeReportDialog*) otrDialog)->report->resetOptions(); } bool b = otrDialog->isVisible(); otrDialog->show(); if(!b) ((OverTimeReportDialog*) otrDialog)->report->updateDisplay(); otrDialog->raise(); otrDialog->activateWindow(); } void Eqonomize::showCategoriesComparisonReport() { if(!ccrDialog) { ccrDialog = new CategoriesComparisonReportDialog(b_extra, budget, NULL); QSettings settings; QSize dialog_size = settings.value("CategoriesComparisonReport/size", QSize()).toSize(); if(!dialog_size.isValid()) { #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) # if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) QScreen *scr = screen(); # else QScreen *scr = QGuiApplication::screenAt(pos); # endif if(!scr) scr = QGuiApplication::primaryScreen(); QRect rect = scr->availableGeometry(); #else QRect rect = QApplication::desktop()->availableGeometry(this); #endif dialog_size = QSize(750, 670).boundedTo(rect.size()); } ccrDialog->resize(dialog_size); connect(this, SIGNAL(tagsModified()), ((CategoriesComparisonReportDialog*) ccrDialog)->report, SLOT(updateTags())); connect(this, SIGNAL(accountsModified()), ((CategoriesComparisonReportDialog*) ccrDialog)->report, SLOT(updateAccounts())); connect(this, SIGNAL(transactionsModified()), ((CategoriesComparisonReportDialog*) ccrDialog)->report, SLOT(updateTransactions())); connect(this, SIGNAL(timeToSaveConfig()), ((CategoriesComparisonReportDialog*) ccrDialog)->report, SLOT(saveConfig())); } else if(!ccrDialog->isVisible()) { ((CategoriesComparisonReportDialog*) ccrDialog)->report->resetOptions(); } bool b = ccrDialog->isVisible(); ccrDialog->show(); if(!b) ((CategoriesComparisonReportDialog*) ccrDialog)->report->updateDisplay(); ccrDialog->raise(); ccrDialog->activateWindow(); } void Eqonomize::showOverTimeChart() { if(!otcDialog) { otcDialog = new OverTimeChartDialog(b_extra, budget, NULL); QSettings settings; QSize dialog_size = settings.value("OverTimeChart/size", QSize()).toSize(); if(!dialog_size.isValid()) { #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) # if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) QScreen *scr = screen(); # else QScreen *scr = QGuiApplication::screenAt(pos); # endif if(!scr) scr = QGuiApplication::primaryScreen(); QRect rect = scr->availableGeometry(); #else QRect rect = QApplication::desktop()->availableGeometry(this); #endif dialog_size = QSize(850, b_extra ? 750 : 730).boundedTo(rect.size()); } otcDialog->resize(dialog_size); connect(this, SIGNAL(tagsModified()), ((OverTimeChartDialog*) otcDialog)->chart, SLOT(updateTags())); connect(this, SIGNAL(accountsModified()), ((OverTimeChartDialog*) otcDialog)->chart, SLOT(updateAccounts())); connect(this, SIGNAL(transactionsModified()), ((OverTimeChartDialog*) otcDialog)->chart, SLOT(updateTransactions())); connect(this, SIGNAL(timeToSaveConfig()), ((OverTimeChartDialog*) otcDialog)->chart, SLOT(saveConfig())); } else if(!otcDialog->isVisible()) { ((OverTimeChartDialog*) otcDialog)->chart->resetOptions(); } bool b = otcDialog->isVisible(); otcDialog->show(); if(!b) ((OverTimeChartDialog*) otcDialog)->chart->updateDisplay(); otcDialog->raise(); otcDialog->activateWindow(); } void Eqonomize::showCategoriesComparisonChart() { if(!cccDialog) { cccDialog = new CategoriesComparisonChartDialog(budget, NULL); QSettings settings; QSize dialog_size = settings.value("CategoriesComparisonChart/size", QSize()).toSize(); if(!dialog_size.isValid()) { #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) # if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) QScreen *scr = screen(); # else QScreen *scr = QGuiApplication::screenAt(pos); # endif if(!scr) scr = QGuiApplication::primaryScreen(); QRect rect = scr->availableGeometry(); #else QRect rect = QApplication::desktop()->availableGeometry(this); #endif dialog_size = QSize(750, 700).boundedTo(rect.size()); } cccDialog->resize(dialog_size); connect(this, SIGNAL(accountsModified()), ((CategoriesComparisonChartDialog*) cccDialog)->chart, SLOT(updateAccounts())); connect(this, SIGNAL(transactionsModified()), ((CategoriesComparisonChartDialog*) cccDialog)->chart, SLOT(updateTransactions())); connect(this, SIGNAL(timeToSaveConfig()), ((CategoriesComparisonChartDialog*) cccDialog)->chart, SLOT(saveConfig())); } else if(!cccDialog->isVisible()) { ((CategoriesComparisonChartDialog*) cccDialog)->chart->resetOptions(); } bool b = cccDialog->isVisible(); cccDialog->show(); if(!b) ((CategoriesComparisonChartDialog*) cccDialog)->chart->updateDisplay(); cccDialog->raise(); cccDialog->activateWindow(); } bool Eqonomize::exportScheduleList(QTextStream &outf, int fileformat) { switch(fileformat) { case 'h': { #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) outf.setCodec("UTF-8"); #endif outf << "" << '\n'; outf << "" << '\n'; outf << "\t" << '\n'; outf << "\t\t"; outf << htmlize_string(tr("Transaction Schedule")); outf << "" << '\n'; outf << "\t\t" << '\n'; outf << "\t\tapplicationDisplayName() << "\">" << '\n'; outf << "\t" << '\n'; outf << "\t" << '\n'; outf << "\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t\t" << '\n'; QTreeWidgetItem *header = scheduleView->headerItem(); outf << "\t\t\t\t\t"; for(int index = 0; index <= 8; index++) { if(!scheduleView->isColumnHidden(index)) outf << ""; } outf << "\n\t\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; QTreeWidgetItemIterator it(scheduleView); ScheduleListViewItem *i = (ScheduleListViewItem*) *it; while(i) { outf << "\t\t\t\t" << '\n'; outf << "\t\t\t\t\t"; for(int index = 0; index <= 8; index++) { if(!scheduleView->isColumnHidden(index)) { if(index == 0) outf << ""; else if(index == 3) outf << ""; else outf << ""; } } outf << "\n\t\t\t\t" << '\n'; ++it; i = (ScheduleListViewItem*) *it; } outf << "\t\t\t" << '\n'; outf << "\t\t
    "; outf << htmlize_string(tr("Transaction Schedule")); outf << "
    " << htmlize_string(header->text(index)) << "
    " << htmlize_string(i->text(index)) << "" << htmlize_string(i->text(index)) << "" << htmlize_string(i->text(index)) << "
    " << '\n'; outf << "\t" << '\n'; outf << "" << '\n'; break; } case 'c': { //outf.setEncoding(Q3TextStream::Locale); QTreeWidgetItem *header = scheduleView->headerItem(); for(int index = 0; index <= 8; index++) { if(!scheduleView->isColumnHidden(index)) { if(index > 0) outf << ","; outf << "\"" << header->text(index) << "\""; } } outf << "\n"; QTreeWidgetItemIterator it(scheduleView); ScheduleListViewItem *i = (ScheduleListViewItem*) *it; while(i) { for(int index = 0; index <= 8; index++) { if(!scheduleView->isColumnHidden(index)) { if(index > 0) outf << ","; if(index == 3) { outf << "\"" << htmlize_string(i->text(index).replace("−", "-").remove(" ")) << "\""; } else { outf << "\"" << i->text(index) << "\""; } } } outf << "\n"; ++it; i = (ScheduleListViewItem*) *it; } break; } } return true; } bool Eqonomize::exportSecuritiesList(QTextStream &outf, int fileformat) { switch(fileformat) { case 'h': { #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) outf.setCodec("UTF-8"); #endif outf << "" << '\n'; outf << "" << '\n'; outf << "\t" << '\n'; outf << "\t\t"; outf << htmlize_string(tr("Securities", "Financial security (e.g. stock, mutual fund)")); outf << "" << '\n'; outf << "\t\t" << '\n'; outf << "\t\tapplicationDisplayName() << "\">" << '\n'; outf << "\t" << '\n'; outf << "\t" << '\n'; outf << "\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t\t" << '\n'; QTreeWidgetItem *header = securitiesView->headerItem(); outf << "\t\t\t\t\t"; outf << ""; outf << ""; outf << ""; outf << ""; outf << ""; outf << ""; outf << ""; outf << "" << "\n"; outf << "\t\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; QTreeWidgetItemIterator it(securitiesView); SecurityListViewItem *i = (SecurityListViewItem*) *it; while(i) { outf << "\t\t\t\t" << '\n'; outf << "\t\t\t\t\t"; outf << ""; outf << ""; outf << ""; outf << ""; outf << ""; outf << ""; outf << ""; outf << "" << "\n"; outf << "\t\t\t\t" << '\n'; ++it; i = (SecurityListViewItem*) *it; } outf << "\t\t\t\t" << '\n'; if(securitiesView->topLevelItemCount() > 1) { outf << "\t\t\t\t\t"; outf << ""; outf << ""; outf << ""; outf << ""; outf << ""; outf << ""; outf << ""; outf << "" << "\n"; outf << "\t\t\t\t" << '\n'; } outf << "\t\t\t" << '\n'; outf << "\t\t
    "; outf << htmlize_string(tr("Securities", "Financial security (e.g. stock, mutual fund)")); outf << "
    " << htmlize_string(header->text(0)) << "" << htmlize_string(header->text(1)) << "" << htmlize_string(header->text(2)) << "" << htmlize_string(header->text(3)) << "" << htmlize_string(header->text(4)) << "" << htmlize_string(header->text(5)) << "" << htmlize_string(header->text(6)) << "" << htmlize_string(header->text(7)) << "" << htmlize_string(header->text(8)) << "
    " << htmlize_string(i->text(0)) << "" << htmlize_string(i->text(1)) << "" << htmlize_string(i->text(2)) << "" << htmlize_string(i->text(3)) << "" << htmlize_string(i->text(4)) << "" << htmlize_string(i->text(5)) << "" << htmlize_string(i->text(6)) << "" << htmlize_string(i->text(7)) << "" << htmlize_string(i->text(8)) << "
    " << htmlize_string(tr("Total")) << "" << htmlize_string(budget->formatMoney(total_value)) << "--" << htmlize_string(budget->formatMoney(total_cost)) << "" << htmlize_string(budget->formatMoney(total_profit)) << "" << htmlize_string(budget->formatValue(total_rate * 100, 2) + "%") << "--
    " << '\n'; outf << "\t" << '\n'; outf << "" << '\n'; break; } case 'c': { //outf.setEncoding(Q3TextStream::Locale); QTreeWidgetItem *header = scheduleView->headerItem(); outf << "\"" << header->text(0) << "\",\"" << header->text(1) << "\",\"" << header->text(2) << "\",\"" << header->text(3) << "\",\"" << header->text(4) << "\",\"" << header->text(5) << "\",\"" << header->text(6) << "\",\"" << header->text(7) << "\",\"" << header->text(8) << "\"\n"; QTreeWidgetItemIterator it(securitiesView); SecurityListViewItem *i = (SecurityListViewItem*) *it; while(i) { outf << "\"" << i->text(0) << "\",\"" << i->text(1) << "\",\"" << i->text(2) << "\",\"" << i->text(3) << "\",\"" << i->text(4) << "\",\"" << i->text(5) << "\",\"" << i->text(6) << "\",\"" << i->text(7) << "\",\"" << i->text(8) << '\n'; ++it; i = (SecurityListViewItem*) *it; } break; } } return true; } bool Eqonomize::exportAccountsList(QTextStream &outf, int fileformat) { switch(fileformat) { case 'h': { #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) outf.setCodec("UTF-8"); #endif outf << "" << '\n'; outf << "" << '\n'; outf << "\t" << '\n'; outf << "\t\t"; outf << tr("Accounts & Categories", "html format"); outf << "" << '\n'; outf << "\t\t" << '\n'; outf << "\t\tapplicationDisplayName() << "\">" << '\n'; outf << "\t" << '\n'; outf << "\t" << '\n'; if(accountsPeriodFromButton->isChecked()) outf << "\t\t

    " << tr("Accounts & Categories (%1–%2)", "html format").arg(htmlize_string(QLocale().toString(from_date, QLocale::ShortFormat))).arg(htmlize_string(QLocale().toString(to_date, QLocale::ShortFormat))) << "

    " << '\n'; else outf << "\t\t

    " << tr("Accounts & Categories (to %1)", "html format").arg(htmlize_string(QLocale().toString(to_date, QLocale::ShortFormat))) << "

    " << '\n'; outf << "\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t\t" << '\n'; outf << "\t\t\t\t\t"; //: Noun, how much the account balance has changed outf << ""; outf << "" << '\n'; outf << "\t\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; QTreeWidgetItemIterator it(assetsItem); QTreeWidgetItem *group_item = NULL; it++; while(*it && *it != liabilitiesItem) { if((*it)->childCount() > 0) { outf << "\t\t\t\t" << '\n'; outf << "\t\t\t\t\t"; outf << ""; outf << "" << "\n"; outf << "\t\t\t\t" << '\n'; group_item = *it; } else if(group_item && (*it)->parent() != group_item) { outf << "\t\t\t\t" << '\n'; outf << "\t\t\t\t\t"; outf << ""; outf << "" << "\n"; outf << "\t\t\t\t" << '\n'; group_item = NULL; } else { outf << "\t\t\t\t" << '\n'; outf << "\t\t\t\t\t"; outf << ""; outf << "" << "\n"; outf << "\t\t\t\t" << '\n'; } ++it; } outf << "\t\t\t\t" << '\n'; outf << "\t\t\t\t\t"; outf << ""; outf << "" << "\n"; outf << "\t\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t
    "; outf << htmlize_string(tr("Assets")); outf << "
    " << htmlize_string(tr("Name")) << "" << htmlize_string(tr("Change")); bool includes_budget = (to_date > QDate::currentDate() && (expenses_budget >= 0.0 || incomes_budget >= 0.0)); outf << "" << htmlize_string(tr("Balance", "Noun. Balance of an account")); outf << "
    " << htmlize_string((*it)->text(0)); outf << ":" << htmlize_string((*it)->text(CHANGE_COLUMN)) << "" << htmlize_string((*it)->text(VALUE_COLUMN)) << "
    " << htmlize_string((*it)->text(0)); outf << "" << htmlize_string((*it)->text(CHANGE_COLUMN)) << "" << htmlize_string((*it)->text(VALUE_COLUMN)) << "
    " << htmlize_string((*it)->text(0)); outf << "" << htmlize_string((*it)->text(CHANGE_COLUMN)) << "" << htmlize_string((*it)->text(VALUE_COLUMN)) << "
    " << htmlize_string(tr("Total")); if(includes_budget) outf << "*"; outf << "" << htmlize_string(budget->formatMoney(assets_accounts_change)) << "" << htmlize_string(budget->formatMoney(assets_accounts_value)) << "
    " << '\n'; it++; if(liabilitiesItem->childCount() > 0) { outf << "\t\t
    " << '\n'; outf << "\t\t
    " << '\n'; outf << "\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t\t" << '\n'; outf << "\t\t\t\t\t"; //: Noun, how much the account balance has changed outf << ""; outf << "" << '\n'; outf << "\t\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; group_item = NULL; while(*it && *it != incomesItem) { if((*it)->childCount() > 0) { outf << "\t\t\t\t" << '\n'; outf << "\t\t\t\t\t"; outf << ""; outf << "" << "\n"; outf << "\t\t\t\t" << '\n'; group_item = *it; } else if(group_item && (*it)->parent() != group_item) { outf << "\t\t\t\t" << '\n'; outf << "\t\t\t\t\t"; outf << ""; outf << "" << "\n"; outf << "\t\t\t\t" << '\n'; group_item = NULL; } else { outf << "\t\t\t\t" << '\n'; outf << "\t\t\t\t\t"; outf << ""; outf << "" << "\n"; outf << "\t\t\t\t" << '\n'; } ++it; } outf << "\t\t\t\t" << '\n'; outf << "\t\t\t\t\t"; outf << ""; outf << "" << "\n"; outf << "\t\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t
    "; outf << htmlize_string(tr("Liabilities")); outf << "
    " << htmlize_string(tr("Name")) << "" << htmlize_string(tr("Change")); outf << "" << htmlize_string(tr("Balance", "Noun. Balance of an account")); outf << "
    " << htmlize_string((*it)->text(0)); outf << ":" << htmlize_string((*it)->text(CHANGE_COLUMN)) << "" << htmlize_string((*it)->text(VALUE_COLUMN)) << "
    " << htmlize_string((*it)->text(0)); outf << "" << htmlize_string((*it)->text(CHANGE_COLUMN)) << "" << htmlize_string((*it)->text(VALUE_COLUMN)) << "
    " << htmlize_string((*it)->text(0)); outf << "" << htmlize_string((*it)->text(CHANGE_COLUMN)) << "" << htmlize_string((*it)->text(VALUE_COLUMN)) << "
    " << htmlize_string(tr("Total")); outf << "" << htmlize_string(budget->formatMoney(-liabilities_accounts_change)) << "" << htmlize_string(budget->formatMoney(-liabilities_accounts_value)) << "
    " << '\n'; } outf << "\t\t
    " << '\n'; outf << "\t\t
    " << '\n'; outf << "\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t\t" << '\n'; outf << "\t\t\t\t\t"; outf << ""; outf << ""; //: Noun, how much the account balance has changed outf << "" << '\n'; outf << "" << '\n'; outf << "\t\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; it++; group_item = NULL; while(*it && *it != expensesItem) { Account *account = account_items[*it]; bool b_sub = ((*it)->parent() != incomesItem); outf << "\t\t\t\t" << '\n'; outf << "\t\t\t\t\t"; if(account_budget[account] < 0.0) { if(b_sub) { outf << ""; outf << ""; } else { outf << ""; outf << ""; } } else { outf << ""; outf << ""; } outf << ""; outf << "" << "\n"; outf << "\t\t\t\t" << '\n'; ++it; } outf << "\t\t\t\t" << '\n'; outf << "\t\t\t\t\t"; if(incomes_budget >= 0.0) { outf << ""; outf << ""; } else { outf << ""; outf << ""; } outf << ""; outf << "" << "\n"; outf << "\t\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t
    "; outf << htmlize_string(tr("Incomes")); outf << "
    " << htmlize_string(tr("Category")) << "" << htmlize_string(tr("Budget")) << "" << htmlize_string(tr("Remaining Budget")) << "" << htmlize_string(tr("Change")) << "" << htmlize_string(tr("Total Incomes")) << "
    "; if(b_sub) outf << ""; outf << htmlize_string(account->name()); if(b_sub) outf << ""; outf << "----"; if(b_sub) outf << ""; outf << htmlize_string(budget->formatMoney(account_budget[account])); if(b_sub) outf << ""; outf << ""; if(b_sub) outf << ""; outf << htmlize_string(budget->formatMoney(account_budget_diff[account])); if(b_sub) outf << ""; outf << ""; if(b_sub) outf << ""; outf << htmlize_string(budget->formatMoney(account_change[account])); if(b_sub) outf << ""; outf << ""; if(b_sub) outf << ""; outf << htmlize_string(budget->formatMoney(account_value[account])); if(b_sub) outf << ""; outf << "
    " << htmlize_string(tr("Total")) << "" << htmlize_string(budget->formatMoney(incomes_budget)) << "" << htmlize_string(budget->formatMoney(incomes_budget_diff)) << "" << "-" << "" << "-" << "" << htmlize_string(budget->formatMoney(incomes_accounts_change)) << "" << htmlize_string(budget->formatMoney(incomes_accounts_value)) << "
    " << '\n'; outf << "\t\t
    " << '\n'; outf << "\t\t
    " << '\n'; outf << "\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t\t" << '\n'; outf << "\t\t\t\t\t"; outf << ""; outf << ""; //: Noun, how much the account balance has changed outf << "" << '\n'; outf << "" << '\n'; outf << "\t\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; it++; group_item = NULL; while(*it && *it != tagsItem) { Account *account = account_items[*it]; bool b_sub = ((*it)->parent() != expensesItem); outf << "\t\t\t\t" << '\n'; outf << "\t\t\t\t\t"; if(account_budget[account] < 0.0) { if(b_sub) { outf << ""; outf << ""; } else { outf << ""; outf << ""; } } else { outf << ""; outf << ""; } outf << ""; outf << "" << "\n"; outf << "\t\t\t\t" << '\n'; ++it; } outf << "\t\t\t\t" << '\n'; outf << "\t\t\t\t\t"; if(expenses_budget >= 0.0) { outf << ""; outf << ""; } else { outf << ""; outf << ""; } outf << ""; outf << "" << "\n"; outf << "\t\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t
    "; outf << htmlize_string(tr("Expenses")); outf << "
    " << htmlize_string(tr("Category")) << "" << htmlize_string(tr("Budget")) << "" << htmlize_string(tr("Remaining Budget")) << "" << htmlize_string(tr("Change")) << "" << htmlize_string(tr("Total Expenses")) << "
    "; if(b_sub) outf << ""; outf << htmlize_string(account->name()); if(b_sub) outf << ""; outf << "----"; if(b_sub) outf << ""; outf << htmlize_string(budget->formatMoney(account_budget[account])); if(b_sub) outf << ""; outf << ""; if(b_sub) outf << ""; outf << htmlize_string(budget->formatMoney(account_budget_diff[account])); if(b_sub) outf << ""; outf << ""; if(b_sub) outf << ""; outf << htmlize_string(budget->formatMoney(account_change[account])); if(b_sub) outf << ""; outf << ""; if(b_sub) outf << ""; outf << htmlize_string(budget->formatMoney(account_value[account])); if(b_sub) outf << ""; outf << "
    " << htmlize_string(tr("Total")) << "" << htmlize_string(budget->formatMoney(expenses_budget)) << "" << htmlize_string(budget->formatMoney(expenses_budget_diff)) << "" << "-" << "" << "-" << "" << htmlize_string(budget->formatMoney(expenses_accounts_change)) << "" << htmlize_string(budget->formatMoney(expenses_accounts_value)) << "
    " << '\n'; it++; if(tagsItem->childCount() > 0 && tagsItem->isExpanded()) { outf << "\t\t
    " << '\n'; outf << "\t\t
    " << '\n'; outf << "\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t\t" << '\n'; outf << "\t\t\t\t\t"; //: Noun, how much the account balance has changed outf << ""; outf << "" << '\n'; outf << "\t\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; group_item = NULL; while(*it) { outf << "\t\t\t\t" << '\n'; outf << "\t\t\t\t\t"; outf << ""; outf << "" << "\n"; outf << "\t\t\t\t" << '\n'; ++it; } outf << "\t\t\t" << '\n'; outf << "\t\t
    "; outf << htmlize_string(tr("Tags")); outf << "
    " << htmlize_string(tr("Name")) << "" << htmlize_string(tr("Change")); outf << "" << htmlize_string(tr("Balance", "Noun. Balance of an account")); outf << "
    " << htmlize_string((*it)->text(0)); outf << "" << htmlize_string((*it)->text(CHANGE_COLUMN)) << "" << htmlize_string((*it)->text(VALUE_COLUMN)) << "
    " << '\n'; } if(includes_budget) { outf << "\t\t

    " << '\n'; outf << "\t\t
    " << ""; outf << "*" << htmlize_string(tr("Includes budgeted transactions")); outf << "
    " << '\n'; } outf << "\t" << '\n'; outf << "" << '\n'; break; } case 'c': { //outf.setEncoding(Q3TextStream::Locale); //: Noun, how much the account balance has changed outf << "\"" << tr("Account/Category") << "\",\"" << tr("Change") << "\",\"" << tr("Value") << "\"\n"; for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { Account *account = *it; outf << "\"" << account->name() << "\",\"" << budget->formatMoney(account_change[account]) << "\",\"" << budget->formatMoney(account_value[account]) << "\"\n"; } for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) { Account *account = *it; outf << "\"" << account->name() << "\",\"" << budget->formatMoney(account_change[account]) << "\",\"" << budget->formatMoney(account_value[account]) << "\"\n"; } for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) { Account *account = *it; outf << "\"" << account->name() << "\",\"" << budget->formatMoney(account_change[account]) << "\",\"" << budget->formatMoney(account_value[account]) << "\"\n"; } /*for(int i = 0; i < budget->tags.count(); i++) { outf << "\"" << budget->tags[i] << "\",\"" << budget->formatMoney(tag_change[budget->tags[i]]) << "\",\"" << budget->formatMoney(tag_value[budget->tags[i]]) << "\"\n"; }*/ break; } } return true; } void Eqonomize::printPreviewPaint(QPrinter *printer) { QString str; QTextStream stream(&str, QIODevice::WriteOnly); saveView(stream, 'h'); QTextDocument htmldoc; htmldoc.setHtml(str); htmldoc.print(printer); } void Eqonomize::showPrintPreview() { if(tabs->currentIndex() == EXPENSES_PAGE_INDEX) { if(expensesWidget->isEmpty()) { QMessageBox::critical(this, tr("Error"), tr("Empty expenses list.")); return; } } else if(tabs->currentIndex() == INCOMES_PAGE_INDEX) { if(incomesWidget->isEmpty()) { QMessageBox::critical(this, tr("Error"), tr("Empty incomes list.")); return; } } else if(tabs->currentIndex() == TRANSFERS_PAGE_INDEX) { if(transfersWidget->isEmpty()) { QMessageBox::critical(this, tr("Error"), tr("Empty transfers list.")); return; } } else if(tabs->currentIndex() == SECURITIES_PAGE_INDEX) { if(securitiesView->topLevelItemCount() == 0) { QMessageBox::critical(this, tr("Error"), tr("Empty securities list.", "Financial security (e.g. stock, mutual fund)")); return; } } else if(tabs->currentIndex() == SCHEDULE_PAGE_INDEX) { if(scheduleView->topLevelItemCount() == 0) { QMessageBox::critical(this, tr("Error"), tr("Empty schedule list.")); return; } } QPrintPreviewDialog preview_dialog(this, Qt::Window | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint); connect(&preview_dialog, SIGNAL(paintRequested(QPrinter*)), this, SLOT(printPreviewPaint(QPrinter*))); preview_dialog.exec(); } void Eqonomize::printView() { if(tabs->currentIndex() == EXPENSES_PAGE_INDEX) { if(expensesWidget->isEmpty()) { QMessageBox::critical(this, tr("Error"), tr("Empty expenses list.")); return; } } else if(tabs->currentIndex() == INCOMES_PAGE_INDEX) { if(incomesWidget->isEmpty()) { QMessageBox::critical(this, tr("Error"), tr("Empty incomes list.")); return; } } else if(tabs->currentIndex() == TRANSFERS_PAGE_INDEX) { if(transfersWidget->isEmpty()) { QMessageBox::critical(this, tr("Error"), tr("Empty transfers list.")); return; } } else if(tabs->currentIndex() == SECURITIES_PAGE_INDEX) { if(securitiesView->topLevelItemCount() == 0) { QMessageBox::critical(this, tr("Error"), tr("Empty securities list.", "Financial security (e.g. stock, mutual fund)")); return; } } else if(tabs->currentIndex() == SCHEDULE_PAGE_INDEX) { if(scheduleView->topLevelItemCount() == 0) { QMessageBox::critical(this, tr("Error"), tr("Empty schedule list.")); return; } } QPrinter printer; QPrintDialog print_dialog(&printer, this); if(print_dialog.exec() == QDialog::Accepted) { QString str; QTextStream stream(&str, QIODevice::WriteOnly); saveView(stream, 'h'); QTextDocument htmldoc; htmldoc.setHtml(str); htmldoc.print(&printer); } } bool Eqonomize::saveView(QTextStream &file, int fileformat) { if(tabs->currentIndex() == ACCOUNTS_PAGE_INDEX) {return exportAccountsList(file, fileformat);} else if(tabs->currentIndex() == EXPENSES_PAGE_INDEX) {return expensesWidget->exportList(file, fileformat);} else if(tabs->currentIndex() == INCOMES_PAGE_INDEX) {return incomesWidget->exportList(file, fileformat);} else if(tabs->currentIndex() == TRANSFERS_PAGE_INDEX) {return transfersWidget->exportList(file, fileformat);} else if(tabs->currentIndex() == SECURITIES_PAGE_INDEX) {return exportSecuritiesList(file, fileformat);} else if(tabs->currentIndex() == SCHEDULE_PAGE_INDEX) {return exportScheduleList(file, fileformat);} return false; } void Eqonomize::onFilterSelected(QString filter) { QMimeDatabase db; QFileDialog *fileDialog = qobject_cast(sender()); if(filter == db.mimeTypeForName("text/csv").filterString()) { fileDialog->setDefaultSuffix(db.mimeTypeForName("text/csv").preferredSuffix()); } else { fileDialog->setDefaultSuffix(db.mimeTypeForName("text/html").preferredSuffix()); } } void Eqonomize::saveView() { if(tabs->currentIndex() == EXPENSES_PAGE_INDEX) { if(expensesWidget->isEmpty()) { QMessageBox::critical(this, tr("Error"), tr("Empty expenses list.")); return; } } else if(tabs->currentIndex() == INCOMES_PAGE_INDEX) { if(incomesWidget->isEmpty()) { QMessageBox::critical(this, tr("Error"), tr("Empty incomes list.")); return; } } else if(tabs->currentIndex() == TRANSFERS_PAGE_INDEX) { if(transfersWidget->isEmpty()) { QMessageBox::critical(this, tr("Error"), tr("Empty transfers list.")); return; } } else if(tabs->currentIndex() == SECURITIES_PAGE_INDEX) { if(securitiesView->topLevelItemCount() == 0) { QMessageBox::critical(this, tr("Error"), tr("Empty securities list.", "Financial security (e.g. stock, mutual fund)")); return; } } else if(tabs->currentIndex() == SCHEDULE_PAGE_INDEX) { if(scheduleView->topLevelItemCount() == 0) { QMessageBox::critical(this, tr("Error"), tr("Empty schedule list.")); return; } } char filetype = 'h'; QMimeDatabase db; QString html_filter = db.mimeTypeForName("text/html").filterString(); QString csv_filter = db.mimeTypeForName("text/csv").filterString(); QFileDialog fileDialog(this); fileDialog.setNameFilters(QStringList(html_filter) << csv_filter); fileDialog.selectNameFilter(html_filter); fileDialog.setDefaultSuffix(db.mimeTypeForName("text/html").preferredSuffix()); fileDialog.setAcceptMode(QFileDialog::AcceptSave); #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) fileDialog.setSupportedSchemes(QStringList("file")); #endif fileDialog.setDirectory(last_document_directory); connect(&fileDialog, SIGNAL(filterSelected(QString)), this, SLOT(onFilterSelected(QString))); QString url; if(!fileDialog.exec()) return; QStringList urls = fileDialog.selectedFiles(); if(urls.isEmpty()) return; url = urls[0]; if((fileDialog.selectedNameFilter() == csv_filter || db.mimeTypeForFile(url, QMimeDatabase::MatchExtension) == db.mimeTypeForName("text/csv")) && db.mimeTypeForFile(url, QMimeDatabase::MatchExtension) != db.mimeTypeForName("text/html")) filetype = 'c'; QSaveFile ofile(url); ofile.open(QIODevice::WriteOnly); if(!ofile.isOpen()) { ofile.cancelWriting(); QMessageBox::critical(this, tr("Error"), tr("Couldn't open file for writing.")); return; } last_document_directory = fileDialog.directory().absolutePath(); QTextStream stream(&ofile); saveView(stream, filetype); if(!ofile.commit()) { QMessageBox::critical(this, tr("Error"), tr("Error while writing file; file was not saved.")); return; } } #define NEW_ACTION(action, text, icon, shortcut, receiver, slot, name, menu) action = new QAction(this); action->setObjectName(name); action->setText(text); action->setIcon(LOAD_ICON(icon)); action->setShortcut(shortcut); menu->addAction(action); connect(action, SIGNAL(triggered()), receiver, slot); #define NEW_ACTION_ALT(action, text, icon, icon_alt, shortcut, receiver, slot, name, menu) action = new QAction(this); action->setObjectName(name); action->setText(text); action->setIcon(LOAD_ICON2(icon, icon_alt)); action->setShortcut(shortcut); menu->addAction(action); connect(action, SIGNAL(triggered()), receiver, slot); #define NEW_ACTION_3(action, text, icon, shortcuts, receiver, slot, name, menu) action = new QAction(this); action->setObjectName(name); action->setText(text); action->setIcon(LOAD_ICON(icon)); action->setShortcuts(shortcuts); menu->addAction(action); connect(action, SIGNAL(triggered()), receiver, slot); #define NEW_ACTION_NOMENU(action, text, icon, shortcut, receiver, slot, name) action = new QAction(this); action->setObjectName(name); action->setText(text); action->setIcon(LOAD_ICON(icon)); action->setShortcut(shortcut); connect(action, SIGNAL(triggered()), receiver, slot); #define NEW_ACTION_NOMENU_NOICON(action, text, shortcut, receiver, slot, name) action = new QAction(this); action->setObjectName(name); action->setText(text); action->setShortcut(shortcut); connect(action, SIGNAL(triggered()), receiver, slot); #define NEW_ACTION_NOMENU_ALT(action, text, icon, icon_alt, shortcut, receiver, slot, name) action = new QAction(this); action->setObjectName(name); action->setText(text); action->setIcon(LOAD_ICON2(icon, icon_alt)); action->setShortcut(shortcut); connect(action, SIGNAL(triggered()), receiver, slot); #define NEW_ACTION_2(action, text, shortcut, receiver, slot, name, menu) action = new QAction(this); action->setObjectName(name); action->setText(text); action->setShortcut(shortcut); menu->addAction(action); connect(action, SIGNAL(triggered()), receiver, slot); #define NEW_ACTION_2_NOMENU(action, text, shortcut, receiver, slot, name) action = new QAction(this); action->setObjectName(name); action->setText(text); action->setShortcut(shortcut); connect(action, SIGNAL(triggered()), receiver, slot); #define NEW_TOGGLE_ACTION(action, text, shortcut, receiver, slot, name, menu) action = new QAction(this); action->setObjectName(name); action->setText(text); action->setShortcut(shortcut); action->setCheckable(true); menu->addAction(action); connect(action, SIGNAL(triggered(bool)), receiver, slot); #define NEW_RADIO_ACTION(action, text, group) action = new QAction(group); action->setCheckable(true); action->setText(text); void Eqonomize::setupActions() { QMenu *fileMenu = menuBar()->addMenu(tr("&File")); QMenu *accountsMenu = menuBar()->addMenu(tr("&Accounts")); QMenu *transactionsMenu = new QMenu(menuBar()); transactionsMenu->setTitle(tr("&Transactions")); menuBar()->addMenu(transactionsMenu); QMenu *loansMenu = menuBar()->addMenu(tr("&Loans")); QMenu *securitiesMenu = menuBar()->addMenu(tr("&Securities", "Financial security (e.g. stock, mutual fund)")); QMenu *statisticsMenu = menuBar()->addMenu(tr("Stat&istics")); QMenu *settingsMenu = menuBar()->addMenu(tr("S&ettings")); QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); fileToolbar = addToolBar(tr("File")); fileToolbar->setObjectName("file_toolbar"); fileToolbar->setFloatable(false); fileToolbar->setMovable(false); accountsToolbar = addToolBar(tr("Accounts")); accountsToolbar->setObjectName("account_toolbar"); accountsToolbar->setFloatable(false); accountsToolbar->setMovable(false); transactionsToolbar = addToolBar(tr("Transactions")); transactionsToolbar->setObjectName("transaction_toolbar"); transactionsToolbar->setFloatable(false); transactionsToolbar->setMovable(false); statisticsToolbar = addToolBar(tr("Statistics")); statisticsToolbar->setObjectName("statistics_toolbar"); statisticsToolbar->setFloatable(false); statisticsToolbar->setMovable(false); linkToolbar = addToolBar("Link"); linkToolbar->setObjectName("link_toolbar"); linkToolbar->setFloatable(false); linkToolbar->setMovable(false); linkToolbar->setIconSize(QSize(16, 16)); linkToolbar->hide(); new QShortcut(QKeySequence::Find, this, SLOT(showFilter())); NEW_ACTION_3(ActionFileNew, tr("&New"), "document-new", QKeySequence::New, this, SLOT(fileNew()), "file_new", fileMenu); fileToolbar->addAction(ActionFileNew); NEW_ACTION_3(ActionFileOpen, tr("&Open…"), "document-open", QKeySequence::Open, this, SLOT(fileOpen()), "file_open", fileMenu); fileToolbar->addAction(ActionFileOpen); recentFilesMenu = fileMenu->addMenu(LOAD_ICON("document-open-recent"), tr("Open Recent")); QAction* recentFileAction = 0; for(int i = 0; i < MAX_RECENT_FILES; i++){ recentFileAction = new QAction(this); recentFileAction->setVisible(false); QObject::connect(recentFileAction, SIGNAL(triggered()), this, SLOT(openRecent())); recentFilesMenu->addAction(recentFileAction); recentFileActionList.append(recentFileAction); } recentFilesMenu->addSeparator(); NEW_ACTION_2(ActionClearRecentFiles, tr("Clear List"), 0, this, SLOT(clearRecentFiles()), "clear_recent_files", recentFilesMenu); fileMenu->addSeparator(); NEW_ACTION_3(ActionFileSave, tr("&Save"), "document-save", QKeySequence::Save, this, SLOT(fileSave()), "file_save", fileMenu); fileToolbar->addAction(ActionFileSave); NEW_ACTION_3(ActionFileSaveAs, tr("Save As…"), "document-save-as", QKeySequence::SaveAs, this, SLOT(fileSaveAs()), "file_save_as", fileMenu); NEW_ACTION(ActionFileReload, tr("&Revert"), "document-revert", 0, this, SLOT(fileReload()), "file_revert", fileMenu); NEW_ACTION(ActionFileSync, tr("S&ynchronize"), "view-refresh", 0, this, SLOT(fileSynchronize()), "file_synchronize", fileMenu); fileMenu->addSeparator(); NEW_ACTION_3(ActionPrintView, tr("&Print…"), "document-print", QKeySequence::Print, this, SLOT(printView()), "print_view", fileMenu); NEW_ACTION(ActionPrintPreview, tr("Print Preview…"), "document-print-preview", 0, this, SLOT(showPrintPreview()), "print_preview", fileMenu); fileToolbar->addAction(ActionPrintPreview); fileMenu->addSeparator(); QMenu *importMenu = fileMenu->addMenu(LOAD_ICON2("document-import", "eqz-import"), tr("Import")); NEW_ACTION_ALT(ActionImportEQZ, tr("Import %1 File…").arg(qApp->applicationDisplayName()), "document-import", "eqz-import", 0, this, SLOT(importEQZ()), "import_eqz", importMenu); NEW_ACTION_ALT(ActionImportCSV, tr("Import CSV File…"), "document-import", "eqz-import", 0, this, SLOT(importCSV()), "import_csv", importMenu); NEW_ACTION_ALT(ActionImportQIF, tr("Import QIF File…"), "document-import", "eqz-import", 0, this, SLOT(importQIF()), "import_qif", importMenu); NEW_ACTION_ALT(ActionSaveView, tr("Export View…"), "document-export", "eqz-export", 0, this, SLOT(saveView()), "save_view", fileMenu); fileToolbar->addAction(ActionSaveView); NEW_ACTION_ALT(ActionExportQIF, tr("Export As QIF File…"), "document-export", "eqz-export", 0, this, SLOT(exportQIF()), "export_qif", fileMenu); fileMenu->addSeparator(); NEW_ACTION(ActionConvertCurrencies, tr("Currency Converter"), "eqz-currency", 0, this, SLOT(openCurrencyConversion()), "convert_currencies", fileMenu); NEW_ACTION(ActionUpdateExchangeRates, tr("Update Exchange Rates"), "view-refresh", 0, this, SLOT(updateExchangeRates()), "update_exchange_rates", fileMenu); fileMenu->addSeparator(); QList keySequences; keySequences << QKeySequence(QKeySequence::Quit); if(keySequences.last() != QKeySequence(Qt::CTRL | Qt::Key_Q)) keySequences << QKeySequence(Qt::CTRL | Qt::Key_Q); NEW_ACTION_3(ActionQuit, tr("&Quit"), "application-exit", keySequences, this, SLOT(close()), "application_quit", fileMenu); NEW_ACTION_NOMENU(ActionAddAccount, tr("Add Account…"), "document-new", 0, this, SLOT(addAccount()), "add_account"); NEW_ACTION(ActionNewAssetsAccount, tr("New Account…"), "eqz-account", 0, this, SLOT(newAssetsAccount()), "new_assets_account", accountsMenu); NEW_ACTION(ActionNewLoan, tr("New Loan…"), "eqz-liabilities", 0, this, SLOT(newLoan()), "new_loan", loansMenu); NEW_ACTION(ActionNewIncomesAccount, tr("New Income Category…"), "eqz-income", 0, this, SLOT(newIncomesAccount()), "new_incomes_account", accountsMenu); NEW_ACTION(ActionNewExpensesAccount, tr("New Expense Category…"), "eqz-expense", 0, this, SLOT(newExpensesAccount()), "new_expenses_account", accountsMenu); NEW_ACTION_NOMENU(ActionAddAccountMenu, tr("Add Account…"), "eqz-account", 0, this, SLOT(addAccount()), "add_account"); QMenu *newAccountMenu = new QMenu(tr("Add Account"), this); newAccountMenu->setIcon(LOAD_ICON("eqz-account")); newAccountMenu->addAction(ActionNewAssetsAccount); newAccountMenu->addAction(ActionNewLoan); newAccountMenu->addAction(ActionNewIncomesAccount); newAccountMenu->addAction(ActionNewExpensesAccount); ActionAddAccountMenu->setMenu(newAccountMenu); accountsToolbar->addAction(ActionAddAccountMenu); accountsMenu->addSeparator(); NEW_ACTION_ALT(ActionEditAccount, tr("Edit…"), "document-edit", "eqz-edit", 0, this, SLOT(editAccount()), "edit_account", accountsMenu); NEW_ACTION(ActionReconcileAccount, tr("Reconcile Account…"), "eqz-ledger", 0, this, SLOT(reconcileAccount()), "reconcile_account", accountsMenu); NEW_ACTION(ActionBalanceAccount, tr("Adjust balance…", "Referring to account balance"), "eqz-balance", 0, this, SLOT(balanceAccount()), "balance_account", accountsMenu); accountsMenu->addSeparator(); NEW_ACTION(ActionCloseAccount, tr("Close Account", "Mark account as closed"), "edit-delete", 0, this, SLOT(closeAccount()), "close_account", accountsMenu); NEW_ACTION(ActionDeleteAccount, tr("Remove"), "edit-delete", 0, this, SLOT(deleteAccount()), "delete_account", accountsMenu); accountsMenu->addSeparator(); NEW_ACTION(ActionShowAccountTransactions, tr("Show Transactions"), "eqz-transactions", 0, this, SLOT(showAccountTransactions()), "show_account_transactions", accountsMenu); NEW_ACTION(ActionShowLedger, tr("Show Ledger"), "eqz-ledger", 0, this, SLOT(showLedger()), "show_ledger", accountsMenu); accountsToolbar->addAction(ActionShowLedger); NEW_ACTION(ActionNewExpense, tr("New Expense…"), "eqz-expense", Qt::CTRL | Qt::Key_E, this, SLOT(newScheduledExpense()), "new_expense", transactionsMenu); transactionsToolbar->addAction(ActionNewExpense); NEW_ACTION(ActionNewIncome, tr("New Income…"), "eqz-income", Qt::CTRL | Qt::Key_I, this, SLOT(newScheduledIncome()), "new_income", transactionsMenu); transactionsToolbar->addAction(ActionNewIncome); NEW_ACTION(ActionNewTransfer, tr("New Transfer…"), "eqz-transfer", Qt::CTRL | Qt::Key_T, this, SLOT(newScheduledTransfer()), "new_transfer", transactionsMenu); transactionsToolbar->addAction(ActionNewTransfer); NEW_ACTION(ActionNewMultiItemTransaction, tr("New Split Transaction…"), "eqz-split-transaction", Qt::CTRL | Qt::Key_W, this, SLOT(newMultiItemTransaction()), "new_multi_item_transaction", transactionsMenu); transactionsToolbar->addAction(ActionNewMultiItemTransaction); NEW_ACTION(ActionNewMultiAccountExpense, tr("New Expense with Multiple Payments…"), "eqz-expense", 0, this, SLOT(newMultiAccountExpense()), "new_multi_account_expense", transactionsMenu); NEW_ACTION_NOMENU(ActionNewRefund, tr("Refund…"), "eqz-income", 0, this, SLOT(newRefund()), "new_refund"); NEW_ACTION_NOMENU(ActionNewRepayment, tr("Repayment…"), "eqz-expense", 0, this, SLOT(newRepayment()), "new_repayment"); NEW_ACTION(ActionNewRefundRepayment, tr("New Refund/Repayment…"), "eqz-refund-repayment", 0, this, SLOT(newRefundRepayment()), "new_refund_repayment", transactionsMenu); transactionsMenu->addSeparator(); NEW_ACTION(ActionCloneTransaction, tr("Duplicate Transaction…", "duplicate as verb"), "edit-copy", 0, this, SLOT(cloneSelectedTransaction()), "clone_transaction", transactionsMenu); transactionsMenu->addSeparator(); NEW_ACTION_ALT(ActionEditTransaction, tr("Edit Transaction(s) (Occurrence)…"), "document-edit", "eqz-edit", 0, this, SLOT(editSelectedTransaction()), "edit_transaction", transactionsMenu); NEW_ACTION_NOMENU_ALT(ActionEditOccurrence, tr("Edit Occurrence…"), "document-edit", "eqz-edit", 0, this, SLOT(editOccurrence()), "edit_occurrence"); NEW_ACTION_ALT(ActionEditScheduledTransaction, tr("Edit Schedule (Recurrence)…"), "document-edit", "eqz-edit", 0, this, SLOT(editSelectedScheduledTransaction()), "edit_scheduled_transaction", transactionsMenu); NEW_ACTION_NOMENU_ALT(ActionEditSchedule, tr("Edit Schedule…"), "document-edit", "eqz-edit", 0, this, SLOT(editScheduledTransaction()), "edit_schedule"); NEW_ACTION_ALT(ActionEditSplitTransaction, tr("Edit Split Transaction…"), "document-edit", "eqz-edit", 0, this, SLOT(editSelectedSplitTransaction()), "edit_split_transaction", transactionsMenu); //: join transactions together NEW_ACTION(ActionJoinTransactions, tr("Join Transactions…"), "eqz-join-transactions", 0, this, SLOT(joinSelectedTransactions()), "join_transactions", transactionsMenu); //: split up joined transactions NEW_ACTION(ActionSplitUpTransaction, tr("Split Up Transaction"), "eqz-split-transaction", 0, this, SLOT(splitUpSelectedTransaction()), "split_up_transaction", transactionsMenu); transactionsMenu->addSeparator(); tagMenu = new TagMenu(budget, this, true); connect(tagMenu, SIGNAL(selectedTagsChanged()), this, SLOT(tagsChanged())); connect(tagMenu, SIGNAL(newTagRequested()), this, SLOT(newTag())); ActionTags = transactionsMenu->addMenu(tagMenu); ActionTags->setIcon(LOAD_ICON2("tag", "eqz-tag")); ActionTags->setText(tr("Tags")); linkMenu = new QMenu(this); ActionLinks = transactionsMenu->addMenu(linkMenu); ActionLinks->setIcon(LOAD_ICON("go-jump")); ActionLinks->setText(tr("Links")); //: create link to or between transaction(s) NEW_ACTION(ActionCreateLink, tr("Create Link"), "go-jump", 0, this, SLOT(createLink()), "create_link", transactionsMenu); NEW_ACTION_NOMENU_NOICON(ActionLinkTo, "", 0, this, SLOT(linkTo()), "link_to"); linkToolbar->addAction(ActionLinkTo); NEW_ACTION_NOMENU(ActionCancelLinkTo, "", "edit-clear", 0, this, SLOT(cancelLinkTo()), "cancel_link_to"); linkToolbar->addAction(ActionCancelLinkTo); NEW_ACTION(ActionSelectAssociatedFile, tr("Select Associated File"), "document-open", 0, this, SLOT(selectAssociatedFile()), "select_attachment", transactionsMenu); NEW_ACTION(ActionOpenAssociatedFile, tr("Open Associated File"), "system-run", 0, this, SLOT(openAssociatedFile()), "open_attachment", transactionsMenu); NEW_ACTION(ActionEditTimestamp, tr("Edit Timestamp…"), "eqz-schedule", 0, this, SLOT(editSelectedTimestamp()), "edit_timestamp", transactionsMenu); transactionsMenu->addSeparator(); NEW_ACTION(ActionDeleteTransaction, tr("Remove Transaction(s) (Occurrence)"), "edit-delete", 0, this, SLOT(deleteSelectedTransaction()), "delete_transaction", transactionsMenu); NEW_ACTION_NOMENU(ActionDeleteOccurrence, tr("Remove Occurrence"), "edit-delete", 0, this, SLOT(removeOccurrence()), "delete_occurrence"); NEW_ACTION(ActionDeleteScheduledTransaction, tr("Delete Schedule (Recurrence)"), "edit-delete", 0, this, SLOT(deleteSelectedScheduledTransaction()), "delete_scheduled_transaction", transactionsMenu); NEW_ACTION_NOMENU(ActionDeleteSchedule, tr("Delete Schedule"), "edit-delete", 0, this, SLOT(removeScheduledTransaction()), "delete_schedule"); NEW_ACTION(ActionDeleteSplitTransaction, tr("Remove Split Transaction"), "edit-delete", 0, this, SLOT(deleteSelectedSplitTransaction()), "delete_split_transaction", transactionsMenu); loansMenu->addSeparator(); NEW_ACTION(ActionNewDebtPayment, tr("New Debt Payment…"), "eqz-debt-payment", 0, this, SLOT(newDebtPayment()), "new_loan_transaction", loansMenu); NEW_ACTION(ActionNewDebtInterest, tr("New Unpaid Interest…"), "eqz-debt-interest", 0, this, SLOT(newDebtInterest()), "new_debt_interest", loansMenu); NEW_ACTION(ActionNewExpenseWithLoan, tr("New Expense Paid with Loan…"), "eqz-expense", 0, this, SLOT(newExpenseWithLoan()), "new_expense_with_loan", loansMenu); transactionsToolbar->addAction(ActionNewDebtPayment); NEW_ACTION(ActionNewSecurity, tr("New Security…", "Financial security (e.g. stock, mutual fund)"), "document-new", 0, this, SLOT(newSecurity()), "new_security", securitiesMenu); NEW_ACTION_ALT(ActionEditSecurity, tr("Edit Security…", "Financial security (e.g. stock, mutual fund)"), "document-edit", "eqz-edit", 0, this, SLOT(editSecurity()), "edit_security", securitiesMenu); NEW_ACTION(ActionDeleteSecurity, tr("Remove Security", "Financial security (e.g. stock, mutual fund)"), "edit-delete", 0, this, SLOT(deleteSecurity()), "delete_security", securitiesMenu); securitiesMenu->addSeparator(); NEW_ACTION(ActionBuyShares, tr("Shares Bought…", "Financial shares"), "eqz-income", 0, this, SLOT(buySecurities()), "buy_shares", securitiesMenu); NEW_ACTION(ActionSellShares, tr("Shares Sold…", "Financial shares"), "eqz-expense", 0, this, SLOT(sellSecurities()), "sell_shares", securitiesMenu); NEW_ACTION(ActionNewSecurityTrade, tr("Shares Exchanged…", "Shares of one security directly exchanged for shares of another; Financial shares"), "eqz-transfer", 0, this, SLOT(newSecurityTrade()), "new_security_trade", securitiesMenu); ActionNewSecurityTrade->setToolTip(tr("Shares of one security directly exchanged for shares of another", "Financial shares")); NEW_ACTION(ActionNewDividend, tr("Dividend…"), "eqz-income", 0, this, SLOT(newDividend()), "new_dividend", securitiesMenu); NEW_ACTION(ActionNewReinvestedDividend, tr("Reinvested Dividend…"), "eqz-income", 0, this, SLOT(newReinvestedDividend()), "new_reinvested_dividend", securitiesMenu); securitiesMenu->addSeparator(); NEW_ACTION(ActionEditSecurityTransactions, tr("Transactions…"), "eqz-transactions", 0, this, SLOT(editSecurityTransactions()), "edit_security_transactions", securitiesMenu); securitiesMenu->addSeparator(); NEW_ACTION(ActionSetQuotation, tr("Set Quote…", "Financial quote"), "view-calendar-day", 0, this, SLOT(setQuotation()), "set_quotation", securitiesMenu); NEW_ACTION_ALT(ActionEditQuotations, tr("Edit Quotes…", "Financial quote"), "view-calendar-list", "eqz-edit", 0, this, SLOT(editQuotations()), "edit_quotations", securitiesMenu); NEW_ACTION(ActionOverTimeReport, tr("Development Over Time Report…"), "eqz-overtime-report", 0, this, SLOT(showOverTimeReport()), "over_time_report", statisticsMenu); statisticsToolbar->addAction(ActionOverTimeReport); NEW_ACTION(ActionCategoriesComparisonReport, tr("Categories Comparison Report…"), "eqz-categories-report", 0, this, SLOT(showCategoriesComparisonReport()), "categories_comparison_report", statisticsMenu); statisticsToolbar->addAction(ActionCategoriesComparisonReport); statisticsMenu->addSeparator(); NEW_ACTION(ActionOverTimeChart, tr("Development Over Time Chart…"), "eqz-overtime-chart", 0, this, SLOT(showOverTimeChart()), "over_time_chart", statisticsMenu); statisticsToolbar->addAction(ActionOverTimeChart); NEW_ACTION(ActionCategoriesComparisonChart, tr("Categories Comparison Chart…"), "eqz-categories-chart", 0, this, SLOT(showCategoriesComparisonChart()), "categories_comparison_chart", statisticsMenu); statisticsToolbar->addAction(ActionCategoriesComparisonChart); NEW_ACTION(ActionSetMainCurrency, tr("Set Main Currency…"), "eqz-currency", 0, this, SLOT(setMainCurrency()), "set_main_currency", settingsMenu); NEW_TOGGLE_ACTION(ActionUseExchangeRateForTransactionDate, tr("Use Exchange Rate for Transaction Date"), 0, this, SLOT(useExchangeRateForTransactionDate(bool)), "use_exchange_rate_for_transaction_date", settingsMenu); #ifndef RESOURCES_COMPILED ActionUseExchangeRateForTransactionDate->setIcon(LOAD_ICON("eqz-currency")); #endif ActionUseExchangeRateForTransactionDate->setChecked(budget->defaultTransactionConversionRateDate() == TRANSACTION_CONVERSION_RATE_AT_DATE); ActionUseExchangeRateForTransactionDate->setToolTip(tr("Use the exchange rate nearest the transaction date, instead of the latest available rate, when converting the value of transactions.")); NEW_TOGGLE_ACTION(ActionExtraProperties, tr("Show payee and quantity"), 0, this, SLOT(useExtraProperties(bool)), "extra_properties", settingsMenu); #ifndef RESOURCES_COMPILED ActionExtraProperties->setIcon(LOAD_ICON("eqz-expense")); #endif ActionExtraProperties->setChecked(b_extra); ActionExtraProperties->setToolTip(tr("Show quantity and payer/payee properties for incomes and expenses.")); settingsMenu->addSeparator(); NEW_ACTION(ActionSetScheduleConfirmationTime, tr("Set Schedule Confirmation Time…"), "eqz-schedule", 0, this, SLOT(setScheduleConfirmationTime()), "set_schedule_confirmation_time", settingsMenu); NEW_ACTION(ActionSetBudgetPeriod, tr("Set Budget Period…"), "view-calendar-day", 0, this, SLOT(setBudgetPeriod()), "set_budget_period", settingsMenu); QMenu *periodMenu = settingsMenu->addMenu(LOAD_ICON("view-calendar-day"), tr("Initial Period")); ActionSelectInitialPeriod = new QActionGroup(this); ActionSelectInitialPeriod->setObjectName("select_initial_period"); NEW_RADIO_ACTION(AIPCurrentMonth, tr("Current Month"), ActionSelectInitialPeriod); NEW_RADIO_ACTION(AIPCurrentYear, tr("Current Year"), ActionSelectInitialPeriod); NEW_RADIO_ACTION(AIPCurrentWholeMonth, tr("Current Whole Month"), ActionSelectInitialPeriod); NEW_RADIO_ACTION(AIPCurrentWholeYear, tr("Current Whole Year"), ActionSelectInitialPeriod); NEW_RADIO_ACTION(AIPRememberLastDates, tr("Remember Last Dates"), ActionSelectInitialPeriod); periodMenu->addActions(ActionSelectInitialPeriod->actions()); settingsMenu->addSeparator(); QMenu *backupMenu = settingsMenu->addMenu(LOAD_ICON("document-save"), tr("Backup Frequency")); ActionSelectBackupFrequency = new QActionGroup(this); ActionSelectBackupFrequency->setObjectName("select_backup_frequency"); NEW_RADIO_ACTION(ABFDaily, tr("Daily"), ActionSelectBackupFrequency); NEW_RADIO_ACTION(ABFWeekly, tr("Weekly"), ActionSelectBackupFrequency); NEW_RADIO_ACTION(ABFFortnightly, tr("Fortnightly"), ActionSelectBackupFrequency); NEW_RADIO_ACTION(ABFMonthly, tr("Monthly"), ActionSelectBackupFrequency); NEW_RADIO_ACTION(ABFNever, tr("Never"), ActionSelectBackupFrequency); backupMenu->addActions(ActionSelectBackupFrequency->actions()); NEW_ACTION(ActionSyncSettings, tr("Cloud Synchronization (experimental)…"), "view-refresh", 0, this, SLOT(openSynchronizationSettings()), "open_synchronization_settings", settingsMenu); settingsMenu->addSeparator(); NEW_ACTION_2(ActionSelectFont, tr("Select Font…"), 0, this, SLOT(selectFont()), "select_font", settingsMenu); ActionSelectFont->setIcon(LOAD_ICON_APP("preferences-desktop-font")); NEW_TOGGLE_ACTION(ActionDarkMode, tr("Dark Mode"), 0, this, SLOT(setDarkMode(bool)), "dark_mode", settingsMenu); QSettings settings; ActionDarkMode->setChecked(settings.value("GeneralOptions/darkMode", false).toBool()); QMenu *langMenu = settingsMenu->addMenu(LOAD_ICON_APP("preferences-desktop-locale"), tr("Language")); ActionSelectLang = new QActionGroup(this); ActionSelectLang->setObjectName("select_language"); QAction *action_lang; NEW_RADIO_ACTION(action_lang, tr("Default"), ActionSelectLang); action_lang->setData(QString("")); connect(action_lang, SIGNAL(triggered()), this, SLOT(languageSelected())); NEW_RADIO_ACTION(action_lang, "English", ActionSelectLang); action_lang->setData(QString("en")); connect(action_lang, SIGNAL(triggered()), this, SLOT(languageSelected())); QDir langdir(TRANSLATIONS_DIR); QStringList langfiles = langdir.entryList(QDir::Files, QDir::Name); for(int i = 0; i < langfiles.size(); i++) { if(langfiles[i].endsWith(".qm") && langfiles[i].startsWith("eqonomize_")) { QString slang = langfiles[i].mid(10, langfiles[i].length() - 13); if(slang == "bg") { NEW_RADIO_ACTION(action_lang, "Български", ActionSelectLang); } else if(slang == "cs") { NEW_RADIO_ACTION(action_lang, "Čeština", ActionSelectLang); } else if(slang == "da") { NEW_RADIO_ACTION(action_lang, "Dansk", ActionSelectLang); } else if(slang == "de") { NEW_RADIO_ACTION(action_lang, "Deutsch", ActionSelectLang); } else if(slang == "es") { NEW_RADIO_ACTION(action_lang, "Español", ActionSelectLang); } else if(slang == "fr") { NEW_RADIO_ACTION(action_lang, "Français", ActionSelectLang); } else if(slang == "hu") { NEW_RADIO_ACTION(action_lang, "Magyar nyelv", ActionSelectLang); } else if(slang == "it") { NEW_RADIO_ACTION(action_lang, "Italiano", ActionSelectLang); } else if(slang == "nl") { NEW_RADIO_ACTION(action_lang, "Nederlands", ActionSelectLang); } else if(slang == "pt") { NEW_RADIO_ACTION(action_lang, "Português", ActionSelectLang); } else if(slang == "pt_BR") { NEW_RADIO_ACTION(action_lang, "Português do Brasil", ActionSelectLang); } else if(slang == "ro") { NEW_RADIO_ACTION(action_lang, "Românește", ActionSelectLang); } else if(slang == "ru") { NEW_RADIO_ACTION(action_lang, "Русский", ActionSelectLang); } else if(slang == "sk") { NEW_RADIO_ACTION(action_lang, "Slovenčina", ActionSelectLang); } else if(slang == "sv") { NEW_RADIO_ACTION(action_lang, "Svenska", ActionSelectLang); } else { NEW_RADIO_ACTION(action_lang, slang, ActionSelectLang); } action_lang->setData(slang); connect(action_lang, SIGNAL(triggered()), this, SLOT(languageSelected())); } } langMenu->addActions(ActionSelectLang->actions()); NEW_ACTION_3(ActionHelp, tr("Help"), "help-contents", QKeySequence::HelpContents, this, SLOT(showHelp()), "help", helpMenu); //ActionWhatsThis = QWhatsThis::createAction(this); helpMenu->addAction(ActionWhatsThis); helpMenu->addSeparator(); NEW_ACTION(ActionReportBug, tr("Report Bug"), "tools-report-bug", 0, this, SLOT(reportBug()), "report-bug", helpMenu); helpMenu->addSeparator(); NEW_ACTION(ActionAbout, tr("About %1").arg(qApp->applicationDisplayName()), "", 0, this, SLOT(showAbout()), "about", helpMenu); ActionAbout->setIcon(LOAD_APP_ICON("eqonomize")); NEW_ACTION(ActionAboutQt, tr("About Qt"), "help-about", 0, this, SLOT(showAboutQt()), "about-qt", helpMenu); NEW_ACTION_NOMENU(ActionNewTag, tr("New Tag…"), "document-new", 0, this, SLOT(newTag()), "new-tag"); NEW_ACTION_NOMENU_ALT(ActionRenameTag, tr("Rename Tag…"), "document-edit", "eqz-edit", 0, this, SLOT(renameTag()), "rename-tag"); NEW_ACTION_NOMENU(ActionRemoveTag, tr("Remove Tag"), "edit-delete", 0, this, SLOT(deleteTag()), "remove-tag"); //ActionFileSave->setEnabled(false); ActionFileReload->setEnabled(false); ActionBalanceAccount->setEnabled(false); ActionEditAccount->setEnabled(false); ActionDeleteAccount->setEnabled(false); ActionCloseAccount->setEnabled(false); ActionShowAccountTransactions->setEnabled(false); ActionReconcileAccount->setEnabled(false); ActionEditTransaction->setEnabled(false); ActionDeleteTransaction->setEnabled(false); ActionEditSplitTransaction->setEnabled(false); ActionDeleteSplitTransaction->setEnabled(false); ActionSelectAssociatedFile->setEnabled(false); ActionOpenAssociatedFile->setEnabled(false); ActionCloneTransaction->setEnabled(false); ActionJoinTransactions->setEnabled(false); ActionSplitUpTransaction->setEnabled(false); ActionEditTimestamp->setEnabled(false); ActionTags->setEnabled(false); ActionEditScheduledTransaction->setEnabled(false); ActionDeleteScheduledTransaction->setEnabled(false); ActionNewRefund->setEnabled(false); ActionNewRepayment->setEnabled(false); ActionNewRefundRepayment->setEnabled(false); ActionEditSecurity->setEnabled(false); ActionDeleteSecurity->setEnabled(false); ActionSellShares->setEnabled(true); ActionBuyShares->setEnabled(true); ActionNewDividend->setEnabled(true); ActionNewReinvestedDividend->setEnabled(true); ActionNewSecurityTrade->setEnabled(true); ActionSetQuotation->setEnabled(false); ActionEditQuotations->setEnabled(false); ActionEditSecurityTransactions->setEnabled(false); ActionRenameTag->setEnabled(false); ActionRemoveTag->setEnabled(false); } void Eqonomize::openRecent(){ QAction *action = qobject_cast(sender()); if(action) fileOpenRecent(QUrl::fromLocalFile(action->data().toString())); } void Eqonomize::clearRecentFiles(){ QSettings settings; settings.beginGroup("GeneralOptions"); QStringList recentFilePaths; settings.setValue("recentFiles", recentFilePaths); for (int i = 0; i < MAX_RECENT_FILES; i++) { recentFileActionList.at(i)->setVisible(false); } recentFilesMenu->setEnabled(false); } void Eqonomize::updateRecentFiles(QString filePath){ QSettings settings; settings.beginGroup("GeneralOptions"); QStringList recentFilePaths = settings.value("recentFiles").toStringList(); if(!filePath.isEmpty()) { recentFilePaths.removeAll(filePath); recentFilePaths.prepend(filePath); while(recentFilePaths.size() > MAX_RECENT_FILES) recentFilePaths.removeLast(); settings.setValue("recentFiles", recentFilePaths); } for (int i = 0; i < recentFilePaths.size() && i < MAX_RECENT_FILES; i++) { recentFileActionList.at(i)->setText(QFileInfo(recentFilePaths.at(i)).fileName()); recentFileActionList.at(i)->setData(recentFilePaths.at(i)); recentFileActionList.at(i)->setVisible(true); } for (int i = recentFilePaths.size(); i < MAX_RECENT_FILES; i++) { recentFileActionList.at(i)->setVisible(false); } recentFilesMenu->setEnabled(recentFilePaths.size() > 0); } void Eqonomize::languageSelected() { QAction *lang_action = qobject_cast(sender()); QString slang = lang_action->data().toString(); QSettings settings; settings.beginGroup("GeneralOptions"); settings.setValue("language", slang); QMessageBox::information(this, tr("Restart required"), tr("Please restart the application for the language change to take effect.")); } void Eqonomize::showFilter() { TransactionListWidget *w = NULL; if(tabs->currentIndex() == EXPENSES_PAGE_INDEX) w = expensesWidget; else if(tabs->currentIndex() == INCOMES_PAGE_INDEX) w = incomesWidget; else if(tabs->currentIndex() == TRANSFERS_PAGE_INDEX) w = transfersWidget; if(!w) return; w->showFilter(true); } void Eqonomize::showHelp() { QLocale locale; QStringList langs = locale.uiLanguages(); QString docdir = DOCUMENTATION_DIR "/C"; for(int i = 0; i < langs.size(); ++i) { QString lang = langs.at(i); lang.replace('-', '_'); QFileInfo fileinfo(QString(DOCUMENTATION_DIR "/") + lang + "/index.html"); if(fileinfo.exists()) { docdir = QString(DOCUMENTATION_DIR "/") + lang; break;; } lang = lang.section('_', 0, 0); fileinfo.setFile(QString(DOCUMENTATION_DIR "/") + lang + "/index.html"); if(fileinfo.exists()) { docdir = QString(DOCUMENTATION_DIR "/") + lang; break; } } if(!helpDialog) { helpDialog = new QDialog(0, Qt::Window | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint); helpDialog->setModal(false); helpDialog->setWindowTitle(tr("Help")); QVBoxLayout *box1 = new QVBoxLayout(helpDialog); QTextBrowser *helpBrowser = new QTextBrowser(helpDialog); if(docdir[0] == ':') { helpBrowser->setSource(QUrl(QString("qrc") + docdir + "/index.html")); helpBrowser->setSearchPaths(QStringList(QString("qrc") + docdir)); } else { helpBrowser->setSearchPaths(QStringList(docdir)); helpBrowser->setSource(QUrl(docdir + "/index.html")); } box1->addWidget(helpBrowser); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); connect(buttonBox->button(QDialogButtonBox::Close), SIGNAL(clicked()), helpDialog, SLOT(reject())); box1->addWidget(buttonBox); #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) # if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) QScreen *scr = screen(); # else QScreen *scr = QGuiApplication::screenAt(pos); # endif if(!scr) scr = QGuiApplication::primaryScreen(); QRect rect = scr->availableGeometry(); #else QRect rect = QApplication::desktop()->availableGeometry(this); #endif QSize helpSize = rect.size(); helpSize.setHeight(helpSize.height() * 0.85); helpSize.setWidth(helpSize.height() * 1.2); helpDialog->resize(helpSize); } helpDialog->show(); helpDialog->raise(); helpDialog->activateWindow(); } void Eqonomize::reportBug() { QDesktopServices::openUrl(QUrl("https://github.com/Eqonomize/Eqonomize/issues/new")); } void Eqonomize::showAbout() { QMessageBox::about(this, tr("About %1").arg(qApp->applicationDisplayName()), QString("%1 v1.5.3
    %2
    <https://eqonomize.github.io/

    Copyright © 2006-2008, 2014, 2016-2021 Hanna Knutsson
    %3").arg(qApp->applicationDisplayName()).arg(tr("A personal accounting program")).arg(tr("License: GNU General Public License Version 3"))); } void Eqonomize::showAboutQt() { QMessageBox::aboutQt(this); } bool Eqonomize::crashRecovery(QUrl url) { QString autosaveFileName; #if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)) autosaveFileName = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/autosave/"; #else autosaveFileName = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/Eqonomize/eqonomize/autosave/"; #endif if(url.isEmpty()) autosaveFileName += "UNSAVED EQZ"; else autosaveFileName += url.fileName(); QFileInfo fileinfo(autosaveFileName); if(fileinfo.exists() && fileinfo.isWritable()) { if(QMessageBox::question(this, tr("Crash Recovery"), tr("%1 exited unexpectedly before the file was saved and data was lost.\nDo you want to load the last auto-saved version of the file?").arg(qApp->applicationDisplayName()), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { QString errors; bool new_currency = false; QString error = budget->loadFile(autosaveFileName, errors, &new_currency); if(!error.isNull()) { QMessageBox::critical(this, tr("Couldn't open file"), tr("Error loading %1: %2.").arg(autosaveFileName).arg(error)); QFile autosaveFile(autosaveFileName); autosaveFile.remove(); return false; } if(!errors.isEmpty()) { QMessageBox::critical(this, tr("Error"), errors); } current_url = url; ActionFileReload->setEnabled(true); setWindowTitle(current_url.fileName() + "[*]"); QFile autosaveFile(autosaveFileName); autosaveFile.remove(); if(!cr_tmp_file.isEmpty()) { QFile autosaveFile2(cr_tmp_file); autosaveFile2.remove(); cr_tmp_file = ""; } if(new_currency) warnAndAskForExchangeRate(); reloadBudget(); emit tagsModified(); emit accountsModified(); emit transactionsModified(); emit budgetUpdated(); setModified(true); checkSchedule(true, this); return true; } QFile autosaveFile(autosaveFileName); autosaveFile.remove(); } return false; } void Eqonomize::onAutoSaveTimeout() { auto_save_timeout = true; if(modified_auto_save) { autoSave(); } } void Eqonomize::autoSave() { if(auto_save_timeout) { saveCrashRecovery(); modified_auto_save = false; auto_save_timeout = false; } } void Eqonomize::saveCrashRecovery() { if(cr_tmp_file.isEmpty()) { #if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)) cr_tmp_file = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/autosave/"; #else cr_tmp_file = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "Eqonomize/eqonomize/autosave/"; #endif QDir autosaveDir(cr_tmp_file); if(!autosaveDir.mkpath(cr_tmp_file)) { cr_tmp_file = ""; return; } if(current_url.isEmpty()) cr_tmp_file += "UNSAVED EQZ"; else cr_tmp_file += current_url.fileName(); } if(budget->saveFile(cr_tmp_file, QFile::ReadUser | QFile::WriteUser, true).isNull()) { QSettings settings; settings.beginGroup("GeneralOptions"); settings.setValue("lastURL", current_url.url()); settings.endGroup(); settings.sync(); } } void Eqonomize::setCommandLineParser(QCommandLineParser *p) { parser = p; } void Eqonomize::onActivateRequested(const QStringList &arguments, const QString &workingDirectory) { if(!arguments.isEmpty()) { parser->process(arguments); if(parser->isSet("expenses")) { showExpenses(); } else if(parser->isSet("incomes")) { showIncomes(); } else if(parser->isSet("transfers")) { showTransfers(); } QStringList args = parser->positionalArguments(); if(args.count() > 0) { QString curpath = QDir::currentPath(); QDir::setCurrent(workingDirectory); openURL(QUrl::fromUserInput(args.at(0))); QDir::setCurrent(curpath); } args.clear(); } setWindowState((windowState() & ~Qt::WindowMinimized) | Qt::WindowActive); show(); activateWindow(); } void Eqonomize::saveOptions() { QSettings settings; settings.beginGroup("GeneralOptions"); settings.setValue("version", 141); settings.setValue("lastURL", current_url.url()); if(ActionSelectBackupFrequency->checkedAction() == ABFNever) {settings.setValue("backupFrequency", BACKUP_NEVER);} else if(ActionSelectBackupFrequency->checkedAction() == ABFDaily) {settings.setValue("backupFrequency", BACKUP_DAILY);} else if(ActionSelectBackupFrequency->checkedAction() == ABFWeekly) {settings.setValue("backupFrequency", BACKUP_WEEKLY);} else if(ActionSelectBackupFrequency->checkedAction() == ABFFortnightly) {settings.setValue("backupFrequency", BACKUP_FORTNIGHTLY);} else if(ActionSelectBackupFrequency->checkedAction() == ABFMonthly) {settings.setValue("backupFrequency", BACKUP_MONTHLY);} settings.setValue("useExtraProperties", b_extra); settings.setValue("useExchangeRateForTransactionDate", budget->defaultTransactionConversionRateDate() == TRANSACTION_CONVERSION_RATE_AT_DATE); settings.setValue("firstRun", false); settings.setValue("size", size()); settings.setValue("windowState", saveState()); settings.setValue("expensesListState", expensesWidget->saveState()); settings.setValue("incomesListState", incomesWidget->saveState()); settings.setValue("transfersListState", transfersWidget->saveState()); settings.setValue("securitiesListState", securitiesView->header()->saveState()); settings.setValue("scheduleListState", scheduleView->header()->saveState()); settings.setValue("assetsGroupExpanded", assets_expanded); settings.setValue("liabilitiesGroupExpanded", liabilities_expanded); settings.setValue("incomesCategoryExpanded", incomes_expanded); settings.setValue("expensesCategoryExpanded", expenses_expanded); settings.setValue("tagsExpanded", tagsItem->isExpanded()); if(ActionSelectInitialPeriod->checkedAction() == AIPCurrentMonth) {settings.setValue("initialPeriod", 0);} else if(ActionSelectInitialPeriod->checkedAction() == AIPCurrentYear) {settings.setValue("initialPeriod", 1);} else if(ActionSelectInitialPeriod->checkedAction() == AIPCurrentWholeMonth) {settings.setValue("initialPeriod", 2);} else if(ActionSelectInitialPeriod->checkedAction() == AIPCurrentWholeYear) {settings.setValue("initialPeriod", 3);} else { settings.setValue("initialPeriod", 4); settings.setValue("initialFromDate", from_date.toString(Qt::ISODate)); settings.setValue("initialFromDateEnabled", accountsPeriodFromButton->isChecked()); settings.setValue("initialToDate", to_date.toString(Qt::ISODate)); } settings.endGroup(); emit timeToSaveConfig(); } void Eqonomize::readFileDependentOptions() {} void Eqonomize::readOptions() { QSettings settings; settings.beginGroup("GeneralOptions"); first_run = settings.value("firstRun", true).toBool(); settings.setValue("firstRun", false); QSize window_size = settings.value("size", QSize()).toSize(); if(window_size.isValid()) resize(window_size); restoreState(settings.value("windowState").toByteArray()); expensesWidget->restoreState(settings.value("expensesListState").toByteArray()); incomesWidget->restoreState(settings.value("incomesListState").toByteArray()); transfersWidget->restoreState(settings.value("transfersListState").toByteArray()); securitiesView->header()->restoreState(settings.value("securitiesListState").toByteArray()); if(settings.value("version", 0).toInt() >= 140) { scheduleView->header()->restoreState(settings.value("scheduleListState").toByteArray()); } assets_expanded = settings.value("assetsGroupExpanded").toMap(); liabilities_expanded = settings.value("liabilitiesGroupExpanded").toMap(); incomes_expanded = settings.value("incomesCategoryExpanded").toMap(); expenses_expanded = settings.value("expensesCategoryExpanded").toMap(); tagsItem->setExpanded(settings.value("tagsExpanded", true).toBool()); scheduleView->sortByColumn(0, Qt::AscendingOrder); settings.endGroup(); updateRecentFiles(); } void Eqonomize::closeEvent(QCloseEvent *event) { if(askSave(true)) { saveOptions(); if(server) delete server; QMainWindow::closeEvent(event); qApp->closeAllWindows(); } else { event->ignore(); } } void Eqonomize::dragEnterEvent(QDragEnterEvent *event) { event->setAccepted(event->mimeData()->hasUrls()); } void Eqonomize::dropEvent(QDropEvent *event) { QList urls =event->mimeData()->urls(); if(!urls.isEmpty()) { const QUrl &url = urls.first(); if(!askSave()) return; openURL(url); } } void Eqonomize::fileNew() { if(!askSave()) return; budget->clear(); bool new_currency = false; if(current_url.isEmpty()) new_currency = budget->resetDefaultCurrency(); current_url = ""; setWindowTitle(tr("Untitled") + "[*]"); ActionFileReload->setEnabled(false); QSettings settings; settings.beginGroup("GeneralOptions"); settings.setValue("lastURL", current_url.url()); if(!cr_tmp_file.isEmpty()) { QFile autosaveFile(cr_tmp_file); autosaveFile.remove(); cr_tmp_file = ""; } settings.endGroup(); settings.sync(); if(new_currency) warnAndAskForExchangeRate(); reloadBudget(); setModified(false); ActionFileSave->setEnabled(true); emit tagsModified(); emit accountsModified(); emit transactionsModified(); emit budgetUpdated(); } void Eqonomize::fileOpen() { if(!askSave()) return; QMimeDatabase db; QMimeType mime = db.mimeTypeForName("application/x-eqonomize"); QString filter_string; if(mime.isValid()) filter_string = mime.filterString(); if(filter_string.isEmpty()) filter_string = tr("Eqonomize! Accounting File") + "(*.eqz)"; QString url = QFileDialog::getOpenFileName(this, QString(), current_url.isValid() ? current_url.adjusted(QUrl::RemoveFilename).toLocalFile() : QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + QString("/"), filter_string); if(!url.isEmpty()) openURL(QUrl::fromLocalFile(url)); } void Eqonomize::fileOpenRecent(const QUrl &url) { if(!askSave()) return; openURL(url); } void Eqonomize::fileReload() { openURL(current_url); } bool Eqonomize::fileSave() { if(!current_url.isValid()) { return fileSaveAs(); } else { return saveURL(current_url); } return false; } bool Eqonomize::fileSaveAs() { return saveAs(true, true); } bool Eqonomize::saveAs(bool do_local_sync, bool do_cloud_sync, QWidget *parent) { if(!parent) parent = this; QMimeDatabase db; QMimeType mime = db.mimeTypeForName("application/x-eqonomize"); QString filter_string; QString suffix; if(mime.isValid()) { filter_string = mime.filterString(); suffix = mime.preferredSuffix(); } if(filter_string.isEmpty()) filter_string = "Eqonomize! Accounting File (*.eqz)"; if(suffix.isEmpty()) suffix = "eqz"; QFileDialog fileDialog(parent); fileDialog.setNameFilter(filter_string); fileDialog.setDefaultSuffix(suffix); fileDialog.setAcceptMode(QFileDialog::AcceptSave); #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) fileDialog.setSupportedSchemes(QStringList("file")); #endif if(current_url.isValid()) { fileDialog.setDirectory(current_url.adjusted(QUrl::RemoveFilename).toLocalFile()); } else { fileDialog.setDirectory(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)); fileDialog.selectFile(QString("budget.") + suffix); } if(fileDialog.exec()) { QList urls = fileDialog.selectedUrls(); if(urls.isEmpty()) return false; return saveURL(urls[0], do_local_sync, do_cloud_sync, parent); } return false; } bool Eqonomize::askSave(bool) { if(!modified) return true; int b_save = QMessageBox::warning(this, tr("Save file?"), tr("The current file has been modified. Do you want to save it?"), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel); if(b_save == QMessageBox::Yes) { return fileSave(); } if(b_save == QMessageBox::No) { if(!cr_tmp_file.isEmpty()) { QFile autosaveFile(cr_tmp_file); autosaveFile.remove(); cr_tmp_file = ""; } return true; } return false; } void Eqonomize::optionsPreferences() { } void Eqonomize::checkSchedule() { checkSchedule(true, this); } bool Eqonomize::checkSchedule(bool update_display, QWidget *parent, bool allow_account_creation) { bool b = false; QSettings settings; settings.beginGroup("GeneralOptions"); QTime confirm_time = settings.value("scheduleConfirmationTime", QTime(18, 0)).toTime(); settings.endGroup(); for(ScheduledTransactionList::const_iterator it = budget->scheduledTransactions.constBegin(); it != budget->scheduledTransactions.constEnd(); ++it) { ScheduledTransaction *strans = *it; if(strans->firstOccurrence() < QDate::currentDate() || (QTime::currentTime() >= confirm_time && strans->firstOccurrence() == QDate::currentDate())) { b = true; break; } } if(b) { if(allow_account_creation) { budget->setRecordNewAccounts(true); budget->setRecordNewSecurities(true); budget->resetDefaultCurrencyChanged(); budget->resetCurrenciesModified(); budget->setRecordNewTags(true); } qApp->processEvents(); ConfirmScheduleDialog *dialog = new ConfirmScheduleDialog(b_extra, budget, parent ? parent : this, tr("Confirm Schedule"), allow_account_creation); dialog->exec(); if(allow_account_creation) { foreach(Account* acc, budget->newAccounts) accountAdded(acc); budget->newAccounts.clear(); foreach(Security *sec, budget->newSecurities) securityAdded(sec); budget->newSecurities.clear(); if(budget->currenciesModified() || budget->defaultCurrencyChanged()) currenciesModified(); budget->setRecordNewAccounts(false); budget->setRecordNewSecurities(false); budget->setRecordNewTags(false); foreach(QString str, budget->newTags) tagAdded(str); budget->newTags.clear(); } Transactions *trans = dialog->firstTransaction(); while(trans) { addTransactionLinks(trans, false); budget->addTransactions(trans); trans = dialog->nextTransaction(); } dialog->deleteLater(); } if(b && update_display) { expensesWidget->transactionsReset(); incomesWidget->transactionsReset(); transfersWidget->transactionsReset(); filterAccounts(); updateScheduledTransactions(); updateSecurities(); emit transactionsModified(); setModified(true); } return b; } void Eqonomize::startBatchEdit() { in_batch_edit = true; } void Eqonomize::endBatchEdit() { if(in_batch_edit) { in_batch_edit = false; emit budgetUpdated(); emit transactionsModified(); } } void Eqonomize::updateScheduledTransactions() { scheduleView->clear(); for(ScheduledTransactionList::const_iterator it = budget->scheduledTransactions.constBegin(); it != budget->scheduledTransactions.constEnd(); ++it) { ScheduledTransaction *strans = *it; new ScheduleListViewItem(scheduleView, strans, strans->firstOccurrence(), right_align_values); } scheduleView->setSortingEnabled(true); } void Eqonomize::appendScheduledTransaction(ScheduledTransaction *strans) { new ScheduleListViewItem(scheduleView, strans, strans->firstOccurrence(), right_align_values); scheduleView->setSortingEnabled(true); } void Eqonomize::addAccount() { QTreeWidgetItem *i = selectedItem(accountsView); if(i == NULL || i == tagsItem) { newAssetsAccount(); } else if(i == liabilitiesItem || (account_items.contains(i) && (account_items[i]->type() == ACCOUNT_TYPE_ASSETS) && (((AssetsAccount*) account_items[i])->isDebt())) || (liabilities_group_items.contains(i) && liabilities_group_items[i] == budget->getAccountTypeName(ASSETS_TYPE_LIABILITIES, true, true))) { newLoan(); } else if(i == assetsItem || (account_items.contains(i) && (account_items[i]->type() == ACCOUNT_TYPE_ASSETS)) || assets_group_items.contains(i) || liabilities_group_items.contains(i)) { newAssetsAccount(); } else if(i == incomesItem || (account_items.contains(i) && (account_items[i]->type() == ACCOUNT_TYPE_INCOMES))) { newIncomesAccount(account_items.contains(i) ? (IncomesAccount*) account_items[i] : NULL); } else { newExpensesAccount(account_items.contains(i) ? (ExpensesAccount*) account_items[i] : NULL); } } void Eqonomize::accountAdded(Account *acc) { switch(acc->type()) { case ACCOUNT_TYPE_ASSETS: { AssetsAccount *account = (AssetsAccount*) acc; appendAssetsAccount(account); filterAccounts(); if(sender() != expensesWidget) expensesWidget->updateFromAccounts(); if(sender() != incomesWidget) incomesWidget->updateToAccounts(); if(sender() != transfersWidget) transfersWidget->updateAccounts(); updateUsesMultipleCurrencies(); break; } case ACCOUNT_TYPE_INCOMES: { IncomesAccount *account = (IncomesAccount*) acc; if(account->parentCategory()) { appendIncomesAccount(account, item_accounts[account->parentCategory()]); } else { appendIncomesAccount(account, incomesItem); } filterAccounts(); if(sender() != incomesWidget) incomesWidget->updateFromAccounts(); break; } case ACCOUNT_TYPE_EXPENSES: { ExpensesAccount *account = (ExpensesAccount*) acc; if(account->parentCategory()) { appendExpensesAccount(account, item_accounts[account->parentCategory()]); } else { appendExpensesAccount(account, expensesItem); } filterAccounts(); if(sender() != expensesWidget) expensesWidget->updateToAccounts(); break; } } emit accountsModified(); setModified(true); } void Eqonomize::newAssetsAccount() { QTreeWidgetItem *i = selectedItem(accountsView); QString s_group; int i_type = -1; if(i && assets_group_items.contains(i)) { s_group = assets_group_items[i]; } else if(i && liabilities_group_items.contains(i)) { s_group = liabilities_group_items[i]; } else if(i && account_items.contains(i) && account_items[i]->type() == ACCOUNT_TYPE_ASSETS && (((!IS_DEBT((AssetsAccount*) account_items[i]) && item_assets_groups.contains(((AssetsAccount*) account_items[i])->group())) || (IS_DEBT((AssetsAccount*) account_items[i]) && item_liabilities_groups.contains(((AssetsAccount*) account_items[i])->group()))))) { s_group = ((AssetsAccount*) account_items[i])->group(); } if(!s_group.isEmpty()) i_type = budget->getAccountType(s_group, true, true); if(i_type == ASSETS_TYPE_OTHER) i_type = -1; EditAssetsAccountDialog *dialog = new EditAssetsAccountDialog(budget, this, tr("New Account"), false, i_type, false, s_group); budget->resetDefaultCurrencyChanged(); budget->resetCurrenciesModified(); if(dialog->exec() == QDialog::Accepted) { AssetsAccount *account = dialog->newAccount(); budget->addAccount(account); appendAssetsAccount(account); if(!IS_DEBT(account) && item_assets_groups.contains(account->group())) item_assets_groups[account->group()]->setExpanded(true); else if(IS_DEBT(account) && item_liabilities_groups.contains(account->group())) item_liabilities_groups[account->group()]->setExpanded(true); if(budget->currenciesModified() || budget->defaultCurrencyChanged()) { currenciesModified(); } else { filterAccounts(); expensesWidget->updateFromAccounts(); incomesWidget->updateToAccounts(); transfersWidget->updateAccounts(); updateUsesMultipleCurrencies(); } emit accountsModified(); setModified(true); } else if(budget->currenciesModified() || budget->defaultCurrencyChanged()) { currenciesModified(); if(budget->defaultCurrencyChanged()) setModified(true); } dialog->deleteLater(); } void Eqonomize::newLoan() { EditAssetsAccountDialog *dialog = new EditAssetsAccountDialog(budget, this, tr("New Loan"), true); budget->resetDefaultCurrencyChanged(); budget->resetCurrenciesModified(); if(dialog->exec() == QDialog::Accepted) { Transaction *trans = NULL; AssetsAccount *account = dialog->newAccount(&trans); budget->addAccount(account); appendAssetsAccount(account); if(item_liabilities_groups.contains(account->group())) item_liabilities_groups[account->group()]->setExpanded(true); if(budget->currenciesModified() || budget->defaultCurrencyChanged()) { currenciesModified(); } else { filterAccounts(); expensesWidget->updateFromAccounts(); incomesWidget->updateToAccounts(); transfersWidget->updateAccounts(); updateUsesMultipleCurrencies(); } emit accountsModified(); if(trans) { if(trans->date() > QDate::currentDate()) { ScheduledTransaction *strans = new ScheduledTransaction(budget, trans, NULL); budget->addScheduledTransaction(strans); transactionAdded(strans); } else { budget->addTransaction(trans); transactionAdded(trans); } } setModified(true); } else if(budget->currenciesModified() || budget->defaultCurrencyChanged()) { currenciesModified(); if(budget->defaultCurrencyChanged()) setModified(true); } dialog->deleteLater(); } void Eqonomize::newIncomesAccount(IncomesAccount *default_parent) { EditIncomesAccountDialog *dialog = new EditIncomesAccountDialog(budget, default_parent, this, tr("New Income Category")); if(dialog->exec() == QDialog::Accepted) { IncomesAccount *account = dialog->newAccount(); budget->addAccount(account); if(account->parentCategory()) { appendIncomesAccount(account, item_accounts[account->parentCategory()]); item_accounts[account->parentCategory()]->setExpanded(true); } else { appendIncomesAccount(account, incomesItem); } filterAccounts(); incomesWidget->updateFromAccounts(); emit accountsModified(); setModified(true); } dialog->deleteLater(); } void Eqonomize::newExpensesAccount(ExpensesAccount *default_parent) { EditExpensesAccountDialog *dialog = new EditExpensesAccountDialog(budget, default_parent, this, tr("New Expense Category")); if(dialog->exec() == QDialog::Accepted) { ExpensesAccount *account = dialog->newAccount(); budget->addAccount(account); if(account->parentCategory()) { appendExpensesAccount(account, item_accounts[account->parentCategory()]); item_accounts[account->parentCategory()]->setExpanded(true); } else { appendExpensesAccount(account, expensesItem); } filterAccounts(); expensesWidget->updateToAccounts(); emit accountsModified(); setModified(true); } dialog->deleteLater(); } void Eqonomize::accountExecuted(QTreeWidgetItem *i) { if(i->childCount() > 0) { i->setExpanded(!i->isExpanded()); } else { showAccountTransactions(true); } } void Eqonomize::accountExecuted(QTreeWidgetItem *i, int c) { if(i == NULL) return; switch(c) { case 0: { if(i->childCount() == 0 && account_items.contains(i)) { if(account_items[i]->type() == ACCOUNT_TYPE_ASSETS) showAccountTransactions(true); else editAccount(account_items[i]); } if(tag_items.contains(i)) showAccountTransactions(true); break; } case 1: { if(account_items.contains(i)) { if(account_items[i]->type() == ACCOUNT_TYPE_ASSETS) { showAccountTransactions(); } else { accountsTabs->setCurrentIndex(1); if(budgetEdit->isEnabled()) { budgetEdit->setFocus(); budgetEdit->selectNumber(); } else { budgetButton->setFocus(); } } } else if(tag_items.contains(i)) { showAccountTransactions(true); } break; } case 2: { showAccountTransactions(); break; } case 3: { showAccountTransactions(true); break; } } } void Eqonomize::accountClickedTimeout() { clicked_item = NULL; } void Eqonomize::accountClicked(QTreeWidgetItem *i, int c) { if(clicked_item == i) { clicked_item = NULL; return; } if(i != NULL && i != expensesItem && i != assetsItem && i != incomesItem && i != liabilitiesItem && c == 0 && i->childCount() > 0) { i->setExpanded(!i->isExpanded()); clicked_item = i; QTimer::singleShot(QApplication::doubleClickInterval(), this, SLOT(accountClickedTimeout())); } else { clicked_item = NULL; } } void Eqonomize::balanceAccount() { QTreeWidgetItem *i = selectedItem(accountsView); if(!account_items.contains(i)) return; Account *i_account = account_items[i]; balanceAccount(i_account); } void Eqonomize::balanceAccount(Account *i_account) { if(!i_account) return; if(i_account->type() != ACCOUNT_TYPE_ASSETS || ((AssetsAccount*) i_account)->isSecurities()) return; AssetsAccount *account = (AssetsAccount*) i_account; double book_value = account->initialBalance(); double current_balancing = 0.0; for(TransactionList::const_iterator it = budget->transactions.constBegin(); it != budget->transactions.constEnd(); ++it) { Transaction *trans = *it; if(trans->fromAccount() == account) { book_value -= trans->value(); if(trans->toAccount() == budget->balancingAccount) current_balancing -= trans->value(); } if(trans->toAccount() == account) { book_value += trans->value(); if(trans->fromAccount() == budget->balancingAccount) current_balancing += trans->value(); } } QDialog *dialog = new QDialog(this); dialog->setWindowTitle(tr("Adjust Account Balance")); dialog->setModal(true); QVBoxLayout *box1 = new QVBoxLayout(dialog); box1->setSpacing(12); QGridLayout *grid = new QGridLayout(); box1->addLayout(grid); grid->setSpacing(6); grid->addWidget(new QLabel(tr("Book value:"), dialog), 0, 0); QLabel *label = new QLabel(account->currency()->formatValue(book_value), dialog); label->setAlignment(Qt::AlignRight | Qt::AlignVCenter); grid->addWidget(label, 0, 1); label = new QLabel(tr("of which %1 is balance adjustment", "Referring to account balance").arg(account->currency()->formatValue(current_balancing)), dialog); label->setAlignment(Qt::AlignRight | Qt::AlignVCenter); grid->addWidget(label, 1, 1); grid->addWidget(new QLabel(tr("Real value:"), dialog), 2, 0); EqonomizeValueEdit *realEdit = new EqonomizeValueEdit(book_value, true, true, dialog, budget); realEdit->setCurrency(account->currency()); grid->addWidget(realEdit, 2, 1); QFrame *frame = new QFrame(this); QHBoxLayout *wbox = new QHBoxLayout(frame); frame->setFrameShape(QFrame::Box); label = new QLabel(tr("Only use this when unable to find the cause of the incorrect recorded account balance."), dialog); label->setContentsMargins(6, 6, 6, 6); label->setWordWrap(true); wbox->addWidget(label); box1->addWidget(frame); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, dialog); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), dialog, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), dialog, SLOT(accept())); box1->addWidget(buttonBox); if(dialog->exec() == QDialog::Accepted && realEdit->value() != book_value) { Transaction *trans = new Balancing(budget, realEdit->value() - book_value, QDate::currentDate(), account); budget->addTransaction(trans); transactionAdded(trans); } dialog->deleteLater(); } void Eqonomize::editAccount() { QTreeWidgetItem *i = selectedItem(accountsView); if(!account_items.contains(i)) return; Account *i_account = account_items[i]; editAccount(i_account); } bool Eqonomize::editAccount(Account *i_account) { return editAccount(i_account, this); } void Eqonomize::updateBudgetAccountTitle(AssetsAccount *account) { bool b_time = to_date > QDate::currentDate(); if(!account) account = budget->budgetAccount; QTreeWidgetItem *i = NULL; if(account) i = item_accounts[account]; if(i) { if(b_time && account->isBudgetAccount()) i->setText(0, account->name() + "*"); else i->setText(0, account->name()); } if(b_time) { if(!assetsItem->text(0).endsWith('*')) assetsItem->setText(0, assetsItem->text(0) + '*'); } else { if(assetsItem->text(0).endsWith('*')) assetsItem->setText(0, assetsItem->text(0).left(assetsItem->text(0).length() - 1)); } for(QMap::iterator it = assets_group_items.begin(); it != assets_group_items.end(); ++it) { if(b_time && budget->budgetAccount && it.value() == budget->budgetAccount->group()) { if(!it.key()->text(0).endsWith('*')) it.key()->setText(0, it.key()->text(0) + '*'); else break; } else { if(it.key()->text(0).endsWith('*')) it.key()->setText(0, it.key()->text(0).left(it.key()->text(0).length() - 1)); } } footer1->setVisible(b_time); } bool Eqonomize::editAccount(Account *i_account, QWidget *parent) { QTreeWidgetItem *i = item_accounts[i_account]; switch(i_account->type()) { case ACCOUNT_TYPE_ASSETS: { EditAssetsAccountDialog *dialog = new EditAssetsAccountDialog(budget, parent, tr("Edit Account")); AssetsAccount *account = (AssetsAccount*) i_account; dialog->setAccount(account); double prev_ib = account->initialBalance(); bool prev_debt = IS_DEBT(account); QString prev_group = account->group(); int prev_type = account->accountType(); Account *previous_budget_account = budget->budgetAccount; Currency *cur = account->currency(); budget->resetDefaultCurrencyChanged(); budget->resetCurrenciesModified(); if(dialog->exec() == QDialog::Accepted) { dialog->modifyAccount(account); bool currency_changed = account->currency() != cur; budget->accountModified(account); if(previous_budget_account != budget->budgetAccount) { if(account->isBudgetAccount() && previous_budget_account) { item_accounts[previous_budget_account]->setText(0, previous_budget_account->name()); } else { i->setText(0, account->name()); } } account_value[account] += (account->initialBalance() - prev_ib); bool is_debt = IS_DEBT(account); updateBudgetAccountTitle(account); QString s_group = account->group(); if(prev_group != s_group || is_debt != prev_debt) { int type_copy = account->accountType(); account->setAccountType(prev_type); account->setGroup(prev_group); assetsAccountItemHiddenOrRemoved(account); account->setAccountType(type_copy); account->setGroup(s_group); if(!is_debt && item_assets_groups.contains(s_group)) { i->parent()->removeChild(i); item_assets_groups[s_group]->addChild(i); } else if(is_debt && item_liabilities_groups.contains(s_group)) { i->parent()->removeChild(i); item_liabilities_groups[s_group]->addChild(i); } else if(is_debt != prev_debt || (i->parent() != assetsItem && i->parent() != liabilitiesItem)) { i->parent()->removeChild(i); if(is_debt) liabilitiesItem->addChild(i); else assetsItem->addChild(i); } assetsAccountItemShownOrAdded(account); } if(budget->currenciesModified() || budget->defaultCurrencyChanged()) { currenciesModified(); } else if(previous_budget_account != budget->budgetAccount || currency_changed || prev_group != s_group || is_debt != prev_debt) { filterAccounts(); } else if(is_debt) { liabilities_group_value[s_group] += account->currency()->convertTo(account->initialBalance() - prev_ib, budget->defaultCurrency(), to_date); liabilities_accounts_value += account->currency()->convertTo(account->initialBalance() - prev_ib, budget->defaultCurrency(), to_date); i->setText(VALUE_COLUMN, account->currency()->formatValue(-account_value[account]) + " "); liabilitiesItem->setText(VALUE_COLUMN, budget->formatMoney(-liabilities_accounts_value) + " "); if(item_liabilities_groups.contains(s_group)) item_liabilities_groups[s_group]->setText(VALUE_COLUMN, budget->formatMoney(-liabilities_group_value[s_group]) + " "); } else { assets_group_value[s_group] += account->currency()->convertTo(account->initialBalance() - prev_ib, budget->defaultCurrency(), to_date); assets_accounts_value += account->currency()->convertTo(account->initialBalance() - prev_ib, budget->defaultCurrency(), to_date); i->setText(VALUE_COLUMN, account->currency()->formatValue(account_value[account]) + " "); assetsItem->setText(VALUE_COLUMN, budget->formatMoney(assets_accounts_value) + " "); if(item_assets_groups.contains(s_group)) item_assets_groups[s_group]->setText(VALUE_COLUMN, budget->formatMoney(assets_group_value[s_group]) + " "); } bool b_hide = account->isClosed() && is_zero(account_value[account]) && is_zero(account_change[account]); if(b_hide != i->isHidden()) { i->setHidden(b_hide); if(b_hide) assetsAccountItemHiddenOrRemoved(account); else assetsAccountItemShownOrAdded(account); } emit accountsModified(); setModified(true); if(!budget->currenciesModified() && !budget->defaultCurrencyChanged()) { expensesWidget->updateFromAccounts(); incomesWidget->updateToAccounts(); transfersWidget->updateAccounts(); expensesWidget->filterTransactions(); incomesWidget->filterTransactions(); transfersWidget->filterTransactions(); updateScheduledTransactions(); updateSecurities(); } assetsItem->sortChildren(0, Qt::AscendingOrder); liabilitiesItem->sortChildren(0, Qt::AscendingOrder); dialog->deleteLater(); updateUsesMultipleCurrencies(); return true; } else if(budget->currenciesModified() || budget->defaultCurrencyChanged()) { currenciesModified(); } dialog->deleteLater(); break; } case ACCOUNT_TYPE_INCOMES: { EditIncomesAccountDialog *dialog = new EditIncomesAccountDialog(budget, NULL, parent, tr("Edit Income Category")); IncomesAccount *account = (IncomesAccount*) i_account; dialog->setAccount(account); CategoryAccount *prev_parent = account->parentCategory(); if(dialog->exec() == QDialog::Accepted) { dialog->modifyAccount(account); budget->accountModified(account); i->setText(0, account->name()); emit accountsModified(); setModified(true); incomesWidget->updateFromAccounts(); if(prev_parent != account->parentCategory()) { QTreeWidgetItem *prev_parent_item = i->parent(); item_accounts.remove(account); account_items.remove(i); delete i; QTreeWidgetItem *parent_item = incomesItem; if(account->parentCategory()) parent_item = item_accounts[account->parentCategory()]; NEW_ACCOUNT_TREE_WIDGET_ITEM(i, parent_item, account->name(), "-", budget->formatMoney(account_change[account]), budget->formatMoney(account_value[account]) + " "); if(account->parentCategory()) { i->setFlags(i->flags() & ~Qt::ItemIsDropEnabled); parent_item->setFlags(parent_item->flags() & ~Qt::ItemIsDragEnabled); } if(prev_parent_item->childCount() == 0) prev_parent_item->setFlags(prev_parent_item->flags() | Qt::ItemIsDragEnabled); account_items[i] = account; item_accounts[account] = i; parent_item->sortChildren(0, Qt::AscendingOrder); filterAccounts(); } incomesItem->sortChildren(0, Qt::AscendingOrder); incomesWidget->filterTransactions(); updateScheduledTransactions(); dialog->deleteLater(); return true; } dialog->deleteLater(); break; } case ACCOUNT_TYPE_EXPENSES: { EditExpensesAccountDialog *dialog = new EditExpensesAccountDialog(budget, NULL, parent, tr("Edit Expense Category")); ExpensesAccount *account = (ExpensesAccount*) i_account; dialog->setAccount(account); CategoryAccount *prev_parent = account->parentCategory(); if(dialog->exec() == QDialog::Accepted) { dialog->modifyAccount(account); budget->accountModified(account); i->setText(0, account->name()); emit accountsModified(); setModified(true); expensesWidget->updateToAccounts(); if(prev_parent != account->parentCategory()) { QTreeWidgetItem *prev_parent_item = i->parent(); item_accounts.remove(account); account_items.remove(i); delete i; QTreeWidgetItem *parent_item = expensesItem; if(account->parentCategory()) parent_item = item_accounts[account->parentCategory()]; NEW_ACCOUNT_TREE_WIDGET_ITEM(i, parent_item, account->name(), "-", budget->formatMoney(account_change[account]), budget->formatMoney(account_value[account]) + " "); if(account->parentCategory()) { i->setFlags(i->flags() & ~Qt::ItemIsDropEnabled); parent_item->setFlags(parent_item->flags() & ~Qt::ItemIsDragEnabled); } if(prev_parent_item->childCount() == 0) prev_parent_item->setFlags(prev_parent_item->flags() | Qt::ItemIsDragEnabled); account_items[i] = account; item_accounts[account] = i; parent_item->sortChildren(0, Qt::AscendingOrder); filterAccounts(); } expensesItem->sortChildren(0, Qt::AscendingOrder); expensesWidget->filterTransactions(); updateScheduledTransactions(); dialog->deleteLater(); return true; } dialog->deleteLater(); break; } } return false; } void Eqonomize::accountExpanded(QTreeWidgetItem *i) { if(assets_group_items.contains(i)) { assets_expanded[assets_group_items[i]] = true; } else if(liabilities_group_items.contains(i)) { liabilities_expanded[liabilities_group_items[i]] = true; } else if(account_items.contains(i)) { if(account_items[i]->type() == ACCOUNT_TYPE_INCOMES) incomes_expanded[account_items[i]->name()] = true; else expenses_expanded[account_items[i]->name()] = true; } } void Eqonomize::accountCollapsed(QTreeWidgetItem *i) { if(assets_group_items.contains(i)) { assets_expanded[assets_group_items[i]] = false; } else if(liabilities_group_items.contains(i)) { liabilities_expanded[liabilities_group_items[i]] = false; } else if(account_items.contains(i)) { if(account_items[i]->type() == ACCOUNT_TYPE_INCOMES) incomes_expanded[account_items[i]->name()] = false; else expenses_expanded[account_items[i]->name()] = false; } } void Eqonomize::accountMoved(QTreeWidgetItem *i, QTreeWidgetItem *target) { QMap::const_iterator it_i = account_items.find(i); if(it_i == account_items.end()) return; Account *account = *it_i, *target_account = NULL; if(target != incomesItem && target != expensesItem) { QMap::const_iterator it_target = account_items.find(target); if(it_target == account_items.end()) return; target_account = *it_target; if(target_account->type() != account->type()) return; } if(account->type() == ACCOUNT_TYPE_EXPENSES || account->type() == ACCOUNT_TYPE_INCOMES) { if(target == incomesItem && account->type() == ACCOUNT_TYPE_EXPENSES) return; if(target == expensesItem && account->type() == ACCOUNT_TYPE_INCOMES) return; CategoryAccount *ca = (CategoryAccount*) account; CategoryAccount *target_ca = (CategoryAccount*) target_account; if(target_ca && target_ca->parentCategory()) target_ca = target_ca->parentCategory(); if(!ca->subCategories.isEmpty()) return; if(ca->parentCategory() == target_ca) return; QTreeWidgetItem *prev_parent_item = i->parent(); ca->setParentCategory(target_ca); budget->accountModified(account); emit accountsModified(); setModified(true); if(account->type() == ACCOUNT_TYPE_EXPENSES) expensesWidget->updateToAccounts(); else incomesWidget->updateToAccounts(); item_accounts.remove(ca); account_items.remove(i); delete i; QTreeWidgetItem *parent_item = NULL; if(ca->parentCategory()) parent_item = item_accounts[ca->parentCategory()]; else if(account->type() == ACCOUNT_TYPE_EXPENSES) parent_item = expensesItem; else parent_item = incomesItem; NEW_ACCOUNT_TREE_WIDGET_ITEM(i, parent_item, ca->name(), "-", budget->formatMoney(account_change[ca]), budget->formatMoney(account_value[ca]) + " "); if(ca->parentCategory()) { i->setFlags(i->flags() & ~Qt::ItemIsDropEnabled); parent_item->setFlags(parent_item->flags() & ~Qt::ItemIsDragEnabled); } else { i->setFlags(i->flags() | Qt::ItemIsDropEnabled); } if(prev_parent_item->childCount() == 0) prev_parent_item->setFlags(prev_parent_item->flags() | Qt::ItemIsDragEnabled); account_items[i] = ca; item_accounts[ca] = i; parent_item->sortChildren(0, Qt::AscendingOrder); filterAccounts(); } } void Eqonomize::deleteAccount() { QTreeWidgetItem *i = selectedItem(accountsView); if(!account_items.contains(i)) return; Account *account = account_items[i]; if((account->type() == ACCOUNT_TYPE_INCOMES || account->type() == ACCOUNT_TYPE_EXPENSES) && !((CategoryAccount*) account)->subCategories.isEmpty()) { if(QMessageBox::question(this, tr("Remove subcategories?"), tr("Do you wish to remove the category including all subcategories?"), QMessageBox::Yes | QMessageBox::Cancel) != QMessageBox::Yes) return; } if(!budget->accountHasTransactions(account)) { if((account->type() == ACCOUNT_TYPE_INCOMES || account->type() == ACCOUNT_TYPE_EXPENSES) && !((CategoryAccount*) account)->subCategories.isEmpty()) { for(AccountList::const_iterator it = ((CategoryAccount*) account)->subCategories.constBegin(); it != ((CategoryAccount*) account)->subCategories.constEnd(); ++it) { CategoryAccount *ca = *it; QTreeWidgetItem *ca_i = item_accounts[ca]; item_accounts.remove(ca); account_items.remove(ca_i); } } item_accounts.remove(account); account_items.remove(i); delete i; if(account->type() == ACCOUNT_TYPE_ASSETS) assetsAccountItemHiddenOrRemoved((AssetsAccount*) account); account_change.remove(account); account_value.remove(account); budget->removeAccount(account); expensesWidget->updateAccounts(); transfersWidget->updateAccounts(); incomesWidget->updateAccounts(); filterAccounts(); updateUsesMultipleCurrencies(); emit accountsModified(); setModified(true); } else { QRadioButton *deleteButton = NULL, *moveToButton = NULL; QComboBox *moveToCombo = NULL; QButtonGroup *group = NULL; QDialog *dialog = NULL; bool accounts_left = false; QVector moveto_accounts; switch(account->type()) { case ACCOUNT_TYPE_EXPENSES: {accounts_left = budget->expensesAccounts.count() > 1; break;} case ACCOUNT_TYPE_INCOMES: {accounts_left = budget->incomesAccounts.count() > 1; break;} case ACCOUNT_TYPE_ASSETS: { for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { AssetsAccount *aaccount = *it; if(aaccount != budget->balancingAccount && aaccount != account && (((AssetsAccount*) account)->isSecurities() == aaccount->isSecurities())) { accounts_left = true; break; } } break; } default: {break;} } if(accounts_left) { dialog = new QDialog(this); dialog->setWindowTitle(tr("Move transactions?")); dialog->setModal(true); QVBoxLayout *box1 = new QVBoxLayout(dialog); box1->setSpacing(12); QGridLayout *grid = new QGridLayout(); box1->addLayout(grid); group = new QButtonGroup(dialog); QLabel *label = NULL; moveToButton = new QRadioButton(tr("Move to:"), dialog); group->addButton(moveToButton); deleteButton = new QRadioButton(tr("Remove irreversibly from all accounts\n(do not do this if account has been closed!)"), dialog); group->addButton(deleteButton); moveToButton->setChecked(true); moveToCombo = new QComboBox(dialog); moveToCombo->setEditable(false); switch(account->type()) { case ACCOUNT_TYPE_EXPENSES: { label = new QLabel(tr("The category contains some expenses.\nWhat do you want to do with them?"), dialog); for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) { ExpensesAccount *eaccount = *it; if(eaccount != account) { moveToCombo->addItem(eaccount->name()); moveto_accounts.push_back(eaccount); } } break; } case ACCOUNT_TYPE_INCOMES: { label = new QLabel(tr("The category contains some incomes.\nWhat do you want to do with them?"), dialog); for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) { IncomesAccount *iaccount = *it; if(iaccount != account) { moveToCombo->addItem(iaccount->name()); moveto_accounts.push_back(iaccount); } } break; } case ACCOUNT_TYPE_ASSETS: { label = new QLabel(tr("The account contains some transactions.\nWhat do you want to do with them?"), dialog); for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { AssetsAccount *aaccount = *it; if(aaccount != budget->balancingAccount && aaccount != account && ((AssetsAccount*) account)->isSecurities() == aaccount->isSecurities()) { moveToCombo->addItem(aaccount->name()); moveto_accounts.push_back(aaccount); } } break; } default: {break;} } grid->addWidget(label, 0, 0, 1, 2); grid->addWidget(moveToButton, 1, 0); grid->addWidget(moveToCombo, 1, 1); grid->addWidget(deleteButton, 2, 0, 1, 2); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, dialog); buttonBox->button(QDialogButtonBox::Ok)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); buttonBox->button(QDialogButtonBox::Cancel)->setDefault(true); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), dialog, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), dialog, SLOT(accept())); box1->addWidget(buttonBox); } bool do_delete = false; if(accounts_left) { do_delete = (dialog->exec() == QDialog::Accepted); } else { switch(account->type()) { case ACCOUNT_TYPE_EXPENSES: {do_delete = (QMessageBox::warning(this, tr("Remove Category?"), tr("The category contains some expenses that will be removed. Do you still want to remove the category?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes); break;} case ACCOUNT_TYPE_INCOMES: {do_delete = (QMessageBox::warning(this, tr("Remove Category?"), tr("The category contains some incomes that will be removed. Do you still want to remove the category?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes); break;} case ACCOUNT_TYPE_ASSETS: {do_delete = (QMessageBox::warning(this, tr("Remove Account?"), tr("The account contains some transactions that will be removed. Do you still want to remove the account?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes); break;} } } if(do_delete) { if(accounts_left && moveToButton->isChecked()) { budget->moveTransactions(account, moveto_accounts[moveToCombo->currentIndex()]); } if((account->type() == ACCOUNT_TYPE_INCOMES || account->type() == ACCOUNT_TYPE_EXPENSES) && !((CategoryAccount*) account)->subCategories.isEmpty()) { for(AccountList::const_iterator it = ((CategoryAccount*) account)->subCategories.constBegin(); it != ((CategoryAccount*) account)->subCategories.constEnd(); ++it) { CategoryAccount *ca = *it; QTreeWidgetItem *ca_i = item_accounts[ca]; item_accounts.remove(ca); account_items.remove(ca_i); } } if(account->topAccount() != account && i->parent()->childCount() == 0) i->parent()->setFlags(i->parent()->flags() | Qt::ItemIsDragEnabled); item_accounts.remove(account); account_items.remove(i); delete i; if(account->type() == ACCOUNT_TYPE_ASSETS) assetsAccountItemHiddenOrRemoved((AssetsAccount*) account); account_change.remove(account); account_value.remove(account); AccountType type = account->type(); budget->removeAccount(account); filterAccounts(); updateSecurities(); updateScheduledTransactions(); switch(type) { case ACCOUNT_TYPE_EXPENSES: {expensesWidget->filterTransactions(); break;} case ACCOUNT_TYPE_INCOMES: {incomesWidget->filterTransactions(); break;} case ACCOUNT_TYPE_ASSETS: {incomesWidget->filterTransactions(); expensesWidget->filterTransactions(); transfersWidget->filterTransactions(); break;} } expensesWidget->updateAccounts(); transfersWidget->updateAccounts(); incomesWidget->updateAccounts(); emit accountsModified(); emit transactionsModified(); setModified(true); updateUsesMultipleCurrencies(); } if(dialog) dialog->deleteLater(); } } void Eqonomize::closeAccount() { QTreeWidgetItem *i = selectedItem(accountsView); if(!account_items.contains(i)) return; Account *acc = account_items[i]; if(acc->type() == ACCOUNT_TYPE_ASSETS) { AssetsAccount *account = (AssetsAccount*) acc; bool b = !account->isClosed(); account->setClosed(b); bool b_hide = account->isClosed() && is_zero(account_value[account]) && is_zero(account_change[account]); if(b_hide != i->isHidden()) { i->setHidden(b_hide); if(b_hide) assetsAccountItemHiddenOrRemoved(account); else assetsAccountItemShownOrAdded(account); } emit accountsModified(); expensesWidget->updateFromAccounts(); incomesWidget->updateToAccounts(); transfersWidget->updateAccounts(); setModified(true); if(b) { ActionCloseAccount->setText(tr("Reopen Account", "Mark account as not closed")); ActionCloseAccount->setIcon(LOAD_ICON("edit-undo")); } else { ActionCloseAccount->setText(tr("Close Account", "Mark account as closed")); ActionCloseAccount->setIcon(LOAD_ICON("edit-delete")); } } } void Eqonomize::tagAdded(QString tag) { expensesWidget->tagsModified(); incomesWidget->tagsModified(); transfersWidget->tagsModified(); tagMenu->updateTags(); updateTransactionActions(); NEW_ACCOUNT_TREE_WIDGET_ITEM(i, tagsItem, tag, "", budget->formatMoney(0.0), budget->formatMoney(0.0) + " "); tag_items[i] = tag; item_tags[tag] = i; tag_value[tag] = 0.0; tag_change[tag] = 0.0; tagsItem->setHidden(false); tagsItem->sortChildren(0, Qt::AscendingOrder); emit tagsModified(); } void Eqonomize::tagsChanged() { ActionTags->setText(tr("Tags") + QString(" (") + QString::number(tagMenu->selectedTagsCount()) + ")"); TransactionListWidget *w = NULL; if(tabs->currentIndex() == EXPENSES_PAGE_INDEX) w = expensesWidget; else if(tabs->currentIndex() == INCOMES_PAGE_INDEX) w = incomesWidget; else if(tabs->currentIndex() == TRANSFERS_PAGE_INDEX) w = transfersWidget; else if(tabs->currentIndex() == SCHEDULE_PAGE_INDEX) { ScheduleListViewItem *i = (ScheduleListViewItem*) selectedItem(scheduleView); if(i) { Transactions *trans = i->scheduledTransaction(); Transactions *oldtrans = trans->copy(); tagMenu->modifyTransaction(trans); transactionModified(trans, oldtrans); delete oldtrans; } } if(!w) return; w->modifyTags(); } void Eqonomize::newTag() { QString new_tag = QInputDialog::getText(this, tr("New Tag"), tr("Tag name:")).trimmed(); if(!new_tag.isEmpty()) { if((new_tag.contains(",") && new_tag.contains("\"") && new_tag.contains("\'")) || (new_tag[0] == '\'' && new_tag.contains("\"")) || (new_tag[0] == '\"' && new_tag.contains("\'"))) { if(new_tag[0] == '\'') new_tag.remove("\'"); else new_tag.remove("\""); } QString str = budget->findTag(new_tag); if(str.isEmpty()) { budget->tagAdded(new_tag); tagAdded(new_tag); } else { new_tag = str; } tagMenu->setTagSelected(new_tag, true); tagsChanged(); } } void Eqonomize::deleteTag() { QTreeWidgetItem *i = selectedItem(accountsView); if(!tag_items.contains(i)) return; QString tag = tag_items[i]; int n = 0; for(TransactionList::const_iterator it = budget->transactions.constBegin(); it != budget->transactions.constEnd(); ++it) { if((*it)->hasTag(tag, false)) n++; } for(TransactionList::const_iterator it = budget->splitTransactions.constBegin(); it != budget->splitTransactions.constEnd(); ++it) { if((*it)->hasTag(tag, false)) n++; } for(TransactionList::const_iterator it = budget->scheduledTransactions.constBegin(); it != budget->scheduledTransactions.constEnd(); ++it) { if((*it)->hasTag(tag, false)) n++; } if(n > 0) { if(QMessageBox::question(this, tr("Remove tag?"), tr("Do you wish to remove the tag \"%1\" from %n transaction(s)?", "", n).arg(tag), QMessageBox::Yes | QMessageBox::Cancel) != QMessageBox::Yes) return; startBatchEdit(); for(TransactionList::const_iterator it = budget->transactions.constBegin(); it != budget->transactions.constEnd(); ++it) { if((*it)->removeTag(tag)) transactionModified(*it, *it); } for(TransactionList::const_iterator it = budget->splitTransactions.constBegin(); it != budget->splitTransactions.constEnd(); ++it) { if((*it)->removeTag(tag)) transactionModified(*it, *it); } for(TransactionList::const_iterator it = budget->scheduledTransactions.constBegin(); it != budget->scheduledTransactions.constEnd(); ++it) { if((*it)->removeTag(tag)) transactionModified(*it, *it); } endBatchEdit(); } budget->tagRemoved(tag); item_tags.remove(tag); tag_items.remove(i); delete i; tag_change.remove(tag); tag_value.remove(tag); tagMenu->updateTags(); expensesWidget->tagsModified(); incomesWidget->tagsModified(); transfersWidget->tagsModified(); emit tagsModified(); } void Eqonomize::renameTag() { QTreeWidgetItem *i = selectedItem(accountsView); if(!tag_items.contains(i)) return; QString tag = tag_items[i]; QString new_tag = QInputDialog::getText(this, tr("Rename Tag"), tr("Tag name:"), QLineEdit::Normal, tag).trimmed(); if(!new_tag.isEmpty() && new_tag != tag) { startBatchEdit(); budget->tagRemoved(tag); budget->tagAdded(new_tag); tagMenu->updateTags(); expensesWidget->tagsModified(); incomesWidget->tagsModified(); transfersWidget->tagsModified(); item_tags[new_tag] = item_tags[tag]; tag_items[i] = new_tag; tag_change[new_tag] = tag_change[tag]; tag_value[new_tag] = tag_value[tag]; bool b = false; for(TransactionList::const_iterator it = budget->transactions.constBegin(); it != budget->transactions.constEnd(); ++it) { if((*it)->removeTag(tag)) {(*it)->addTag(new_tag); transactionModified(*it, *it); b = true;} } for(TransactionList::const_iterator it = budget->splitTransactions.constBegin(); it != budget->splitTransactions.constEnd(); ++it) { if((*it)->removeTag(tag)) {(*it)->addTag(new_tag); transactionModified(*it, *it); b = true;} } for(TransactionList::const_iterator it = budget->scheduledTransactions.constBegin(); it != budget->scheduledTransactions.constEnd(); ++it) { if((*it)->removeTag(tag)) {(*it)->addTag(new_tag); transactionModified(*it, *it); b = true;} } if(b) endBatchEdit(); else in_batch_edit = false; i->setText(0, new_tag); item_tags.remove(tag); tag_change.remove(tag); tag_value.remove(tag); emit tagsModified(); } } void Eqonomize::transactionAdded(Transactions *transs) { setModified(true); if(transs == link_trans) setLinkTransaction(transs); switch(transs->generaltype()) { case GENERAL_TRANSACTION_TYPE_SINGLE: { Transaction *trans = (Transaction*) transs; addTransactionValue(trans, trans->date(), true); if(trans->type() == TRANSACTION_TYPE_SECURITY_BUY || trans->type() == TRANSACTION_TYPE_SECURITY_SELL) { updateSecurity(((SecurityTransaction*) trans)->security()); } else if(trans->type() == TRANSACTION_TYPE_INCOME && ((Income*) trans)->security()) { updateSecurity(((Income*) trans)->security()); } break; } case GENERAL_TRANSACTION_TYPE_SPLIT: { SplitTransaction *split = (SplitTransaction*) transs; int c = split->count(); for(int i = 0; i < c; i++) { Transaction *trans = split->at(i); addTransactionValue(trans, trans->date(), true); expensesWidget->onTransactionAdded(trans); incomesWidget->onTransactionAdded(trans); transfersWidget->onTransactionAdded(trans); if(trans->type() == TRANSACTION_TYPE_SECURITY_BUY || trans->type() == TRANSACTION_TYPE_SECURITY_SELL) { updateSecurity(((SecurityTransaction*) trans)->security()); } else if(trans->type() == TRANSACTION_TYPE_INCOME && ((Income*) trans)->security()) { updateSecurity(((Income*) trans)->security()); } } break; } case GENERAL_TRANSACTION_TYPE_SCHEDULE: { ScheduledTransaction *strans = (ScheduledTransaction*) transs; appendScheduledTransaction(strans); addScheduledTransactionValue(strans, true); if(strans->transactiontype() == TRANSACTION_TYPE_SECURITY_BUY || strans->transactiontype() == TRANSACTION_TYPE_SECURITY_SELL) { updateSecurity(((SecurityTransaction*) strans->transaction())->security()); } else if(strans->transactiontype() == TRANSACTION_TYPE_INCOME && ((Income*) strans->transaction())->security()) { updateSecurity(((Income*) strans->transaction())->security()); } if(strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { SplitTransaction *split = (SplitTransaction*) strans->transaction(); int c = split->count(); for(int i = 0; i < c; i++) { Transaction *trans = split->at(i); if(trans->type() == TRANSACTION_TYPE_SECURITY_BUY || trans->type() == TRANSACTION_TYPE_SECURITY_SELL) { updateSecurity(((SecurityTransaction*) trans)->security()); } else if(trans->type() == TRANSACTION_TYPE_INCOME && ((Income*) trans)->security()) { updateSecurity(((Income*) trans)->security()); } } } break; } } if(!in_batch_edit) emit transactionsModified(); expensesWidget->onTransactionAdded(transs); incomesWidget->onTransactionAdded(transs); transfersWidget->onTransactionAdded(transs); } void Eqonomize::transactionModified(Transactions *transs, Transactions *oldtranss) { setModified(true); if(transs == link_trans || oldtranss == link_trans) setLinkTransaction(transs); switch(transs->generaltype()) { case GENERAL_TRANSACTION_TYPE_SINGLE: { Transaction *trans = (Transaction*) transs; Transaction *oldtrans = (Transaction*) oldtranss; subtractTransactionValue(oldtrans, true); addTransactionValue(trans, trans->date(), true); if(trans->type() == TRANSACTION_TYPE_SECURITY_BUY || trans->type() == TRANSACTION_TYPE_SECURITY_SELL) { updateSecurity(((SecurityTransaction*) trans)->security()); } else if(trans->type() == TRANSACTION_TYPE_INCOME && ((Income*) trans)->security()) { updateSecurity(((Income*) trans)->security()); } if(trans->type() == TRANSACTION_TYPE_SECURITY_BUY || trans->type() == TRANSACTION_TYPE_SECURITY_SELL) { updateSecurity(((SecurityTransaction*) trans)->security()); if(((SecurityTransaction*) trans)->security() != ((SecurityTransaction*) oldtrans)->security()) { updateSecurity(((SecurityTransaction*) oldtrans)->security()); } } else if(trans->type() == TRANSACTION_TYPE_INCOME && ((Income*) trans)->security()) { updateSecurity(((Income*) trans)->security()); if(((Income*) trans)->security() != ((Income*) oldtrans)->security()) { updateSecurity(((Income*) oldtrans)->security()); } } break; } case GENERAL_TRANSACTION_TYPE_SPLIT: { SplitTransaction *split = (SplitTransaction*) oldtranss; int c = split->count(); for(int i = 0; i < c; i++) { Transaction *trans = split->at(i); subtractTransactionValue(trans, true); } split = (SplitTransaction*) transs; c = split->count(); for(int i = 0; i < c; i++) { Transaction *trans = split->at(i); addTransactionValue(trans, trans->date(), true); } break; } case GENERAL_TRANSACTION_TYPE_SCHEDULE: { ScheduledTransaction *strans = (ScheduledTransaction*) transs; ScheduledTransaction *oldstrans = (ScheduledTransaction*) oldtranss; QTreeWidgetItemIterator it(scheduleView); ScheduleListViewItem *i = (ScheduleListViewItem*) *it; while(i) { if(i->scheduledTransaction() == strans) { i->setScheduledTransaction(strans); i->setDate(strans->firstOccurrence()); if(i->isSelected()) { scheduleSelectionChanged(); if(tabs->currentIndex() == SCHEDULE_PAGE_INDEX) updateTransactionActions(); } break; } ++it; i = (ScheduleListViewItem*) *it; } subtractScheduledTransactionValue(oldstrans, true); addScheduledTransactionValue(strans, true); if(strans->transactiontype() == TRANSACTION_TYPE_SECURITY_BUY || strans->transactiontype() == TRANSACTION_TYPE_SECURITY_SELL) { updateSecurity(((SecurityTransaction*) strans->transaction())->security()); if(((SecurityTransaction*) strans->transaction())->security() != ((SecurityTransaction*) oldstrans->transaction())->security()) { updateSecurity(((SecurityTransaction*) oldstrans->transaction())->security()); } } else if(strans->transactiontype() == TRANSACTION_TYPE_INCOME && ((Income*) strans->transaction())->security()) { updateSecurity(((Income*) strans->transaction())->security()); if(((Income*) strans->transaction())->security() != ((Income*) oldstrans->transaction())->security()) { updateSecurity(((Income*) oldstrans->transaction())->security()); } } break; } } if(!in_batch_edit) emit transactionsModified(); expensesWidget->onTransactionModified(transs, oldtranss); incomesWidget->onTransactionModified(transs, oldtranss); transfersWidget->onTransactionModified(transs, oldtranss); } bool Eqonomize::removeTransactionLinks(Transactions *trans) { bool b = false; if(trans->generaltype() == GENERAL_TRANSACTION_TYPE_SCHEDULE) trans = ((ScheduledTransaction*) trans)->transaction(); for(int i = 0; i < trans->linksCount(false); i++) { Transactions *ltrans = trans->getLink(i, false); if(ltrans) { ltrans->removeLink(trans); linksUpdated(ltrans); b = true; } } if(trans->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { int n = ((SplitTransaction*) trans)->count(); for(int i = 0; i < n; i++) { if(removeTransactionLinks(((SplitTransaction*) trans)->at(i))) b = true; } } return b; } void Eqonomize::transactionRemoved(Transactions *transs, Transactions *oldvalue, bool b) { if(!oldvalue) oldvalue = transs; setModified(true); if(b) { if(removeTransactionLinks(transs)) updateTransactionActions(); if(link_trans == transs) setLinkTransaction(NULL); } switch(oldvalue->generaltype()) { case GENERAL_TRANSACTION_TYPE_SINGLE: { Transaction *trans = (Transaction*) oldvalue; subtractTransactionValue(trans, true); if(trans->type() == TRANSACTION_TYPE_SECURITY_BUY || trans->type() == TRANSACTION_TYPE_SECURITY_SELL) { updateSecurity(((SecurityTransaction*) trans)->security()); } else if(trans->type() == TRANSACTION_TYPE_INCOME && ((Income*) trans)->security()) { updateSecurity(((Income*) trans)->security()); } break; } case GENERAL_TRANSACTION_TYPE_SPLIT: { SplitTransaction *split = (SplitTransaction*) oldvalue; int c = split->count(); for(int i = 0; i < c; i++) { Transaction *trans = split->at(i); subtractTransactionValue(trans, true); expensesWidget->onTransactionRemoved(trans); incomesWidget->onTransactionRemoved(trans); transfersWidget->onTransactionRemoved(trans); if(trans->type() == TRANSACTION_TYPE_SECURITY_BUY || trans->type() == TRANSACTION_TYPE_SECURITY_SELL) { updateSecurity(((SecurityTransaction*) trans)->security()); } else if(trans->type() == TRANSACTION_TYPE_INCOME && ((Income*) trans)->security()) { updateSecurity(((Income*) trans)->security()); } } break; } case GENERAL_TRANSACTION_TYPE_SCHEDULE: { ScheduledTransaction *strans = (ScheduledTransaction*) oldvalue; QTreeWidgetItemIterator it(scheduleView); ScheduleListViewItem *i = (ScheduleListViewItem*) *it; while(i) { if(i->scheduledTransaction() == transs) { delete i; break; } ++it; i = (ScheduleListViewItem*) *it; } subtractScheduledTransactionValue(strans, true); if(strans->transactiontype() == TRANSACTION_TYPE_SECURITY_BUY || strans->transactiontype() == TRANSACTION_TYPE_SECURITY_SELL) { updateSecurity(((SecurityTransaction*) strans->transaction())->security()); } else if(strans->transactiontype() == TRANSACTION_TYPE_INCOME && ((Income*) strans->transaction())->security()) { updateSecurity(((Income*) strans->transaction())->security()); } if(strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { SplitTransaction *split = (SplitTransaction*) strans->transaction(); int c = split->count(); for(int i = 0; i < c; i++) { Transaction *trans = split->at(i); if(trans->type() == TRANSACTION_TYPE_SECURITY_BUY || trans->type() == TRANSACTION_TYPE_SECURITY_SELL) { updateSecurity(((SecurityTransaction*) trans)->security()); } else if(trans->type() == TRANSACTION_TYPE_INCOME && ((Income*) trans)->security()) { updateSecurity(((Income*) trans)->security()); } } } break; } } if(!in_batch_edit) emit transactionsModified(); expensesWidget->onTransactionRemoved(transs); incomesWidget->onTransactionRemoved(transs); transfersWidget->onTransactionRemoved(transs); } void Eqonomize::appendExpensesAccount(ExpensesAccount *account, QTreeWidgetItem *parent_item) { NEW_ACCOUNT_TREE_WIDGET_ITEM(i, parent_item, account->name(), "-", budget->formatMoney(0.0), budget->formatMoney(0.0) + " "); if(!account->subCategories.isEmpty()) { i->setFlags(i->flags() & ~Qt::ItemIsDragEnabled); i->setExpanded(expenses_expanded[account->name()].toBool()); } if(account->parentCategory()) { i->setFlags(i->flags() & ~Qt::ItemIsDropEnabled); parent_item->setFlags(parent_item->flags() & ~Qt::ItemIsDragEnabled); } account_items[i] = account; item_accounts[account] = i; account_value[account] = 0.0; account_change[account] = 0.0; parent_item->sortChildren(0, Qt::AscendingOrder); for(AccountList::const_iterator it = account->subCategories.constBegin(); it != account->subCategories.constEnd(); ++it) { ExpensesAccount *ea = (ExpensesAccount*) *it; appendExpensesAccount(ea, i); } } void Eqonomize::appendIncomesAccount(IncomesAccount *account, QTreeWidgetItem *parent_item) { NEW_ACCOUNT_TREE_WIDGET_ITEM(i, parent_item, account->name(), "-", budget->formatMoney(0.0), budget->formatMoney(0.0) + " "); if(!account->subCategories.isEmpty()) { i->setFlags(i->flags() & ~Qt::ItemIsDragEnabled); i->setExpanded(incomes_expanded[account->name()].toBool()); } if(account->parentCategory()) { i->setFlags(i->flags() & ~Qt::ItemIsDropEnabled); parent_item->setFlags(parent_item->flags() & ~Qt::ItemIsDragEnabled); } account_items[i] = account; item_accounts[account] = i; account_value[account] = 0.0; account_change[account] = 0.0; parent_item->sortChildren(0, Qt::AscendingOrder); for(AccountList::const_iterator it = account->subCategories.constBegin(); it != account->subCategories.constEnd(); ++it) { IncomesAccount *ia = (IncomesAccount*) *it; appendIncomesAccount(ia, i); } } void Eqonomize::assetsAccountItemHiddenOrRemoved(AssetsAccount *account) { bool is_debt = IS_DEBT(account); if((!is_debt && item_assets_groups.contains(account->group())) || (is_debt && item_liabilities_groups.contains(account->group()))) { QString g = account->group(); int n = 0; for(QMap::const_iterator it = account_items.constBegin(); it != account_items.constEnd(); ++it) { if(it.value() != account && !it.key()->isHidden() && it.value()->type() == ACCOUNT_TYPE_ASSETS && is_debt == IS_DEBT((AssetsAccount*) it.value()) && ((AssetsAccount*) it.value())->group() == g) { n++; if(n == 2) break; } } if(n <= 1) { QTreeWidgetItem *i_sel = selectedItem(accountsView); QTreeWidgetItem *i_cur = accountsView->currentItem(); QTreeWidgetItem *i = (is_debt ? item_liabilities_groups[g] : item_assets_groups[g]); QHash i_hide; for(int index = 0; index < i->childCount(); index++) { i_hide[i->child(index)] = i->child(index)->isHidden(); } QList il = i->takeChildren(); if(is_debt) { liabilitiesItem->addChildren(il); for(int index = 0; index < il.count(); index++) { il[index]->setHidden(i_hide[il[index]]); } liabilitiesItem->sortChildren(0, Qt::AscendingOrder); accountsView->setCurrentItem(i_cur); if(i_sel && liabilitiesItem->indexOfChild(i_sel) >= 0) { accountsView->clearSelection(); i_sel->setSelected(true); } liabilities_group_items.remove(i); item_liabilities_groups.remove(g); } else { assetsItem->addChildren(il); for(int index = 0; index < il.count(); index++) { il[index]->setHidden(i_hide[il[index]]); } assetsItem->sortChildren(0, Qt::AscendingOrder); accountsView->setCurrentItem(i_cur); if(i_sel && assetsItem->indexOfChild(i_sel) >= 0) { accountsView->clearSelection(); i_sel->setSelected(true); } assets_group_items.remove(i); item_assets_groups.remove(g); } delete i; } } if(is_debt && liabilities_group_items.count() == 1 && liabilitiesItem->childCount() == 1) { QTreeWidgetItem *i_sel = selectedItem(accountsView); QTreeWidgetItem *i_cur = accountsView->currentItem(); QTreeWidgetItem *i = liabilities_group_items.firstKey(); QHash i_hide; for(int index = 0; index < i->childCount(); index++) { i_hide[i->child(index)] = i->child(index)->isHidden(); } QList il = i->takeChildren(); liabilities_group_items.clear(); item_liabilities_groups.clear(); delete i; liabilitiesItem->addChildren(il); for(int index = 0; index < il.count(); index++) { il[index]->setHidden(i_hide[il[index]]); } liabilitiesItem->sortChildren(0, Qt::AscendingOrder); accountsView->setCurrentItem(i_cur); if(i_sel && liabilitiesItem->indexOfChild(i_sel) >= 0) { accountsView->clearSelection(); i_sel->setSelected(true); } } else if(!is_debt && assets_group_items.count() == 1 && assetsItem->childCount() == 1) { QTreeWidgetItem *i_sel = selectedItem(accountsView); QTreeWidgetItem *i_cur = accountsView->currentItem(); QTreeWidgetItem *i = assets_group_items.firstKey(); QHash i_hide; for(int index = 0; index < i->childCount(); index++) { i_hide[i->child(index)] = i->child(index)->isHidden(); } QList il = i->takeChildren(); assets_group_items.clear(); item_assets_groups.clear(); delete i; assetsItem->addChildren(il); for(int index = 0; index < il.count(); index++) { il[index]->setHidden(i_hide[il[index]]); } assetsItem->sortChildren(0, Qt::AscendingOrder); accountsView->setCurrentItem(i_cur); if(i_sel && assetsItem->indexOfChild(i_sel) >= 0) { accountsView->clearSelection(); i_sel->setSelected(true); } } } void Eqonomize::assetsAccountItemShownOrAdded(AssetsAccount *account) { bool is_debt = IS_DEBT(account); QString g = account->group(); if(!g.isEmpty() && ((!is_debt && !item_assets_groups.contains(g)) || (is_debt && !item_liabilities_groups.contains(g)))) { int n = 1; for(QMap::const_iterator it = account_items.constBegin(); it != account_items.constEnd(); ++it) { if(it.value() != account && !it.key()->isHidden() && it.value()->type() == ACCOUNT_TYPE_ASSETS && is_debt == IS_DEBT((AssetsAccount*) it.value()) && ((AssetsAccount*) it.value())->group() == g) { n++; } } if(n > 1 && n < (is_debt ? liabilitiesItem->childCount() : assetsItem->childCount())) { QTreeWidgetItem *i_sel = selectedItem(accountsView); QTreeWidgetItem *i_cur = accountsView->currentItem(); NEW_ACCOUNT_TREE_WIDGET_ITEM(i, is_debt ? liabilitiesItem : assetsItem, g, QString(), budget->formatMoney(is_debt ? -liabilities_group_change[g] : assets_group_change[g]), budget->formatMoney(is_debt ? -liabilities_group_change[g] : assets_group_change[g]) + " "); if(is_debt) setAccountChangeColor(i, -liabilities_group_change[g], true); else setAccountChangeColor(i, assets_group_change[g], false); i->setFlags(i->flags() & ~Qt::ItemIsDragEnabled); i->setFlags(i->flags() & ~Qt::ItemIsDropEnabled); if(IS_DEBT(account)) i->setExpanded(liabilities_expanded[g].toBool()); else i->setExpanded(assets_expanded[g].toBool()); QList il; for(int index = 0; ; index++) { if(is_debt) { QTreeWidgetItem *i2 = liabilitiesItem->child(index); if(!i2) break; if(account_items.contains(i2) && ((AssetsAccount*) account_items[i2])->group() == g) { bool b_hide = i2->isHidden(); il << liabilitiesItem->takeChild(index); if(b_hide) i2->setHidden(true); index--; } } else { QTreeWidgetItem *i2 = assetsItem->child(index); if(!i2) break; if(account_items.contains(i2) && ((AssetsAccount*) account_items[i2])->group() == g) { bool b_hide = i2->isHidden(); il << assetsItem->takeChild(index); if(b_hide) i2->setHidden(true); index--; } } } i->addChildren(il); accountsView->setCurrentItem(i_cur); if(i_sel && i->indexOfChild(i_sel) >= 0) { accountsView->clearSelection(); i_sel->setSelected(true); } if(is_debt) { liabilities_group_items[i] = g; item_liabilities_groups[g] = i; liabilitiesItem->sortChildren(0, Qt::AscendingOrder); } else { assets_group_items[i] = g; item_assets_groups[g] = i; assetsItem->sortChildren(0, Qt::AscendingOrder); } } if(n > 1) return; } if((is_debt && item_liabilities_groups.isEmpty()) || (!is_debt && item_assets_groups.isEmpty())) { int n = 0; QString s_group; AssetsAccount *account2 = NULL; for(QMap::const_iterator it = account_items.constBegin(); it != account_items.constEnd(); ++it) { if(it.value() != account && !it.key()->isHidden() && it.value()->type() == ACCOUNT_TYPE_ASSETS && is_debt == IS_DEBT((AssetsAccount*) it.value())) { account2 = (AssetsAccount*) it.value(); if(s_group.isEmpty()) {s_group = account2->group(); if(s_group.isEmpty()) return;} else if(account2->group() != s_group) return; n++; } } if(n > 1) assetsAccountItemShownOrAdded(account2); } } void Eqonomize::appendAssetsAccount(AssetsAccount *account) { bool is_debt = IS_DEBT(account); double initial_balance = account->initialBalance(); QTreeWidgetItem *i_parent = (is_debt ? liabilitiesItem : assetsItem); QString s_group = account->group(); if(is_debt && item_liabilities_groups.contains(s_group)) { i_parent = item_liabilities_groups[s_group]; } else if(!is_debt && item_assets_groups.contains(s_group)) { i_parent = item_assets_groups[s_group]; } NEW_ACCOUNT_TREE_WIDGET_ITEM(i, i_parent, account->name(), QString(), account->currency()->formatValue(0.0), account->currency()->formatValue((is_debt ? -initial_balance : initial_balance)) + " "); i->setFlags(i->flags() & ~Qt::ItemIsDragEnabled); i->setFlags(i->flags() & ~Qt::ItemIsDropEnabled); account_items[i] = account; item_accounts[account] = i; account_value[account] = initial_balance; if(is_debt) { liabilities_accounts_value += account->currency()->convertTo(initial_balance, budget->defaultCurrency(), to_date); liabilitiesItem->setText(VALUE_COLUMN, budget->formatMoney(-liabilities_accounts_value) + " "); liabilitiesItem->sortChildren(0, Qt::AscendingOrder); if(liabilities_group_value.contains(s_group)) { liabilities_group_value[s_group] += account->currency()->convertTo(initial_balance, budget->defaultCurrency(), to_date); } else { liabilities_group_value[s_group] = account->currency()->convertTo(initial_balance, budget->defaultCurrency(), to_date); liabilities_group_change[s_group] = 0.0; } if(item_liabilities_groups.contains(s_group)) { item_liabilities_groups[s_group]->setText(VALUE_COLUMN, budget->formatMoney(-liabilities_group_value[s_group]) + " "); item_liabilities_groups[s_group]->sortChildren(0, Qt::AscendingOrder); } } else { assets_accounts_value += account->currency()->convertTo(initial_balance, budget->defaultCurrency(), to_date); assetsItem->setText(VALUE_COLUMN, budget->formatMoney(assets_accounts_value) + " "); assetsItem->sortChildren(0, Qt::AscendingOrder); if(assets_group_value.contains(s_group)) { assets_group_value[s_group] += account->currency()->convertTo(initial_balance, budget->defaultCurrency(), to_date); } else { assets_group_value[s_group] = account->currency()->convertTo(initial_balance, budget->defaultCurrency(), to_date); assets_group_change[s_group] = 0.0; } if(item_assets_groups.contains(s_group)) { item_assets_groups[s_group]->setText(VALUE_COLUMN, budget->formatMoney(assets_group_value[s_group]) + " "); item_assets_groups[s_group]->sortChildren(0, Qt::AscendingOrder); } } account_change[account] = 0.0; if(account->isClosed() && is_zero(initial_balance)) i->setHidden(true); else assetsAccountItemShownOrAdded(account); updateBudgetAccountTitle(account); } void Eqonomize::appendLoanAccount(LoanAccount*) {} bool Eqonomize::filterTransaction(Transaction *trans) { if(accountsPeriodFromButton->isChecked() && trans->date() < from_date) return true; if(trans->date() > to_date) return true; return false; } void Eqonomize::subtractScheduledTransactionValue(ScheduledTransaction *strans, bool update_value_display) { addScheduledTransactionValue(strans, update_value_display, true); } void Eqonomize::addScheduledTransactionValue(ScheduledTransaction *strans, bool update_value_display, bool subtract) { if(!strans->recurrence()) { if(strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { SplitTransaction *split = (SplitTransaction*) strans->transaction(); int c = split->count(); for(int i = 0; i < c; i++) { addTransactionValue(split->at(i), strans->date(), update_value_display, subtract, -1, -1, NULL); } return; } return addTransactionValue((Transaction*) strans->transaction(), strans->transaction()->date(), update_value_display, subtract, -1, -1, NULL); } Recurrence *rec = strans->recurrence(); QDate curdate = rec->firstOccurrence(); int b_future = 1; if(to_date <= QDate::currentDate()) b_future = 0; else if(strans->transaction()->date() <= QDate::currentDate()) b_future = -1; while(!curdate.isNull() && curdate <= to_date) { if(strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { SplitTransaction *split = (SplitTransaction*) strans->transaction(); int c = split->count(); for(int i = 0; i < c; i++) { addTransactionValue(split->at(i), curdate, update_value_display, subtract, 1, b_future, NULL); } } else { addTransactionValue((Transaction*) strans->transaction(), curdate, update_value_display, subtract, 1, b_future, NULL); } curdate = rec->nextOccurrence(curdate); } } void Eqonomize::subtractTransactionValue(Transaction *trans, bool update_value_display) { addTransactionValue(trans, trans->date(), update_value_display, true); } void Eqonomize::addTransactionValue(Transaction *trans, const QDate &transdate, bool update_value_display, bool subtract, int n, int b_future, const QDate *monthdate) { if(n == 0) return; bool b_filter_to = n < 0 && transdate > to_date; bool b_from = accountsPeriodFromButton->isChecked(); bool b_lastmonth = false; QDate date; if(b_filter_to) { if(!monthdate) { if(!budget->isSameBudgetMonth(transdate, to_date)) return; } else { if(transdate > *monthdate) return; } b_lastmonth = true; } bool b_filter = !b_lastmonth && b_from && transdate < from_date; bool b_curmonth = false; bool b_firstmonth = false; if(!b_lastmonth && b_future < 0) { if(to_date <= QDate::currentDate()) { b_future = 0; } else { b_future = (transdate > QDate::currentDate()); if(!b_future) { QDate curdate = QDate::currentDate(); if(budget->isSameBudgetMonth(curdate, transdate)) { b_curmonth = true; b_future = true; } } } } else if(!b_lastmonth && b_future) { b_curmonth = (transdate <= QDate::currentDate()); } if(b_from && !b_lastmonth && b_filter && !frommonth_begin.isNull()) { if(transdate >= frommonth_begin) b_firstmonth = true; } bool balfrom = false, balto = false; bool to_is_debt = false, from_is_debt = false; double value = subtract ? -trans->fromValue(false) : trans->fromValue(false); double cvalue = trans->fromCurrency()->convertTo(trans->fromValue(false), budget->defaultCurrency(), to_date); double cvalue_then = trans->fromValue(true); if(subtract) cvalue = -cvalue; if(subtract) cvalue_then = -cvalue_then; if(!monthdate) { date = budget->lastBudgetDay(transdate); monthdate = &date; } if(n > 1) value *= n; bool from_sub = (trans->fromAccount() != trans->fromAccount()->topAccount()); bool to_sub = (trans->toAccount() != trans->toAccount()->topAccount()); switch(trans->fromAccount()->type()) { case ACCOUNT_TYPE_EXPENSES: { if(b_lastmonth) { account_month_endlast[trans->fromAccount()] -= cvalue_then; if(from_sub) account_month_endlast[trans->fromAccount()->topAccount()] -= cvalue_then; account_month[trans->fromAccount()][*monthdate] -= cvalue_then; if(from_sub) account_month[trans->fromAccount()->topAccount()][*monthdate] -= cvalue_then; if(update_value_display) { updateMonthlyBudget(trans->fromAccount()); if(from_sub) updateMonthlyBudget(trans->fromAccount()->topAccount()); updateTotalMonthlyExpensesBudget(); } break; } bool update_month_display = false; if(b_firstmonth) { account_month_beginfirst[trans->fromAccount()] -= cvalue_then; if(from_sub) account_month_beginfirst[trans->fromAccount()->topAccount()] -= cvalue_then; update_month_display = true; } if(b_curmonth) { account_month_begincur[trans->fromAccount()] -= cvalue_then; if(from_sub) account_month_begincur[trans->fromAccount()->topAccount()] -= cvalue_then; update_month_display = true; } if(b_future || (!frommonth_begin.isNull() && transdate >= frommonth_begin) || (!prevmonth_begin.isNull() && transdate >= prevmonth_begin)) { account_month[trans->fromAccount()][*monthdate] -= cvalue_then; if(from_sub) account_month[trans->fromAccount()->topAccount()][*monthdate] -= cvalue_then; update_month_display = true; } if(update_value_display && update_month_display) { updateMonthlyBudget(trans->fromAccount()); if(from_sub) updateMonthlyBudget(trans->fromAccount()->topAccount()); updateTotalMonthlyExpensesBudget(); } account_value[trans->fromAccount()] -= cvalue_then; if(from_sub) account_value[trans->fromAccount()->topAccount()] -= cvalue_then; expenses_accounts_value -= cvalue_then; if(!b_filter) { account_change[trans->fromAccount()] -= cvalue_then; if(from_sub) account_value[trans->fromAccount()->topAccount()] -= cvalue_then; expenses_accounts_change -= cvalue_then; if(update_value_display) { expensesItem->setText(CHANGE_COLUMN, budget->formatMoney(expenses_accounts_change)); setAccountChangeColor(expensesItem, expenses_accounts_change, true); } } if(update_value_display) { expensesItem->setText(VALUE_COLUMN, budget->formatMoney(expenses_accounts_value) + " "); } break; } case ACCOUNT_TYPE_INCOMES: { balfrom = (trans->fromAccount() == budget->null_incomes_account); if(b_lastmonth) { account_month_endlast[trans->fromAccount()] += cvalue_then; if(from_sub) account_month_endlast[trans->fromAccount()->topAccount()] += cvalue_then; account_month[trans->fromAccount()][*monthdate] += cvalue_then; if(from_sub) account_month[trans->fromAccount()->topAccount()][*monthdate] += cvalue_then; if(update_value_display) { updateMonthlyBudget(trans->fromAccount()); if(from_sub) updateMonthlyBudget(trans->fromAccount()->topAccount()); updateTotalMonthlyIncomesBudget(); } break; } bool update_month_display = false; if(b_firstmonth) { account_month_beginfirst[trans->fromAccount()] += cvalue_then; if(from_sub) account_month_beginfirst[trans->fromAccount()->topAccount()] += cvalue_then; update_month_display = true; } if(b_curmonth) { account_month_begincur[trans->fromAccount()] += cvalue_then; if(from_sub) account_month_begincur[trans->fromAccount()->topAccount()] += cvalue_then; update_month_display = true; } if(b_future || (!frommonth_begin.isNull() && transdate >= frommonth_begin) || (!prevmonth_begin.isNull() && transdate >= prevmonth_begin)) { account_month[trans->fromAccount()][*monthdate] += cvalue_then; if(from_sub) account_month[trans->fromAccount()->topAccount()][*monthdate] += cvalue_then; update_month_display = true; } if(update_value_display && update_month_display) { updateMonthlyBudget(trans->fromAccount()); if(from_sub) updateMonthlyBudget(trans->fromAccount()->topAccount()); updateTotalMonthlyIncomesBudget(); } account_value[trans->fromAccount()] += cvalue_then; if(from_sub) account_value[trans->fromAccount()->topAccount()] += cvalue_then; incomes_accounts_value += cvalue_then; if(!b_filter) { account_change[trans->fromAccount()] += cvalue_then; if(from_sub) account_change[trans->fromAccount()->topAccount()] += cvalue_then; incomes_accounts_change += cvalue_then; if(update_value_display) { incomesItem->setText(CHANGE_COLUMN, budget->formatMoney(incomes_accounts_change)); setAccountChangeColor(incomesItem, incomes_accounts_change, false); } } if(update_value_display) { incomesItem->setText(VALUE_COLUMN, budget->formatMoney(incomes_accounts_value) + " "); } break; } case ACCOUNT_TYPE_ASSETS: { if(b_lastmonth) break; if(((AssetsAccount*) trans->fromAccount())->accountType() == ASSETS_TYPE_SECURITIES) { if(update_value_display) { updateSecurityAccount((AssetsAccount*) trans->fromAccount(), false); assetsItem->setText(VALUE_COLUMN, budget->formatMoney(assets_accounts_value) + " "); assetsItem->setText(CHANGE_COLUMN, budget->formatMoney(assets_accounts_change)); QString s_group = ((AssetsAccount*) trans->fromAccount())->group(); if(item_assets_groups.contains(s_group)) { item_assets_groups[s_group]->setText(VALUE_COLUMN, budget->formatMoney(assets_group_value[s_group]) + " "); item_assets_groups[s_group]->setText(CHANGE_COLUMN, budget->formatMoney(assets_group_change[s_group])); setAccountChangeColor(item_assets_groups[s_group], assets_group_change[s_group], false); } setAccountChangeColor(assetsItem, assets_accounts_change, false); item_accounts[trans->fromAccount()]->setText(CHANGE_COLUMN, trans->fromAccount()->currency()->formatValue(account_change[trans->fromAccount()])); setAccountChangeColor(item_accounts[trans->fromAccount()], account_change[trans->fromAccount()], false); } break; } balfrom = (trans->fromAccount() == budget->balancingAccount); if(!balfrom) { from_is_debt = IS_DEBT(((AssetsAccount*) trans->fromAccount())); account_value[trans->fromAccount()] -= value; if(from_is_debt) liabilities_accounts_value -= cvalue; else assets_accounts_value -= cvalue; QString s_group = ((AssetsAccount*) trans->fromAccount())->group(); if(from_is_debt) liabilities_group_value[s_group] -= cvalue; else assets_group_value[s_group] -= cvalue; if(!b_filter) { account_change[trans->fromAccount()] -= value; if(from_is_debt) liabilities_accounts_change -= cvalue; else assets_accounts_change -= cvalue; if(from_is_debt) liabilities_group_change[s_group] -= cvalue; else assets_group_change[s_group] -= cvalue; if(update_value_display) { if(from_is_debt) { liabilitiesItem->setText(CHANGE_COLUMN, budget->formatMoney(-liabilities_accounts_change)); setAccountChangeColor(liabilitiesItem, -liabilities_accounts_change, true); item_accounts[trans->fromAccount()]->setText(CHANGE_COLUMN, trans->fromAccount()->currency()->formatValue(-account_change[trans->fromAccount()])); setAccountChangeColor(item_accounts[trans->fromAccount()], -account_change[trans->fromAccount()], true); } else { assetsItem->setText(CHANGE_COLUMN, budget->formatMoney(assets_accounts_change)); setAccountChangeColor(assetsItem, assets_accounts_change, false); item_accounts[trans->fromAccount()]->setText(CHANGE_COLUMN, trans->fromAccount()->currency()->formatValue(account_change[trans->fromAccount()])); setAccountChangeColor(item_accounts[trans->fromAccount()], account_change[trans->fromAccount()], false); } bool b_hide = trans->fromAccount()->isClosed() && is_zero(account_change[trans->fromAccount()]) && is_zero(account_value[trans->fromAccount()]); if(b_hide != item_accounts[trans->fromAccount()]->isHidden()) { item_accounts[trans->fromAccount()]->setHidden(b_hide); if(b_hide) assetsAccountItemHiddenOrRemoved((AssetsAccount*) trans->fromAccount()); else assetsAccountItemShownOrAdded((AssetsAccount*) trans->fromAccount()); } if(!from_is_debt && item_assets_groups.contains(s_group)) { item_assets_groups[s_group]->setText(CHANGE_COLUMN, budget->formatMoney(assets_group_change[s_group])); setAccountChangeColor(item_assets_groups[s_group], assets_group_change[s_group], false); } else if(from_is_debt && item_liabilities_groups.contains(s_group)) { item_liabilities_groups[s_group]->setText(CHANGE_COLUMN, budget->formatMoney(-liabilities_group_change[s_group])); setAccountChangeColor(item_liabilities_groups[s_group], -liabilities_group_change[s_group], true); } } } if(update_value_display) { if(from_is_debt) liabilitiesItem->setText(VALUE_COLUMN, budget->formatMoney(-liabilities_accounts_value) + " "); else assetsItem->setText(VALUE_COLUMN, budget->formatMoney(assets_accounts_value) + " "); if(!from_is_debt && item_assets_groups.contains(s_group)) item_assets_groups[s_group]->setText(VALUE_COLUMN, budget->formatMoney(assets_group_value[s_group]) + " "); else if(from_is_debt && item_liabilities_groups.contains(s_group)) item_liabilities_groups[s_group]->setText(VALUE_COLUMN, budget->formatMoney(-liabilities_group_value[s_group]) + " "); } } break; } } if(trans->fromAccount()->type() == ACCOUNT_TYPE_EXPENSES || trans->fromAccount()->type() == ACCOUNT_TYPE_INCOMES) { for(int i = 0; ; i++) { const QString &tag = trans->getTag(i, true); if(tag.isEmpty()) break; tag_value[tag] += cvalue_then; if(!b_filter) tag_change[tag] += cvalue_then; if(update_value_display) { item_tags[tag]->setText(VALUE_COLUMN, budget->formatMoney(tag_value[tag]) + " "); if(!b_filter) { item_tags[tag]->setText(CHANGE_COLUMN, budget->formatMoney(tag_change[tag])); setAccountChangeColor(item_tags[tag], tag_change[tag], false); } } } } value = subtract ? -trans->toValue(false) : trans->toValue(false); cvalue = trans->toCurrency()->convertTo(trans->toValue(false), budget->defaultCurrency(), to_date); cvalue_then = trans->toValue(true); if(subtract) cvalue = -cvalue; if(subtract) cvalue_then = -cvalue_then; switch(trans->toAccount()->type()) { case ACCOUNT_TYPE_EXPENSES: { if(b_lastmonth) { account_month_endlast[trans->toAccount()] += cvalue_then; if(to_sub) account_month_endlast[trans->toAccount()->topAccount()] += cvalue_then; account_month[trans->toAccount()][*monthdate] += cvalue_then; if(to_sub) account_month[trans->toAccount()->topAccount()][*monthdate] += cvalue_then; if(update_value_display) { updateMonthlyBudget(trans->toAccount()); if(to_sub) updateMonthlyBudget(trans->toAccount()->topAccount()); updateTotalMonthlyExpensesBudget(); } break; } bool update_month_display = false; if(b_firstmonth) { account_month_beginfirst[trans->toAccount()] += cvalue_then; if(to_sub) account_month_beginfirst[trans->toAccount()->topAccount()] += cvalue_then; update_month_display = true; } if(b_curmonth) { account_month_begincur[trans->toAccount()] += cvalue_then; if(to_sub) account_month_begincur[trans->toAccount()->topAccount()] += cvalue_then; update_month_display = true; } if(b_future || (!frommonth_begin.isNull() && transdate >= frommonth_begin) || (!prevmonth_begin.isNull() && transdate >= prevmonth_begin)) { account_month[trans->toAccount()][*monthdate] += cvalue_then; if(to_sub) account_month[trans->toAccount()->topAccount()][*monthdate] += cvalue_then; update_month_display = true; } if(update_value_display && update_month_display) { updateMonthlyBudget(trans->toAccount()); if(to_sub) updateMonthlyBudget(trans->toAccount()->topAccount()); updateTotalMonthlyExpensesBudget(); } account_value[trans->toAccount()] += cvalue_then; if(to_sub) account_value[trans->toAccount()->topAccount()] += cvalue_then; expenses_accounts_value += cvalue_then; if(!b_filter) { account_change[trans->toAccount()] += cvalue_then; if(to_sub) account_change[trans->toAccount()->topAccount()] += cvalue_then; expenses_accounts_change += cvalue_then; if(update_value_display) { expensesItem->setText(CHANGE_COLUMN, budget->formatMoney(expenses_accounts_change)); setAccountChangeColor(expensesItem, expenses_accounts_change, true); } } if(update_value_display) { expensesItem->setText(VALUE_COLUMN, budget->formatMoney(expenses_accounts_value) + " "); } break; } case ACCOUNT_TYPE_INCOMES: { balto = (trans->toAccount() == budget->null_incomes_account); if(b_lastmonth) { account_month_endlast[trans->toAccount()] -= cvalue_then; if(to_sub) account_month_endlast[trans->toAccount()->topAccount()] -= cvalue_then; account_month[trans->toAccount()][*monthdate] -= cvalue_then; if(to_sub) account_month[trans->toAccount()->topAccount()][*monthdate] -= cvalue_then; if(update_value_display) { updateMonthlyBudget(trans->toAccount()); if(to_sub) updateMonthlyBudget(trans->toAccount()->topAccount()); updateTotalMonthlyIncomesBudget(); } break; } bool update_month_display = false; if(b_firstmonth) { account_month_beginfirst[trans->toAccount()] -= cvalue_then; if(to_sub) account_month_beginfirst[trans->toAccount()->topAccount()] -= cvalue_then; update_month_display = true; } if(b_curmonth) { account_month_begincur[trans->toAccount()] -= cvalue_then; if(to_sub) account_month_begincur[trans->toAccount()->topAccount()] -= cvalue_then; update_month_display = true; } if(b_future || (!frommonth_begin.isNull() && transdate >= frommonth_begin) || (!prevmonth_begin.isNull() && transdate >= prevmonth_begin)) { account_month[trans->toAccount()][*monthdate] -= cvalue_then; if(to_sub) account_month[trans->toAccount()->topAccount()][*monthdate] -= cvalue_then; update_month_display = true; } if(update_value_display && update_month_display) { updateMonthlyBudget(trans->toAccount()); if(to_sub) updateMonthlyBudget(trans->toAccount()->topAccount()); updateTotalMonthlyIncomesBudget(); } account_value[trans->toAccount()] -= cvalue_then; incomes_accounts_value -= cvalue_then; if(!b_filter) { account_change[trans->toAccount()] -= cvalue_then; if(to_sub) account_change[trans->toAccount()->topAccount()] -= cvalue_then; incomes_accounts_change -= value; if(update_value_display) { incomesItem->setText(CHANGE_COLUMN, budget->formatMoney(incomes_accounts_change)); setAccountChangeColor(incomesItem, incomes_accounts_change, false); } } if(update_value_display) { incomesItem->setText(VALUE_COLUMN, budget->formatMoney(incomes_accounts_value) + " "); } break; } case ACCOUNT_TYPE_ASSETS: { if(b_lastmonth) break; if(((AssetsAccount*) trans->toAccount())->accountType() == ASSETS_TYPE_SECURITIES) { if(update_value_display) { updateSecurityAccount((AssetsAccount*) trans->toAccount(), false); assetsItem->setText(VALUE_COLUMN, budget->formatMoney(assets_accounts_value) + " "); assetsItem->setText(CHANGE_COLUMN, budget->formatMoney(assets_accounts_change)); setAccountChangeColor(assetsItem, assets_accounts_change, false); QString s_group = ((AssetsAccount*) trans->toAccount())->group(); if(item_assets_groups.contains(s_group)) { item_assets_groups[s_group]->setText(VALUE_COLUMN, budget->formatMoney(assets_group_value[s_group]) + " "); item_assets_groups[s_group]->setText(CHANGE_COLUMN, budget->formatMoney(assets_group_change[s_group])); setAccountChangeColor(item_assets_groups[s_group], assets_group_change[s_group], false); } item_accounts[trans->toAccount()]->setText(CHANGE_COLUMN, trans->toAccount()->currency()->formatValue(account_change[trans->toAccount()])); setAccountChangeColor(item_accounts[trans->toAccount()], account_change[trans->toAccount()], false); } break; } balto = (trans->toAccount() == budget->balancingAccount); if(!balto) { to_is_debt = IS_DEBT(((AssetsAccount*) trans->toAccount())); account_value[trans->toAccount()] += value; if(to_is_debt) liabilities_accounts_value += cvalue; else assets_accounts_value += cvalue; QString s_group = ((AssetsAccount*) trans->toAccount())->group(); if(to_is_debt) liabilities_group_value[s_group] += cvalue; else assets_group_value[s_group] += cvalue; if(!b_filter) { account_change[trans->toAccount()] += value; if(to_is_debt) liabilities_accounts_change += cvalue; else assets_accounts_change += cvalue; if(to_is_debt) liabilities_group_change[s_group] += cvalue; else assets_group_change[s_group] += cvalue; if(update_value_display) { if(to_is_debt) { liabilitiesItem->setText(CHANGE_COLUMN, budget->formatMoney(-liabilities_accounts_change)); setAccountChangeColor(liabilitiesItem, -liabilities_accounts_change, true); item_accounts[trans->toAccount()]->setText(CHANGE_COLUMN, trans->toAccount()->currency()->formatValue(-account_change[trans->toAccount()])); setAccountChangeColor(item_accounts[trans->toAccount()], -account_change[trans->toAccount()], true); } else { assetsItem->setText(CHANGE_COLUMN, budget->formatMoney(assets_accounts_change)); setAccountChangeColor(assetsItem, assets_accounts_change, false); item_accounts[trans->toAccount()]->setText(CHANGE_COLUMN, trans->toAccount()->currency()->formatValue(account_change[trans->toAccount()])); setAccountChangeColor(item_accounts[trans->toAccount()], account_change[trans->toAccount()], false); } bool b_hide = trans->toAccount()->isClosed() && is_zero(account_change[trans->toAccount()]) && is_zero(account_value[trans->toAccount()]); if(b_hide != item_accounts[trans->toAccount()]->isHidden()) { item_accounts[trans->toAccount()]->setHidden(b_hide); if(b_hide) assetsAccountItemHiddenOrRemoved((AssetsAccount*) trans->toAccount()); else assetsAccountItemShownOrAdded((AssetsAccount*) trans->toAccount()); } if(!to_is_debt && item_assets_groups.contains(s_group)) { item_assets_groups[s_group]->setText(CHANGE_COLUMN, budget->formatMoney(assets_group_change[s_group])); setAccountChangeColor(item_assets_groups[s_group], assets_group_change[s_group], false); } else if(to_is_debt && item_liabilities_groups.contains(s_group)) { item_liabilities_groups[s_group]->setText(CHANGE_COLUMN, budget->formatMoney(-liabilities_group_change[s_group])); setAccountChangeColor(item_liabilities_groups[s_group], -liabilities_group_change[s_group], true); } } } if(update_value_display) { if(to_is_debt) liabilitiesItem->setText(VALUE_COLUMN, budget->formatMoney(-liabilities_accounts_value) + " "); else assetsItem->setText(VALUE_COLUMN, budget->formatMoney(assets_accounts_value) + " "); if(!to_is_debt && item_assets_groups.contains(s_group)) item_assets_groups[s_group]->setText(VALUE_COLUMN, budget->formatMoney(assets_group_value[s_group]) + " "); else if(to_is_debt && item_liabilities_groups.contains(s_group)) item_liabilities_groups[s_group]->setText(VALUE_COLUMN, budget->formatMoney(-liabilities_group_value[s_group]) + " "); } } break; } } if(trans->toAccount()->type() == ACCOUNT_TYPE_EXPENSES || trans->toAccount()->type() == ACCOUNT_TYPE_INCOMES) { for(int i = 0; ; i++) { const QString &tag = trans->getTag(i, true); if(tag.isEmpty()) break; tag_value[tag] -= cvalue_then; if(!b_filter) tag_change[tag] -= cvalue_then; if(update_value_display) { item_tags[tag]->setText(VALUE_COLUMN, budget->formatMoney(tag_value[tag]) + " "); if(!b_filter) { item_tags[tag]->setText(CHANGE_COLUMN, budget->formatMoney(tag_change[tag])); setAccountChangeColor(item_tags[tag], tag_change[tag], false); } } } } if(update_value_display && !b_lastmonth) { if(!balfrom) { item_accounts[trans->fromAccount()]->setText(VALUE_COLUMN, trans->fromAccount()->currency()->formatValue(from_is_debt ? -account_value[trans->fromAccount()] : account_value[trans->fromAccount()]) + " "); item_accounts[trans->fromAccount()]->setText(CHANGE_COLUMN, trans->fromAccount()->currency()->formatValue(from_is_debt ? -account_change[trans->fromAccount()] : account_change[trans->fromAccount()])); setAccountChangeColor(item_accounts[trans->fromAccount()], from_is_debt ? -account_change[trans->fromAccount()] : account_change[trans->fromAccount()], from_is_debt || trans->fromAccount()->type() == ACCOUNT_TYPE_EXPENSES); bool b_hide = trans->fromAccount()->isClosed() && is_zero(account_change[trans->fromAccount()]) && is_zero(account_value[trans->fromAccount()]); if(b_hide != item_accounts[trans->fromAccount()]->isHidden()) { item_accounts[trans->fromAccount()]->setHidden(b_hide); if(b_hide) assetsAccountItemHiddenOrRemoved((AssetsAccount*) trans->fromAccount()); else assetsAccountItemShownOrAdded((AssetsAccount*) trans->fromAccount()); } if(from_sub) { item_accounts[trans->fromAccount()->topAccount()]->setText(VALUE_COLUMN, trans->fromAccount()->topAccount()->currency()->formatValue(account_value[trans->fromAccount()->topAccount()]) + " "); item_accounts[trans->fromAccount()->topAccount()]->setText(CHANGE_COLUMN, trans->fromAccount()->topAccount()->currency()->formatValue(account_change[trans->fromAccount()->topAccount()])); setAccountChangeColor(item_accounts[trans->fromAccount()->topAccount()], account_change[trans->fromAccount()->topAccount()], trans->fromAccount()->topAccount()->type() == ACCOUNT_TYPE_EXPENSES); } } if(!balto) { item_accounts[trans->toAccount()]->setText(VALUE_COLUMN, trans->toAccount()->currency()->formatValue(to_is_debt ? -account_value[trans->toAccount()] : account_value[trans->toAccount()]) + " "); item_accounts[trans->toAccount()]->setText(CHANGE_COLUMN, trans->toAccount()->currency()->formatValue(to_is_debt ? -account_change[trans->toAccount()] : account_change[trans->toAccount()])); setAccountChangeColor(item_accounts[trans->toAccount()], to_is_debt ? -account_change[trans->toAccount()] : account_change[trans->toAccount()], to_is_debt || trans->toAccount()->type() == ACCOUNT_TYPE_EXPENSES); bool b_hide = trans->toAccount()->isClosed() && is_zero(account_change[trans->toAccount()]) && is_zero(account_value[trans->toAccount()]); if(b_hide != item_accounts[trans->toAccount()]->isHidden()) { item_accounts[trans->toAccount()]->setHidden(b_hide); if(b_hide) assetsAccountItemHiddenOrRemoved((AssetsAccount*) trans->toAccount()); else assetsAccountItemShownOrAdded((AssetsAccount*) trans->toAccount()); } if(to_sub) { item_accounts[trans->toAccount()->topAccount()]->setText(VALUE_COLUMN, trans->toAccount()->topAccount()->currency()->formatValue(account_value[trans->toAccount()->topAccount()]) + " "); item_accounts[trans->toAccount()->topAccount()]->setText(CHANGE_COLUMN, trans->toAccount()->topAccount()->currency()->formatValue(account_change[trans->toAccount()->topAccount()])); setAccountChangeColor(item_accounts[trans->toAccount()->topAccount()], account_change[trans->toAccount()->topAccount()], trans->toAccount()->topAccount()->type() == ACCOUNT_TYPE_EXPENSES); } } } } void Eqonomize::updateTotalMonthlyExpensesBudget() { if(budget->expensesAccounts.count() > 0) { expenses_budget = 0.0; expenses_budget_diff = 0.0; bool b_budget = false; for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) { ExpensesAccount *eaccount = *it; if(!eaccount->parentCategory()) { double d = account_budget[eaccount]; if(d >= 0.0) { expenses_budget += d; expenses_budget_diff += account_budget_diff[eaccount]; b_budget = true; } } } if(b_budget) { expensesItem->setText(BUDGET_COLUMN, tr("%2 of %1", "%1: budget; %2: remaining budget").arg(budget->formatMoney(expenses_budget)).arg(budget->formatMoney(expenses_budget_diff))); setAccountBudgetColor(expensesItem, expenses_budget_diff, true); return; } else { expenses_budget = -1.0; } } expensesItem->setText(BUDGET_COLUMN, "-"); setAccountBudgetColor(expensesItem, 0.0, true); } void Eqonomize::updateTotalMonthlyIncomesBudget() { if(budget->incomesAccounts.count() > 0) { incomes_budget = 0.0; incomes_budget_diff = 0.0; bool b_budget = false; for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) { IncomesAccount *iaccount = *it; double d = account_budget[iaccount]; if(d >= 0.0) { incomes_budget += d; incomes_budget_diff += account_budget_diff[iaccount]; b_budget = true; } } if(b_budget) { incomesItem->setText(BUDGET_COLUMN, tr("%2 of %1", "%1: budget; %2: remaining budget").arg(budget->formatMoney(incomes_budget)).arg(budget->formatMoney(incomes_budget_diff))); setAccountBudgetColor(incomesItem, incomes_budget_diff, false); return; } else { incomes_budget = -1.0; } } incomesItem->setText(BUDGET_COLUMN, "-"); setAccountBudgetColor(incomesItem, 0.0, false); } struct budget_info { QMap::const_iterator it; QMap::const_iterator it_n; QMap::const_iterator it_e; CategoryAccount *ca; bool after_from; }; void Eqonomize::updateMonthlyBudget(Account *account) { if(account->type() == ACCOUNT_TYPE_ASSETS) return; CategoryAccount *ca = (CategoryAccount*) account; double mbudget = 0.0; QTreeWidgetItem *i = item_accounts[account]; QMap::iterator it = ca->mbudgets.begin(); QMap::iterator it_e = ca->mbudgets.end(); QVector subs; while(it != it_e && it.value() < 0.0) ++it; QMap::const_iterator tmp_it; QMap::const_iterator tmp_it_e; for(AccountList::const_iterator it = ca->subCategories.constBegin(); it != ca->subCategories.constEnd(); ++it) { CategoryAccount *sub = *it; tmp_it = sub->mbudgets.begin(); tmp_it_e = sub->mbudgets.end(); while(tmp_it != tmp_it_e && tmp_it.value() < 0.0) ++tmp_it; if(tmp_it != tmp_it_e && tmp_it.key() <= to_date) { struct budget_info bi; bi.it = tmp_it; bi.it_e = tmp_it_e; bi.ca = sub; subs << bi; } } if(subs.isEmpty() && (it == it_e || budget->monthToBudgetMonth(it.key()) > to_date)) { i->setText(BUDGET_COLUMN, "-"); setAccountBudgetColor(i, 0.0, account->type() == ACCOUNT_TYPE_EXPENSES); account_budget[account] = -1.0; } else { bool after_from = true; QDate monthdate, monthend, curdate = QDate::currentDate(), curmonth, frommonth; frommonth = frommonth_begin; if(it != it_e && accountsPeriodFromButton->isChecked() && frommonth > budget->monthToBudgetMonth(it.key())) { QMap::iterator it_b = ca->mbudgets.begin(); it = it_e; --it; while(it != it_b) { if(frommonth >= budget->monthToBudgetMonth(it.key())) break; --it; } after_from = false; } for(QVector::iterator sit = subs.begin(); sit != subs.end(); ++sit) { if(accountsPeriodFromButton->isChecked() && frommonth > budget->monthToBudgetMonth(sit->it.key())) { QMap::iterator it_b = sit->ca->mbudgets.begin(); sit->it = sit->it_e; --(sit->it); while(sit->it != it_b) { if(frommonth >= budget->monthToBudgetMonth(sit->it.key())) break; --(sit->it); } after_from = false; } } double diff = 0.0, future_diff = 0.0, future_change_diff = 0.0, m = 0.0, v = 0.0; QDate monthlast = budget->firstBudgetDay(to_date); QMap::iterator it_n = it; if(it_n != it_e) ++it_n; for(QVector::iterator sit = subs.begin(); sit != subs.end(); ++sit) { sit->it_n = sit->it; if(sit->it_n != sit->it_e) ++(sit->it_n); } bool has_budget = false, has_subs_budget = false; bool b_firstmonth = !after_from && (monthdate != frommonth); monthdate = frommonth; do { if(it != it_e && budget->monthToBudgetMonth(it.key()) <= monthdate) m = it.value(); else m = -1.0; if(m >= 0.0) { monthend = budget->lastBudgetDay(monthdate); has_budget = true; bool b_lastmonth = (monthlast == monthdate && to_date != monthend); v = account_month[account][monthend]; if(partial_budget && (b_firstmonth || b_lastmonth)) { int days; if(b_firstmonth) days = from_date.daysTo(b_lastmonth ? to_date : monthend); else days = monthdate.daysTo(b_lastmonth ? to_date : monthend); int dim = monthdate.daysTo(monthend) + 1; m = (m * (days + 1)) / dim; if(b_firstmonth) v -= account_month_beginfirst[account]; if(b_lastmonth) v -= account_month_endlast[account]; } mbudget += m; diff += m - v; } else if(!subs.isEmpty()) { monthend = budget->lastBudgetDay(monthdate); bool b_lastmonth = (monthlast == monthdate && to_date != monthend); for(QVector::iterator sit = subs.begin(); sit != subs.end(); ++sit) { if(budget->monthToBudgetMonth(sit->it.key()) <= monthdate) m = sit->it.value(); else m = -1.0; if(m >= 0.0) { has_subs_budget = true; v = account_month[sit->ca][monthend]; if(partial_budget && (b_firstmonth || b_lastmonth)) { int days; if(b_firstmonth) days = from_date.daysTo(b_lastmonth ? to_date : monthend); else days = monthdate.daysTo(b_lastmonth ? to_date : monthend); int dim = monthdate.daysTo(monthend) + 1; m = (m * (days + 1)) / dim; if(b_firstmonth) v -= account_month_beginfirst[sit->ca]; if(b_lastmonth) v -= account_month_endlast[sit->ca]; } mbudget += m; diff += m - v; } } } b_firstmonth = false; budget->addBudgetMonthsSetFirst(monthdate, 1); if(it_n != it_e && monthdate == budget->monthToBudgetMonth(it_n.key())) { it = it_n; ++it_n; } for(QVector::iterator sit = subs.begin(); sit != subs.end(); ++sit) { if(sit->it_n != sit->it_e && monthdate == budget->monthToBudgetMonth(sit->it_n.key())) { sit->it = sit->it_n; ++(sit->it_n); } } } while(monthdate <= monthlast); bool b_future = (curdate < to_date); curdate = curdate.addDays(1); if(b_future && !ca->parentCategory()) { bool after_cur = true; it = ca->mbudgets.begin(); while(it != it_e && it.value() < 0.0) ++it; if(it != it_e) { if(curdate < budget->monthToBudgetMonth(it.key())) { curmonth = budget->monthToBudgetMonth(it.key()); after_cur = true; } else { curmonth = budget->monthToBudgetMonth(curdate); QMap::const_iterator it_b = ca->mbudgets.begin(); it = it_e; --it; while(it != it_b) { if(curmonth >= budget->monthToBudgetMonth(it.key())) break; --it; } after_cur = false; } } it_n = it; if(it_n != it_e) ++it_n; for(QVector::iterator sit = subs.begin(); sit != subs.end(); ++sit) { sit->it = sit->ca->mbudgets.begin(); while(sit->it != sit->it_e && sit->it.value() < 0.0) ++(sit->it); if(curdate < budget->monthToBudgetMonth(sit->it.key())) { if(after_cur && curmonth > budget->monthToBudgetMonth(sit->it.key())) curmonth = budget->monthToBudgetMonth(sit->it.key()); } else { if(after_cur) curmonth = budget->monthToBudgetMonth(curdate); QMap::const_iterator it_b = sit->ca->mbudgets.begin(); sit->it = sit->it_e; --(sit->it); while(sit->it != it_b) { if(curmonth >= budget->monthToBudgetMonth(sit->it.key())) break; --(sit->it); } after_cur = false; } sit->it_n = sit->it; if(sit->it_n != sit->it_e) ++(sit->it_n); } bool had_from = after_from || from_date <= curdate; bool b_curmonth = !after_cur && (curmonth != curdate); do { if(it != it_e && budget->monthToBudgetMonth(it.key()) <= curmonth) m = it.value(); else m = -1.0; if(m >= 0.0) { monthend = budget->lastBudgetDay(curmonth); v = account_month[account][monthend]; bool b_lastmonth = (monthlast == curmonth && to_date != monthend); bool b_frommonth = !had_from && frommonth == curmonth; int dim = curmonth.daysTo(monthend) + 1; if(partial_budget && (b_curmonth || b_lastmonth || b_frommonth)) { int days; if(b_curmonth) { v -= account_month_begincur[account]; days = curdate.daysTo(b_lastmonth ? to_date : monthend); } else { days = curmonth.daysTo(b_lastmonth ? to_date : monthend); } if(b_lastmonth) v -= account_month_endlast[account]; m = (m * (days + 1)) / dim; if(b_frommonth) { int days2; if(b_curmonth) days2 = curdate.daysTo(from_date); else days2 = curmonth.daysTo(from_date); double v3 = b_curmonth ? (account_month_beginfirst[account] - account_month_begincur[account]) : account_month_beginfirst[account]; double m3 = ((m - v) * (days2 + 1)) / (days + 1); if(v3 > m3) m3 = v3; double m2 = m - m3; double v2 = v - v3; if(m2 > v2) future_change_diff += m2 - v2; } } else if(b_frommonth) { int days, days2; if(b_lastmonth) { v -= account_month_endlast[account]; m = (m * curmonth.daysTo(to_date)) / dim; } if(b_curmonth) { days = curdate.daysTo(b_lastmonth ? to_date : monthend); days2 = curdate.daysTo(from_date); } else { days = curmonth.daysTo(b_lastmonth ? to_date : monthend); days2 = curmonth.daysTo(from_date); } double v3 = b_curmonth ? (account_month_beginfirst[account] - account_month_begincur[account]) : account_month_beginfirst[account]; double m3 = ((m - v) * (days2 + 1)) / (days + 1); if(v3 > m3) m3 = v3; double m2 = m - v - m3; double v2 = v - account_month_beginfirst[account]; if(m2 > v2) future_change_diff += m2 - v2; } else if(b_lastmonth) { v -= account_month_endlast[account]; m = (m * curmonth.daysTo(to_date)) / dim; } if(m > v) { future_diff += m - v; if(had_from) future_change_diff += m - v; } if(b_frommonth) had_from = true; } else if(!subs.isEmpty()) { monthend = budget->lastBudgetDay(curmonth); bool b_lastmonth = (monthlast == monthdate && to_date != monthend); bool b_frommonth = !had_from && frommonth == curmonth; for(QVector::iterator sit = subs.begin(); sit != subs.end(); ++sit) { if(budget->monthToBudgetMonth(sit->it.key()) <= curmonth) m = sit->it.value(); else m = -1.0; if(m >= 0.0) { v = account_month[sit->ca][monthend]; int dim = curmonth.daysTo(monthend) + 1; if(partial_budget && (b_curmonth || b_lastmonth || b_frommonth)) { int days; if(b_curmonth) { v -= account_month_begincur[sit->ca]; days = curdate.daysTo(b_lastmonth ? to_date : monthend); } else { days = curmonth.daysTo(b_lastmonth ? to_date : monthend); } if(b_lastmonth) v -= account_month_endlast[sit->ca]; m = (m * (days + 1)) / dim; if(b_frommonth) { int days2; if(b_curmonth) days2 = curdate.daysTo(from_date); else days2 = curmonth.daysTo(from_date); double v3 = b_curmonth ? (account_month_beginfirst[sit->ca] - account_month_begincur[sit->ca]) : account_month_beginfirst[sit->ca]; double m3 = ((m - v) * (days2 + 1)) / (days + 1); if(v3 > m3) m3 = v3; double m2 = m - m3; double v2 = v - v3; if(m2 > v2) future_change_diff += m2 - v2; } } else if(b_frommonth) { int days, days2; if(b_lastmonth) { v -= account_month_endlast[sit->ca]; m = (m * curmonth.daysTo(to_date)) / dim; } if(b_curmonth) { days = curdate.daysTo(b_lastmonth ? to_date : monthend); days2 = curdate.daysTo(from_date); } else { days = curmonth.daysTo(b_lastmonth ? to_date : monthend); days2 = curmonth.daysTo(from_date); } double v3 = b_curmonth ? (account_month_beginfirst[sit->ca] - account_month_begincur[sit->ca]) : account_month_beginfirst[sit->ca]; double m3 = ((m - v) * (days2 + 1)) / (days + 1); if(v3 > m3) m3 = v3; double m2 = m - v - m3; double v2 = v - account_month_beginfirst[sit->ca]; if(m2 > v2) future_change_diff += m2 - v2; } else if(b_lastmonth) { v -= account_month_endlast[sit->ca]; m = (m * curmonth.daysTo(to_date)) / dim; } if(m > v) { future_diff += m - v; if(had_from) future_change_diff += m - v; } if(b_frommonth) had_from = true; } } } b_curmonth = false; budget->addBudgetMonthsSetFirst(curmonth, 1); if(it_n != it_e && curmonth == budget->monthToBudgetMonth(it_n.key())) { it = it_n; ++it_n; } for(QVector::iterator sit = subs.begin(); sit != subs.end(); ++sit) { if(sit->it_n != sit->it_e && curmonth == budget->monthToBudgetMonth(sit->it_n.key())) { sit->it = sit->it_n; ++(sit->it_n); } } } while(curmonth <= monthlast); } if(has_budget || has_subs_budget) { if(has_budget) i->setText(BUDGET_COLUMN, tr("%2 of %1", "%1: budget; %2: remaining budget").arg(budget->formatMoney(mbudget)).arg(budget->formatMoney(diff))); else i->setText(BUDGET_COLUMN, QString("(") + tr("%2 of %1", "%1: budget; %2: remaining budget").arg(budget->formatMoney(mbudget)).arg(budget->formatMoney(diff)) + QString(")")); setAccountBudgetColor(i, diff, account->type() == ACCOUNT_TYPE_EXPENSES); account_budget[account] = mbudget; account_budget_diff[account] = diff; } else { i->setText(BUDGET_COLUMN, "-"); account_budget[account] = -1.0; } double future_diff_bak = future_diff, future_diff_change_bak = future_change_diff; future_diff -= account_future_diff[account]; future_change_diff -= account_future_diff_change[account]; account_future_diff[account] = future_diff_bak; account_future_diff_change[account] = future_diff_change_bak; if(is_zero(future_diff) && is_zero(future_change_diff)) return; if(budget->budgetAccount) { if(account->type() == ACCOUNT_TYPE_EXPENSES) { account_value[budget->budgetAccount] -= budget->budgetAccount->currency()->convertFrom(future_diff, budget->defaultCurrency()); account_change[budget->budgetAccount] -= budget->budgetAccount->currency()->convertFrom(future_change_diff, budget->defaultCurrency()); } else { account_value[budget->budgetAccount] += budget->budgetAccount->currency()->convertFrom(future_diff, budget->defaultCurrency()); account_change[budget->budgetAccount] += budget->budgetAccount->currency()->convertFrom(future_change_diff, budget->defaultCurrency()); } item_accounts[budget->budgetAccount]->setText(CHANGE_COLUMN, budget->budgetAccount->currency()->formatValue(account_change[budget->budgetAccount])); item_accounts[budget->budgetAccount]->setText(VALUE_COLUMN, budget->budgetAccount->currency()->formatValue(account_value[budget->budgetAccount]) + " "); setAccountChangeColor(item_accounts[budget->budgetAccount], account_value[budget->budgetAccount], false); QString s_group = budget->budgetAccount->group(); if(account->type() == ACCOUNT_TYPE_EXPENSES) { assets_group_value[s_group] -= future_diff; assets_group_change[s_group] -= future_change_diff; } else { assets_group_value[s_group] += future_diff; assets_group_change[s_group] += future_change_diff; } if(item_assets_groups.contains(s_group)) { item_assets_groups[s_group]->setText(VALUE_COLUMN, budget->formatMoney(assets_group_value[s_group]) + " "); item_assets_groups[s_group]->setText(CHANGE_COLUMN, budget->formatMoney(assets_group_change[s_group])); setAccountChangeColor(item_assets_groups[s_group], assets_group_change[s_group], false); } } if(account->type() == ACCOUNT_TYPE_EXPENSES) { assets_accounts_value -= future_diff; assets_accounts_change -= future_change_diff; } else { assets_accounts_value += future_diff; assets_accounts_change += future_change_diff; } assetsItem->setText(VALUE_COLUMN, budget->formatMoney(assets_accounts_value) + " "); assetsItem->setText(CHANGE_COLUMN, budget->formatMoney(assets_accounts_change)); setAccountChangeColor(assetsItem, assets_accounts_change, false); } if(item_accounts[account] == selectedItem(accountsView)) updateBudgetEdit(); } void Eqonomize::updateBudgetEdit() { QTreeWidgetItem *i = selectedItem(accountsView); budgetEdit->blockSignals(true); budgetButton->blockSignals(true); if(i == NULL || i == liabilitiesItem || i == assetsItem || i == incomesItem || i == tagsItem || i == expensesItem || !account_items.contains(i) || account_items[i]->type() == ACCOUNT_TYPE_ASSETS) { budgetEdit->setEnabled(false); budgetButton->setEnabled(false); if(i == incomesItem || i == expensesItem) { QDate tomonth, prevmonth, prevmonth_end; tomonth = budget->budgetDateToMonth(to_date); prevmonth = budget->budgetDateToMonth(prevmonth_begin); prevmonth_end = prevmonth_begin.addDays(budget->daysInBudgetMonth(prevmonth_begin) - 1); double d_to = 0.0, d_prev = 0.0, v_prev = 0.0; CategoryAccount *ca = NULL; bool b_budget = false, b_budget_prev = false; AccountList::const_iterator it_e = budget->expensesAccounts.constBegin(); AccountList::const_iterator it_i = budget->incomesAccounts.constBegin(); while((i == incomesItem && it_i != budget->incomesAccounts.constEnd()) || (i != incomesItem && it_e != budget->expensesAccounts.constEnd())) { if(i == incomesItem) { ca = *it_i; ++it_i; } else { ca = *it_e; ++it_e; } double d = ca->monthlyBudget(tomonth); if(d >= 0.0) { d_to += d; b_budget = true; } d = ca->monthlyBudget(prevmonth); if(d >= 0.0) { d_prev += d; b_budget_prev = true; v_prev += account_month[ca][prevmonth_end]; } } if(!b_budget_prev) { it_e = budget->expensesAccounts.constBegin(); it_i = budget->incomesAccounts.constBegin(); while((i == incomesItem && it_i != budget->incomesAccounts.constEnd()) || (i != incomesItem && it_e != budget->expensesAccounts.constEnd())) { if(i == incomesItem) { ca = *it_i; ++it_i; } else { ca = *it_e; ++it_e; } v_prev += account_month[ca][prevmonth_end]; } } if(!b_budget_prev) prevMonthBudgetLabel->setText(tr("%1 (with no budget)").arg(budget->formatMoney(v_prev))); else prevMonthBudgetLabel->setText(tr("%1 (with budget %2)").arg(budget->formatMoney(v_prev)).arg(budget->formatMoney(d_prev))); budgetButton->setChecked(b_budget); if(budgetEdit->value() != d_to) budgetEdit->setValue(d_to); } else { if(budgetEdit->value() != 0.0) budgetEdit->setValue(0.0); budgetButton->setChecked(false); prevMonthBudgetLabel->setText("-"); } } else { CategoryAccount *ca = (CategoryAccount*) account_items[i]; QDate tomonth = budget->budgetDateToMonth(to_date); double d = ca->monthlyBudget(tomonth); if(d < 0.0) { if(budgetEdit->value() != 0.0) budgetEdit->setValue(0.0); budgetButton->setChecked(false); budgetEdit->setEnabled(false); } else { if(budgetEdit->value() != d) budgetEdit->setValue(d); budgetButton->setChecked(true); budgetEdit->setEnabled(true); } budgetButton->setEnabled(true); d = ca->monthlyBudget(budget->budgetDateToMonth(prevmonth_begin)); if(d < 0.0) prevMonthBudgetLabel->setText(tr("%1 (with no budget)").arg(budget->formatMoney(account_month[ca][prevmonth_begin.addDays(budget->daysInBudgetMonth(prevmonth_begin) - 1)]))); else prevMonthBudgetLabel->setText(tr("%1 (with budget %2)").arg(budget->formatMoney(account_month[ca][prevmonth_begin.addDays(budget->daysInBudgetMonth(prevmonth_begin) - 1)])).arg(budget->formatMoney(d))); } budgetEdit->blockSignals(false); budgetButton->blockSignals(false); } void Eqonomize::accountsSelectionChanged() { QTreeWidgetItem *i = selectedItem(accountsView); if(account_items.contains(i)) { ActionDeleteAccount->setEnabled(true); ActionEditAccount->setEnabled(true); ActionCloseAccount->setEnabled(true); ActionBalanceAccount->setEnabled(account_items[i]->type() == ACCOUNT_TYPE_ASSETS && !((AssetsAccount*) account_items[i])->isSecurities()); ActionReconcileAccount->setEnabled(account_items[i]->type() == ACCOUNT_TYPE_ASSETS && !((AssetsAccount*) account_items[i])->isSecurities()); if(account_items[i]->type() == ACCOUNT_TYPE_ASSETS && ((AssetsAccount*) account_items[i])->isClosed()) { ActionCloseAccount->setEnabled(account_items[i]->type() == ACCOUNT_TYPE_ASSETS); ActionCloseAccount->setText(tr("Reopen Account", "Mark account as not closed")); ActionCloseAccount->setIcon(LOAD_ICON("edit-undo")); } else { ActionCloseAccount->setEnabled(account_items[i]->type() == ACCOUNT_TYPE_ASSETS && budget->accountHasTransactions(account_items[i])); ActionCloseAccount->setText(tr("Close Account", "Mark account as closed")); ActionCloseAccount->setIcon(LOAD_ICON("edit-delete")); } } else { ActionDeleteAccount->setEnabled(false); ActionCloseAccount->setEnabled(false); ActionEditAccount->setEnabled(false); ActionBalanceAccount->setEnabled(false); budgetEdit->setEnabled(false); ActionReconcileAccount->setEnabled(false); } if(tag_items.contains(i)) { ActionRenameTag->setEnabled(true); ActionRemoveTag->setEnabled(true); } else { ActionRenameTag->setEnabled(false); ActionRemoveTag->setEnabled(false); } ActionShowAccountTransactions->setEnabled(i != NULL && i != tagsItem && i != assetsItem && i != liabilitiesItem && !assets_group_items.contains(i) && !liabilities_group_items.contains(i)); updateBudgetEdit(); } void Eqonomize::updateSecurityAccount(AssetsAccount *account, bool update_display) { double value = 0.0, value_from = 0.0; bool b_from = accountsPeriodFromButton->isChecked(); for(SecurityList::const_iterator it = budget->securities.constBegin(); it != budget->securities.constEnd(); ++it) { Security *security = *it; if(security->account() == account) { value += security->value(to_date, -1); if(b_from) value_from += security->value(from_date, -1); } } if(!b_from) { value_from = account->initialBalance(); } assets_accounts_value -= account->currency()->convertTo(account_value[account], budget->defaultCurrency(), to_date); assets_accounts_value += account->currency()->convertTo(value, budget->defaultCurrency(), to_date); assets_accounts_change -= account->currency()->convertTo(account_change[account], budget->defaultCurrency(), to_date); assets_accounts_change += account->currency()->convertTo((value - value_from), budget->defaultCurrency(), to_date); QString s_group = account->group(); assets_group_value[s_group] -= account->currency()->convertTo(account_value[account], budget->defaultCurrency(), to_date); assets_group_value[s_group] += account->currency()->convertTo(value, budget->defaultCurrency(), to_date); assets_group_change[s_group] -= account->currency()->convertTo(account_change[account], budget->defaultCurrency(), to_date); assets_group_change[s_group] += account->currency()->convertTo((value - value_from), budget->defaultCurrency(), to_date); account_value[account] = value; account_change[account] = value - value_from; if(update_display) { assetsItem->setText(VALUE_COLUMN, budget->formatMoney(assets_accounts_value) + " "); assetsItem->setText(CHANGE_COLUMN, budget->formatMoney(assets_accounts_change)); setAccountChangeColor(assetsItem, assets_accounts_change, false); item_accounts[account]->setText(CHANGE_COLUMN, account->currency()->formatValue(value - value_from)); item_accounts[account]->setText(VALUE_COLUMN, account->currency()->formatValue(value) + " "); setAccountChangeColor(item_accounts[account], value - value_from, false); bool b_hide = account->isClosed() && is_zero(value) && is_zero(value_from); if(b_hide != item_accounts[account]->isHidden()) { item_accounts[account]->setHidden(b_hide); if(b_hide) assetsAccountItemHiddenOrRemoved(account); else assetsAccountItemShownOrAdded(account); } if(item_assets_groups.contains(s_group)) { item_assets_groups[s_group]->setText(VALUE_COLUMN, budget->formatMoney(assets_group_value[s_group]) + " "); item_assets_groups[s_group]->setText(CHANGE_COLUMN, budget->formatMoney(assets_group_change[s_group])); setAccountChangeColor(item_assets_groups[s_group], assets_group_change[s_group], false); } } } void Eqonomize::filterAccounts() { expenses_accounts_value = 0.0; expenses_accounts_change = 0.0; incomes_accounts_value = 0.0; incomes_accounts_change = 0.0; assets_accounts_value = 0.0; assets_accounts_change = 0.0; liabilities_accounts_value = 0.0; liabilities_accounts_change = 0.0; incomes_budget = 0.0; incomes_budget_diff = 0.0; expenses_budget = 0.0; expenses_budget_diff = 0.0; assets_group_value.clear(); assets_group_change.clear(); assets_group_value[""] = 0.0; assets_group_change[""] = 0.0; liabilities_group_value.clear(); liabilities_group_change.clear(); liabilities_group_value[""] = 0.0; liabilities_group_change[""] = 0.0; tag_value.clear(); tag_change.clear(); for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { AssetsAccount *aaccount = *it; QString s_group = aaccount->group(); bool is_debt = IS_DEBT(aaccount); if(is_debt && !liabilities_group_value.contains(s_group)) { liabilities_group_value[s_group] = 0.0; liabilities_group_change[s_group] = 0.0; } else if(!is_debt && !assets_group_value.contains(s_group)) { assets_group_value[s_group] = 0.0; assets_group_change[s_group] = 0.0; } if(aaccount->isSecurities()) { account_value[aaccount] = 0.0; account_change[aaccount] = 0.0; updateSecurityAccount(aaccount, false); } else { account_value[aaccount] = aaccount->initialBalance(); account_change[aaccount] = 0.0; if(is_debt) liabilities_accounts_value += aaccount->currency()->convertTo(account_value[aaccount], budget->defaultCurrency(), to_date); else assets_accounts_value += aaccount->currency()->convertTo(account_value[aaccount], budget->defaultCurrency(), to_date); if(is_debt) liabilities_group_value[s_group] += aaccount->currency()->convertTo(account_value[aaccount], budget->defaultCurrency(), to_date); else assets_group_value[s_group] += aaccount->currency()->convertTo(account_value[aaccount], budget->defaultCurrency(), to_date); } } QDate monthdate, monthdate_begin; bool b_from = accountsPeriodFromButton->isChecked(); QDate lastmonth = budget->lastBudgetDay(to_date); QDate curdate = QDate::currentDate(), curmonth, curmonth_begin; curmonth_begin = budget->firstBudgetDay(curdate); prevmonth_begin = budget->firstBudgetDay(to_date); budget->addBudgetMonthsSetFirst(prevmonth_begin, -1); curmonth = budget->lastBudgetDay(curdate); frommonth_begin = QDate(); for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) { IncomesAccount *iaccount = *it; account_value[iaccount] = 0.0; account_change[iaccount] = 0.0; account_month[iaccount] = QMap(); account_month[iaccount][monthdate] = 0.0; account_budget[iaccount] = -1.0; account_budget_diff[iaccount] = 0.0; account_month_beginfirst[iaccount] = 0.0; account_month_begincur[iaccount] = 0.0; account_month_endlast[iaccount] = 0.0; account_future_diff[iaccount] = 0.0; account_future_diff_change[iaccount] = 0.0; if(!iaccount->mbudgets.isEmpty() && iaccount->mbudgets.begin().value() >= 0.0 && (frommonth_begin.isNull() || budget->monthToBudgetMonth(iaccount->mbudgets.begin().key()) < frommonth_begin)) { frommonth_begin = budget->monthToBudgetMonth(iaccount->mbudgets.begin().key()); } } for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) { ExpensesAccount *eaccount = *it; account_value[eaccount] = 0.0; account_change[eaccount] = 0.0; account_month[eaccount] = QMap(); account_month[eaccount][monthdate] = 0.0; account_budget[eaccount] = -1.0; account_budget_diff[eaccount] = 0.0; account_month_beginfirst[eaccount] = 0.0; account_month_begincur[eaccount] = 0.0; account_month_endlast[eaccount] = 0.0; account_future_diff[eaccount] = 0.0; account_future_diff_change[eaccount] = 0.0; if(!eaccount->mbudgets.isEmpty() && eaccount->mbudgets.begin().value() >= 0.0 && (frommonth_begin.isNull() || budget->monthToBudgetMonth(eaccount->mbudgets.begin().key()) < frommonth_begin)) { frommonth_begin = budget->monthToBudgetMonth(eaccount->mbudgets.begin().key()); } } for(QStringList::const_iterator it = budget->tags.constBegin(); it != budget->tags.constEnd(); ++it) { tag_value[*it] = 0.0; tag_change[*it] = 0.0; } if(frommonth_begin.isNull() || (b_from && frommonth_begin < from_date)) { if(b_from) frommonth_begin = budget->firstBudgetDay(from_date); else frommonth_begin = curmonth_begin; } if(frommonth_begin.isNull() || frommonth_begin > prevmonth_begin) { monthdate_begin = prevmonth_begin; } else { monthdate_begin = frommonth_begin; } if(monthdate_begin > curmonth_begin) monthdate_begin = curmonth_begin; monthdate = budget->lastBudgetDay(monthdate_begin); bool b_future = false; bool b_past = (curdate >= to_date); updateBudgetAccountTitle(); for(TransactionList::const_iterator it = budget->transactions.constBegin(); it != budget->transactions.constEnd(); ++it) { Transaction *trans = *it; if(trans->date() > lastmonth) break; if(!b_past && !b_future && trans->date() >= curmonth_begin) b_future = true; if(!b_from || b_future || trans->date() >= frommonth_begin || trans->date() >= prevmonth_begin) { while(trans->date() > monthdate) { budget->addBudgetMonthsSetFirst(monthdate_begin, 1); monthdate = budget->lastBudgetDay(monthdate_begin); for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) { IncomesAccount *iaccount = *it; account_month[iaccount][monthdate] = 0.0; } for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) { ExpensesAccount *eaccount = *it; account_month[eaccount][monthdate] = 0.0; } } addTransactionValue(trans, trans->date(), false, false, -1, b_future, &monthdate); } else { addTransactionValue(trans, trans->date(), false, false, -1, b_future, NULL); } } while(lastmonth >= monthdate) { budget->addBudgetMonthsSetFirst(monthdate_begin, 1); monthdate = budget->lastBudgetDay(monthdate_begin); for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) { IncomesAccount *iaccount = *it; account_month[iaccount][monthdate] = 0.0; } for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) { ExpensesAccount *eaccount = *it; account_month[eaccount][monthdate] = 0.0; } } for(ScheduledTransactionList::const_iterator it = budget->scheduledTransactions.constBegin(); it != budget->scheduledTransactions.constEnd(); ++it) { ScheduledTransaction *strans = *it; if(strans->transaction()->date() > lastmonth) break; addScheduledTransactionValue(strans, false, false); } for(QMap::iterator it = account_items.begin(); it != account_items.end(); ++it) { switch(it.value()->type()) { case ACCOUNT_TYPE_INCOMES: {} case ACCOUNT_TYPE_EXPENSES: { updateMonthlyBudget(it.value()); break; } default: {} } } updateTotalMonthlyIncomesBudget(); updateTotalMonthlyExpensesBudget(); for(QMap::iterator it = account_items.begin(); it != account_items.end(); ++it) { bool is_debt = (it.value()->type() == ACCOUNT_TYPE_ASSETS && IS_DEBT((AssetsAccount*) it.value())); it.key()->setText(CHANGE_COLUMN, it.value()->currency()->formatValue(is_debt ? -account_change[it.value()] : account_change[it.value()])); it.key()->setText(VALUE_COLUMN, it.value()->currency()->formatValue(is_debt ? -account_value[it.value()] : account_value[it.value()]) + " "); setAccountChangeColor(it.key(), is_debt ? -account_change[it.value()] : account_change[it.value()], is_debt || it.value()->type() == ACCOUNT_TYPE_EXPENSES); bool b_hide = it.value()->isClosed() && is_zero(account_change[it.value()]) && is_zero(account_value[it.value()]); if(b_hide != it.key()->isHidden()) { it.key()->setHidden(b_hide); if(b_hide) assetsAccountItemHiddenOrRemoved((AssetsAccount*) it.value()); else assetsAccountItemShownOrAdded((AssetsAccount*) it.value()); } } for(QMap::iterator it = assets_group_items.begin(); it != assets_group_items.end(); ++it) { it.key()->setText(CHANGE_COLUMN, budget->formatMoney(assets_group_change[it.value()])); it.key()->setText(VALUE_COLUMN, budget->formatMoney(assets_group_value[it.value()]) + " "); setAccountChangeColor(it.key(), assets_group_change[it.value()], false); } for(QMap::iterator it = liabilities_group_items.begin(); it != liabilities_group_items.end(); ++it) { it.key()->setText(CHANGE_COLUMN, budget->formatMoney(-liabilities_group_change[it.value()])); it.key()->setText(VALUE_COLUMN, budget->formatMoney(-liabilities_group_value[it.value()]) + " "); setAccountChangeColor(it.key(), -liabilities_group_change[it.value()], true); } for(QMap::iterator it = tag_items.begin(); it != tag_items.end(); ++it) { it.key()->setText(CHANGE_COLUMN, budget->formatMoney(tag_change[it.value()])); it.key()->setText(VALUE_COLUMN, budget->formatMoney(tag_value[it.value()]) + " "); setAccountChangeColor(it.key(), tag_change[it.value()], false); } incomesItem->setText(VALUE_COLUMN, budget->formatMoney(incomes_accounts_value) + " "); incomesItem->setText(CHANGE_COLUMN, budget->formatMoney(incomes_accounts_change)); setAccountChangeColor(incomesItem, incomes_accounts_change, false); expensesItem->setText(VALUE_COLUMN, budget->formatMoney(expenses_accounts_value) + " "); expensesItem->setText(CHANGE_COLUMN, budget->formatMoney(expenses_accounts_change)); setAccountChangeColor(expensesItem, expenses_accounts_change, true); assetsItem->setText(VALUE_COLUMN, budget->formatMoney(assets_accounts_value) + " "); assetsItem->setText(CHANGE_COLUMN, budget->formatMoney(assets_accounts_change)); setAccountChangeColor(assetsItem, assets_accounts_change, false); liabilitiesItem->setText(VALUE_COLUMN, budget->formatMoney(-liabilities_accounts_value) + " "); liabilitiesItem->setText(CHANGE_COLUMN, budget->formatMoney(-liabilities_accounts_change)); setAccountChangeColor(liabilitiesItem, -liabilities_accounts_change, true); budgetMonthEdit->blockSignals(true); budgetMonthEdit->setDate(budget->budgetDateToMonth(to_date)); budgetMonthEdit->blockSignals(false); updateBudgetEdit(); } EqonomizeTreeWidget::EqonomizeTreeWidget(QWidget *parent) : QTreeWidget(parent) { setAlternatingRowColors(true); setExpandsOnDoubleClick(false); setItemDelegate(new EqonomizeItemDelegate(this)); } EqonomizeTreeWidget::EqonomizeTreeWidget() : QTreeWidget() {} void EqonomizeTreeWidget::keyPressEvent(QKeyEvent *e) { if((e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) && currentItem()) { emit returnPressed(currentItem()); QTreeWidget::keyPressEvent(e); e->accept(); return; } else if(e->key() == Qt::Key_Space && currentItem()) { emit spacePressed(currentItem()); QTreeWidget::keyPressEvent(e); e->accept(); return; } QTreeWidget::keyPressEvent(e); } void EqonomizeTreeWidget::dropEvent(QDropEvent *event) { #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) QTreeWidgetItem *target = itemAt(event->position().toPoint()); #else QTreeWidgetItem *target = itemAt(event->pos()); #endif if(!target) return; DropIndicatorPosition dropPos = dropIndicatorPosition(); if(dropPos != OnItem) target = target->parent(); QList dragItems = selectedItems(); if(!dragItems.isEmpty() && target) { emit itemMoved(dragItems[0], target); } event->setDropAction(Qt::IgnoreAction); } QIFWizardPage::QIFWizardPage() : QWizardPage() { is_complete = false; } bool QIFWizardPage::isComplete() const {return is_complete;} void QIFWizardPage::setComplete(bool b) {is_complete = b; emit completeChanged();} extern QTranslator translator_qt, translator_qtbase; EqonomizeTranslator::EqonomizeTranslator() : QTranslator() {} QString EqonomizeTranslator::translate(const char *context, const char *sourceText, const char *disambiguation, int n) const { if(!translator_qt.translate(context, sourceText, disambiguation, n).isEmpty() || !translator_qtbase.translate(context, sourceText, disambiguation, n).isEmpty()) return QString(); if(strcmp(context, "EqonomizeTranslator") == 0) return QString(); //: Only used when Qt translation is missing if(strcmp(sourceText, "OK") == 0) return tr("OK"); //: Only used when Qt translation is missing if(strcmp(sourceText, "Cancel") == 0) return tr("Cancel"); //: Only used when Qt translation is missing if(strcmp(sourceText, "Close") == 0) return tr("Close"); //: Only used when Qt translation is missing if(strcmp(sourceText, "&Yes") == 0) return tr("&Yes"); //: Only used when Qt translation is missing if(strcmp(sourceText, "&No") == 0) return tr("&No"); //: Only used when Qt translation is missing if(strcmp(sourceText, "&Open") == 0) return tr("&Open"); //: Only used when Qt translation is missing if(strcmp(sourceText, "&Save") == 0) return tr("&Save"); //: Only used when Qt translation is missing if(strcmp(sourceText, "&Select All") == 0) return tr("&Select All"); //: Only used when Qt translation is missing if(strcmp(sourceText, "Look in:") == 0) return tr("Look in:"); //: Only used when Qt translation is missing if(strcmp(sourceText, "File &name:") == 0) return tr("File &name:"); //: Only used when Qt translation is missing if(strcmp(sourceText, "Files of type:") == 0) return tr("Files of type:"); return QString(); } Eqonomize-1.5.3/src/eqonomize.h000066400000000000000000000702761416454732000164560ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016-2020 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifndef EQONOMIZE_H #define EQONOMIZE_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef LOAD_EQZICONS_FROM_FILE #ifdef RESOURCES_COMPILED #define LOAD_APP_ICON(x) QIcon(ICON_DIR "/EQZ/apps/64x64/" x ".png") #define LOAD_ICON(x) QIcon(ICON_DIR "/EQZ/actions/64x64/" x ".png") #define LOAD_ICON_APP(x) QIcon(ICON_DIR "/EQZ/apps/64x64/" x ".png") #define LOAD_ICON_STATUS(x) QIcon(ICON_DIR "/EQZ/status/64x64/" x ".png") #define LOAD_ICON2(x, y) QIcon(ICON_DIR "/EQZ/actions/64x64/" y ".png") #else #define LOAD_APP_ICON(x) QIcon(ICON_DIR "/hicolor/64x64/apps/" x ".png") #define LOAD_ICON(x) (QString(x).startsWith("eqz") ? QIcon(ICON_DIR "/hicolor/64x64/actions/" x ".png") : QIcon::fromTheme(x)) #define LOAD_ICON_APP(x) QIcon::fromTheme(x) #define LOAD_ICON_STATUS(x) QIcon::fromTheme(x) #define LOAD_ICON2(x, y) (QString(x).startsWith("eqz") ? QIcon(ICON_DIR "/hicolor/64x64/actions/" x ".png") : QIcon::fromTheme(x, QIcon::fromTheme(y))) #endif #else #define LOAD_APP_ICON(x) QIcon::fromTheme(x) #define LOAD_ICON(x) QIcon::fromTheme(x) #define LOAD_ICON_APP(x) QIcon::fromTheme(x) #define LOAD_ICON_STATUS(x) QIcon::fromTheme(x) #define LOAD_ICON2(x, y) QIcon::fromTheme(x, QIcon::fromTheme(y)) #endif class QAction; class QActionGroup; class QButtonGroup; class QCheckBox; class QLabel; class QMenu; class QPushButton; class QRadioButton; class QSpinBox; class QTabWidget; class QVBoxLayout; class QLineEdit; class QCommandLineParser; class QToolBar; class QTabWidget; class QDateEdit; class QTextEdit; class QLocalSocket; class QLocalServer; class QPrinter; class QDialog; class QNetworkReply; class TagMenu; class CategoriesComparisonChart; class CategoriesComparisonReport; class CurrencyConversionDialog; class OverTimeChart; class OverTimeReport; class Account; class AssetsAccount; class CategoryAccount; class ExpensesAccount; class LoanAccount; class Budget; class ConfirmScheduleListViewItem; class EqonomizeMonthSelector; class EqonomizeValueEdit; class Expense; class ExpensesAccount; class Income; class IncomesAccount; class ReinvestedDividend; class ScheduledTransaction; class Security; class SecurityTrade; class SplitTransaction; class Transaction; class Transactions; class TransactionListWidget; class Transfer; class AccountComboBox; class Eqonomize : public QMainWindow { Q_OBJECT public: Eqonomize(); virtual ~Eqonomize(); void sync(bool do_save = true, bool on_load = false, QWidget *parent = NULL); bool saveURL(const QUrl& url, bool do_local_sync = true, bool do_cloud_sync = true, QWidget *parent = NULL); bool saveAs(bool do_local_sync = true, bool do_cloud_sync = true, QWidget *parent = NULL); bool askSave(bool before_exit = false); void createDefaultBudget(); void readFileDependentOptions(); Budget *budget; bool first_run; bool in_batch_edit; void startBatchEdit(); void endBatchEdit(); void appendFilterExpense(Expense *expense, bool update_total_cost, bool update_accounts); void appendFilterIncome(Income *income, bool update_total_income, bool update_accounts); void appendFilterTransfer(Transfer *transfer, bool update_total_amount, bool update_accounts); bool filterTransaction(Transaction *trans); void subtractScheduledTransactionValue(ScheduledTransaction *strans, bool update_value_display); void addScheduledTransactionValue(ScheduledTransaction *strans, bool update_value_display, bool subtract = false); void subtractTransactionValue(Transaction *trans, bool update_value_display); void addTransactionValue(Transaction *trans, const QDate &transdate, bool update_value_display, bool subtract = false, int n = -1, int b_future = -1, const QDate *monthdate = NULL); void appendIncomesAccount(IncomesAccount *account, QTreeWidgetItem *parent_item); void appendExpensesAccount(ExpensesAccount *account, QTreeWidgetItem *parent_item); void assetsAccountItemHiddenOrRemoved(AssetsAccount *account); void assetsAccountItemShownOrAdded(AssetsAccount *account); void appendAssetsAccount(AssetsAccount *account); void appendLoanAccount(LoanAccount *account); void updateMonthlyBudget(Account *account); void updateTotalMonthlyExpensesBudget(); void updateTotalMonthlyIncomesBudget(); void updateBudgetAccountTitle(AssetsAccount *account = NULL); bool editAccount(Account*); bool editAccount(Account*, QWidget *parent); void balanceAccount(Account*); bool checkSchedule(bool update_display, QWidget *parent, bool allow_account_creation = true); void updateScheduledTransactions(); void appendScheduledTransaction(ScheduledTransaction *strans); bool editScheduledTransaction(ScheduledTransaction *strans); bool editScheduledTransaction(ScheduledTransaction *strans, QWidget *parent, bool clone_trans = false, bool allow_account_creation = true); bool editOccurrence(ScheduledTransaction *strans, const QDate &date); bool editOccurrence(ScheduledTransaction *strans, const QDate &date, QWidget *parent); bool editTransaction(Transaction *trans, QWidget *parent, bool clone_trans = false, bool allow_account_creation = true); bool editTransaction(Transaction *trans); bool removeScheduledTransaction(ScheduledTransaction *strans); bool removeOccurrence(ScheduledTransaction *strans, const QDate &date); bool newScheduledTransaction(int transaction_type, Security *security = NULL, bool select_security = false); bool newScheduledTransaction(int transaction_type, Security *security, bool select_security, QWidget *parent, Account *account = NULL); bool newExpenseWithLoan(QString description_value, double value_value, double quantity_value, QDate date_value, ExpensesAccount *category_value, QString payee_value, QString comment_value); bool newExpenseWithLoan(QWidget *parent); bool newMultiAccountTransaction(bool create_expenses, QString description_string, CategoryAccount *category_account, double quantity_value, QString comment_string); bool newMultiAccountTransaction(QWidget *parent, bool create_expenses); bool newMultiItemTransaction(QWidget *parent, AssetsAccount *account = NULL); bool newDebtPayment(QWidget *parent, AssetsAccount *loan = NULL, bool only_interest = false); bool editTimestamp(QList trans, QWidget *parent = NULL); bool editSplitTransaction(SplitTransaction *split); bool editSplitTransaction(SplitTransaction *split, QWidget *parent, bool temporary_split = false, bool clone_trans = false, bool allow_account_creation = true); bool splitUpTransaction(SplitTransaction *split); bool removeSplitTransaction(SplitTransaction *split); bool saveView(QTextStream &file, int fileformat); bool exportScheduleList(QTextStream &outf, int fileformat); bool exportAccountsList(QTextStream &outf, int fileformat); bool exportSecuritiesList(QTextStream &outf, int fileformat); void editSecurity(QTreeWidgetItem *i); void appendSecurity(Security *security); void updateSecurity(Security *security); void updateSecurity(QTreeWidgetItem *i); void updateSecurityAccount(AssetsAccount *account, bool update_display = true); bool editSecurityTrade(SecurityTrade *ts, QWidget *parent); void editSecurityTrade(SecurityTrade *ts); void setModified(bool has_been_modified = true); void showExpenses(); void showIncomes(); void showTransfers(); void updateSecuritiesStatistics(); bool crashRecovery(QUrl url); bool newRefundRepayment(Transactions *trans); void readOptions(); void setCommandLineParser(QCommandLineParser*); bool timeToUpdateExchangeRates(); void addNewSchedule(ScheduledTransaction *strans, QWidget *parent); void removeOldLinks(Transactions*, Transactions*); void addTransactionLinks(Transactions*, bool update_display = true); bool removeTransactionLinks(Transactions*); void linksUpdated(Transactions*); void updateLinksAction(Transactions*, bool enable_remove = true); void updateLinksAction(); QMenu *createPopupMenu(); void setLinkTransaction(Transactions *trans); Transactions *getLinkTransaction(); void createLink(QList transactions, bool link_to); static void openLink(Transactions *trans, QWidget *parent = NULL); QAction *ActionAP_1, *ActionAP_2, *ActionAP_3, *ActionAP_4, *ActionAP_5, *ActionAP_6, *ActionAP_7, *ActionAP_8; QAction *ActionEditSchedule, *ActionEditOccurrence, *ActionDeleteSchedule, *ActionDeleteOccurrence; QAction *ActionAddAccount, *ActionNewAssetsAccount, *ActionNewLoan, *ActionNewIncomesAccount, *ActionNewExpensesAccount, *ActionEditAccount, *ActionDeleteAccount, *ActionCloseAccount, *ActionBalanceAccount, *ActionAddAccountMenu; QAction *ActionShowAccountTransactions, *ActionShowLedger, *ActionReconcileAccount; QAction *ActionNewExpense, *ActionNewIncome, *ActionNewTransfer, *ActionNewMultiItemTransaction; QAction *ActionNewMultiAccountExpense, *ActionNewExpenseWithLoan, *ActionNewDebtPayment, *ActionNewDebtInterest; QAction *ActionEditTransaction, *ActionEditScheduledTransaction, *ActionEditSplitTransaction; QAction *ActionJoinTransactions, *ActionSplitUpTransaction; QAction *ActionCloneTransaction; QAction *ActionEditTimestamp; QAction *ActionTags, *ActionLinks, *ActionCreateLink, *ActionLinkTo, *ActionCancelLinkTo; QAction *ActionSelectAssociatedFile, *ActionOpenAssociatedFile; QAction *ActionDeleteTransaction, *ActionDeleteScheduledTransaction, *ActionDeleteSplitTransaction; QAction *ActionNewSecurity, *ActionEditSecurity, *ActionBuyShares, *ActionSellShares, *ActionNewDividend, *ActionNewReinvestedDividend, *ActionNewSecurityTrade, *ActionSetQuotation, *ActionEditQuotations, *ActionEditSecurityTransactions, *ActionDeleteSecurity; QAction *ActionNewRefund, *ActionNewRepayment, *ActionNewRefundRepayment; QAction *ActionFileNew, *ActionFileOpen, *ActionFileSave, *ActionFileSaveAs, *ActionFileReload, *ActionFileSync, *ActionSaveView, *ActionPrintView, *ActionPrintPreview, *ActionQuit; QMenu *recentFilesMenu; QList recentFileActionList; QAction *ActionClearRecentFiles; QAction *ActionOverTimeReport, *ActionCategoriesComparisonReport, *ActionOverTimeChart, *ActionCategoriesComparisonChart; QAction *ActionImportCSV, *ActionImportQIF, *ActionImportEQZ, *ActionExportQIF; QAction *ActionConvertCurrencies, *ActionUpdateExchangeRates; QAction *ActionExtraProperties, *ActionUseExchangeRateForTransactionDate, *ActionSetBudgetPeriod, *ActionSetScheduleConfirmationTime, *AIPCurrentMonth, *AIPCurrentYear, *AIPCurrentWholeMonth, *AIPCurrentWholeYear, *AIPRememberLastDates, *ABFDaily, *ABFWeekly, *ABFFortnightly, *ABFMonthly, *ABFNever, *ACSTime[11]; QAction *ActionSetMainCurrency, *ActionSyncSettings, *ActionSelectFont, *ActionDarkMode; QActionGroup *ActionSelectInitialPeriod, *ActionSelectBackupFrequency, *ActionSelectLang; QAction *ActionHelp, *ActionWhatsThis, *ActionReportBug, *ActionAbout, *ActionAboutQt; QAction *ActionNewTag, *ActionRenameTag, *ActionRemoveTag; QAction *ActionRightAlignValues, *SeparatorRightAlignValues; TagMenu *tagMenu; QMenu *linkMenu; protected: void setupActions(); void updateRecentFiles(QString filePath = QString()); void saveOptions(); void closeEvent(QCloseEvent *event); void updatePalette(bool); void dragEnterEvent(QDragEnterEvent *event); void dropEvent(QDropEvent *event); QUrl current_url; double period_months, from_to_months; bool modified, modified_auto_save, auto_save_timeout; QDate from_date, to_date, frommonth_begin, prevmonth_begin; QDate securities_from_date, securities_to_date; QDate prev_cur_date; bool partial_budget; bool b_extra; bool right_align_values; QLocalSocket *socket; QLocalServer *server; QString cr_tmp_file; Transactions *link_trans; QToolBar *fileToolbar, *accountsToolbar, *transactionsToolbar, *statisticsToolbar, *linkToolbar; QTabWidget *tabs; QTabWidget *accountsTabs; QCheckBox *budgetButton; EqonomizeValueEdit *budgetEdit; EqonomizeMonthSelector *budgetMonthEdit; QLabel *prevMonthBudgetLabel; QWidget *accounts_page, *expenses_page, *incomes_page, *transfers_page, *securities_page, *schedule_page; QVBoxLayout *expensesLayout, *incomesLayout, *transfersLayout; TransactionListWidget *expensesWidget, *incomesWidget, *transfersWidget; QTreeWidget *accountsView, *securitiesView, *scheduleView; QTreeWidgetItem *assetsItem, *liabilitiesItem, *incomesItem, *expensesItem, *tagsItem; QCheckBox *accountsPeriodFromButton; QDateEdit *accountsPeriodFromEdit, *accountsPeriodToEdit; QCheckBox *partialBudgetButton; QComboBox *accountsPeriodCombo; QCheckBox *securitiesPeriodFromButton; QDateEdit *securitiesPeriodFromEdit, *securitiesPeriodToEdit; QPushButton *newScheduleButton, *editScheduleButton, *removeScheduleButton; QMenu *editScheduleMenu, *removeScheduleMenu; QPushButton *newSecurityTransactionButton, *newSecurityButton, *setQuotationButton; QLabel *securitiesStatLabel; QLabel *footer1; QCommandLineParser *parser; QComboBox *setMainCurrencyCombo; QNetworkReply *updateExchangeRatesReply, *checkVersionReply; CurrencyConversionDialog *currencyConversionWindow; int prev_set_main_currency_index; double total_value, total_cost, total_profit, total_rate; double expenses_accounts_value, incomes_accounts_value, assets_accounts_value, liabilities_accounts_value; double expenses_accounts_change, incomes_accounts_change, assets_accounts_change, liabilities_accounts_change; double expenses_budget, expenses_budget_diff, incomes_budget, incomes_budget_diff; QMap account_value; QMap account_change; QMap assets_group_value; QMap assets_group_change; QMap liabilities_group_value; QMap liabilities_group_change; QMap tag_value; QMap tag_change; QMap > account_month; QMap account_month_begincur; QMap account_month_beginfirst; QMap account_month_endlast; QMap account_budget; QMap account_budget_diff; QMap account_future_diff; QMap account_future_diff_change; QMap account_items; QMap assets_group_items, liabilities_group_items, tag_items; QMap item_accounts; QMap item_assets_groups, item_liabilities_groups, item_tags; QMap assets_expanded, liabilities_expanded, expenses_expanded, incomes_expanded; QMenu *assetsPopupMenu, *accountPopupMenu, *tagPopupMenu, *securitiesPopupMenu, *schedulePopupMenu, *scheduleHeaderPopupMenu; QDialog *helpDialog, *cccDialog, *ccrDialog, *otcDialog, *otrDialog, *syncDialog; QLineEdit *syncUploadEdit, *syncUrlEdit, *syncDownloadEdit; QPushButton *uploadButton; QCheckBox *syncAutoBox; QTreeWidgetItem *clicked_item; protected slots: void checkAvailableVersion_readdata(); void languageSelected(); public slots: void saveCrashRecovery(); void autoSave(); void onAutoSaveTimeout(); void onActivateRequested(const QStringList&, const QString&); void useExtraProperties(bool); void useExchangeRateForTransactionDate(bool); void updateBudgetDay(); void setBudgetPeriod(); void setScheduleConfirmationTime(); void selectFont(); void setDarkMode(bool); void showFilter(); void showHelp(); void reportBug(); void showAbout(); void showAboutQt(); void importCSV(); void importQIF(); void importEQZ(); void exportQIF(); void checkAvailableVersion(); void checkExchangeRatesTimeOut(); void updateExchangeRates(bool do_currencies_modified = true); void cancelUpdateExchangeRates(); void currenciesModified(); void warnAndAskForExchangeRate(); void setMainCurrency(); void setMainCurrencyIndexChanged(int index); void updateUsesMultipleCurrencies(); void openCurrencyConversion(); void cancelSync(); void fileSynchronize(); void openSynchronizationSettings(); void syncUploadChanged(const QString&); void uploadClicked(); void serverNewConnection(); void socketReadyRead(); void reloadBudget(); void showOverTimeReport(); void showCategoriesComparisonReport(); void showOverTimeChart(); void showCategoriesComparisonChart(); void printPreviewPaint(QPrinter*); void showPrintPreview(); void printView(); void saveView(); void newSecurity(); void editSecurity(); void deleteSecurity(); void buySecurities(); void sellSecurities(); void newDividend(); void newReinvestedDividend(); void newSecurityTrade(); void setQuotation(); void editQuotations(); void editSecurityTransactions(); void securitiesSelectionChanged(); void securitiesExecuted(QTreeWidgetItem*); void securitiesExecuted(QTreeWidgetItem*, int); void popupSecuritiesMenu(const QPoint&); void updateSecurities(); void newExpenseWithLoan(); void newMultiAccountExpense(); void newMultiAccountIncome(); void newMultiItemTransaction(); void newDebtPayment(); void newDebtInterest(); void newScheduledExpense(); void newScheduledIncome(); void newScheduledTransfer(); void editScheduledTransaction(); void cloneScheduledTransaction(); void editOccurrence(); void removeScheduledTransaction(); void removeOccurrence(); void scheduleSelectionChanged(); void scheduleExecuted(QTreeWidgetItem*); void hideScheduleColumn(bool); void popupScheduleHeaderMenu(const QPoint&); void popupScheduleMenu(const QPoint&); void editSelectedTimestamp(); void editSelectedScheduledTransaction(); void editSelectedTransaction(); void cloneSelectedTransaction(); void editSelectedSplitTransaction(); void deleteSelectedScheduledTransaction(); void deleteSelectedTransaction(); void deleteSelectedSplitTransaction(); void joinSelectedTransactions(); void splitUpSelectedTransaction(); void selectAssociatedFile(); void openAssociatedFile(); void newRefund(); void newRepayment(); void newRefundRepayment(); void onPageChange(int); void showAccountTransactions(bool = false); void showLedger(); void reconcileAccount(); void createLink(); void linkTo(); void cancelLinkTo(); void openLink(); void removeLink(); void updateTransactionActions(); bool openURL(const QUrl&, bool merge = false); void fileNew(); void fileOpen(); void fileOpenRecent(const QUrl&); void fileReload(); bool fileSave(); void onFilterSelected(QString); bool fileSaveAs(); void optionsPreferences(); void clearRecentFiles(); void openRecent(); void checkSchedule(); void checkDate(); void popupAccountsMenu(const QPoint&); void addAccount(); void accountAdded(Account *account); void securityAdded(Security *security); void newAssetsAccount(); void newLoan(); void newIncomesAccount(IncomesAccount *default_parent = NULL); void newExpensesAccount(ExpensesAccount *default_parent = NULL); void accountExecuted(QTreeWidgetItem*, int); void accountClicked(QTreeWidgetItem*, int); void accountClickedTimeout(); void accountExecuted(QTreeWidgetItem*); void accountExpanded(QTreeWidgetItem*); void accountCollapsed(QTreeWidgetItem*); void accountMoved(QTreeWidgetItem*, QTreeWidgetItem*); void balanceAccount(); void editAccount(); void deleteAccount(); void closeAccount(); void accountsSelectionChanged(); void tagAdded(QString); void newTag(); void deleteTag(); void renameTag(); void tagsChanged(); void setPartialBudget(bool); void budgetEditReturnPressed(); void budgetMonthChanged(const QDate&); void budgetChanged(double); void budgetToggled(bool); void updateBudgetEdit(); void accountsPeriodFromChanged(const QDate&); void accountsPeriodToChanged(const QDate&); void periodSelected(QAction*); void prevMonth(); void nextMonth(); void currentMonth(); void prevYear(); void nextYear(); void currentYear(); void securitiesPeriodFromChanged(const QDate&); void securitiesPeriodToChanged(const QDate&); void securitiesPrevMonth(); void securitiesNextMonth(); void securitiesCurrentMonth(); void securitiesPrevYear(); void securitiesNextYear(); void securitiesCurrentYear(); void transactionAdded(Transactions*); void transactionModified(Transactions*, Transactions*); void transactionRemoved(Transactions*, Transactions* = NULL, bool permanent = false); void valueAlignmentUpdated(bool); void filterAccounts(); signals: void accountsModified(); void transactionsModified(); void budgetUpdated(); void timeToSaveConfig(); void tagsModified(); }; class OverTimeReportDialog : public QDialog { Q_OBJECT public: OverTimeReportDialog(Budget *budg, QWidget *parent); OverTimeReport *report; public slots: void reject(); }; class CategoriesComparisonReportDialog : public QDialog { Q_OBJECT public: CategoriesComparisonReportDialog(bool extra_parameters, Budget *budg, QWidget *parent); CategoriesComparisonReport *report; public slots: void reject(); }; class CategoriesComparisonChartDialog : public QDialog { Q_OBJECT public: CategoriesComparisonChartDialog(Budget *budg, QWidget *parent); CategoriesComparisonChart *chart; public slots: void reject(); }; class OverTimeChartDialog : public QDialog { Q_OBJECT public: OverTimeChartDialog(bool extra_parameters, Budget *budg, QWidget *parent); OverTimeChart *chart; public slots: void reject(); }; class ConfirmScheduleDialog : public QDialog { Q_OBJECT protected: QTreeWidget *transactionsView; Budget *budget; bool b_extra, b_create_accounts; QPushButton *editButton, *removeButton, *postponeButton; int current_index; public: ConfirmScheduleDialog(bool extra_parameters, Budget *budg, QWidget *parent, QString title, bool allow_account_creation = true); Transactions *firstTransaction(); Transactions *nextTransaction(); public slots: void transactionSelectionChanged(); void remove(); void edit(); void postpone(); void updateTransactions(); }; class EditSecurityDialog : public QDialog { Q_OBJECT protected: QLineEdit *nameEdit; QTextEdit *descriptionEdit; EqonomizeValueEdit *sharesEdit, *quotationEdit; QDateEdit *quotationDateEdit; QComboBox *typeCombo; AccountComboBox *accountCombo; QSpinBox *decimalsEdit, *quotationDecimalsEdit; QLabel *quotationLabel, *quotationDateLabel; Budget *budget; bool b_create_accounts; public: EditSecurityDialog(Budget *budg, QWidget *parent, QString title, bool allow_account_creation = false); Security *newSecurity(); bool modifySecurity(Security *security); void setSecurity(Security *security); bool checkAccount(); protected slots: void decimalsChanged(int); void quotationDecimalsChanged(int); void accountActivated(Account*); void accept(); void newAccount(); }; struct q_csv_info; class EditQuotationsDialog : public QDialog { Q_OBJECT protected: QLabel *titleLabel; QTreeWidget *quotationsView; EqonomizeValueEdit *quotationEdit; QDateEdit *dateEdit; QPushButton *changeButton, *addButton, *deleteButton; int i_quotation_decimals; Budget *budget; Security *security; bool import(QString url, bool test, q_csv_info *ci); public: EditQuotationsDialog(Security *sec, QWidget *parent); void setSecurity(Security *sec); void modifyQuotations(); protected slots: void onSelectionChanged(); void addQuotation(); void changeQuotation(); void deleteQuotation(); void importQuotations(); void exportQuotations(); void onFilterSelected(QString filter); }; class RefundDialog : public QDialog { Q_OBJECT protected: Transactions *transaction; EqonomizeValueEdit *valueEdit, *quantityEdit; QDateEdit *dateEdit; AccountComboBox *accountCombo; QLineEdit *commentsEdit, *payeeEdit; QButtonGroup *joinGroup; QLayout *joinGroup_layout; void keyPressEvent(QKeyEvent*); public: RefundDialog(Transactions *trans, QWidget *parent, bool extra_parameters); Transaction *createRefund(); bool validValues(); bool joinIsChecked(); protected slots: void accept(); void accountActivated(Account*); void joinToggled(bool); void accountNextFocus(); }; class EditSecurityTradeDialog : public QDialog { Q_OBJECT protected: Budget *budget; QComboBox *fromSecurityCombo, *toSecurityCombo; QLabel *sharesFromLabel, *shareToLabel; EqonomizeValueEdit *fromSharesEdit, *toSharesEdit; QDateEdit *dateEdit; int prev_from_index; void keyPressEvent(QKeyEvent *e); public: EditSecurityTradeDialog(Budget *budg, Security *sec, QWidget *parent); void setSecurityTrade(SecurityTrade *ts); SecurityTrade *createSecurityTrade(); bool validValues(); bool checkSecurities(); protected slots: void accept(); void maxShares(); Security *selectedFromSecurity(); Security *selectedToSecurity(); void fromSecurityChanged(bool = false); void toSecurityChanged(); void focusDate(); }; class SecurityTransactionsDialog : public QDialog { Q_OBJECT protected: Security *security; Eqonomize *mainWin; QTreeWidget *transactionsView; QPushButton *editButton, *removeButton; void updateTransactions(); public: SecurityTransactionsDialog(Security *sec, Eqonomize *parent, QString title); protected slots: void remove(); void edit(); void edit(QTreeWidgetItem*); void transactionSelectionChanged(); }; class EqonomizeTreeWidget : public QTreeWidget { Q_OBJECT public: EqonomizeTreeWidget(QWidget *parent); EqonomizeTreeWidget(); protected: void dropEvent(QDropEvent *event); protected slots: void keyPressEvent(QKeyEvent*); signals: void returnPressed(QTreeWidgetItem*); void spacePressed(QTreeWidgetItem*); void itemMoved(QTreeWidgetItem*, QTreeWidgetItem*); }; class QIFWizardPage : public QWizardPage { protected: bool is_complete; public: QIFWizardPage(); bool isComplete() const; void setComplete(bool b); }; class EqonomizeComboBox : public QComboBox { Q_OBJECT protected: bool block_selected; public: EqonomizeComboBox(QWidget *parent); protected slots: void keyPressEvent(QKeyEvent *event); void itemActivated(int); signals: void returnPressed(); void itemSelected(int); }; class EqonomizeItemDelegate : public QStyledItemDelegate { Q_OBJECT public: EqonomizeItemDelegate(QObject *parent = NULL); public slots: bool helpEvent(QHelpEvent *e, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &index); void paint(QPainter *painter, const QStyleOptionViewItem& option, const QModelIndex &index) const; }; class EqonomizeTranslator : public QTranslator { Q_OBJECT public: EqonomizeTranslator(); QString translate(const char *context, const char *sourceText, const char *disambiguation = NULL, int n = -1) const; }; void open_file_list(QString); #endif Eqonomize-1.5.3/src/eqonomizelist.h000066400000000000000000000040221416454732000173340ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2017 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifndef EQONOMIZE_LIST_H #define EQONOMIZE_LIST_H #include template class EqonomizeList : public QList { protected: bool b_auto_delete; public: EqonomizeList() : QList(), b_auto_delete(false) {}; virtual ~EqonomizeList () {} void setAutoDelete(bool b) { b_auto_delete = b; } void clear() { if(b_auto_delete) { while(!QList::isEmpty()) delete QList::takeFirst(); } else { QList::clear(); } } bool removeRef(type value) { if(b_auto_delete) delete value; return QList::removeOne(value); } }; #endif Eqonomize-1.5.3/src/eqonomizemonthselector.cpp000066400000000000000000000073521416454732000216130ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include "budget.h" #include "eqonomizemonthselector.h" EqonomizeMonthSelector::EqonomizeMonthSelector(QWidget *parent) : QWidget(parent) { d_date = QDate::currentDate(); d_date.setDate(d_date.year(), d_date.month(), 1); QHBoxLayout *layout = new QHBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); monthCombo = new QComboBox(this); monthCombo->setEditable(false); layout->addWidget(monthCombo); yearEdit = new QSpinBox(this); yearEdit->setRange(0, 4000); yearEdit->setValue(d_date.year()); layout->addWidget(yearEdit); updateMonths(); monthCombo->setCurrentIndex(d_date.month() - 1); connect(yearEdit, SIGNAL(valueChanged(int)), this, SLOT(onYearChanged(int))); connect(monthCombo, SIGNAL(activated(int)), this, SLOT(onMonthChanged(int))); } EqonomizeMonthSelector::~EqonomizeMonthSelector() {} QDate EqonomizeMonthSelector::date() const {return d_date;} void EqonomizeMonthSelector::onYearChanged(int year) { d_date.setDate(year, d_date.month(), 1); updateMonths(); emit yearChanged(d_date); emit dateChanged(d_date); } void EqonomizeMonthSelector::onMonthChanged(int month) { d_date.setDate(d_date.year(), month + 1, 1); emit monthChanged(d_date); emit dateChanged(d_date); } void EqonomizeMonthSelector::setDate(const QDate &newdate) { if(newdate.isValid()) { d_date.setDate(newdate.year(), newdate.month(), 1); yearEdit->blockSignals(true); yearEdit->setValue(newdate.year()); yearEdit->blockSignals(false); monthCombo->blockSignals(true); updateMonths(); monthCombo->setCurrentIndex(d_date.month() - 1); monthCombo->blockSignals(false); } } void EqonomizeMonthSelector::setMonthEnabled(bool b) { monthCombo->setEnabled(b); } void EqonomizeMonthSelector::updateMonths() { int months = 12; monthCombo->blockSignals(true); if(monthCombo->count() != 12 || !IS_GREGORIAN_CALENDAR) { monthCombo->clear(); for(int i = 1; i <= months; i++) { monthCombo->addItem(QLocale().monthName(i, QLocale::LongFormat)); } monthCombo->setCurrentIndex(d_date.month() - 1); } monthCombo->blockSignals(false); } void EqonomizeMonthSelector::focusMonth() {monthCombo->setFocus();} void EqonomizeMonthSelector::focusYear() {yearEdit->setFocus();} Eqonomize-1.5.3/src/eqonomizemonthselector.h000066400000000000000000000042271416454732000212560ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifndef EQONOMIZE_MONTH_SELECTOR_H #define EQONOMIZE_MONTH_SELECTOR_H #include #include class QComboBox; class QSpinBox; class EqonomizeMonthSelector : public QWidget { Q_OBJECT public: EqonomizeMonthSelector(QWidget *parent); ~EqonomizeMonthSelector(); QDate date() const; protected: QComboBox *monthCombo; QSpinBox *yearEdit; QDate d_date; void updateMonths(); public slots: void setDate(const QDate&); void focusMonth(); void focusYear(); void setMonthEnabled(bool); protected slots: void onYearChanged(int); void onMonthChanged(int); signals: void dateChanged(const QDate&); void yearChanged(const QDate&); void monthChanged(const QDate&); }; #endif Eqonomize-1.5.3/src/eqonomizevalueedit.cpp000066400000000000000000000541411416454732000207050ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016-2019 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include "eqonomizevalueedit.h" #include "budget.h" #include #include #include #include #include #include #include #define MAX_VALUE 1000000000000.0 QString calculatedText; QString last_error; const EqonomizeValueEdit *calculatedText_object = NULL; EqonomizeValueEdit::EqonomizeValueEdit(bool allow_negative, QWidget *parent, Budget *budg) : QDoubleSpinBox(parent), budget(budg) { init(allow_negative ? -MAX_VALUE : 0.0, MAX_VALUE, 1.0, 0.0, -1, true); } EqonomizeValueEdit::EqonomizeValueEdit(double value, bool allow_negative, bool show_currency, QWidget *parent, Budget *budg) : QDoubleSpinBox(parent), budget(budg) { init(allow_negative ? -MAX_VALUE : 0.0, MAX_VALUE, 1.0, value, -1, show_currency); } EqonomizeValueEdit::EqonomizeValueEdit(double value, int precision, bool allow_negative, bool show_currency, QWidget *parent, Budget *budg) : QDoubleSpinBox(parent), budget(budg) { init(allow_negative ? -MAX_VALUE : 0.0, MAX_VALUE, 1.0, value, precision, show_currency); } EqonomizeValueEdit::EqonomizeValueEdit(double lower, double step, double value, int precision, bool show_currency, QWidget *parent, Budget *budg) : QDoubleSpinBox(parent), budget(budg) { init(lower, MAX_VALUE, step, value, precision, show_currency); } EqonomizeValueEdit::EqonomizeValueEdit(double lower, double upper, double step, double value, int precision, bool show_currency, QWidget *parent, Budget *budg) : QDoubleSpinBox(parent), budget(budg) { init(lower, upper, step, value, precision, show_currency); } EqonomizeValueEdit::~EqonomizeValueEdit() {} void EqonomizeValueEdit::init(double lower, double upper, double step, double value, int precision, bool show_currency) { o_currency = NULL; i_precision = precision; QDoubleSpinBox::setRange(lower, upper); setSingleStep(step); setAlignment(Qt::AlignRight); if(show_currency) { if(i_precision < 0) i_precision = budget->defaultCurrency()->fractionalDigits(true); setCurrency(budget->defaultCurrency(), true); } if(i_precision < 0) i_precision = MONETARY_DECIMAL_PLACES; setDecimals(i_precision); setValue(value); connect(this, SIGNAL(editingFinished()), this, SLOT(onEditingFinished())); QLineEdit *w = findChild(); if(w) connect(w, SIGNAL(textChanged(const QString&)), this, SLOT(onTextChanged(const QString&))); w->installEventFilter(this); } bool EqonomizeValueEdit::eventFilter(QObject *, QEvent *e) { if(e->type() == QMouseEvent::MouseButtonDblClick) { QLineEdit *w = findChild(); QString text = w->text(); int pos = w->cursorPosition(); if(pos >= text.length()) pos = text.length() - 1; if(!text[pos].isNumber() && !text[pos].isSpace() && !text[pos].isPunct()) return false; selectNumber(); return true; } return false; } void EqonomizeValueEdit::onTextChanged(const QString &text) { if(text == s_suffix) { QLineEdit *w = findChild(); if(w) { w->setCursorPosition(0); } } } void EqonomizeValueEdit::onEditingFinished() { if(hasFocus()) emit returnPressed(); } void EqonomizeValueEdit::setRange(double lower, double step, int precision) { setRange(lower, MAX_VALUE, step, precision); } void EqonomizeValueEdit::setRange(double lower, double upper, double step, int precision) { i_precision = precision; setDecimals(precision); QDoubleSpinBox::setRange(lower, upper); setSingleStep(step); } void EqonomizeValueEdit::setPrecision(int precision) { if(precision == i_precision) return; i_precision = precision; setDecimals(precision); } void EqonomizeValueEdit::selectNumber() { if(s_prefix.isEmpty() && s_suffix.isEmpty()) { selectAll(); return; } QLineEdit *w = findChild(); if(w) { QString text = w->text(); int start = 0; int end = text.length(); if(!s_prefix.isEmpty() && text.startsWith(s_prefix)) { start = s_prefix.length(); if(text.length() > start && text[start] == ' ') start++; } if(!s_suffix.isEmpty() && text.endsWith(s_suffix)) { end -= s_suffix.length(); if(end > 0 && text[end - 1] == ' ') end--; } w->setSelection(end, start - end); } } void EqonomizeValueEdit::focusInEvent(QFocusEvent *e) { if(e->reason() == Qt::TabFocusReason || e->reason() == Qt::BacktabFocusReason) { QDoubleSpinBox::focusInEvent(e); selectNumber(); } else { QDoubleSpinBox::focusInEvent(e); } } void EqonomizeValueEdit::enterFocus() { setFocus(Qt::TabFocusReason); } void EqonomizeValueEdit::setCurrency(Currency *currency, bool keep_precision, int as_default, bool is_temporary) { if(is_temporary) o_currency = NULL; else o_currency = currency; if(!currency) { s_suffix = QString(); s_prefix = QString(); setValue(value()); return; } if((as_default == 0 || (as_default < 0 && currency != budget->defaultCurrency())) || currency->symbol().isEmpty()) { if(currency && currency->codePrecedes()) { s_prefix = currency->code(); s_suffix = QString(); } else { s_suffix = currency->code(); s_prefix = QString(); } } else { if(currency && currency->symbolPrecedes()) s_prefix = currency->symbol(); else s_prefix = QString(); if(currency && !currency->symbolPrecedes()) s_suffix = currency->symbol(); else s_suffix = QString(); } if(!keep_precision) { setDecimals(currency->fractionalDigits(true)); } else { setValue(value()); } } Currency *EqonomizeValueEdit::currency() {return o_currency;} QValidator::State EqonomizeValueEdit::validate(QString &input, int &pos) const { QString input2 = input; if(o_currency) { input2.remove(budget->monetary_group_separator); input2.replace(budget->monetary_decimal_separator, QLocale().decimalPoint()); } else { input2.remove(budget->group_separator); input2.replace(budget->decimal_separator, QLocale().decimalPoint()); } int pos2 = pos; QValidator::State s = QDoubleSpinBox::validate(input2, pos2); if(s == QValidator::Invalid) { QString str = input2.trimmed(); if(!s_suffix.isEmpty() && str.endsWith(s_suffix)) { str = str.left(str.length() - s_suffix.length()); } if(!s_suffix.isEmpty()) { str.remove(s_suffix); } str = str.simplified(); str.remove(' '); if(str != input2) { if(pos2 > str.length()) pos2 = str.length(); if(QDoubleSpinBox::validate(str, pos2) == QValidator::Acceptable) return QValidator::Acceptable; } return QValidator::Intermediate; } return s; } QString EqonomizeValueEdit::textFromValue(double value) const { if(o_currency) return o_currency->formatValue(value, decimals(), true, false, true); if(!s_suffix.isEmpty()) return s_prefix + budget->formatValue(value, decimals()) + QString(" ") + s_suffix; return s_prefix + budget->formatValue(value, decimals()); } double EqonomizeValueEdit::valueFromText(const QString &t) const { QString str = t.simplified(); if(!s_suffix.isEmpty()) { str.remove(s_suffix); } if(!s_prefix.isEmpty()) { str.remove(s_prefix); } str.remove(' '); if(o_currency) { str.remove(budget->monetary_group_separator); str.replace(budget->monetary_decimal_separator, QLocale().decimalPoint()); } else { str.remove(budget->group_separator); str.replace(budget->decimal_separator, QLocale().decimalPoint()); } return QDoubleSpinBox::valueFromText(str); } void EqonomizeValueEdit::fixup(QString &input) const { if(!s_prefix.isEmpty() && input.startsWith(s_prefix)) { input = input.right(input.length() - s_prefix.length()); if(input.isEmpty()) input = QString::number(1); } if(!s_suffix.isEmpty() && input.endsWith(s_suffix)) { input = input.left(input.length() - s_suffix.length()); if(input.isEmpty()) input = QString::number(1); } QString calculatedText_pre = input.trimmed(); input.replace("√", QString('^') + (o_currency ? o_currency->formatValue(0.5, -1, false, false, true) : budget->formatValue(0.5, 1))); #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) input.remove(QRegularExpression("\\s")); #else input.remove(QRegExp("\\s")); #endif if(o_currency) { input.remove(budget->monetary_group_separator); if(!budget->monetary_negative_sign.isEmpty()) input.replace(budget->monetary_negative_sign, "-"); if(!budget->monetary_positive_sign.isEmpty()) input.replace(budget->monetary_positive_sign, "+"); } else { input.remove(budget->group_separator); if(!budget->negative_sign.isEmpty()) input.replace(budget->negative_sign, "-"); if(!budget->positive_sign.isEmpty()) input.replace(budget->positive_sign, "+"); } input.replace("⋅", "*"); input.replace("×", "*"); input.replace("−", "-"); input.replace("∕", "/"); input.replace("÷", "/"); input.replace("²", "^2"); input.replace("³", "^3"); input.replace("]", ")"); input.replace("[", "("); QStringList errors; bool calculated = false; double v = fixup_sub(input, errors, calculated); if(o_currency) { input = o_currency->formatValue(v, decimals(), false, false, true); } else { input = budget->formatValue(v, decimals()); } if(calculated && errors.isEmpty()) { calculatedText = calculatedText_pre; calculatedText_object = this; } else if(calculatedText_object == this) { calculatedText_object = NULL; calculatedText.clear(); } if(!errors.isEmpty()) { QString error; for(int i = 0; i < errors.size(); i++) { if(i != 0) error += '\n'; error += errors[i]; } if(last_error == error) { last_error = ""; } else { last_error = error; QMessageBox::critical((QWidget*) parent(), tr("Error"), error); } } } double EqonomizeValueEdit::fixup_sub(QString &input, QStringList &errors, bool &calculated) const { input = input.trimmed(); if(input.isEmpty()) { return 0.0; } if(o_currency) { input.remove(budget->monetary_group_separator); if(!budget->monetary_negative_sign.isEmpty()) input.replace(budget->monetary_negative_sign, "-"); if(!budget->monetary_positive_sign.isEmpty()) input.replace(budget->monetary_positive_sign, "+"); } else { input.remove(budget->group_separator); if(!budget->negative_sign.isEmpty()) input.replace(budget->negative_sign, "-"); if(!budget->positive_sign.isEmpty()) input.replace(budget->positive_sign, "+"); } input.replace(QLocale().negativeSign(), "-"); input.replace(QLocale().positiveSign(), "+"); int i = input.indexOf(')', 1); if(i < 1) { i = input.indexOf('(', 0); if(i == 0) { input.remove(0, 1); return fixup_sub(input, errors, calculated); } else if(i >= 0) { input += ')'; i = input.length() - 1; } else { i = -1; } } if(i >= 1) { int i2 = input.lastIndexOf('(', i - 1); if(i2 < 0 || i2 > i) { if(i == input.length() - 1) { input.chop(1); return fixup_sub(input, errors, calculated); } input.prepend('('); i++; i2 = 0; } if(i2 == 0 && i == input.length() - 1) { input.remove(0, 1); input.chop(1); return fixup_sub(input, errors, calculated); } if(i < input.length() - 1 && (input[i + 1].isNumber() || input[i + 1] == '(')) input.insert(i + 1, '*'); QString str = input.mid(i2 + 1, i - i2 - 1); double v = fixup_sub(str, errors, calculated); input.replace(i2, i - i2 + 1, o_currency ? o_currency->formatValue(v, decimals() + 2, false, false, true) : budget->formatValue(v, decimals() + 2)); if(i2 > 0 && (input[i2 - 1].isNumber() || input[i2 - 1] == ')')) input.insert(i2, '*'); calculated = true; return fixup_sub(input, errors, calculated); } #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) i = input.indexOf(QRegularExpression("[-+]"), 1); #else i = input.indexOf(QRegExp("[-+]"), 1); #endif if(i >= 1) { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) QStringList terms = input.split(QRegularExpression("[-+]")); #else QStringList terms = input.split(QRegExp("[-+]")); #endif i = 0; double v = 0.0; QList signs; signs << true; for(int terms_i = 0; terms_i < terms.size() - 1; terms_i++) { i += terms[terms_i].length(); if(input[i] == '-') signs << false; else signs << true; i++; } for(int terms_i = 0; terms_i < terms.size() - 1; terms_i++) { if(terms[terms_i].endsWith('*') || terms[terms_i].endsWith('/') || terms[terms_i].endsWith('^')) { if(!signs[terms_i + 1]) terms[terms_i] += '-'; else terms[terms_i] += '+'; terms[terms_i] += terms[terms_i + 1]; signs.removeAt(terms_i + 1); terms.removeAt(terms_i + 1); terms_i--; } } if(terms.size() > 1) { for(int terms_i = 0; terms_i < terms.size(); terms_i++) { if(terms[terms_i].isEmpty()) { if(!signs[terms_i] && terms_i + 1 < terms.size()) { signs[terms_i + 1] = !signs[terms_i + 1]; } } else { if(!signs[terms_i]) v -= fixup_sub(terms[terms_i], errors, calculated); else v += fixup_sub(terms[terms_i], errors, calculated); } } calculated = true; return v; } } if(input.indexOf("**") >= 0) input.replace("**", "^"); #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) i = input.indexOf(QRegularExpression("[*/]"), 0); #else i = input.indexOf(QRegExp("[*/]"), 0); #endif if(i >= 0) { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) QStringList terms = input.split(QRegularExpression("[*/]")); #else QStringList terms = input.split(QRegExp("[*/]")); #endif QChar c = '*'; i = 0; double v = 1.0; for(int terms_i = 0; terms_i < terms.size(); terms_i++) { if(terms[terms_i].isEmpty()) { if(c == '/') { errors << tr("Empty denominator."); } else { errors << tr("Empty factor."); } } else { i += terms[terms_i].length(); if(c == '/') { double den = fixup_sub(terms[terms_i], errors, calculated); if(den == 0.0) { errors << tr("Division by zero."); } else { v /= den; } } else { v *= fixup_sub(terms[terms_i], errors, calculated); } if(i < input.length()) c = input[i]; } i++; } calculated = true; return v; } i = input.indexOf(QLocale().percent()); if(i >= 0) { double v = 0.01; if(input.length() > 1) { if(i > 0 && i < input.length() - 1) { QString str = input.right(input.length() - 1 - i); input = input.left(i); i = 0; v = fixup_sub(str, errors, calculated) * v; } else if(i == input.length() - 1) { input = input.left(i); } else if(i == 0) { input = input.right(input.length() - 1); } v = fixup_sub(input, errors, calculated) * v; } calculated = true; return v; } if(o_currency) { QString reg_exp_str = "[\\d\\+\\-\\^"; reg_exp_str += '\\'; reg_exp_str += budget->monetary_decimal_separator; reg_exp_str += '\\'; reg_exp_str += budget->monetary_group_separator; if(budget->monetary_decimal_separator != "." && budget->monetary_group_separator != ".") { reg_exp_str += '\\'; reg_exp_str += '.'; } reg_exp_str += "]"; #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) int i = input.indexOf(QRegularExpression(reg_exp_str)); #else int i = input.indexOf(QRegExp(reg_exp_str)); #endif if(i >= 1) { QString scur = input.left(i).trimmed(); Currency *cur = budget->findCurrency(scur); if(!cur && budget->defaultCurrency()->symbol(false) == scur) cur = budget->defaultCurrency(); if(!cur) cur = budget->findCurrencySymbol(scur, true); if(cur) { QString value = input.right(input.length() - i); double v = fixup_sub(value, errors, calculated); if(cur != o_currency) { v = cur->convertTo(v, o_currency); } calculated = true; return v; } errors << tr("Unknown or ambiguous currency, or unrecognized characters, in expression: %1.").arg(scur); } if(i >= 0) { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) i = input.lastIndexOf(QRegularExpression(reg_exp_str)); #else i = input.lastIndexOf(QRegExp(reg_exp_str)); #endif if(i >= 0 && i < input.length() - 1) { QString scur = input.right(input.length() - (i + 1)).trimmed(); Currency *cur = budget->findCurrency(scur); if(!cur && budget->defaultCurrency()->symbol(false) == scur) cur = budget->defaultCurrency(); if(!cur) cur = budget->findCurrencySymbol(scur, true); if(cur) { QString value = input.left(i + 1); double v = fixup_sub(value, errors, calculated); if(cur != o_currency) { v = cur->convertTo(v, o_currency); } calculated = true; return v; } errors << tr("Unknown or ambiguous currency, or unrecognized characters, in expression: %1.").arg(scur); } } else { Currency *cur = budget->findCurrency(input); if(!cur && budget->defaultCurrency()->symbol(false) == input) cur = budget->defaultCurrency(); if(!cur) cur = budget->findCurrencySymbol(input, true); if(cur) { double v = 1.0; if(cur != o_currency) { v = cur->convertTo(v, o_currency); } calculated = true; return v; } errors << tr("Unknown or ambiguous currency, or unrecognized characters, in expression: %1.").arg(input); } } i = input.indexOf('^', 0); if(i >= 0 && i != input.length() - 1) { QString base = input.left(i); if(base.isEmpty()) { errors << tr("Empty base."); } else { QString exp = input.right(input.length() - (i + 1)); double v; if(exp.isEmpty()) { errors << tr("Error"), tr("Empty exponent."); v = 1.0; } else { v = pow(fixup_sub(base, errors, calculated), fixup_sub(exp, errors, calculated)); } calculated = true; return v; } } if(!o_currency) { QString reg_exp_str = "[^\\d\\+\\-"; reg_exp_str += '\\'; reg_exp_str += budget->decimal_separator; reg_exp_str += '\\'; reg_exp_str += budget->group_separator; if(budget->decimal_separator != "." && budget->group_separator != ".") { reg_exp_str += '\\'; reg_exp_str += '.'; } reg_exp_str += "]"; #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) i = input.indexOf(QRegularExpression(reg_exp_str)); #else i = input.indexOf(QRegExp(reg_exp_str)); #endif if(i >= 0) { errors << tr("Unrecognized characters in expression."); } input.remove(budget->group_separator); input.replace(budget->decimal_separator, "."); return input.toDouble(); } input.remove(budget->monetary_group_separator); input.replace(budget->monetary_decimal_separator, "."); return input.toDouble(); } EqonomizeCalendarWidget::EqonomizeCalendarWidget(QWidget *parent) : QCalendarWidget(parent) { setContextMenuPolicy(Qt::CustomContextMenu); connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(popupContextMenu(const QPoint&))); popupMenu = NULL; } void EqonomizeCalendarWidget::keyPressEvent(QKeyEvent *event) { if(event->key() == Qt::Key_Home) { setSelectedDate(QDate::currentDate()); event->accept(); return; } } void EqonomizeCalendarWidget::popupContextMenu(const QPoint &pos) { if(!popupMenu) { popupMenu = new QMenu(this); popupMenu->addAction(tr("Today"), this, SLOT(selectToday())); } popupMenu->popup(mapToGlobal(pos)); } void EqonomizeCalendarWidget::selectToday() { setSelectedDate(QDate::currentDate()); } EqonomizeDateEdit::EqonomizeDateEdit(QWidget *parent) : QDateEdit(QDate::currentDate(), parent) { setCalendarPopup(true); setCalendarWidget(new EqonomizeCalendarWidget(this)); popupMenu = NULL; } EqonomizeDateEdit::EqonomizeDateEdit(const QDate &date, QWidget *parent) : QDateEdit(date, parent) { setCalendarPopup(true); setCalendarWidget(new EqonomizeCalendarWidget(this)); popupMenu = NULL; } void EqonomizeDateEdit::keyPressEvent(QKeyEvent *event) { if(event->key() == Qt::Key_Down || event->key() == Qt::Key_Up) { if(currentSection() == QDateTimeEdit::DaySection) { QDate d = date(); if(event->key() == Qt::Key_Up && d.day() == d.daysInMonth()) { setDate(d.addDays(1)); event->accept(); return; } else if(event->key() == Qt::Key_Down && d.day() == 1) { setDate(d.addDays(-1)); event->accept(); return; } } else if(currentSection() == QDateTimeEdit::MonthSection) { QDate d = date(); if(event->key() == Qt::Key_Up && d.month() == 12) { setDate(d.addMonths(1)); event->accept(); return; } else if(event->key() == Qt::Key_Down && d.month() == 1) { setDate(d.addMonths(-1)); event->accept(); return; } } } else if((event->key() == Qt::Key_PageUp || event->key() == Qt::Key_PageDown)) { if(currentSection() == QDateTimeEdit::DaySection) { setDate(date().addMonths(event->key() == Qt::Key_PageUp ? 1 : -1)); event->accept(); return; } else if(currentSection() == QDateTimeEdit::MonthSection) { setDate(date().addYears(event->key() == Qt::Key_PageUp ? 1 : -1)); event->accept(); return; } } else if(event->key() == Qt::Key_Home && event->modifiers() == Qt::ControlModifier) { setDate(QDate::currentDate()); event->accept(); return; } QDateEdit::keyPressEvent(event); if(event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) { event->accept(); emit returnPressed(); } } void EqonomizeDateEdit::setToday() { setDate(QDate::currentDate()); } void EqonomizeDateEdit::contextMenuEvent(QContextMenuEvent *event) { if(!popupMenu) { popupMenu = lineEdit()->createStandardContextMenu(); popupMenu->addSeparator(); todayAction = popupMenu->addAction(tr("Today"), this, SLOT(setToday()), Qt::CTRL | Qt::Key_Home); } todayAction->setEnabled(date() != QDate::currentDate()); popupMenu->exec(event->globalPos()); } Eqonomize-1.5.3/src/eqonomizevalueedit.h000066400000000000000000000102171416454732000203460ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016-2019 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifndef EQONOMIZE_VALUE_EDIT_H #define EQONOMIZE_VALUE_EDIT_H #include #include #include #include class Currency; class Budget; class QMenu; class EqonomizeValueEdit : public QDoubleSpinBox { Q_OBJECT public: EqonomizeValueEdit(bool allow_negative, QWidget *parent, Budget *budg); EqonomizeValueEdit(double value, bool allow_negative, bool show_currency, QWidget *parent, Budget *budg); EqonomizeValueEdit(double value, int precision, bool allow_negative, bool show_currency, QWidget *parent, Budget *budg); EqonomizeValueEdit(double lower, double step, double value, int precision, bool show_currency, QWidget *parent, Budget *budg); EqonomizeValueEdit(double lower, double upper, double step, double value, int precision, bool show_currency, QWidget *parent, Budget *budg); ~EqonomizeValueEdit(); void init(double lower, double upper, double step, double value, int precision, bool show_currency); void setRange(double lower, double step, int precision); void setRange(double lower, double upper, double step, int precision); void setPrecision(int precision); void setCurrency(Currency *currency, bool keep_precision = false, int as_default = -1, bool is_temporary = false); Currency *currency(); virtual void fixup(QString &input) const; virtual QValidator::State validate(QString &input, int &pos) const; virtual QString textFromValue(double value) const; virtual double valueFromText(const QString &text) const; protected: int i_precision; Budget *budget; Currency *o_currency; QString s_prefix, s_suffix; double fixup_sub(QString &input, QStringList &errors, bool &calculated) const; virtual void focusInEvent(QFocusEvent*); bool eventFilter(QObject*, QEvent*); public slots: void enterFocus(); void selectNumber(); protected slots: void onEditingFinished(); void onTextChanged(const QString&); signals: void returnPressed(); }; class EqonomizeDateEdit : public QDateEdit { Q_OBJECT protected: QMenu *popupMenu; QAction *todayAction; public: EqonomizeDateEdit(QWidget *parent = NULL); EqonomizeDateEdit(const QDate &date, QWidget *parent = NULL); protected slots: void keyPressEvent(QKeyEvent *event); void setToday(); void contextMenuEvent(QContextMenuEvent *event); signals: void returnPressed(); }; class EqonomizeCalendarWidget : public QCalendarWidget { Q_OBJECT protected: QMenu *popupMenu; public: EqonomizeCalendarWidget(QWidget *parent = NULL); protected slots: void keyPressEvent(QKeyEvent *event); void popupContextMenu(const QPoint &pos); void selectToday(); }; extern QString calculatedText; extern const EqonomizeValueEdit *calculatedText_object; #endif Eqonomize-1.5.3/src/importcsvdialog.cpp000066400000000000000000002046141416454732000202040ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "budget.h" #include "eqonomizevalueedit.h" #include "eqonomize.h" #include "importcsvdialog.h" #include #include #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) # define DATE_TO_MSECS(d) QDateTime(d.startOfDay()).toMSecsSinceEpoch() #else # define DATE_TO_MSECS(d) QDateTime(d).toMSecsSinceEpoch() #endif #define ALL_TYPES_ID 5 extern QString last_document_directory; ImportCSVDialog::ImportCSVDialog(bool extra_parameters, Budget *budg, QWidget *parent) : QWizard(parent), b_extra(extra_parameters), budget(budg) { setWindowTitle(tr("Import CSV file")); setModal(true); QIFWizardPage *page1 = new QIFWizardPage(); page1->setTitle(tr("Transaction Type Selection")); setPage(0, page1); QVBoxLayout *layout1 = new QVBoxLayout(page1); typeGroup = new QButtonGroup(this); QVBoxLayout *typeGroup_layout = new QVBoxLayout(); layout1->addLayout(typeGroup_layout); QRadioButton *rb = new QRadioButton(tr("Expenses")); rb->setChecked(true); typeGroup_layout->addWidget(rb); typeGroup->addButton(rb, 0); rb->setFocus(); rb = new QRadioButton(tr("Incomes")); typeGroup_layout->addWidget(rb); typeGroup->addButton(rb, 1); rb = new QRadioButton(tr("Transfers")); typeGroup_layout->addWidget(rb); typeGroup->addButton(rb, 2); rb = new QRadioButton(tr("Expenses and incomes (negative cost)")); typeGroup_layout->addWidget(rb); typeGroup->addButton(rb, 3); rb = new QRadioButton(tr("Expenses and incomes (separate columns)")); typeGroup_layout->addWidget(rb); typeGroup->addButton(rb, 4); rb = new QRadioButton(tr("All types")); typeGroup_layout->addWidget(rb); typeGroup->addButton(rb, 5); typeDescriptionLabel = new QLabel(page1); typeDescriptionLabel->setWordWrap(true); layout1->addWidget(typeDescriptionLabel); layout1->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Expanding)); QHBoxLayout *layoutPreset = new QHBoxLayout(); presetLabel = new QLabel(tr("Presets:")); layoutPreset->addWidget(presetLabel); presetCombo = new QComboBox(); presetCombo->setMinimumContentsLength(20); presetCombo->setEditable(false); QSettings settings; settings.beginGroup("GeneralOptions"); presets = settings.value("CSVPresets").toMap(); for(QMap::const_iterator it = presets.constBegin(); it != presets.constEnd(); ++it) { presetCombo->addItem(it.key()); } if(presetCombo->count() == 0) presetCombo->setEnabled(false); else presetCombo->setCurrentIndex(-1); layoutPreset->addWidget(presetCombo); layoutPreset->addStretch(1); layout1->addLayout(layoutPreset); QIFWizardPage *page2 = new QIFWizardPage(); page2->setTitle(tr("File Selection")); setPage(1, page2); QGridLayout *layout2 = new QGridLayout(page2); layout2->addWidget(new QLabel(tr("File:"), page2), 0, 0); QHBoxLayout *layout2h = new QHBoxLayout(); fileEdit = new QLineEdit(page2); QCompleter *completer = new QCompleter(this); QFileSystemModel *fsModel = new QFileSystemModel(completer); fsModel->setRootPath(QString()); completer->setModel(fsModel); fileEdit->setCompleter(completer); layout2h->addWidget(fileEdit); fileButton = new QPushButton(LOAD_ICON("document-open"), QString(), page2); layout2h->addWidget(fileButton); layout2->addLayout(layout2h, 0, 1); layout2->addWidget(new QLabel(tr("First data row:"), page2), 1, 0); rowEdit = new QSpinBox(page2); rowEdit->setRange(0, 1000); rowEdit->setSpecialValueText(tr("Auto")); rowEdit->setValue(0); layout2->addWidget(rowEdit, 1, 1); layout2->addWidget(new QLabel(tr("Column delimiter:"), page2), 2, 0); delimiterCombo = new QComboBox(page2); delimiterCombo->setEditable(false); delimiterCombo->addItem(tr("Comma")); delimiterCombo->addItem(tr("Tabulator")); delimiterCombo->addItem(tr("Semicolon")); delimiterCombo->addItem(tr("Space")); delimiterCombo->addItem(tr("Other")); layout2->addWidget(delimiterCombo, 2, 1); delimiterEdit = new QLineEdit(page2); delimiterEdit->setEnabled(false); layout2->addWidget(delimiterEdit, 3, 1); layout2->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Expanding), 4, 0, 1, 2); QIFWizardPage *page3 = new QIFWizardPage(); page3->setTitle(tr("Columns Specification")); setPage(2, page3); QGridLayout *layout3 = new QGridLayout(page3); int row = 0; layout3->addWidget(new QLabel(tr("Date:"), page3), row, 0); dateGroup = new QButtonGroup(this); columnDateButton = new QRadioButton(tr("Column"), page3); dateGroup->addButton(columnDateButton); layout3->addWidget(columnDateButton, row, 1); columnDateEdit = new QSpinBox(page3); columnDateEdit->setRange(1, 100); columnDateEdit->setValue(1); columnDateButton->setChecked(true); layout3->addWidget(columnDateEdit, row, 2); valueDateButton = new QRadioButton(tr("Value"), page3); dateGroup->addButton(valueDateButton); layout3->addWidget(valueDateButton, row, 3); valueDateEdit = new EqonomizeDateEdit(QDate::currentDate(), page3); valueDateEdit->setCalendarPopup(true); valueDateEdit->setEnabled(false); layout3->addWidget(valueDateEdit, row, 4); row++; layout3->addWidget(new QLabel(tr("Description:", "Transaction description property (transaction title/generic article name)"), page3), row, 0); descriptionGroup = new QButtonGroup(this); columnDescriptionButton = new QRadioButton(tr("Column"), page3); descriptionGroup->addButton(columnDescriptionButton); layout3->addWidget(columnDescriptionButton, row, 1); columnDescriptionEdit = new QSpinBox(page3); columnDescriptionEdit->setRange(1, 100); columnDescriptionEdit->setValue(2); columnDescriptionButton->setChecked(true); layout3->addWidget(columnDescriptionEdit, row, 2); valueDescriptionButton = new QRadioButton(tr("Value"), page3); descriptionGroup->addButton(valueDescriptionButton); layout3->addWidget(valueDescriptionButton, row, 3); valueDescriptionEdit = new QLineEdit(page3); valueDescriptionEdit->setEnabled(false); layout3->addWidget(valueDescriptionEdit, row, 4); row++; costLabel = new QLabel(tr("Cost:"), page3); layout3->addWidget(costLabel, row, 0); costGroup = new QButtonGroup(this); columnCostButton = new QRadioButton(tr("Column"), page3); costGroup->addButton(columnCostButton); layout3->addWidget(columnCostButton, row, 1); columnCostEdit = new QSpinBox(page3); columnCostEdit->setRange(1, 100); columnCostEdit->setValue(3); columnCostButton->setChecked(true); layout3->addWidget(columnCostEdit, row, 2); valueCostButton = new QRadioButton(tr("Value"), page3); costGroup->addButton(valueCostButton); layout3->addWidget(valueCostButton, row, 3); valueCostEdit = new EqonomizeValueEdit(false, page3, budget); valueCostEdit->setEnabled(false); layout3->addWidget(valueCostEdit, row, 4); row++; valueLabel = new QLabel(tr("Cost:"), page3); layout3->addWidget(valueLabel, row, 0); valueGroup = new QButtonGroup(this); columnValueButton = new QRadioButton(tr("Column"), page3); valueGroup->addButton(columnValueButton); layout3->addWidget(columnValueButton, row, 1); columnValueEdit = new QSpinBox(page3); columnValueEdit->setRange(1, 100); columnValueEdit->setValue(3); columnValueButton->setChecked(true); layout3->addWidget(columnValueEdit, row, 2); valueValueButton = new QRadioButton(tr("Value"), page3); valueGroup->addButton(valueValueButton); layout3->addWidget(valueValueButton, row, 3); valueValueEdit = new EqonomizeValueEdit(false, page3, budget); valueValueEdit->setEnabled(false); layout3->addWidget(valueValueEdit, row, 4); row++; AC1Label = new QLabel(tr("Category:"), page3); layout3->addWidget(AC1Label, row, 0); AC1Group = new QButtonGroup(this); columnAC1Button = new QRadioButton(tr("Column"), page3); AC1Group->addButton(columnAC1Button); layout3->addWidget(columnAC1Button, row, 1); columnAC1Edit = new QSpinBox(page3); columnAC1Edit->setRange(1, 100); columnAC1Edit->setValue(4); columnAC1Edit->setEnabled(false); layout3->addWidget(columnAC1Edit, row, 2); valueAC1Button = new QRadioButton(tr("Value"), page3); AC1Group->addButton(valueAC1Button); valueAC1Button->setChecked(true); layout3->addWidget(valueAC1Button, row, 3); valueAC1Edit = new QComboBox(page3); valueAC1Edit->setEditable(false); layout3->addWidget(valueAC1Edit, row, 4); row++; valueAC1IncomeEdit = new QComboBox(page3); valueAC1IncomeEdit->setEditable(false); layout3->addWidget(valueAC1IncomeEdit, row, 4); row++; AC2Label = new QLabel(tr("From account:"), page3); layout3->addWidget(AC2Label, row, 0); AC2Group = new QButtonGroup(this); columnAC2Button = new QRadioButton(tr("Column"), page3); AC2Group->addButton(columnAC2Button); layout3->addWidget(columnAC2Button, row, 1); columnAC2Edit = new QSpinBox(page3); columnAC2Edit->setRange(1, 100); columnAC2Edit->setValue(5); columnAC2Edit->setEnabled(false); layout3->addWidget(columnAC2Edit, row, 2); valueAC2Button = new QRadioButton(tr("Value"), page3); AC2Group->addButton(valueAC2Button); valueAC2Button->setChecked(true); layout3->addWidget(valueAC2Button, row, 3); valueAC2Edit = new QComboBox(page3); valueAC2Edit->setEditable(false); layout3->addWidget(valueAC2Edit, row, 4); row++; if(b_extra) { quantityLabel = new QLabel(tr("Quantity:"), page3); layout3->addWidget(quantityLabel, row, 0); quantityGroup = new QButtonGroup(this); columnQuantityButton = new QRadioButton(tr("Column"), page3); quantityGroup->addButton(columnQuantityButton); layout3->addWidget(columnQuantityButton, row, 1); columnQuantityEdit = new QSpinBox(page3); columnQuantityEdit->setRange(1, 100); columnQuantityEdit->setValue(6); columnQuantityEdit->setEnabled(false); layout3->addWidget(columnQuantityEdit, row, 2); valueQuantityButton = new QRadioButton(tr("Value"), page3); quantityGroup->addButton(valueQuantityButton); valueQuantityButton->setChecked(true); layout3->addWidget(valueQuantityButton, row, 3); valueQuantityEdit = new EqonomizeValueEdit(1.0, 2, false, false, page3, budget); layout3->addWidget(valueQuantityEdit, row, 4); row++; payeeLabel = new QLabel(tr("Payee:"), page3); layout3->addWidget(payeeLabel, row, 0); payeeGroup = new QButtonGroup(this); columnPayeeButton = new QRadioButton(tr("Column"), page3); payeeGroup->addButton(columnPayeeButton); layout3->addWidget(columnPayeeButton, row, 1); columnPayeeEdit = new QSpinBox(page3); columnPayeeEdit->setRange(1, 100); columnPayeeEdit->setValue(7); columnPayeeEdit->setEnabled(false); layout3->addWidget(columnPayeeEdit, row, 2); valuePayeeButton = new QRadioButton(tr("Value"), page3); payeeGroup->addButton(valuePayeeButton); valuePayeeButton->setChecked(true); layout3->addWidget(valuePayeeButton, row, 3); valuePayeeEdit = new QLineEdit(page3); layout3->addWidget(valuePayeeEdit, row, 4); row++; } tagsLabel = new QLabel(tr("Tags:"), page3); layout3->addWidget(tagsLabel, row, 0); tagsGroup = new QButtonGroup(this); columnTagsButton = new QRadioButton(tr("Column"), page3); tagsGroup->addButton(columnTagsButton); layout3->addWidget(columnTagsButton, row, 1); columnTagsEdit = new QSpinBox(page3); columnTagsEdit->setRange(1, 100); columnTagsEdit->setValue(b_extra ? 8 : 6); columnTagsEdit->setEnabled(false); layout3->addWidget(columnTagsEdit, row, 2); valueTagsButton = new QRadioButton(tr("Value"), page3); tagsGroup->addButton(valueTagsButton); valueTagsButton->setChecked(true); layout3->addWidget(valueTagsButton, row, 3); valueTagsEdit = new QLineEdit(page3); layout3->addWidget(valueTagsEdit, row, 4); row++; layout3->addWidget(new QLabel(tr("Comments:"), page3), row, 0); commentsGroup = new QButtonGroup(this); columnCommentsButton = new QRadioButton(tr("Column"), page3); commentsGroup->addButton(columnCommentsButton); layout3->addWidget(columnCommentsButton, row, 1); columnCommentsEdit = new QSpinBox(page3); columnCommentsEdit->setRange(1, 100); columnCommentsEdit->setValue(b_extra ? 8 : 6); columnCommentsEdit->setEnabled(false); layout3->addWidget(columnCommentsEdit, row, 2); valueCommentsButton = new QRadioButton(tr("Value"), page3); commentsGroup->addButton(valueCommentsButton); valueCommentsButton->setChecked(true); layout3->addWidget(valueCommentsButton, row, 3); valueCommentsEdit = new QLineEdit(page3); layout3->addWidget(valueCommentsEdit, row, 4); row++; QHBoxLayout *layout3_cm = new QHBoxLayout(); layout3_cm->addStretch(1); createMissingButton = new QCheckBox(tr("Create missing categories and accounts"), page3); createMissingButton->setChecked(true); layout3_cm->addWidget(createMissingButton); layout3->addLayout(layout3_cm, row, 0, 1, 5); row++; QHBoxLayout *layoutPreset2 = new QHBoxLayout(); layoutPreset2->addStretch(1); savePresetButton = new QPushButton(tr("Save as preset…"), page3); layoutPreset2->addWidget(savePresetButton); layout3->addLayout(layoutPreset2, row, 0, 1, 5); row++; layout3->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Expanding), row, 0, 1, 5); setOption(QWizard::HaveHelpButton, false); page3->setFinalPage(true); page1->setComplete(true); page2->setComplete(false); page3->setComplete(true); disconnect(button(NextButton), SIGNAL(clicked()), this, 0); connect(button(NextButton), SIGNAL(clicked()), this, SLOT(nextClicked())); typeChanged(0); connect(fileEdit, SIGNAL(textChanged(const QString&)), this, SLOT(onFileChanged(const QString&))); connect(fileButton, SIGNAL(clicked()), this, SLOT(selectFile())); connect(delimiterCombo, SIGNAL(activated(int)), this, SLOT(delimiterChanged(int))); connect(columnDescriptionButton, SIGNAL(toggled(bool)), columnDescriptionEdit, SLOT(setEnabled(bool))); connect(valueDescriptionButton, SIGNAL(toggled(bool)), valueDescriptionEdit, SLOT(setEnabled(bool))); connect(columnValueButton, SIGNAL(toggled(bool)), columnValueEdit, SLOT(setEnabled(bool))); connect(valueValueButton, SIGNAL(toggled(bool)), valueValueEdit, SLOT(setEnabled(bool))); connect(columnDateButton, SIGNAL(toggled(bool)), columnDateEdit, SLOT(setEnabled(bool))); connect(valueDateButton, SIGNAL(toggled(bool)), valueDateEdit, SLOT(setEnabled(bool))); connect(columnAC1Button, SIGNAL(toggled(bool)), columnAC1Edit, SLOT(setEnabled(bool))); connect(valueAC1Button, SIGNAL(toggled(bool)), valueAC1Edit, SLOT(setEnabled(bool))); connect(valueAC1Button, SIGNAL(toggled(bool)), valueAC1IncomeEdit, SLOT(setEnabled(bool))); connect(columnAC2Button, SIGNAL(toggled(bool)), columnAC2Edit, SLOT(setEnabled(bool))); connect(valueAC2Button, SIGNAL(toggled(bool)), valueAC2Edit, SLOT(setEnabled(bool))); connect(columnTagsButton, SIGNAL(toggled(bool)), columnTagsEdit, SLOT(setEnabled(bool))); connect(valueTagsButton, SIGNAL(toggled(bool)), valueTagsEdit, SLOT(setEnabled(bool))); connect(columnCommentsButton, SIGNAL(toggled(bool)), columnCommentsEdit, SLOT(setEnabled(bool))); connect(valueCommentsButton, SIGNAL(toggled(bool)), valueCommentsEdit, SLOT(setEnabled(bool))); #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) connect(typeGroup, SIGNAL(idClicked(int)), this, SLOT(typeChanged(int))); #else connect(typeGroup, SIGNAL(buttonClicked(int)), this, SLOT(typeChanged(int))); #endif if(b_extra) { connect(columnQuantityButton, SIGNAL(toggled(bool)), columnQuantityEdit, SLOT(setEnabled(bool))); connect(valueQuantityButton, SIGNAL(toggled(bool)), valueQuantityEdit, SLOT(setEnabled(bool))); connect(columnPayeeButton, SIGNAL(toggled(bool)), columnPayeeEdit, SLOT(setEnabled(bool))); connect(valuePayeeButton, SIGNAL(toggled(bool)), valuePayeeEdit, SLOT(setEnabled(bool))); } connect(presetCombo, SIGNAL(activated(int)), this, SLOT(loadPreset(int))); connect(savePresetButton, SIGNAL(clicked()), this, SLOT(savePreset())); page3->adjustSize(); page2->setMinimumWidth(page3->minimumSizeHint().width() + 100); page2->setMinimumHeight(page3->minimumSizeHint().height() + 100); page1->setMinimumSize(page2->minimumSize()); costLabel->hide(); valueCostEdit->hide(); valueCostButton->hide(); columnCostEdit->hide(); columnCostButton->hide(); } ImportCSVDialog::~ImportCSVDialog() { } void ImportCSVDialog::loadPreset(int index) { s_preset = presetCombo->itemText(index); if(!presets.contains(s_preset)) return; QList preset = presets[s_preset].toList(); if(preset.count() < 26) return; typeGroup->button(preset.at(0).toInt())->setChecked(true); typeChanged(preset.at(0).toInt()); fileEdit->setText(preset.at(1).toString()); rowEdit->setValue(preset.at(2).toInt()); QString delimiter = preset.at(3).toString(); if(delimiter == ",") delimiterCombo->setCurrentIndex(0); else if(delimiter == "\t") delimiterCombo->setCurrentIndex(1); else if(delimiter == ";") delimiterCombo->setCurrentIndex(2); else if(delimiter == " ") delimiterCombo->setCurrentIndex(3); else { delimiterCombo->setCurrentIndex(4); delimiterEdit->setText(delimiter); } int i = 4; if(preset.at(i).toBool()) { valueDateButton->setChecked(true); valueDateEdit->setDate(preset.at(i + 1).toDate()); } else { columnDateButton->setChecked(true); columnDateEdit->setValue(preset.at(i + 1).toInt()); } i += 2; if(preset.at(i).toBool()) { valueDescriptionButton->setChecked(true); valueDescriptionEdit->setText(preset.at(i + 1).toString()); } else { columnDescriptionButton->setChecked(true); columnDescriptionEdit->setValue(preset.at(i + 1).toInt()); } i += 2; if(preset.at(i).toBool()) { valueCostButton->setChecked(true); valueCostEdit->setValue(preset.at(i + 1).toDouble()); } else { columnCostButton->setChecked(true); columnCostEdit->setValue(preset.at(i + 1).toInt()); } i += 2; if(preset.at(i).toBool()) { valueValueButton->setChecked(true); valueValueEdit->setValue(preset.at(i + 1).toDouble()); } else { columnValueButton->setChecked(true); columnValueEdit->setValue(preset.at(i + 1).toInt()); } i += 2; if(preset.at(i).toBool()) { valueAC1Button->setChecked(true); qlonglong id = preset.at(i + 1).toLongLong(); bool b = false; for(int acc_i = 0; acc_i < valueAC1Edit->count(); acc_i++) { if(((Account*) valueAC1Edit->itemData(acc_i).value())->id() == id) { valueAC1Edit->setCurrentIndex(acc_i); b = true; break; } } if(!b) valueAC1Edit->setCurrentIndex(0); id = preset.at(i + 2).toLongLong(); b = false; for(int acc_i = 0; acc_i < valueAC1IncomeEdit->count(); acc_i++) { if(((Account*) valueAC1IncomeEdit->itemData(acc_i).value())->id() == id) { valueAC1IncomeEdit->setCurrentIndex(acc_i); b = true; break; } } if(!b) valueAC1IncomeEdit->setCurrentIndex(0); } else { columnAC1Button->setChecked(true); columnAC1Edit->setValue(preset.at(i + 1).toInt()); } i += 3; if(preset.at(i).toBool()) { valueAC2Button->setChecked(true); qlonglong id = preset.at(i + 1).toLongLong(); bool b = false; for(int acc_i = 0; acc_i < valueAC2Edit->count(); acc_i++) { if(((Account*) valueAC2Edit->itemData(acc_i).value())->id() == id) { valueAC2Edit->setCurrentIndex(acc_i); b = true; break; } } if(!b) valueAC2Edit->setCurrentIndex(0); } else { columnAC2Button->setChecked(true); columnAC2Edit->setValue(preset.at(i + 1).toInt()); } i += 2; if(b_extra) { if(preset.at(i).toBool()) { valueQuantityButton->setChecked(true); valueQuantityEdit->setValue(preset.at(i + 1).toDouble()); } else { columnQuantityButton->setChecked(true); columnQuantityEdit->setValue(preset.at(i + 1).toInt()); } i += 2; if(preset.at(i).toBool()) { valuePayeeButton->setChecked(true); valuePayeeEdit->setText(preset.at(i + 1).toString()); } else { columnPayeeButton->setChecked(true); columnPayeeEdit->setValue(preset.at(i + 1).toInt()); } i += 2; } else { i += 4; } if(preset.at(i).toBool()) { valueTagsButton->setChecked(true); valueTagsEdit->setText(preset.at(i + 1).toString()); } else { columnTagsButton->setChecked(true); columnTagsEdit->setValue(preset.at(i + 1).toInt()); } i += 2; if(preset.at(i).toBool()) { valueCommentsButton->setChecked(true); valueCommentsEdit->setText(preset.at(i + 1).toString()); } else { columnCommentsButton->setChecked(true); columnCommentsEdit->setValue(preset.at(i + 1).toInt()); } i += 2; createMissingButton->setChecked(preset.at(i).toBool()); } void ImportCSVDialog::savePreset() { QDialog *dialog = new QDialog(this); dialog->setWindowTitle(tr("Save Preset")); QVBoxLayout *box1 = new QVBoxLayout(dialog); QComboBox *presetEdit = new QComboBox(dialog); presetEdit->setMinimumContentsLength(20); presetEdit->setEditable(true); for(QMap::const_iterator it = presets.constBegin(); it != presets.constEnd(); ++it) { presetEdit->addItem(it.key()); } presetEdit->setCurrentText(s_preset); box1->addWidget(presetEdit); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, dialog); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), dialog, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), dialog, SLOT(accept())); box1->addWidget(buttonBox); if(dialog->exec() == QDialog::Accepted) { QList preset; s_preset = presetEdit->currentText(); preset << typeGroup->checkedId(); preset << fileEdit->text(); preset << rowEdit->value(); switch(delimiterCombo->currentIndex()) { case 0: {preset << ","; break;} case 1: {preset << "\t"; break;} case 2: {preset << ";"; break;} case 3: {preset << " "; break;} default: {preset << delimiterEdit->text();} } if(valueDateButton->isChecked()) { preset << true; preset << valueDateEdit->date(); } else { preset << false; preset << columnDateEdit->value(); } if(valueDescriptionButton->isChecked()) { preset << true; preset << valueDescriptionEdit->text(); } else { preset << false; preset << columnDescriptionEdit->value(); } if(valueCostButton->isChecked()) { preset << true; preset << valueCostEdit->value(); } else { preset << false; preset << columnCostEdit->value(); } if(valueValueButton->isChecked()) { preset << true; preset << valueValueEdit->value(); } else { preset << false; preset << columnValueEdit->value(); } if(valueAC1Button->isChecked()) { preset << true; if(valueAC1Edit->currentIndex() >= 0) { preset << ((Account*) valueAC1Edit->currentData().value())->id(); } else { preset << (qlonglong) 0; } if(valueAC1IncomeEdit->currentIndex() >= 0) { preset << ((Account*) valueAC1IncomeEdit->currentData().value())->id(); } else { preset << (qlonglong) 0; } } else { preset << false; preset << columnAC1Edit->value(); preset << 0; } if(valueAC2Button->isChecked()) { preset << true; if(valueAC2Edit->currentIndex() >= 0) { preset << ((Account*) valueAC2Edit->currentData().value())->id(); } else { preset << (qlonglong) 0; } } else { preset << false; preset << columnAC2Edit->value(); } if(b_extra) { if(valueQuantityButton->isChecked()) { preset << true; preset << valueQuantityEdit->value(); } else { preset << false; preset << columnQuantityEdit->value(); } if(valuePayeeButton->isChecked()) { preset << true; preset << valuePayeeEdit->text(); } else { preset << false; preset << columnPayeeEdit->value(); } } else { preset << true; preset << 1.0; preset << true; preset << QString(); } if(valueTagsButton->isChecked()) { preset << true; preset << valueTagsEdit->text(); } else { preset << false; preset << columnTagsEdit->value(); } if(valueCommentsButton->isChecked()) { preset << true; preset << valueCommentsEdit->text(); } else { preset << false; preset << columnCommentsEdit->value(); } preset << createMissingButton->isChecked(); presets[s_preset] = preset; if(presetEdit->currentIndex() >= 0) { presetCombo->setCurrentIndex(presetEdit->currentIndex()); } else { presetCombo->addItem(s_preset); presetCombo->setCurrentIndex(presetCombo->count() - 1); presetCombo->setEnabled(true); } QSettings settings; settings.beginGroup("GeneralOptions"); settings.setValue("CSVPresets", presets); } dialog->deleteLater(); } void ImportCSVDialog::onFileChanged(const QString &str) { ((QIFWizardPage*) page(1))->setComplete(!str.isEmpty()); } void ImportCSVDialog::selectFile() { QMimeDatabase db; QString url = QFileDialog::getOpenFileName(this, QString(), fileEdit->text().isEmpty() ? last_document_directory + "/" : fileEdit->text().trimmed(), db.mimeTypeForName("text/csv").filterString()); if(!url.isEmpty()) fileEdit->setText(url); } void ImportCSVDialog::delimiterChanged(int index) { delimiterEdit->setEnabled(index == 4); } void ImportCSVDialog::typeChanged(int id) { valueAC1Button->setChecked(true); columnAC1Edit->setEnabled(false); valueAC1Edit->setEnabled(true); valueAC1Button->setEnabled(true); valueAC2Button->setChecked(true); columnAC2Edit->setEnabled(false); valueAC2Edit->setEnabled(true); valueAC2Button->setEnabled(true); createMissingButton->setEnabled(id != ALL_TYPES_ID); createMissingButton->setChecked(id != ALL_TYPES_ID); valueAC1Edit->clear(); valueAC1IncomeEdit->clear(); valueAC2Edit->clear(); if(id < 5) { for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { AssetsAccount *aa = *it; if(aa != budget->balancingAccount && aa->accountType() != ASSETS_TYPE_SECURITIES) valueAC2Edit->addItem(aa->nameWithParent(), QVariant::fromValue((void*) aa)); } } if(b_extra) { quantityLabel->setVisible(id != 2); valueQuantityEdit->setVisible(id != 2); columnQuantityEdit->setVisible(id != 2); columnQuantityButton->setVisible(id != 2); valueQuantityButton->setVisible(id != 2); payeeLabel->setVisible(id != 2); valuePayeeEdit->setVisible(id != 2); columnPayeeEdit->setVisible(id != 2); columnPayeeButton->setVisible(id != 2); valuePayeeButton->setVisible(id != 2); valueQuantityButton->setChecked(id == 2); valuePayeeButton->setChecked(id == 2); } valueTagsButton->setChecked(id == 2); tagsLabel->setVisible(id != 2); valueTagsEdit->setVisible(id != 2); columnTagsEdit->setVisible(id != 2); columnTagsButton->setVisible(id != 2); valueTagsButton->setVisible(id != 2); valueAC1IncomeEdit->setVisible(id == 3 || id == 4); if(id == 4) { costLabel->show(); valueCostEdit->show(); columnCostEdit->show(); columnCostButton->show(); valueCostButton->show(); columnCostButton->setChecked(true); valueCostButton->setEnabled(false); valueCostEdit->setEnabled(false); columnValueEdit->setValue(4); columnAC1Edit->setValue(5); columnAC2Edit->setValue(6); if(b_extra) { columnQuantityEdit->setValue(7); columnPayeeEdit->setValue(8); columnTagsEdit->setValue(9); columnCommentsEdit->setValue(10); } else { columnTagsEdit->setValue(7); columnCommentsEdit->setValue(8); } } else { costLabel->hide(); valueCostEdit->hide(); columnCostEdit->hide(); columnCostButton->hide(); valueCostButton->hide(); columnValueEdit->setValue(3); columnAC1Edit->setValue(4); columnAC2Edit->setValue(5); if(id == 2) { columnCommentsEdit->setValue(6); } else if(b_extra) { columnQuantityEdit->setValue(6); columnPayeeEdit->setValue(7); columnTagsEdit->setValue(8); columnCommentsEdit->setValue(9); } else { columnTagsEdit->setValue(6); columnCommentsEdit->setValue(7); } } switch(id) { case 0: { typeDescriptionLabel->setText(tr("Imports data as expenses. Costs have positive value. Value is the only required column.")); valueLabel->setText(tr("Cost:")); AC1Label->setText(tr("Category:")); AC2Label->setText(tr("From account:")); if(b_extra) payeeLabel->setText(tr("Payee:")); for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) { ExpensesAccount *ea = *it; valueAC1Edit->addItem(ea->nameWithParent(), QVariant::fromValue((void*) ea)); } break; } case 1: { typeDescriptionLabel->setText(tr("Imports data as incomes. Value is the only required column.")); valueLabel->setText(tr("Income:")); AC1Label->setText(tr("Category:")); AC2Label->setText(tr("To account:")); if(b_extra) payeeLabel->setText(tr("Payer:")); for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) { IncomesAccount *ia = *it; valueAC1Edit->addItem(ia->nameWithParent(), QVariant::fromValue((void*) ia)); } break; } case 2: { typeDescriptionLabel->setText(tr("Imports data as transfers. Value is the only required column.")); valueLabel->setText(tr("Amount:")); AC1Label->setText(tr("From account:")); AC2Label->setText(tr("To account:")); for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { AssetsAccount *aa = *it; if(aa != budget->balancingAccount && aa->accountType() != ASSETS_TYPE_SECURITIES) valueAC1Edit->addItem(aa->nameWithParent(), QVariant::fromValue((void*) *it)); } break; } case 3: { typeDescriptionLabel->setText(tr("Imports data as expenses and incomes. Costs have negative value. Value is the only required column.")); valueLabel->setText(tr("Value:")); AC1Label->setText(tr("Category:")); AC2Label->setText(tr("Account:")); for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) { ExpensesAccount *ea = *it; valueAC1Edit->addItem(ea->nameWithParent(), QVariant::fromValue((void*) ea)); } for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) { IncomesAccount *ia = *it; valueAC1IncomeEdit->addItem(ia->nameWithParent(), QVariant::fromValue((void*) ia)); } if(b_extra) payeeLabel->setText(tr("Payee/payer:")); break; } case 4: { typeDescriptionLabel->setText(tr("Imports data as expenses and incomes. Costs and incomes have separate columns. Income and cost both all required columns.")); valueLabel->setText(tr("Income:")); AC1Label->setText(tr("Category:")); AC2Label->setText(tr("Account:")); for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) { ExpensesAccount *ea = *it; valueAC1Edit->addItem(ea->nameWithParent(), QVariant::fromValue((void*) ea)); } for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) { IncomesAccount *ia = *it; valueAC1IncomeEdit->addItem(ia->nameWithParent(), QVariant::fromValue((void*) ia)); } if(b_extra) payeeLabel->setText(tr("Payee/payer:")); break; } case ALL_TYPES_ID: { typeDescriptionLabel->setText(tr("Imports data as expenses, incomes, and transfers. Costs have negative or positive value. Value, to, and from are all required columns. Accounts and categories must be existing.")); columnAC1Button->setChecked(true); columnAC1Edit->setEnabled(true); valueAC1Edit->setEnabled(false); valueAC1Button->setEnabled(false); columnAC2Button->setChecked(true); columnAC2Edit->setEnabled(true); valueAC2Edit->setEnabled(false); valueAC2Button->setEnabled(false); valueLabel->setText(tr("Value:")); AC1Label->setText(tr("From:")); AC2Label->setText(tr("To:")); if(b_extra) payeeLabel->setText(tr("Payee/payer:")); break; } } columnValueButton->setChecked(true); valueValueButton->setEnabled(false); if(valueAC1Edit->count() == 0) { columnAC1Button->setChecked(true); columnAC1Edit->setEnabled(true); valueAC1Edit->setEnabled(false); valueAC1Button->setEnabled(false); } if((id == 3 || id == 4) && valueAC1IncomeEdit->count() == 0) { columnAC1Button->setChecked(true); columnAC1Edit->setEnabled(true); valueAC1Edit->setEnabled(false); valueAC1Button->setEnabled(false); } if(valueAC2Edit->count() == 0) { columnAC2Button->setChecked(true); columnAC2Edit->setEnabled(true); valueAC2Edit->setEnabled(false); valueAC2Button->setEnabled(false); } } void ImportCSVDialog::nextClicked() { if(currentPage() == page(0)) { fileEdit->setFocus(); } else if(currentPage() == page(1)) { QString url = fileEdit->text().trimmed(); if(url.isEmpty()) { QMessageBox::critical(this, tr("Error"), tr("A file must be selected.")); fileEdit->setFocus(); return; } else { QFileInfo info(url); if(info.isDir()) { QMessageBox::critical(this, tr("Error"), tr("Selected file is a directory.")); fileEdit->setFocus(); return; } else if(!info.exists()) { QMessageBox::critical(this, tr("Error"), tr("Selected file does not exist.")); fileEdit->setFocus(); return; } } if(delimiterCombo->currentIndex() == 4 && delimiterEdit->text().isEmpty()) { QMessageBox::critical(this, tr("Error"), tr("Empty delimiter.")); delimiterEdit->setFocus(); return; } columnDescriptionEdit->setFocus(); } QWizard::next(); } QDate readCSVDate(const QString &str, const QString &date_format, const QString &alt_date_format) { QDate date = QDate::fromString(str, date_format); if(!date.isValid() && !alt_date_format.isEmpty()) { date = QDate::fromString(str, alt_date_format); if(date.year() < 1970 && alt_date_format.count('y') < 4) { date = date.addYears(100); } } else if(date.year() < 1970 && date_format.count('y') < 4) { date = date.addYears(100); } return date; } double readCSVValue(const QString &str, int value_format, bool *ok) { QString str2 = str; int l = (int) str2.length(); str2.replace(QLocale().negativeSign(), "-"); str2.replace(QLocale().positiveSign(), "+"); str2.replace(QChar(0x2212), "-"); if(value_format == 2) { str2.replace(".", ""); str2.replace(",", "."); } else if(value_format == 1) { str2.replace(",", ""); } for(int i = 0; i < l; i++) { if(str2[i].isDigit() || str2[i] == '+' || str2[i] == '-' || str2[i] == '.') { if(i > 0) { str2.remove(0, i); l -= i; } break; } } l--; for(int i = l; i >= 0; i--) { if(str2[i].isDigit()) { if(i < l) { str2.truncate(i + 1); } break; } } return str2.toDouble(ok); } //p1 MDY //p2 DMY //p3 YMD //p4 YDM void testCSVDate(const QString &str, bool &p1, bool &p2, bool &p3, bool &p4, bool &ly, char &separator, int &lz) { if(separator < 0) { for(int i = 0; i < (int) str.length(); i++) { if(str[i] < '0' || str[i] > '9') { separator = str[i].toLatin1(); break; } } if(separator < 0) separator = 0; p1 = (separator != 0 || str.length() == 6); p2 = (separator != 0 || str.length() == 6); p3 = true; p4 = (separator != 0 || str.length() == 6); ly = (separator == 0 && str.length() >= 8); } if(p1 + p2 + p3 + p4 <= 1) { lz = 1; return; } QStringList strlist; if(separator == 0) { strlist << str.left(2); strlist << str.mid(2, 2); strlist << str.right(2); } else { #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) strlist = str.split(separator, Qt::SkipEmptyParts); #else strlist = str.split(separator, QString::SkipEmptyParts); #endif } if(strlist.count() == 2 && (p1 || p2)) { int i = strlist[1].indexOf('\''); if(i >= 0) { strlist.append(strlist[1]); strlist[2].remove(0, i + 1); strlist[1].truncate(i); p3 = false; p4 = false; ly = false; } } if(strlist.count() < 3) return; if(p1 || p2) { int v1 = strlist[0].toInt(); if(v1 > 12) p1 = false; if(v1 > 31 || v1 < 1) { p2 = false; if(v1 >= 100) ly = true; else ly = false; } } int v2 = strlist[1].toInt(); if(v2 > 12) {p2 = false; p3 = false;} int v3 = strlist[2].toInt(); if(v3 > 12) p4 = false; if(v3 > 31 || v3 < 1) { p3 = false; if(v3 >= 100) ly = true; else ly = false; } if(strlist[1].length() == 1) lz = 0; else if(strlist[1][0] == '0') lz = 1; else if(!p3 && !p4 && strlist[0].length() == 1) lz = 0; else if(!p3 && !p4 && strlist[0][0] == '0') lz = 1; else if(!p1 && !p2 && strlist[2].length() == 1) lz = 0; else if(!p1 && !p2 && strlist[2][0] == '0') lz = 1; } void testCSVValue(const QString &str, int &value_format) { if(value_format <= 0) { int i = str.lastIndexOf('.'); int i2 = str.lastIndexOf(','); if(i2 >= 0 && i >= 0) { if(i2 > i) value_format = 2; else value_format = 1; return; } if(i >= 0) { i2 = 0; int l = (int) str.length(); for(int index = i + 1; index < l; index++) { if(str[index].isDigit()) { i2++; } else { break; } } if(i2 < 3) value_format = 1; else value_format = -1; } else if(i2 >= 0) { i = 0; int l = (int) str.length(); for(int index = i2 + 1; index < l; index++) { if(str[index].isDigit()) { i++; } else { break; } } if(i < 3) value_format = 2; else value_format = -1; } } } struct csv_info { int value_format; char separator; bool p1, p2, p3, p4, ly; int lz; }; bool ImportCSVDialog::import(bool test, csv_info *ci) { QString date_format, alt_date_format; if(test) { ci->p1 = true; ci->p2 = true; ci->p3 = true; ci->p4 = true; ci->ly = true; ci->lz = -1; ci->value_format = 0; ci->separator = -1; } else { if(ci->p1) { date_format += ci->lz == 0 ? "M" : "MM"; if(ci->separator > 0) date_format += ci->separator; date_format += ci->lz == 0 ? "d" : "dd"; if(ci->separator > 0) date_format += ci->separator; if(ci->ly) { date_format += "yyyy"; } else { if(ci->separator > 0) { alt_date_format = date_format; alt_date_format += '\''; alt_date_format += "yy"; } date_format += "yy"; } } else if(ci->p2) { date_format += ci->lz == 0 ? "d" : "dd"; if(ci->separator > 0) date_format += ci->separator; date_format += ci->lz == 0 ? "M" : "MM"; if(ci->separator > 0) date_format += ci->separator; if(ci->ly) { date_format += "yyyy"; } else { if(ci->separator > 0) { alt_date_format = date_format; alt_date_format += '\''; alt_date_format += "yy"; } date_format += "yy"; } } else if(ci->p3) { if(ci->ly) date_format += "yyyy"; else date_format += "yy"; if(ci->separator > 0) date_format += ci->separator; date_format += ci->lz == 0 ? "M" : "MM"; if(ci->separator > 0) date_format += ci->separator; date_format += ci->lz == 0 ? "d" : "dd"; } else if(ci->p4) { if(ci->ly) date_format += "yyyy"; else date_format += "yy"; if(ci->separator > 0) date_format += ci->separator; date_format += ci->lz == 0 ? "d" : "dd"; if(ci->separator > 0) date_format += ci->separator; date_format += ci->lz == 0 ? "M" : "MM"; } } int first_row = rowEdit->value(); int type = typeGroup->checkedId(); QString delimiter; switch(delimiterCombo->currentIndex()) { case 0: {delimiter = ","; break;} case 1: {delimiter = "\t"; break;} case 2: {delimiter = ";"; break;} case 3: {delimiter = " "; break;} case 4: {delimiter = delimiterEdit->text(); break;} } int description_c = columnDescriptionButton->isChecked() ? columnDescriptionEdit->value() : -1; int value_c = columnValueButton->isChecked() ? columnValueEdit->value() : -1; int cost_c = (type == 4 && columnCostButton->isChecked()) ? columnCostEdit->value() : -1; int date_c = columnDateButton->isChecked() ? columnDateEdit->value() : -1; if(test && date_c < 0) { ci->p1 = true; ci->p2 = false; ci->p3 = false; ci->p4 = false; ci->ly = false; ci->lz = 1; } int AC1_c = columnAC1Button->isChecked() ? columnAC1Edit->value() : -1; int AC2_c = columnAC2Button->isChecked() ? columnAC2Edit->value() : -1; int comments_c = columnCommentsButton->isChecked() ? columnCommentsEdit->value() : -1; int tags_c = columnTagsButton->isChecked() ? columnTagsEdit->value() : -1; int payee_c = -1; if(b_extra && columnPayeeButton->isChecked()) payee_c = columnPayeeEdit->value(); int quantity_c = -1; if(b_extra && columnQuantityButton->isChecked()) quantity_c = columnQuantityEdit->value(); int ncolumns = 0, min_columns = 0; if(value_c > ncolumns) ncolumns = value_c; if(cost_c > ncolumns) ncolumns = cost_c; if(date_c > ncolumns) ncolumns = date_c; if(AC1_c > ncolumns) ncolumns = AC1_c; if(AC2_c > ncolumns) ncolumns = AC2_c; min_columns = ncolumns; if(description_c > ncolumns) ncolumns = description_c; if(comments_c > ncolumns) ncolumns = comments_c; if(tags_c > ncolumns) ncolumns = tags_c; if(payee_c > ncolumns) ncolumns = payee_c; if(quantity_c > ncolumns) ncolumns = quantity_c; if((description_c > 0 && (description_c == value_c || description_c == cost_c || description_c == date_c || description_c == AC1_c || description_c == AC2_c || description_c == comments_c || description_c == payee_c || description_c == quantity_c || description_c == tags_c)) || (value_c > 0 && (value_c == date_c || value_c == cost_c || value_c == AC1_c || value_c == AC2_c || value_c == comments_c || value_c == payee_c || value_c == quantity_c || value_c == tags_c)) || (cost_c > 0 && (cost_c == date_c || cost_c == AC1_c || cost_c == AC2_c || cost_c == comments_c || cost_c == payee_c || cost_c == quantity_c || cost_c == tags_c)) || (date_c > 0 && (date_c == AC1_c || date_c == AC2_c || date_c == comments_c || date_c == payee_c || date_c == quantity_c || date_c == tags_c)) || (AC1_c > 0 && (AC1_c == AC2_c || AC1_c == comments_c || AC1_c == payee_c || AC1_c == quantity_c || AC1_c == tags_c)) || (AC2_c > 0 && (AC2_c == comments_c || AC2_c == payee_c || AC2_c == quantity_c || AC2_c == tags_c)) || (comments_c > 0 && (comments_c == payee_c || comments_c == quantity_c || comments_c == tags_c)) || (payee_c > 0 && (payee_c == quantity_c || payee_c == tags_c)) || (tags_c > 0 && (tags_c == quantity_c)) ) { if(QMessageBox::warning(this, tr("Warning"), tr("The same column number is selected multiple times. Do you wish to proceed anyway?"), QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) { return false; } } bool create_missing = createMissingButton->isChecked() && type != ALL_TYPES_ID; QString description, comments, payee, tags; double quantity = 1.0; if(!test && description_c < 0) description = valueDescriptionEdit->text(); if(!test && comments_c < 0) comments = valueCommentsEdit->text(); if(!test && b_extra && quantity_c < 0) quantity = valueQuantityEdit->value(); if(!test && tags_c < 0) tags = valueTagsEdit->text(); QMap eaccounts, iaccounts, aaccounts; Account *ac1 = NULL, *ac1i = NULL, *ac2 = NULL; if(!test && (AC1_c >= 0 || AC2_c >= 0)) { for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) { ExpensesAccount *ea = *it; eaccounts[ea->nameWithParent()] = ea; if(ea->parentCategory() && !eaccounts.contains(ea->name())) eaccounts[ea->name()] = ea; } for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) { IncomesAccount *ia = *it; iaccounts[ia->nameWithParent()] = ia; if(ia->parentCategory() && !iaccounts.contains(ia->name())) iaccounts[ia->name()] = ia; } for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { AssetsAccount *aa = *it; aaccounts[aa->name()] = aa; } } if(AC1_c < 0) { if(valueAC1Edit->currentData().isValid()) ac1 = (Account*) valueAC1Edit->currentData().value(); if(valueAC1IncomeEdit->currentData().isValid()) ac1i = (Account*) valueAC1IncomeEdit->currentData().value(); } if(AC2_c < 0) { if(valueAC2Edit->currentData().isValid()) ac2 = (Account*) valueAC2Edit->currentData().value(); if(ac1 == ac2) { QMessageBox::critical(this, tr("Error"), tr("Selected from account is the same as the to account.")); return false; } } QDate date; if(date_c < 0) { date = valueDateEdit->date(); if(!date.isValid()) { QMessageBox::critical(this, tr("Error"), tr("Invalid date.")); return false; } } double value = 0.0; if(value_c < 0) { value = valueValueEdit->value(); } double cost = 0.0; QString url = fileEdit->text().trimmed(); QFile file(url); if(!file.open(QIODevice::ReadOnly) ) { QMessageBox::critical(this, tr("Error"), tr("Couldn't open %1 for reading.").arg(url)); return false; } else if(!file.size()) { QMessageBox::critical(this, tr("Error"), tr("Error reading %1.").arg(url)); return false; } QFileInfo fileInfo(url); last_document_directory = fileInfo.absoluteDir().absolutePath(); QTextStream fstream(&file); #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) fstream.setCodec("UTF-8"); #endif //bool had_data = false; int successes = 0; int failed = 0; bool missing_columns = false, value_error = false, date_error = false; bool AC1_empty = false, AC2_empty = false, AC1_missing = false, AC2_missing = false, AC_security = false, AC_balancing = false, AC_same = false; bool AC1_category = (type == 0 || type == 1 || type == 3 || type == 4); int AC1_c_bak = AC1_c; int AC2_c_bak = AC2_c; int row = 0; QString line = fstream.readLine(); QString new_ac1 = "", new_ac2 = ""; QDate curdate = QDate::currentDate(); QMap datestamps; while(!line.isNull()) { row++; if((first_row == 0 && !line.isEmpty() && line[0] != '#') || (first_row > 0 && row >= first_row && !line.isEmpty())) { #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) QStringList columns = line.split(delimiter, Qt::KeepEmptyParts); #else QStringList columns = line.split(delimiter, QString::KeepEmptyParts); #endif for(QStringList::Iterator it = columns.begin(); it != columns.end(); ++it) { int i = 0; while(i < (int) (*it).length() && ((*it)[i] == ' ' || (*it)[i] == '\t')) { i++; } if(!(*it).isEmpty() && (*it)[i] == '\"') { (*it).remove(0, i + 1); i = (*it).length() - 1; while(i > 0 && ((*it)[i] == ' ' || (*it)[i] == '\t')) { i--; } if(i >= 0 && (*it)[i] == '\"') { (*it).truncate(i); } else { QStringList::Iterator it2 = it; ++it2; while(it2 != columns.end()) { i = (*it2).length() - 1; while(i > 0 && ((*it2)[i] == ' ' || (*it2)[i] == '\t')) { i--; } if(i >= 0 && (*it2)[i] == '\"') { (*it2).truncate(i); *it += delimiter; *it += *it2; it2 = columns.erase(it2); it = it2; it--; break; } *it += delimiter; *it += *it2; it2 = columns.erase(it2); it = it2; it--; } } } *it = (*it).trimmed(); } if((int) columns.count() < min_columns) { if(first_row != 0) { missing_columns = true; failed++; } } else { bool success = true; if(!test && success && description_c > 0) { description = columns[description_c - 1]; } if(success && value_c > 0) { if(cost_c <= 0 || !columns[value_c - 1].isEmpty()) { bool ok = true; if(first_row == 0) { ok = false; QString &str = columns[value_c - 1]; int l = (int) str.length(); for(int i = 0; i < l; i++) { if(str[i].isDigit()) { ok = true; break; } } } if(!ok) { failed--; success = false; } else if(test) { if(ci->value_format <= 0) testCSVValue(columns[value_c - 1], ci->value_format); } else { value = readCSVValue(columns[value_c - 1], ci->value_format, &ok); if(!ok) { if(first_row == 0) failed--; else value_error = true; success = false; } } } else { value = 0.0; } } if(success && cost_c > 0) { if(value == 0.0 || !columns[cost_c - 1].isEmpty()) { bool ok = true; if(first_row == 0) { ok = false; QString &str = columns[cost_c - 1]; int l = (int) str.length(); for(int i = 0; i < l; i++) { if(str[i].isDigit()) { ok = true; break; } } } if(!ok) { failed--; success = false; } else if(test) { if(ci->value_format <= 0) testCSVValue(columns[cost_c - 1], ci->value_format); } else { cost = readCSVValue(columns[cost_c - 1], ci->value_format, &ok); if(!ok) { if(first_row == 0) failed--; else value_error = true; success = false; } value -= cost; } } } if(success && date_c > 0) { bool ok = true; if(first_row == 0) { ok = false; QString &str = columns[date_c - 1]; for(int i = 0; i < (int) str.length(); i++) { if(str[i].isDigit()) { ok = true; break; } } } if(!ok) { failed--; success = false; } else if(test) { if(ci->p1 + ci->p2 + ci->p3 + ci->p4 > 1 || ci->lz < 0) testCSVDate(columns[date_c - 1], ci->p1, ci->p2, ci->p3, ci->p4, ci->ly, ci->separator, ci->lz); } else { date = readCSVDate(columns[date_c - 1], date_format, alt_date_format); if(!date.isValid()) { if(first_row == 0) failed--; else date_error = true; success = false; } } } if(success && first_row == 0) first_row = row; if(test && ci->p1 + ci->p2 + ci->p3 + ci->p4 < 2 && ci->lz >= 0 && ci->value_format > 0) break; if(test) success = false; if(success && type == ALL_TYPES_ID && value < 0.0) { AC1_c = AC2_c_bak; AC2_c = AC1_c_bak; value = -value; } if(success && AC1_c > 0) { if(AC1_category && columns[AC1_c - 1].isEmpty()) columns[AC1_c - 1] = tr("Uncategorized"); QMap::iterator it_ac; bool found = false; if(type == 0 || ((type == 3 || type == 4) && value < 0.0)) { it_ac = eaccounts.find(columns[AC1_c - 1]); found = (it_ac != eaccounts.end()); } else if(type == 1 || type == 3 || type == 4) { it_ac = iaccounts.find(columns[AC1_c - 1]); found = (it_ac != iaccounts.end()); } else if(type == 2) { it_ac = aaccounts.find(columns[AC1_c - 1]); found = (it_ac != aaccounts.end()); } else if(type == ALL_TYPES_ID) { it_ac = iaccounts.find(columns[AC1_c - 1]); found = (it_ac != iaccounts.end()); if(!found) { it_ac = aaccounts.find(columns[AC1_c - 1]); found = (it_ac != aaccounts.end()); } } if(found) { ac1 = it_ac.value(); if(ac1->type() == ACCOUNT_TYPE_ASSETS && ((AssetsAccount*) ac1)->accountType() == ASSETS_TYPE_SECURITIES) { AC_security = true; success = false; } else if(type != 2 && type != ALL_TYPES_ID && ac1 == budget->balancingAccount) { AC_balancing = true; success = false; } } else if(columns[AC1_c - 1].isEmpty()) { AC1_empty = true; success = false; } else if(create_missing) { new_ac1 = columns[AC1_c - 1]; } else { AC1_missing = true; success = false; } } if(success && AC2_c > 0) { QMap::iterator it_ac; bool found = false; if(type == ALL_TYPES_ID) { it_ac = eaccounts.find(columns[AC2_c - 1]); found = (it_ac != eaccounts.end()); if(!found) { it_ac = aaccounts.find(columns[AC2_c - 1]); found = (it_ac != aaccounts.end()); } } else { it_ac = aaccounts.find(columns[AC2_c - 1]); found = (it_ac != aaccounts.end()); } if(found) { ac2 = it_ac.value(); if(ac1 == ac2) { AC_same = true; success = false; } else if(ac2->type() == ACCOUNT_TYPE_ASSETS && ((AssetsAccount*) ac2)->accountType() == ASSETS_TYPE_SECURITIES) { AC_security = true; success = false; } else if(ac2 == budget->balancingAccount) { if(type != 2) { AC_balancing = true; success = false; } else { if(type == ALL_TYPES_ID && ac1->type() != ACCOUNT_TYPE_ASSETS) { it_ac = aaccounts.find(columns[AC1_c - 1]); found = it_ac != aaccounts.end(); if(found) { ac1 = it_ac.value(); if(ac1->type() == ACCOUNT_TYPE_ASSETS && ((AssetsAccount*) ac1)->accountType() == ASSETS_TYPE_SECURITIES) { AC_security = true; success = false; } else if(ac1 == budget->balancingAccount) { AC_same = true; success = false; } } else { AC_balancing = true; success = false; } } if(success) { value = -value; Account *ac1_bak = ac1; ac1 = ac2; ac2 = ac1_bak; } } } else if(type == ALL_TYPES_ID && ac1 == budget->balancingAccount && ac2->type() != ACCOUNT_TYPE_ASSETS) { it_ac = aaccounts.find(columns[AC2_c - 1]); found = it_ac != aaccounts.end(); if(found) { ac2 = it_ac.value(); if(ac2->type() == ACCOUNT_TYPE_ASSETS && ((AssetsAccount*) ac2)->accountType() == ASSETS_TYPE_SECURITIES) { AC_security = true; success = false; } else if(ac2 == budget->balancingAccount) { AC_same = true; success = false; } } else { AC_balancing = true; success = false; } } } else if(columns[AC2_c - 1].isEmpty()) { AC2_empty = true; success = false; } else if(create_missing) { new_ac2 = columns[AC2_c - 1]; if(new_ac1 == new_ac2) { new_ac1 = ""; new_ac2 = ""; AC_same = true; success = false; } } else { AC2_missing = true; success = false; } } if(success && type == ALL_TYPES_ID) { AC1_c = AC1_c_bak; AC2_c = AC2_c_bak; } if(success && comments_c > 0) { comments = columns[comments_c - 1]; } if(success && tags_c > 0) { tags = columns[tags_c - 1]; } if(success && payee_c > 0) { payee = columns[payee_c - 1]; } if(success && quantity_c > 0) { if(!columns[quantity_c - 1].isEmpty()) { bool ok = false; quantity = readCSVValue(columns[quantity_c - 1], ci->value_format, &ok); if(!ok) { quantity = 1.0; } } else { quantity = 1.0; } } if(success) { if(!new_ac1.isEmpty()) { if(type == 0 || ((type == 3 || type == 4) && value < 0.0)) { if(new_ac1.indexOf(':') > 0) { QString new_ac1a = new_ac1.section(':', 0, 0).trimmed(); QString new_ac1b = new_ac1.section(':', 1).trimmed(); Account *ac1a = NULL; if(!new_ac1a.isEmpty()) { QMap::iterator it_ac_a = eaccounts.find(new_ac1a); if(it_ac_a != eaccounts.end()) { ac1a = it_ac_a.value(); } else { ac1a = new ExpensesAccount(budget, new_ac1a); budget->addAccount(ac1a); eaccounts[ac1a->name()] = ac1a; } } if(new_ac1b.isEmpty()) { ac1 = ac1a; } else { ac1 = new ExpensesAccount(budget, new_ac1b); ((ExpensesAccount*) ac1)->setParentCategory((ExpensesAccount*) ac1a); budget->addAccount(ac1); eaccounts[ac1->nameWithParent()] = ac1; if(!eaccounts.contains(ac1->name())) eaccounts[ac1->name()] = ac1; } } else { ac1 = new ExpensesAccount(budget, new_ac1); budget->addAccount(ac1); eaccounts[ac1->name()] = ac1; } } else if(type == 1 || type == 3 || type == 4) { if(new_ac1.indexOf(':') > 0) { QString new_ac1a = new_ac1.section(':', 0, 0); QString new_ac1b = new_ac1.section(':', 1); Account *ac1a = NULL; QMap::iterator it_ac_a = iaccounts.find(new_ac1a); if(!new_ac1a.isEmpty()) { if(it_ac_a != iaccounts.end()) { ac1a = it_ac_a.value(); } else { ac1a = new IncomesAccount(budget, new_ac1a); budget->addAccount(ac1a); iaccounts[ac1a->name()] = ac1a; } } if(new_ac1b.isEmpty()) { ac1 = ac1a; } else { ac1 = new IncomesAccount(budget, new_ac1b); ((IncomesAccount*) ac1)->setParentCategory((IncomesAccount*) ac1a); budget->addAccount(ac1); iaccounts[ac1->nameWithParent()] = ac1; if(!iaccounts.contains(ac1->name())) iaccounts[ac1->name()] = ac1; } } else { ac1 = new IncomesAccount(budget, new_ac1); budget->addAccount(ac1); iaccounts[ac1->name()] = ac1; } } else if(type == 2) { ac1 = new AssetsAccount(budget, ASSETS_TYPE_CASH, new_ac1); budget->addAccount(ac1); aaccounts[ac1->name()] = ac1; } new_ac1 = ""; } if(!new_ac2.isEmpty()) { ac2 = new AssetsAccount(budget, ASSETS_TYPE_CASH, new_ac2); budget->addAccount(ac2); aaccounts[ac2->name()] = ac2; new_ac2 = ""; } Transaction *trans = NULL; switch(type) { case 0: { trans = new Expense(budget, value, date, (ExpensesAccount*) ac1, (AssetsAccount*) ac2, description, comments); ((Expense*) trans)->setPayee(payee); successes++; break; } case 1: { trans = new Income(budget, value, date, (IncomesAccount*) ac1, (AssetsAccount*) ac2, description, comments); ((Income*) trans)->setPayer(payee); successes++; break; } case 2: { if(ac1 == budget->balancingAccount) { trans = new Balancing(budget, value, date, (AssetsAccount*) ac2, description); } else if(value < 0.0) { trans = new Transfer(budget, -value, date, (AssetsAccount*) ac2, (AssetsAccount*) ac1, description, comments); } else { trans = new Transfer(budget, value, date, (AssetsAccount*) ac1, (AssetsAccount*) ac2, description, comments); } successes++; break; } case 3: {} case 4: { if(value < 0.0) { trans = new Expense(budget, -value, date, (ExpensesAccount*) ac1, (AssetsAccount*) ac2, description, comments); ((Expense*) trans)->setPayee(payee); } else { trans = new Income(budget, value, date, AC1_c < 0 ? (IncomesAccount*) ac1i : (IncomesAccount*) ac1, (AssetsAccount*) ac2, description, comments); ((Income*) trans)->setPayer(payee); } successes++; break; } case ALL_TYPES_ID: { if(ac1 == budget->balancingAccount) { trans = new Balancing(budget, value, date, (AssetsAccount*) ac2, description); } else if(ac1->type() == ACCOUNT_TYPE_INCOMES) { trans = new Income(budget, value, date, (IncomesAccount*) ac1, (AssetsAccount*) ac2, description, comments); ((Income*) trans)->setPayer(payee); } else if(ac2->type() == ACCOUNT_TYPE_EXPENSES) { trans = new Expense(budget, value, date, (ExpensesAccount*) ac2, (AssetsAccount*) ac1, description, comments); ((Expense*) trans)->setPayee(payee); } else { trans = new Transfer(budget, value, date, (AssetsAccount*) ac1, (AssetsAccount*) ac2, description, comments); } successes++; break; } } if(trans) { trans->readTags(tags); trans->setQuantity(quantity); if(trans->date() > curdate) { trans->setTimestamp(datestamps.contains(QDate::currentDate()) ? datestamps[QDate::currentDate()] + 1 : DATE_TO_MSECS(QDate::currentDate()) / 1000); datestamps[QDate::currentDate()] = trans->timestamp(); budget->addScheduledTransaction(new ScheduledTransaction(budget, trans, NULL)); } else { trans->setTimestamp(datestamps.contains(trans->date()) ? datestamps[trans->date()] + 1 : DATE_TO_MSECS(trans->date()) / 1000); datestamps[trans->date()] = trans->timestamp(); budget->addTransaction(trans); } } } else { failed++; } } } line = fstream.readLine(); } file.close(); if(test) { return true; } QString info = "", details = ""; if(successes > 0) { info = tr("Successfully imported %n transaction(s).", "", successes); } else { info = tr("Unable to import any transactions."); } if(failed > 0) { info += '\n'; info += tr("Failed to import %n data row(s).", "", failed); if(missing_columns) {details += "\n-"; details += tr("Required columns missing.");} if(value_error) {details += "\n-"; details += tr("Invalid value.");} if(date_error) {details += "\n-"; details += tr("Invalid date.");} if(AC1_empty) {details += "\n-"; if(AC1_category) {details += tr("Empty category name.");} else {details += tr("Empty account name.");}} if(AC2_empty) {details += "\n-"; details += tr("Empty account name.");} if(AC1_missing) {details += "\n-"; if(AC1_category) {details += tr("Unknown category found.");} else {details += tr("Unknown account found.");}} if(AC2_missing) {details += "\n-"; details += tr("Unknown account found.");} if(AC_security) {details += "\n-"; details += tr("Cannot import security transactions (to/from security accounts).");} if(AC_balancing) {details += "\n-"; details += tr("Balancing account wrongly used.", "Referring to the account used for adjustments of account balances.");} if(AC_same) {details += "\n-"; details += tr("Same to and from account/category.");} } else if(successes == 0) { info = tr("No data found."); } if(failed > 0 || successes == 0) { QMessageBox::critical(this, tr("Error"), info + details); } else { QMessageBox::information(this, tr("Information"), info); } return successes > 0; } void ImportCSVDialog::accept() { csv_info ci; if(!import(true, &ci)) return; int ps = ci.p1 + ci.p2 + ci.p3 + ci.p4; if(ps == 0) { QMessageBox::critical(this, tr("Error"), tr("Unrecognized date format.")); return; } if(ci.value_format < 0 || ps > 1) { QDialog *dialog = new QDialog(this); dialog->setWindowTitle(tr("Specify Format")); dialog->setModal(true); QVBoxLayout *box1 = new QVBoxLayout(dialog); QGridLayout *grid = new QGridLayout(); box1->addLayout(grid); QLabel *label = new QLabel(tr("The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format."), dialog); label->setWordWrap(true); grid->addWidget(label, 0, 0, 1, 2); QComboBox *dateFormatCombo = NULL; if(ps > 1) { grid->addWidget(new QLabel(tr("Date format:"), dialog), 1, 0); dateFormatCombo = new QComboBox(dialog); dateFormatCombo->setEditable(false); if(ci.p1) { QString date_format = ci.lz == 0 ? "M" : "MM";; if(ci.separator > 0) date_format += ci.separator; date_format += ci.lz == 0 ? "D" : "DD"; if(ci.separator > 0) date_format += ci.separator; date_format += "YY"; if(ci.ly) date_format += "YY"; dateFormatCombo->addItem(date_format); } if(ci.p2) { QString date_format = ci.lz == 0 ? "D" : "DD"; if(ci.separator > 0) date_format += ci.separator; date_format += ci.lz == 0 ? "M" : "MM"; if(ci.separator > 0) date_format += ci.separator; date_format += "YY"; if(ci.ly) date_format += "YY"; dateFormatCombo->addItem(date_format); } if(ci.p3) { QString date_format = "YY"; if(ci.ly) date_format += "YY"; if(ci.separator > 0) date_format += ci.separator; date_format += ci.lz == 0 ? "M" : "MM"; if(ci.separator > 0) date_format += ci.separator; date_format += ci.lz == 0 ? "D" : "DD"; dateFormatCombo->addItem(date_format); } if(ci.p4) { QString date_format = "YY"; if(ci.ly) date_format += "YY"; if(ci.separator > 0) date_format += ci.separator; date_format += ci.lz == 0 ? "D" : "DD"; if(ci.separator > 0) date_format += ci.separator; date_format += ci.lz == 0 ? "M" : "MM"; dateFormatCombo->addItem(date_format); } grid->addWidget(dateFormatCombo, 1, 1); } QComboBox *valueFormatCombo = NULL; if(ci.value_format < 0) { grid->addWidget(new QLabel(tr("Value format:"), dialog), ps > 1 ? 2 : 1, 0); valueFormatCombo = new QComboBox(dialog); valueFormatCombo->setEditable(false); valueFormatCombo->addItem("1,000,000.00"); valueFormatCombo->addItem("1.000.000,00"); grid->addWidget(valueFormatCombo, ps > 1 ? 2 : 1, 1); } QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, dialog); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), dialog, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), dialog, SLOT(accept())); box1->addWidget(buttonBox); if(dialog->exec() != QDialog::Accepted) { return; } if(ps > 1) { bool p1 = false, p2 = false, p3 = false, p4 = false; int p[4]; int i = 0; if(ci.p1) {p[i] = 1; i++;} if(ci.p2) {p[i] = 2; i++;} if(ci.p3) {p[i] = 3; i++;} if(ci.p4) {p[i] = 4; i++;} switch(p[dateFormatCombo->currentIndex()]) { case 1: {p1 = true; break;} case 2: {p2 = true; break;} case 3: {p3 = true; break;} case 4: {p4 = true; break;} } ci.p1 = p1; ci.p2 = p2; ci.p3 = p3; ci.p4 = p4; if(ci.lz < 0) ci.lz = 1; } if(ci.value_format < 0) ci.value_format = valueFormatCombo->currentIndex() + 1; dialog->deleteLater(); } if(import(false, &ci)) QWizard::accept(); } Eqonomize-1.5.3/src/importcsvdialog.h000066400000000000000000000100171416454732000176410ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifndef IMPORT_CSV_DIALOG_H #define IMPORT_CSV_DIALOG_H #include #include class QButtonGroup; class QCheckBox; class QLabel; class QRadioButton; class QSpinBox; class QComboBox; class QLineEdit; class QDateEdit; class QPushButton; class Budget; class EqonomizeValueEdit; struct csv_info; class ImportCSVDialog : public QWizard { Q_OBJECT protected: bool b_extra; Budget *budget; QMap presets; QString s_preset; QLabel *typeDescriptionLabel; QButtonGroup *typeGroup, *dateGroup, *valueGroup, *costGroup, *descriptionGroup, *AC1Group, *AC2Group, *commentsGroup, *payeeGroup, *quantityGroup, *tagsGroup; QLineEdit *fileEdit; QPushButton *fileButton; QSpinBox *rowEdit; QComboBox *delimiterCombo; QLineEdit *delimiterEdit; QRadioButton *columnDescriptionButton, *valueDescriptionButton; QSpinBox *columnDescriptionEdit; QLineEdit *valueDescriptionEdit; QLabel *valueLabel; QRadioButton *columnValueButton, *valueValueButton; QSpinBox *columnValueEdit; EqonomizeValueEdit *valueValueEdit; QLabel *costLabel; QRadioButton *columnCostButton, *valueCostButton; QSpinBox *columnCostEdit; EqonomizeValueEdit *valueCostEdit; QRadioButton *columnDateButton, *valueDateButton; QSpinBox *columnDateEdit; QDateEdit *valueDateEdit; QLabel *AC1Label; QRadioButton *columnAC1Button, *valueAC1Button; QSpinBox *columnAC1Edit; QComboBox *valueAC1Edit; QComboBox *valueAC1IncomeEdit; QLabel *AC2Label; QRadioButton *columnAC2Button, *valueAC2Button; QSpinBox *columnAC2Edit; QComboBox *valueAC2Edit; QRadioButton *columnCommentsButton, *valueCommentsButton; QSpinBox *columnCommentsEdit; QLineEdit *valueCommentsEdit; QLabel *tagsLabel; QRadioButton *columnTagsButton, *valueTagsButton; QSpinBox *columnTagsEdit; QLineEdit *valueTagsEdit; QLabel *payeeLabel; QRadioButton *columnPayeeButton, *valuePayeeButton; QSpinBox *columnPayeeEdit; QLineEdit *valuePayeeEdit; QLabel *quantityLabel; QRadioButton *columnQuantityButton, *valueQuantityButton; QSpinBox *columnQuantityEdit; EqonomizeValueEdit *valueQuantityEdit; QComboBox *presetCombo; QPushButton *savePresetButton; QLabel *presetLabel; QCheckBox *createMissingButton; bool import(bool test, csv_info *ci); public: ImportCSVDialog(bool extra_parameters, Budget *budg, QWidget *parent); ~ImportCSVDialog(); protected slots: void loadPreset(int); void savePreset(); void onFileChanged(const QString&); void selectFile(); void nextClicked(); void typeChanged(int); void delimiterChanged(int); void accept(); }; #endif Eqonomize-1.5.3/src/ledgerdialog.cpp000066400000000000000000002440601416454732000174170ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016-2017 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include "ledgerdialog.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) # include #else # include #endif #include #include #include "budget.h" #include "eqonomize.h" #include "eqonomizevalueedit.h" #include "transactioneditwidget.h" #include "eqonomizevalueedit.h" #include "editaccountdialogs.h" extern QString htmlize_string(QString str); extern QColor createExpenseColor(QTreeWidgetItem *i, int = 0); extern QColor createIncomeColor(QTreeWidgetItem *i, int = 0); extern QColor createTransferColor(QTreeWidgetItem *i, int = 0); extern QColor createExpenseColor(QWidget *w); extern QColor createIncomeColor(QWidget *w); extern QColor createTransferColor(QWidget *w); extern void setColumnTextWidth(QTreeWidget *w, int i, QString str); extern void setColumnDateWidth(QTreeWidget *w, int i); extern void setColumnMoneyWidth(QTreeWidget *w, int i, Budget *budget, double v = 9999999.99, int d = -1); extern void setColumnStrlenWidth(QTreeWidget *w, int i, int l); QColor incomeColor, expenseColor; QColor labelIncomeColor, labelExpenseColor, labelTransferColor; class LedgerListViewItem : public QTreeWidgetItem, public QObject { protected: Transaction *o_trans; SplitTransaction *o_split; public: LedgerListViewItem(Transaction *trans, SplitTransaction *split, QTreeWidget *parent, QString, QString = QString(), QString = QString(), QString = QString(), QString = QString(), QString = QString(), QString = QString(), QString = QString(), QString = QString(), QString = QString(), QString = QString()); void setReconciled(int, int); void updateMark(int); void setColors(); Transaction *transaction() const; SplitTransaction *splitTransaction() const; bool matches(const QString&) const; double d_balance; bool b_other_account; int b_reconciled; }; LedgerListViewItem::LedgerListViewItem(Transaction *trans, SplitTransaction *split, QTreeWidget *parent, QString s1, QString s2, QString s3, QString s4, QString s5, QString s6, QString s7, QString s8, QString s9, QString s10, QString s11) : QTreeWidgetItem(parent), o_trans(trans), o_split(split), b_other_account(false), b_reconciled(-1) { setText(1, s1); setText(2, s2); setText(3, s3); setText(4, s4); setText(5, s5); setText(6, s6); setText(7, s7); setText(9, s8); setText(10, s9); setText(11, s10); setText(8, s11); setTextAlignment(8, Qt::AlignRight | Qt::AlignVCenter); setTextAlignment(9, Qt::AlignRight | Qt::AlignVCenter); setTextAlignment(10, Qt::AlignRight | Qt::AlignVCenter); setTextAlignment(11, Qt::AlignRight | Qt::AlignVCenter); setTextAlignment(0, Qt::AlignCenter | Qt::AlignVCenter); if(parent) { if(!expenseColor.isValid()) expenseColor = createExpenseColor(this, 8); setForeground(8, expenseColor); if(!incomeColor.isValid()) incomeColor = createIncomeColor(this, 9); setForeground(9, incomeColor); setForeground(10, expenseColor); } } void LedgerListViewItem::setReconciled(int b, int mark) { b_reconciled = b; if(b < 0) { setCheckState(0, Qt::Unchecked); } else if(b) { setCheckState(0, Qt::Checked); } else { setCheckState(0, Qt::Unchecked); } updateMark(mark); } void LedgerListViewItem::updateMark(int mark) { if(mark < -1) return; QBrush br; if(mark == 0 || (mark > 0 && b_reconciled != 0)) { br = treeWidget()->viewport()->palette().alternateBase(); } else if(mark > 0) { br = treeWidget()->viewport()->palette().base(); } if(background(1) != br) { for(int c = 0; c <= 11; c++) { setBackground(c, br); } } if(isDisabled() != (mark >= 0 && b_reconciled < 0)) setDisabled(mark >= 0 && b_reconciled < 0); } void LedgerListViewItem::setColors() { if(!expenseColor.isValid()) expenseColor = createExpenseColor(this, 8); setForeground(8, expenseColor); if(!incomeColor.isValid()) incomeColor = createIncomeColor(this, 9); setForeground(9, incomeColor); setForeground(10, expenseColor); } Transaction *LedgerListViewItem::transaction() const { return o_trans; } SplitTransaction *LedgerListViewItem::splitTransaction() const { return o_split; } bool LedgerListViewItem::matches(const QString &str) const { for(int i = 3; i <= 7; i++) { if(!treeWidget()->isColumnHidden(i) && text(i).contains(str, Qt::CaseInsensitive)) return true; } return false; } LedgerDialog::LedgerDialog(AssetsAccount *acc, Budget *budg, Eqonomize *parent, QString title, bool extra_parameters, bool do_reconciliation) : QDialog(NULL, Qt::Window | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint), account(acc), mainWin(parent), budget(budg), b_extra(extra_parameters) { setWindowTitle(title); setModal(false); headerMenu = NULL; listMenu = NULL; key_event = NULL; re1 = 0; re2 = 0; setAttribute(Qt::WA_DeleteOnClose, true); if(!budget) budget = account->budget(); QVBoxLayout *box1 = new QVBoxLayout(this); bool focus_list = (account != NULL); if(!account) { for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { AssetsAccount *aaccount = *it; if(aaccount != budget->balancingAccount && aaccount->accountType() != ASSETS_TYPE_SECURITIES && (!account || !aaccount->isClosed())) { account = aaccount; if(!account->isClosed()) break; } } } QHBoxLayout *topbox = new QHBoxLayout(); box1->addLayout(topbox); topbox->addWidget(new QLabel(tr("Account:"), this)); accountCombo = new QComboBox(this); accountCombo->setEditable(false); int i = 0; for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { AssetsAccount *aaccount = *it; if(aaccount != budget->balancingAccount && aaccount->accountType() != ASSETS_TYPE_SECURITIES) { accountCombo->addItem(aaccount->name(), QVariant::fromValue((void*) aaccount)); if(aaccount == account) accountCombo->setCurrentIndex(i); i++; } } topbox->addWidget(accountCombo); QDialogButtonBox *topbuttons = new QDialogButtonBox(this); editAccountButton = topbuttons->addButton(tr("Edit Account…"), QDialogButtonBox::ActionRole); editAccountButton->setAutoDefault(false); editAccountButton->setEnabled(accountCombo->count() > 0); exportButton = topbuttons->addButton(tr("Export…"), QDialogButtonBox::ActionRole); exportButton->setAutoDefault(false); printButton = topbuttons->addButton(tr("Print…"), QDialogButtonBox::ActionRole); printButton->setAutoDefault(false); reconcileButton = topbuttons->addButton(tr("Reconcile", "Accounting context"), QDialogButtonBox::ActionRole); reconcileButton->setCheckable(true); reconcileButton->setChecked(do_reconciliation); reconcileButton->setAutoDefault(false); markReconciledButton = topbuttons->addButton(tr("Mark all as reconciled", "Accounting context"), QDialogButtonBox::ActionRole); markReconciledButton->setAutoDefault(false); topbox->addWidget(topbuttons); QHBoxLayout *findbox = new QHBoxLayout(); findbox->setSpacing(0); searchEdit = new QLineEdit(this); ActionSearch = searchEdit->addAction(LOAD_ICON("edit-find"), QLineEdit::LeadingPosition); findbox->addWidget(searchEdit); searchNextButton = new QPushButton(LOAD_ICON("go-down"), "", this); searchNextButton->setEnabled(false); findbox->addWidget(searchNextButton); searchPreviousButton = new QPushButton(LOAD_ICON("go-up"), "", this); searchPreviousButton->setEnabled(false); findbox->addWidget(searchPreviousButton); topbox->addLayout(findbox); topbox->addStretch(1); reconcileWidget = new QFrame(this); QGridLayout *reconcileLayout = new QGridLayout; reconcileLayout->addWidget(new QLabel(tr("Opening balance:", "Accounting context")), 0, 0); reconcileStartEdit = new EqonomizeDateEdit(QDate::currentDate(), this); reconcileStartEdit->setCalendarPopup(true); reconcileLayout->addWidget(reconcileStartEdit, 0, 1); reconcileOpeningEdit = new EqonomizeValueEdit(0.0, true, true, this, budget); reconcileLayout->addWidget(reconcileOpeningEdit, 0, 2); reconcileBOpeningLabel = new QLabel(this); reconcileLayout->addWidget(reconcileBOpeningLabel, 0, 3); reconcileROpeningLabel = new QLabel(this); reconcileLayout->addWidget(reconcileROpeningLabel, 0, 4); reconcileLayout->addWidget(new QLabel(tr("Change:", "Accounting context")), 1, 0); reconcileChangeEdit = new EqonomizeValueEdit(0.0, true, true, this, budget); reconcileLayout->addWidget(reconcileChangeEdit, 1, 2); reconcileBChangeLabel = new QLabel(this); reconcileLayout->addWidget(reconcileBChangeLabel, 1, 3); reconcileRChangeLabel = new QLabel(this); reconcileLayout->addWidget(reconcileRChangeLabel, 1, 4); reconcileLayout->addWidget(new QLabel(tr("Closing balance:", "Accounting context")), 2, 0); reconcileEndEdit = new EqonomizeDateEdit(QDate::currentDate(), this); reconcileEndEdit->setCalendarPopup(true); reconcileLayout->addWidget(reconcileEndEdit, 2, 1); reconcileClosingEdit = new EqonomizeValueEdit(0.0, true, true, this, budget); reconcileLayout->addWidget(reconcileClosingEdit, 2, 2); reconcileBClosingLabel = new QLabel(this); reconcileLayout->addWidget(reconcileBClosingLabel, 2, 3); reconcileRClosingLabel = new QLabel(this); reconcileLayout->addWidget(reconcileRClosingLabel, 2, 4); reconcileLayout->setColumnStretch(0, 0); reconcileLayout->setColumnStretch(1, 1); reconcileLayout->setColumnStretch(2, 1); reconcileLayout->setColumnStretch(3, 0); reconcileLayout->setColumnStretch(4, 3); reconcileLayout->setHorizontalSpacing(12); reconcileWidget->setLayout(reconcileLayout); box1->addWidget(reconcileWidget); QHBoxLayout *box2 = new QHBoxLayout(); box1->addLayout(box2); QVBoxLayout *box3 = new QVBoxLayout(); box2->addLayout(box3); transactionsView = new EqonomizeTreeWidget(this); transactionsView->setSortingEnabled(false); transactionsView->setAllColumnsShowFocus(true); transactionsView->setColumnCount(12); QStringList headers; headers << tr("R", "Header for account reconciled checkbox column"); headers << tr("Date"); headers << tr("Type"); headers << tr("Description", "Transaction description property (transaction title/generic article name)"); headers << tr("Account/Category"); headers << tr("Payee/Payer"); headers << tr("Tags"); headers << tr("Comments"); headers << tr("Expense"); headers << tr("Deposit", "Money put into account"); headers << tr("Withdrawal", "Money taken out from account"); headers << tr("Balance", "Noun. Balance of an account"); transactionsView->setHeaderLabels(headers); transactionsView->setRootIsDecorated(false); transactionsView->header()->setSectionsMovable(false); transactionsView->resizeColumnToContents(0); setColumnDateWidth(transactionsView, 1); setColumnTextWidth(transactionsView, 2, tr("Debt Payment")); setColumnStrlenWidth(transactionsView, 3, 20); setColumnStrlenWidth(transactionsView, 4, 20); setColumnStrlenWidth(transactionsView, 5, 20); setColumnStrlenWidth(transactionsView, 6, 10); setColumnStrlenWidth(transactionsView, 7, 20); setColumnMoneyWidth(transactionsView, 8, budget); setColumnMoneyWidth(transactionsView, 9, budget); setColumnMoneyWidth(transactionsView, 10, budget); setColumnMoneyWidth(transactionsView, 11, budget, 999999999.99); min_width_1 = transactionsView->columnWidth(0) + transactionsView->columnWidth(1) + transactionsView->columnWidth(2) + transactionsView->columnWidth(3) + transactionsView->columnWidth(4) + transactionsView->columnWidth(9) + transactionsView->columnWidth(10) + transactionsView->columnWidth(11) + 30; min_width_2 = min_width_1 + transactionsView->columnWidth(8); #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) # if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) QScreen *scr = screen(); # else QScreen *scr = QGuiApplication::screenAt(pos); # endif if(!scr) scr = QGuiApplication::primaryScreen(); QRect rect = scr->availableGeometry(); #else QRect rect = QApplication::desktop()->availableGeometry(this); #endif if(rect.width() > min_width_1 * 1.2) transactionsView->setMinimumWidth(min_width_1); transactionsView->setColumnHidden(5, true); transactionsView->setColumnHidden(6, true); transactionsView->setColumnHidden(7, true); transactionsView->setSelectionMode(QTreeWidget::ExtendedSelection); QSizePolicy sp = transactionsView->sizePolicy(); sp.setHorizontalPolicy(QSizePolicy::MinimumExpanding); transactionsView->setSizePolicy(sp); box3->addWidget(transactionsView); QDialogButtonBox *buttons = new QDialogButtonBox(Qt::Vertical, this); QPushButton *newButton = buttons->addButton(tr("New"), QDialogButtonBox::ActionRole); QMenu *newMenu = new QMenu(this); newButton->setMenu(newMenu); newButton->setAutoDefault(false); ActionNewDebtPayment = newMenu->addAction(mainWin->ActionNewDebtPayment->icon(), mainWin->ActionNewDebtPayment->text()); connect(ActionNewDebtPayment, SIGNAL(triggered()), this, SLOT(newDebtPayment())); ActionNewDebtInterest = newMenu->addAction(mainWin->ActionNewDebtInterest->icon(), mainWin->ActionNewDebtInterest->text()); connect(ActionNewDebtInterest, SIGNAL(triggered()), this, SLOT(newDebtInterest())); connect(newMenu->addAction(mainWin->ActionNewExpense->icon(), mainWin->ActionNewExpense->text()), SIGNAL(triggered()), this, SLOT(newExpense())); connect(newMenu->addAction(mainWin->ActionNewIncome->icon(), mainWin->ActionNewIncome->text()), SIGNAL(triggered()), this, SLOT(newIncome())); connect(newMenu->addAction(mainWin->ActionNewTransfer->icon(), mainWin->ActionNewTransfer->text()), SIGNAL(triggered()), this, SLOT(newTransfer())); connect(newMenu->addAction(mainWin->ActionNewMultiItemTransaction->icon(), mainWin->ActionNewMultiItemTransaction->text()), SIGNAL(triggered()), this, SLOT(newSplit())); editButton = buttons->addButton(tr("Edit…"), QDialogButtonBox::ActionRole); editButton->setEnabled(false); editButton->setAutoDefault(false); removeButton = buttons->addButton(tr("Delete"), QDialogButtonBox::ActionRole); removeButton->setEnabled(false); removeButton->setAutoDefault(false); //: join transactions together joinButton = buttons->addButton(tr("Join…"), QDialogButtonBox::ActionRole); joinButton->setEnabled(false); joinButton->setAutoDefault(false); //: split up joined transactions splitUpButton = buttons->addButton(tr("Split Up"), QDialogButtonBox::ActionRole); splitUpButton->setEnabled(false); splitUpButton->setAutoDefault(false); box2->addWidget(buttons); statLabel = new QLabel("", this); box3->addWidget(statLabel); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); buttonBox->button(QDialogButtonBox::Close)->setShortcut(Qt::CTRL | Qt::Key_Return); buttonBox->button(QDialogButtonBox::Close)->setAutoDefault(false); connect(buttonBox->button(QDialogButtonBox::Close), SIGNAL(clicked()), this, SLOT(reject())); box1->addWidget(buttonBox); #define NEW_ACTION(action, text, icon, receiver, slot) action = new QAction(this); action->setText(text); action->setIcon(LOAD_ICON(icon)); connect(action, SIGNAL(triggered()), receiver, slot); #define NEW_ACTION_ALT(action, text, icon, icon_alt, receiver, slot) action = new QAction(this); action->setText(text); action->setIcon(LOAD_ICON2(icon, icon_alt)); connect(action, SIGNAL(triggered()), receiver, slot); NEW_ACTION_ALT(ActionEdit, tr("Edit Transaction(s)…"), "document-edit", "eqz-edit", this, SLOT(edit())); NEW_ACTION(ActionClone, mainWin->ActionCloneTransaction->text(), "edit-copy", this, SLOT(cloneTransaction())); NEW_ACTION(ActionJoin, mainWin->ActionJoinTransactions->text(), "eqz-join-transactions", this, SLOT(joinTransactions())); NEW_ACTION(ActionSplit, mainWin->ActionSplitUpTransaction->text(), "eqz-split-transaction", this, SLOT(splitUpTransaction())); NEW_ACTION(ActionOpenFile, mainWin->ActionOpenAssociatedFile->text(), "system-run", this, SLOT(openAssociatedFile())); NEW_ACTION(ActionDelete, tr("Remove Transaction(s)"), "edit-delete", this, SLOT(remove())); NEW_ACTION(ActionMarkReconciled, tr("Mark as reconciled"), "edit-delete", this, SLOT(reconcileTransactions())); NEW_ACTION(ActionEditTimestamp, mainWin->ActionEditTimestamp->text(), "eqz-schedule", this, SLOT(editTimestamp())); new QShortcut(QKeySequence::Find, searchEdit, SLOT(setFocus())); connect(transactionsView, SIGNAL(itemSelectionChanged()), this, SLOT(transactionSelectionChanged())); connect(transactionsView, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(edit(QTreeWidgetItem*, int))); connect(transactionsView, SIGNAL(returnPressed(QTreeWidgetItem*)), this, SLOT(onTransactionReturnPressed(QTreeWidgetItem*))); connect(transactionsView, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT(transactionActivated(QTreeWidgetItem*, int))); connect(transactionsView, SIGNAL(spacePressed(QTreeWidgetItem*)), this, SLOT(onTransactionSpacePressed(QTreeWidgetItem*))); connect(removeButton, SIGNAL(clicked()), this, SLOT(remove())); connect(editButton, SIGNAL(clicked()), this, SLOT(edit())); connect(joinButton, SIGNAL(clicked()), this, SLOT(joinTransactions())); connect(splitUpButton, SIGNAL(clicked()), this, SLOT(splitUpTransaction())); connect(exportButton, SIGNAL(clicked()), this, SLOT(saveView())); connect(printButton, SIGNAL(clicked()), this, SLOT(printView())); connect(editAccountButton, SIGNAL(clicked()), this, SLOT(editAccount())); connect(accountCombo, SIGNAL(activated(int)), this, SLOT(accountActivated(int))); connect(mainWin, SIGNAL(transactionsModified()), this, SLOT(updateTransactions())); connect(mainWin, SIGNAL(accountsModified()), this, SLOT(updateAccounts())); connect(reconcileButton, SIGNAL(toggled(bool)), this, SLOT(toggleReconciliation(bool))); connect(markReconciledButton, SIGNAL(clicked()), this, SLOT(markAsReconciled())); connect(reconcileStartEdit, SIGNAL(dateChanged(const QDate&)), this, SLOT(reconcileStartDateChanged(const QDate&))); connect(reconcileEndEdit, SIGNAL(dateChanged(const QDate&)), this, SLOT(reconcileEndDateChanged(const QDate&))); connect(reconcileOpeningEdit, SIGNAL(valueChanged(double)), this, SLOT(reconcileOpeningChanged(double))); connect(reconcileClosingEdit, SIGNAL(valueChanged(double)), this, SLOT(reconcileClosingChanged(double))); connect(reconcileChangeEdit, SIGNAL(valueChanged(double)), this, SLOT(reconcileChangeChanged(double))); transactionsView->header()->setContextMenuPolicy(Qt::CustomContextMenu); connect(transactionsView->header(), SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(popupHeaderMenu(const QPoint&))); transactionsView->setContextMenuPolicy(Qt::CustomContextMenu); connect(transactionsView, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(popupListMenu(const QPoint&))); connect(ActionSearch, SIGNAL(triggered(bool)), this, SLOT(search())); connect(searchEdit, SIGNAL(textChanged(const QString&)), this, SLOT(searchChanged(const QString&))); connect(searchNextButton, SIGNAL(clicked()), this, SLOT(search())); connect(searchPreviousButton, SIGNAL(clicked()), this, SLOT(searchPrevious())); QSettings settings; QSize dialog_size = settings.value("Ledger/size", QSize()).toSize(); if(settings.value("GeneralOptions/version", 0).toInt() >= 140) { transactionsView->header()->restoreState(settings.value("Ledger/listState", QByteArray()).toByteArray()); } b_ascending = settings.value("Ledger/ascending", false).toBool(); if(dialog_size.isValid()) { resize(dialog_size); } accountChanged(); if(focus_list) transactionsView->setFocus(); toggleReconciliation(reconcileButton->isChecked()); transactionsView->setMinimumHeight(500); } LedgerDialog::~LedgerDialog() {} void LedgerDialog::keyPressEvent(QKeyEvent *e) { if(e == key_event) return; QDialog::keyPressEvent(e); if(!e->isAccepted() && !transactionsView->hasFocus()) { #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) key_event = new QKeyEvent(e->type(), e->key(), e->modifiers(), e->nativeScanCode(), e->nativeVirtualKey(), e->nativeModifiers(), e->text(), e->isAutoRepeat(), e->count()); #else key_event = new QKeyEvent(*e); #endif QApplication::sendEvent(transactionsView, key_event); delete key_event; } } void LedgerDialog::updateReconciliationStats(bool b_toggled, bool scroll_to, bool update_markers) { if(!account) return; QDate d_start = reconcileStartEdit->date(); QDate d_end = reconcileEndEdit->date(); if(!d_start.isValid() || !d_end.isValid()) return; double d_rec_ch = 0.0; d_book_op = account->initialBalance(); d_book_cl = account->initialBalance(); d_rec_op = account->initialBalance(); bool b_started = false, b_finished = false;; LedgerListViewItem *i_first = NULL, *i_last = NULL; transactionsView->model()->blockSignals(true); QTreeWidgetItemIterator it(transactionsView, QTreeWidgetItemIterator::All); while(*it) { LedgerListViewItem *i = (LedgerListViewItem*) *it; Transactions *trans = i->transaction(); if(i->splitTransaction()) trans = i->splitTransaction(); if(!trans) { i->updateMark(0); break; } if(!b_finished && trans->date() < d_start) { d_book_op = i->d_balance; b_finished = true; } if(!b_finished && trans->date() <= d_end) { if(!b_started) { b_started = true; d_book_cl = i->d_balance; i_first = i; } i_last = i; if(update_markers) i->updateMark(1); } if(b_started && trans->isReconciled(account)) { if(b_finished) d_rec_op += trans->accountChange(account); else d_rec_ch += trans->accountChange(account); } if(update_markers && (b_finished || !b_started)) i->updateMark(b_finished ? 2 : 0); ++it; } transactionsView->model()->blockSignals(false); transactionsView->dataChanged(QModelIndex(), QModelIndex()); if(scroll_to && i_first && i_last) { transactionsView->scrollToItem(i_first); transactionsView->scrollToItem(i_last); } if(b_toggled || re1 == 0) { reconcileOpeningEdit->blockSignals(true); reconcileClosingEdit->blockSignals(true); reconcileChangeEdit->blockSignals(true); if(re1 == 0 || reconcileOpeningEdit->value() == 0.0) reconcileOpeningEdit->setValue(d_book_op); if(re1 == 0 || reconcileClosingEdit->value() == 0.0) reconcileClosingEdit->setValue(d_book_cl); reconcileChangeEdit->setValue(d_book_cl - d_book_op); reconcileOpeningEdit->blockSignals(false); reconcileClosingEdit->blockSignals(false); reconcileChangeEdit->blockSignals(false); } d_rec_cl = d_rec_op + d_rec_ch; updateReconciliationStatLabels(); } QString format_diff_value(double d_value, Currency *currency) { QString str = ""; str += currency->formatValue(d_value, -1, true, true); str += ""; return str; } QString format_value(double d_value, Currency *currency) { return QString("") + currency->formatValue(d_value) + ""; } void LedgerDialog::updateReconciliationStatLabels() { if(!labelExpenseColor.isValid()) labelExpenseColor = createExpenseColor(reconcileRChangeLabel); if(!labelIncomeColor.isValid()) labelIncomeColor = createIncomeColor(reconcileRChangeLabel); if(!labelTransferColor.isValid()) labelTransferColor = createTransferColor(reconcileRChangeLabel); reconcileRChangeLabel->setText(tr("Reconciled: %1 (%2)", "Accounting context").arg(format_value(d_rec_cl - d_rec_op, account->currency())).arg(format_diff_value(d_rec_cl - d_rec_op - reconcileChangeEdit->value(), account->currency()))); reconcileROpeningLabel->setText(tr("Reconciled: %1 (%2)", "Accounting context").arg(format_value(d_rec_op, account->currency())).arg(format_diff_value(d_rec_op - reconcileOpeningEdit->value(), account->currency()))); reconcileRClosingLabel->setText(tr("Reconciled: %1 (%2)", "Accounting context").arg(format_value(d_rec_cl, account->currency())).arg(format_diff_value(d_rec_cl - reconcileClosingEdit->value(), account->currency()))); reconcileBChangeLabel->setText(tr("Book value: %1 (%2)", "Accounting context").arg(format_value(d_book_cl - d_book_op, account->currency())).arg(format_diff_value(d_book_cl - d_book_op - reconcileChangeEdit->value(), account->currency()))); reconcileBClosingLabel->setText(tr("Book value: %1 (%2)", "Accounting context").arg(format_value(d_book_cl, account->currency())).arg(format_diff_value(d_book_cl - reconcileClosingEdit->value(), account->currency()))); reconcileBOpeningLabel->setText(tr("Book value: %1 (%2)", "Accounting context").arg(format_value(d_book_op, account->currency())).arg(format_diff_value(d_book_op - reconcileOpeningEdit->value(), account->currency()))); } void LedgerDialog::popupListMenu(const QPoint &p) { QTreeWidgetItem *qwi = transactionsView->itemAt(p); if(!qwi || qwi->isDisabled()) return; QList selection = transactionsView->selectedItems(); if(selection.isEmpty()) return; bool b = false; if(reconcileButton->isChecked()) { for(int index = 0; index < selection.size(); index++) { LedgerListViewItem *i = (LedgerListViewItem*) selection[index]; if(i->b_reconciled == 0) { b = true; } } } if(!listMenu) { listMenu = new QMenu(this); listMenu->addAction(ActionMarkReconciled); listMenu->addSeparator(); listMenu->addAction(ActionEdit); listMenu->addAction(ActionClone); listMenu->addAction(ActionJoin); listMenu->addAction(ActionSplit); listMenu->addAction(ActionEditTimestamp); listMenu->addSeparator(); listMenu->addAction(ActionOpenFile); listMenu->addSeparator(); listMenu->addAction(ActionDelete); } ActionMarkReconciled->setVisible(reconcileButton->isChecked()); ActionMarkReconciled->setEnabled(b); listMenu->popup(transactionsView->viewport()->mapToGlobal(p)); } void LedgerDialog::toggleReconciliation(bool b) { transactionsView->setColumnHidden(0, !b); transactionsView->setAlternatingRowColors(!b); reconcileWidget->setVisible(b); markReconciledButton->setVisible(b); if(b) { updateReconciliationStats(true, true, true); reconcileStartEdit->setFocus(); } else { transactionsView->model()->blockSignals(true); QTreeWidgetItemIterator it(transactionsView, QTreeWidgetItemIterator::All); while(*it) { LedgerListViewItem *i = (LedgerListViewItem*) *it; i->updateMark(-1); ++it; } transactionsView->model()->blockSignals(false); transactionsView->dataChanged(QModelIndex(), QModelIndex()); } } void LedgerDialog::reconcileStartDateChanged(const QDate &date) { if(!date.isValid()) { QMessageBox::critical(this, tr("Error"), tr("Invalid date.")); return; } if(date > reconcileEndEdit->date()) { reconcileEndEdit->blockSignals(true); reconcileStartEdit->blockSignals(true); reconcileEndEdit->setDate(date); QMessageBox::critical(this, tr("Error"), tr("Opening date is after closing date.")); reconcileStartEdit->blockSignals(false); reconcileEndEdit->blockSignals(false); } updateReconciliationStats(false, true, true); } void LedgerDialog::reconcileEndDateChanged(const QDate &date) { if(!date.isValid()) { QMessageBox::critical(this, tr("Error"), tr("Invalid date.")); return; } if(date < reconcileStartEdit->date()) { reconcileEndEdit->blockSignals(true); reconcileStartEdit->blockSignals(true); reconcileStartEdit->setDate(date); QMessageBox::critical(this, tr("Error"), tr("Closing date is before opening date.")); reconcileStartEdit->blockSignals(false); reconcileEndEdit->blockSignals(false); } updateReconciliationStats(false, true, true); } void LedgerDialog::reconcileOpeningChanged(double) { re2 = re1; re1 = 1; reconcileClosingEdit->blockSignals(true); reconcileChangeEdit->blockSignals(true); if(re2 == 3) reconcileClosingEdit->setValue(reconcileOpeningEdit->value() + reconcileChangeEdit->value()); else reconcileChangeEdit->setValue(reconcileClosingEdit->value() - reconcileOpeningEdit->value()); reconcileClosingEdit->blockSignals(false); reconcileChangeEdit->blockSignals(false); updateReconciliationStatLabels(); } void LedgerDialog::reconcileClosingChanged(double) { re2 = re1; re1 = 2; reconcileOpeningEdit->blockSignals(true); reconcileChangeEdit->blockSignals(true); if(re2 == 3) reconcileOpeningEdit->setValue(reconcileClosingEdit->value() - reconcileChangeEdit->value()); else reconcileChangeEdit->setValue(reconcileClosingEdit->value() - reconcileOpeningEdit->value()); reconcileOpeningEdit->blockSignals(false); reconcileChangeEdit->blockSignals(false); updateReconciliationStatLabels(); } void LedgerDialog::reconcileChangeChanged(double) { re2 = re1; re1 = 3; reconcileClosingEdit->blockSignals(true); reconcileOpeningEdit->blockSignals(true); if(re2 == 2) reconcileOpeningEdit->setValue(reconcileClosingEdit->value() - reconcileChangeEdit->value()); else reconcileClosingEdit->setValue(reconcileOpeningEdit->value() + reconcileChangeEdit->value()); reconcileClosingEdit->blockSignals(false); reconcileOpeningEdit->blockSignals(false); updateReconciliationStatLabels(); } void LedgerDialog::onTransactionSpacePressed(QTreeWidgetItem *i) { transactionActivated(i, -1); } void LedgerDialog::onTransactionReturnPressed(QTreeWidgetItem *i) { if(transactionsView->isColumnHidden(0)) edit(i, -1); else transactionActivated(i, -1); } void LedgerDialog::transactionActivated(QTreeWidgetItem *i, int c) { if(c == 0 || (c < 0 && !transactionsView->isColumnHidden(0))) { LedgerListViewItem *li = (LedgerListViewItem*) i; if(li->b_reconciled >= 0) { Transactions *trans = li->splitTransaction(); if(!trans) trans = li->transaction(); if(!trans) return; bool b = !trans->isReconciled(account); trans->setReconciled(account, b); trans->setModified(); if(trans->isReconciled(account) == b) { if(trans->date() <= reconcileEndEdit->date()) { if(b) { if(trans->date() < reconcileStartEdit->date()) d_rec_op += trans->accountChange(account); d_rec_cl += trans->accountChange(account); } else { if(trans->date() < reconcileStartEdit->date()) d_rec_op -= trans->accountChange(account); d_rec_cl -= trans->accountChange(account); } } li->setReconciled(b, trans->date() > reconcileEndEdit->date() ? 0 : (trans->date() >= reconcileStartEdit->date() ? 1 : 2)); updateReconciliationStatLabels(); mainWin->setModified(true); } } } } void LedgerDialog::reconcileTransactions() { QList selection = transactionsView->selectedItems(); bool b = false; transactionsView->model()->blockSignals(true); for(int index = 0; index < selection.size(); index++) { LedgerListViewItem *i = (LedgerListViewItem*) selection[index]; if(i->b_reconciled == 0) { Transactions *trans = i->splitTransaction(); if(!trans) trans = i->transaction(); if(trans) { trans->setReconciled(account, true); trans->setModified(); if(trans->isReconciled(account)) { if(trans->date() <= reconcileEndEdit->date()) { if(trans->date() < reconcileStartEdit->date()) d_rec_op += trans->accountChange(account); d_rec_cl += trans->accountChange(account); } i->setReconciled(true, trans->date() > reconcileEndEdit->date() ? 0 : (trans->date() >= reconcileStartEdit->date() ? 1 : 2)); b = true; } } } } transactionsView->model()->blockSignals(false); if(b) { transactionsView->dataChanged(QModelIndex(), QModelIndex()); updateReconciliationStatLabels(); mainWin->setModified(true); } } void LedgerDialog::markAsReconciled() { QTreeWidgetItemIterator it(transactionsView, QTreeWidgetItemIterator::All); QDate d_end = reconcileEndEdit->date(); if(!d_end.isValid()) return; bool b_started = false; bool b = false; transactionsView->model()->blockSignals(true); while(*it) { LedgerListViewItem *i = (LedgerListViewItem*) *it; if(i->b_reconciled == 0) { Transactions *trans = i->transaction(); if(i->splitTransaction()) trans = i->splitTransaction(); if(trans && (b_started || trans->date() <= d_end)) { b_started = true; trans->setReconciled(account, true); trans->setModified(); if(trans->isReconciled(account)) { if(trans->date() <= reconcileEndEdit->date()) { if(trans->date() < reconcileStartEdit->date()) d_rec_op += trans->accountChange(account); d_rec_cl += trans->accountChange(account); } i->setReconciled(true, trans->date() > reconcileEndEdit->date() ? 0 : (trans->date() >= reconcileStartEdit->date() ? 1 : 2)); b = true; } } } ++it; } transactionsView->model()->blockSignals(false); if(b) { transactionsView->dataChanged(QModelIndex(), QModelIndex()); updateReconciliationStatLabels(); mainWin->setModified(true); } } void LedgerDialog::popupHeaderMenu(const QPoint &p) { if(!headerMenu) { headerMenu = new QMenu(this); QTreeWidgetItem *header = transactionsView->headerItem(); QAction *a = headerMenu->addAction(header->text(2)); a->setProperty("column_index", QVariant::fromValue(2)); a->setCheckable(true); a->setChecked(!transactionsView->isColumnHidden(2)); connect(a, SIGNAL(toggled(bool)), this, SLOT(hideColumn(bool))); a = headerMenu->addAction(header->text(3)); a->setProperty("column_index", QVariant::fromValue(3)); a->setCheckable(true); a->setChecked(!transactionsView->isColumnHidden(3)); connect(a, SIGNAL(toggled(bool)), this, SLOT(hideColumn(bool))); a = headerMenu->addAction(header->text(4)); a->setProperty("column_index", QVariant::fromValue(4)); a->setCheckable(true); a->setChecked(!transactionsView->isColumnHidden(4)); connect(a, SIGNAL(toggled(bool)), this, SLOT(hideColumn(bool))); if(b_extra) { a = headerMenu->addAction(header->text(5)); a->setProperty("column_index", QVariant::fromValue(5)); a->setCheckable(true); a->setChecked(!transactionsView->isColumnHidden(5)); connect(a, SIGNAL(toggled(bool)), this, SLOT(hideColumn(bool))); } a = headerMenu->addAction(header->text(6)); a->setCheckable(true); a->setProperty("column_index", QVariant::fromValue(6)); a->setChecked(!transactionsView->isColumnHidden(6)); connect(a, SIGNAL(toggled(bool)), this, SLOT(hideColumn(bool))); a = headerMenu->addAction(header->text(7)); a->setCheckable(true); a->setProperty("column_index", QVariant::fromValue(7)); a->setChecked(!transactionsView->isColumnHidden(7)); connect(a, SIGNAL(toggled(bool)), this, SLOT(hideColumn(bool))); headerMenu->addSeparator(); a = headerMenu->addAction(tr("Ascending order")); a->setCheckable(true); a->setChecked(b_ascending); connect(a, SIGNAL(toggled(bool)), this, SLOT(ascendingToggled(bool))); } headerMenu->popup(transactionsView->header()->viewport()->mapToGlobal(p)); } void LedgerDialog::ascendingToggled(bool b) { b_ascending = b; transactionsView->verticalScrollBar()->setValue(0); updateTransactions(); } void LedgerDialog::hideColumn(bool do_show) { transactionsView->setColumnHidden(sender()->property("column_index").toInt(), !do_show); } void LedgerDialog::saveConfig() { QSettings settings; settings.setValue("Ledger/size", size()); settings.setValue("Ledger/listState", transactionsView->header()->saveState()); settings.setValue("Ledger/ascending", b_ascending); } void LedgerDialog::accountChanged() { editAccountButton->setEnabled(account != NULL); if(!account) return; bool b_loan = (account->accountType() == ASSETS_TYPE_LIABILITIES || account->accountType() == ASSETS_TYPE_CREDIT_CARD); transactionsView->setColumnHidden(8, !b_loan); #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) # if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) QScreen *scr = screen(); # else QScreen *scr = QGuiApplication::screenAt(pos); # endif if(!scr) scr = QGuiApplication::primaryScreen(); QRect rect = scr->availableGeometry(); #else QRect rect = QApplication::desktop()->availableGeometry(this); #endif if(rect.width() > min_width_2 * 1.2) transactionsView->setMinimumWidth(b_loan ? min_width_2 : min_width_1); ActionNewDebtInterest->setVisible(b_loan); ActionNewDebtPayment->setVisible(b_loan); transactionsView->verticalScrollBar()->setValue(0); updateTransactions(true); reconcileOpeningEdit->setCurrency(account->currency()); reconcileChangeEdit->setCurrency(account->currency()); reconcileClosingEdit->setCurrency(account->currency()); } void LedgerDialog::accountActivated(int index) { if(accountCombo->itemData(index).isValid()) account = (AssetsAccount*) accountCombo->itemData(index).value(); accountChanged(); } void LedgerDialog::updateAccounts() { accountCombo->blockSignals(true); accountCombo->clear(); int i = 0; bool account_found = false; for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { AssetsAccount *aaccount = *it; if(aaccount != budget->balancingAccount && aaccount->accountType() != ASSETS_TYPE_SECURITIES) { accountCombo->addItem(aaccount->name(), QVariant::fromValue((void*) aaccount)); if(aaccount == account) { accountCombo->setCurrentIndex(i); account_found = true; } i++; } } if(!account_found) { if(accountCombo->count() == 0) { close(); return; } accountActivated(0); } else { updateTransactions(); } accountCombo->blockSignals(false); } extern QString last_document_directory; void LedgerDialog::saveView() { if(transactionsView->topLevelItemCount() == 0) { QMessageBox::critical(this, tr("Error"), tr("Empty transaction list.")); return; } char filetype = 'h'; QMimeDatabase db; QString html_filter = db.mimeTypeForName("text/html").filterString(); QString csv_filter = db.mimeTypeForName("text/csv").filterString(); QFileDialog fileDialog(this); fileDialog.setNameFilters(QStringList(html_filter) << csv_filter); fileDialog.selectNameFilter(html_filter); fileDialog.setDefaultSuffix(db.mimeTypeForName("text/html").preferredSuffix()); fileDialog.setAcceptMode(QFileDialog::AcceptSave); #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) fileDialog.setSupportedSchemes(QStringList("file")); #endif fileDialog.setDirectory(last_document_directory); connect(&fileDialog, SIGNAL(filterSelected(QString)), this, SLOT(onFilterSelected(QString))); QString url; if(!fileDialog.exec()) return; QStringList urls = fileDialog.selectedFiles(); if(urls.isEmpty()) return; url = urls[0]; if((fileDialog.selectedNameFilter() == csv_filter || db.mimeTypeForFile(url, QMimeDatabase::MatchExtension) == db.mimeTypeForName("text/csv")) && db.mimeTypeForFile(url, QMimeDatabase::MatchExtension) != db.mimeTypeForName("text/html")) filetype = 'c'; QSaveFile ofile(url); ofile.open(QIODevice::WriteOnly); if(!ofile.isOpen()) { ofile.cancelWriting(); QMessageBox::critical(this, tr("Error"), tr("Couldn't open file for writing.")); return; } last_document_directory = fileDialog.directory().absolutePath(); QTextStream stream(&ofile); exportList(stream, filetype); if(!ofile.commit()) { QMessageBox::critical(this, tr("Error"), tr("Error while writing file; file was not saved.")); return; } } void LedgerDialog::onFilterSelected(QString filter) { QMimeDatabase db; QFileDialog *fileDialog = qobject_cast(sender()); if(filter == db.mimeTypeForName("text/csv").filterString()) { fileDialog->setDefaultSuffix(db.mimeTypeForName("text/csv").preferredSuffix()); } else { fileDialog->setDefaultSuffix(db.mimeTypeForName("text/html").preferredSuffix()); } } bool LedgerDialog::exportList(QTextStream &outf, int fileformat, QDate first_date, QDate last_date) { switch(fileformat) { case 'h': { #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) outf.setCodec("UTF-8"); #endif outf << "" << '\n'; outf << "" << '\n'; outf << "\t" << '\n'; outf << "\t\t"; outf << htmlize_string(tr("Ledger")); outf << "" << '\n'; outf << "\t\t" << '\n'; outf << "\t\tapplicationDisplayName() << "\">" << '\n'; outf << "\t" << '\n'; outf << "\t" << '\n'; outf << "\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t\t" << '\n'; outf << "\t\t\t\t\t"; QTreeWidgetItem *header = transactionsView->headerItem(); for(int index = 1; index <= 11; index++) { if(!transactionsView->isColumnHidden(index)) outf << ""; } outf << "\n"; outf << "\t\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; QTreeWidgetItemIterator it(transactionsView); LedgerListViewItem *i = (LedgerListViewItem*) *it; while(i) { bool include = true; Transactions *transs = i->transaction(); if(!transs) transs = i->splitTransaction(); if(first_date.isValid() && (!transs || transs->date() < first_date)) include = false; if(include && last_date.isValid() && transs && transs->date() > last_date) include = false; if(include) { outf << "\t\t\t\t" << '\n'; outf << "\t\t\t\t\t"; for(int index = 1; index <= 11; index++) { if(!transactionsView->isColumnHidden(index)) { if(index == 1) outf << ""; else if(index >= 8) outf << ""; else outf << ""; } } outf << "\n"; outf << "\t\t\t\t" << '\n'; } ++it; i = (LedgerListViewItem*) *it; } outf << "\t\t\t" << '\n'; outf << "\t\t
    "; outf << htmlize_string(tr("Transactions for %1").arg(account->name())); outf << "
    " << htmlize_string(header->text(index)) << "
    " << htmlize_string(i->text(index)) << "" << htmlize_string(i->text(index)) << "" << htmlize_string(i->text(index)) << "
    " << '\n'; outf << "\t" << '\n'; outf << "" << '\n'; break; } case 'c': { //outf.setEncoding(Q3TextStream::Locale); QTreeWidgetItem *header = transactionsView->headerItem(); for(int index = 1; index <= 11; index++) { if(!transactionsView->isColumnHidden(index)) { if(index > 1) outf << ","; outf << "\"" << header->text(index) << "\""; } } outf << "\n"; QTreeWidgetItemIterator it(transactionsView); LedgerListViewItem *i = (LedgerListViewItem*) *it; while(i) { bool include = true; Transactions *transs = i->transaction(); if(!transs) transs = i->splitTransaction(); if(first_date.isValid() && (!transs || transs->date() < first_date)) include = false; if(include && last_date.isValid() && transs && transs->date() > last_date) include = false; if(include) { for(int index = 1; index <= 11; index++) { if(!transactionsView->isColumnHidden(index)) { if(index > 1) outf << ","; if(index >= 8) outf << "\"" << i->text(index).replace("−", "-").remove(" ") << "\""; else if(index == 6) outf << "\"" << i->text(index).replace("\"", "\'") << "\""; else outf << "\"" << i->text(index) << "\""; } } outf << "\n"; } ++it; i = (LedgerListViewItem*) *it; } break; } } return true; } void LedgerDialog::printView() { if(transactionsView->topLevelItemCount() == 0) { QMessageBox::critical(this, tr("Error"), tr("Empty transaction list.")); return; } QDate first_date, last_date = QDate::currentDate(); QTreeWidgetItemIterator it(transactionsView); LedgerListViewItem *i = (LedgerListViewItem*) *it; Transactions *transs = NULL, *prev_transs = NULL; while(i) { prev_transs = transs; transs = i->transaction(); if(!transs) transs = i->splitTransaction(); ++it; i = (LedgerListViewItem*) *it; } if(!transs) transs = prev_transs; if(transs) first_date = transs->date(); bool run_print = true; if(first_date.isValid()) { QDialog *dialog = new QDialog(this); dialog->setWindowTitle(tr("Select Time Period")); QVBoxLayout *box1 = new QVBoxLayout(dialog); QGridLayout *grid = new QGridLayout(); box1->addLayout(grid); grid->addWidget(new QLabel(tr("From:"), dialog), 0, 0); QDateEdit *dateFromEdit = new EqonomizeDateEdit(first_date, dialog); dateFromEdit->setCalendarPopup(true); grid->addWidget(dateFromEdit, 0, 1); grid->addWidget(new QLabel(tr("To:"), dialog), 1, 0); QDateEdit *dateToEdit = new EqonomizeDateEdit(QDate::currentDate(), dialog); dateToEdit->setCalendarPopup(true); grid->addWidget(dateToEdit, 1, 1); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, dialog); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), dialog, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), dialog, SLOT(accept())); box1->addWidget(buttonBox); if(dialog->exec() == QDialog::Accepted) { if(dateFromEdit->date() <= first_date) first_date = QDate(); else first_date = dateFromEdit->date(); last_date = dateToEdit->date(); if(last_date < first_date) { QMessageBox::critical(this, tr("Error"), tr("To date is before from date.")); run_print = false; } } else { run_print = false; } dialog->deleteLater(); } if(run_print) { QPrinter printer; QPrintDialog print_dialog(&printer, this); if(print_dialog.exec() == QDialog::Accepted) { QString str; QTextStream stream(&str, QIODevice::WriteOnly); exportList(stream, 'h', first_date, last_date); QTextDocument htmldoc; htmldoc.setHtml(str); htmldoc.print(&printer); } } } void LedgerDialog::joinTransactions() { QList selection = transactionsView->selectedItems(); MultiItemTransaction *split = NULL; QString payee; QString file; QList sel_bak; bool use_payee = true; for(int index = 0; index < selection.size(); index++) { LedgerListViewItem *i = (LedgerListViewItem*) selection[index]; if(!i->splitTransaction()) { Transaction *trans = i->transaction(); if(trans && !trans->parentSplit()) { sel_bak << trans; if(!split) { split = new MultiItemTransaction(budget, i->transaction()->date(), account); } if(!trans->associatedFile().isEmpty()) { if(split->associatedFile().isEmpty()) { split->setAssociatedFile(trans->associatedFile()); } else { QString str; if((split->associatedFile().startsWith("\"") && split->associatedFile().endsWith("\"")) || (split->associatedFile().startsWith("\'") && split->associatedFile().endsWith("\'"))) str += split->associatedFile(); else if(split->associatedFile().contains("\"")) {str += "\'"; str += split->associatedFile(); str += "\'";} else {str += "\""; str += split->associatedFile(); str += "\"";} str += ", "; if((trans->associatedFile().startsWith("\"") && trans->associatedFile().endsWith("\"")) || (trans->associatedFile().startsWith("\'") && trans->associatedFile().endsWith("\'"))) str += trans->associatedFile(); else if(trans->associatedFile().contains("\"")) {str += "\'"; str += trans->associatedFile(); str += "\'";} else {str += "\""; str += trans->associatedFile(); str += "\"";} split->setAssociatedFile(str); } } if(use_payee) { if(payee.isEmpty()) { if(trans->type() == TRANSACTION_TYPE_EXPENSE) payee = ((Expense*) trans)->payee(); else if(trans->type() == TRANSACTION_TYPE_INCOME) payee = ((Income*) trans)->payer(); } else { if(trans->type() == TRANSACTION_TYPE_EXPENSE && !((Expense*) trans)->payee().isEmpty() && payee != ((Expense*) trans)->payee()) use_payee = false; else if(trans->type() == TRANSACTION_TYPE_INCOME && !((Income*) trans)->payer().isEmpty() && payee != ((Income*) trans)->payer()) use_payee = false; } } split->addTransaction(trans->copy()); } } } if(!split) return; if(use_payee && !payee.isEmpty()) split->setPayee(payee); if(mainWin->editSplitTransaction(split, this, true)) { delete split; for(int index = 0; index < sel_bak.size(); index++) { Transaction *trans = sel_bak.at(index); budget->removeTransaction(trans, true); mainWin->transactionRemoved(trans); delete trans; } } else { delete split; } } void LedgerDialog::splitUpTransaction() { QList selection = transactionsView->selectedItems(); LedgerListViewItem *i = (LedgerListViewItem*) selection.first(); if(i) { if(i->splitTransaction() && i->splitTransaction()->type() == SPLIT_TRANSACTION_TYPE_MULTIPLE_ITEMS) mainWin->splitUpTransaction(i->splitTransaction()); else if(i->transaction() && i->transaction()->parentSplit() && i->transaction()->parentSplit()->type() == SPLIT_TRANSACTION_TYPE_MULTIPLE_ITEMS) mainWin->splitUpTransaction(i->transaction()->parentSplit()); } } void LedgerDialog::transactionSelectionChanged() { QList selection = transactionsView->selectedItems(); bool selected = !selection.isEmpty(); bool b_join = selected; bool b_split = selected; bool b_edit = selected; bool b_remove = selected; bool b_file = selected; bool b_clone = selection.size() == 1; SplitTransaction *split = NULL; for(int index = 0; index < selection.size(); index++) { LedgerListViewItem *i = (LedgerListViewItem*) selection[index]; Transaction *trans = i->transaction(); if(i->splitTransaction()) { if(b_edit && (index > 0 || selection.size() > 1)) b_edit = false; b_join = false; if(b_split) b_split = (selection.count() == 1) && (i->splitTransaction()->type() != SPLIT_TRANSACTION_TYPE_LOAN); if(b_file) b_file = (selection.count() == 1) && !i->splitTransaction()->associatedFile().isEmpty(); } else if(!trans) { if(selection.size() > 1) b_edit = false; b_remove = false; b_join = false; b_split = false; b_file = false; b_clone = false; break; } else { if((b_join || b_edit) && trans->subtype() == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND) { b_join = false; if(index > 0 || selection.size() > 1) b_edit = false; } if(b_edit && trans->parentSplit() && (index > 0 || selection.size() > 1)) b_edit = false; if(b_split) { if(!split) split = trans->parentSplit(); if(!trans->parentSplit() || trans->parentSplit() != split || trans->parentSplit()->type() == SPLIT_TRANSACTION_TYPE_LOAN) b_split = false; } if(b_join && trans->parentSplit()) b_join = false; if(b_file) b_file = (selection.count() == 1) && (!trans->associatedFile().isEmpty() || (trans->parentSplit() && !trans->parentSplit()->associatedFile().isEmpty())); } } if(b_join && selection.size() == 1) b_join = false; joinButton->setEnabled(b_join); ActionJoin->setEnabled(b_join); splitUpButton->setEnabled(b_split); ActionSplit->setEnabled(b_split); removeButton->setEnabled(b_remove); ActionDelete->setEnabled(b_remove); editButton->setEnabled(b_edit); ActionEdit->setEnabled(b_edit); ActionClone->setEnabled(b_clone); ActionOpenFile->setEnabled(b_file); ActionEditTimestamp->setEnabled(b_edit); if(selection.size() > 1) { double v = 0.0, total_balance = 0.0, previous_balance = 0.0; int quantity = 0; QDate first_date, last_date; LedgerListViewItem *i_prev = NULL; bool b_continuous = true, b_initial = false; bool b_reverse = transactionsView->itemAbove(selection[0]) != selection[1]; for(int index = (b_reverse ? selection.size() - 1 : 0); b_reverse ? index >= 0 : index < selection.size(); b_reverse ? index-- : index++) { LedgerListViewItem *i = (LedgerListViewItem*) selection[index]; if(b_continuous && i_prev && transactionsView->itemAbove(i_prev) != i) b_continuous = false; i_prev = i; Transactions *trans = i->transaction(); if(i->splitTransaction()) trans = i->splitTransaction(); if(trans) { if(!i->b_other_account) { v += trans->accountChange(account); quantity++; if(b_continuous) { if(last_date.isValid() && trans->date() != last_date) total_balance += previous_balance * last_date.daysTo(trans->date()); previous_balance = i->d_balance; last_date = trans->date(); if(!first_date.isValid()) first_date = last_date; } } } else { v += i->d_balance; b_initial = true; } } if(b_continuous) { total_balance += previous_balance; if(first_date.isValid() && first_date != last_date) total_balance /= first_date.daysTo(last_date) + 1; } if(quantity + b_initial > 1) { if(b_continuous) statLabel->setText(QString("
    %1 %4   %2 %5   %3 %6
    ").arg(tr("Balance change:", "Account balance")).arg(tr("Average balance:", "Account balance")).arg(tr("Number of transactions:")).arg(account->currency()->formatValue(v)).arg(account->currency()->formatValue(total_balance)).arg(budget->formatValue(quantity, 0))); else statLabel->setText(QString("
    %1 %3   %2 %4").arg(tr("Balance change:", "Account balance")).arg(tr("Number of transactions:")).arg(account->currency()->formatValue(v)).arg(budget->formatValue(quantity, 0))); } else { statLabel->setText(stat_total_text); } } else { statLabel->setText(stat_total_text); } } void LedgerDialog::newExpense() { mainWin->newScheduledTransaction(TRANSACTION_TYPE_EXPENSE, NULL, false, this, account); } void LedgerDialog::newIncome() { mainWin->newScheduledTransaction(TRANSACTION_TYPE_INCOME, NULL, false, this, account); } void LedgerDialog::newTransfer() { mainWin->newScheduledTransaction(TRANSACTION_TYPE_TRANSFER, NULL, false, this, account); } void LedgerDialog::newSplit() { mainWin->newMultiItemTransaction(this, account); } void LedgerDialog::newDebtPayment() { mainWin->newDebtPayment(this, account, false); } void LedgerDialog::newDebtInterest() { mainWin->newDebtPayment(this, account, true); } void LedgerDialog::remove() { QList selection = transactionsView->selectedItems(); if(selection.count() > 1) { if(QMessageBox::warning(this, tr("Delete transactions?"), tr("Are you sure you want to delete all (%1) selected transactions?").arg(selection.count()), QMessageBox::Ok | QMessageBox::Cancel) != QMessageBox::Ok) { return; } mainWin->startBatchEdit(); } transactionsView->clearSelection(); for(int index = 0; index < selection.size(); index++) { LedgerListViewItem *i = (LedgerListViewItem*) selection[index]; if(i->splitTransaction()) { SplitTransaction *split = i->splitTransaction(); qDebug() << split->description(); budget->removeSplitTransaction(split, true); mainWin->transactionRemoved(split, NULL, true); delete split; } else if(i->transaction()) { Transaction *trans = i->transaction(); if(trans->parentSplit() && trans->parentSplit()->count() == 1) { SplitTransaction *split = trans->parentSplit(); budget->removeSplitTransaction(split, true); mainWin->transactionRemoved(split, NULL, true); delete split; } else if(trans->parentSplit() && trans->parentSplit()->type() != SPLIT_TRANSACTION_TYPE_LOAN && trans->parentSplit()->count() == 2) { SplitTransaction *split = trans->parentSplit(); mainWin->splitUpTransaction(split); budget->removeTransaction(trans, true); mainWin->transactionRemoved(trans, NULL, true); delete trans; } else { budget->removeTransaction(trans, true); mainWin->transactionRemoved(trans, NULL, true); delete trans; } } } if(selection.count() > 1) mainWin->endBatchEdit(); } void LedgerDialog::openAssociatedFile() { QList selection = transactionsView->selectedItems(); if(selection.count() > 0) { LedgerListViewItem *i = (LedgerListViewItem*) selection.first(); Transactions *transs = i->transaction(); if(i->splitTransaction()) transs = i->splitTransaction(); else if(i->transaction()->parentSplit() && transs->associatedFile().isEmpty()) transs = i->transaction()->parentSplit(); if(transs) { open_file_list(transs->associatedFile()); } } } void LedgerDialog::editTimestamp() { QList selection = transactionsView->selectedItems(); QList trans; for(int index = 0; index < selection.size(); index++) { LedgerListViewItem *i = (LedgerListViewItem*) selection[index]; if(i->splitTransaction()) trans << i->splitTransaction(); else if(i->transaction()) trans << i->transaction(); } mainWin->editTimestamp(trans, this); } void LedgerDialog::cloneTransaction() { QList selection = transactionsView->selectedItems(); if(selection.count() == 1) { LedgerListViewItem *i = (LedgerListViewItem*) selection.first(); if(i->splitTransaction()) mainWin->editSplitTransaction(i->splitTransaction(), this, true); else if(i->transaction()->parentSplit()) mainWin->editSplitTransaction(i->transaction()->parentSplit(), this, false, true); else if(i->transaction()) mainWin->editTransaction(i->transaction(), this, true); } } void LedgerDialog::edit() { QList selection = transactionsView->selectedItems(); if(selection.count() == 1) { LedgerListViewItem *i = (LedgerListViewItem*) selection.first(); if(i->splitTransaction()) mainWin->editSplitTransaction(i->splitTransaction(), this); else if(!i->transaction()) mainWin->editAccount(account, this); else if(i->transaction()->parentSplit()) mainWin->editSplitTransaction(i->transaction()->parentSplit(), this); else if(i->transaction()) mainWin->editTransaction(i->transaction(), this); } else if(selection.count() > 1) { bool warned1 = false, warned2 = false, warned3 = false; bool equal_date = true, equal_description = true, equal_value = true, equal_category = true, equal_payee = b_extra; int transtype = -1; Transaction *comptrans = NULL; Account *compcat = NULL; QDate compdate; for(int index = 0; index < selection.size(); index++) { LedgerListViewItem *i = (LedgerListViewItem*) selection[index]; if(i->transaction() && !i->transaction()->parentSplit()) { if(!comptrans) { comptrans = i->transaction(); compdate = i->transaction()->date(); transtype = i->transaction()->type(); if(i->transaction()->type() != TRANSACTION_TYPE_EXPENSE && i->transaction()->type() != TRANSACTION_TYPE_INCOME) equal_payee = false; if(i->transaction()->type() == TRANSACTION_TYPE_INCOME) { compcat = ((Income*) i->transaction())->category(); } else if(i->transaction()->type() == TRANSACTION_TYPE_EXPENSE) { compcat = ((Expense*) i->transaction())->category(); } else if(i->transaction()->type() == TRANSACTION_TYPE_SECURITY_BUY || i->transaction()->type() == TRANSACTION_TYPE_SECURITY_SELL) { equal_value = false; equal_description = false; compcat = ((SecurityTransaction*) i->transaction())->account(); if(compcat->type() == ACCOUNT_TYPE_ASSETS) { equal_category = false; } } } else { if(transtype >= 0 && i->transaction()->type() != transtype) { transtype = -1; } if(equal_date && (compdate != i->transaction()->date())) { equal_date = false; } if(equal_description && (i->transaction()->type() == TRANSACTION_TYPE_SECURITY_BUY || i->transaction()->type() == TRANSACTION_TYPE_SECURITY_SELL || comptrans->description() != i->transaction()->description())) { equal_description = false; } if(equal_payee && (i->transaction()->type() != comptrans->type() || (comptrans->type() == TRANSACTION_TYPE_EXPENSE && ((Expense*) comptrans)->payee() != ((Expense*) i->transaction())->payee()) || (comptrans->type() == TRANSACTION_TYPE_INCOME && ((Income*) comptrans)->payer() != ((Income*) i->transaction())->payer()))) { equal_payee = false; } if(equal_value && (i->transaction()->type() == TRANSACTION_TYPE_SECURITY_BUY || i->transaction()->type() == TRANSACTION_TYPE_SECURITY_SELL || comptrans->value() != i->transaction()->value())) { equal_value = false; } if(equal_category) { if(i->transaction()->type() == TRANSACTION_TYPE_INCOME) { if(compcat != ((Income*) i->transaction())->category()) { equal_category = false; } } else if(i->transaction()->type() == TRANSACTION_TYPE_EXPENSE) { if(compcat != ((Expense*) i->transaction())->category()) { equal_category = false; } } else if(i->transaction()->type() == TRANSACTION_TYPE_SECURITY_BUY || i->transaction()->type() == TRANSACTION_TYPE_SECURITY_SELL) { if(compcat != ((SecurityTransaction*) i->transaction())->account()) { equal_category = false; } } } } } } MultipleTransactionsEditDialog *dialog = new MultipleTransactionsEditDialog(b_extra, transtype, budget, this); LedgerListViewItem *i = (LedgerListViewItem*) transactionsView->currentItem(); if(!i || !i->isSelected()) i = (LedgerListViewItem*) selection.first(); if(i && i->transaction()) { dialog->setTransaction(i->transaction()); } if(equal_description) dialog->descriptionButton->setChecked(true); if(equal_payee && dialog->payeeButton) dialog->payeeButton->setChecked(true); if(equal_value && dialog->valueButton) dialog->valueButton->setChecked(true); if(equal_date) dialog->dateButton->setChecked(true); if(equal_category && dialog->categoryButton) dialog->categoryButton->setChecked(true); if(dialog->exec() == QDialog::Accepted) { QDate date = dialog->date(); bool future = !date.isNull() && date > QDate::currentDate(); mainWin->startBatchEdit(); for(int index = 0; index < selection.size(); index++) { LedgerListViewItem *i = (LedgerListViewItem*) selection[index]; if(i->transaction() && !i->transaction()->parentSplit()) { if(!warned1 && (i->transaction()->type() == TRANSACTION_TYPE_SECURITY_BUY || i->transaction()->type() == TRANSACTION_TYPE_SECURITY_SELL)) { if(dialog->valueButton && dialog->valueButton->isChecked()) { QMessageBox::critical(this, tr("Error"), tr("Cannot set the value of security transactions using the dialog for modifying multiple transactions.", "Financial security (e.g. stock, mutual fund)")); warned1 = true; } } if(!warned2 && (i->transaction()->type() == TRANSACTION_TYPE_SECURITY_BUY || i->transaction()->type() == TRANSACTION_TYPE_SECURITY_SELL || (i->transaction()->type() == TRANSACTION_TYPE_INCOME && ((Income*) i->transaction())->security()))) { if(dialog->descriptionButton->isChecked()) { QMessageBox::critical(this, tr("Error"), tr("Cannot change description of dividends and security transactions.", "Referring to the transaction description property (transaction title/generic article name); Financial security (e.g. stock, mutual fund)")); warned2 = true; } } if(!warned3 && dialog->payeeButton && (i->transaction()->type() == TRANSACTION_TYPE_SECURITY_BUY || i->transaction()->type() == TRANSACTION_TYPE_SECURITY_SELL || (i->transaction()->type() == TRANSACTION_TYPE_INCOME && ((Income*) i->transaction())->security()))) { if(dialog->payeeButton->isChecked()) { QMessageBox::critical(this, tr("Error"), tr("Cannot change payer of dividends and security transactions.", "Financial security (e.g. stock, mutual fund)")); warned3 = true; } } Transaction *trans = i->transaction(); Transaction *oldtrans = trans->copy(); if(dialog->modifyTransaction(trans)) { if(future) { budget->removeTransaction(trans, true); mainWin->transactionRemoved(trans); ScheduledTransaction *strans = new ScheduledTransaction(budget, trans, NULL); budget->addScheduledTransaction(strans); mainWin->transactionAdded(strans); } else { mainWin->transactionModified(trans, oldtrans); } } delete oldtrans; } } mainWin->endBatchEdit(); //transactionSelectionChanged(); } dialog->deleteLater(); } } void LedgerDialog::edit(QTreeWidgetItem *qwi, int c) { if(c != 0 && qwi) { LedgerListViewItem *i = (LedgerListViewItem*) qwi; if(i->splitTransaction()) mainWin->editSplitTransaction(i->splitTransaction(), this); else if(!i->transaction()) mainWin->editAccount(account, this); else if(i->transaction()->parentSplit()) mainWin->editSplitTransaction(i->transaction()->parentSplit(), this); else if(i->transaction()) mainWin->editTransaction(i->transaction(), this); } } void LedgerDialog::updateTransactions(bool update_reconciliation_date) { expenseColor = QColor(); incomeColor = QColor(); int scroll_h = transactionsView->horizontalScrollBar()->value(); int scroll_v = transactionsView->verticalScrollBar()->value(); Transaction *selected_transaction = NULL; SplitTransaction *selected_split = NULL; QList selection = transactionsView->selectedItems(); if(selection.count() == 1) { LedgerListViewItem *i = (LedgerListViewItem*) selection.first(); selected_split = i->splitTransaction(); if(!selected_split) selected_transaction = i->transaction(); } int scrollpos = transactionsView->verticalScrollBar()->value(); transactionsView->clear(); double balance = account->initialBalance(); double total_balance = 0.0; double previous_balance = 0.0; QDate previous_date; double reductions = 0.0; double expenses = 0.0; int quantity = 0; QDate curdate = QDate::currentDate(); bool b_reconciling = reconcileButton->isChecked(); if(balance != 0.0) { LedgerListViewItem *i = new LedgerListViewItem(NULL, NULL, transactionsView, "-", "-", tr("Opening balance", "Account balance"), "-", "-", QString(), QString(), QString(), QString(), account->currency()->formatValue(balance)); i->d_balance = balance; previous_balance = balance; i->setReconciled(-1, b_reconciling ? 2 : -2); } int trans_index = 0; int split_index = 0; Transaction *trans = NULL; if(trans_index < budget->transactions.size()) trans = budget->transactions.at(trans_index); SplitTransaction *split = NULL; if(split_index < budget->splitTransactions.size()) split = budget->splitTransactions.at(split_index); Transactions *transs = trans; if(!transs || (split && split->date() < trans->date())) transs = split; QVector splits; bool last_reconciled = true; QDate rec_date, first_date; LedgerListViewItem *selected_item = NULL; while(transs) { if(transs == split) { if(split->type() == SPLIT_TRANSACTION_TYPE_MULTIPLE_ITEMS && ((MultiItemTransaction*) split)->account() == account) { double value = split->accountChange(account); balance += value; if(previous_date.isValid() && split->date() != previous_date) total_balance += previous_balance * previous_date.daysTo(split->date()); previous_balance = balance; previous_date = split->date(); if(!first_date.isValid()) first_date = previous_date; LedgerListViewItem *i = new LedgerListViewItem(NULL, split, NULL, QLocale().toString(split->date(), QLocale::ShortFormat), tr("Split Transaction"), split->description(), ((MultiItemTransaction*) split)->fromAccountsString(), split->payeeText(), split->tagsText(), split->comment(), (value >= 0.0) ? account->currency()->formatValue(value) : QString(), (value < 0.0) ? account->currency()->formatValue(-value) : QString(), account->currency()->formatValue(balance)); if(b_ascending) transactionsView->addTopLevelItem(i); else transactionsView->insertTopLevelItem(0, i); i->setColors(); i->d_balance = balance; i->setReconciled(split->isReconciled(account), b_reconciling ? 2 : -2); if(split->isReconciled(account)) { last_reconciled = true; } else if(last_reconciled) { rec_date = split->date(); last_reconciled = false; } quantity++; if(split == selected_split) { selected_item = i; } if(!split->associatedFile().isEmpty()) i->setIcon(value >= 0 ? 9 : 10, LOAD_ICON_STATUS("mail-attachment")); } else if(split->type() == SPLIT_TRANSACTION_TYPE_LOAN) { if(((DebtPayment*) split)->loan() == account) { DebtPayment *lsplit = (DebtPayment*) split; Transaction *ltrans = lsplit->paymentTransaction(); bool b_tb = false; if(ltrans) { b_tb = true; double value = ltrans->toValue(); balance += value; reductions += value; LedgerListViewItem *i = new LedgerListViewItem(ltrans, NULL, NULL, QLocale().toString(split->date(), QLocale::ShortFormat), tr("Debt Payment"), tr("Reduction"), ltrans->fromAccount()->name(), lsplit->loan()->maintainer(), ltrans->tagsText(true), lsplit->comment(), (value >= 0.0) ? account->currency()->formatValue(value) : QString(), value >= 0.0 ? QString() : account->currency()->formatValue(-value), account->currency()->formatValue(balance)); if(b_ascending) transactionsView->addTopLevelItem(i); else transactionsView->insertTopLevelItem(0, i); i->setColors(); i->d_balance = balance; i->setReconciled(ltrans->isReconciled(account), b_reconciling ? 2 : -2); if(ltrans->isReconciled(account)) { last_reconciled = true; } else if(last_reconciled) { rec_date = ltrans->date(); last_reconciled = false; } if(ltrans == selected_transaction) { selected_item = i; } quantity++; if(!split->associatedFile().isEmpty()) i->setIcon(value >= 0 ? 9 : 10, LOAD_ICON_STATUS("mail-attachment")); } ltrans = lsplit->feeTransaction(); if(ltrans) { double value = ltrans->value(); expenses += value; bool to_balance = (ltrans->fromAccount() == account); if(to_balance) { b_tb = true; balance -= value; reductions -= value; quantity++; } LedgerListViewItem *i = new LedgerListViewItem(ltrans, NULL, NULL, QLocale().toString(split->date(), QLocale::ShortFormat), tr("Debt Payment"), tr("Fee"), ltrans->fromAccount()->name(), ((DebtFee*) ltrans)->payee(), ltrans->tagsText(true), lsplit->comment(), (to_balance || value >= 0.0) ? QString() : account->currency()->formatValue(-value), (to_balance && value >= 0.0) ? account->currency()->formatValue(value) : QString(), account->currency()->formatValue(balance), to_balance ? QString() : account->currency()->formatValue(value)); if(b_ascending) transactionsView->addTopLevelItem(i); else transactionsView->insertTopLevelItem(0, i); i->setColors(); i->d_balance = balance; i->b_other_account = !to_balance; i->setReconciled(to_balance ? ltrans->isReconciled(account) : -1, b_reconciling ? 2 : -2); if(ltrans->isReconciled(account)) { last_reconciled = true; } else if(last_reconciled) { rec_date = ltrans->date(); last_reconciled = false; } if(ltrans == selected_transaction) { selected_item = i; } if(!split->associatedFile().isEmpty()) i->setIcon(to_balance ? (value >= 0.0 ? 10 : 9) : 8, LOAD_ICON_STATUS("mail-attachment")); } ltrans = lsplit->interestTransaction(); if(ltrans) { double value = ltrans->value(); expenses += value; bool to_balance = (ltrans->fromAccount() == account); if(to_balance) { b_tb = true; balance -= value; reductions -= value; quantity++; } LedgerListViewItem *i = new LedgerListViewItem(ltrans, NULL, NULL, QLocale().toString(split->date(), QLocale::ShortFormat), tr("Debt Payment"), tr("Interest"), ltrans->fromAccount()->name(), ((DebtInterest*) ltrans)->payee(), ltrans->tagsText(true), lsplit->comment(), (to_balance || value >= 0.0) ? QString() : account->currency()->formatValue(-value), (to_balance && value >= 0.0) ? account->currency()->formatValue(value) : QString(), account->currency()->formatValue(balance), to_balance ? QString() : account->currency()->formatValue(value)); if(b_ascending) transactionsView->addTopLevelItem(i); else transactionsView->insertTopLevelItem(0, i); i->setColors(); i->d_balance = balance; i->b_other_account = !to_balance; i->setReconciled(to_balance ? ltrans->isReconciled(account) : -1, b_reconciling ? 2 : -2); if(ltrans->isReconciled(account)) { last_reconciled = true; } else if(last_reconciled) { rec_date = ltrans->date(); last_reconciled = false; } if(ltrans == selected_transaction) { selected_item = i; } if(!split->associatedFile().isEmpty()) i->setIcon(to_balance ? (value >= 0.0 ? 10 : 9) : 8, LOAD_ICON_STATUS("mail-attachment")); } if(b_tb) { if(previous_date.isValid() && lsplit->date() != previous_date) total_balance += previous_balance * previous_date.daysTo(lsplit->date()); previous_balance = balance; previous_date = lsplit->date(); if(!first_date.isValid()) first_date = previous_date; } } else if(((DebtPayment*) split)->account() == account) { double value = split->accountChange(account); if(value != 0.0) { balance += value; LedgerListViewItem *i = new LedgerListViewItem(NULL, split, NULL, QLocale().toString(split->date(), QLocale::ShortFormat), tr("Debt Payment"), split->description(), ((DebtPayment*) split)->loan()->name(), ((DebtPayment*) split)->loan()->maintainer(), split->tagsText(), split->comment(), (value >= 0.0) ? account->currency()->formatValue(value) : QString(), (value < 0.0) ? account->currency()->formatValue(-value) : QString(), account->currency()->formatValue(balance)); if(b_ascending) transactionsView->addTopLevelItem(i); else transactionsView->insertTopLevelItem(0, i); i->setColors(); i->d_balance = balance; i->setReconciled(split->isReconciled(account), b_reconciling ? 2 : -2); if(split->isReconciled(account)) { last_reconciled = true; } else if(last_reconciled) { rec_date = split->date(); last_reconciled = false; } quantity++; if(split == selected_split) { selected_item = i; } if(!split->associatedFile().isEmpty()) i->setIcon(value >= 0 ? 9 : 10, LOAD_ICON_STATUS("mail-attachment")); } if(previous_date.isValid() && split->date() != previous_date) total_balance += previous_balance * previous_date.daysTo(split->date()); previous_balance = balance; previous_date = split->date(); if(!first_date.isValid()) first_date = previous_date; } } } else if(transs->relatesToAccount(account) && (!trans->parentSplit() || trans->parentSplit()->type() == SPLIT_TRANSACTION_TYPE_MULTIPLE_ACCOUNTS || (trans->parentSplit()->type() == SPLIT_TRANSACTION_TYPE_MULTIPLE_ITEMS && ((MultiItemTransaction*) trans->parentSplit())->account() != account))) { double value = trans->accountChange(account); balance += value; LedgerListViewItem *i = new LedgerListViewItem(trans, NULL, NULL, QLocale().toString(trans->date(), QLocale::ShortFormat), QString(), trans->description(), account == trans->fromAccount() ? trans->toAccount()->name() : trans->fromAccount()->name(), trans->payeeText(), trans->tagsText(true), trans->comment(), (value >= 0.0) ? account->currency()->formatValue(value) : QString(), value >= 0.0 ? QString() : account->currency()->formatValue(-value), account->currency()->formatValue(balance)); quantity++; if(b_ascending) transactionsView->addTopLevelItem(i); else transactionsView->insertTopLevelItem(0, i); i->setColors(); i->setReconciled(trans->isReconciled(account), b_reconciling ? 2 : -2); if(trans->type() == TRANSACTION_TYPE_INCOME) { if(value >= 0.0) i->setText(2, tr("Income")); else i->setText(2, tr("Repayment")); } else if(trans->type() == TRANSACTION_TYPE_EXPENSE) { if(value <= 0.0) i->setText(2, tr("Expense")); else i->setText(2, tr("Refund")); } else if(trans->relatesToAccount(budget->balancingAccount)) { i->setText(2, tr("Account Balance Adjustment")); i->setReconciled(-1, b_reconciling ? 2 : -2); } else { i->setText(2, tr("Transfer")); } if(trans == selected_transaction) { selected_item = i; } i->d_balance = balance; if(trans->isReconciled(account)) { last_reconciled = true; } else if(last_reconciled) { rec_date = trans->date(); last_reconciled = false; } if(previous_date.isValid() && trans->date() != previous_date) total_balance += previous_balance * previous_date.daysTo(trans->date()); previous_balance = balance; previous_date = trans->date(); if(!first_date.isValid()) first_date = previous_date; if(!trans->associatedFile().isEmpty() || (trans->parentSplit() && !trans->parentSplit()->associatedFile().isEmpty())) i->setIcon(value >= 0 ? 9 : 10, LOAD_ICON_STATUS("mail-attachment")); } if(transs == trans) { ++trans_index; trans = NULL; if(trans_index < budget->transactions.size()) trans = budget->transactions.at(trans_index); if(trans && trans->date() > curdate) trans = NULL; } else { ++split_index; split = NULL; if(split_index < budget->splitTransactions.size()) split = budget->splitTransactions.at(split_index); if(split && split->date() > curdate) split = NULL; } transs = trans; if(!transs || (split && (split->date() < trans->date() || (split->date() == trans->date() && split->timestamp() < trans->timestamp())))) transs = split; } if(!update_reconciliation_date) transactionsView->verticalScrollBar()->setValue(scrollpos); if(selected_item) { selected_item->setSelected(true); transactionsView->setCurrentItem(selected_item); transactionsView->scrollToItem(selected_item); } if(previous_date.isValid() && previous_date < QDate::currentDate()) previous_balance *= previous_date.daysTo(QDate::currentDate()); total_balance += previous_balance; if(first_date.isValid() && first_date < QDate::currentDate()) total_balance /= (first_date.daysTo(QDate::currentDate()) + (previous_date == QDate::currentDate() ? 1 : 0)); if(account->accountType() == ASSETS_TYPE_LIABILITIES || account->accountType() == ASSETS_TYPE_CREDIT_CARD) { stat_total_text = QString("
    %1 %4   %2 %5   %3 %6
    ").arg(tr("Current debt:")).arg(tr("Total debt reduction:")).arg(tr("Total interest and fees:")).arg(account->currency()->formatValue(-balance)).arg(account->currency()->formatValue(reductions)).arg(account->currency()->formatValue(expenses)); } else { stat_total_text = QString("
    %1 %4   %2 %5   %3 %6
    ").arg(tr("Current balance:", "Account balance")).arg(tr("Average balance:", "Account balance")).arg(tr("Number of transactions:")).arg(account->currency()->formatValue(balance)).arg(account->currency()->formatValue(total_balance)).arg(budget->formatValue(quantity, 0)); } statLabel->setText(stat_total_text); transactionsView->horizontalScrollBar()->setValue(scroll_h); transactionsView->verticalScrollBar()->setValue(scroll_v); if(!rec_date.isValid()) { LedgerListViewItem *i = (LedgerListViewItem*) transactionsView->topLevelItem(0); if(i) { if(i->splitTransaction()) rec_date = i->splitTransaction()->date(); else if(i->transaction()) rec_date = i->transaction()->date(); if(rec_date < QDate::currentDate()) rec_date = rec_date.addDays(1); } } if(update_reconciliation_date && rec_date.isValid()) { reconcileStartEdit->blockSignals(true); reconcileStartEdit->setDate(rec_date); reconcileStartEdit->blockSignals(false); } labelExpenseColor = QColor(); labelIncomeColor = QColor(); labelTransferColor = QColor(); if(b_reconciling) updateReconciliationStats(false, true, true); } void LedgerDialog::reject() { saveConfig(); QDialog::reject(); } void LedgerDialog::editAccount() { if(!account) return; mainWin->editAccount(account, this); } void LedgerDialog::search() { QString str = searchEdit->text().trimmed(); if(str.isEmpty()) return; QTreeWidgetItem *i_first = transactionsView->currentItem(); if(i_first && !i_first->isSelected()) i_first = NULL; QTreeWidgetItemIterator it(transactionsView, QTreeWidgetItemIterator::All); if(i_first) { it = QTreeWidgetItemIterator(i_first, QTreeWidgetItemIterator::All); ++it; if(!(*it)) { i_first = NULL; it = QTreeWidgetItemIterator(transactionsView, QTreeWidgetItemIterator::All); } } transactionsView->clearSelection(); transactionsView->setCurrentItem(NULL); bool wrapped_around = false; while(*it) { if(((LedgerListViewItem*) *it)->matches(str)) { (*it)->setSelected(true); transactionsView->setCurrentItem(*it, 1); transactionsView->scrollToItem(*it); break; } if(wrapped_around && *it == i_first) break; ++it; if(!wrapped_around && i_first && !(*it)) { it = QTreeWidgetItemIterator(transactionsView, QTreeWidgetItemIterator::All); wrapped_around = true; } } } void LedgerDialog::searchPrevious() { QString str = searchEdit->text().trimmed(); if(str.isEmpty()) return; QTreeWidgetItem *i_first = transactionsView->currentItem(); if(i_first && !i_first->isSelected()) i_first = NULL; int i = transactionsView->topLevelItemCount(); QTreeWidgetItemIterator it(transactionsView, QTreeWidgetItemIterator::All); if(i_first) { it = QTreeWidgetItemIterator(i_first, QTreeWidgetItemIterator::All); --it; if(!(*it)) { i_first = NULL; it = QTreeWidgetItemIterator(transactionsView, QTreeWidgetItemIterator::All); it += i - 1; } } else { it += i - 1; } transactionsView->clearSelection(); transactionsView->setCurrentItem(NULL); bool wrapped_around = false; while(*it) { if(((LedgerListViewItem*) *it)->matches(str)) { (*it)->setSelected(true); transactionsView->setCurrentItem(*it, 1); transactionsView->scrollToItem(*it); break; } if(wrapped_around && *it == i_first) break; --it; if(!wrapped_around && i_first && !(*it)) { it = QTreeWidgetItemIterator(transactionsView, QTreeWidgetItemIterator::All); it += i - 1; wrapped_around = true; } } } void LedgerDialog::searchChanged(const QString &str) { searchNextButton->setEnabled(!str.trimmed().isEmpty()); searchPreviousButton->setEnabled(!str.trimmed().isEmpty()); } Eqonomize-1.5.3/src/ledgerdialog.h000066400000000000000000000113631416454732000170620ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016-2017 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifndef LEDGER_DIALOG_H #define LEDGER_DIALOG_H #include #include #include class QPushButton; class QTreeWidget; class QTreeWidgetItem; class QComboBox; class QLabel; class QLineEdit; class QAction; class QMenu; class QFrame; class QDateEdit; class EqonomizeValueEdit; class Eqonomize; class AssetsAccount; class Budget; class LedgerDialog : public QDialog { Q_OBJECT protected: AssetsAccount *account; Eqonomize *mainWin; Budget *budget; bool b_extra, b_ascending; QString stat_total_text; double d_rec_cl, d_rec_op; double d_book_cl, d_book_op; int re1, re2; int min_width_1, min_width_2; QTreeWidget *transactionsView; QPushButton *editButton, *removeButton, *joinButton, *splitUpButton, *reconcileButton, *markReconciledButton; QDateEdit *reconcileStartEdit, *reconcileEndEdit; EqonomizeValueEdit *reconcileOpeningEdit, *reconcileClosingEdit, *reconcileChangeEdit; QLabel *reconcileBOpeningLabel, *reconcileBClosingLabel, *reconcileBChangeLabel, *reconcileROpeningLabel, *reconcileRClosingLabel, *reconcileRChangeLabel; QFrame *reconcileWidget; QPushButton *exportButton, *printButton, *editAccountButton; QComboBox *accountCombo; QLabel *statLabel; QAction *ActionNewDebtInterest, *ActionNewDebtPayment; QAction *ActionMarkReconciled, *ActionEdit, *ActionClone, *ActionSplit, *ActionJoin, *ActionDelete, *ActionOpenFile, *ActionEditTimestamp; QMenu *headerMenu, *listMenu; QLineEdit *searchEdit; QPushButton *searchPreviousButton, *searchNextButton; QAction *ActionSearch; bool exportList(QTextStream &outf, int fileformat, QDate first_date = QDate(), QDate last_date = QDate()); void accountChanged(); void updateReconciliationStats(bool = false, bool = false, bool = false); void updateReconciliationStatLabels(); QKeyEvent *key_event; void keyPressEvent(QKeyEvent*); public: LedgerDialog(AssetsAccount *acc, Budget *budg, Eqonomize *parent, QString title, bool extra_parameters, bool do_reconciliation = false); ~LedgerDialog(); public slots: void saveConfig(); protected slots: void popupHeaderMenu(const QPoint&); void popupListMenu(const QPoint&); void toggleReconciliation(bool); void reconcileTransactions(); void markAsReconciled(); void reconcileStartDateChanged(const QDate&); void reconcileEndDateChanged(const QDate&); void reconcileOpeningChanged(double); void reconcileClosingChanged(double); void reconcileChangeChanged(double); void hideColumn(bool); void remove(); void cloneTransaction(); void edit(); void editTimestamp(); void openAssociatedFile(); void edit(QTreeWidgetItem*, int); void onTransactionSpacePressed(QTreeWidgetItem*); void onTransactionReturnPressed(QTreeWidgetItem*); void transactionActivated(QTreeWidgetItem*, int); void transactionSelectionChanged(); void updateTransactions(bool = false); void updateAccounts(); void newExpense(); void newIncome(); void newTransfer(); void newSplit(); void newDebtPayment(); void newDebtInterest(); void joinTransactions(); void splitUpTransaction(); void saveView(); void printView(); void accountActivated(int); void reject(); void editAccount(); void search(); void searchPrevious(); void searchChanged(const QString&); void ascendingToggled(bool); void onFilterSelected(QString); }; #endif Eqonomize-1.5.3/src/main.cpp000066400000000000000000000201261416454732000157140ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "budget.h" #include "eqonomize.h" QTranslator translator, translator_qt, translator_qtbase; int main(int argc, char **argv) { QApplication app(argc, argv); app.setApplicationName("eqonomize"); app.setApplicationDisplayName("Eqonomize!"); app.setOrganizationName("Eqonomize"); app.setApplicationVersion(VERSION); QString locale = setlocale(LC_MONETARY, NULL); if(locale == QLocale::c().name()) { setlocale(LC_MONETARY, QLocale::system().name().toLocal8Bit()); } else { setlocale(LC_MONETARY, ""); } QSettings settings; settings.beginGroup("GeneralOptions"); QString slang = settings.value("language", QString()).toString(); EqonomizeTranslator eqtr; app.installTranslator(&eqtr); if(!slang.isEmpty()) { if(translator.load(QLatin1String("eqonomize") + QLatin1String("_") + slang, QLatin1String(TRANSLATIONS_DIR))) app.installTranslator(&translator); #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) if(translator_qt.load("qt_" + slang, QLibraryInfo::path(QLibraryInfo::TranslationsPath))) app.installTranslator(&translator_qt); if(translator_qtbase.load("qtbase_" + slang, QLibraryInfo::path(QLibraryInfo::TranslationsPath))) app.installTranslator(&translator_qtbase); #else if(translator_qt.load("qt_" + slang, QLibraryInfo::location(QLibraryInfo::TranslationsPath))) app.installTranslator(&translator_qt); if(translator_qtbase.load("qtbase_" + slang, QLibraryInfo::location(QLibraryInfo::TranslationsPath))) app.installTranslator(&translator_qtbase); #endif } else { if(translator.load(QLocale(), QLatin1String("eqonomize"), QLatin1String("_"), QLatin1String(TRANSLATIONS_DIR))) app.installTranslator(&translator); #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) if(translator_qt.load(QLocale(), QLatin1String("qt"), QLatin1String("_"), QLibraryInfo::path(QLibraryInfo::TranslationsPath))) app.installTranslator(&translator_qt); if(translator_qtbase.load(QLocale(), QLatin1String("qtbase"), QLatin1String("_"), QLibraryInfo::path(QLibraryInfo::TranslationsPath))) app.installTranslator(&translator_qtbase); #else if(translator_qt.load(QLocale(), QLatin1String("qt"), QLatin1String("_"), QLibraryInfo::location(QLibraryInfo::TranslationsPath))) app.installTranslator(&translator_qt); if(translator_qtbase.load(QLocale(), QLatin1String("qtbase"), QLatin1String("_"), QLibraryInfo::location(QLibraryInfo::TranslationsPath))) app.installTranslator(&translator_qtbase); #endif } QCommandLineParser *parser = new QCommandLineParser(); QCommandLineOption eOption(QStringList() << "e" << "expenses", QApplication::tr("Start with expenses list displayed")); parser->addOption(eOption); QCommandLineOption iOption(QStringList() << "i" << "incomes", QApplication::tr("Start with incomes list displayed")); parser->addOption(iOption); QCommandLineOption tOption("transfers", QApplication::tr("Start with transfers list displayed")); parser->addOption(tOption); QCommandLineOption sOption(QStringList() << "s" << "sync", QApplication::tr("Synchronize file")); parser->addOption(sOption); parser->addPositionalArgument("url", QApplication::tr("Document to open"), "[url]"); parser->addHelpOption(); parser->process(app); #if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)) QString lockpath = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation); #else QString lockpath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/" + app.organizationName() + "/" + app.applicationName(); #endif QDir lockdir(lockpath); QLockFile lockFile(lockpath + "/eqonomize.lock"); if(lockdir.mkpath(lockpath)) { if(!lockFile.tryLock(100)){ if(lockFile.error() == QLockFile::LockFailedError) { QTextStream outStream(stdout); outStream << QApplication::tr("%1 is already running.").arg(app.applicationDisplayName()) << '\n'; QLocalSocket socket; socket.connectToServer("eqonomize"); if(socket.waitForConnected()) { QStringList args = parser->positionalArguments(); QString command; if(parser->isSet(eOption)) { command = 'e'; } else if(parser->isSet(iOption)) { command = 'i'; } else if(parser->isSet(tOption)) { command = 't'; } else if(parser->isSet(sOption)) { command = 's'; } else { command = '0'; } if(args.count() > 0) command += args.at(0); socket.write(command.toUtf8()); socket.waitForBytesWritten(3000); socket.disconnectFromServer(); } return 1; } } } QString url = settings.value("lastURL", QString()).toString(); settings.endGroup(); if(parser->isSet(sOption)) { QStringList args = parser->positionalArguments(); QUrl u; if(args.count() > 0) { u = QUrl::fromUserInput(args.at(0)); } else { u = QUrl(url); } Budget *budget = new Budget(); QString errors; QString error = budget->loadFile(u.toLocalFile(), errors); if(!error.isNull()) {qWarning() << error; return EXIT_FAILURE;} if(!errors.isEmpty()) qWarning() << errors; errors = QString(); if(budget->sync(error, errors, true, true)) { if(!errors.isEmpty()) qWarning() << errors; error = budget->saveFile(u.toLocalFile()); if(!error.isNull()) {qWarning() << error; return EXIT_FAILURE;} } else { if(!error.isNull()) {qWarning() << error; return EXIT_FAILURE;} if(!errors.isEmpty()) qWarning() << errors; } return 0; } #ifndef LOAD_EQZICONS_FROM_FILE if(QIcon::themeName().isEmpty() || !QIcon::hasThemeIcon("eqz-account")) { QIcon::setThemeSearchPaths(QStringList(ICON_DIR)); QIcon::setThemeName("EQZ"); } #endif app.setWindowIcon(LOAD_APP_ICON("eqonomize")); Eqonomize *win = new Eqonomize(); win->setCommandLineParser(parser); if(parser->isSet(eOption)) { win->showExpenses(); } else if(parser->isSet(iOption)) { win->showIncomes(); } else if(parser->isSet(tOption)) { win->showTransfers(); } win->show(); app.processEvents(); QStringList args = parser->positionalArguments(); if(args.count() > 0) { win->openURL(QUrl::fromUserInput(args.at(0))); } else if(!url.isEmpty()) { win->openURL(QUrl(url)); } else { if(!win->crashRecovery(QUrl())) { win->createDefaultBudget(); } } #ifdef RESOURCES_COMPILED settings.beginGroup("GeneralOptions"); if(!settings.value("lastVersionCheck").toDate().isValid() || settings.value("lastVersionCheck").toDate().addDays(10) <= QDate::currentDate()) win->checkAvailableVersion(); #endif args.clear(); return app.exec(); } Eqonomize-1.5.3/src/overtimechart.cpp000066400000000000000000006136001416454732000176510ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016-2020 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include "overtimechart.h" #ifdef QT_CHARTS_LIB #include #include #include #include #include #include #include #include #include #include #include #else #include #include #include #include #include #endif #include #include #include #include #include #include #include #include #include #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "account.h" #include "budget.h" #include "eqonomizemonthselector.h" #include "recurrence.h" #include "transaction.h" #include #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) # define DATE_TO_MSECS(d) QDateTime(d.startOfDay()).toMSecsSinceEpoch() #else # define DATE_TO_MSECS(d) QDateTime(d).toMSecsSinceEpoch() #endif struct chart_month_info { double value; double count; QDate date; }; extern QString last_picture_directory; void calculate_minmax_lines(double &maxvalue, double &minvalue, int &y_lines, int &y_minor, bool minmaxequal = false, bool use_deciminor = true) { if(minvalue > -0.01) minvalue = 0.0; if(-minvalue > maxvalue) maxvalue = -minvalue; int maxvalue_exp = floor(log10(maxvalue)); int maxvalue_digit; double orig_maxvalue = maxvalue; if(maxvalue_exp < 1.0) { maxvalue_digit = ceil(maxvalue); maxvalue = maxvalue_digit; y_lines = maxvalue_digit; maxvalue_exp = 0.0; } else { maxvalue /= pow(10, maxvalue_exp); if(maxvalue <= 1.0) { maxvalue = 10.0; maxvalue_exp -= 1.0; } maxvalue_digit = ceil(maxvalue); y_lines = maxvalue_digit; maxvalue = maxvalue_digit * pow(10, maxvalue_exp); if(((!minmaxequal && y_lines <= 5) || y_lines <= 3) && orig_maxvalue <= (maxvalue / (y_lines * 2)) * ((y_lines * 2) - 1)) { maxvalue = (maxvalue / (y_lines * 2)) * ((y_lines * 2) - 1); y_lines = (y_lines * 2) - 1; } if(y_lines <= 2) y_lines = 4; } if(minvalue < 0.0) { if(minmaxequal) { if(y_lines <= 6) { y_lines *= 2; } else { maxvalue = ceil(maxvalue_digit / 2.0) * pow(10, maxvalue_exp) * 2; y_lines += y_lines % 2; } minvalue = -maxvalue; } else { int neg_y_lines = -floor(minvalue / (maxvalue / y_lines)); minvalue = -neg_y_lines * (maxvalue / y_lines); y_lines += neg_y_lines; } } if(maxvalue == 0.0 && minvalue == 0.0) { maxvalue = 1.0; minvalue = -1.0; y_lines = 2; } double tickdiff = (maxvalue - minvalue) / y_lines; y_minor = round(tickdiff/pow(10, floor(log10(tickdiff)))) - 1; if(y_minor == 0 && (use_deciminor || maxvalue > 10.0)) { if(y_lines <= 3) y_minor = 9; else if(y_lines <= 6) y_minor = 4; else if(y_lines <= 12) y_minor = 1; } } OverTimeChart::OverTimeChart(Budget *budg, QWidget *parent, bool extra_parameters) : QWidget(parent), budget(budg), b_extra(extra_parameters) { QVBoxLayout *layout = new QVBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); QHBoxLayout *buttons = new QHBoxLayout(); #ifdef QT_CHARTS_LIB buttons->addWidget(new QLabel(tr("Chart type:"), this)); typeCombo = new QComboBox(this); typeCombo->addItem(tr("Line Chart")); typeCombo->addItem(tr("Vertical Bar Chart")); typeCombo->addItem(tr("Horizontal Bar Chart")); typeCombo->addItem(tr("Stacked Bar Chart")); buttons->addWidget(typeCombo); buttons->addWidget(new QLabel(tr("Theme:"), this)); themeCombo = new QComboBox(this); themeCombo->addItem(tr("Default"), -1); themeCombo->addItem("Light", QChart::ChartThemeLight); themeCombo->addItem("Blue Cerulean", QChart::ChartThemeBlueCerulean); themeCombo->addItem("Dark", QChart::ChartThemeDark); themeCombo->addItem("Brown Sand", QChart::ChartThemeBrownSand); themeCombo->addItem("Blue NCS", QChart::ChartThemeBlueNcs); themeCombo->addItem("High Contrast", QChart::ChartThemeHighContrast); themeCombo->addItem("Blue Icy", QChart::ChartThemeBlueIcy); themeCombo->addItem("Qt", QChart::ChartThemeQt); buttons->addWidget(themeCombo); #endif buttons->addStretch(); saveButton = new QPushButton(tr("Save As…"), this); saveButton->setAutoDefault(false); buttons->addWidget(saveButton); printButton = new QPushButton(tr("Print…"), this); printButton->setAutoDefault(false); buttons->addWidget(printButton); layout->addLayout(buttons); #ifdef QT_CHARTS_LIB chart = new QChart(); view = new QChartView(chart, this); view->setRubberBand(QChartView::RectangleRubberBand); axisX = NULL; axisY = NULL; point_label = NULL; #else scene = NULL; view = new QGraphicsView(this); #endif view->setRenderHint(QPainter::Antialiasing, true); layout->addWidget(view); QSettings settings; settings.beginGroup("OverTimeChart"); QWidget *settingsWidget = new QWidget(this); QGridLayout *settingsLayout = new QGridLayout(settingsWidget); QLabel *sourceLabel = new QLabel(tr("Source:"), settingsWidget); settingsLayout->addWidget(sourceLabel, 2, 0, Qt::AlignLeft | Qt::AlignTop); QGridLayout *choicesLayout = new QGridLayout(); settingsLayout->addLayout(choicesLayout, 2, 1); sourceCombo = new QComboBox(settingsWidget); sourceCombo->setEditable(false); sourceCombo->addItem(tr("Incomes and Expenses")); sourceCombo->addItem(tr("Profits")); sourceCombo->addItem(tr("Expenses")); sourceCombo->addItem(tr("Incomes")); sourceCombo->addItem(tr("Assets and Liabilities")); sourceCombo->addItem(tr("Tags")); choicesLayout->addWidget(sourceCombo, 0, 0); sourceLabel->setMinimumHeight(sourceCombo->sizeHint().height()); categoryCombo = new QComboBox(settingsWidget); categoryCombo->setEditable(false); categoryCombo->addItem(tr("All Categories Combined")); categoryCombo->setEnabled(false); choicesLayout->addWidget(categoryCombo, 0, 1); descriptionCombo = new QComboBox(settingsWidget); descriptionCombo->setEditable(false); descriptionCombo->addItem(tr("All Descriptions Combined", "Referring to the transaction description property (transaction title/generic article name)")); descriptionCombo->setEnabled(false); choicesLayout->addWidget(descriptionCombo, 0, 2); payeeCombo = NULL; if(b_extra) { payeeCombo = new QComboBox(settingsWidget); payeeCombo->setEditable(false); payeeCombo->addItem(tr("All Payees/Payers Combined")); payeeCombo->setEnabled(false); choicesLayout->addWidget(payeeCombo, 1, 0); } accountCombo = new QComboBox(settingsWidget); accountCombo->setEditable(false); accountCombo->addItem(tr("All Accounts Combined"), QVariant::fromValue(NULL)); accountCombo->addItem(tr("All Accounts Split"), QVariant::fromValue(NULL)); for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { AssetsAccount *account = *it; if(account != budget->balancingAccount) { accountCombo->addItem(account->name(), QVariant::fromValue((void*) account)); } } choicesLayout->addWidget(accountCombo, b_extra ? 1 : 0, b_extra ? 1 : 3); current_account = NULL; current_source = 0; settingsLayout->addWidget(new QLabel(tr("Start date:"), settingsWidget), 0, 0); QHBoxLayout *monthLayout = new QHBoxLayout(); settingsLayout->addLayout(monthLayout, 0, 1); startDateEdit = new EqonomizeMonthSelector(settingsWidget); monthLayout->addWidget(startDateEdit); monthLayout->setStretchFactor(startDateEdit, 1); monthLayout->addWidget(new QLabel(tr("End date:"), settingsWidget)); endDateEdit = new EqonomizeMonthSelector(settingsWidget); monthLayout->addWidget(endDateEdit); monthLayout->setStretchFactor(endDateEdit, 1); monthLayout->addStretch(1); settingsLayout->addWidget(new QLabel(tr("Value:"), settingsWidget), 1, 0); QHBoxLayout *enabledLayout = new QHBoxLayout(); settingsLayout->addLayout(enabledLayout, 1, 1); valueGroup = new QButtonGroup(this); yearlyButton = new QRadioButton(tr("Annual total"), settingsWidget); yearlyButton->setChecked(settings.value("yearlyEnabled", false).toBool()); valueGroup->addButton(yearlyButton, 4); enabledLayout->addWidget(yearlyButton); valueButton = new QRadioButton(tr("Monthly total"), settingsWidget); valueButton->setChecked(settings.value("valueEnabled", true).toBool()); valueGroup->addButton(valueButton, 0); enabledLayout->addWidget(valueButton); dailyButton = new QRadioButton(tr("Daily average"), settingsWidget); dailyButton->setChecked(settings.value("dailyAverageEnabled", false).toBool()); valueGroup->addButton(dailyButton, 1); enabledLayout->addWidget(dailyButton); countButton = new QRadioButton(tr("Quantity"), settingsWidget); countButton->setChecked(settings.value("transactionCountEnabled", false).toBool()); valueGroup->addButton(countButton, 2); enabledLayout->addWidget(countButton); perButton = new QRadioButton(tr("Average value"), settingsWidget); perButton->setChecked(settings.value("valuePerTransactionEnabled", false).toBool()); valueGroup->addButton(perButton, 3); enabledLayout->addWidget(perButton); enabledLayout->addStretch(1); startDateEdit->setMonthEnabled(!yearlyButton->isChecked()); settings.endGroup(); resetOptions(); layout->addWidget(settingsWidget); #ifdef QT_CHARTS_LIB connect(themeCombo, SIGNAL(activated(int)), this, SLOT(themeChanged(int))); connect(typeCombo, SIGNAL(activated(int)), this, SLOT(typeChanged(int))); #endif connect(startDateEdit, SIGNAL(monthChanged(const QDate&)), this, SLOT(startMonthChanged(const QDate&))); connect(startDateEdit, SIGNAL(yearChanged(const QDate&)), this, SLOT(startYearChanged(const QDate&))); connect(endDateEdit, SIGNAL(monthChanged(const QDate&)), this, SLOT(endMonthChanged(const QDate&))); connect(endDateEdit, SIGNAL(yearChanged(const QDate&)), this, SLOT(endYearChanged(const QDate&))); connect(yearlyButton, SIGNAL(toggled(bool)), this, SLOT(valueTypeToggled(bool))); connect(valueButton, SIGNAL(toggled(bool)), this, SLOT(valueTypeToggled(bool))); connect(dailyButton, SIGNAL(toggled(bool)), this, SLOT(valueTypeToggled(bool))); connect(countButton, SIGNAL(toggled(bool)), this, SLOT(valueTypeToggled(bool))); connect(perButton, SIGNAL(toggled(bool)), this, SLOT(valueTypeToggled(bool))); connect(sourceCombo, SIGNAL(activated(int)), this, SLOT(sourceChanged(int))); connect(accountCombo, SIGNAL(activated(int)), this, SLOT(accountChanged(int))); connect(categoryCombo, SIGNAL(activated(int)), this, SLOT(categoryChanged(int))); connect(descriptionCombo, SIGNAL(activated(int)), this, SLOT(descriptionChanged(int))); if(b_extra) connect(payeeCombo, SIGNAL(activated(int)), this, SLOT(payeeChanged(int))); connect(saveButton, SIGNAL(clicked()), this, SLOT(save())); connect(printButton, SIGNAL(clicked()), this, SLOT(print())); } OverTimeChart::~OverTimeChart() {} void OverTimeChart::resetOptions() { #ifdef QT_CHARTS_LIB QSettings settings; settings.beginGroup("OverTimeChart"); int theme = settings.value("theme", -1).toInt(); int index = themeCombo->findData(QVariant::fromValue(theme)); if(index < 0) index = 0; themeCombo->setCurrentIndex(index); typeCombo->setCurrentIndex(0); chart->setTheme(theme >= 0 ? (QChart::ChartTheme) theme : QChart::ChartThemeBlueNcs); settings.endGroup(); #endif accountCombo->blockSignals(true); accountCombo->setCurrentIndex(0); accountCombo->blockSignals(false); sourceCombo->blockSignals(true); sourceCombo->setCurrentIndex(0); sourceCombo->blockSignals(false); sourceChanged(0); resetDate(); } void OverTimeChart::resetDate() { start_date = QDate(); for(TransactionList::const_iterator it = budget->transactions.constBegin(); it != budget->transactions.constEnd(); ++it) { Transaction *trans = *it; if(trans->fromAccount()->type() != ACCOUNT_TYPE_ASSETS || trans->toAccount()->type() != ACCOUNT_TYPE_ASSETS) { start_date = trans->date(); if(!budget->isFirstBudgetDay(start_date)) { budget->addBudgetMonthsSetFirst(start_date, 1); } break; } } QDate curmonth = budget->firstBudgetDay(QDate::currentDate()); if(start_date.isNull() || start_date > curmonth) start_date = curmonth; if(start_date == curmonth) { budget->addBudgetMonthsSetFirst(start_date, -1); } start_date = budget->budgetDateToMonth(start_date); end_date = QDate::currentDate().addDays(-1); if(!budget->isLastBudgetDay(end_date)) { end_date = budget->lastBudgetDay(end_date); budget->addBudgetMonthsSetLast(end_date, -1); } if(end_date < start_date || budget->isSameBudgetMonth(start_date, end_date)) { end_date = budget->lastBudgetDay(QDate::currentDate()); } end_date = budget->firstBudgetDay(end_date); start_date = budget->budgetDateToMonth(start_date); end_date = budget->budgetDateToMonth(end_date); endDateEdit->setMonthEnabled(!yearlyButton->isEnabled() || !yearlyButton->isChecked() || budget->budgetYear(end_date) == budget->budgetYear(QDate::currentDate())); startDateEdit->blockSignals(true); endDateEdit->blockSignals(true); startDateEdit->setDate(start_date); endDateEdit->setDate(end_date); startDateEdit->blockSignals(false); endDateEdit->blockSignals(false); } void OverTimeChart::valueTypeToggled(bool b) { if(!b) return; startDateEdit->setMonthEnabled(!yearlyButton->isEnabled() || !yearlyButton->isChecked()); endDateEdit->setMonthEnabled(!yearlyButton->isEnabled() || !yearlyButton->isChecked() || budget->budgetYear(end_date) == budget->budgetYear(QDate::currentDate())); #ifdef QT_CHARTS_LIB if(typeCombo->currentIndex() != 0) { if(valueGroup->checkedId() == 4) {resetDate(); updateDisplay();} else endMonthChanged(end_date); } else { updateDisplay(); } #else updateDisplay(); #endif } void OverTimeChart::accountChanged(int index) { int c_index = categoryCombo->currentIndex(); int d_index = descriptionCombo->currentIndex(); bool b_subs = (current_account && !current_account->subCategories.isEmpty()); int p_index = 0; if(b_extra) p_index = payeeCombo->currentIndex(); if(index == 0) { if(current_source > 50) current_source -= 100; } else if(index == 1) { if(current_source == 0 || (c_index == 0 && sourceCombo->currentIndex() == 5)) { sourceCombo->blockSignals(true); sourceCombo->setCurrentIndex(1); sourceCombo->blockSignals(false); sourceChanged(1); return; } if(d_index == 1 || (b_subs && d_index == 2)) { descriptionCombo->blockSignals(true); descriptionCombo->setCurrentIndex(0); descriptionCombo->blockSignals(false); } if(p_index == 1) { payeeCombo->blockSignals(true); payeeCombo->setCurrentIndex(0); payeeCombo->blockSignals(false); } if(c_index == 1 && sourceCombo->currentIndex() != 5) { categoryCombo->blockSignals(true); categoryCombo->setCurrentIndex(0); categoryCombo->blockSignals(false); } if(current_source == 3) current_source = 1; else if(current_source == 4) current_source = 2; else if(current_source == 33 || current_source == 39) current_source = 27; else if(current_source == 11 || current_source == 7 || current_source == 21) current_source = 5; else if(current_source == 12 || current_source == 8 || current_source == 22) current_source = 6; else if(current_source == 35) current_source = 31; else if(current_source == 13) current_source = 9; else if(current_source == 14) current_source = 10; else if(current_source == 23 || current_source == 17) current_source = 15; else if(current_source == 24 || current_source == 18) current_source = 16; if(current_source <= 50) current_source += 100; } else { if(current_source > 50) current_source -= 100; } updateDisplay(); } void OverTimeChart::payeeChanged(int index) { current_payee = ""; bool b_tag = (!current_account && !current_tag.isEmpty()); bool b_income = b_tag || (current_account && current_account->type() == ACCOUNT_TYPE_INCOMES); bool b_subs = (current_account && !current_account->subCategories.isEmpty()); int d_index = descriptionCombo->currentIndex(); if(index == 0) { if(d_index == 1) current_source = b_income ? 7 : 8; else if(b_subs && d_index == 2) current_source = b_income ? 21 : 22; else if(d_index == 0) current_source = b_income ? 5 : 6; else current_source = b_income ? 9 : 10; if(b_tag) current_source += 22; if(accountCombo->currentIndex() == 1) current_source += 100; } else if(index == 1) { if(d_index == 1 || (b_subs && d_index == 2)) { descriptionCombo->blockSignals(true); descriptionCombo->setCurrentIndex(0); descriptionCombo->blockSignals(false); d_index = 0; } if(accountCombo->currentIndex() == 1) { accountCombo->blockSignals(true); accountCombo->setCurrentIndex(0); accountCombo->blockSignals(false); } if(d_index == 0) current_source = b_income ? 11 : 12; else current_source = b_income ? 13 : 14; if(b_tag) current_source += 22; } else { if(!has_empty_payee || index < payeeCombo->count() - 1) current_payee = payeeCombo->itemText(index); if(b_subs && d_index == 1) current_source = b_income ? 23 : 24; else if(d_index == 1 || (b_subs && d_index == 2)) current_source = b_income ? 17 : 18; else if(d_index == 0) current_source = b_income ? 15 : 16; else current_source = b_income ? 19 : 20; if(b_tag) current_source += 22; if(accountCombo->currentIndex() == 1) current_source += 100; } updateDisplay(); } void OverTimeChart::descriptionChanged(int index) { current_description = ""; bool b_tag = (!current_account && !current_tag.isEmpty()); bool b_income = b_tag || (current_account && current_account->type() == ACCOUNT_TYPE_INCOMES); bool b_subs = (current_account && !current_account->subCategories.isEmpty()); int p_index = 0; if(b_extra) p_index = payeeCombo->currentIndex(); if(index == 0) { if(p_index == 1) current_source = b_income ? 11 : 12; else if(p_index == 0) current_source = b_income ? 5 : 6; else current_source = b_income ? 15 : 16; if(b_tag) current_source += 22; if(accountCombo->currentIndex() == 1) current_source += 100; } else if(b_subs && index == 1) { if(p_index == 1) { payeeCombo->blockSignals(true); payeeCombo->setCurrentIndex(0); payeeCombo->blockSignals(false); p_index = 0; } if(accountCombo->currentIndex() == 1) { accountCombo->blockSignals(true); accountCombo->setCurrentIndex(0); accountCombo->blockSignals(false); } if(p_index == 0) current_source = b_income ? 21 : 22; else current_source = b_income ? 23 : 24; if(b_tag) current_source += 22; } else if(index == 1 || (b_subs && index == 2)) { if(p_index == 1) { payeeCombo->blockSignals(true); payeeCombo->setCurrentIndex(0); payeeCombo->blockSignals(false); p_index = 0; } if(accountCombo->currentIndex() == 1) { accountCombo->blockSignals(true); accountCombo->setCurrentIndex(0); accountCombo->blockSignals(false); } if(p_index == 0) current_source = b_income ? 7 : 8; else current_source = b_income ? 17 : 18; if(b_tag) current_source += 22; } else { if(!has_empty_description || index < descriptionCombo->count() - 1) current_description = descriptionCombo->itemText(index); if(p_index == 1) current_source = b_income ? 13 : 14; else if(p_index == 0) current_source = b_income ? 9 : 10; else current_source = b_income ? 19 : 20; if(b_tag) current_source += 22; if(accountCombo->currentIndex() == 1) current_source += 100; } updateDisplay(); } void OverTimeChart::categoryChanged(int index) { bool b_income = (sourceCombo->currentIndex() == 3); bool b_tags = (sourceCombo->currentIndex() == 5); descriptionCombo->blockSignals(true); int d_index = descriptionCombo->currentIndex(); descriptionCombo->clear(); descriptionCombo->addItem(tr("All Descriptions Combined", "Referring to the transaction description property (transaction title/generic article name)")); int p_index = 0; current_description = ""; current_payee = ""; current_account = NULL; current_tag = ""; if(b_tags) index++; if(b_extra) { p_index = payeeCombo->currentIndex(); payeeCombo->blockSignals(true); payeeCombo->clear(); if(index <= 1) { if(sourceCombo->currentIndex() == 3) payeeCombo->addItem(tr("All Payers Combined")); else if(sourceCombo->currentIndex() == 2) payeeCombo->addItem(tr("All Payees Combined")); else payeeCombo->addItem(tr("All Payees/Payers Combined")); } } if(index == 0) { if(b_income) { current_source = 1; } else { current_source = 2; } descriptionCombo->setEnabled(false); if(b_extra) { payeeCombo->setEnabled(false); payeeCombo->setCurrentIndex(0); } } else if(index == 1) { if(accountCombo->currentIndex() == 1) { accountCombo->blockSignals(true); accountCombo->setCurrentIndex(0); accountCombo->blockSignals(false); } if(b_tags) { current_source = -3; } else if(b_income) { current_source = (index == 2 ? 25 : 3); } else { current_source = (index == 2 ? 26 : 4); } descriptionCombo->setEnabled(false); if(b_extra) { payeeCombo->setEnabled(false); payeeCombo->setCurrentIndex(0); } } else { if(b_tags) { int i = categoryCombo->currentIndex() - 1; if(i < (int) budget->tags.count()) current_tag = budget->tags.at(i); } else if(!b_income) { int i = categoryCombo->currentIndex() - 2; if(i < (int) budget->expensesAccounts.count()) current_account = budget->expensesAccounts.at(i); } else { int i = categoryCombo->currentIndex() - 2; if(i < (int) budget->incomesAccounts.count()) current_account = budget->incomesAccounts.at(i); } bool b_subs = current_account && !current_account->subCategories.isEmpty(); if(b_subs) { descriptionCombo->addItem(tr("All Subcategories Split")); descriptionCombo->setItemText(0, tr("All Subcategories and Descriptions Combined", "Referring to the transaction description property (transaction title/generic article name)")); } descriptionCombo->addItem(tr("All Descriptions Split", "Referring to the transaction description property (transaction title/generic article name)")); if(!current_account && current_tag.isEmpty()) return categoryChanged(0); switch(current_source) { case 29: {} case 7: {} case 8: {} case 39: {} case 17: {} case 18: {d_index = b_subs ? 2 : 1; p_index = 0; break;} case 33: {} case 11: {} case 12: {d_index = 0; p_index = 1; break;} case 21: {} case 22: {} case 23: {} case 24: {d_index = b_subs ? 1 : 0; p_index = 0; break;} default: {d_index = 0; p_index = 0; break;} } has_empty_description = false; has_empty_payee = false; QMap descriptions, payees; bool had_income = false, had_expense = false; for(TransactionList::const_iterator it = budget->transactions.constEnd(); it != budget->transactions.constBegin();) { --it; Transaction *trans = *it; if((b_tags && trans->hasTag(current_tag, true)) || (!b_tags && (trans->fromAccount() == current_account || trans->toAccount() == current_account || trans->fromAccount()->topAccount() == current_account || trans->toAccount()->topAccount() == current_account))) { if(trans->description().isEmpty()) has_empty_description = true; else if(!descriptions.contains(trans->description().toLower())) descriptions[trans->description().toLower()] = trans->description(); if(b_extra) { if(trans->type() == TRANSACTION_TYPE_EXPENSE) { had_expense = true; if(((Expense*) trans)->payee().isEmpty()) has_empty_payee = true; else if(!payees.contains(((Expense*) trans)->payee().toLower())) payees[((Expense*) trans)->payee().toLower()] = ((Expense*) trans)->payee(); } else if(trans->type() == TRANSACTION_TYPE_INCOME) { had_income = true; if(((Income*) trans)->payer().isEmpty()) has_empty_payee = true; else if(!payees.contains(((Income*) trans)->payer().toLower())) payees[((Income*) trans)->payer().toLower()] = ((Income*) trans)->payer(); } } } } QMap::iterator it_e = descriptions.end(); for(QMap::iterator it = descriptions.begin(); it != it_e; ++it) { descriptionCombo->addItem(it.value()); } if(has_empty_description) descriptionCombo->addItem(tr("No description", "Referring to the transaction description property (transaction title/generic article name)")); descriptionCombo->setEnabled(true); if(b_extra) { if((!b_tags && b_income) || (b_tags && !had_expense && had_income)) {payeeCombo->addItem(tr("All Payers Combined")); payeeCombo->addItem(tr("All Payers Split"));} else if(!b_tags || (b_tags && had_expense && !had_income)) {payeeCombo->addItem(tr("All Payees Combined")); payeeCombo->addItem(tr("All Payees Split"));} else {payeeCombo->addItem(tr("All Payees/Payers Combined")); payeeCombo->addItem(tr("All Payees/Payers Split"));} QMap::iterator it2_e = payees.end(); for(QMap::iterator it2 = payees.begin(); it2 != it2_e; ++it2) { payeeCombo->addItem(it2.value()); } if(has_empty_payee) { if((!b_tags && b_income) || (b_tags && !had_expense && had_income)) payeeCombo->addItem(tr("No payer")); else if(!b_tags || (b_tags && had_expense && !had_income)) payeeCombo->addItem(tr("No payee")); else payeeCombo->addItem(tr("No payee/payer")); } payeeCombo->setEnabled(true); } descriptionCombo->setCurrentIndex(d_index); if(b_extra) payeeCombo->setCurrentIndex(p_index); if(b_subs && d_index == 1) current_source = b_income ? 21 : 22; else if(d_index == 1 || (b_subs && d_index == 2)) current_source = b_income ? 7 : 8; else if(p_index == 1) current_source = b_income ? 11 : 12; else current_source = b_income ? 5 : 6; if(b_tags) current_source += 21; } descriptionCombo->blockSignals(false); if(b_extra) payeeCombo->blockSignals(false); if(accountCombo->currentIndex() == 1) current_source += 100; updateDisplay(); } void OverTimeChart::sourceChanged(int index) { categoryCombo->blockSignals(true); descriptionCombo->blockSignals(true); if(b_extra) payeeCombo->blockSignals(true); int c_index = 1; if(accountCombo->currentIndex() == 1 || index == 5 || (categoryCombo->count() > 1 && categoryCombo->currentIndex() == 0)) c_index = 0; categoryCombo->clear(); descriptionCombo->clear(); descriptionCombo->setEnabled(false); descriptionCombo->addItem(tr("All Descriptions Combined", "Referring to the transaction description property (transaction title/generic article name)")); if(b_extra) { payeeCombo->clear(); payeeCombo->setEnabled(false); if(index == 3) payeeCombo->addItem(tr("All Payers Combined")); else if(index == 2) payeeCombo->addItem(tr("All Payees Combined")); else payeeCombo->addItem(tr("All Payees/Payers Combined")); } current_description = ""; current_payee = ""; current_account = NULL; if(index != 5) categoryCombo->addItem(tr("All Categories Combined")); if(index == 3) { categoryCombo->addItem(tr("All Categories Split")); //categoryCombo->addItem(tr("All Categories and Subcategories Split")); categoryCombo->setCurrentIndex(c_index); for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) { Account *account = *it; categoryCombo->addItem(account->nameWithParent()); } categoryCombo->setEnabled(true); current_source = 3; if(accountCombo->currentIndex() == 1 && current_source <= 50) current_source += 100; categoryChanged(c_index); } else if(index == 2) { categoryCombo->addItem(tr("All Categories Split")); //categoryCombo->addItem(tr("All Categories and Subcategories Split")); categoryCombo->setCurrentIndex(c_index); for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) { Account *account = *it; categoryCombo->addItem(account->nameWithParent()); } categoryCombo->setEnabled(true); current_source = 4; if(accountCombo->currentIndex() == 1 && current_source <= 50) current_source += 100; categoryChanged(c_index); } else if(index == 5) { categoryCombo->addItem(tr("All Tags Split")); if(accountCombo->currentIndex() == 1) { accountCombo->blockSignals(true); accountCombo->setCurrentIndex(0); accountCombo->blockSignals(false); } categoryCombo->setCurrentIndex(c_index); for(int i = 0; i < budget->tags.count(); i++) { categoryCombo->addItem(budget->tags[i]); } categoryCombo->setEnabled(true); current_source = -3; categoryChanged(c_index); } else if(index == 1) { categoryCombo->setEnabled(false); current_source = -1; if(accountCombo->currentIndex() == 1 && current_source <= 50) current_source += 100; if(countButton->isChecked() || perButton->isChecked()) { valueButton->blockSignals(true); countButton->blockSignals(true); perButton->blockSignals(true); valueButton->setChecked(true); countButton->setChecked(false); perButton->setChecked(false); valueButton->blockSignals(false); countButton->blockSignals(false); perButton->blockSignals(false); } updateDisplay(); } else if(index == 4) { categoryCombo->setEnabled(false); current_source = -2; if(accountCombo->currentIndex() == 1 && current_source <= 50) current_source += 100; updateDisplay(); } else { if(accountCombo->currentIndex() == 1) { accountCombo->blockSignals(true); accountCombo->setCurrentIndex(0); accountCombo->blockSignals(false); } categoryCombo->setEnabled(false); current_source = 0; if(accountCombo->currentIndex() == 1 && current_source <= 50) current_source += 100; updateDisplay(); } countButton->setEnabled(index != 1 && index != 4); perButton->setEnabled(index != 1 && index != 4); dailyButton->setEnabled(index != 4); #ifdef QT_CHARTS_LIB yearlyButton->setEnabled(index != 4 || typeCombo->currentIndex() > 0); valueButton->setEnabled(index != 4 || typeCombo->currentIndex() > 0); #else yearlyButton->setEnabled(index != 4); valueButton->setEnabled(index != 4); #endif startDateEdit->setMonthEnabled(!yearlyButton->isEnabled() || !yearlyButton->isChecked()); endDateEdit->setMonthEnabled(!yearlyButton->isEnabled() || !yearlyButton->isChecked() || budget->budgetYear(end_date) == budget->budgetYear(QDate::currentDate())); categoryCombo->blockSignals(false); descriptionCombo->blockSignals(false); if(b_extra) payeeCombo->blockSignals(false); } void OverTimeChart::startYearChanged(const QDate &date) { bool error = false; if(!date.isValid()) { QMessageBox::critical(this, tr("Error"), tr("Invalid date.")); error = true; } if(!error && date > end_date) { end_date = date; endDateEdit->blockSignals(true); endDateEdit->setDate(end_date); endDateEdit->blockSignals(false); } #ifdef QT_CHARTS_LIB if(!error && typeCombo->currentIndex() != 0 && valueGroup->checkedId() != 4 && budget->calendarMonthsBetweenDates(date, end_date, false) > 11) { end_date = date.addMonths(11); endDateEdit->blockSignals(true); endDateEdit->setDate(end_date); endDateEdit->blockSignals(false); } #endif if(error) { startDateEdit->focusYear(); startDateEdit->blockSignals(true); startDateEdit->setDate(start_date); startDateEdit->blockSignals(false); return; } start_date = date; updateDisplay(); } void OverTimeChart::startMonthChanged(const QDate &date) { bool error = false; if(!date.isValid()) { QMessageBox::critical(this, tr("Error"), tr("Invalid date.")); error = true; } if(!error && date > end_date) { end_date = date; endDateEdit->blockSignals(true); endDateEdit->setDate(end_date); endDateEdit->blockSignals(false); } #ifdef QT_CHARTS_LIB if(!error && typeCombo->currentIndex() != 0 && valueGroup->checkedId() != 4 && budget->calendarMonthsBetweenDates(date, end_date, false) > 11) { end_date = date.addMonths(11); endDateEdit->blockSignals(true); endDateEdit->setDate(end_date); endDateEdit->blockSignals(false); } #endif if(error) { startDateEdit->focusMonth(); startDateEdit->blockSignals(true); startDateEdit->setDate(start_date); startDateEdit->blockSignals(false); return; } start_date = date; updateDisplay(); } void OverTimeChart::endYearChanged(const QDate &date) { bool error = false; if(!date.isValid()) { QMessageBox::critical(this, tr("Error"), tr("Invalid date.")); error = true; } if(!error && date < start_date) { start_date = date; startDateEdit->blockSignals(true); startDateEdit->setDate(start_date); startDateEdit->blockSignals(false); } #ifdef QT_CHARTS_LIB if(!error && typeCombo->currentIndex() != 0 && valueGroup->checkedId() != 4 && budget->calendarMonthsBetweenDates(start_date, date, false) > 11) { start_date = date.addMonths(-11); startDateEdit->blockSignals(true); startDateEdit->setDate(start_date); startDateEdit->blockSignals(false); } #endif if(error) { endDateEdit->focusYear(); endDateEdit->blockSignals(true); endDateEdit->setDate(end_date); endDateEdit->blockSignals(false); return; } end_date = date; if(yearlyButton->isChecked() && budget->budgetYear(end_date) != budget->budgetYear(QDate::currentDate())) { endDateEdit->blockSignals(true); end_date = end_date.addMonths(12 - end_date.month()); endDateEdit->setDate(end_date); endDateEdit->blockSignals(false); } endDateEdit->setMonthEnabled(!yearlyButton->isEnabled() || !yearlyButton->isChecked() || budget->budgetYear(end_date) == budget->budgetYear(QDate::currentDate())); updateDisplay(); } void OverTimeChart::endMonthChanged(const QDate &date) { bool error = false; if(!date.isValid()) { QMessageBox::critical(this, tr("Error"), tr("Invalid date.")); error = true; } if(!error && date < start_date) { start_date = date; startDateEdit->blockSignals(true); startDateEdit->setDate(start_date); startDateEdit->blockSignals(false); } #ifdef QT_CHARTS_LIB if(!error && valueGroup->checkedId() != 4 && typeCombo->currentIndex() != 0 && budget->calendarMonthsBetweenDates(start_date, date, false) > 11) { start_date = date.addMonths(-11); startDateEdit->blockSignals(true); startDateEdit->setDate(start_date); startDateEdit->blockSignals(false); } #endif if(error) { endDateEdit->focusMonth(); endDateEdit->blockSignals(true); endDateEdit->setDate(end_date); endDateEdit->blockSignals(false); return; } end_date = date; updateDisplay(); } void OverTimeChart::saveConfig() { QSettings settings; settings.beginGroup("OverTimeChart"); settings.setValue("size", ((QDialog*) parent())->size()); settings.setValue("yearlyEnabled", yearlyButton->isChecked()); settings.setValue("valueEnabled", valueButton->isChecked()); settings.setValue("dailyAverageEnabled", dailyButton->isChecked()); settings.setValue("transactionCountEnabled", countButton->isChecked()); settings.setValue("valuePerTransactionEnabled", perButton->isChecked()); settings.endGroup(); } void OverTimeChart::onFilterSelected(QString filter) { QMimeDatabase db; QFileDialog *fileDialog = qobject_cast(sender()); if(filter == db.mimeTypeForName("image/gif").filterString()) { fileDialog->setDefaultSuffix(db.mimeTypeForName("image/gif").preferredSuffix()); } else if(filter == db.mimeTypeForName("image/jpeg").filterString()) { fileDialog->setDefaultSuffix(db.mimeTypeForName("image/jpeg").preferredSuffix()); } else if(filter == db.mimeTypeForName("image/tiff").filterString()) { fileDialog->setDefaultSuffix(db.mimeTypeForName("image/tiff").preferredSuffix()); } else if(filter == db.mimeTypeForName("image/x-bmp").filterString()) { fileDialog->setDefaultSuffix(db.mimeTypeForName("image/x-bmp").preferredSuffix()); } else if(filter == db.mimeTypeForName("image/x-eps").filterString()) { fileDialog->setDefaultSuffix(db.mimeTypeForName("image/x-eps").preferredSuffix()); } else { fileDialog->setDefaultSuffix(db.mimeTypeForName("image/png").preferredSuffix()); } } void OverTimeChart::save() { #ifdef QT_CHARTS_LIB QGraphicsScene *scene = chart->scene(); #endif if(!scene) return; QMimeDatabase db; QMimeType image_mime = db.mimeTypeForName("image/*"); QMimeType png_mime = db.mimeTypeForName("image/png"); QMimeType gif_mime = db.mimeTypeForName("image/gif"); QMimeType jpeg_mime = db.mimeTypeForName("image/jpeg"); QMimeType tiff_mime = db.mimeTypeForName("image/tiff"); QMimeType bmp_mime = db.mimeTypeForName("image/x-bmp"); QMimeType eps_mime = db.mimeTypeForName("image/x-eps"); QString png_filter = png_mime.filterString(); QString gif_filter = gif_mime.filterString(); QString jpeg_filter = jpeg_mime.filterString(); QString tiff_filter = tiff_mime.filterString(); QString bmp_filter = bmp_mime.filterString(); QString eps_filter = eps_mime.filterString(); QStringList filter(png_filter); QList image_formats = QImageWriter::supportedImageFormats(); if(image_formats.contains("gif")) { filter << gif_filter; } if(image_formats.contains("jpeg")) { filter << jpeg_filter; } if(image_formats.contains("tiff")) { filter << tiff_filter; } if(image_formats.contains("bmp")) { filter << bmp_filter; } if(image_formats.contains("eps")) { filter << eps_filter; } QFileDialog fileDialog(this); fileDialog.setNameFilters(filter); fileDialog.selectNameFilter(png_filter); fileDialog.setDefaultSuffix(png_mime.preferredSuffix()); fileDialog.setAcceptMode(QFileDialog::AcceptSave); #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) fileDialog.setSupportedSchemes(QStringList("file")); #endif fileDialog.setDirectory(last_picture_directory); connect(&fileDialog, SIGNAL(filterSelected(QString)), this, SLOT(onFilterSelected(QString))); QString url; if(!fileDialog.exec()) return; QStringList urls = fileDialog.selectedFiles(); if(urls.isEmpty()) return; url = urls[0]; QString selected_filter = fileDialog.selectedNameFilter(); QMimeType url_mime = db.mimeTypeForFile(url, QMimeDatabase::MatchExtension); QSaveFile ofile(url); ofile.open(QIODevice::WriteOnly); ofile.setPermissions((QFile::Permissions) 0x0660); if(!ofile.isOpen()) { ofile.cancelWriting(); QMessageBox::critical(this, tr("Error"), tr("Couldn't open file for writing.")); return; } last_picture_directory = fileDialog.directory().absolutePath(); QRectF rect = scene->sceneRect(); QPixmap pixmap((int) ceil(rect.width()), (int) ceil(rect.height())); QPainter p(&pixmap); #ifdef QT_CHARTS_LIB bool drop_shadow_save = chart->isDropShadowEnabled(); chart->setDropShadowEnabled(false); p.fillRect(pixmap.rect(), chart->backgroundBrush()); #endif p.setRenderHint(QPainter::Antialiasing, true); scene->render(&p); #ifdef QT_CHARTS_LIB chart->setDropShadowEnabled(drop_shadow_save); #endif if(url_mime == png_mime) {pixmap.save(&ofile, "PNG");} else if(url_mime == bmp_mime) {pixmap.save(&ofile, "BMP");} else if(url_mime == eps_mime) {pixmap.save(&ofile, "EPS");} else if(url_mime == tiff_mime) {pixmap.save(&ofile, "TIF");} else if(url_mime == gif_mime) {pixmap.save(&ofile, "GIF");} else if(url_mime == jpeg_mime) {pixmap.save(&ofile, "JPEG");} else if(selected_filter == png_filter) {pixmap.save(&ofile, "PNG");} else if(selected_filter == bmp_filter) {pixmap.save(&ofile, "BMP");} else if(selected_filter == eps_filter) {pixmap.save(&ofile, "EPS");} else if(selected_filter == tiff_filter) {pixmap.save(&ofile, "TIF");} else if(selected_filter == gif_filter) {pixmap.save(&ofile, "GIF");} else if(selected_filter == jpeg_filter) {pixmap.save(&ofile, "JPEG");} else pixmap.save(&ofile); if(!ofile.commit()) { QMessageBox::critical(this, tr("Error"), tr("Error while writing file; file was not saved.")); return; } } void OverTimeChart::print() { #ifdef QT_CHARTS_LIB QGraphicsScene *scene = view->scene(); #endif if(!scene) return; QPrinter pr; QPrintDialog dialog(&pr, this); if(dialog.exec() == QDialog::Accepted) { QPainter p(&pr); p.setRenderHint(QPainter::Antialiasing, true); scene->render(&p); p.end(); } } QColor getBarColor(int index, int) { switch(index % 8) { case 0: return QColor(114, 147, 203); case 1: return QColor(225, 151, 70); case 2: return QColor(132, 186, 91); case 3: return QColor(211, 94, 96); case 4: return QColor(128, 133, 133); case 5: return QColor(144, 103, 167); case 6: return QColor(171, 104, 87); case 7: return QColor(204, 194, 16); } return Qt::black; } QBrush getBarBrush(int index, int total) { QBrush brush; if(total > 9) total = 9; else if(total <= 0) total = 1; switch(index / total) { case 0: {brush.setStyle(Qt::SolidPattern); break;} case 1: {brush.setStyle(Qt::Dense3Pattern); break;} case 2: {brush.setStyle(Qt::DiagCrossPattern); break;} case 3: {brush.setStyle(Qt::HorPattern); break;} case 4: {brush.setStyle(Qt::VerPattern); break;} default: {} } brush.setColor(getBarColor(index, total)); return brush; } QColor getLineColor(int index) { switch(index % 8) { case 0: return QColor(57, 106, 177); case 1: return QColor(218, 124, 48); case 2: return QColor(62, 150, 81); case 3: return QColor(204, 37, 41); case 4: return QColor(83, 81, 84); case 5: return QColor(107, 76, 154); case 6: return QColor(146, 36, 40); case 7: return QColor(148, 139, 61); } return Qt::black; } QPen getLinePen(int index) { QPen pen; pen.setWidth(2); switch(index / 8) { case 0: {pen.setStyle(Qt::SolidLine); break;} case 1: {pen.setStyle(Qt::DotLine); break;} case 2: {pen.setStyle(Qt::DashLine); break;} case 3: {pen.setStyle(Qt::DashDotLine); break;} default: {} } pen.setColor(getLineColor(index % 8)); return pen; } void OverTimeChart::updateDisplay() { if(!isVisible() || budget->accounts.count() <= 1) return; int current_source2 = (current_source > 50 ? current_source - 100 : current_source); QVector monthly_incomes, monthly_expenses; QMap > monthly_cats; QMap mi_c; QMap > monthly_desc; QMap desc_values; QMap cat_values; QMap desc_map; QMap mi_d; chart_month_info *mi_e = NULL, *mi_i = NULL; chart_month_info **mi = NULL, **mi2 = NULL; QVector *monthly_values = NULL, *monthly_values2 = NULL; QMap scheduled_cats; QMap scheduled_cat_counts; QMap scheduled_desc; QMap scheduled_desc_counts; bool isfirst_i = true, isfirst_e = true; QMap isfirst_c; QMap isfirst_d; bool *isfirst = NULL, *isfirst2 = NULL; QStringList desc_order; QList cat_order; bool exclude_subs = false; bool is_parent = (current_account && !current_account->subCategories.isEmpty()); AssetsAccount *current_assets = selectedAccount(); bool do_convert = (current_source2 != -2) && !current_assets; Currency *currency = budget->defaultCurrency(); if(current_assets) currency = current_assets->currency(); bool b_income = false, b_expense = false; if(current_source == 25) current_source = 3; if(current_source == 26) current_source = 4; #ifdef QT_CHARTS_LIB int chart_type = typeCombo->currentIndex() + 1; #else int chart_type = 1; #endif int type = valueGroup->checkedId(); if(current_source == -2 && chart_type == 1) type = 0; QString title_string, note_string; if(current_source == 3 || (current_source < 2 && current_source > -2)) { for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) { Account *account = *it; if(!exclude_subs || account->topAccount() == account) { monthly_cats[account] = QVector(); mi_c[account] = NULL; isfirst_c[account] = true; scheduled_cats[account] = 0.0; scheduled_cat_counts[account] = 0.0; } } } if(current_source == -2 || current_source > 50) { for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { Account *account = *it; if(account != budget->balancingAccount && (!current_assets || account == current_assets)) { monthly_cats[account] = QVector(); mi_c[account] = NULL; isfirst_c[account] = true; scheduled_cats[account] = 0.0; scheduled_cat_counts[account] = 0.0; cat_values[account] = 0.0; } } } else if(current_source == -3) { for(int i = 0; i < budget->tags.count(); i++) { desc_map[budget->tags[i]] = budget->tags[i]; monthly_desc[budget->tags[i]] = QVector(); desc_values[budget->tags[i]] = 0.0; mi_d[budget->tags[i]] = NULL; isfirst_d[budget->tags[i]] = true; scheduled_desc[budget->tags[i]] = 0.0; scheduled_desc_counts[budget->tags[i]] = 0.0; } } else if(current_source == 4 || current_source < 3) { for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) { Account *account = *it; if(!exclude_subs || account->topAccount() == account) { monthly_cats[account] = QVector(); mi_c[account] = NULL; isfirst_c[account] = true; scheduled_cats[account] = 0.0; scheduled_cat_counts[account] = 0.0; cat_values[account] = 0.0; } } } else if(current_source >= 21 && current_source <= 24) { if(!current_account) return; CategoryAccount *account = NULL; for(AccountList::const_iterator it = current_account->subCategories.constBegin();;) { if(account == current_account) break; if(it != current_account->subCategories.constEnd()) { account = *it; ++it; } else { account = current_account; } monthly_cats[account] = QVector(); mi_c[account] = NULL; isfirst_c[account] = true; scheduled_cats[account] = 0.0; scheduled_cat_counts[account] = 0.0; cat_values[account] = 0.0; } } else if(current_source == 29 || current_source == 39 || current_source == 7 || current_source == 8 || current_source == 17 || current_source == 18) { if(has_empty_description) descriptionCombo->setItemText(descriptionCombo->count() - 1, ""); for(int i = 2; i < descriptionCombo->count(); i++) { QString str = descriptionCombo->itemText(i).toLower(); desc_map[str] = descriptionCombo->itemText(i); monthly_desc[str] = QVector(); desc_values[str] = 0.0; mi_d[str] = NULL; isfirst_d[str] = true; scheduled_desc[str] = 0.0; scheduled_desc_counts[str] = 0.0; } } else if(current_source == 33 || current_source == 35 || current_source == 11 || current_source == 12 || current_source == 13 || current_source == 14) { if(has_empty_payee) payeeCombo->setItemText(payeeCombo->count() - 1, ""); for(int i = 2; i < payeeCombo->count(); i++) { QString str = payeeCombo->itemText(i).toLower(); desc_map[str] = payeeCombo->itemText(i); monthly_desc[str] = QVector(); desc_values[str] = 0.0; mi_d[str] = NULL; isfirst_d[str] = true; scheduled_desc[str] = 0.0; scheduled_desc_counts[str] = 0.0; } } QDate first_date = budget->monthToBudgetMonth(start_date); QDate last_date = budget->lastBudgetDay(budget->monthToBudgetMonth(end_date)); if(type == 4) first_date = budget->firstBudgetDayOfYear(first_date); double maxvalue = 1.0; double minvalue = 0.0; double maxcount = 1.0; bool started = false; int tag_index = 0; for(TransactionList::const_iterator it = budget->transactions.constBegin(); it != budget->transactions.constEnd();) { Transaction *trans = *it; if(trans->date() > last_date) break; bool include = false; int sign = 1; bool use_to_value = false; monthly_values2 = NULL; if(!started && (current_source2 == -2 || trans->date() >= first_date)) { started = true; if(type == 4) first_date = budget->firstBudgetDayOfYear(trans->date()); else first_date = budget->firstBudgetDay(trans->date()); } if(started && (!current_assets || trans->relatesToAccount(current_assets))) { switch(current_source2) { case -3: { if((trans->type() == TRANSACTION_TYPE_INCOME || trans->type() == TRANSACTION_TYPE_EXPENSE) && trans->tagsCount(true) > 0) { QString str = trans->getTag(tag_index, true); monthly_values = &monthly_desc[str]; mi = &mi_d[str]; isfirst = &isfirst_d[str]; if(trans->type() == TRANSACTION_TYPE_INCOME) {b_income = true; sign = 1;} else {b_expense = true; sign = -1;} include = true; if(tag_index + 1 < trans->tagsCount(true)) tag_index++; else tag_index = 0; } break; } case -2: { if(trans->toAccount()->type() == ACCOUNT_TYPE_ASSETS && ((AssetsAccount*) trans->toAccount())->accountType() != ASSETS_TYPE_SECURITIES && trans->toAccount() != budget->balancingAccount) { monthly_values = &monthly_cats[trans->toAccount()]; mi = &mi_c[trans->toAccount()]; isfirst = &isfirst_c[trans->toAccount()]; use_to_value = true; if(trans->fromAccount()->type() == ACCOUNT_TYPE_ASSETS && ((AssetsAccount*) trans->fromAccount())->accountType() != ASSETS_TYPE_SECURITIES && trans->fromAccount() != budget->balancingAccount) { monthly_values2 = &monthly_cats[trans->fromAccount()]; mi2 = &mi_c[trans->fromAccount()]; isfirst2 = &isfirst_c[trans->fromAccount()]; } sign = 1; include = true; } else if(trans->fromAccount()->type() == ACCOUNT_TYPE_ASSETS && ((AssetsAccount*) trans->fromAccount())->accountType() != ASSETS_TYPE_SECURITIES && trans->fromAccount() != budget->balancingAccount) { monthly_values = &monthly_cats[trans->fromAccount()]; mi = &mi_c[trans->fromAccount()]; isfirst = &isfirst_c[trans->fromAccount()]; sign = -1; include = true; } break; } case -1: {} case 0: {} case 1: {} case 2: {} case 3: {} case 4: { if(current_source2 != 2 && current_source2 != 4 && trans->fromAccount()->type() == ACCOUNT_TYPE_INCOMES) { if(current_source > 50) { monthly_values = &monthly_cats[trans->toAccount()]; mi = &mi_c[trans->toAccount()]; isfirst = &isfirst_c[trans->toAccount()]; } else { monthly_values = &monthly_cats[exclude_subs ? trans->fromAccount()->topAccount() : trans->fromAccount()]; mi = &mi_c[exclude_subs ? trans->fromAccount()->topAccount() : trans->fromAccount()]; isfirst = &isfirst_c[exclude_subs ? trans->fromAccount()->topAccount() : trans->fromAccount()]; } sign = 1; include = true; } else if(current_source2 != 1 && current_source2 != 3 && trans->fromAccount()->type() == ACCOUNT_TYPE_EXPENSES) { if(current_source > 50) { monthly_values = &monthly_cats[trans->toAccount()]; mi = &mi_c[trans->toAccount()]; isfirst = &isfirst_c[trans->toAccount()]; } else { monthly_values = &monthly_cats[exclude_subs ? trans->fromAccount()->topAccount() : trans->fromAccount()]; mi = &mi_c[exclude_subs ? trans->fromAccount()->topAccount() : trans->fromAccount()]; isfirst = &isfirst_c[exclude_subs ? trans->fromAccount()->topAccount() : trans->fromAccount()]; } if(current_source == 99) sign = 1; else sign = -1; include = true; } else if(current_source2 != 2 && current_source2 != 4 && trans->toAccount()->type() == ACCOUNT_TYPE_INCOMES) { if(current_source > 50) { monthly_values = &monthly_cats[trans->fromAccount()]; mi = &mi_c[trans->fromAccount()]; isfirst = &isfirst_c[trans->fromAccount()]; } else { monthly_values = &monthly_cats[exclude_subs ? trans->toAccount()->topAccount() : trans->toAccount()]; mi = &mi_c[exclude_subs ? trans->toAccount()->topAccount() : trans->toAccount()]; isfirst = &isfirst_c[exclude_subs ? trans->toAccount()->topAccount() : trans->toAccount()]; } sign = -1; include = true; } else if(current_source2 != 1 && current_source2 != 3 && trans->toAccount()->type() == ACCOUNT_TYPE_EXPENSES) { if(current_source > 50) { monthly_values = &monthly_cats[trans->fromAccount()]; mi = &mi_c[trans->fromAccount()]; isfirst = &isfirst_c[trans->fromAccount()]; } else { monthly_values = &monthly_cats[exclude_subs ? trans->toAccount()->topAccount() : trans->toAccount()]; mi = &mi_c[exclude_subs ? trans->toAccount()->topAccount() : trans->toAccount()]; isfirst = &isfirst_c[exclude_subs ? trans->toAccount()->topAccount() : trans->toAccount()]; } if(current_source == 99) sign = -1; else sign = 1; include = true; } break; } case 23: { if(trans->type() != TRANSACTION_TYPE_INCOME) break; if(!((Income*) trans)->payer().compare(current_payee, Qt::CaseInsensitive)) break; } case 21: { if(trans->fromAccount()->topAccount() == current_account) { monthly_values = &monthly_cats[trans->fromAccount()]; mi = &mi_c[trans->fromAccount()]; isfirst = &isfirst_c[trans->fromAccount()]; sign = 1; include = true; } else if(trans->toAccount()->topAccount() == current_account) { monthly_values = &monthly_cats[trans->toAccount()]; mi = &mi_c[trans->toAccount()]; isfirst = &isfirst_c[trans->toAccount()]; sign = -1; include = true; } break; } case 24: { if(trans->type() != TRANSACTION_TYPE_EXPENSE) break; if(!((Expense*) trans)->payee().compare(current_payee, Qt::CaseInsensitive)) break; } case 22: { if(trans->fromAccount()->topAccount() == current_account) { monthly_values = &monthly_cats[trans->fromAccount()]; mi = &mi_c[trans->fromAccount()]; isfirst = &isfirst_c[trans->fromAccount()]; sign = -1; include = true; } else if(trans->toAccount()->topAccount() == current_account) { monthly_values = &monthly_cats[trans->toAccount()]; mi = &mi_c[trans->toAccount()]; isfirst = &isfirst_c[trans->toAccount()]; sign = 1; include = true; } break; } case 27: { if(trans->hasTag(current_tag, true) && (trans->type() == TRANSACTION_TYPE_INCOME || trans->type() == TRANSACTION_TYPE_EXPENSE)) { if(current_source > 50) { Account *acc = trans->toAccount(); if(acc->type() != ACCOUNT_TYPE_ASSETS) acc = trans->fromAccount(); monthly_values = &monthly_cats[acc]; mi = &mi_c[acc]; isfirst = &isfirst_c[acc]; } else { monthly_values = &monthly_incomes; mi = &mi_i; isfirst = &isfirst_i; } include = true; if(trans->type() == TRANSACTION_TYPE_INCOME) {b_income = true; sign = 1;} else {b_expense = true; sign = -1;} } break; } case 5: { if((is_parent ? trans->fromAccount()->topAccount() : trans->fromAccount()) == current_account) { if(current_source > 50) { monthly_values = &monthly_cats[trans->toAccount()]; mi = &mi_c[trans->toAccount()]; isfirst = &isfirst_c[trans->toAccount()]; } else { monthly_values = &monthly_incomes; mi = &mi_i; isfirst = &isfirst_i; } sign = 1; include = true; } else if((is_parent ? trans->toAccount()->topAccount() : trans->toAccount()) == current_account) { if(current_source > 50) { monthly_values = &monthly_cats[trans->fromAccount()]; mi = &mi_c[trans->fromAccount()]; isfirst = &isfirst_c[trans->fromAccount()]; } else { monthly_values = &monthly_incomes; mi = &mi_i; isfirst = &isfirst_i; } sign = -1; include = true; } break; } case 6: { if((is_parent ? trans->fromAccount()->topAccount() : trans->fromAccount()) == current_account) { if(current_source > 50) { monthly_values = &monthly_cats[trans->toAccount()]; mi = &mi_c[trans->toAccount()]; isfirst = &isfirst_c[trans->toAccount()]; } else { monthly_values = &monthly_expenses; mi = &mi_e; isfirst = &isfirst_e; } sign = -1; include = true; } else if((is_parent ? trans->toAccount()->topAccount() : trans->toAccount()) == current_account) { if(current_source > 50) { monthly_values = &monthly_cats[trans->fromAccount()]; mi = &mi_c[trans->fromAccount()]; isfirst = &isfirst_c[trans->fromAccount()]; } else { monthly_values = &monthly_expenses; mi = &mi_e; isfirst = &isfirst_e; } sign = 1; include = true; } break; } case 29: { if(trans->hasTag(current_tag, true) && (trans->type() == TRANSACTION_TYPE_INCOME || trans->type() == TRANSACTION_TYPE_EXPENSE)) { monthly_values = &monthly_desc[trans->description().toLower()]; mi = &mi_d[trans->description().toLower()]; isfirst = &isfirst_d[trans->description().toLower()]; if(trans->type() == TRANSACTION_TYPE_INCOME) {b_income = true; sign = 1;} else {b_expense = true; sign = -1;} include = true; } break; } case 7: { if((is_parent ? trans->fromAccount()->topAccount() : trans->fromAccount()) == current_account) { monthly_values = &monthly_desc[trans->description().toLower()]; mi = &mi_d[trans->description().toLower()]; isfirst = &isfirst_d[trans->description().toLower()]; sign = 1; include = true; } else if((is_parent ? trans->toAccount()->topAccount() : trans->toAccount()) == current_account) { monthly_values = &monthly_desc[trans->description().toLower()]; mi = &mi_d[trans->description().toLower()]; isfirst = &isfirst_d[trans->description().toLower()]; sign = -1; include = true; } break; } case 8: { if((is_parent ? trans->fromAccount()->topAccount() : trans->fromAccount()) == current_account) { monthly_values = &monthly_desc[trans->description().toLower()]; mi = &mi_d[trans->description().toLower()]; isfirst = &isfirst_d[trans->description().toLower()]; sign = -1; include = true; } else if((is_parent ? trans->toAccount()->topAccount() : trans->toAccount()) == current_account) { monthly_values = &monthly_desc[trans->description().toLower()]; mi = &mi_d[trans->description().toLower()]; isfirst = &isfirst_d[trans->description().toLower()]; sign = 1; include = true; } break; } case 31: { if(trans->hasTag(current_tag, true) && (trans->type() == TRANSACTION_TYPE_INCOME || trans->type() == TRANSACTION_TYPE_EXPENSE) && !trans->description().compare(current_description, Qt::CaseInsensitive)) { if(current_source > 50) { Account *acc = trans->toAccount(); if(acc->type() != ACCOUNT_TYPE_ASSETS) acc = trans->fromAccount(); monthly_values = &monthly_cats[acc]; mi = &mi_c[acc]; isfirst = &isfirst_c[acc]; } else { monthly_values = &monthly_incomes; mi = &mi_i; isfirst = &isfirst_i; } if(trans->type() == TRANSACTION_TYPE_INCOME) {b_income = true; sign = 1;} else {b_expense = true; sign = -1;} include = true; } break; } case 9: { if((is_parent ? trans->fromAccount()->topAccount() : trans->fromAccount()) == current_account && !trans->description().compare(current_description, Qt::CaseInsensitive)) { if(current_source > 50) { monthly_values = &monthly_cats[trans->toAccount()]; mi = &mi_c[trans->toAccount()]; isfirst = &isfirst_c[trans->toAccount()]; } else { monthly_values = &monthly_incomes; mi = &mi_i; isfirst = &isfirst_i; } sign = 1; include = true; } else if((is_parent ? trans->toAccount()->topAccount() : trans->toAccount()) == current_account && !trans->description().compare(current_description, Qt::CaseInsensitive)) { if(current_source > 50) { monthly_values = &monthly_cats[trans->fromAccount()]; mi = &mi_c[trans->fromAccount()]; isfirst = &isfirst_c[trans->fromAccount()]; } else { monthly_values = &monthly_incomes; mi = &mi_i; isfirst = &isfirst_i; } sign = -1; include = true; } break; } case 10: { if((is_parent ? trans->fromAccount()->topAccount() : trans->fromAccount()) == current_account && !trans->description().compare(current_description, Qt::CaseInsensitive)) { if(current_source > 50) { monthly_values = &monthly_cats[trans->toAccount()]; mi = &mi_c[trans->toAccount()]; isfirst = &isfirst_c[trans->toAccount()]; } else { monthly_values = &monthly_expenses; mi = &mi_e; isfirst = &isfirst_e; } sign = -1; include = true; } else if((is_parent ? trans->toAccount()->topAccount() : trans->toAccount()) == current_account && !trans->description().compare(current_description, Qt::CaseInsensitive)) { if(current_source > 50) { monthly_values = &monthly_cats[trans->fromAccount()]; mi = &mi_c[trans->fromAccount()]; isfirst = &isfirst_c[trans->fromAccount()]; } else { monthly_values = &monthly_expenses; mi = &mi_e; isfirst = &isfirst_e; } sign = 1; include = true; } break; } case 33: { if(trans->hasTag(current_tag, true) && (trans->type() == TRANSACTION_TYPE_INCOME || trans->type() == TRANSACTION_TYPE_EXPENSE)) { QString str; if(trans->type() == TRANSACTION_TYPE_INCOME) str = ((Income*) trans)->payer().toLower(); else str = ((Expense*) trans)->payee().toLower(); monthly_values = &monthly_desc[str]; mi = &mi_d[str]; isfirst = &isfirst_d[str]; if(trans->type() == TRANSACTION_TYPE_INCOME) {b_income = true; sign = 1;} else {b_expense = true; sign = -1;} include = true; } break; } case 11: { if(trans->type() != TRANSACTION_TYPE_INCOME) break; Income *income = (Income*) trans; if((is_parent ? income->category()->topAccount() : income->category()) == current_account) { monthly_values = &monthly_desc[income->payer().toLower()]; mi = &mi_d[income->payer().toLower()]; isfirst = &isfirst_d[income->payer().toLower()]; sign = 1; include = true; } break; } case 12: { if(trans->type() != TRANSACTION_TYPE_EXPENSE) break; Expense *expense = (Expense*) trans; if((is_parent ? expense->category()->topAccount() : expense->category()) == current_account) { monthly_values = &monthly_desc[expense->payee().toLower()]; mi = &mi_d[expense->payee().toLower()]; isfirst = &isfirst_d[expense->payee().toLower()]; sign = 1; include = true; } break; } case 35: { if(trans->hasTag(current_tag, true) && (trans->type() == TRANSACTION_TYPE_INCOME || trans->type() == TRANSACTION_TYPE_EXPENSE) && !trans->description().compare(current_description, Qt::CaseInsensitive)) { QString str; if(trans->type() == TRANSACTION_TYPE_INCOME) str = ((Income*) trans)->payer().toLower(); else str = ((Expense*) trans)->payee().toLower(); monthly_values = &monthly_desc[str]; mi = &mi_d[str]; isfirst = &isfirst_d[str]; if(trans->type() == TRANSACTION_TYPE_INCOME) {b_income = true; sign = 1;} else {b_expense = true; sign = -1;} sign = 1; include = true; } break; } case 13: { if(trans->type() != TRANSACTION_TYPE_INCOME) break; Income *income = (Income*) trans; if((is_parent ? income->category()->topAccount() : income->category()) == current_account && !income->description().compare(current_description, Qt::CaseInsensitive)) { monthly_values = &monthly_desc[income->payer().toLower()]; mi = &mi_d[income->payer().toLower()]; isfirst = &isfirst_d[income->payer().toLower()]; sign = 1; include = true; } break; } case 14: { if(trans->type() != TRANSACTION_TYPE_EXPENSE) break; Expense *expense = (Expense*) trans; if((is_parent ? expense->category()->topAccount() : expense->category()) == current_account && !expense->description().compare(current_description, Qt::CaseInsensitive)) { monthly_values = &monthly_desc[expense->payee().toLower()]; mi = &mi_d[expense->payee().toLower()]; isfirst = &isfirst_d[expense->payee().toLower()]; sign = 1; include = true; } break; } case 37: { if(trans->hasTag(current_tag, true) && ((trans->type() == TRANSACTION_TYPE_INCOME && !((Income*) trans)->payer().compare(current_payee, Qt::CaseInsensitive)) || (trans->type() == TRANSACTION_TYPE_EXPENSE && !((Expense*) trans)->payee().compare(current_payee, Qt::CaseInsensitive)))) { if(current_source > 50) { Account *acc = trans->toAccount(); if(acc->type() != ACCOUNT_TYPE_ASSETS) acc = trans->fromAccount(); monthly_values = &monthly_cats[acc]; mi = &mi_c[acc]; isfirst = &isfirst_c[acc]; } else { monthly_values = &monthly_incomes; mi = &mi_i; isfirst = &isfirst_i; } if(trans->type() == TRANSACTION_TYPE_INCOME) {b_income = true; sign = 1;} else {b_expense = true; sign = -1;} include = true; } } case 15: { if(trans->type() != TRANSACTION_TYPE_INCOME) break; Income *income = (Income*) trans; if((is_parent ? income->category()->topAccount() : income->category()) == current_account && !income->payer().compare(current_payee, Qt::CaseInsensitive)) { if(current_source > 50) { monthly_values = &monthly_cats[income->to()]; mi = &mi_c[income->to()]; isfirst = &isfirst_c[income->to()]; } else { monthly_values = &monthly_incomes; mi = &mi_i; isfirst = &isfirst_i; } sign = 1; include = true; } break; } case 16: { if(trans->type() != TRANSACTION_TYPE_EXPENSE) break; Expense *expense = (Expense*) trans; if((is_parent ? expense->category()->topAccount() : expense->category()) == current_account && !expense->payee().compare(current_payee, Qt::CaseInsensitive)) { if(current_source > 50) { monthly_values = &monthly_cats[expense->from()]; mi = &mi_c[expense->from()]; isfirst = &isfirst_c[expense->from()]; } else { monthly_values = &monthly_expenses; mi = &mi_e; isfirst = &isfirst_e; } sign = 1; include = true; } break; } case 39: { if(trans->hasTag(current_tag, true) && ((trans->type() == TRANSACTION_TYPE_INCOME && !((Income*) trans)->payer().compare(current_payee, Qt::CaseInsensitive)) || (trans->type() == TRANSACTION_TYPE_EXPENSE && !((Expense*) trans)->payee().compare(current_payee, Qt::CaseInsensitive)))) { monthly_values = &monthly_desc[trans->description().toLower()]; mi = &mi_d[trans->description().toLower()]; isfirst = &isfirst_d[trans->description().toLower()]; if(trans->type() == TRANSACTION_TYPE_INCOME) {b_income = true; sign = 1;} else {b_expense = true; sign = -1;} include = true; } } case 17: { if(trans->type() != TRANSACTION_TYPE_INCOME) break; Income *income = (Income*) trans; if((is_parent ? income->category()->topAccount() : income->category()) == current_account && !income->payer().compare(current_payee, Qt::CaseInsensitive)) { monthly_values = &monthly_desc[income->description().toLower()]; mi = &mi_d[income->description().toLower()]; isfirst = &isfirst_d[income->description().toLower()]; sign = 1; include = true; } break; } case 18: { if(trans->type() != TRANSACTION_TYPE_EXPENSE) break; Expense *expense = (Expense*) trans; if((is_parent ? expense->category()->topAccount() : expense->category()) == current_account && !expense->payee().compare(current_payee, Qt::CaseInsensitive)) { monthly_values = &monthly_desc[expense->description().toLower()]; mi = &mi_d[expense->description().toLower()]; isfirst = &isfirst_d[expense->description().toLower()]; sign = 1; include = true; } break; } case 41: { if(trans->hasTag(current_tag, true) && !trans->description().compare(current_description, Qt::CaseInsensitive) && ((trans->type() == TRANSACTION_TYPE_INCOME && !((Income*) trans)->payer().compare(current_payee, Qt::CaseInsensitive)) || (trans->type() == TRANSACTION_TYPE_EXPENSE && !((Expense*) trans)->payee().compare(current_payee, Qt::CaseInsensitive)))) { if(current_source > 50) { Account *acc = trans->toAccount(); if(acc->type() != ACCOUNT_TYPE_ASSETS) acc = trans->fromAccount(); monthly_values = &monthly_cats[acc]; mi = &mi_c[acc]; isfirst = &isfirst_c[acc]; } else { monthly_values = &monthly_incomes; mi = &mi_i; isfirst = &isfirst_i; } if(trans->type() == TRANSACTION_TYPE_INCOME) {b_income = true; sign = 1;} else {b_expense = true; sign = -1;} include = true; } } case 19: { if(trans->type() != TRANSACTION_TYPE_INCOME) break; Income *income = (Income*) trans; if((is_parent ? income->category()->topAccount() : income->category()) == current_account && !income->description().compare(current_description, Qt::CaseInsensitive) && !income->payer().compare(current_payee, Qt::CaseInsensitive)) { if(current_source > 50) { monthly_values = &monthly_cats[income->to()]; mi = &mi_c[income->to()]; isfirst = &isfirst_c[income->to()]; } else { monthly_values = &monthly_incomes; mi = &mi_i; isfirst = &isfirst_i; } sign = 1; include = true; } break; } case 20: { if(trans->type() != TRANSACTION_TYPE_EXPENSE) break; Expense *expense = (Expense*) trans; if((is_parent ? expense->category()->topAccount() : expense->category()) == current_account && !expense->description().compare(current_description, Qt::CaseInsensitive) && !expense->payee().compare(current_payee, Qt::CaseInsensitive)) { if(current_source > 50) { monthly_values = &monthly_cats[expense->from()]; mi = &mi_c[expense->from()]; isfirst = &isfirst_c[expense->from()]; } else { monthly_values = &monthly_expenses; mi = &mi_e; isfirst = &isfirst_e; } sign = 1; include = true; } break; } } } if(include) { if(!(*mi) || trans->date() > (*mi)->date) { QDate newdate, olddate; newdate = budget->lastBudgetDay(trans->date()); if(*mi) { olddate = (*mi)->date; budget->addBudgetMonthsSetLast(olddate, 1); (*isfirst) = false; } else { olddate = budget->lastBudgetDay(first_date); (*isfirst) = true; } while(olddate < newdate) { monthly_values->append(chart_month_info()); (*mi) = &monthly_values->back(); (*mi)->value = 0.0; (*mi)->count = 0.0; (*mi)->date = olddate; budget->addBudgetMonthsSetLast(olddate, 1); (*isfirst) = false; } monthly_values->append(chart_month_info()); (*mi) = &monthly_values->back(); if(use_to_value) (*mi)->value = trans->toValue(do_convert) * sign; else (*mi)->value = trans->value(do_convert) * sign; (*mi)->count = trans->quantity(); (*mi)->date = newdate; } else { if(use_to_value) (*mi)->value += trans->toValue(do_convert) * sign; else (*mi)->value += trans->value(do_convert) * sign; (*mi)->count += trans->quantity(); } if(monthly_values2) { if(!(*mi2) || trans->date() > (*mi2)->date) { QDate newdate, olddate; newdate = budget->lastBudgetDay(trans->date()); if(*mi2) { olddate = (*mi2)->date; budget->addBudgetMonthsSetLast(olddate, 1); (*isfirst2) = false; } else { olddate = budget->lastBudgetDay(first_date); (*isfirst2) = true; } while(olddate < newdate) { monthly_values2->append(chart_month_info()); (*mi2) = &monthly_values2->back(); (*mi2)->value = 0.0; (*mi2)->count = 0.0; (*mi2)->date = olddate; budget->addBudgetMonthsSetLast(olddate, 1); (*isfirst2) = false; } monthly_values2->append(chart_month_info()); (*mi2) = &monthly_values2->back(); (*mi2)->value = trans->value(do_convert) * sign * -1; (*mi2)->date = newdate; } else { (*mi2)->value += trans->value(do_convert) * sign * -1; } } } if(tag_index == 0) ++it; } int source_org = 0; switch(current_source) { case -3: {source_org = -3; break;} case -2: {source_org = -2; break;} case -1: {} case 0: {source_org = 0; break;} case 1: {source_org = 3; break;} case 2: {source_org = 4; break;} case 3: {source_org = 3; break;} case 4: {source_org = 4; break;} case 27: {} case 5: {source_org = 1; break;} case 6: {source_org = 2; break;} case 29: {} case 7: {} case 8: {source_org = 7; break;} case 31: {} case 9: {source_org = 1; break;} case 10: {source_org = 2; break;} case 33: {} case 11: {} case 12: {} case 35: {} case 13: {} case 14: {source_org = 11; break;} case 37: {} case 15: {source_org = 1; break;} case 16: {source_org = 2; break;} case 39: {} case 17: {} case 18: {source_org = 7; break;} case 41: {} case 19: {source_org = 1; break;} case 20: {source_org = 2; break;} case 21: {} case 22: {} case 23: {} case 24: {source_org = 21; break;} } if(current_source > 50) source_org = -2; int first_desc_i = 2; if(source_org == 7 && is_parent) first_desc_i = 3; else if(source_org == -3) first_desc_i = 0; Account *account = NULL; QString tag; int desc_i = first_desc_i; int desc_nr = 0; bool at_expenses = false; int account_index = 0; bool includes_scheduled = false; if(source_org == 7) desc_nr = descriptionCombo->count(); else if(source_org == 11) desc_nr = payeeCombo->count(); else if(source_org == 0) { if(account_index < budget->incomesAccounts.size()) { account = budget->incomesAccounts.at(account_index); } else { at_expenses = true; if(account_index < budget->expensesAccounts.size()) account = budget->expensesAccounts.at(account_index); } } else if(source_org == -2) { if(current_assets) account = current_assets; else if(account_index < budget->assetsAccounts.size()) account = budget->assetsAccounts.at(account_index); } else if(source_org == -3) desc_nr = budget->tags.count(); else if(source_org == 3) {if(account_index < budget->incomesAccounts.size()) account = budget->incomesAccounts.at(account_index);} else if(source_org == 4) {if(account_index < budget->expensesAccounts.size()) account = budget->expensesAccounts.at(account_index);} else if(source_org == 21) {if(account_index < current_account->subCategories.size()) account = current_account->subCategories.at(account_index);} else if(source_org == 2) {mi = &mi_e; monthly_values = &monthly_expenses; isfirst = &isfirst_e;} else if(source_org == 1) {mi = &mi_i; monthly_values = &monthly_incomes; isfirst = &isfirst_i;} while(source_org == 1 || source_org == 2 || account || ((source_org == 7 || source_org == 11 || source_org == -3) && desc_i < desc_nr)) { if(source_org == -2 && account == budget->balancingAccount) { ++account_index; account = NULL; if(account_index < budget->assetsAccounts.size()) account = budget->assetsAccounts.at(account_index); } while(exclude_subs && account && account->topAccount() != account) { ++account_index; account = NULL; if(source_org == 3 && account_index < budget->incomesAccounts.size()) account = budget->incomesAccounts.at(account_index); else if(source_org != 3 && account_index < budget->expensesAccounts.size()) account = budget->expensesAccounts.at(account_index); } if((exclude_subs || source_org == -2) && !account) break; if(source_org == -3) {mi = &mi_d[budget->tags[desc_i]]; monthly_values = &monthly_desc[budget->tags[desc_i]]; isfirst = &isfirst_d[budget->tags[desc_i]];} else if(source_org == -2 || source_org == 3 || source_org == 4 || source_org == 0 || source_org == 21) {mi = &mi_c[account]; monthly_values = &monthly_cats[account]; isfirst = &isfirst_c[account];} else if(source_org == 7) {mi = &mi_d[descriptionCombo->itemText(desc_i).toLower()]; monthly_values = &monthly_desc[descriptionCombo->itemText(desc_i).toLower()]; isfirst = &isfirst_d[descriptionCombo->itemText(desc_i).toLower()];} else if(source_org == 11) {mi = &mi_d[payeeCombo->itemText(desc_i).toLower()]; monthly_values = &monthly_desc[payeeCombo->itemText(desc_i).toLower()]; isfirst = &isfirst_d[payeeCombo->itemText(desc_i).toLower()];} if(!(*mi)) { monthly_values->append(chart_month_info()); (*mi) = &monthly_values->back(); (*mi)->value = 0.0; (*mi)->count = 0.0; (*mi)->date = budget->lastBudgetDay(first_date); (*isfirst) = true; } while((*mi)->date < last_date) { QDate newdate = (*mi)->date; budget->addBudgetMonthsSetLast(newdate, 1); monthly_values->append(chart_month_info()); (*mi) = &monthly_values->back(); (*mi)->value = 0.0; (*mi)->count = 0.0; (*mi)->date = newdate; (*isfirst) = false; } ++account_index; if(source_org == 7 || source_org == 11 || source_org == -3) { desc_i++; } else if(source_org == 3) { account = NULL; if(account_index < budget->incomesAccounts.size()) account = budget->incomesAccounts.at(account_index); } else if(source_org == 4) { account = NULL; if(account_index < budget->expensesAccounts.size()) account = budget->expensesAccounts.at(account_index); } else if(source_org == 21) { if(account == current_account) break; account = NULL; if(account_index < current_account->subCategories.size()) account = current_account->subCategories.at(account_index); if(!account) account = current_account; } else if(source_org == 0) { account = NULL; if(!at_expenses) { if(account_index < budget->incomesAccounts.size()) account = budget->incomesAccounts.at(account_index); if(!account) { at_expenses = true; account_index = 0; if(account_index < budget->expensesAccounts.size()) account = budget->expensesAccounts.at(account_index); } } else { if(account_index < budget->expensesAccounts.size()) account = budget->expensesAccounts.at(account_index); } } else if(source_org == -2) { account = NULL; if(!current_assets && account_index < budget->assetsAccounts.size()) account = budget->assetsAccounts.at(account_index); } else { break; } } tag_index = 0; int split_i = 0; Transaction *trans = NULL; for(ScheduledTransactionList::const_iterator it = budget->scheduledTransactions.constBegin(); it != budget->scheduledTransactions.constEnd();) { ScheduledTransaction *strans = *it; if(strans->firstOccurrence() > last_date) break; if(split_i == 0 && strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT && ((SplitTransaction*) strans->transaction())->count() == 0) { do { ++it; if(it == budget->scheduledTransactions.constEnd()) { strans = NULL; break; } strans = *it; if(strans->firstOccurrence() > last_date) { strans = NULL; break; } } while(split_i == 0 && strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT && ((SplitTransaction*) strans->transaction())->count() == 0); if(!strans) break; } if(strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { trans = ((SplitTransaction*) strans->transaction())->at(split_i); } else { trans = (Transaction*) strans->transaction(); } monthly_values2 = NULL; bool include = false; int sign = 1; bool use_to_value = false; if(!current_assets || trans->relatesToAccount(current_assets)) { switch(current_source2) { case -3: { if((trans->type() == TRANSACTION_TYPE_INCOME || trans->type() == TRANSACTION_TYPE_EXPENSE) && trans->tagsCount(true) > 0) { QString str = trans->getTag(tag_index, true); monthly_values = &monthly_desc[str]; mi = &mi_d[str]; isfirst = &isfirst_d[str]; if(trans->type() == TRANSACTION_TYPE_INCOME) {b_income = true; sign = 1;} else {b_expense = true; sign = -1;} include = true; if(tag_index + 1 < trans->tagsCount(true)) tag_index++; else tag_index = 0; } break; } case -2: { if(trans->toAccount()->type() == ACCOUNT_TYPE_ASSETS && ((AssetsAccount*) trans->toAccount())->accountType() != ASSETS_TYPE_SECURITIES && trans->toAccount() != budget->balancingAccount) { monthly_values = &monthly_cats[trans->toAccount()]; mi = &mi_c[trans->toAccount()]; isfirst = &isfirst_c[trans->toAccount()]; use_to_value = true; if(trans->fromAccount()->type() == ACCOUNT_TYPE_ASSETS && ((AssetsAccount*) trans->fromAccount())->accountType() != ASSETS_TYPE_SECURITIES && trans->fromAccount() != budget->balancingAccount) { monthly_values2 = &monthly_cats[trans->fromAccount()]; mi2 = &mi_c[trans->fromAccount()]; isfirst2 = &isfirst_c[trans->fromAccount()]; } sign = 1; include = true; } else if(trans->fromAccount()->type() == ACCOUNT_TYPE_ASSETS && ((AssetsAccount*) trans->fromAccount())->accountType() != ASSETS_TYPE_SECURITIES && trans->fromAccount() != budget->balancingAccount) { monthly_values = &monthly_cats[trans->fromAccount()]; mi = &mi_c[trans->fromAccount()]; isfirst = &isfirst_c[trans->fromAccount()]; sign = -1; include = true; } break; } case -1: {} case 0: {} case 1: {} case 2: {} case 3: {} case 4: { if(current_source2 != 2 && current_source2 != 4 && trans->fromAccount()->type() == ACCOUNT_TYPE_INCOMES) { if(current_source > 50) { monthly_values = &monthly_cats[trans->toAccount()]; mi = &mi_c[trans->toAccount()]; isfirst = &isfirst_c[trans->toAccount()]; } else { monthly_values = &monthly_cats[exclude_subs ? trans->fromAccount()->topAccount() : trans->fromAccount()]; mi = &mi_c[exclude_subs ? trans->fromAccount()->topAccount() : trans->fromAccount()]; isfirst = &isfirst_c[exclude_subs ? trans->fromAccount()->topAccount() : trans->fromAccount()]; } sign = 1; include = true; } else if(current_source2 != 1 && current_source2 != 3 && trans->fromAccount()->type() == ACCOUNT_TYPE_EXPENSES) { if(current_source > 50) { monthly_values = &monthly_cats[trans->toAccount()]; mi = &mi_c[trans->toAccount()]; isfirst = &isfirst_c[trans->toAccount()]; } else { monthly_values = &monthly_cats[exclude_subs ? trans->fromAccount()->topAccount() : trans->fromAccount()]; mi = &mi_c[exclude_subs ? trans->fromAccount()->topAccount() : trans->fromAccount()]; isfirst = &isfirst_c[exclude_subs ? trans->fromAccount()->topAccount() : trans->fromAccount()]; } if(current_source == 99) sign = 1; else sign = -1; include = true; } else if(current_source2 != 2 && current_source2 != 4 && trans->toAccount()->type() == ACCOUNT_TYPE_INCOMES) { if(current_source > 50) { monthly_values = &monthly_cats[trans->fromAccount()]; mi = &mi_c[trans->fromAccount()]; isfirst = &isfirst_c[trans->fromAccount()]; } else { monthly_values = &monthly_cats[exclude_subs ? trans->toAccount()->topAccount() : trans->toAccount()]; mi = &mi_c[exclude_subs ? trans->toAccount()->topAccount() : trans->toAccount()]; isfirst = &isfirst_c[exclude_subs ? trans->toAccount()->topAccount() : trans->toAccount()]; } sign = -1; include = true; } else if(current_source2 != 1 && current_source2 != 3 && trans->toAccount()->type() == ACCOUNT_TYPE_EXPENSES) { if(current_source > 50) { monthly_values = &monthly_cats[trans->fromAccount()]; mi = &mi_c[trans->fromAccount()]; isfirst = &isfirst_c[trans->fromAccount()]; } else { monthly_values = &monthly_cats[exclude_subs ? trans->toAccount()->topAccount() : trans->toAccount()]; mi = &mi_c[exclude_subs ? trans->toAccount()->topAccount() : trans->toAccount()]; isfirst = &isfirst_c[exclude_subs ? trans->toAccount()->topAccount() : trans->toAccount()]; } if(current_source == 99) sign = -1; else sign = 1; include = true; } break; } case 23: { if(trans->type() != TRANSACTION_TYPE_INCOME) break; if(!((Income*) trans)->payer().compare(current_payee, Qt::CaseInsensitive)) break; } case 21: { if(trans->fromAccount()->topAccount() == current_account) { monthly_values = &monthly_cats[trans->fromAccount()]; mi = &mi_c[trans->fromAccount()]; isfirst = &isfirst_c[trans->fromAccount()]; sign = 1; include = true; } else if(trans->toAccount()->topAccount() == current_account) { monthly_values = &monthly_cats[trans->toAccount()]; mi = &mi_c[trans->toAccount()]; isfirst = &isfirst_c[trans->toAccount()]; sign = -1; include = true; } break; } case 24: { if(trans->type() != TRANSACTION_TYPE_EXPENSE) break; if(!((Expense*) trans)->payee().compare(current_payee, Qt::CaseInsensitive)) break; } case 22: { if(trans->fromAccount()->topAccount() == current_account) { monthly_values = &monthly_cats[trans->fromAccount()]; mi = &mi_c[trans->fromAccount()]; isfirst = &isfirst_c[trans->fromAccount()]; sign = -1; include = true; } else if(trans->toAccount()->topAccount() == current_account) { monthly_values = &monthly_cats[trans->toAccount()]; mi = &mi_c[trans->toAccount()]; isfirst = &isfirst_c[trans->toAccount()]; sign = 1; include = true; } break; } case 27: { if(trans->hasTag(current_tag, true) && (trans->type() == TRANSACTION_TYPE_INCOME || trans->type() == TRANSACTION_TYPE_EXPENSE)) { if(current_source > 50) { Account *acc = trans->toAccount(); if(acc->type() != ACCOUNT_TYPE_ASSETS) acc = trans->fromAccount(); monthly_values = &monthly_cats[acc]; mi = &mi_c[acc]; isfirst = &isfirst_c[acc]; } else { monthly_values = &monthly_incomes; mi = &mi_i; isfirst = &isfirst_i; } include = true; if(trans->type() == TRANSACTION_TYPE_INCOME) {b_income = true; sign = 1;} else {b_expense = true; sign = -1;} } break; } case 5: { if((is_parent ? trans->fromAccount()->topAccount() : trans->fromAccount()) == current_account) { if(current_source > 50) { monthly_values = &monthly_cats[trans->toAccount()]; mi = &mi_c[trans->toAccount()]; isfirst = &isfirst_c[trans->toAccount()]; } else { monthly_values = &monthly_incomes; mi = &mi_i; isfirst = &isfirst_i; } sign = 1; include = true; } else if((is_parent ? trans->toAccount()->topAccount() : trans->toAccount()) == current_account) { if(current_source > 50) { monthly_values = &monthly_cats[trans->fromAccount()]; mi = &mi_c[trans->fromAccount()]; isfirst = &isfirst_c[trans->fromAccount()]; } else { monthly_values = &monthly_incomes; mi = &mi_i; isfirst = &isfirst_i; } sign = -1; include = true; } break; } case 6: { if((is_parent ? trans->fromAccount()->topAccount() : trans->fromAccount()) == current_account) { if(current_source > 50) { monthly_values = &monthly_cats[trans->toAccount()]; mi = &mi_c[trans->toAccount()]; isfirst = &isfirst_c[trans->toAccount()]; } else { monthly_values = &monthly_expenses; mi = &mi_e; isfirst = &isfirst_e; } sign = -1; include = true; } else if((is_parent ? trans->toAccount()->topAccount() : trans->toAccount()) == current_account) { if(current_source > 50) { monthly_values = &monthly_cats[trans->fromAccount()]; mi = &mi_c[trans->fromAccount()]; isfirst = &isfirst_c[trans->fromAccount()]; } else { monthly_values = &monthly_expenses; mi = &mi_e; isfirst = &isfirst_e; } sign = 1; include = true; } break; } case 29: { if(trans->hasTag(current_tag, true) && (trans->type() == TRANSACTION_TYPE_INCOME || trans->type() == TRANSACTION_TYPE_EXPENSE)) { monthly_values = &monthly_desc[trans->description().toLower()]; mi = &mi_d[trans->description().toLower()]; isfirst = &isfirst_d[trans->description().toLower()]; if(trans->type() == TRANSACTION_TYPE_INCOME) {b_income = true; sign = 1;} else {b_expense = true; sign = -1;} include = true; } break; } case 7: { if((is_parent ? trans->fromAccount()->topAccount() : trans->fromAccount()) == current_account) { monthly_values = &monthly_desc[trans->description().toLower()]; mi = &mi_d[trans->description().toLower()]; isfirst = &isfirst_d[trans->description().toLower()]; sign = 1; include = true; } else if((is_parent ? trans->toAccount()->topAccount() : trans->toAccount()) == current_account) { monthly_values = &monthly_desc[trans->description().toLower()]; mi = &mi_d[trans->description().toLower()]; isfirst = &isfirst_d[trans->description().toLower()]; sign = -1; include = true; } break; } case 8: { if((is_parent ? trans->fromAccount()->topAccount() : trans->fromAccount()) == current_account) { monthly_values = &monthly_desc[trans->description().toLower()]; mi = &mi_d[trans->description().toLower()]; isfirst = &isfirst_d[trans->description().toLower()]; sign = -1; include = true; } else if((is_parent ? trans->toAccount()->topAccount() : trans->toAccount()) == current_account) { monthly_values = &monthly_desc[trans->description().toLower()]; mi = &mi_d[trans->description().toLower()]; isfirst = &isfirst_d[trans->description().toLower()]; sign = 1; include = true; } break; } case 31: { if(trans->hasTag(current_tag, true) && (trans->type() == TRANSACTION_TYPE_INCOME || trans->type() == TRANSACTION_TYPE_EXPENSE) && !trans->description().compare(current_description, Qt::CaseInsensitive)) { if(current_source > 50) { Account *acc = trans->toAccount(); if(acc->type() != ACCOUNT_TYPE_ASSETS) acc = trans->fromAccount(); monthly_values = &monthly_cats[acc]; mi = &mi_c[acc]; isfirst = &isfirst_c[acc]; } else { monthly_values = &monthly_incomes; mi = &mi_i; isfirst = &isfirst_i; } if(trans->type() == TRANSACTION_TYPE_INCOME) {b_income = true; sign = 1;} else {b_expense = true; sign = -1;} include = true; } break; } case 9: { if((is_parent ? trans->fromAccount()->topAccount() : trans->fromAccount()) == current_account && !trans->description().compare(current_description, Qt::CaseInsensitive)) { if(current_source > 50) { monthly_values = &monthly_cats[trans->toAccount()]; mi = &mi_c[trans->toAccount()]; isfirst = &isfirst_c[trans->toAccount()]; } else { monthly_values = &monthly_incomes; mi = &mi_i; isfirst = &isfirst_i; } sign = 1; include = true; } else if((is_parent ? trans->toAccount()->topAccount() : trans->toAccount()) == current_account && !trans->description().compare(current_description, Qt::CaseInsensitive)) { if(current_source > 50) { monthly_values = &monthly_cats[trans->fromAccount()]; mi = &mi_c[trans->fromAccount()]; isfirst = &isfirst_c[trans->fromAccount()]; } else { monthly_values = &monthly_incomes; mi = &mi_i; isfirst = &isfirst_i; } sign = -1; include = true; } break; } case 10: { if((is_parent ? trans->fromAccount()->topAccount() : trans->fromAccount()) == current_account && !trans->description().compare(current_description, Qt::CaseInsensitive)) { if(current_source > 50) { monthly_values = &monthly_cats[trans->toAccount()]; mi = &mi_c[trans->toAccount()]; isfirst = &isfirst_c[trans->toAccount()]; } else { monthly_values = &monthly_expenses; mi = &mi_e; isfirst = &isfirst_e; } sign = -1; include = true; } else if((is_parent ? trans->toAccount()->topAccount() : trans->toAccount()) == current_account && !trans->description().compare(current_description, Qt::CaseInsensitive)) { if(current_source > 50) { monthly_values = &monthly_cats[trans->fromAccount()]; mi = &mi_c[trans->fromAccount()]; isfirst = &isfirst_c[trans->fromAccount()]; } else { monthly_values = &monthly_expenses; mi = &mi_e; isfirst = &isfirst_e; } sign = 1; include = true; } break; } case 33: { if(trans->hasTag(current_tag, true) && (trans->type() == TRANSACTION_TYPE_INCOME || trans->type() == TRANSACTION_TYPE_EXPENSE)) { QString str; if(trans->type() == TRANSACTION_TYPE_INCOME) str = ((Income*) trans)->payer().toLower(); else str = ((Expense*) trans)->payee().toLower(); monthly_values = &monthly_desc[str]; mi = &mi_d[str]; isfirst = &isfirst_d[str]; if(trans->type() == TRANSACTION_TYPE_INCOME) {b_income = true; sign = 1;} else {b_expense = true; sign = -1;} include = true; } break; } case 11: { if(trans->type() != TRANSACTION_TYPE_INCOME) break; Income *income = (Income*) trans; if((is_parent ? income->category()->topAccount() : income->category()) == current_account) { monthly_values = &monthly_desc[income->payer().toLower()]; mi = &mi_d[income->payer().toLower()]; isfirst = &isfirst_d[income->payer().toLower()]; sign = 1; include = true; } break; } case 12: { if(trans->type() != TRANSACTION_TYPE_EXPENSE) break; Expense *expense = (Expense*) trans; if((is_parent ? expense->category()->topAccount() : expense->category()) == current_account) { monthly_values = &monthly_desc[expense->payee().toLower()]; mi = &mi_d[expense->payee().toLower()]; isfirst = &isfirst_d[expense->payee().toLower()]; sign = 1; include = true; } break; } case 35: { if(trans->hasTag(current_tag, true) && (trans->type() == TRANSACTION_TYPE_INCOME || trans->type() == TRANSACTION_TYPE_EXPENSE) && !trans->description().compare(current_description, Qt::CaseInsensitive)) { QString str; if(trans->type() == TRANSACTION_TYPE_INCOME) str = ((Income*) trans)->payer().toLower(); else str = ((Expense*) trans)->payee().toLower(); monthly_values = &monthly_desc[str]; mi = &mi_d[str]; isfirst = &isfirst_d[str]; if(trans->type() == TRANSACTION_TYPE_INCOME) {b_income = true; sign = 1;} else {b_expense = true; sign = -1;} sign = 1; include = true; } break; } case 13: { if(trans->type() != TRANSACTION_TYPE_INCOME) break; Income *income = (Income*) trans; if((is_parent ? income->category()->topAccount() : income->category()) == current_account && !income->description().compare(current_description, Qt::CaseInsensitive)) { monthly_values = &monthly_desc[income->payer().toLower()]; mi = &mi_d[income->payer().toLower()]; isfirst = &isfirst_d[income->payer().toLower()]; sign = 1; include = true; } break; } case 14: { if(trans->type() != TRANSACTION_TYPE_EXPENSE) break; Expense *expense = (Expense*) trans; if((is_parent ? expense->category()->topAccount() : expense->category()) == current_account && !expense->description().compare(current_description, Qt::CaseInsensitive)) { monthly_values = &monthly_desc[expense->payee().toLower()]; mi = &mi_d[expense->payee().toLower()]; isfirst = &isfirst_d[expense->payee().toLower()]; sign = 1; include = true; } break; } case 37: { if(trans->hasTag(current_tag, true) && ((trans->type() == TRANSACTION_TYPE_INCOME && !((Income*) trans)->payer().compare(current_payee, Qt::CaseInsensitive)) || (trans->type() == TRANSACTION_TYPE_EXPENSE && !((Expense*) trans)->payee().compare(current_payee, Qt::CaseInsensitive)))) { if(current_source > 50) { Account *acc = trans->toAccount(); if(acc->type() != ACCOUNT_TYPE_ASSETS) acc = trans->fromAccount(); monthly_values = &monthly_cats[acc]; mi = &mi_c[acc]; isfirst = &isfirst_c[acc]; } else { monthly_values = &monthly_incomes; mi = &mi_i; isfirst = &isfirst_i; } if(trans->type() == TRANSACTION_TYPE_INCOME) {b_income = true; sign = 1;} else {b_expense = true; sign = -1;} include = true; } } case 15: { if(trans->type() != TRANSACTION_TYPE_INCOME) break; Income *income = (Income*) trans; if((is_parent ? income->category()->topAccount() : income->category()) == current_account && !income->payer().compare(current_payee, Qt::CaseInsensitive)) { if(current_source > 50) { monthly_values = &monthly_cats[income->to()]; mi = &mi_c[income->to()]; isfirst = &isfirst_c[income->to()]; } else { monthly_values = &monthly_incomes; mi = &mi_i; isfirst = &isfirst_i; } sign = 1; include = true; } break; } case 16: { if(trans->type() != TRANSACTION_TYPE_EXPENSE) break; Expense *expense = (Expense*) trans; if((is_parent ? expense->category()->topAccount() : expense->category()) == current_account && !expense->payee().compare(current_payee, Qt::CaseInsensitive)) { if(current_source > 50) { monthly_values = &monthly_cats[expense->from()]; mi = &mi_c[expense->from()]; isfirst = &isfirst_c[expense->from()]; } else { monthly_values = &monthly_expenses; mi = &mi_e; isfirst = &isfirst_e; } sign = 1; include = true; } break; } case 39: { if(trans->hasTag(current_tag, true) && ((trans->type() == TRANSACTION_TYPE_INCOME && !((Income*) trans)->payer().compare(current_payee, Qt::CaseInsensitive)) || (trans->type() == TRANSACTION_TYPE_EXPENSE && !((Expense*) trans)->payee().compare(current_payee, Qt::CaseInsensitive)))) { monthly_values = &monthly_desc[trans->description().toLower()]; mi = &mi_d[trans->description().toLower()]; isfirst = &isfirst_d[trans->description().toLower()]; if(trans->type() == TRANSACTION_TYPE_INCOME) {b_income = true; sign = 1;} else {b_expense = true; sign = -1;} include = true; } } case 17: { if(trans->type() != TRANSACTION_TYPE_INCOME) break; Income *income = (Income*) trans; if((is_parent ? income->category()->topAccount() : income->category()) == current_account && !income->payer().compare(current_payee, Qt::CaseInsensitive)) { monthly_values = &monthly_desc[income->description().toLower()]; mi = &mi_d[income->description().toLower()]; isfirst = &isfirst_d[income->description().toLower()]; sign = 1; include = true; } break; } case 18: { if(trans->type() != TRANSACTION_TYPE_EXPENSE) break; Expense *expense = (Expense*) trans; if((is_parent ? expense->category()->topAccount() : expense->category()) == current_account && !expense->payee().compare(current_payee, Qt::CaseInsensitive)) { monthly_values = &monthly_desc[expense->description().toLower()]; mi = &mi_d[expense->description().toLower()]; isfirst = &isfirst_d[expense->description().toLower()]; sign = 1; include = true; } break; } case 41: { if(trans->hasTag(current_tag, true) && !trans->description().compare(current_description, Qt::CaseInsensitive) && ((trans->type() == TRANSACTION_TYPE_INCOME && !((Income*) trans)->payer().compare(current_payee, Qt::CaseInsensitive)) || (trans->type() == TRANSACTION_TYPE_EXPENSE && !((Expense*) trans)->payee().compare(current_payee, Qt::CaseInsensitive)))) { if(current_source > 50) { Account *acc = trans->toAccount(); if(acc->type() != ACCOUNT_TYPE_ASSETS) acc = trans->fromAccount(); monthly_values = &monthly_cats[acc]; mi = &mi_c[acc]; isfirst = &isfirst_c[acc]; } else { monthly_values = &monthly_incomes; mi = &mi_i; isfirst = &isfirst_i; } if(trans->type() == TRANSACTION_TYPE_INCOME) {b_income = true; sign = 1;} else {b_expense = true; sign = -1;} include = true; } } case 19: { if(trans->type() != TRANSACTION_TYPE_INCOME) break; Income *income = (Income*) trans; if((is_parent ? income->category()->topAccount() : income->category()) == current_account && !income->description().compare(current_description, Qt::CaseInsensitive) && !income->payer().compare(current_payee, Qt::CaseInsensitive)) { if(current_source > 50) { monthly_values = &monthly_cats[income->to()]; mi = &mi_c[income->to()]; isfirst = &isfirst_c[income->to()]; } else { monthly_values = &monthly_incomes; mi = &mi_i; isfirst = &isfirst_i; } sign = 1; include = true; } break; } case 20: { if(trans->type() != TRANSACTION_TYPE_EXPENSE) break; Expense *expense = (Expense*) trans; if((is_parent ? expense->category()->topAccount() : expense->category()) == current_account && !expense->description().compare(current_description, Qt::CaseInsensitive) && !expense->payee().compare(current_payee, Qt::CaseInsensitive)) { if(current_source > 50) { monthly_values = &monthly_cats[expense->from()]; mi = &mi_c[expense->from()]; isfirst = &isfirst_c[expense->from()]; } else { monthly_values = &monthly_expenses; mi = &mi_e; isfirst = &isfirst_e; } sign = 1; include = true; } break; } } } if(include) { QDate transdate = strans->firstOccurrence(); QVector::iterator cmi_it = monthly_values->begin(); do { if(transdate >= first_date) { while(cmi_it->date < transdate) { ++cmi_it; } (*mi) = cmi_it; if(use_to_value) (*mi)->value += trans->toValue(do_convert) * sign; else (*mi)->value += trans->value(do_convert) * sign; (*mi)->count += trans->quantity(); includes_scheduled = true; } if(strans->recurrence()) { transdate = strans->recurrence()->nextOccurrence(transdate); } else { break; } } while(transdate <= last_date); if(monthly_values2) { transdate = strans->firstOccurrence(); cmi_it = monthly_values2->begin(); do { if(transdate >= first_date) { while(cmi_it->date < transdate) { ++cmi_it; } (*mi2) = cmi_it; (*mi2)->value += trans->value(do_convert) * sign * -1; includes_scheduled = true; } if(strans->recurrence()) { transdate = strans->recurrence()->nextOccurrence(transdate); } else { break; } } while(transdate <= last_date); } } if(tag_index == 0) { split_i++; if(strans->transaction()->generaltype() != GENERAL_TRANSACTION_TYPE_SPLIT || split_i >= ((SplitTransaction*) strans->transaction())->count()) { ++it; split_i = 0; } } } bool includes_budget = false; QDate imonth = budget->lastBudgetDay(QDate::currentDate()); if(QDate::currentDate() == imonth) { budget->addBudgetMonthsSetLast(imonth, 1); } exclude_subs = (current_source == 3 || current_source == 4); if(exclude_subs) { for(int i = 0; i < (current_source == 3 ? budget->incomesAccounts.size() : budget->expensesAccounts.size()); i++) { CategoryAccount *pacc; if(current_source == 3) pacc = budget->incomesAccounts.at(i); else pacc = budget->expensesAccounts.at(i); if(!pacc->subCategories.isEmpty()) { for(int i3 = 0; i3 < pacc->subCategories.size(); i3++) { CategoryAccount *acc = pacc->subCategories[i3]; monthly_values = &monthly_cats[pacc]; monthly_values2 = &monthly_cats[acc]; bool in_future = false; for(int i2 = 0; i2 < monthly_values->size(); i2++) { if(!in_future && monthly_values2->at(i2).date >= imonth) { in_future = true; } if(in_future) { double d_budget = acc->monthlyBudget(budget->budgetYear(monthly_values2->at(i2).date), budget->budgetMonth(monthly_values2->at(i2).date), false); if(d_budget >= 0.0 && d_budget > monthly_values2->at(i2).value) { (*monthly_values2)[i2].value = d_budget; includes_budget = true; } } (*monthly_values)[i2].value += monthly_values2->at(i2).value; (*monthly_values)[i2].count += monthly_values2->at(i2).count; } monthly_cats.remove(acc); } } } } account = current_account; desc_i = first_desc_i; desc_nr = 0; at_expenses = false; account = NULL; account_index = 0; if(source_org == 7) desc_nr = descriptionCombo->count(); else if(source_org == 11) desc_nr = payeeCombo->count(); else if(source_org == 0) { if(account_index < budget->incomesAccounts.size()) { account = budget->incomesAccounts.at(account_index); } else { at_expenses = true; if(account_index < budget->expensesAccounts.size()) account = budget->expensesAccounts.at(account_index); } } else if(source_org == -2) { if(current_assets) account = current_assets; else if(account_index < budget->assetsAccounts.size()) account = budget->assetsAccounts.at(account_index); } else if(source_org == -3) desc_nr = budget->tags.count(); else if(source_org == 3) {if(account_index < budget->incomesAccounts.size()) account = budget->incomesAccounts.at(account_index);} else if(source_org == 4) {if(account_index < budget->expensesAccounts.size()) account = budget->expensesAccounts.at(account_index);} else if(source_org == 21) {if(account_index < current_account->subCategories.size()) account = current_account->subCategories.at(account_index);} else if(source_org == 2) {mi = &mi_e; monthly_values = &monthly_expenses; isfirst = &isfirst_e;} else if(source_org == 1) {mi = &mi_i; monthly_values = &monthly_incomes; isfirst = &isfirst_i;} while(source_org == 1 || source_org == 2 || account || ((source_org == -3 || source_org == 7 || source_org == 11) && desc_i < desc_nr)) { if(source_org == -2 && (account == budget->balancingAccount)) { ++account_index; account = NULL; if(account_index < budget->assetsAccounts.size()) account = budget->assetsAccounts.at(account_index); } while(exclude_subs && account && account->topAccount() != account) { ++account_index; account = NULL; if(source_org == 3 && account_index < budget->incomesAccounts.size()) account = budget->incomesAccounts.at(account_index); else if(source_org != 3 && account_index < budget->expensesAccounts.size()) account = budget->expensesAccounts.at(account_index); } if((exclude_subs || source_org == -2) && !account) break; if(source_org == -3) {mi = &mi_d[budget->tags[desc_i]]; monthly_values = &monthly_desc[budget->tags[desc_i]]; isfirst = &isfirst_d[budget->tags[desc_i]];} else if(source_org == -2 || source_org == 4 || source_org == 3 || source_org == 0 || source_org == 21) {mi = &mi_c[account]; monthly_values = &monthly_cats[account]; isfirst = &isfirst_c[account];} else if(source_org == 7) {mi = &mi_d[descriptionCombo->itemText(desc_i).toLower()]; monthly_values = &monthly_desc[descriptionCombo->itemText(desc_i).toLower()]; isfirst = &isfirst_d[descriptionCombo->itemText(desc_i).toLower()];} else if(source_org == 11) {mi = &mi_d[payeeCombo->itemText(desc_i).toLower()]; monthly_values = &monthly_desc[payeeCombo->itemText(desc_i).toLower()]; isfirst = &isfirst_d[payeeCombo->itemText(desc_i).toLower()];} (*mi) = &monthly_values->front(); QVector::iterator cmi_it = monthly_values->begin(); QVector::iterator cmi_year = monthly_values->begin(); int year = budget->budgetYear(cmi_year->date); bool in_future = false; while(cmi_it != monthly_values->end()) { (*mi) = cmi_it; if((type < 2 || type == 4) && (current_source <= 6 || current_source == 21 || current_source == 22) && (!current_assets || current_assets->isBudgetAccount())) { if(!in_future && (*mi)->date >= imonth) { in_future = true; } if(in_future) { double d_budget = 0.0; if(current_source == 5 || current_source == 6) { d_budget = ((CategoryAccount*) current_account)->monthlyBudget(budget->budgetYear((*mi)->date), budget->budgetMonth((*mi)->date), false); } else if(account && account->type() != ACCOUNT_TYPE_ASSETS) { d_budget = ((CategoryAccount*) account)->monthlyBudget(budget->budgetYear((*mi)->date), budget->budgetMonth((*mi)->date), false); if((current_source == 21 || current_source == 22) && account == current_account) { for(int i = 0; i < ((CategoryAccount*) account)->subCategories.size(); i++) { double d_budget2 = (((CategoryAccount*) account)->subCategories[i])->monthlyBudget(budget->budgetYear((*mi)->date), budget->budgetMonth((*mi)->date), false); if(d_budget2 >= 0.0) d_budget -= d_budget2; } } } if(d_budget >= 0.0 && d_budget > (*mi)->value) { (*mi)->value = d_budget; includes_budget = true; } } } if(!b_income && b_expense) { (*mi)->value = -(*mi)->value; } switch(type) { case 1: { if((*mi)->date >= last_date) { (*mi)->value /= ((*isfirst) ? (first_date.daysTo(last_date) + 1) : budget->dayOfBudgetMonth(last_date)); } else { (*mi)->value /= ((*isfirst) ? (first_date.daysTo((*mi)->date) + 1) : budget->daysInBudgetMonth((*mi)->date)); } break; } case 2: {(*mi)->value = (*mi)->count; break;} case 3: {if((*mi)->count > 0.0) (*mi)->value /= (*mi)->count; else (*mi)->value = 0.0; break;} case 4: { if(current_source != -2 && current_source != 21 && current_source != 22) { if(cmi_it == cmi_year) { (*mi)->date = budget->lastBudgetDayOfYear((*mi)->date); } else { if(budget->budgetYear((*mi)->date) == year) { cmi_year->value += (*mi)->value; cmi_it = monthly_values->erase(cmi_it); --cmi_it; } else { if(cmi_year->value > maxvalue) maxvalue = cmi_year->value; else if(cmi_year->value < minvalue) minvalue = cmi_year->value; cmi_year = cmi_it; year = budget->budgetYear((*mi)->date); (*mi)->date = budget->lastBudgetDayOfYear((*mi)->date); } } } break; } } if(type == 4 && current_source != -2 && current_source != 21 && current_source != 22) { if(cmi_year->value > maxvalue) maxvalue = cmi_year->value; else if(cmi_year->value < minvalue) minvalue = cmi_year->value; } else if(type != 4) { if((*mi)->value > maxvalue) maxvalue = (*mi)->value; else if((*mi)->value < minvalue) minvalue = (*mi)->value; if((*mi)->count > maxcount) maxcount = (*mi)->count; } ++cmi_it; } ++account_index; if(source_org == 7 || source_org == 11 || source_org == -3) { desc_i++; } else if(source_org == 3) { account = NULL; if(account_index < budget->incomesAccounts.size()) account = budget->incomesAccounts.at(account_index); } else if(source_org == 4) { account = NULL; if(account_index < budget->expensesAccounts.size()) account = budget->expensesAccounts.at(account_index); } else if(source_org == 21) { if(account == current_account) break; account = NULL; if(account_index < current_account->subCategories.size()) account = current_account->subCategories.at(account_index); if(!account) account = current_account; } else if(source_org == 0) { account = NULL; if(!at_expenses) { if(account_index < budget->incomesAccounts.size()) account = budget->incomesAccounts.at(account_index); if(!account) { at_expenses = true; account_index = 0; if(account_index < budget->expensesAccounts.size()) account = budget->expensesAccounts.at(account_index); } } else { if(account_index < budget->expensesAccounts.size()) account = budget->expensesAccounts.at(account_index); } } else if(source_org == -2) { account = NULL; if(!current_assets && account_index < budget->assetsAccounts.size()) account = budget->assetsAccounts.at(account_index); } else { break; } } if(type == 4 && (current_source == 21 || current_source == 22)) { for(int i = -1; i < ((CategoryAccount*) current_account)->subCategories.size(); i++) { CategoryAccount *acc = (CategoryAccount*) current_account; if(i >= 0) acc = acc->subCategories[i]; monthly_values = &monthly_cats[acc]; if(monthly_values->size() > 0) { int i_year = 0; int year = budget->budgetYear(monthly_values->at(0).date); for(int i2 = 0; i2 < monthly_values->size(); i2++) { if(i2 == i_year) { (*monthly_values)[i2].date = budget->lastBudgetDayOfYear(monthly_values->at(i2).date); } else { if(budget->budgetYear(monthly_values->at(i2).date) == year) { (*monthly_values)[i_year].value += monthly_values->at(i2).value; monthly_values->remove(i2); i2--; } else { if(monthly_values->at(i_year).value > maxvalue) maxvalue = monthly_values->at(i_year).value; else if(monthly_values->at(i_year).value < minvalue) minvalue = monthly_values->at(i_year).value; i_year = i2; year = budget->budgetYear(monthly_values->at(i2).date); (*monthly_values)[i2].date = budget->lastBudgetDayOfYear(monthly_values->at(i2).date); } } } if(monthly_values->at(i_year).value > maxvalue) maxvalue = monthly_values->at(i_year).value; else if(monthly_values->at(i_year).value < minvalue) minvalue = monthly_values->at(i_year).value; } } } chart_month_info *mi0 = NULL; mi = &mi0; if(type == 4) { imonth = budget->lastBudgetDayOfYear(QDate::currentDate()); if(QDate::currentDate() == imonth) budget->addBudgetMonthsSetLast(imonth, 12); } bool second_run = false; if(current_source < 3) { maxvalue = 0.0; minvalue = 0.0; maxcount = 0.0; } if(current_source2 == -2) { if(first_date < (type == 4 ? budget->firstBudgetDayOfYear(budget->monthToBudgetMonth(start_date)) : budget->monthToBudgetMonth(start_date))) { first_date = budget->monthToBudgetMonth(start_date); if(type == 4) first_date = budget->firstBudgetDayOfYear(first_date); } if(type != 4) budget->addBudgetMonthsSetFirst(first_date, type == 4 ? -12 : -1); for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { AssetsAccount *ass = *it; if(ass != budget->balancingAccount && (!current_assets || ass == current_assets)) { QVector::iterator it = monthly_cats[ass].begin(); QVector::iterator it_e = monthly_cats[ass].end(); double acc_total = ass->initialBalance(false); chart_month_info initial_cmi; initial_cmi.date = it->date; budget->addBudgetMonthsSetLast(initial_cmi.date, type == 4 ? -12 : -1); if(current_assets) initial_cmi.value = acc_total; else initial_cmi.value = ass->currency()->convertTo(acc_total, budget->defaultCurrency(), initial_cmi.date); while(it != it_e) { acc_total += it->value; if(current_assets) it->value = acc_total; else it->value = ass->currency()->convertTo(acc_total, budget->defaultCurrency(), it->date); ++it; } monthly_cats[ass].push_front(initial_cmi); it = monthly_cats[ass].begin(); it_e = monthly_cats[ass].end(); while(it != it_e && it->date < first_date) { monthly_cats[ass].pop_front(); it = monthly_cats[ass].begin(); } } } for(SecurityList::const_iterator it = budget->securities.constBegin(); it != budget->securities.constEnd(); ++it) { Security *sec = *it; AssetsAccount *ass = sec->account(); if(!current_assets || ass == current_assets) { QVector::iterator it_b = monthly_cats[ass].begin(); QVector::iterator it_e = monthly_cats[ass].end(); while(it_b != it_e) { if(current_assets) it_b->value += sec->value(it_b->date, -1); else it_b->value += ass->currency()->convertTo(sec->value(it_b->date, -1), budget->defaultCurrency(), it_b->date); it_b++; } } } if(current_source > 50) { for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { AssetsAccount *ass = *it; if(ass != budget->balancingAccount) { cat_values[ass] = 0.0; for(QVector::iterator it = monthly_cats[ass].begin(); it != monthly_cats[ass].end(); ++it) { if(abs(it->value) > cat_values[ass]) cat_values[ass] = abs(it->value); } } } } if(type == 4) { for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { AssetsAccount *ass = *it; if(ass != budget->balancingAccount && (!current_assets || ass == current_assets)) { for(QVector::iterator it = monthly_cats[ass].begin(); it != monthly_cats[ass].end();) { QVector::iterator it_next = it; it_next++; if(budget->budgetMonth(it->date) != 12 && it_next != monthly_cats[ass].end()) { it = monthly_cats[ass].erase(it); it_next = it; } it = it_next; } } } } } bool b_assets = false, b_liabilities = false; while(current_source < 3 && current_source != -3) { if(current_source == -1 || current_source == 1 || second_run) monthly_values = &monthly_incomes; else monthly_values = &monthly_expenses; if(!second_run || current_source != -1) { monthly_values->append(chart_month_info()); (*mi) = &monthly_values->back(); (*mi)->value = 0.0; (*mi)->count = 0.0; (*mi)->date = budget->lastBudgetDay(first_date); while((*mi)->date < last_date) { QDate newdate = (*mi)->date; budget->addBudgetMonthsSetLast(newdate, type == 4 ? 12 : 1); if(type == 4 && newdate > last_date) break; monthly_values->append(chart_month_info()); (*mi) = &monthly_values->back(); (*mi)->value = 0.0; (*mi)->count = 0.0; (*mi)->date = newdate; } } account_index = 0; while(true) { account = NULL; if(current_source == -2) { if(current_assets) { if(account_index > 0) break; else account = current_assets; } else { if(account_index < budget->assetsAccounts.size()) account = budget->assetsAccounts.at(account_index); if(account && account == budget->balancingAccount) { ++account_index; if(account_index < budget->assetsAccounts.size()) account = budget->assetsAccounts.at(account_index); } } } else if(current_source == 1 || second_run) { if(account_index < budget->incomesAccounts.size()) account = budget->incomesAccounts.at(account_index); } else { if(account_index < budget->expensesAccounts.size()) account = budget->expensesAccounts.at(account_index); } if(!account) break; QVector::iterator cmi_it = monthly_values->begin(); QVector::iterator cmi_itc = monthly_cats[account].begin(); while(cmi_it != monthly_values->end() && cmi_itc != monthly_cats[account].end()) { (*mi) = cmi_it; bool b_add = (current_source != -2 || (((AssetsAccount*) account)->accountType() != ASSETS_TYPE_LIABILITIES && (((AssetsAccount*) account)->accountType() != ASSETS_TYPE_CREDIT_CARD || cmi_itc->value > 0.0))); if(current_source != -2 || (b_add == second_run)) { if((!second_run && current_source == -1) || (!second_run && current_source == -2)) (*mi)->value -= cmi_itc->value; else (*mi)->value += cmi_itc->value; (*mi)->count += cmi_itc->count; if(current_source == -2) { if(!second_run && !b_liabilities) b_liabilities = (*mi)->value >= 0.01 || (*mi)->value <= -0.01; else if(second_run && !b_assets) b_assets = (*mi)->value >= 0.01 || (*mi)->value <= -0.01; } } ++cmi_it; ++cmi_itc; } ++account_index; } if(current_source != -1 || second_run) { QVector::iterator cmi_it = monthly_values->begin(); while(cmi_it != monthly_values->end()) { (*mi) = cmi_it; if((*mi)->value > maxvalue) maxvalue = (*mi)->value; else if((*mi)->value < minvalue) minvalue = (*mi)->value; if((*mi)->count > maxcount) maxcount = (*mi)->count; ++cmi_it; } } if(current_source > 0 || second_run) break; second_run = true; } switch(current_source) { case -2: {source_org = 0; break;} case -1: {source_org = 1; break;} case 0: {source_org = 0; break;} case 1: {source_org = 1; break;} case 2: {source_org = 2; break;} default: {} } if(source_org == 7 || source_org == 11 || source_org == -3) { int max_series = 7; QString r_desc_str; if(current_source == -3) { r_desc_str = tr("Other tags"); } if(current_source == 12 || current_source == 14 || ((b_expense || !b_income) && (current_source == 33 || current_source == 35))) { r_desc_str = tr("Other payees"); } else if(current_source == 11 || current_source == 13 || ((!b_expense || b_income) && (current_source == 33 || current_source == 35))) { r_desc_str = tr("Other payers"); } else if(current_source == 33 || current_source == 35) { r_desc_str = tr("Other payees/payers"); } else { r_desc_str = tr("Other descriptions", "Referring to the transaction description property (transaction title/generic article name)"); } desc_map[r_desc_str] = r_desc_str; monthly_desc[r_desc_str] = QVector(); monthly_values = &monthly_desc[r_desc_str]; monthly_values->append(chart_month_info()); (*mi) = &monthly_values->back(); (*mi)->value = 0.0; (*mi)->count = 0.0; if(type == 4) (*mi)->date = budget->lastBudgetDayOfYear(first_date); else (*mi)->date = budget->lastBudgetDay(first_date); while((*mi)->date < last_date) { QDate newdate = (*mi)->date; budget->addBudgetMonthsSetLast(newdate, type == 4 ? 12 : 1); monthly_values->append(chart_month_info()); (*mi) = &monthly_values->back(); (*mi)->value = 0.0; (*mi)->count = 0.0; (*mi)->date = newdate; } desc_i = first_desc_i; QString desc_str; while(desc_i < desc_nr) { if(source_org == 7) desc_str = descriptionCombo->itemText(desc_i).toLower(); else if(source_org == -3) desc_str = budget->tags[desc_i]; else desc_str = payeeCombo->itemText(desc_i).toLower(); desc_values[desc_str] = 0.0; for(QVector::iterator cmi_it = monthly_desc[desc_str].begin(); cmi_it != monthly_desc[desc_str].end(); ++cmi_it) { desc_values[desc_str] += abs(cmi_it->value); } bool b_added = false; if(desc_values[desc_str] >= 0.01 || desc_values[desc_str] <= -0.01) { int i = desc_order.size() - 1; b_added = true; while(i >= 0) { if(desc_values[desc_str] < desc_values[desc_order[i]]) { if(i == desc_order.size() - 1) { if(i < max_series - 1 || desc_nr - first_desc_i <= max_series) desc_order.push_back(desc_str); else b_added = false; } else { desc_order.insert(i + 1, desc_str); } break; } i--; } if(i < 0) desc_order.push_front(desc_str); if(desc_order.size() > max_series - 1 && desc_nr - first_desc_i > max_series) { QVector *monthly_values2 = &monthly_desc[desc_order.last()]; QVector::iterator it2 = monthly_values2->begin(); QVector::iterator it2_e = monthly_values2->end(); QVector::iterator it = monthly_values->begin(); QVector::iterator it_e = monthly_values->end(); while(it != it_e && it2 != it2_e) { it->value += it2->value; ++it; ++it2; } desc_order.pop_back(); } } if(!b_added) { QVector *monthly_values2 = &monthly_desc[desc_str]; QVector::iterator it2 = monthly_values2->begin(); QVector::iterator it2_e = monthly_values2->end(); QVector::iterator it = monthly_values->begin(); QVector::iterator it_e = monthly_values->end(); while(it != it_e && it2 != it2_e) { it->value += it2->value; ++it; ++it2; } } desc_i++; } if(desc_order.isEmpty() && desc_nr > 0) { desc_i = first_desc_i; while(desc_i < desc_nr && desc_i - first_desc_i < max_series - 1) { if(source_org == 7) desc_str = descriptionCombo->itemText(desc_i).toLower(); else if(source_org == -3) desc_str = budget->tags[desc_i]; else desc_str = payeeCombo->itemText(desc_i).toLower(); desc_order.push_back(desc_str); desc_i++; } } if(desc_nr - first_desc_i > desc_order.size()) { desc_order.push_back(r_desc_str); } maxvalue = 0.0; minvalue = 0.0; for(int i = 0; i < desc_order.size(); i++) { monthly_values = &monthly_desc[desc_order[i]]; QVector::iterator it = monthly_values->begin(); QVector::iterator it_e = monthly_values->end(); while(it != it_e) { if(it->value > maxvalue) maxvalue = it->value; else if(it->value < minvalue) minvalue = it->value; ++it; } } } if(source_org == -3) source_org = 11; if(source_org == -2) { int max_series = 7; monthly_cats[NULL] = QVector(); monthly_values = &monthly_cats[NULL]; monthly_values->append(chart_month_info()); (*mi) = &monthly_values->back(); (*mi)->value = 0.0; (*mi)->count = 0.0; if(type == 4) (*mi)->date = budget->lastBudgetDayOfYear(first_date); else (*mi)->date = budget->lastBudgetDay(first_date); while((*mi)->date < last_date) { QDate newdate = (*mi)->date; budget->addBudgetMonthsSetLast(newdate, type == 4 ? 12 : 1); monthly_values->append(chart_month_info()); (*mi) = &monthly_values->back(); (*mi)->value = 0.0; (*mi)->count = 0.0; (*mi)->date = newdate; } for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { AssetsAccount *account = *it; if(account != budget->balancingAccount) { cat_values[account] = 0.0; for(QVector::iterator cmi_it = monthly_cats[account].begin(); cmi_it != monthly_cats[account].end(); ++cmi_it) { cat_values[account] += abs(cmi_it->value); } bool b_added = false; if(cat_values[account] >= 0.01 || cat_values[account] <= -0.01) { int i = cat_order.size() - 1; b_added = true; while(i >= 0) { if(cat_values[account] < cat_values[cat_order[i]]) { if(i == cat_order.size() - 1) { if(i < max_series - 1 || accountCombo->count() - 2 <= max_series) cat_order.push_back(account); else b_added = false; } else { cat_order.insert(i + 1, account); } break; } i--; } if(i < 0) cat_order.push_front(account); if(cat_order.size() > max_series - 1 && accountCombo->count() - 2 > max_series) { QVector *monthly_values2 = &monthly_cats[cat_order.last()]; QVector::iterator it2 = monthly_values2->begin(); QVector::iterator it2_e = monthly_values2->end(); QVector::iterator it = monthly_values->begin(); QVector::iterator it_e = monthly_values->end(); while(it != it_e && it2 != it2_e) { it->value += it2->value; ++it; ++it2; } cat_order.pop_back(); } } if(!b_added) { QVector *monthly_values2 = &monthly_cats[account]; QVector::iterator it2 = monthly_values2->begin(); QVector::iterator it2_e = monthly_values2->end(); QVector::iterator it = monthly_values->begin(); QVector::iterator it_e = monthly_values->end(); while(it != it_e && it2 != it2_e) { it->value += it2->value; ++it; ++it2; } } } } if(cat_order.isEmpty() && accountCombo->count() - 2 > 0) { for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { AssetsAccount *account = *it; if(account != budget->balancingAccount) { cat_order.push_back(account); } } } if(accountCombo->count() - 2 > cat_order.size()) { cat_order.push_back(NULL); } maxvalue = 0.0; minvalue = 0.0; for(int i = 0; i < cat_order.size(); i++) { monthly_values = &monthly_cats[cat_order[i]]; QVector::iterator it = monthly_values->begin(); QVector::iterator it_e = monthly_values->end(); while(it != it_e) { if(it->value > maxvalue) maxvalue = it->value; else if(it->value < minvalue) minvalue = it->value; ++it; } } } if(source_org == 3 || source_org == 4 || source_org == 21) { account_index = 0; if(source_org == 3) {if(account_index < budget->incomesAccounts.size()) account = budget->incomesAccounts.at(account_index);} else if(source_org == 4) {if(account_index < budget->expensesAccounts.size()) account = budget->expensesAccounts.at(account_index);} else if(source_org == 21) {if(account_index < current_account->subCategories.size()) account = current_account->subCategories.at(account_index);} while(account) { while(exclude_subs && account && account->topAccount() != account) { ++account_index; account = NULL; if(source_org == 3 && account_index < budget->incomesAccounts.size()) account = budget->incomesAccounts.at(account_index); else if(source_org != 3 && account_index < budget->expensesAccounts.size()) account = budget->expensesAccounts.at(account_index); } if(exclude_subs && !account) break; cat_values[account] = 0.0; for(QVector::iterator cmi_it = monthly_cats[account].begin(); cmi_it != monthly_cats[account].end(); ++cmi_it) { cat_values[account] += abs(cmi_it->value); } bool b = false; for(int i = 0; i < cat_order.count(); i++) { if(cat_values[account] > cat_values[cat_order.at(i)]) { cat_order.insert(i, account); b = true; break; } } if(!b) cat_order.push_back(account); ++account_index; if(source_org == 3) { account = NULL; if(account_index < budget->incomesAccounts.size()) account = budget->incomesAccounts.at(account_index); } else if(source_org == 4) { account = NULL; if(account_index < budget->expensesAccounts.size()) account = budget->expensesAccounts.at(account_index); } else if(source_org == 21) { if(account == current_account) break; account = NULL; if(account_index < current_account->subCategories.size()) account = current_account->subCategories.at(account_index); if(!account) account = current_account; } } for(int i = 0; i < cat_order.count(); i++) { if(cat_values[cat_order.at(i)] >= 0.01 || cat_values[cat_order.at(i)] <= -0.01) { for(int i2 = 0; i2 < cat_order.count(); ) { if(cat_values[cat_order.at(i2)] < 0.01 && cat_values[cat_order.at(i2)] > -0.01) { cat_order.removeAt(i2); } else { i2++; } } break; } } source_org = -2; } QString axis_string; if(current_source2 == -2) { if(type == 2) axis_string = tr("Quantity"); else axis_string = tr("Value") + QString(" (%1)").arg(currency->symbol(true)); } else { int v_type = 3; if(current_source2 == -3 || current_source2 >= 27) { if(b_expense && !b_income) v_type = 3; else if(b_income && !b_expense) v_type = 2; else v_type = 0; } else if(current_source2 == 0 && chart_type != 4) { v_type = 0; } else if(current_source == -1) { v_type = 1; } else if(current_source2 % 2 == 1 || (current_source2 == 0 && chart_type == 4)) { v_type = 3; } switch(type) { case 1: { if(v_type == 0) axis_string = tr("Daily average value") + QString(" (%1)").arg(currency->symbol(true)); else if(v_type == 1) axis_string = tr("Daily average profit") + QString(" (%1)").arg(currency->symbol(true)); else if(v_type == 2) axis_string = tr("Daily average income") + QString(" (%1)").arg(currency->symbol(true)); else axis_string = tr("Daily average cost") + QString(" (%1)").arg(currency->symbol(true)); break; } case 2: { axis_string = tr("Quantity"); break; } case 3: { if(v_type == 0) axis_string = tr("Average value") + QString(" (%1)").arg(currency->symbol(true)); else if(v_type < 3) axis_string = tr("Average income") + QString(" (%1)").arg(currency->symbol(true)); else axis_string = tr("Average cost") + QString(" (%1)").arg(currency->symbol(true)); break; } case 4: { if(v_type == 0) axis_string = tr("Annual value") + QString(" (%1)").arg(currency->symbol(true)); else if(v_type == 1) axis_string = tr("Annual profit") + QString(" (%1)").arg(currency->symbol(true)); else if(v_type == 2) axis_string = tr("Annual income") + QString(" (%1)").arg(currency->symbol(true)); else axis_string = tr("Annual cost") + QString(" (%1)").arg(currency->symbol(true)); break; } default: { if(v_type == 0) axis_string = tr("Monthly value") + QString(" (%1)").arg(currency->symbol(true)); else if(v_type == 1) axis_string = tr("Monthly profit") + QString(" (%1)").arg(currency->symbol(true)); else if(v_type == 2) axis_string = tr("Monthly income") + QString(" (%1)").arg(currency->symbol(true)); else axis_string = tr("Monthly cost") + QString(" (%1)").arg(currency->symbol(true)); break; } } } #ifdef QT_CHARTS_LIB if(includes_budget && includes_scheduled) axis_string += QString("
    (*") + tr("Includes scheduled and budgeted transactions") + ")
    "; else if(includes_budget) axis_string += QString("
    (*") + tr("Includes budgeted transactions") + ")
    "; else if(includes_scheduled) axis_string += QString("
    (*") + tr("Includes scheduled transactions") + ")
    "; #endif if((current_source == 0 || (current_source == -2 && !current_assets)) && chart_type == 4 && type != 2) { QVector::iterator it_e = monthly_expenses.end(); for(QVector::iterator it = monthly_expenses.begin(); it != it_e; ++it) { it->value = -(it->value); if(it->value < minvalue) minvalue = it->value; else if(it->value > maxvalue) maxvalue = it->value; } } if(chart_type == 4) { QVector total_values; desc_i = 0; desc_nr = desc_order.size(); int cat_i = 0; int cat_nr = cat_order.size(); account = NULL; account_index = 0; if(source_org == 2) {monthly_values = &monthly_expenses;} else if(source_org == 1 || source_org == 0) {monthly_values = &monthly_incomes;} while((source_org < 3 && source_org != -2) || ((source_org == 7 || source_org == 11) && desc_i < desc_nr) || (source_org == -2 && cat_i < cat_nr)) { if(source_org == 7 || source_org == 11) {monthly_values = &monthly_desc[desc_order[desc_i]];} else if(source_org == -2) {monthly_values = &monthly_cats[cat_order[cat_i]];} int index = 0; QVector::iterator it_e = monthly_values->end(); for(QVector::iterator it = monthly_values->begin(); it != it_e; ++it) { if(index >= total_values.count()) total_values << it->value; else total_values[index] += it->value; index++; } if(source_org == 7 || source_org == 11) { desc_i++; } else if(source_org == 0 && monthly_values != &monthly_expenses) { monthly_values = &monthly_expenses; } else if(source_org == -2) { cat_i++; } else { break; } } for(int index = 0; index < total_values.count(); index++) { if(total_values[index] > maxvalue) maxvalue = total_values[index]; if(total_values[index] < minvalue) minvalue = total_values[index]; } } int months = budget->calendarMonthsBetweenDates(first_date, last_date, true) + 1; int years = budget->budgetYear(last_date) - budget->budgetYear(first_date); int n = 0; QDate monthdate = first_date; QDate curmonth; if(type == 4) curmonth = budget->lastBudgetDayOfYear(budget->monthToBudgetMonth(end_date)); else curmonth = budget->lastBudgetDay(budget->monthToBudgetMonth(end_date)); while(monthdate <= curmonth) { budget->addBudgetMonthsSetLast(monthdate, type == 4 ? 12 : 1); n++; } int y_lines = 5, y_minor = 0; calculate_minmax_lines(maxvalue, minvalue, y_lines, y_minor, current_source2 == -1 || (current_source2 == 0 && chart_type == 4 && type != 2), type != 2); switch((current_source2 >= 27 && b_income != b_expense) ? (b_income ? current_source2 - 22 : current_source2 - 21) : current_source2) { case -3: { if(b_income && !b_expense) { if(current_assets) title_string = tr("Incomes, %2: %1").arg(tr("Tags")).arg(current_assets->name()); else title_string = tr("Incomes: %1").arg(tr("Tags")); } else if(!b_income && b_expense) { if(current_assets) title_string = tr("Expenses, %2: %1").arg(tr("Tags")).arg(current_assets->name()); else title_string = tr("Expenses: %1").arg(tr("Tags")); } else { if(current_assets) title_string = tr("Tags, %1").arg(current_assets->name()); else title_string = tr("Tags"); } break; } case -2: { if(current_assets) title_string = tr("Value: %1").arg(current_assets->name()); else title_string = tr("Assets & Liabilities"); break; } case -1: { if(current_assets) title_string = tr("Incomes − Expenses, %1").arg(current_assets->name()); else if(current_source > 50) title_string = tr("Incomes − Expenses"); else title_string = tr("Profits"); if(!budget->securities.isEmpty() && (!current_assets || current_assets->accountType() == ASSETS_TYPE_SECURITIES)) note_string = tr("Excluding any profits or losses in trading of security shares", "Financial security (e.g. stock, mutual fund)"); break;} case 0: { if(current_assets) title_string = tr("Incomes & Expenses, %1").arg(current_assets->name()); else title_string = tr("Incomes & Expenses"); break; } case 3: case 1: { if(current_assets) title_string = tr("Incomes, %1").arg(current_assets->name()); else title_string = tr("Incomes"); break; } case 4: case 2: { if(current_assets) title_string = tr("Expenses, %1").arg(current_assets->name()); else title_string = tr("Expenses"); break; } case 21: case 11: case 7: case 5: { if(current_assets) title_string = tr("Incomes, %2: %1").arg(current_account ? current_account->nameWithParent() : current_tag).arg(current_assets->name()); else title_string = tr("Incomes: %1").arg(current_account ? current_account->nameWithParent() : current_tag); break; } case 22: case 12: case 8: case 6: { if(current_assets) title_string = tr("Expenses, %2: %1").arg(current_account ? current_account->nameWithParent() : current_tag).arg(current_assets->name()); else title_string = tr("Expenses: %1").arg(current_account ? current_account->nameWithParent() : current_tag); break; } case 33: case 29: case 27: { if(current_assets) title_string = tr("%2: %1").arg(current_tag).arg(current_assets->name()); else title_string = current_tag; break; } case 13: case 9: { if(current_assets) title_string = tr("Incomes, %3: %2, %1").arg(current_account ? current_account->nameWithParent() : current_tag).arg(current_description).arg(current_assets->name()); else title_string = tr("Incomes: %2, %1").arg(current_account ? current_account->nameWithParent() : current_tag).arg(current_description); break; } case 14: case 10: { if(current_assets) title_string = tr("Expenses, %3: %2, %1").arg(current_account ? current_account->nameWithParent() : current_tag).arg(current_description).arg(current_assets->name()); else title_string = tr("Expenses: %2, %1").arg(current_account ? current_account->nameWithParent() : current_tag).arg(current_description); break; } case 35: case 31: { if(current_assets) title_string = tr("%3: %2, %1").arg(current_tag).arg(current_description).arg(current_assets->name()); else title_string = tr("%2, %1").arg(current_tag).arg(current_description); break; } case 19: { if(current_assets) title_string = tr("Incomes, %4: %3, %2, %1").arg(current_account ? current_account->nameWithParent() : current_tag).arg(current_description).arg(current_payee.isEmpty() ? tr("No payer") : current_payee).arg(current_assets->name()); else title_string = tr("Incomes: %3, %2, %1").arg(current_account ? current_account->nameWithParent() : current_tag).arg(current_description).arg(current_payee.isEmpty() ? tr("No payer") : current_payee); break; } case 20: { if(current_assets) title_string = tr("Expenses, %4: %3, %2, %1").arg(current_account ? current_account->nameWithParent() : current_tag).arg(current_description).arg(current_payee.isEmpty() ? tr("No payee") : current_payee).arg(current_assets->name()); else title_string = tr("Expenses: %3, %2, %1").arg(current_account ? current_account->nameWithParent() : current_tag).arg(current_description).arg(current_payee.isEmpty() ? tr("No payee") : current_payee); break; } case 41: { if(current_assets) title_string = tr("%4: %3, %2, %1").arg(current_tag).arg(current_description).arg(current_payee.isEmpty() ? tr("No payee/payer") : current_payee).arg(current_assets->name()); else title_string = tr("%3, %2, %1").arg(current_tag).arg(current_description).arg(current_payee.isEmpty() ? tr("No payee/payer") : current_payee); break; } case 23: case 17: case 15: { if(current_assets) title_string = tr("Incomes, %3: %2, %1").arg(current_account ? current_account->nameWithParent() : current_tag).arg(current_payee.isEmpty() ? tr("No payer") : current_payee).arg(current_assets->name()); else title_string = tr("Incomes: %2, %1").arg(current_account ? current_account->nameWithParent() : current_tag).arg(current_payee.isEmpty() ? tr("No payer") : current_payee); break; } case 24: case 18: case 16: { if(current_assets) title_string = tr("Expenses, %3: %2, %1").arg(current_account ? current_account->nameWithParent() : current_tag).arg(current_payee.isEmpty() ? tr("No payee") : current_payee).arg(current_assets->name()); else title_string = tr("Expenses: %2, %1").arg(current_account ? current_account->nameWithParent() : current_tag).arg(current_payee.isEmpty() ? tr("No payee") : current_payee); break; } case 37: case 39: { if(current_assets) title_string = tr("%3: %2, %1").arg(current_tag).arg(current_payee.isEmpty() ? tr("No payee/payer") : current_payee).arg(current_assets->name()); else title_string = tr("%2, %1").arg(current_tag).arg(current_payee.isEmpty() ? tr("No payee/payer") : current_payee); break; } } #ifdef QT_CHARTS_LIB int theme = themeCombo->currentData().toInt(); bool show_legend; switch(current_source) { case -1: case 1: case 2: case 27: case 5: case 6: case 31: case 9: case 10: case 37: case 15: case 16: case 41: case 19: case 20: {show_legend = false; break;} default: show_legend = true; } chart->removeAllSeries(); int index = 0; account = NULL; desc_i = 0; desc_nr = desc_order.size(); int cat_i = 0; int cat_nr = cat_order.size(); if(axisX) chart->removeAxis(axisX); saved_last_date = last_date; saved_first_date = first_date; if(type == 4) last_date = budget->firstBudgetDayOfYear(last_date); else last_date = budget->firstBudgetDay(last_date); if(axisY) chart->removeAxis(axisY); axisY = new QValueAxis(); axisY->setTitleText(axis_string); QAbstractBarSeries *bar_series = NULL; if(chart_type == 1) { QCategoryAxis *c_axisX = new QCategoryAxis(); axisX = c_axisX; bool single_month = (first_date == last_date); QDate axis_date = first_date, displayed_date = first_date; if(type == 4 || months > 72) { int yearjump = years / 12 + 1; if(budget->budgetMonth(axis_date) > 1) { axis_date = budget->firstBudgetDayOfYear(axis_date); budget->addBudgetMonthsSetFirst(axis_date, 12); } last_date = last_date.addMonths(yearjump); if(budget->budgetMonth(last_date) <= yearjump + 1 && years % yearjump == 0) last_date = last_date.addMonths(yearjump + 2 - budget->budgetMonth(last_date)); c_axisX->setStartValue(DATE_TO_MSECS(axis_date)); c_axisX->setLabelsPosition(QCategoryAxis::AxisLabelsPositionOnValue); while(axis_date <= last_date) { QDate next_axis_date = axis_date; budget->addBudgetMonthsSetFirst(next_axis_date, 12 * yearjump); displayed_date = axis_date; if(current_source2 == -2) budget->addBudgetMonthsSetFirst(displayed_date, 1); if((includes_budget || includes_scheduled) && next_axis_date >= imonth) c_axisX->append(type != 4 ? budget->budgetDateToMonth(displayed_date).toString("yyyy*") : budget->budgetYearString(displayed_date, true) + "*", DATE_TO_MSECS(axis_date)); else c_axisX->append(type != 4 ? budget->budgetDateToMonth(displayed_date).toString("yyyy") : budget->budgetYearString(displayed_date, true), DATE_TO_MSECS(axis_date)); axis_date = next_axis_date; } } else { int monthjump = 1; if(months >= 48) monthjump = 6; else if(months >= 36) monthjump = 4; else if(months >= 24) monthjump = 3; else if(months >= 12) monthjump = 2; last_date = last_date.addDays(monthjump * 3); if(monthjump > 1) { int mod_m = (budget->budgetMonth(axis_date) % monthjump); if(mod_m == 0) budget->addBudgetMonthsSetFirst(axis_date, 1); else if(mod_m != 1) budget->addBudgetMonthsSetFirst(axis_date, monthjump - mod_m + 1); } c_axisX->setStartValue(DATE_TO_MSECS(axis_date)); c_axisX->setLabelsPosition(QCategoryAxis::AxisLabelsPositionOnValue); QString unique_s; bool month_shown = false; while(axis_date <= last_date) { QDate next_axis_date = axis_date; budget->addBudgetMonthsSetFirst(next_axis_date, monthjump); displayed_date = axis_date; if(current_source2 == -2) budget->addBudgetMonthsSetFirst(displayed_date, 1); if(budget->budgetMonth(axis_date) == 1) { if(month_shown) unique_s += " "; if((includes_budget || includes_scheduled) && next_axis_date > imonth) c_axisX->append(budget->budgetDateToMonth(displayed_date).toString("MMM*
    yyyy"), DATE_TO_MSECS(axis_date)); else c_axisX->append(budget->budgetDateToMonth(displayed_date).toString("MMM
    yyyy"), DATE_TO_MSECS(axis_date)); } else { if((includes_budget || includes_scheduled) && next_axis_date > imonth) c_axisX->append(budget->budgetDateToMonth(displayed_date).toString("MMM*%1").arg(unique_s), DATE_TO_MSECS(axis_date)); else c_axisX->append(budget->budgetDateToMonth(displayed_date).toString("MMM%1").arg(unique_s), DATE_TO_MSECS(axis_date)); } month_shown = true; axis_date = next_axis_date; } } if(single_month) c_axisX->setRange(DATE_TO_MSECS(first_date.addDays(-15)), DATE_TO_MSECS(last_date.addDays(12))); else c_axisX->setRange(DATE_TO_MSECS(first_date), DATE_TO_MSECS(last_date)); } else { QBarCategoryAxis *bc_axisX = new QBarCategoryAxis(); axisX = bc_axisX; QDate axis_date = first_date; if(chart_type == 3) axis_date = last_date; while(chart_type == 3 ? (axis_date >= first_date) : (axis_date <= last_date)) { QDate next_axis_date = axis_date; if(type == 4) { budget->addBudgetMonthsSetFirst(next_axis_date, chart_type == 3 ? -12 : 12); if((includes_budget || includes_scheduled) && next_axis_date > imonth) bc_axisX->append(type != 4 ? budget->budgetDateToMonth(axis_date).toString("yyyy*") : budget->budgetYearString(axis_date, true) + "*"); else bc_axisX->append(type != 4 ? budget->budgetDateToMonth(axis_date).toString("yyyy") : budget->budgetYearString(axis_date, true)); } else { budget->addBudgetMonthsSetFirst(next_axis_date, chart_type == 3 ? -1 : 1); if((includes_budget || includes_scheduled) && next_axis_date > imonth) bc_axisX->append(budget->budgetDateToMonth(axis_date).toString("MMMM*")); else bc_axisX->append(budget->budgetDateToMonth(axis_date).toString("MMMM")); } axis_date = next_axis_date; } if(chart_type == 2) bar_series = new QBarSeries(); else if(chart_type == 3) bar_series = new QHorizontalBarSeries(); else bar_series = new QStackedBarSeries(); } if(chart_type == 3) { chart->addAxis(axisY, Qt::AlignBottom); chart->addAxis(axisX, Qt::AlignLeft); } else { chart->addAxis(axisY, Qt::AlignLeft); chart->addAxis(axisX, Qt::AlignBottom); } chart->setLocalizeNumbers(type == 2 || budget->monetary_decimal_separator != "." || budget->monetary_decimal_separator == QLocale().decimalPoint() || ((maxvalue - minvalue) >= 50.0 && (budget->monetary_group_separator == QLocale().groupSeparator() || QLocale().groupSeparator() == ' ' || QLocale().groupSeparator() == QChar(0x202F) || QLocale().groupSeparator() == QChar(0x2009)))); axisY->setRange(minvalue, maxvalue); axisY->setTickCount(y_lines + 1); axisY->setMinorTickCount(chart_type == 3 ? 0 : y_minor); if(type == 2 || (maxvalue - minvalue) >= 50.0) axisY->setLabelFormat(QString("%.0f")); else axisY->setLabelFormat(QString("%.%1f").arg(QString::number(currency->fractionalDigits()))); if(source_org == 2) {monthly_values = &monthly_expenses;} else if(source_org == 1 || source_org == 0) {monthly_values = &monthly_incomes;} while((source_org < 3 && source_org != -2) || ((source_org == 7 || source_org == 11) && desc_i < desc_nr) || (source_org == -2 && cat_i < cat_nr)) { if(source_org == 7 || source_org == 11) {monthly_values = &monthly_desc[desc_order[desc_i]];} else if(source_org == -2) {monthly_values = &monthly_cats[cat_order[cat_i]];} QString series_name; switch((current_source > 27 && current_source < 50 && b_income != b_expense) ? (b_income ? current_source - 22 : current_source - 21) : current_source) { case -2: { if(index == 0) series_name = tr("Assets"); else series_name = tr("Liabilities"); break; } case -1: { if(current_assets) series_name = tr("Incomes − Expenses"); else series_name = tr("Profits"); break; } case 0: { if(index == 0) series_name = tr("Incomes"); else if(index == 1) series_name = tr("Expenses"); break; } case 1: {series_name = tr("Incomes"); break;} case 2: {series_name = tr("Expenses"); break;} case 3: {} case 4: {series_name = cat_order[cat_i]->nameWithParent(); break;} case 21: {} case 22: {series_name = cat_order[cat_i]->name(); break;} case 23: { series_name = tr("%1/%2", "%1: Category; %2: Payee/Payer").arg(cat_order[cat_i]->name()).arg(current_payee.isEmpty() ? tr("No payer") : current_payee); break; } case 24: { series_name = tr("%1/%2", "%1: Category; %2: Payee/Payer").arg(cat_order[cat_i]->name()).arg(current_payee.isEmpty() ? tr("No payee") : current_payee); break; } case 27: {series_name = current_tag; break;} case 5: {} case 6: {series_name = current_account->nameWithParent(); break;} case -3: {} case 39: {} case 17: {} case 18: {} case 29: {} case 7: {} case 8: { if(desc_order[desc_i].isEmpty()) series_name = tr("No description", "Referring to the transaction description property (transaction title/generic article name)"); else series_name = desc_map[desc_order[desc_i]]; break; } case 31: {} case 9: {} case 10: { if(current_description.isEmpty()) series_name = tr("No description", "Referring to the transaction description property (transaction title/generic article name)"); else series_name = current_description; break; } case 13: {} case 11: { if(desc_order[desc_i].isEmpty()) series_name = tr("No payer"); else series_name = desc_map[desc_order[desc_i]]; break; } case 35: {} case 33: { if(desc_order[desc_i].isEmpty()) series_name = tr("No payee/payer"); else series_name = desc_map[desc_order[desc_i]]; break; } case 14: {} case 12: { if(desc_order[desc_i].isEmpty()) series_name = tr("No payee"); else series_name = desc_map[desc_order[desc_i]]; break; } case 15: { if(current_payee.isEmpty()) series_name = tr("No payer"); else series_name = current_payee; break; } case 37: { if(current_payee.isEmpty()) series_name = tr("No payee/payer"); else series_name = current_payee; break; } case 16: { if(current_payee.isEmpty()) series_name = tr("No payee"); else series_name = current_payee; break; } case 41: { QString str1, str2; if(current_payee.isEmpty() && current_description.isEmpty()) {str1 = tr("No description", "Referring to the transaction description property (transaction title/generic article name)"); str2 = tr("No payee/payer");} else if(current_payee.isEmpty()) {str1 = current_description; str2 = tr("No payee/payer");} else if(current_description.isEmpty()) {str1 = tr("No description", "Referring to the transaction description property (transaction title/generic article name)"); str2 = current_payee;} else {str1 = current_description; str2 = current_payee;} series_name = tr("%1/%2", "%1: Description; %2: Payee/Payer").arg(str1).arg(str2); break; } case 19: { QString str1, str2; if(current_payee.isEmpty() && current_description.isEmpty()) {str1 = tr("No description", "Referring to the transaction description property (transaction title/generic article name)"); str2 = tr("No payer");} else if(current_payee.isEmpty()) {str1 = current_description; str2 = tr("No payer");} else if(current_description.isEmpty()) {str1 = tr("No description", "Referring to the transaction description property (transaction title/generic article name)"); str2 = current_payee;} else {str1 = current_description; str2 = current_payee;} series_name = tr("%1/%2", "%1: Description; %2: Payee/Payer").arg(str1).arg(str2); break; } case 20: { QString str1, str2; if(current_payee.isEmpty() && current_description.isEmpty()) {str1 = tr("No description", "Referring to the transaction description property (transaction title/generic article name)"); str2 = tr("No payee");} else if(current_payee.isEmpty()) {str1 = current_description; str2 = tr("No payee");} else if(current_description.isEmpty()) {str1 = tr("No description", "Referring to the transaction description property (transaction title/generic article name)"); str2 = current_payee;} else {str1 = current_description; str2 = current_payee;} series_name = tr("%1/%2", "%1: Description; %2: Payee/Payer").arg(str1).arg(str2); break; } } if(current_source > 50) { if(!cat_order[cat_i]) series_name = tr("Other accounts"); else series_name = cat_order[cat_i]->name(); } n = 1; if(source_org == 7 || source_org == 11) { n = desc_order.count(); } else if(source_org == 0) { n = 2; } else if(source_org == -2) { n = cat_order.count(); } if(current_source2 != -2 || !current_assets || (index == 0 && b_assets) || (index == 1 && b_liabilities) || (!b_liabilities && !b_assets)) { if(chart_type == 1) { QXYSeries *series; if(monthly_values->count() == 1) series = new QScatterSeries(); else series = new QLineSeries(); series->setName(series_name); QVector::iterator it_e = monthly_values->end(); for(QVector::iterator it = monthly_values->begin(); it != it_e; ++it) { QDate date; if(type == 4) date = budget->firstBudgetDayOfYear(it->date); else date = budget->firstBudgetDay(it->date); series->append(DATE_TO_MSECS(date), it->value); } chart->addSeries(series); series->attachAxis(axisY); series->attachAxis(axisX); if(theme < 0) { QPen pen = getLinePen(index); series->setPen(pen); series->setBrush(pen.brush()); if(index >= 8) { QList markers = chart->legend()->markers(series); if(markers.count() > 0) { pen.setWidth(2); markers[0]->setPen(pen); markers[0]->setBrush(QColor(0, 0, 0, 0)); } } } else if(index >= 5) { QPen pen = series->pen(); if(index >= 15) pen.setStyle(Qt::DashDotDotLine); else if(index >= 10) pen.setStyle(Qt::DashLine); else pen.setStyle(Qt::DotLine); series->setPen(pen); QList markers = chart->legend()->markers(series); if(markers.count() > 0) { pen.setWidth(2); markers[0]->setPen(pen); markers[0]->setBrush(QColor(0, 0, 0, 0)); } } connect(series, SIGNAL(hovered(const QPointF&, bool)), this, SLOT(onSeriesHovered(const QPointF&, bool))); } else { QBarSet *bar_set = new QBarSet(series_name); if(theme < 0) { bar_set->setBrush(getBarBrush(index, n)); } if(chart_type == 3) { for(int i = monthly_values->size() - 1; i >= 0; i--) { bar_set->append(monthly_values->at(i).value); } } else { QVector::iterator it_e = monthly_values->end(); for(QVector::iterator it = monthly_values->begin(); it != it_e; ++it) { bar_set->append(it->value); } } bar_series->append(bar_set); } } index++; if(source_org == 7 || source_org == 11) { desc_i++; } else if(source_org == 0 && monthly_values != &monthly_expenses) { monthly_values = &monthly_expenses; } else if(source_org == -2) { cat_i++; } else { break; } } if(theme < 0) { axisX->setLinePen(QPen(Qt::darkGray, 1)); axisX->setLabelsColor(Qt::black); axisY->setLinePen(QPen(Qt::darkGray, 1)); axisY->setLabelsColor(Qt::black); chart->setBackgroundBrush(Qt::white); chart->setTitleBrush(Qt::black); chart->setPlotAreaBackgroundVisible(false); axisX->setTitleBrush(Qt::black); axisY->setTitleBrush(Qt::black); axisX->setGridLineVisible(false); axisY->setGridLinePen(QPen(Qt::darkGray, 1, Qt::DotLine)); axisY->setMinorGridLineVisible(false); axisX->setMinorGridLineVisible(false); axisX->setShadesVisible(false); axisY->setShadesVisible(false); chart->legend()->setBackgroundVisible(false); chart->legend()->setColor(Qt::white); chart->legend()->setLabelColor(Qt::black); } else if(chart_type == 1) { axisX->setGridLineVisible(false); } if(chart_type != 1) { chart->addSeries(bar_series); bar_series->attachAxis(axisY); bar_series->attachAxis(axisX); bar_series->setBarWidth((n <= 4 || chart_type == 4) ? (2.0 / 3.0) : 0.9); connect(bar_series, SIGNAL(hovered(bool, int, QBarSet*)), this, SLOT(onSeriesHovered(bool, int, QBarSet*))); } foreach(QLegendMarker* marker, chart->legend()->markers()) { connect(marker, SIGNAL(clicked()), this, SLOT(legendClicked())); } if(note_string.isEmpty()) chart->setTitle(QString("
    %1
    ").arg(title_string)); else chart->setTitle(QString("
    %1
    (%2)
    ").arg(title_string).arg(note_string)); if(show_legend) { #if (QT_CHARTS_VERSION >= QT_CHARTS_VERSION_CHECK(5, 7, 0)) chart->legend()->setShowToolTips(true); #endif chart->legend()->setAlignment(Qt::AlignBottom); chart->legend()->show(); } else { chart->legend()->hide(); } #else QGraphicsScene *oldscene = scene; scene = new QGraphicsScene(this); scene->setBackgroundBrush(Qt::white); QFont legend_font = font(); QFontMetrics fm(legend_font); int fh = fm.height(); int margin = 15 + fh; QGraphicsTextItem *title_text = new QGraphicsTextItem(); if(note_string.isEmpty()) title_text->setHtml(QString("
    %1
    ").arg(title_string)); else title_text->setHtml(QString("
    %1
    (%2)
    ").arg(title_string).arg(note_string)); title_text->setDefaultTextColor(Qt::black); title_text->setFont(legend_font); title_text->setPos(view->width() / 2 - title_text->boundingRect().width() / 2, margin); scene->addItem(title_text); QVector legend_texts; int text_width = 0; int index = 0; int lcount = 0; account = NULL; desc_i = 0; desc_nr = desc_order.size(); int cat_i = 0; int cat_nr = cat_order.size(); if(source_org == 2) {monthly_values = &monthly_expenses;} else if(source_org == 1 || source_org == 0) {monthly_values = &monthly_incomes;} while((source_org < 3 && source_org != -2) || ((source_org == 7 || source_org == 11) && desc_i < desc_nr) || (source_org == -2 && cat_i < cat_nr)) { if(source_org == 7 || source_org == 11) {monthly_values = &monthly_desc[desc_order[desc_i]];} else if(source_org == -2) {monthly_values = &monthly_cats[cat_order[cat_i]];} if(current_source2 != -2 || !current_assets || (index == 0 && b_assets) || (index == 1 && b_liabilities) || (!b_liabilities && !b_assets)) { QGraphicsSimpleTextItem *legend_text = new QGraphicsSimpleTextItem(); switch((current_source > 27 && current_source < 50 && b_income != b_expense) ? (b_income ? current_source - 22 : current_source - 21) : current_source) { case -2: { if(index == 0) legend_text->setText(tr("Assets")); else legend_text->setText(tr("Liabilities")); break; } case -1: { if(current_assets) legend_text->setText(tr("Incomes − Expenses")); else legend_text->setText(tr("Profits")); break; } case 0: { if(index == 0) legend_text->setText(tr("Incomes")); else if(index == 1) legend_text->setText(tr("Expenses")); break; } case 1: {legend_text->setText(tr("Incomes")); break;} case 2: {legend_text->setText(tr("Expenses")); break;} case 3: {} case 4: {legend_text->setText(cat_order[cat_i]->nameWithParent()); break;} case 21: {} case 22: {legend_text->setText(cat_order[cat_i]->name()); break;} case 23: { legend_text->setText(tr("%1/%2", "%1: Category; %2: Payee/Payer").arg(cat_order[cat_i]->name()).arg(current_payee.isEmpty() ? tr("No payer") : current_payee)); break; } case 24: { legend_text->setText(tr("%1/%2", "%1: Category; %2: Payee/Payer").arg(cat_order[cat_i]->name()).arg(current_payee.isEmpty() ? tr("No payee") : current_payee)); break; } case 27: {legend_text->setText(current_tag); break;} case 5: {} case 6: {legend_text->setText(current_account->nameWithParent()); break;} case -3: {} case 39: {} case 29: {} case 17: {} case 18: {} case 7: {} case 8: { if(desc_order[desc_i].isEmpty()) legend_text->setText(tr("No description", "Referring to the transaction description property (transaction title/generic article name)")); else legend_text->setText(desc_order[desc_i]); break; } case 31: {} case 9: {} case 10: { if(current_description.isEmpty()) legend_text->setText(tr("No description", "Referring to the transaction description property (transaction title/generic article name)")); else legend_text->setText(current_description); break; } case 13: {} case 11: { if(desc_order[desc_i].isEmpty()) legend_text->setText(tr("No payer")); else legend_text->setText(desc_map[desc_order[desc_i]]); break; } case 35: {} case 33: { if(desc_order[desc_i].isEmpty()) legend_text->setText(tr("No payee/payer")); else legend_text->setText(desc_map[desc_order[desc_i]]); break; } case 14: {} case 12: { if(desc_order[desc_i].isEmpty()) legend_text->setText(tr("No payee")); else legend_text->setText(desc_map[desc_order[desc_i]]); break; } case 37: { if(current_payee.isEmpty()) legend_text->setText(tr("No payee/payer")); else legend_text->setText(current_payee); break; } case 15: { if(current_payee.isEmpty()) legend_text->setText(tr("No payer")); else legend_text->setText(current_payee); break; } case 16: { if(current_payee.isEmpty()) legend_text->setText(tr("No payee")); else legend_text->setText(current_payee); break; } case 41: { QString str1, str2; if(current_payee.isEmpty() && current_description.isEmpty()) {str1 = tr("No description", "Referring to the transaction description property (transaction title/generic article name)"); str2 = tr("No payee/payer");} else if(current_payee.isEmpty()) {str1 = current_description; str2 = tr("No payee/payer");} else if(current_description.isEmpty()) {str1 = tr("No description", "Referring to the transaction description property (transaction title/generic article name)"); str2 = current_payee;} else {str1 = current_description; str2 = current_payee;} legend_text->setText(tr("%1/%2", "%1: Description; %2: Payee/Payer").arg(str1).arg(str2)); break; } case 19: { QString str1, str2; if(current_payee.isEmpty() && current_description.isEmpty()) {str1 = tr("No description", "Referring to the transaction description property (transaction title/generic article name)"); str2 = tr("No payer");} else if(current_payee.isEmpty()) {str1 = current_description; str2 = tr("No payer");} else if(current_description.isEmpty()) {str1 = tr("No description", "Referring to the transaction description property (transaction title/generic article name)"); str2 = current_payee;} else {str1 = current_description; str2 = current_payee;} legend_text->setText(tr("%1/%2", "%1: Description; %2: Payee/Payer").arg(str1).arg(str2)); break; } case 20: { QString str1, str2; if(current_payee.isEmpty() && current_description.isEmpty()) {str1 = tr("No description", "Referring to the transaction description property (transaction title/generic article name)"); str2 = tr("No payee");} else if(current_payee.isEmpty()) {str1 = current_description; str2 = tr("No payee");} else if(current_description.isEmpty()) {str1 = tr("No description", "Referring to the transaction description property (transaction title/generic article name)"); str2 = current_payee;} else {str1 = current_description; str2 = current_payee;} legend_text->setText(tr("%1/%2", "%1: Description; %2: Payee/Payer").arg(str1).arg(str2)); break; } } if(current_source > 50) { if(!cat_order[cat_i]) legend_text->setText(tr("Other accounts")); else legend_text->setText(cat_order[cat_i]->name()); } legend_text->setFont(legend_font); legend_text->setBrush(Qt::black); if(legend_text->boundingRect().width() > text_width) text_width = legend_text->boundingRect().width(); legend_texts << legend_text; lcount++; } index++; if(source_org == 7 || source_org == 11) { desc_i++; } else if(source_org == 0 && monthly_values != &monthly_expenses) { monthly_values = &monthly_expenses; } else if(source_org == -2) { cat_i++; } else { break; } } int chart_y = margin * 2 + 15 + title_text->boundingRect().height(); int chart_height = view->height() - chart_y - margin; int axis_width = 11; int linelength = (int) ceil((view->width() - margin * 3 - axis_width - 50 - fh - text_width) / n); int chart_width = linelength * n; int max_axis_value_width = 0; for(int i = 0; i <= y_lines; i++) { int w; if(type == 2) w = fm.boundingRect(budget->formatValue((int) round(maxvalue - (((maxvalue - minvalue) * i) / y_lines)), 0)).width(); else if (maxvalue - minvalue >= 50.0) w = fm.boundingRect(currency->formatValue(round(maxvalue - (((maxvalue - minvalue) * i) / y_lines)), 0, false)).width(); else w = fm.boundingRect(currency->formatValue((maxvalue - (((maxvalue - minvalue) * i) / y_lines)), -1, false)).width(); if(w > max_axis_value_width) max_axis_value_width = w; } axis_width += max_axis_value_width; QGraphicsSimpleTextItem *axis_text = new QGraphicsSimpleTextItem(); QString axis_string2; if(includes_budget && includes_scheduled) axis_string2 += QString(" *") + tr("Includes scheduled and budgeted transactions"); else if(includes_budget) axis_string2 += QString(" *") + tr("Includes budgeted transactions"); else if(includes_scheduled) axis_string2 += QString(" *") + tr("Includes scheduled transactions"); axis_text->setText(axis_string); axis_text->setFont(legend_font); axis_text->setBrush(Qt::black); if(axis_text->boundingRect().width() / 2 > max_axis_value_width) max_axis_value_width = axis_text->boundingRect().width() / 2; axis_text->setPos(margin + axis_width - axis_text->boundingRect().width() / 2, chart_y - 15 - fh); scene->addItem(axis_text); if(!axis_string2.isEmpty()) { QGraphicsSimpleTextItem *axis_text2 = new QGraphicsSimpleTextItem(axis_string2); axis_text->setFont(legend_font); axis_text2->setBrush(Qt::black); axis_text2->setScale(0.8); axis_text2->setPos(margin + axis_width + axis_text->boundingRect().width() / 2, chart_y - 15 - fh); scene->addItem(axis_text2); } QPen axis_pen; axis_pen.setColor(Qt::black); axis_pen.setWidth(1); axis_pen.setStyle(Qt::SolidLine); QGraphicsLineItem *y_axis = new QGraphicsLineItem(); y_axis->setLine(margin + axis_width, chart_y - 12, margin + axis_width, chart_height + chart_y); y_axis->setPen(axis_pen); scene->addItem(y_axis); QGraphicsLineItem *y_axis_dir1 = new QGraphicsLineItem(); y_axis_dir1->setLine(margin + axis_width, chart_y - 12, margin + axis_width - 3, chart_y - 6); y_axis_dir1->setPen(axis_pen); scene->addItem(y_axis_dir1); QGraphicsLineItem *y_axis_dir2 = new QGraphicsLineItem(); y_axis_dir2->setLine(margin + axis_width, chart_y - 12, margin + axis_width + 3, chart_y - 6); y_axis_dir2->setPen(axis_pen); scene->addItem(y_axis_dir2); QGraphicsLineItem *x_axis = new QGraphicsLineItem(); x_axis->setLine(margin + axis_width, chart_height + chart_y, margin + chart_width + axis_width + 12, chart_height + chart_y); x_axis->setPen(axis_pen); scene->addItem(x_axis); QGraphicsLineItem *x_axis_dir1 = new QGraphicsLineItem(); x_axis_dir1->setLine(margin + chart_width + axis_width + 6, chart_height + chart_y - 3, margin + chart_width + axis_width + 12, chart_height + chart_y); x_axis_dir1->setPen(axis_pen); scene->addItem(x_axis_dir1); QGraphicsLineItem *x_axis_dir2 = new QGraphicsLineItem(); x_axis_dir2->setLine(margin + chart_width + axis_width + 6, chart_height + chart_y + 3, margin + chart_width + axis_width + 12, chart_height + chart_y); x_axis_dir2->setPen(axis_pen); scene->addItem(x_axis_dir2); axis_text = new QGraphicsSimpleTextItem(tr("Time")); axis_text->setFont(legend_font); axis_text->setBrush(Qt::black); axis_text->setPos(margin + chart_width + axis_width + 15, chart_y + chart_height - fh / 2); scene->addItem(axis_text); int x_axis_extra_width = 15 + axis_text->boundingRect().width(); QPen div_pen; div_pen.setColor(Qt::darkGray); div_pen.setWidth(1); div_pen.setStyle(Qt::DotLine); double div_height = (double) chart_height / (double) y_lines; for(int i = 0; i < y_lines; i++) { QGraphicsLineItem *y_div = new QGraphicsLineItem(); y_div->setLine(margin + axis_width, chart_y + i * div_height, margin + chart_width + axis_width, chart_y + i * div_height); y_div->setPen(div_pen); scene->addItem(y_div); QGraphicsLineItem *y_mark = new QGraphicsLineItem(); y_mark->setLine(margin + axis_width - 10, chart_y + i * div_height, margin + axis_width, chart_y + i * div_height); y_mark->setPen(axis_pen); scene->addItem(y_mark); axis_text = new QGraphicsSimpleTextItem(); if(type == 2) axis_text->setText(budget->formatValue((int) round(maxvalue - (((maxvalue - minvalue) * i) / y_lines)), 0)); else if((maxvalue - minvalue) >= 50.0) axis_text->setText(currency->formatValue(round(maxvalue - (((maxvalue - minvalue) * i) / y_lines)), 0, false)); else axis_text->setText(currency->formatValue((maxvalue - (((maxvalue - minvalue) * i) / y_lines)), -1, false)); axis_text->setFont(legend_font); axis_text->setBrush(Qt::black); axis_text->setPos(margin + axis_width - axis_text->boundingRect().width() - 11, chart_y + i * div_height - fh / 2); scene->addItem(axis_text); } axis_text = new QGraphicsSimpleTextItem(); if(minvalue != 0.0) { if(type == 2) axis_text->setText(budget->formatValue((int) round(minvalue), 0)); else if((maxvalue - minvalue) >= 50.0) axis_text->setText(currency->formatValue(round(minvalue), 0, false)); else axis_text->setText(currency->formatValue(minvalue, -1, false)); } else { if(type == 2) axis_text->setText(budget->formatValue(0, 0)); else axis_text->setText(currency->formatValue(0.0, 0, false)); } axis_text->setFont(legend_font); axis_text->setBrush(Qt::black); axis_text->setPos(margin + axis_width - axis_text->boundingRect().width() - 11, chart_y + chart_height - fh / 2); scene->addItem(axis_text); index = 0; int year = first_date.year() - 1; bool b_month_names = months <= 12 && type != 4, b_long_month_names = true; if(b_month_names) { monthdate = first_date; while(monthdate <= curmonth) { if(b_long_month_names) { if(fm.boundingRect(QLocale().monthName(budget->budgetMonth(monthdate), QLocale::LongFormat)).width() > linelength - 8) { b_long_month_names = false; } } if(!b_long_month_names) { if(fm.boundingRect(QLocale().monthName(budget->budgetMonth(monthdate), QLocale::ShortFormat)).width() > linelength) { b_month_names = false; break; } } budget->addBudgetMonthsSetFirst(monthdate, 1); } } monthdate = first_date; QDate next_date = monthdate; while(monthdate <= curmonth) { if(years < 5 || year != budget->budgetYear(monthdate)) { QGraphicsLineItem *x_mark = new QGraphicsLineItem(); x_mark->setLine(margin + axis_width + index * linelength, chart_height + chart_y, margin + axis_width + index * linelength, chart_height + chart_y + 10); x_mark->setPen(axis_pen); scene->addItem(x_mark); } if(next_date == monthdate) { budget->addBudgetMonthsSetFirst(next_date, type == 4 ? 12 : 1); if(type != 4 && !b_month_names) { while(budget->budgetYear(monthdate) == budget->budgetYear(next_date)) budget->addBudgetMonthsSetFirst(next_date, 1); } } if(b_month_names) { QGraphicsSimpleTextItem *axis_text = new QGraphicsSimpleTextItem(); if((includes_budget || includes_scheduled) && next_date > imonth) axis_text->setText(QLocale().monthName(budget->budgetMonth(monthdate), b_long_month_names ? QLocale::LongFormat : QLocale::ShortFormat) + "*"); else axis_text->setText(QLocale().monthName(budget->budgetMonth(monthdate), b_long_month_names ? QLocale::LongFormat : QLocale::ShortFormat)); axis_text->setFont(legend_font); axis_text->setBrush(Qt::black); axis_text->setPos(margin + axis_width + index * linelength + (linelength - axis_text->boundingRect().width()) / 2, chart_height + chart_y + 11); scene->addItem(axis_text); } else if(year != budget->budgetYear(monthdate) || type == 4) { year = budget->budgetYear(monthdate); QGraphicsSimpleTextItem *axis_text = new QGraphicsSimpleTextItem(); if((includes_budget || includes_scheduled) && next_date > imonth) axis_text->setText(type == 4 ? budget->budgetYearString(monthdate, true) + "*" : QString::number(budget->budgetYear(monthdate)) + "*"); else axis_text->setText(type == 4 ? budget->budgetYearString(monthdate, true) : QString::number(budget->budgetYear(monthdate))); axis_text->setFont(legend_font); axis_text->setBrush(Qt::black); axis_text->setPos(margin + axis_width + index * linelength, chart_height + chart_y + 11); scene->addItem(axis_text); } budget->addBudgetMonthsSetFirst(monthdate, type == 4 ? 12 : 1); index++; } QGraphicsLineItem *x_mark = new QGraphicsLineItem(); x_mark->setLine(margin + axis_width + index * linelength, chart_height + chart_y, margin + axis_width + index * linelength, chart_height + chart_y + 10); x_mark->setPen(axis_pen); scene->addItem(x_mark); int line_y = chart_height + chart_y; int line_x = margin + axis_width; int legend_x = chart_width + axis_width + margin + x_axis_extra_width + 10; int legend_y = chart_y; index = 0; lcount = 0; account = NULL; desc_i = 0; desc_nr = desc_order.size(); cat_i = 0; cat_nr = cat_order.size(); if(source_org == 2) {monthly_values = &monthly_expenses;} else if(source_org == 1 || source_org == 0) {monthly_values = &monthly_incomes;} while((source_org < 3 && source_org != -2) || ((source_org == 7 || source_org == 11) && desc_i < desc_nr) || (source_org == -2 && cat_i < cat_nr)) { if(source_org == 7 || source_org == 11) {monthly_values = &monthly_desc[desc_order[desc_i]];} else if(source_org == -2) {monthly_values = &monthly_cats[cat_order[cat_i]];} if(current_source2 != -2 || !current_assets || (index == 0 && b_assets) || (index == 1 && b_liabilities) || (!b_liabilities && !b_assets)) { int prev_y = 0; int index2 = 0; QVector::iterator it_e = monthly_values->end(); for(QVector::iterator it = monthly_values->begin(); it != it_e; ++it) { if(index2 == 0) { prev_y = (int) floor((chart_height * (it->value - minvalue)) / (maxvalue - minvalue)) + 1; if(n == 1) { QGraphicsEllipseItem *dot = new QGraphicsEllipseItem(-2.5, -2.5, 5, 5); dot->setPos(line_x + linelength / 2, line_y - prev_y); QBrush brush(getLineColor(lcount)); dot->setBrush(brush); dot->setZValue(10); scene->addItem(dot); } } else { int next_y = (int) floor((chart_height * (it->value - minvalue)) / (maxvalue - minvalue)) + 1; QGraphicsLineItem *line = new QGraphicsLineItem(); line->setPen(getLinePen(lcount)); line->setLine(line_x + ((index2 - 1) * linelength) + linelength / 2, line_y - prev_y, line_x + (index2 * linelength) + linelength / 2, line_y - next_y); line->setZValue(10); prev_y = next_y; scene->addItem(line); } index2++; } QGraphicsLineItem *legend_line = new QGraphicsLineItem(); legend_line->setLine(legend_x, legend_y + (fh + 5) * lcount + fh / 2, legend_x + fh, legend_y + (fh + 5) * lcount + fh / 2); legend_line->setPen(getLinePen(lcount)); scene->addItem(legend_line); legend_texts[lcount]->setPos(legend_x + fh + 5, legend_y + (fh + 5) * lcount); scene->addItem(legend_texts[lcount]); lcount++; } index++; if(source_org == 7 || source_org == 11) { desc_i++; } else if(source_org == 0 && monthly_values != &monthly_expenses) { monthly_values = &monthly_expenses; } else if(source_org == -2) { cat_i++; } else { break; } } QRectF rect = scene->sceneRect(); rect.setX(0); rect.setY(0); rect.setRight(rect.right() + 20); rect.setBottom(rect.bottom() + 20); scene->setSceneRect(rect); scene->update(); view->setScene(scene); view->fitInView(scene->sceneRect(), Qt::KeepAspectRatio); if(oldscene) { delete oldscene; } #endif if(current_source == 7 || current_source == 8 || current_source == 17 || current_source == 18 || current_source == 29 || current_source == 39) { if(has_empty_description) descriptionCombo->setItemText(descriptionCombo->count() - 1, tr("No description", "Referring to the transaction description property (transaction title/generic article name)")); } else if(current_source == 12 || current_source == 14 || ((b_expense || !b_income) && (current_source == 33 || current_source == 35))) { if(has_empty_payee) payeeCombo->setItemText(payeeCombo->count() - 1, tr("No payee")); } else if(current_source == 11 || current_source == 13 || current_source == 33 || current_source == 35) { if(has_empty_payee) payeeCombo->setItemText(payeeCombo->count() - 1, tr("No payer")); } } #ifndef QT_CHARTS_LIB void OverTimeChart::resizeEvent(QResizeEvent *e) { QWidget::resizeEvent(e); if(scene) { view->fitInView(scene->sceneRect(), Qt::KeepAspectRatio); } } #endif void OverTimeChart::updateTransactions() { if(descriptionCombo->isEnabled() && (current_account || !current_tag.isEmpty())) { bool b_tags = !current_account; bool b_income = current_account && (current_account->type() == ACCOUNT_TYPE_INCOMES); int curindex = descriptionCombo->currentIndex(); if(curindex > 1) { curindex = -1; } int curindex_p = 0; if(b_extra) { curindex_p = payeeCombo->currentIndex(); if(curindex_p > 1) { curindex_p = -1; } } descriptionCombo->blockSignals(true); descriptionCombo->clear(); descriptionCombo->addItem(tr("All Descriptions Combined", "Referring to the transaction description property (transaction title/generic article name)")); descriptionCombo->addItem(tr("All Descriptions Split", "Referring to the transaction description property (transaction title/generic article name)")); has_empty_description = false; has_empty_payee = false; QMap descriptions, payees; bool had_income = false, had_expense = false; for(TransactionList::const_iterator it = budget->transactions.constEnd(); it != budget->transactions.constBegin();) { --it; Transaction *trans = *it; if((b_tags && trans->hasTag(current_tag, true)) || (!b_tags && (trans->fromAccount() == current_account || trans->toAccount() == current_account || trans->fromAccount()->topAccount() == current_account || trans->toAccount()->topAccount() == current_account))) { if(trans->description().isEmpty()) has_empty_description = true; else if(!descriptions.contains(trans->description().toLower())) descriptions[trans->description().toLower()] = trans->description(); if(b_extra) { if(trans->type() == TRANSACTION_TYPE_EXPENSE) { had_expense = true; if(((Expense*) trans)->payee().isEmpty()) has_empty_payee = true; else if(!payees.contains(((Expense*) trans)->payee().toLower())) payees[((Expense*) trans)->payee().toLower()] = ((Expense*) trans)->payee(); } else if(trans->type() == TRANSACTION_TYPE_INCOME) { had_income = true; if(((Income*) trans)->payer().isEmpty()) has_empty_payee = true; else if(!payees.contains(((Income*) trans)->payer().toLower())) payees[((Income*) trans)->payer().toLower()] = ((Income*) trans)->payer(); } } } } if(b_extra) { payeeCombo->clear(); if((!b_tags && b_income) || (b_tags && !had_expense && had_income)) {payeeCombo->addItem(tr("All Payers Combined")); payeeCombo->addItem(tr("All Payers Split"));} else if(!b_tags || (b_tags && had_expense && !had_income)) {payeeCombo->addItem(tr("All Payees Combined")); payeeCombo->addItem(tr("All Payees Split"));} else {payeeCombo->addItem(tr("All Payees/Payers Combined")); payeeCombo->addItem(tr("All Payees/Payers Split"));} } QMap::iterator it_e = descriptions.end(); int i = 2; for(QMap::iterator it = descriptions.begin(); it != it_e; ++it) { if(curindex < 0 && (current_source == 31 || current_source == 9 || current_source == 10 || current_source == 35 || current_source == 13 || current_source == 14 || current_source == 41 || current_source == 19 || current_source == 20) && !it.value().compare(current_description, Qt::CaseInsensitive)) { curindex = i; } descriptionCombo->addItem(it.value()); i++; } if(has_empty_description) { if(curindex < 0 && (current_source == 31 || current_source == 9 || current_source == 10 || current_source == 35 || current_source == 13 || current_source == 14 || current_source == 41 || current_source == 19 || current_source == 20) && current_description.isEmpty()) curindex = i; descriptionCombo->addItem(tr("No description", "Referring to the transaction description property (transaction title/generic article name)")); } if(b_extra) { i = 2; QMap::iterator it2_e = payees.end(); for(QMap::iterator it2 = payees.begin(); it2 != it2_e; ++it2) { if(curindex_p < 0 && !it2.value().compare(current_payee, Qt::CaseInsensitive)) { curindex_p = i; } payeeCombo->addItem(it2.value()); i++; } if(has_empty_payee) { if(curindex_p < 0 && current_payee.isEmpty()) { curindex_p = i; } if((!b_tags && b_income) || (b_tags && !had_expense && had_income)) payeeCombo->addItem(tr("No payer")); else if(!b_tags || (b_tags && had_expense && !had_income)) payeeCombo->addItem(tr("No payee")); else payeeCombo->addItem(tr("No payee/payer")); } } if(curindex < 0) curindex = 0; if(curindex_p < 0) curindex_p = 0; if(curindex < descriptionCombo->count()) { descriptionCombo->setCurrentIndex(curindex); } if(b_extra && curindex_p < payeeCombo->count()) { payeeCombo->setCurrentIndex(curindex_p); } int d_index = descriptionCombo->currentIndex(); int p_index = 0; if(b_extra) p_index = payeeCombo->currentIndex(); if(d_index <= 1) current_description = ""; if(p_index <= 1) current_payee = ""; if(d_index == 0) { if(p_index == 0) current_source = b_income ? 5 : 6; else if(p_index == 1) current_source = b_income ? 11 : 12; else current_source = b_income ? 15 : 16; } else if(d_index == 1) { if(p_index == 0) current_source = b_income ? 7 : 8; else current_source = b_income ? 17 : 18; } else { if(p_index == 0) current_source = b_income ? 9 : 10; else if(p_index == 1) current_source = b_income ? 13 : 14; else current_source = b_income ? 19 : 20; } if(b_tags) current_source += 22; descriptionCombo->blockSignals(false); if(b_extra) payeeCombo->blockSignals(false); } updateDisplay(); } void OverTimeChart::updateTags() { if(sourceCombo->currentIndex() != 5) return; if(categoryCombo->isEnabled()) { int curindex = 0; categoryCombo->blockSignals(true); descriptionCombo->blockSignals(true); if(b_extra) payeeCombo->blockSignals(true); categoryCombo->clear(); categoryCombo->addItem(tr("All Tags Split")); for(int i = 0; i < budget->tags.count(); i++) { categoryCombo->addItem(budget->tags[i]); if(budget->tags[i] == current_tag) curindex = i + 1; } if(curindex < categoryCombo->count()) categoryCombo->setCurrentIndex(curindex); if(curindex == 0) { descriptionCombo->clear(); descriptionCombo->setEnabled(false); descriptionCombo->addItem(tr("All Descriptions Combined", "Referring to the transaction description property (transaction title/generic article name)")); if(b_extra) { payeeCombo->clear(); payeeCombo->setEnabled(false); payeeCombo->addItem(tr("All Payees/Payers Combined")); } descriptionCombo->setEnabled(false); if(b_extra) payeeCombo->setEnabled(false); current_tag = ""; current_source = -3; } categoryCombo->blockSignals(false); descriptionCombo->blockSignals(false); if(b_extra) payeeCombo->blockSignals(false); } updateDisplay(); } void OverTimeChart::updateAccounts() { if(categoryCombo->isEnabled() && sourceCombo->currentIndex() != 5) { int curindex = categoryCombo->currentIndex(); if(curindex > 1) { curindex = 1; } categoryCombo->blockSignals(true); descriptionCombo->blockSignals(true); if(b_extra) payeeCombo->blockSignals(true); categoryCombo->clear(); categoryCombo->addItem(tr("All Categories Combined")); categoryCombo->addItem(tr("All Categories Split")); int i = 2; if(sourceCombo->currentIndex() == 2) { for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) { Account *account = *it; categoryCombo->addItem(account->nameWithParent()); if(account == current_account) curindex = i; i++; } } else { for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) { Account *account = *it; categoryCombo->addItem(account->nameWithParent()); if(account == current_account) curindex = i; i++; } } if(curindex < categoryCombo->count()) categoryCombo->setCurrentIndex(curindex); if(curindex <= 1) { descriptionCombo->clear(); descriptionCombo->setEnabled(false); descriptionCombo->addItem(tr("All Descriptions Combined", "Referring to the transaction description property (transaction title/generic article name)")); if(b_extra) { payeeCombo->clear(); payeeCombo->setEnabled(false); if(sourceCombo->currentIndex() == 2) payeeCombo->addItem(tr("All Payees Combined")); else if(sourceCombo->currentIndex() == 3) payeeCombo->addItem(tr("All Payers Combined")); else payeeCombo->addItem(tr("All Payees/Payers Combined")); } descriptionCombo->setEnabled(false); if(b_extra) payeeCombo->setEnabled(false); current_account = NULL; } if(curindex == 0) { if(sourceCombo->currentIndex() == 3) { current_source = 1; } else { current_source = 2; } } else if(curindex == 1) { if(sourceCombo->currentIndex() == 3) { current_source = 3; } else { current_source = 4; } } categoryCombo->blockSignals(false); descriptionCombo->blockSignals(false); if(b_extra) payeeCombo->blockSignals(false); } accountCombo->blockSignals(true); AssetsAccount *current_assets = selectedAccount(); accountCombo->clear(); accountCombo->addItem(tr("All Accounts Combined"), QVariant::fromValue(NULL)); accountCombo->addItem(tr("All Accounts Split"), QVariant::fromValue(NULL)); for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { AssetsAccount *account = *it; if(account != budget->balancingAccount) { accountCombo->addItem(account->name(), QVariant::fromValue((void*) account)); } } int index = 0; if(current_assets) index = accountCombo->findData(QVariant::fromValue((void*) current_assets)); if(index >= 0) accountCombo->setCurrentIndex(index); else accountCombo->setCurrentIndex(0); accountCombo->blockSignals(false); updateDisplay(); } AssetsAccount *OverTimeChart::selectedAccount() { if(!accountCombo->currentData().isValid()) return NULL; return (AssetsAccount*) accountCombo->currentData().value(); } #ifdef QT_CHARTS_LIB class PointLabel : public QGraphicsItem { public: PointLabel(QChart *c, QAbstractAxis *axis_x) : QGraphicsItem(c), chart(c), axis(axis_x) {} void setAxis(QAbstractAxis *axis_x) {axis = axis_x;} void setText(const QString &text) { m_text = text; QFontMetrics metrics(chart->font()); m_textRect = metrics.boundingRect(QRect(0, 0, 150, 150), Qt::AlignLeft, m_text); m_textRect.translate(5, 5); prepareGeometryChange(); m_rect = m_textRect.adjusted(-5, -5, 5, 5); } void setAnchor(QPointF point) { m_anchor = point; } QRectF boundingRect() const { QPointF anchor = mapFromParent(m_anchor); QRectF rect; rect.setLeft(qMin(m_rect.left(), anchor.x())); rect.setRight(qMax(m_rect.right(), anchor.x())); rect.setTop(qMin(m_rect.top(), anchor.y())); rect.setBottom(qMax(m_rect.bottom(), anchor.y())); return rect; } void paint(QPainter *painter, const QStyleOptionGraphicsItem*, QWidget*){ QPainterPath path; path.addRoundedRect(m_rect, 5, 5); QPointF anchor = mapFromParent(m_anchor); if (!m_rect.contains(anchor)) { QPointF point1, point2; // establish the position of the anchor point in relation to m_rect bool above = anchor.y() <= m_rect.top(); bool aboveCenter = anchor.y() > m_rect.top() && anchor.y() <= m_rect.center().y(); bool belowCenter = anchor.y() > m_rect.center().y() && anchor.y() <= m_rect.bottom(); bool below = anchor.y() > m_rect.bottom(); bool onLeft = anchor.x() <= m_rect.left(); bool leftOfCenter = anchor.x() > m_rect.left() && anchor.x() <= m_rect.center().x(); bool rightOfCenter = anchor.x() > m_rect.center().x() && anchor.x() <= m_rect.right(); bool onRight = anchor.x() > m_rect.right(); // get the nearest m_rect corner. qreal x = (onRight + rightOfCenter) * m_rect.width(); qreal y = (below + belowCenter) * m_rect.height(); bool cornerCase = (above && onLeft) || (above && onRight) || (below && onLeft) || (below && onRight); bool vertical = qAbs(anchor.x() - x) > qAbs(anchor.y() - y); qreal x1 = x + leftOfCenter * 10 - rightOfCenter * 20 + cornerCase * !vertical * (onLeft * 10 - onRight * 20); qreal y1 = y + aboveCenter * 10 - belowCenter * 20 + cornerCase * vertical * (above * 10 - below * 20);; point1.setX(x1); point1.setY(y1); qreal x2 = x + leftOfCenter * 20 - rightOfCenter * 10 + cornerCase * !vertical * (onLeft * 20 - onRight * 10);; qreal y2 = y + aboveCenter * 20 - belowCenter * 10 + cornerCase * vertical * (above * 20 - below * 10);; point2.setX(x2); point2.setY(y2); path.moveTo(point1); path.lineTo(mapFromParent(m_anchor)); path.lineTo(point2); path = path.simplified(); } painter->setBrush(chart->backgroundBrush()); QPen pen = axis->linePen(); pen.setWidth(1); painter->setPen(pen); painter->drawPath(path); painter->setPen(QPen(axis->labelsBrush().color())); painter->setBrush(axis->labelsBrush()); painter->drawText(m_textRect, m_text); } private: QString m_text; QRectF m_textRect; QRectF m_rect; QPointF m_anchor; QChart *chart; QAbstractAxis *axis; }; void OverTimeChart::onSeriesHovered(bool state, int index, QBarSet *set) { if(state) { QAbstractBarSeries *series = qobject_cast(sender()); int chart_type = typeCombo->currentIndex() + 1; PointLabel *item; if(!point_label) { item = new PointLabel(chart, axisX); point_label = item; } else { item = (PointLabel*) point_label; item->setAxis(axisX); } QList barsets = series->barSets(); int set_index = barsets.indexOf(set); QPointF pos; qreal bar_width = 0.0; if(chart_type == 2) { pos = chart->mapToPosition(QPointF(index, set->at(index)), series); QPointF pos_next = chart->mapToPosition(QPointF(index + 1, set->at(index)), series); bar_width = (pos_next.x() - pos.x()) * series->barWidth(); qreal pos_x = pos.x() - (bar_width / 2); pos_x += (set_index + 0.5) * (bar_width / barsets.count()); pos.setX(pos_x); } else if(chart_type == 3) { pos = chart->mapToPosition(QPointF(set->at(index), index), series); QPointF pos_next = chart->mapToPosition(QPointF(set->at(index), index + 1), series); bar_width = (pos_next.y() - pos.y()) * series->barWidth(); qreal pos_y = pos.y() - (bar_width / 2); pos_y += (set_index + 0.5) * (bar_width / barsets.count()); pos.setY(pos_y); } else if(chart_type == 4) { qreal acc_value = set->at(index) * 0.75; for(int i = 0; i < set_index && i < barsets.count(); i++) { if((barsets[set_index]->at(index) < 0.0) == (barsets[i]->at(index) < 0.0)) acc_value += barsets[i]->at(index); } pos = chart->mapToPosition(QPointF(index, acc_value), series); QPointF pos_next = chart->mapToPosition(QPointF(index + 1, acc_value), series); bar_width = (pos_next.x() - pos.x()) * series->barWidth(); pos.setX(pos.x() + (bar_width / 2)); } QDate date; Currency *currency = budget->defaultCurrency(); if(selectedAccount()) currency = selectedAccount()->currency(); if(current_source == -2 || current_source == 98) { if(chart_type == 3) { if(valueGroup->checkedId() == 4 && yearlyButton->isEnabled()) { if(index == 0) date = budget->lastBudgetDay(saved_last_date); else date = budget->lastBudgetDayOfYear(saved_last_date.addYears(-index)); } else { date = budget->lastBudgetDay(saved_last_date.addMonths(-index)); } } else { if(valueGroup->checkedId() == 4 && yearlyButton->isEnabled()) { if(index == set->count() - 1) date = budget->lastBudgetDay(saved_last_date); else date = budget->lastBudgetDayOfYear(saved_first_date.addYears(index)); } else { date = budget->lastBudgetDay(saved_first_date.addMonths(index)); } } item->setText(tr("%1\nValue: %2\nDate: %3").arg(set->label()).arg(valueGroup->checkedId() == 2 ? budget->formatValue(set->at(index), 0) : currency->formatValue(set->at(index))).arg(QLocale().toString(date, QLocale::ShortFormat))); } else { if(chart_type == 3) { if(valueGroup->checkedId() == 4 && yearlyButton->isEnabled()) date = saved_last_date.addYears(-index); else date = saved_last_date.addMonths(-index); } else { if(valueGroup->checkedId() == 4 && yearlyButton->isEnabled()) date = saved_first_date.addYears(index); else date = saved_first_date.addMonths(index); } item->setText(tr("%1\nValue: %2\nDate: %3").arg(set->label()).arg(valueGroup->checkedId() == 2 ? budget->formatValue(set->at(index), 0) : currency->formatValue(set->at(index))).arg(valueGroup->checkedId() == 4 ? budget->budgetYearString(date) : budget->budgetDateToMonth(date).toString(tr("MMMM yyyy", "Month and year")))); } item->setAnchor(pos); item->setPos(pos + QPoint(10, -50)); item->setZValue(11); if(pos.x() + item->boundingRect().width() + 10 > chart->size().width()) { if(chart_type == 4) { pos.setX(pos.x() - bar_width); item->setAnchor(pos); item->setPos(pos + QPoint(10, -50)); } item->setPos(pos + QPoint(-10 - item->boundingRect().width(), -50)); } item->show(); } else if(point_label) { point_label->hide(); } } void OverTimeChart::onSeriesHovered(const QPointF &value, bool state) { if(state) { QXYSeries *series = qobject_cast(sender()); PointLabel *item; if(!point_label) { item = new PointLabel(chart, axisX); point_label = item; } else { item = (PointLabel*) point_label; item->setAxis(axisX); } QDate date = QDateTime::fromMSecsSinceEpoch(value.x()).date(); if(budget->dayOfBudgetMonth(date) >= budget->daysInBudgetMonth(date) / 2) { date = budget->firstBudgetDay(date); budget->addBudgetMonthsSetFirst(date, 1); } else { date = budget->firstBudgetDay(date); } qreal value_x = DATE_TO_MSECS(date); qreal value_y = value.y(); for(int i = 0; i < series->count(); i++) { if(series->at(i).x() == value_x) { value_y = series->at(i).y(); } } QPointF pos = chart->mapToPosition(QPointF(value_x, value_y), series); Currency *currency = budget->defaultCurrency(); if(selectedAccount()) currency = selectedAccount()->currency(); if(current_source == -2 || current_source == 98) item->setText(tr("%1\nValue: %2\nDate: %3").arg(series->name()).arg(valueGroup->checkedId() == 2 ? budget->formatValue(value_y, 0) : currency->formatValue(value_y)).arg(QLocale().toString(valueGroup->checkedId() == 4 && yearlyButton->isEnabled() ? budget->lastBudgetDayOfYear(date) : budget->lastBudgetDay(date), QLocale::ShortFormat))); else item->setText(tr("%1\nValue: %2\nDate: %3").arg(series->name()).arg(valueGroup->checkedId() == 2 ? budget->formatValue(value_y, 0) : currency->formatValue(value_y)).arg(valueGroup->checkedId() == 4 ? budget->budgetYearString(date) : budget->budgetDateToMonth(date).toString(tr("MMMM yyyy", "Month and year")))); item->setAnchor(pos); item->setPos(pos + QPoint(10, -50)); item->setZValue(11); if(pos.x() + item->boundingRect().width() + 10 > chart->size().width()) item->setPos(pos + QPoint(-10 - item->boundingRect().width(), -50)); item->show(); } else if(point_label) { point_label->hide(); } } void OverTimeChart::legendClicked() { if(typeCombo->currentIndex() == 0) { QLegendMarker* marker = qobject_cast(sender()); marker->series()->setVisible(!marker->series()->isVisible()); marker->setVisible(true); qreal alpha = 1.0; if(!marker->series()->isVisible()) { alpha = 0.5; } QColor color; QBrush brush = marker->labelBrush(); color = brush.color(); color.setAlphaF(alpha); brush.setColor(color); marker->setLabelBrush(brush); brush = marker->brush(); color = brush.color(); if(color.alphaF() > 0.0) { color.setAlphaF(alpha); brush.setColor(color); marker->setBrush(brush); } QPen pen = marker->pen(); color = pen.color(); color.setAlphaF(alpha); pen.setColor(color); marker->setPen(pen); } else { QBarLegendMarker* marker = qobject_cast(sender()); if(marker->series()->count() == 1) updateDisplay(); else marker->series()->remove(marker->barset()); } } void OverTimeChart::typeChanged(int index) { yearlyButton->setEnabled(sourceCombo->currentIndex() != 4 || index > 0); valueButton->setEnabled(sourceCombo->currentIndex() != 4 || index > 0); startDateEdit->setMonthEnabled(!yearlyButton->isEnabled() || !yearlyButton->isChecked()); endDateEdit->setMonthEnabled(!yearlyButton->isEnabled() || !yearlyButton->isChecked() || budget->budgetYear(end_date) == budget->budgetYear(QDate::currentDate())); if(index != 0) endMonthChanged(end_date); else updateDisplay(); } void OverTimeChart::themeChanged(int index) { int theme = themeCombo->itemData(index).toInt(); chart->setTheme(theme >= 0 ? (QChart::ChartTheme) theme : QChart::ChartThemeBlueNcs); QSettings settings; settings.beginGroup("OverTimeChart"); settings.setValue("theme", theme); settings.endGroup(); updateDisplay(); } #endif Eqonomize-1.5.3/src/overtimechart.h000066400000000000000000000075241416454732000173200ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016-2020 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifndef OVER_TIME_CHART_H #define OVER_TIME_CHART_H #include #include #include class QButtonGroup; class QComboBox; #ifdef QT_CHARTS_LIB #include #include #include #include #include class QGraphicsItem; #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) QT_CHARTS_USE_NAMESPACE #endif #else class QGraphicsScene; class QGraphicsView; #endif class QPushButton; class QRadioButton; class CategoryAccount; class AssetsAccount; class Budget; class EqonomizeMonthSelector; class OverTimeChart : public QWidget { Q_OBJECT public: OverTimeChart(Budget *budg, QWidget *parent, bool extra_parameters); ~OverTimeChart(); protected: Budget *budget; bool b_extra; QComboBox *sourceCombo, *categoryCombo, *descriptionCombo, *payeeCombo, *accountCombo; EqonomizeMonthSelector *startDateEdit, *endDateEdit; QPushButton *saveButton, *printButton; QRadioButton *yearlyButton, *dailyButton, *valueButton, *countButton, *perButton; #ifdef QT_CHARTS_LIB QChartView *view; QChart *chart; QComboBox *themeCombo; QComboBox *typeCombo; QAbstractAxis *axisX; QValueAxis *axisY; QGraphicsItem *point_label; #else QGraphicsScene *scene; QGraphicsView *view; #endif QButtonGroup *valueGroup; QDate start_date, end_date, saved_first_date, saved_last_date; CategoryAccount *current_account; QString current_description, current_payee, current_tag; int current_source; bool has_empty_description, has_empty_payee; #ifndef QT_CHARTS_LIB void resizeEvent(QResizeEvent*); #endif public slots: void resetOptions(); void resetDate(); void sourceChanged(int); void accountChanged(int); void categoryChanged(int); void descriptionChanged(int); void payeeChanged(int); void updateTransactions(); void updateAccounts(); void updateTags(); void updateDisplay(); void onFilterSelected(QString); void save(); void print(); void saveConfig(); void startMonthChanged(const QDate&); void startYearChanged(const QDate&); void endMonthChanged(const QDate&); void endYearChanged(const QDate&); void valueTypeToggled(bool); AssetsAccount *selectedAccount(); #ifdef QT_CHARTS_LIB void themeChanged(int); void typeChanged(int); void legendClicked(); void onSeriesHovered(const QPointF&, bool); void onSeriesHovered(bool, int, QBarSet*); #endif }; #endif Eqonomize-1.5.3/src/overtimereport.cpp000066400000000000000000002576111416454732000200710ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016-2020 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include "overtimereport.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "account.h" #include "budget.h" #include "recurrence.h" #include "transaction.h" #include extern QString htmlize_string(QString str); extern QString last_document_directory; struct month_info { double value; double expense; double count; QDate date; QMap tags; QMap cats; }; DescriptionsCombo::DescriptionsCombo(int type, Budget *budg, QWidget *parent, bool show_all) : QPushButton(parent) { itemsMenu = new DescriptionsMenu(type, budg, this, show_all); setMenu(itemsMenu); setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred); clear(); setMinimumWidth(sizeHint().width()); connect(itemsMenu, SIGNAL(aboutToShow()), this, SLOT(resizeDescriptionsMenu())); connect(itemsMenu, SIGNAL(selectedItemsChanged()), this, SLOT(updateText())); connect(itemsMenu, SIGNAL(selectedItemsChanged()), this, SIGNAL(selectedItemsChanged())); } void DescriptionsCombo::resizeDescriptionsMenu() { itemsMenu->setMinimumWidth(width()); } void DescriptionsCombo::updateText() { setText(itemsMenu->selectedItemsText(0).replace("&", "&&")); setToolTip(itemsMenu->selectedItemsText(1)); } void DescriptionsCombo::addItem(QString str) { itemsMenu->addItem(str); } void DescriptionsCombo::updateItems(const QStringList &list) { itemsMenu->updateItems(list); } void DescriptionsCombo::setItemType(int type) { itemsMenu->setItemType(type); } int DescriptionsCombo::itemType() { return itemsMenu->itemType(); } void DescriptionsCombo::setItemSelected(const QString &str, bool b) { itemsMenu->setItemSelected(str, b); updateText(); } bool DescriptionsCombo::itemSelected(const QString &str) { return itemsMenu->itemSelected(str); } bool DescriptionsCombo::allItemsSelected() { return itemsMenu->allItemsSelected(); } QStringList &DescriptionsCombo::selectedItems() { return itemsMenu->selected_items; } QString DescriptionsCombo::selectedItemsText(int type) { return itemsMenu->selectedItemsText(type); } bool DescriptionsCombo::testTransaction(Transactions *trans) { return itemsMenu->testTransaction(trans); } void DescriptionsCombo::selectAll() { itemsMenu->selectAll(); updateText(); } void DescriptionsCombo::deselectAll() { itemsMenu->deselectAll(); updateText(); } void DescriptionsCombo::clear() { itemsMenu->clearItems(); updateText(); } DescriptionsMenu::DescriptionsMenu(int type, Budget *budg, QWidget *parent, bool show_all) : QMenu(parent), budget(budg), b_all(show_all), i_type(type) { if(b_all) { if(i_type == 0) addAction(tr("All Descriptions Combined", "Referring to the transaction description property (transaction title/generic article name)"), this, SLOT(toggleAll())); else if(i_type == 1) addAction(tr("All Tags Combined"), this, SLOT(toggleAll())); else if(i_type == 2) addAction(tr("All Payees Combined"), this, SLOT(toggleAll())); else if(i_type == 3) addAction(tr("All Payers Combined"), this, SLOT(toggleAll())); else if(i_type == 4) addAction(tr("All Payees/Payers Combined"), this, SLOT(toggleAll())); } } void DescriptionsMenu::addItem(QString str) { if(b_all && item_actions.isEmpty()) addSeparator(); QAction *action = addAction(str.replace("&", "&&"), this, SLOT(itemToggled())); action->setCheckable(true); item_actions[str] = action; } void DescriptionsMenu::updateItems(const QStringList &list) { QHash itemb; for(QHash::const_iterator it = item_actions.constBegin(); it != item_actions.constEnd(); ++it) { itemb[it.key()] = it.value()->isChecked(); } clearItems(); if(!list.isEmpty()) addSeparator(); bool has_empty = false; for(int i = 0; i < list.count(); i++) { QString str = list.at(i); if(str.isEmpty()) { has_empty = true; } else { QAction *action = addAction(str.replace("&", "&&"), this, SLOT(itemToggled())); action->setCheckable(true); if(itemb.contains(list.at(i))) { action->setChecked(itemb[list.at(i)]); if(itemb[list.at(i)]) selected_items << list.at(i); } item_actions[list.at(i)] = action; } } if(has_empty) { QString str; if(i_type == 0) str = tr("No description", "Referring to the transaction description property (transaction title/generic article name)"); else if(i_type == 2) str = tr("No payee"); else if(i_type == 3) str = tr("No payer"); else if(i_type == 4) str = tr("No payee/payer"); QAction *action = addAction(str, this, SLOT(itemToggled())); action->setCheckable(true); if(itemb.contains(QString())) { action->setChecked(itemb[QString()]); if(itemb[QString()]) selected_items << QString(); } item_actions[QString()] = action; } } void DescriptionsMenu::setItemType(int type) { i_type = type; } int DescriptionsMenu::itemType() { return i_type; } void DescriptionsMenu::clearItems() { clear(); item_actions.clear(); selected_items.clear(); if(b_all) { if(i_type == 0) addAction(tr("All Descriptions Combined", "Referring to the transaction description property (transaction title/generic article name)"), this, SLOT(toggleAll())); else if(i_type == 1) addAction(tr("All Tags Combined"), this, SLOT(toggleAll())); else if(i_type == 2) addAction(tr("All Payees Combined"), this, SLOT(toggleAll())); else if(i_type == 3) addAction(tr("All Payers Combined"), this, SLOT(toggleAll())); else if(i_type == 4) addAction(tr("All Payees/Payers Combined"), this, SLOT(toggleAll())); } } bool DescriptionsMenu::testTransaction(Transactions *trans) { if(allItemsSelected()) return true; for(QStringList::const_iterator it = selected_items.constBegin(); it != selected_items.constEnd(); ++it) { if(i_type == 0 && trans->description().compare(*it, Qt::CaseInsensitive) == 0) return true; if(i_type == 1 && trans->hasTag(*it, true)) return true; if(i_type >= 2 && i_type <= 4 && trans->payeeText().compare(*it, Qt::CaseInsensitive) == 0) return true; } return false; } void DescriptionsMenu::setItemSelected(const QString &str, bool b) { QHash::iterator it = item_actions.find(str); if(it != item_actions.end() && b != it.value()->isChecked()) { it.value()->setChecked(b); if(b) selected_items << it.key(); else selected_items.removeAll(it.key()); } } bool DescriptionsMenu::itemSelected(const QString &str) { if(selected_items.count() == 1) return selected_items.at(0) == str; QHash::iterator it = item_actions.find(str); if(it != item_actions.end()) { return it.value()->isChecked(); } return false; } bool DescriptionsMenu::allItemsSelected() { int n = selectedItemsCount(); return (b_all && n == 0) || n == item_actions.count(); } int DescriptionsMenu::selectedItemsCount() { return selected_items.count(); } QString DescriptionsMenu::selectedItemsText(int type) { QString str; int n = 0; for(int i = 0; i < selected_items.count(); i++) { if(i == 0 || type > 0) { if(type == 1 && i > 0) str += ", "; else if(type == 2 && i > 0) str += " + "; if(selected_items.at(i).isEmpty() && i_type != 1) { if(i_type == 0) str += tr("No description", "Referring to the transaction description property (transaction title/generic article name)"); else if(i_type == 2) str += tr("No payee"); else if(i_type == 3) str += tr("No payer"); else if(i_type == 4) str += tr("No payee/payer"); } else { str += selected_items.at(i); } } n++; } if(n == 0 || (type == 0 && n > 1)) { if(b_all && (n == 0 || n == item_actions.count())) { if(i_type == 0) str = tr("All Descriptions Combined", "Referring to the transaction description property (transaction title/generic article name)"); else if(i_type == 1) str = tr("All Tags Combined"); else if(i_type == 2) str = tr("All Payees Combined"); else if(i_type == 3) str = tr("All Payers Combined"); else if(i_type == 4) str = tr("All Payees/Payers Combined"); } else { if(i_type == 0) str = tr("%n descriptions", "Referring to the transaction description property (transaction title/generic article name)", n); else if(i_type == 1) str = tr("%n tags", "", n); else if(i_type == 2) str = tr("%n payees", "", n); else if(i_type == 3) str = tr("%n payers", "", n); else if(i_type == 4) str = tr("%n payees/payers", "", n); } } return str; } void DescriptionsMenu::itemToggled() { QAction *action = qobject_cast(sender()); for(QHash::const_iterator it = item_actions.constBegin(); it != item_actions.constEnd(); ++it) { if(it.value() == action) { selected_items.removeAll(it.key()); if(action->isChecked()) selected_items << it.key(); break; } } emit selectedItemsChanged(); } void DescriptionsMenu::keyPressEvent(QKeyEvent *e) { QAction *action = activeAction(); if(action && item_actions.values().contains(action)) { if(e->key() == Qt::Key_Space) { action->trigger(); e->setAccepted(true); return; } else if(e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) { deselectAll(); action->trigger(); e->setAccepted(true); hide(); return; } } QMenu::keyPressEvent(e); } void DescriptionsMenu::mouseReleaseEvent(QMouseEvent *e) { QAction *action = actionAt(e->pos()); if(action && item_actions.values().contains(action)) { if(e->button() != Qt::LeftButton || e->pos().x() <= actionGeometry(action).height()) { action->trigger(); e->setAccepted(true); } else { deselectAll(); action->trigger(); e->setAccepted(true); hide(); } return; } QMenu::mouseReleaseEvent(e); } void DescriptionsMenu::selectAll() { selected_items.clear(); for(QHash::const_iterator it = item_actions.constBegin(); it != item_actions.constEnd(); ++it) { it.value()->setChecked(true); selected_items << it.key(); } } void DescriptionsMenu::deselectAll() { selected_items.clear(); for(QHash::const_iterator it = item_actions.constBegin(); it != item_actions.constEnd(); ++it) { it.value()->setChecked(false); } } void DescriptionsMenu::toggleAll() { if(selected_items.count() == item_actions.count()) deselectAll(); else selectAll(); emit selectedItemsChanged(); } AccountsCombo::AccountsCombo(Budget *budg, QWidget *parent, bool shows_assets) : QPushButton(parent) { accountsMenu = new AccountsMenu(budg, this, shows_assets); setMenu(accountsMenu); setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred); clear(); setMinimumWidth(sizeHint().width()); connect(accountsMenu, SIGNAL(aboutToShow()), this, SLOT(resizeAccountsMenu())); connect(accountsMenu, SIGNAL(selectedAccountsChanged()), this, SLOT(updateText())); connect(accountsMenu, SIGNAL(selectedAccountsChanged()), this, SIGNAL(selectedAccountsChanged())); } void AccountsCombo::resizeAccountsMenu() { accountsMenu->setMinimumWidth(width()); } void AccountsCombo::updateText() { setText(accountsMenu->selectedAccountsText(0).replace("&", "&&")); setToolTip(accountsMenu->selectedAccountsText(1)); } void AccountsCombo::updateAccounts(int type) { accountsMenu->updateAccounts(type); updateText(); } void AccountsCombo::setAccountSelected(Account *account, bool b) { accountsMenu->setAccountSelected(account, b); updateText(); } bool AccountsCombo::accountSelected(Account *account) { return accountsMenu->accountSelected(account); } bool AccountsCombo::allAccountsSelected() { return accountsMenu->allAccountsSelected(); } bool AccountsCombo::testTransactionRelation(Transactions *trans, bool exclude_securities) { if(accountsMenu->allAccountsSelected()) return true; for(QList::const_iterator it = accountsMenu->selected_accounts.constBegin(); it != accountsMenu->selected_accounts.constEnd(); ++it) { if((!exclude_securities || (*it)->type() != ACCOUNT_TYPE_ASSETS || ((AssetsAccount*) *it)->accountType() != ASSETS_TYPE_SECURITIES) && trans->relatesToAccount(*it)) { return true; } } return false; } double AccountsCombo::transactionChange(Transactions *trans, bool exclude_securities) { double d = 0.0; for(QList::const_iterator it = accountsMenu->selected_accounts.constBegin(); it != accountsMenu->selected_accounts.constEnd(); ++it) { if(!exclude_securities || (*it)->type() != ACCOUNT_TYPE_ASSETS || ((AssetsAccount*) *it)->accountType() != ASSETS_TYPE_SECURITIES) d += trans->accountChange(*it); } return d; } QList &AccountsCombo::selectedAccounts() { return accountsMenu->selected_accounts; } QString AccountsCombo::selectedAccountsText(int type) { return accountsMenu->selectedAccountsText(type); } void AccountsCombo::selectAll() { accountsMenu->selectAll(); updateText(); } void AccountsCombo::deselectAll() { accountsMenu->deselectAll(); updateText(); } void AccountsCombo::clear() { updateAccounts(-1); updateText(); } AccountsMenu::AccountsMenu(Budget *budg, QWidget *parent, bool shows_assets) : QMenu(parent), budget(budg), b_assets(shows_assets) {} void AccountsMenu::updateAccounts(int type) { QHash catb; if(type >= 0) { for(QHash::const_iterator it = account_actions.constBegin(); it != account_actions.constEnd(); ++it) { catb[it.key()] = it.value()->isChecked(); } } clear(); account_actions.clear(); selected_accounts.clear(); if(type >= 0) { if(b_assets) addAction(tr("All Accounts"), this, SLOT(toggleAll())); else addAction(tr("All Categories Combined"), this, SLOT(toggleAll())); } if(type == ACCOUNT_TYPE_ASSETS) { if(!budget->assetsAccounts.isEmpty()) addSeparator(); for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { if(*it != budget->balancingAccount) { QAction *action = addAction((*it)->nameWithParent().replace("&", "&&"), this, SLOT(accountToggled())); action->setCheckable(true); if(catb.contains(*it)) { action->setChecked(catb[*it]); if(catb[*it]) selected_accounts << *it; } account_actions[*it] = action; } } } else if(type == ACCOUNT_TYPE_INCOMES) { if(!budget->incomesAccounts.isEmpty()) addSeparator(); for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) { QAction *action = addAction((*it)->nameWithParent().replace("&", "&&"), this, SLOT(accountToggled())); action->setCheckable(true); if(catb.contains(*it)) { action->setChecked(catb[*it]); if(catb[*it]) selected_accounts << *it; } account_actions[*it] = action; } } else { if(!budget->expensesAccounts.isEmpty()) addSeparator(); for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) { QAction *action = addAction((*it)->nameWithParent().replace("&", "&&"), this, SLOT(accountToggled())); action->setCheckable(true); if(catb.contains(*it)) { action->setChecked(catb[*it]); if(catb[*it]) selected_accounts << *it; } account_actions[*it] = action; } } } void AccountsMenu::setAccountSelected(Account *account, bool b) { QHash::iterator it = account_actions.find(account); if(it != account_actions.end() && b != it.value()->isChecked()) { it.value()->setChecked(b); if(b) selected_accounts << it.key(); else selected_accounts.removeAll(it.key()); } } bool AccountsMenu::accountSelected(Account *account) { if(selected_accounts.count() == 1) return selected_accounts.at(0) == account; QHash::iterator it = account_actions.find(account); if(it != account_actions.end()) { return it.value()->isChecked(); } return false; } bool AccountsMenu::allAccountsSelected() { int n = selectedAccountsCount(); return n == 0 || n == account_actions.count(); } int AccountsMenu::selectedAccountsCount() { return selected_accounts.count(); } QString AccountsMenu::selectedAccountsText(int type) { QString str; int n = 0; for(int i = 0; i < selected_accounts.count(); i++) { if(i == 0 || type > 0) { if(type == 1 && i > 0) str += ", "; else if(type == 2 && i > 0) str += " + "; str += selected_accounts.at(i)->nameWithParent(); } n++; } if(n == 0 || (type == 0 && n > 1)) { if(n == 0 || n == account_actions.count()) { if(b_assets) str = tr("All Accounts"); else str = tr("All Categories Combined"); } else { if(b_assets) str = tr("%n accounts", "", n); else str = tr("%n categories", "", n); } } return str; } void AccountsMenu::accountToggled() { QAction *action = qobject_cast(sender()); for(QHash::const_iterator it = account_actions.constBegin(); it != account_actions.constEnd(); ++it) { if(it.value() == action) { selected_accounts.removeAll(it.key()); if(action->isChecked()) selected_accounts << it.key(); break; } } emit selectedAccountsChanged(); } void AccountsMenu::keyPressEvent(QKeyEvent *e) { QAction *action = activeAction(); if(action && account_actions.values().contains(action)) { if(e->key() == Qt::Key_Space) { action->trigger(); e->setAccepted(true); return; } else if(e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) { deselectAll(); action->trigger(); e->setAccepted(true); hide(); return; } } QMenu::keyPressEvent(e); } void AccountsMenu::mouseReleaseEvent(QMouseEvent *e) { QAction *action = actionAt(e->pos()); if(action && account_actions.values().contains(action)) { if(e->button() != Qt::LeftButton || e->pos().x() <= actionGeometry(action).height()) { action->trigger(); e->setAccepted(true); } else { deselectAll(); action->trigger(); e->setAccepted(true); hide(); } return; } QMenu::mouseReleaseEvent(e); } void AccountsMenu::selectAll() { selected_accounts.clear(); for(QHash::const_iterator it = account_actions.constBegin(); it != account_actions.constEnd(); ++it) { it.value()->setChecked(true); selected_accounts << it.key(); } } void AccountsMenu::deselectAll() { selected_accounts.clear(); for(QHash::const_iterator it = account_actions.constBegin(); it != account_actions.constEnd(); ++it) { it.value()->setChecked(false); } } void AccountsMenu::toggleAll() { if(selected_accounts.count() == account_actions.count()) deselectAll(); else selectAll(); emit selectedAccountsChanged(); } OverTimeReport::OverTimeReport(Budget *budg, QWidget *parent) : QWidget(parent), budget(budg) { block_display_update = false; QVBoxLayout *layout = new QVBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); QDialogButtonBox *buttons = new QDialogButtonBox(this); saveButton = buttons->addButton(tr("Save As…"), QDialogButtonBox::ActionRole); saveButton->setAutoDefault(false); printButton = buttons->addButton(tr("Print…"), QDialogButtonBox::ActionRole); printButton->setAutoDefault(false); layout->addWidget(buttons); htmlview = new QTextEdit(this); htmlview->setReadOnly(true); layout->addWidget(htmlview); QSettings settings; settings.beginGroup("OverTimeReport"); QWidget *settingsWidget = new QWidget(this); QGridLayout *settingsLayout = new QGridLayout(settingsWidget); settingsLayout->addWidget(new QLabel(tr("Source:"), settingsWidget), 0, 0); QHBoxLayout *choicesLayout = new QHBoxLayout(); settingsLayout->addLayout(choicesLayout, 0, 1); sourceCombo = new QComboBox(settingsWidget); sourceCombo->setEditable(false); sourceCombo->addItem(tr("Profits")); sourceCombo->addItem(tr("Expenses")); sourceCombo->addItem(tr("Incomes")); sourceCombo->addItem(tr("Assets & Liabilities")); sourceCombo->addItem(tr("Tags")); choicesLayout->addWidget(sourceCombo); choicesLayout->setStretchFactor(sourceCombo, 0); categoryCombo = new AccountsCombo(budget, settingsWidget); categoryCombo->setEnabled(false); choicesLayout->addWidget(categoryCombo); choicesLayout->setStretchFactor(categoryCombo, 1); tagCombo = new DescriptionsCombo(1, budget, settingsWidget, false); tagCombo->hide(); choicesLayout->addWidget(tagCombo); choicesLayout->setStretchFactor(tagCombo, 1); descriptionCombo = new DescriptionsCombo(0, budget, settingsWidget); descriptionCombo->setEnabled(false); choicesLayout->addWidget(descriptionCombo); choicesLayout->setStretchFactor(descriptionCombo, 1); accountCombo = new AccountsCombo(budget, settingsWidget, true); accountCombo->updateAccounts(ACCOUNT_TYPE_ASSETS); choicesLayout->addWidget(accountCombo); choicesLayout->setStretchFactor(accountCombo, 1); current_source = 0; columnsLabel = new QLabel(tr("Columns:"), settingsWidget); settingsLayout->addWidget(columnsLabel, 1, 0); QHBoxLayout *enabledLayout = new QHBoxLayout(); QButtonGroup *group = new QButtonGroup(this); catsButton = new QRadioButton(tr("Categories"), settingsWidget); group->addButton(catsButton, 1); enabledLayout->addWidget(catsButton); tagsButton = new QRadioButton(tr("Tags"), settingsWidget); group->addButton(tagsButton, 2); enabledLayout->addWidget(tagsButton); totalButton = new QRadioButton(tr("Total:"), settingsWidget); group->addButton(totalButton, 0); enabledLayout->addWidget(totalButton); switch(settings.value("columns", 0).toInt()) { case 1: {catsButton->setChecked(true); break;} case 2: {tagsButton->setChecked(true); break;} default: {totalButton->setChecked(true); break;} } settingsLayout->addLayout(enabledLayout, 1, 1); valueButton = new QCheckBox(tr("Value"), settingsWidget); valueButton->setChecked(settings.value("valueEnabled", true).toBool()); enabledLayout->addWidget(valueButton); dailyButton = new QCheckBox(tr("Daily"), settingsWidget); dailyButton->setChecked(settings.value("dailyAverageEnabled", true).toBool()); enabledLayout->addWidget(dailyButton); monthlyButton = new QCheckBox(tr("Monthly"), settingsWidget); monthlyButton->setChecked(settings.value("monthlyAverageEnabled", true).toBool()); enabledLayout->addWidget(monthlyButton); yearlyButton = new QCheckBox(tr("Yearly"), settingsWidget); yearlyButton->setChecked(settings.value("yearlyEnabled", false).toBool()); enabledLayout->addWidget(yearlyButton); countButton = new QCheckBox(tr("Quantity"), settingsWidget); countButton->setChecked(settings.value("transactionCountEnabled", true).toBool()); enabledLayout->addWidget(countButton); perButton = new QCheckBox(tr("Average value"), settingsWidget); perButton->setChecked(settings.value("valuePerTransactionEnabled", false).toBool()); enabledLayout->addWidget(perButton); enabledLayout->addStretch(1); valueButton->setEnabled(current_source != 12 && current_source != 0 && totalButton->isChecked()); dailyButton->setEnabled(current_source != 12 && current_source != 0 && totalButton->isChecked()); monthlyButton->setEnabled(current_source != 12 && current_source != 0 && totalButton->isChecked()); yearlyButton->setEnabled(current_source != 12 && current_source != 0 && totalButton->isChecked()); countButton->setEnabled(current_source != 12 && current_source != 0 && totalButton->isChecked()); perButton->setEnabled(current_source != 12 && current_source != 0 && totalButton->isChecked()); columnsLabel->setEnabled(current_source != 12 && current_source != 0); tagsButton->setEnabled(current_source != 12 && current_source != 0); catsButton->setEnabled(current_source != 12 && current_source != 0); totalButton->setEnabled(current_source != 12 && current_source != 0); settings.endGroup(); layout->addWidget(settingsWidget); updateTags(); #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) connect(group, SIGNAL(idToggled(int, bool)), this, SLOT(columnsToggled(int, bool))); #else connect(group, SIGNAL(buttonToggled(int, bool)), this, SLOT(columnsToggled(int, bool))); #endif connect(valueButton, SIGNAL(toggled(bool)), this, SLOT(updateDisplay())); connect(dailyButton, SIGNAL(toggled(bool)), this, SLOT(updateDisplay())); connect(monthlyButton, SIGNAL(toggled(bool)), this, SLOT(updateDisplay())); connect(yearlyButton, SIGNAL(toggled(bool)), this, SLOT(updateDisplay())); connect(countButton, SIGNAL(toggled(bool)), this, SLOT(updateDisplay())); connect(perButton, SIGNAL(toggled(bool)), this, SLOT(updateDisplay())); connect(sourceCombo, SIGNAL(activated(int)), this, SLOT(sourceChanged(int))); connect(categoryCombo, SIGNAL(selectedAccountsChanged()), this, SLOT(categoryChanged())); connect(tagCombo, SIGNAL(selectedItemsChanged()), this, SLOT(tagChanged())); connect(descriptionCombo, SIGNAL(selectedItemsChanged()), this, SLOT(descriptionChanged())); connect(accountCombo, SIGNAL(selectedAccountsChanged()), this, SLOT(updateDisplay())); connect(saveButton, SIGNAL(clicked()), this, SLOT(save())); connect(printButton, SIGNAL(clicked()), this, SLOT(print())); } void OverTimeReport::resetOptions() { block_display_update = true; accountCombo->blockSignals(true); accountCombo->deselectAll(); accountCombo->blockSignals(false); sourceCombo->blockSignals(true); sourceCombo->setCurrentIndex(0); sourceCombo->blockSignals(false); columnsToggled(tagsButton->isChecked() ? 2 : (catsButton->isChecked() ? 1 : 0), true); sourceChanged(0); block_display_update = false; updateDisplay(); } void OverTimeReport::columnsToggled(int id, bool b) { if(!b) return; valueButton->setEnabled(id == 0); dailyButton->setEnabled(id == 0); monthlyButton->setEnabled(id == 0); yearlyButton->setEnabled(id == 0); countButton->setEnabled(id == 0); perButton->setEnabled(id == 0); updateDisplay(); } void OverTimeReport::descriptionChanged() { if(descriptionCombo->allItemsSelected()) { if(sourceCombo->currentIndex() == 4) current_source = 13; else if(sourceCombo->currentIndex() == 2) current_source = 5; else current_source = 6; } else { if(sourceCombo->currentIndex() == 4) current_source = 14; else if(sourceCombo->currentIndex() == 2) current_source = 9; else current_source = 10; } updateDisplay(); } void OverTimeReport::categoryChanged() { descriptionCombo->blockSignals(true); if(categoryCombo->allAccountsSelected()) { if(sourceCombo->currentIndex() == 2) { current_source = 1; } else { current_source = 2; } descriptionCombo->clear(); descriptionCombo->setEnabled(false); } else { if(sourceCombo->currentIndex() == 1) { current_source = 6; } else { current_source = 5; } QMap descriptions; for(TransactionList::const_iterator it = budget->transactions.constEnd(); it != budget->transactions.constBegin();) { --it; Transaction *trans = *it; if(categoryCombo->accountSelected(trans->fromAccount()) || categoryCombo->accountSelected(trans->toAccount())) { if(!descriptions.contains(trans->description().toLower())) descriptions[trans->description().toLower()] = trans->description(); } } QStringList items; QMap::iterator it_e = descriptions.end(); for(QMap::iterator it = descriptions.begin(); it != it_e; ++it) { items << it.value(); } descriptionCombo->updateItems(items); descriptionCombo->setEnabled(true); } descriptionCombo->blockSignals(false); updateDisplay(); } void OverTimeReport::tagChanged() { descriptionCombo->blockSignals(true); if(sourceCombo->currentIndex() == 4) { current_source = 13; QMap descriptions; for(TransactionList::const_iterator it = budget->transactions.constEnd(); it != budget->transactions.constBegin();) { --it; Transaction *trans = *it; if((trans->type() == TRANSACTION_TYPE_EXPENSE || trans->type() == TRANSACTION_TYPE_INCOME) && tagCombo->testTransaction(trans)) { if(!descriptions.contains(trans->description().toLower())) descriptions[trans->description().toLower()] = trans->description(); } } QStringList items; QMap::iterator it_e = descriptions.end(); for(QMap::iterator it = descriptions.begin(); it != it_e; ++it) { items << it.value(); } descriptionCombo->updateItems(items); descriptionCombo->setEnabled(true); } else { descriptionCombo->clear(); } descriptionCombo->blockSignals(false); updateDisplay(); } void OverTimeReport::sourceChanged(int index) { categoryCombo->blockSignals(true); descriptionCombo->blockSignals(true); categoryCombo->clear(); tagCombo->blockSignals(true); descriptionCombo->clear(); descriptionCombo->setEnabled(false); if(index == 2) { categoryCombo->updateAccounts(ACCOUNT_TYPE_INCOMES); categoryCombo->setEnabled(true); categoryCombo->show(); tagCombo->hide(); current_source = 1; } else if(index == 1) { categoryCombo->updateAccounts(ACCOUNT_TYPE_EXPENSES); categoryCombo->setEnabled(true); categoryCombo->show(); tagCombo->hide(); current_source = 2; } else if(index == 4) { categoryCombo->setEnabled(false); categoryCombo->hide(); tagCombo->show(); current_source = 13; } else { categoryCombo->setEnabled(false); categoryCombo->show(); tagCombo->hide(); if(index == 3) current_source = 12; else current_source = 0; } valueButton->setEnabled(current_source != 12 && current_source != 0 && totalButton->isChecked()); dailyButton->setEnabled(current_source != 12 && current_source != 0 && totalButton->isChecked()); monthlyButton->setEnabled(current_source != 12 && current_source != 0 && totalButton->isChecked()); yearlyButton->setEnabled(current_source != 12 && current_source != 0 && totalButton->isChecked()); countButton->setEnabled(current_source != 12 && current_source != 0 && totalButton->isChecked()); perButton->setEnabled(current_source != 12 && current_source != 0 && totalButton->isChecked()); columnsLabel->setEnabled(current_source != 12 && current_source != 0); tagsButton->setEnabled(current_source != 12 && current_source != 0); catsButton->setEnabled(current_source != 12 && current_source != 0); totalButton->setEnabled(current_source != 12 && current_source != 0); categoryCombo->blockSignals(false); tagCombo->blockSignals(false); descriptionCombo->blockSignals(false); if(index == 4) tagChanged(); else updateDisplay(); } void OverTimeReport::saveConfig() { QSettings settings; settings.beginGroup("OverTimeReport"); settings.setValue("size", ((QDialog*) parent())->size()); settings.setValue("columns", tagsButton->isChecked() ? 2 : (catsButton->isChecked() ? 1 : 0)); settings.setValue("valueEnabled", valueButton->isChecked()); settings.setValue("dailyAverageEnabled", dailyButton->isChecked()); settings.setValue("monthlyAverageEnabled", monthlyButton->isChecked()); settings.setValue("yearlyAverageEnabled", yearlyButton->isChecked()); settings.setValue("transactionCountEnabled", countButton->isChecked()); settings.setValue("valuePerTransactionEnabled", perButton->isChecked()); settings.endGroup(); } void OverTimeReport::save() { QMimeDatabase db; QFileDialog fileDialog(this); fileDialog.setNameFilter(db.mimeTypeForName("text/html").filterString()); fileDialog.setDefaultSuffix(db.mimeTypeForName("text/html").preferredSuffix()); fileDialog.setAcceptMode(QFileDialog::AcceptSave); #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) fileDialog.setSupportedSchemes(QStringList("file")); #endif fileDialog.setDirectory(last_document_directory); QString url; if(!fileDialog.exec()) return; QStringList urls = fileDialog.selectedFiles(); if(urls.isEmpty()) return; url = urls[0]; QSaveFile ofile(url); ofile.open(QIODevice::WriteOnly); ofile.setPermissions((QFile::Permissions) 0x0660); if(!ofile.isOpen()) { ofile.cancelWriting(); QMessageBox::critical(this, tr("Error"), tr("Couldn't open file for writing.")); return; } last_document_directory = fileDialog.directory().absolutePath(); QTextStream outf(&ofile); #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) outf.setCodec("UTF-8"); #endif outf << source; if(!ofile.commit()) { QMessageBox::critical(this, tr("Error"), tr("Error while writing file; file was not saved.")); return; } } void OverTimeReport::print() { QPrinter printer; QPrintDialog print_dialog(&printer, this); if(print_dialog.exec() == QDialog::Accepted) { htmlview->print(&printer); } } void OverTimeReport::updateDisplay() { if(!isVisible() || block_display_update) return; bool b_tags = tagsButton->isChecked(), b_cats = catsButton->isChecked(); bool enabled[8]; enabled[0] = !b_tags && !b_cats && valueButton->isChecked(); enabled[1] = !b_tags && !b_cats && dailyButton->isChecked(); enabled[2] = !b_tags && !b_cats && monthlyButton->isChecked(); enabled[3] = !b_tags && !b_cats && yearlyButton->isChecked(); enabled[4] = !b_tags && !b_cats && countButton->isChecked(); enabled[5] = !b_tags && !b_cats && perButton->isChecked(); enabled[6] = false; enabled[7] = false; bool assets_selected = !accountCombo->allAccountsSelected(); bool single_assets = assets_selected && accountCombo->selectedAccounts().count() == 1; QList selected_categories; QVector monthly_values; month_info *mi = NULL; QDate first_date; AccountType at = ACCOUNT_TYPE_EXPENSES; CategoryAccount *cat = NULL; int type = 0; QString title, valuetitle, pertitle, expensetitle, sumtitle; switch(current_source) { case 0: { if(assets_selected) { type = 4; //: Noun, how much the account balance has changed title = tr("Change: %1").arg(accountCombo->selectedAccountsText(1)); valuetitle = tr("Deposit", "Money put into account"); expensetitle = tr("Withdrawal", "Money taken out from account"); //: Noun, how much the account balance has changed sumtitle = tr("Change"); } else { type = 0; title = tr("Profits"); valuetitle = tr("Incomes"); expensetitle = tr("Expenses"); sumtitle = title; } enabled[0] = true; enabled[1] = false; enabled[2] = false; enabled[3] = false; enabled[4] = false; enabled[5] = false; enabled[6] = true; enabled[7] = true; b_tags = false; b_cats = false; break; } case 1: { if(assets_selected) title = tr("Incomes, %1").arg(accountCombo->selectedAccountsText(2)); else title = tr("Incomes"); pertitle = tr("Average Income"); valuetitle = title; type = 1; at = ACCOUNT_TYPE_INCOMES; break; } case 2: { if(assets_selected) title = tr("Expenses, %1").arg(accountCombo->selectedAccountsText(2)); else title = tr("Expenses"); pertitle = tr("Average Cost"); valuetitle = title; type = 1; at = ACCOUNT_TYPE_EXPENSES; break; } case 5: { selected_categories = categoryCombo->selectedAccounts(); if(assets_selected) title = tr("Incomes, %2: %1").arg(categoryCombo->selectedAccountsText(1)).arg(accountCombo->selectedAccountsText(2)); else title = tr("Incomes: %1").arg(categoryCombo->selectedAccountsText(1)); pertitle = tr("Average Income"); valuetitle = tr("Incomes"); type = 2; at = ACCOUNT_TYPE_INCOMES; break; } case 6: { selected_categories = categoryCombo->selectedAccounts(); if(assets_selected) title = tr("Expenses, %2: %1").arg(categoryCombo->selectedAccountsText(1)).arg(accountCombo->selectedAccountsText(2)); else title = tr("Expenses: %1").arg(categoryCombo->selectedAccountsText(1)); pertitle = tr("Average Cost"); valuetitle = tr("Expenses"); type = 2; at = ACCOUNT_TYPE_EXPENSES; break; } case 9: { selected_categories = categoryCombo->selectedAccounts(); if(assets_selected) title = tr("Incomes, %3: %2, %1").arg(categoryCombo->selectedAccountsText(2)).arg(descriptionCombo->selectedItemsText(2)).arg(accountCombo->selectedAccountsText(2)); else title = tr("Incomes: %2, %1").arg(categoryCombo->selectedAccountsText(2)).arg(descriptionCombo->selectedItemsText(2)); pertitle = tr("Average Income"); valuetitle = tr("Incomes"); type = 3; at = ACCOUNT_TYPE_INCOMES; break; } case 10: { selected_categories = categoryCombo->selectedAccounts(); if(assets_selected) title = tr("Expenses, %3: %2, %1").arg(categoryCombo->selectedAccountsText(2)).arg(descriptionCombo->selectedItemsText(2)).arg(accountCombo->selectedAccountsText(2)); else title = tr("Expenses: %2, %1").arg(categoryCombo->selectedAccountsText(2)).arg(descriptionCombo->selectedItemsText(2)); pertitle = tr("Average Cost"); valuetitle = tr("Expenses"); type = 3; at = ACCOUNT_TYPE_EXPENSES; break; } case 12: { if(assets_selected) { title = tr("Value: %1").arg(accountCombo->selectedAccountsText(1)); type = 6; valuetitle = tr("Value"); } else { title = tr("Assets & Liabilities"); type = 5; valuetitle = tr("Assets"); expensetitle = tr("Liabilities"); sumtitle = tr("Total"); enabled[6] = true; enabled[7] = true; } enabled[0] = true; enabled[1] = false; enabled[2] = false; enabled[3] = false; enabled[4] = false; enabled[5] = false; b_tags = false; b_cats = false; break; } case 13: { if(tagCombo->selectedItems().isEmpty()) {htmlview->setHtml(""); return;} if(assets_selected) title = tr("%2: %1").arg(tagCombo->selectedItemsText(1)).arg(accountCombo->selectedAccountsText(1)); else title = tagCombo->selectedItemsText(1); pertitle = tr("Average Value"); valuetitle = tr("Value"); at = ACCOUNT_TYPE_ASSETS; type = 7; break; } case 14: { if(tagCombo->selectedItems().isEmpty()) {htmlview->setHtml(""); return;} if(assets_selected) title = tr("%3: %2, %1").arg(tagCombo->selectedItemsText(1)).arg(descriptionCombo->selectedItemsText(2)).arg(accountCombo->selectedAccountsText(2)); else title = tr("%2, %1").arg(tagCombo->selectedItemsText(1)).arg(descriptionCombo->selectedItemsText(2)); pertitle = tr("Average Value"); valuetitle = tr("Value"); at = ACCOUNT_TYPE_ASSETS; type = 8; break; } default: { htmlview->setHtml(""); return; } } if(selected_categories.count() == 1) { cat = (CategoryAccount*) selected_categories.at(0); } QDate start_date, first_trans_date; for(TransactionList::const_iterator it = budget->transactions.constBegin(); it != budget->transactions.constEnd(); ++it) { Transaction *trans = *it; if(!first_trans_date.isValid()) { first_trans_date = budget->firstBudgetDay(trans->date()); } if(((selected_categories.count() == 0 || categoryCombo->testTransactionRelation(trans)) && ((current_source != 13 && current_source != 14) || (tagCombo->testTransaction(trans) && (trans->type() == TRANSACTION_TYPE_EXPENSE || trans->type() == TRANSACTION_TYPE_INCOME))) && (!b_tags || trans->tagsCount(true) > 0) && (current_source == 12 || trans->fromAccount()->type() != ACCOUNT_TYPE_ASSETS || trans->toAccount()->type() != ACCOUNT_TYPE_ASSETS) && (!assets_selected || accountCombo->testTransactionRelation(trans))) || (current_source == 0 && assets_selected && accountCombo->testTransactionRelation(trans))) { start_date = trans->date(); if(!budget->isFirstBudgetDay(start_date)) { start_date = budget->firstBudgetDay(start_date); if(current_source == 12) budget->addBudgetMonthsSetFirst(start_date, -1); else if(start_date == first_trans_date) budget->addBudgetMonthsSetFirst(start_date, 1); } break; } } QDate curmonth = budget->firstBudgetDay(QDate::currentDate()); if(start_date.isNull() || start_date > curmonth) start_date = curmonth; if(start_date != first_trans_date) { if(budget->budgetYear(start_date) == budget->budgetYear(first_trans_date)) start_date = first_trans_date; else start_date = budget->firstBudgetDayOfYear(start_date); } if(start_date == curmonth) { budget->addBudgetMonthsSetFirst(start_date, -1); } first_date = start_date; QDate curdate = QDate::currentDate().addDays(-1); if(!budget->isLastBudgetDay(curdate)) { curdate = budget->lastBudgetDay(curdate); budget->addBudgetMonthsSetLast(curdate, -1); } if(curdate < first_date || budget->isSameBudgetMonth(start_date, curdate)) { curdate = QDate::currentDate(); } bool started = false; bool b_income = false, b_expense = false; bool includes_planned = false; QMap tag_includes_planned; QMap cat_includes_planned; if(b_tags) {for(int i = 0; i < budget->tags.count(); i++) tag_includes_planned[budget->tags[i]] = false;} if(b_cats) { if(cat) { for(AccountList::const_iterator it = cat->subCategories.constBegin(); it != cat->subCategories.constEnd(); ++it) cat_includes_planned[*it] = false; cat_includes_planned[cat] = false; } else if(selected_categories.count() > 0) { for(QList::const_iterator it = selected_categories.constBegin(); it != selected_categories.constEnd(); ++it) cat_includes_planned[*it] = false; } else { if(at != ACCOUNT_TYPE_EXPENSES) {for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) cat_includes_planned[*it] = false;} if(at != ACCOUNT_TYPE_INCOMES) {for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) cat_includes_planned[*it] = false;} } } for(TransactionList::const_iterator it = budget->transactions.constBegin(); it != budget->transactions.constEnd(); ++it) { Transaction *trans = *it; if(trans->date() > curdate) break; bool include = false; int sign = 1; if(!started && trans->date() >= first_date) started = true; if(started && (!assets_selected || accountCombo->testTransactionRelation(trans, type == 6)) && ((current_source != 13 && current_source != 14) || tagCombo->testTransaction(trans))) { if(type == 7 || (type == 8 && descriptionCombo->testTransaction(trans))) { include = true; if(trans->type() == TRANSACTION_TYPE_EXPENSE) {b_expense = true; sign = -1;} else if(trans->type() == TRANSACTION_TYPE_INCOME) {b_income = true; sign = 1;} else include = false; } else if(type >= 4 && type != 8) { include = true; } else if((type == 1 && trans->fromAccount()->type() == at) || (type == 2 && (categoryCombo->accountSelected(trans->fromAccount()) || categoryCombo->accountSelected(trans->fromAccount()->topAccount()))) || (type == 3 && (categoryCombo->accountSelected(trans->fromAccount()) || categoryCombo->accountSelected(trans->fromAccount()->topAccount())) && descriptionCombo->testTransaction(trans)) || (type == 0 && trans->fromAccount()->type() != ACCOUNT_TYPE_ASSETS)) { if(type == 0) sign = 1; else if(at == ACCOUNT_TYPE_INCOMES) sign = 1; else sign = -1; include = true; } else if((type == 1 && trans->toAccount()->type() == at) || (type == 2 && (categoryCombo->accountSelected(trans->toAccount()) || categoryCombo->accountSelected(trans->toAccount()->topAccount()))) || (type == 3 && (categoryCombo->accountSelected(trans->toAccount()) || categoryCombo->accountSelected(trans->toAccount()->topAccount())) && descriptionCombo->testTransaction(trans)) || (type == 0 && trans->toAccount()->type() != ACCOUNT_TYPE_ASSETS)) { if(type == 0) sign = -1; else if(at == ACCOUNT_TYPE_INCOMES) sign = -1; else sign = 1; include = true; } } if(include) { if(!mi || trans->date() > mi->date) { QDate newdate, olddate; newdate = budget->lastBudgetDay(trans->date()); if(mi) { olddate = mi->date; budget->addBudgetMonthsSetLast(olddate, 1); } else { olddate = budget->lastBudgetDay(first_date); } while(olddate < newdate) { monthly_values.append(month_info()); mi = &monthly_values.back(); mi->value = 0.0; mi->count = 0.0; mi->date = olddate; if(b_tags) {for(int i = 0; i < budget->tags.count(); i++) mi->tags[budget->tags[i]] = 0.0;} if(b_cats) { if(cat) { for(AccountList::const_iterator it = cat->subCategories.constBegin(); it != cat->subCategories.constEnd(); ++it) mi->cats[*it] = 0.0; mi->cats[cat] = 0.0; } else if(selected_categories.count() > 0) { for(QList::const_iterator it = selected_categories.constBegin(); it != selected_categories.constEnd(); ++it) mi->cats[*it] = 0.0; } else { if(at != ACCOUNT_TYPE_EXPENSES) {for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) mi->cats[*it] = 0.0;} if(at != ACCOUNT_TYPE_INCOMES) {for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) mi->cats[*it] = 0.0;} } } budget->addBudgetMonthsSetLast(olddate, 1); } monthly_values.append(month_info()); mi = &monthly_values.back(); if(b_tags) {for(int i = 0; i < budget->tags.count(); i++) mi->tags[budget->tags[i]] = 0.0;} if(b_cats) { if(cat) { for(AccountList::const_iterator it = cat->subCategories.constBegin(); it != cat->subCategories.constEnd(); ++it) mi->cats[*it] = 0.0; mi->cats[cat] = 0.0; } else if(selected_categories.count() > 0) { for(QList::const_iterator it = selected_categories.constBegin(); it != selected_categories.constEnd(); ++it) mi->cats[*it] = 0.0; } else { if(at != ACCOUNT_TYPE_EXPENSES) {for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) mi->cats[*it] = 0.0;} if(at != ACCOUNT_TYPE_INCOMES) {for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) mi->cats[*it] = 0.0;} } } if(type == 0) { if(sign == 1) mi->value = trans->value(!single_assets); else mi->expense = trans->value(!single_assets); mi->count = trans->quantity(); } else if(type == 4) { if(accountCombo->transactionChange(trans) >= 0.0) mi->value = accountCombo->transactionChange(trans); else mi->expense = -accountCombo->transactionChange(trans); mi->count = 1.0; } else if(type == 6) { mi->value = accountCombo->transactionChange(trans, true); mi->count = 1.0; } else if(type == 5) { mi->expense = 0.0; mi->value = 0.0; if(trans->fromAccount()->type() == ACCOUNT_TYPE_ASSETS) { if(((AssetsAccount*) trans->fromAccount())->accountType() == ASSETS_TYPE_LIABILITIES || ((AssetsAccount*) trans->fromAccount())->accountType() == ASSETS_TYPE_CREDIT_CARD) mi->expense -= trans->value(true); else if(((AssetsAccount*) trans->fromAccount())->accountType() != ASSETS_TYPE_SECURITIES && trans->fromAccount() != budget->balancingAccount) mi->value -= trans->value(true); } if(trans->toAccount()->type() == ACCOUNT_TYPE_ASSETS) { if(((AssetsAccount*) trans->toAccount())->accountType() == ASSETS_TYPE_LIABILITIES || ((AssetsAccount*) trans->toAccount())->accountType() == ASSETS_TYPE_CREDIT_CARD) mi->expense += trans->value(true); else if(((AssetsAccount*) trans->toAccount())->accountType() != ASSETS_TYPE_SECURITIES && trans->toAccount() != budget->balancingAccount) mi->value += trans->value(true); } } else { mi->value = trans->value(!single_assets) * sign; mi->count = trans->quantity(); } if(b_tags) {for(int i = 0; i < trans->tagsCount(true); i++) mi->tags[trans->getTag(i, true)] = mi->value;} if(b_cats) { if((at == ACCOUNT_TYPE_ASSETS && (trans->fromAccount()->type() == ACCOUNT_TYPE_INCOMES || trans->fromAccount()->type() == ACCOUNT_TYPE_EXPENSES)) || (at != ACCOUNT_TYPE_ASSETS && trans->fromAccount()->type() == at)) mi->cats[cat ? trans->fromAccount() : trans->fromAccount()->topAccount()] = mi->value; else if((at == ACCOUNT_TYPE_ASSETS && (trans->toAccount()->type() == ACCOUNT_TYPE_INCOMES || trans->toAccount()->type() == ACCOUNT_TYPE_EXPENSES)) || (at != ACCOUNT_TYPE_ASSETS && trans->toAccount()->type() == at)) mi->cats[cat ? trans->toAccount() : trans->toAccount()->topAccount()] = mi->value; } mi->date = newdate; } else { if(type == 0) { if(sign == 1) mi->value += trans->value(!single_assets); else mi->expense += trans->value(!single_assets); mi->count += trans->quantity(); } else if(type == 4) { if(accountCombo->transactionChange(trans) >= 0.0) mi->value += accountCombo->transactionChange(trans); else mi->expense -= accountCombo->transactionChange(trans); mi->count++; } else if(type == 6) { mi->value += accountCombo->transactionChange(trans, true); mi->count++; } else if(type == 5) { if(trans->fromAccount()->type() == ACCOUNT_TYPE_ASSETS) { if(((AssetsAccount*) trans->fromAccount())->accountType() == ASSETS_TYPE_LIABILITIES || ((AssetsAccount*) trans->fromAccount())->accountType() == ASSETS_TYPE_CREDIT_CARD) mi->expense -= trans->value(true); else if(((AssetsAccount*) trans->fromAccount())->accountType() != ASSETS_TYPE_SECURITIES && trans->fromAccount() != budget->balancingAccount) mi->value -= trans->value(true); } if(trans->toAccount()->type() == ACCOUNT_TYPE_ASSETS) { if(((AssetsAccount*) trans->toAccount())->accountType() == ASSETS_TYPE_LIABILITIES || ((AssetsAccount*) trans->toAccount())->accountType() == ASSETS_TYPE_CREDIT_CARD) mi->expense += trans->value(true); else if(((AssetsAccount*) trans->toAccount())->accountType() != ASSETS_TYPE_SECURITIES && trans->toAccount() != budget->balancingAccount) mi->value += trans->value(true); } } else { double v = trans->value(!single_assets) * sign; mi->value += v; mi->count += trans->quantity(); if(b_tags) {for(int i = 0; i < trans->tagsCount(true); i++) mi->tags[trans->getTag(i, true)] += v;} if(b_cats) { if((at == ACCOUNT_TYPE_ASSETS && (trans->fromAccount()->type() == ACCOUNT_TYPE_INCOMES || trans->fromAccount()->type() == ACCOUNT_TYPE_EXPENSES)) || (at != ACCOUNT_TYPE_ASSETS && trans->fromAccount()->type() == at)) mi->cats[trans->fromAccount()] += v; else if((at == ACCOUNT_TYPE_ASSETS && (trans->toAccount()->type() == ACCOUNT_TYPE_INCOMES || trans->toAccount()->type() == ACCOUNT_TYPE_EXPENSES)) || (at != ACCOUNT_TYPE_ASSETS && trans->toAccount()->type() == at)) mi->cats[trans->toAccount()] += v; } } } } } if(mi) { while(mi->date < curdate) { QDate newdate = mi->date; budget->addBudgetMonthsSetLast(newdate, 1); monthly_values.append(month_info()); mi = &monthly_values.back(); mi->value = 0.0; mi->expense = 0.0; mi->count = 0.0; mi->date = newdate; if(b_tags) {for(int i = 0; i < budget->tags.count(); i++) mi->tags[budget->tags[i]] = 0.0;} if(b_cats) { if(cat) { for(AccountList::const_iterator it = cat->subCategories.constBegin(); it != cat->subCategories.constEnd(); ++it) mi->cats[*it] = 0.0; mi->cats[cat] = 0.0; } else if(selected_categories.count() > 0) { for(QList::const_iterator it = selected_categories.constBegin(); it != selected_categories.constEnd(); ++it) mi->cats[*it] = 0.0; } else { if(at != ACCOUNT_TYPE_EXPENSES) {for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) mi->cats[*it] = 0.0;} if(at != ACCOUNT_TYPE_INCOMES) {for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) mi->cats[*it] = 0.0;} } } } } double scheduled_value = 0.0; double scheduled_expense = 0.0; double scheduled_count = 0.0; QMap tag_scheduled_value; QMap cat_scheduled_value; if(b_tags) {for(int i = 0; i < budget->tags.count(); i++) tag_scheduled_value[budget->tags[i]] = 0.0;} if(b_cats) { if(cat) { for(AccountList::const_iterator it = cat->subCategories.constBegin(); it != cat->subCategories.constEnd(); ++it) cat_scheduled_value[*it] = 0.0; cat_scheduled_value[cat] = 0.0; } else if(selected_categories.count() > 0) { for(QList::const_iterator it = selected_categories.constBegin(); it != selected_categories.constEnd(); ++it) cat_scheduled_value[*it] = 0.0; } else { if(at != ACCOUNT_TYPE_EXPENSES) {for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) cat_scheduled_value[*it] = 0.0;} if(at != ACCOUNT_TYPE_INCOMES) {for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) cat_scheduled_value[*it] = 0.0;} } } if(mi) { int split_i = 0; for(ScheduledTransactionList::const_iterator it = budget->scheduledTransactions.constBegin(); it != budget->scheduledTransactions.constEnd();) { ScheduledTransaction *strans = *it; if(strans->firstOccurrence() > mi->date) break; started = true; if(split_i == 0 && strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT && ((SplitTransaction*) strans->transaction())->count() == 0) { do { ++it; if(it == budget->scheduledTransactions.constEnd()) { strans = NULL; break; } strans = *it; if(strans->firstOccurrence() > mi->date) { strans = NULL; break; } } while(split_i == 0 && strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT && ((SplitTransaction*) strans->transaction())->count() == 0); if(!strans) break; } Transaction *trans = NULL; if(strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { trans = ((SplitTransaction*) strans->transaction())->at(split_i); split_i++; } else { trans = (Transaction*) strans->transaction(); } bool include = false; int sign = 1; if((!assets_selected || accountCombo->testTransactionRelation(trans, type == 6)) && ((current_source != 13 && current_source != 14) || tagCombo->testTransaction(trans))) { if(type == 7 || (type == 8 && descriptionCombo->testTransaction(trans))) { include = true; if(trans->type() == TRANSACTION_TYPE_EXPENSE) {b_expense = true; sign = -1;} else if(trans->type() == TRANSACTION_TYPE_INCOME) {b_income = true; sign = 1;} else include = false; } else if(type >= 4 && type != 8) { include = true; } else if((type == 1 && trans->fromAccount()->type() == at) || (type == 2 && (categoryCombo->accountSelected(trans->fromAccount()) || categoryCombo->accountSelected(trans->fromAccount()->topAccount()))) || (type == 3 && (categoryCombo->accountSelected(trans->fromAccount()) || categoryCombo->accountSelected(trans->fromAccount()->topAccount())) && descriptionCombo->testTransaction(trans)) || (type == 0 && trans->fromAccount()->type() != ACCOUNT_TYPE_ASSETS)) { if(type == 0) sign = 1; else if(at == ACCOUNT_TYPE_INCOMES) sign = 1; else sign = -1; include = true; } else if((type == 1 && trans->toAccount()->type() == at) || (type == 2 && (categoryCombo->accountSelected(trans->toAccount()) || categoryCombo->accountSelected(trans->toAccount()->topAccount()))) || (type == 3 && (categoryCombo->accountSelected(trans->toAccount()) || categoryCombo->accountSelected(trans->toAccount()->topAccount())) && descriptionCombo->testTransaction(trans)) || (type == 0 && trans->toAccount()->type() != ACCOUNT_TYPE_ASSETS)) { if(type == 0) sign = -1; else if(at == ACCOUNT_TYPE_INCOMES) sign = -1; else sign = 1; include = true; } } if(include) { int count = (strans->recurrence() ? strans->recurrence()->countOccurrences(mi->date) : 1); if(count != 0) { includes_planned = true; if(type == 0) { if(sign == 1) scheduled_value += (trans->value(!single_assets) * count); else scheduled_expense += (trans->value(!single_assets) * count); scheduled_count += count * trans->quantity(); } else if(type == 4) { if(accountCombo->transactionChange(trans) >= 0.0) scheduled_value += accountCombo->transactionChange(trans) * count; else scheduled_expense -= accountCombo->transactionChange(trans) * count; scheduled_count += count; } else if(type == 6) { scheduled_value += accountCombo->transactionChange(trans, true) * count; scheduled_count += count; } else if(type == 5) { if(trans->fromAccount()->type() == ACCOUNT_TYPE_ASSETS) { if(((AssetsAccount*) trans->fromAccount())->accountType() == ASSETS_TYPE_LIABILITIES || ((AssetsAccount*) trans->fromAccount())->accountType() == ASSETS_TYPE_CREDIT_CARD) scheduled_expense -= trans->value(true) * count; else if(((AssetsAccount*) trans->fromAccount())->accountType() != ASSETS_TYPE_SECURITIES && trans->fromAccount() != budget->balancingAccount) scheduled_value -= trans->value(true) * count; } if(trans->toAccount()->type() == ACCOUNT_TYPE_ASSETS) { if(((AssetsAccount*) trans->toAccount())->accountType() == ASSETS_TYPE_LIABILITIES || ((AssetsAccount*) trans->toAccount())->accountType() == ASSETS_TYPE_CREDIT_CARD) scheduled_expense += trans->value(true) * count; else if(((AssetsAccount*) trans->toAccount())->accountType() != ASSETS_TYPE_SECURITIES && trans->toAccount() != budget->balancingAccount) scheduled_value += trans->value(true) * count; } } else { double v = (trans->value(!single_assets) * sign * count); scheduled_value += v; scheduled_count += count * trans->quantity(); if(b_tags) { for(int i = 0; i < trans->tagsCount(true); i++) {tag_scheduled_value[trans->getTag(i, true)] += v; tag_includes_planned[trans->getTag(i, true)] = true;} } if(b_cats) { if((at == ACCOUNT_TYPE_ASSETS && (trans->fromAccount()->type() == ACCOUNT_TYPE_INCOMES || trans->fromAccount()->type() == ACCOUNT_TYPE_EXPENSES)) || (at != ACCOUNT_TYPE_ASSETS && trans->fromAccount()->type() == at)) {cat_scheduled_value[trans->fromAccount()] += v; cat_includes_planned[trans->fromAccount()] = true;} else if((at == ACCOUNT_TYPE_ASSETS && (trans->toAccount()->type() == ACCOUNT_TYPE_INCOMES || trans->toAccount()->type() == ACCOUNT_TYPE_EXPENSES)) || (at != ACCOUNT_TYPE_ASSETS && trans->toAccount()->type() == at)) {cat_scheduled_value[trans->toAccount()] += v; cat_includes_planned[trans->toAccount()] = true;} } } } } if(strans->transaction()->generaltype() != GENERAL_TRANSACTION_TYPE_SPLIT || split_i >= ((SplitTransaction*) strans->transaction())->count()) { ++it; split_i = 0; } } } if(monthly_values.isEmpty()) { monthly_values.append(month_info()); mi = &monthly_values.back(); mi->value = 0.0; mi->expense = 0.0; mi->count = 0.0; mi->date = budget->lastBudgetDay(first_date); while(mi->date < curdate) { QDate newdate = mi->date; budget->addBudgetMonthsSetLast(newdate, 1); monthly_values.append(month_info()); mi = &monthly_values.back(); mi->value = 0.0; mi->expense = 0.0; mi->count = 0.0; mi->date = newdate; if(b_tags) {for(int i = 0; i < budget->tags.count(); i++) mi->tags[budget->tags[i]] = 0.0;} if(b_cats) { if(cat) { for(AccountList::const_iterator it = cat->subCategories.constBegin(); it != cat->subCategories.constEnd(); ++it) mi->cats[*it] = 0.0; mi->cats[cat] = 0.0; } else if(selected_categories.count() > 0) { for(QList::const_iterator it = selected_categories.constBegin(); it != selected_categories.constEnd(); ++it) mi->cats[*it] = 0.0; } else { if(at != ACCOUNT_TYPE_EXPENSES) {for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) mi->cats[*it] = 0.0;} if(at != ACCOUNT_TYPE_INCOMES) {for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) mi->cats[*it] = 0.0;} } } } } Currency *currency = budget->defaultCurrency(); if(single_assets) currency = ((AssetsAccount*) accountCombo->selectedAccounts()[0])->currency(); if(current_source == 12) { if(type == 6) { QList account_list = accountCombo->selectedAccounts(); double total_value = 0.0; for(QList::const_iterator it = account_list.constBegin(); it != account_list.constEnd(); ++it) { AssetsAccount *current_assets = (AssetsAccount*) *it; if(current_assets->accountType() != ASSETS_TYPE_SECURITIES) { total_value += current_assets->currency()->convertTo(current_assets->initialBalance(false), currency, start_date); } } QVector::iterator it_b = monthly_values.begin(); QVector::iterator it_e = monthly_values.end(); while(it_b != it_e) { total_value += it_b->value; it_b->value = total_value; for(QList::const_iterator it = account_list.constBegin(); it != account_list.constEnd(); ++it) { AssetsAccount *current_assets = (AssetsAccount*) *it; if(current_assets->accountType() == ASSETS_TYPE_SECURITIES) { for(SecurityList::const_iterator it_s = budget->securities.constBegin(); it_s != budget->securities.constEnd(); ++it_s) { if((*it_s)->account() == current_assets) { it_b->value += current_assets->currency()->convertTo((*it_s)->value(it_b->date, -1), currency, it_b->date); } } } } it_b++; } } else if(type == 5) { double total_value = 0.0, total_expense = 0.0; for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { AssetsAccount *account = *it; if(account->accountType() == ASSETS_TYPE_LIABILITIES || account->accountType() == ASSETS_TYPE_CREDIT_CARD) total_expense += account->currency()->convertTo(account->initialBalance(false), budget->defaultCurrency(), start_date); else total_value += account->currency()->convertTo(account->initialBalance(false), budget->defaultCurrency(), start_date); } QVector::iterator it_b = monthly_values.begin(); QVector::iterator it_e = monthly_values.end(); while(it_b != it_e) { total_value += it_b->value; it_b->value = total_value; total_expense += it_b->expense; it_b->expense = total_expense; it_b++; } for(SecurityList::const_iterator it = budget->securities.constBegin(); it != budget->securities.constEnd(); ++it) { Security *sec = *it; it_b = monthly_values.begin(); it_e = monthly_values.end(); while(it_b != it_e) { it_b->value += sec->currency()->convertTo(sec->value(it_b->date, -1), budget->defaultCurrency(), it_b->date); it_b++; } } } } QStringList tags; if(b_tags) { for(int i = 0; i < budget->tags.count(); i++) { if(tag_includes_planned[budget->tags[i]]) { tags << budget->tags[i]; } else { for(QVector::iterator mit = monthly_values.begin(); mit != monthly_values.end(); ++mit) { if(mit->tags[budget->tags[i]] != 0.0) { tags << budget->tags[i]; break; } } } } if(tags.isEmpty()) tags = budget->tags; } QVector cats; if(b_cats) { if(cat) { if(cat->subCategories.isEmpty()) { cats << cat; } else { for(AccountList::const_iterator it = cat->subCategories.constBegin(); it != cat->subCategories.constEnd(); ++it) { cats << *it; } if(cat_includes_planned[cat]) { cats << cat; } else { for(QVector::iterator mit = monthly_values.begin(); mit != monthly_values.end(); ++mit) { if(mit->cats[cat] != 0.0) { cats << cat; break; } } } } } else if(selected_categories.count() > 0) { Account *acc = NULL; bool b_subs = true; for(QList::const_iterator it = selected_categories.constBegin(); it != selected_categories.constEnd(); ++it) { bool b = false; if(cat_includes_planned[*it]) { b = true; } else { for(QVector::iterator mit = monthly_values.begin(); mit != monthly_values.end(); ++mit) { if(mit->cats[*it] != 0.0) { b = true; break; } } } if(b) { if(!acc) acc = (*it)->topAccount(); else if(acc != (*it)->topAccount()) b_subs = false; cats << *it; } } if(!b_subs) { for(int i = 0; i < cats.count();) { Account *acc = cats[i]->topAccount(); if(acc != cats[i]) { if(!cat_includes_planned[acc]) cat_includes_planned[acc] = cat_includes_planned[cats[i]]; cat_scheduled_value[acc] += cat_scheduled_value[cats[i]]; for(QVector::iterator mit = monthly_values.begin(); mit != monthly_values.end(); ++mit) { mit->cats[acc] += mit->cats[cats[i]]; } cats.removeAt(i); if(!cats.contains(acc)) cats << acc; } else { i++; } } } else if(cats.isEmpty()) { b_subs = false; for(QList::const_iterator it = selected_categories.constBegin(); it != selected_categories.constEnd(); ++it) { if(*it == (*it)->topAccount()) { cats << *it; } } } } else { Account *acc = NULL; bool b_subs = true; if(at != ACCOUNT_TYPE_EXPENSES) { for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) { bool b = false; if(cat_includes_planned[*it]) { b = true; } else { for(QVector::iterator mit = monthly_values.begin(); mit != monthly_values.end(); ++mit) { if(mit->cats[*it] != 0.0) { b = true; break; } } } if(b) { if(!acc) acc = (*it)->topAccount(); else if(acc != (*it)->topAccount()) b_subs = false; cats << *it; } } } if(at != ACCOUNT_TYPE_INCOMES) { for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) { bool b = false; if(cat_includes_planned[*it]) { b = true; } else { for(QVector::iterator mit = monthly_values.begin(); mit != monthly_values.end(); ++mit) { if(mit->cats[*it] != 0.0) { b = true; break; } } } if(b) { if(!acc) acc = (*it)->topAccount(); else if(acc != (*it)->topAccount()) b_subs = false; cats << *it; } } } if(!b_subs) { for(int i = 0; i < cats.count();) { Account *acc = cats[i]->topAccount(); if(acc != cats[i]) { if(!cat_includes_planned[acc]) cat_includes_planned[acc] = cat_includes_planned[cats[i]]; cat_scheduled_value[acc] += cat_scheduled_value[cats[i]]; for(QVector::iterator mit = monthly_values.begin(); mit != monthly_values.end(); ++mit) { mit->cats[acc] += mit->cats[cats[i]]; } cats.removeAt(i); if(!cats.contains(acc)) cats << acc; } else { i++; } } } else if(cats.isEmpty()) { b_subs = false; if(at != ACCOUNT_TYPE_EXPENSES) { for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) { if(*it == (*it)->topAccount()) { cats << *it; } } } if(at != ACCOUNT_TYPE_INCOMES) { for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) { if(*it == (*it)->topAccount()) { cats << *it; } } } } } } if(current_source == 13 || current_source == 14) { if(b_expense && !b_income) { pertitle = tr("Average Cost"); valuetitle = tr("Expenses"); for(QVector::iterator mit = monthly_values.begin(); mit != monthly_values.end(); ++mit) { mit->value = -mit->value; mit->expense = -mit->expense; if(b_tags) { for(int i = 0; i < tags.count(); i++) { mit->tags[tags[i]] = -mit->tags[tags[i]]; } } if(b_cats) { for(int i = 0; i < cats.count(); i++) { mit->cats[cats[i]] = -mit->cats[cats[i]]; } } } scheduled_value = -scheduled_value; scheduled_expense = -scheduled_expense; if(b_tags) { for(int i = 0; i < tags.count(); i++) { tag_scheduled_value[tags[i]] = -tag_scheduled_value[tags[i]]; } } if(b_cats) { for(int i = 0; i < cats.count(); i++) { cat_scheduled_value[cats[i]] = -cat_scheduled_value[cats[i]]; } } if(current_source == 13) { if(assets_selected) title = tr("Expenses, %2: %1").arg(tagCombo->selectedItemsText(1)).arg(accountCombo->selectedAccountsText(2)); else title = tr("Expenses: %1").arg(tagCombo->selectedItemsText(1)); } else { if(assets_selected) title = tr("Expenses, %3: %2, %1").arg(tagCombo->selectedItemsText(2)).arg(descriptionCombo->selectedItemsText(2)).arg(accountCombo->selectedAccountsText(2)); else title = tr("Expenses: %2, %1").arg(tagCombo->selectedItemsText(2)).arg(descriptionCombo->selectedItemsText(2)); } } else if(b_income && !b_expense) { pertitle = tr("Average Income"); valuetitle = tr("Incomes"); if(current_source == 13) { if(assets_selected) title = tr("Incomes, %2: %1").arg(tagCombo->selectedItemsText(1)).arg(accountCombo->selectedAccountsText(2)); else title = tr("Incomes: %1").arg(tagCombo->selectedItemsText(1)); } else { if(assets_selected) title = tr("Incomes, %3: %2, %1").arg(tagCombo->selectedItemsText(2)).arg(descriptionCombo->selectedItemsText(2)).arg(accountCombo->selectedAccountsText(2)); else title = tr("Incomes: %2, %1").arg(tagCombo->selectedItemsText(2)).arg(descriptionCombo->selectedItemsText(2)); } } } double average_month = budget->averageMonth(first_date, curdate, true); double average_year = budget->averageYear(first_date, curdate, true); source = ""; QTextStream outf(&source, QIODevice::WriteOnly); outf << "" << '\n'; outf << "" << '\n'; outf << "\t" << '\n'; outf << "\t\t"; outf << htmlize_string(title); outf << "" << '\n'; outf << "\t\t" << '\n'; outf << "\t\tapplicationDisplayName() << "\">" << '\n'; outf << "\t" << '\n'; outf << "\t" << '\n'; outf << "\t\t

    " << htmlize_string(title) << "

    " << '\n' << "\t\t
    "; outf << "\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t\t" << '\n'; outf << "\t\t\t\t\t"; outf << "\t\t\t\t\t"; bool use_footer1 = false; if(enabled[0]) { outf << "\t\t\t\t\t"; } if(enabled[1]) outf << "\t\t\t\t\t"; if(enabled[2]) outf << "\t\t\t\t\t"; if(enabled[3]) outf << "\t\t\t\t\t"; if(enabled[4]) { outf << "\t\t\t\t\t"; } if(enabled[5]) { outf << "\t\t\t\t\t"; } if(enabled[6]) { outf << "\t\t\t\t\t"; } if(enabled[7]) { outf << "\t\t\t\t\t"; } if(b_tags) { for(int i = 0; i < tags.count(); i++) { outf << "\t\t\t\t\t"; } } if(b_cats) { for(int i = 0; i < cats.count(); i++) { outf << "\t\t\t\t\t"; } if(cats.count() > 1) { outf << "\t\t\t\t\t"; } } outf << "\t\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; QVector::iterator it_b = monthly_values.begin(); QVector::iterator it_e = monthly_values.end(); if(it_e != it_b) --it_e; QVector::iterator it = monthly_values.end(); int year = 0; double yearly_value = 0.0, total_value = 0.0; double yearly_expense = 0.0, total_expense = 0.0; double yearly_count = 0.0, total_count = 0.0; QMap tag_total_value, tag_yearly_value; QMap cat_total_value, cat_yearly_value; if(b_tags) {for(int i = 0; i < tags.count(); i++) {tag_yearly_value[tags[i]] = 0.0; tag_total_value[tags[i]] = 0.0;}} if(b_cats) {for(int i = 0; i < cats.count(); i++) {cat_yearly_value[cats[i]] = 0.0; cat_total_value[cats[i]] = 0.0;}} QDate year_date; bool first_year = true, first_month = true; bool multiple_months = monthly_values.size() > 1; bool multiple_years = multiple_months && budget->budgetYear(first_date) != budget->budgetYear(curdate); int i_count_frac = 0; double intpart = 0.0; while(it != it_b) { --it; if(modf(it->count, &intpart) != 0.0) { i_count_frac = 2; break; } } it = monthly_values.end(); while(it != it_b) { --it; if(first_month || year != budget->budgetYear(it->date)) { if(!first_month && multiple_years && current_source != 12) { outf << "\t\t\t\t" << '\n'; outf << "\t\t\t\t\t"; outf << "\t\t\t\t\t"; if(enabled[0]) outf << ""; int days = 1; if(first_year) { days = budget->dayOfBudgetYear(curdate); } else if(budget->budgetYear(first_date) == year) { days = budget->daysInBudgetYear(year_date); days -= (budget->dayOfBudgetYear(first_date) - 1); } else { days = budget->daysInBudgetYear(year_date); } if(enabled[1]) outf << ""; if(enabled[2]) outf << ""; if(enabled[3]) outf << ""; if(enabled[4]) outf << ""; double pervalue = 0.0; if(first_year) { pervalue = (((yearly_count + scheduled_count) == 0.0) ? 0.0 : ((yearly_value + scheduled_value) / (yearly_count + scheduled_count))); } else { pervalue = (yearly_count == 0.0 ? 0.0 : (yearly_value / yearly_count)); } if(enabled[5]) outf << ""; if(enabled[6]) outf << ""; if(enabled[7]) outf << ""; if(b_tags) { for(int i = 0; i < tags.count(); i++) { outf << ""; } } if(b_cats) { for(int i = 0; i < cats.count(); i++) { outf << ""; } if(cats.count() > 1) outf << ""; } first_year = false; outf << "\n"; outf << "\t\t\t\t" << '\n'; outf << "\t\t\t\t" << '\n'; } else if(!first_month && multiple_years && current_source == 12) { outf << "\t\t\t\t" << '\n'; } else { outf << "\t\t\t\t" << '\n'; } year = budget->budgetYear(it->date); yearly_value = it->value; yearly_expense = it->expense; yearly_count = it->count; year_date = it->date; if(b_tags) {for(int i = 0; i < tags.count(); i++) tag_yearly_value[tags[i]] = it->tags[tags[i]];} if(b_cats) {for(int i = 0; i < cats.count(); i++) cat_yearly_value[cats[i]] = it->cats[cats[i]];} outf << "\t\t\t\t\t"; } else { outf << "\t\t\t\t" << '\n'; yearly_value += it->value; yearly_expense += it->expense; yearly_count += it->count; if(b_tags) {for(int i = 0; i < tags.count(); i++) tag_yearly_value[tags[i]] += it->tags[tags[i]];} if(b_cats) {for(int i = 0; i < cats.count(); i++) cat_yearly_value[cats[i]] += it->cats[cats[i]];} outf << "\t\t\t\t\t"; } total_value += it->value; total_expense += it->expense; total_count += it->count; outf << "\t\t\t\t\t"; if(enabled[0]) outf << ""; int days = 0; if(first_month) { days = budget->dayOfBudgetMonth(curdate); } else if(it == it_b) { days = budget->daysInBudgetMonth(it->date); days -= (budget->dayOfBudgetMonth(first_date) - 1); } else { days = budget->dayOfBudgetMonth(it->date); } if(enabled[1]) outf << ""; if(enabled[2]) outf << ""; if(enabled[3]) outf << ""; if(enabled[4]) outf << ""; if(enabled[5]) { double pervalue = 0.0; if(first_month) { pervalue = (((it->count + scheduled_count) == 0.0) ? 0.0 : ((it->value + scheduled_value) / (it->count + scheduled_count))); } else { pervalue = (it->count == 0.0 ? 0.0 : (it->value / it->count)); } outf << ""; } if(enabled[6]) outf << ""; if(enabled[7]) outf << ""; if(b_tags) { for(int i = 0; i < tags.count(); i++) { tag_total_value[tags[i]] += it->tags[tags[i]]; outf << ""; } } if(b_cats) { for(int i = 0; i < cats.count(); i++) { cat_total_value[cats[i]] += it->cats[cats[i]]; outf << ""; } if(cats.count() > 1) outf << ""; } first_month = false; outf << "\n"; outf << "\t\t\t\t" << '\n'; } if(multiple_years && current_source != 12) { outf << "\t\t\t\t" << '\n'; outf << "\t\t\t\t\t"; outf << "\t\t\t\t\t"; if(enabled[0]) outf << ""; int days = budget->daysInBudgetYear(year_date); days -= (budget->dayOfBudgetYear(first_date) - 1); if(enabled[1]) outf << ""; if(enabled[2]) outf << ""; if(enabled[3]) outf << ""; if(enabled[4]) outf << ""; if(enabled[5]) outf << ""; if(enabled[6]) outf << ""; if(enabled[7]) outf << ""; if(b_tags) { for(int i = 0; i < tags.count(); i++) { outf << ""; } } if(b_cats) { for(int i = 0; i < cats.count(); i++) { outf << ""; } if(cats.count() > 1) outf << ""; } outf << "\n"; outf << "\t\t\t\t" << '\n'; } if(multiple_months && current_source != 12) { outf << "\t\t\t\t" << '\n'; int days = first_date.daysTo(curdate) + 1; outf << "\t\t\t\t\t"; outf << "\t\t\t\t\t"; if(enabled[0]) outf << ""; if(enabled[1]) outf << ""; if(enabled[2]) outf << ""; if(enabled[3]) outf << ""; if(enabled[4]) outf << ""; if(enabled[5]) outf << ""; if(enabled[6]) outf << ""; if(enabled[7]) outf << ""; if(b_tags) { for(int i = 0; i < tags.count(); i++) { outf << ""; } } if(b_cats) { for(int i = 0; i < cats.count(); i++) { outf << ""; } if(cats.count() > 1) outf << ""; } outf << "\n"; outf << "\t\t\t\t" << '\n'; } outf << "\t\t\t" << '\n'; outf << "\t\t
    " << htmlize_string(tr("Year")) << "" << htmlize_string(tr("Month")) << "" << htmlize_string(valuetitle); if(includes_planned) {outf << "*"; use_footer1 = true;} outf<< "" << htmlize_string(tr("Daily Average")) << "" << htmlize_string(tr("Monthly Average")) << (use_footer1 ? "**" : "*") << "" << htmlize_string(tr("Yearly Average")) << (use_footer1 ? "**" : "*") << "" << htmlize_string(tr("Quantity")); if(includes_planned) {outf << "*"; use_footer1 = true;} outf<< "" << htmlize_string(pertitle); if(includes_planned) {outf << "*"; use_footer1 = true;} outf<< "" << htmlize_string(expensetitle); if(includes_planned) {outf << "*"; use_footer1 = true;} outf<< "" << htmlize_string(sumtitle); if(includes_planned) {outf << "*"; use_footer1 = true;} outf<< "" << htmlize_string(tags[i]); if(tag_includes_planned[tags[i]]) {outf << "*"; use_footer1 = true;} outf<< "" << htmlize_string(cats[i]->name()); if(cat_includes_planned[cats[i]]) {outf << "*"; use_footer1 = true;} outf<< "" << htmlize_string(tr("Total")); if(includes_planned) {outf << "*"; use_footer1 = true;} outf<< "
    " << htmlize_string(tr("Subtotal")) << "" << htmlize_string(currency->formatValue(first_year ? (yearly_value + scheduled_value) : yearly_value)) << "" << htmlize_string(currency->formatValue(yearly_value / days)) << "" << htmlize_string(currency->formatValue(((yearly_value * average_month) / days))) << "" << htmlize_string(currency->formatValue((yearly_value * average_year) / days)) << "" << htmlize_string(budget->formatValue(first_year ? (yearly_count + scheduled_count) : yearly_count, i_count_frac)) << "" << htmlize_string(currency->formatValue(pervalue)) << "" << htmlize_string(currency->formatValue(first_year ? (yearly_expense + scheduled_expense) : yearly_expense)) << "" << htmlize_string(currency->formatValue(first_year ? (yearly_value + scheduled_value - yearly_expense - scheduled_expense) : yearly_value - yearly_expense)) << "" << htmlize_string(currency->formatValue(first_year ? (tag_yearly_value[tags[i]] + tag_scheduled_value[tags[i]]) : tag_yearly_value[tags[i]])) << "" << htmlize_string(currency->formatValue(first_year ? (cat_yearly_value[cats[i]] + cat_scheduled_value[cats[i]]) : cat_yearly_value[cats[i]])) << "" << htmlize_string(currency->formatValue(first_year ? (yearly_value + scheduled_value) : yearly_value)) << "
    " << htmlize_string(budget->budgetYearString(it->date)) << "
    " << htmlize_string(QLocale().monthName(budget->budgetMonth(it->date), QLocale::LongFormat)) << "" << htmlize_string(currency->formatValue(first_month ? (it->value + scheduled_value) : it->value)) << "" << htmlize_string(currency->formatValue(it->value / days)) << "" << htmlize_string(currency->formatValue((it->value * average_month) / days)) << "" << htmlize_string(currency->formatValue((it->value * average_year) / days)) << "" << htmlize_string(budget->formatValue(first_month ? (it->count + scheduled_count) : it->count, i_count_frac)) << "" << htmlize_string(currency->formatValue(pervalue)) << "" << htmlize_string(currency->formatValue(first_month ? (it->expense + scheduled_expense) : it->expense)) << "" << htmlize_string(currency->formatValue(current_source == 12 ? (first_month ? (it->value + it->expense + scheduled_value + scheduled_expense) : it->value + it->expense) : (first_month ? (it->value - it->expense + scheduled_value - scheduled_expense) : it->value - it->expense))) << "" << htmlize_string(currency->formatValue(first_month ? (it->tags[tags[i]] + tag_scheduled_value[tags[i]]) : it->tags[tags[i]])) << "" << htmlize_string(currency->formatValue(first_month ? (it->cats[cats[i]] + cat_scheduled_value[cats[i]]) : it->cats[cats[i]])) << "" << htmlize_string(currency->formatValue(first_month ? (it->value + scheduled_value) : it->value)) << "
    " << htmlize_string(tr("Subtotal")) << "" << htmlize_string(currency->formatValue(yearly_value)) << "" << htmlize_string(currency->formatValue(yearly_value / days)) << "" << htmlize_string(currency->formatValue((yearly_value * average_month) / days)) << "" << htmlize_string(currency->formatValue((yearly_value * average_year) / days)) << "" << htmlize_string(budget->formatValue(yearly_count, i_count_frac)) << "" << htmlize_string(currency->formatValue(yearly_count == 0.0 ? 0.0 : (yearly_value / yearly_count))) << "" << htmlize_string(currency->formatValue(yearly_expense)) << "" << htmlize_string(currency->formatValue(yearly_value - yearly_expense)) << "" << htmlize_string(currency->formatValue(tag_yearly_value[tags[i]])) << "" << htmlize_string(currency->formatValue(cat_yearly_value[cats[i]])) << "" << htmlize_string(currency->formatValue(yearly_value)) << "
    " << htmlize_string(tr("Total")) << "" << htmlize_string(currency->formatValue(total_value + scheduled_value)) << "" << htmlize_string(currency->formatValue(total_value / days)) << "" << htmlize_string(currency->formatValue((total_value * average_month) / days)) << "" << htmlize_string(currency->formatValue((total_value * average_year) / days)) << "" << htmlize_string(budget->formatValue(total_count + scheduled_count, i_count_frac)) << "" << htmlize_string(currency->formatValue((total_count + scheduled_count) == 0.0 ? 0.0 : ((total_value + scheduled_value) / (total_count + scheduled_count)))) << "" << htmlize_string(currency->formatValue(total_expense + scheduled_expense)) << "" << htmlize_string(currency->formatValue(total_value - total_expense + scheduled_value - scheduled_expense)) << "" << htmlize_string(currency->formatValue(tag_total_value[tags[i]] + tag_scheduled_value[tags[i]])) << "" << htmlize_string(currency->formatValue(cat_total_value[cats[i]] + cat_scheduled_value[cats[i]])) << "" << htmlize_string(currency->formatValue(total_value + scheduled_value)) << "
    " << '\n'; outf << "\t\t
    " << "" << '\n'; if(use_footer1) { outf << "\t\t\t
    " << '\n'; outf << "\t\t\t" << "*" << htmlize_string(tr("Includes scheduled transactions")) << '\n'; } if(enabled[2] || enabled[3]) { outf << "\t\t\t" << "
    " << '\n'; outf << "\t\t\t" << (use_footer1 ? "**" : "*") << htmlize_string(tr("Adjusted for the average month / year (%1 / %2 days)").arg(budget->formatValue(average_month, 1)).arg(budget->formatValue(average_year, 1))) << '\n'; } outf << "\t\t
    " << '\n'; outf << "\t" << '\n'; outf << "" << '\n'; htmlview->setLineWrapMode(QTextEdit::NoWrap); htmlview->setHtml(source); if(htmlview->document()->size().width() < htmlview->width()) htmlview->setLineWrapMode(QTextEdit::WidgetWidth); } void OverTimeReport::updateTransactions() { if(categoryCombo->isVisible()) categoryChanged(); else tagChanged(); } void OverTimeReport::updateTags() { block_display_update = true; tagCombo->blockSignals(true); descriptionCombo->blockSignals(true); tagCombo->clear(); tagCombo->updateItems(budget->tags); tagCombo->blockSignals(false); descriptionCombo->blockSignals(false); if(tagCombo->isVisible()) { tagChanged(); block_display_update = false; updateDisplay(); } else { block_display_update = false; } } void OverTimeReport::updateAccounts() { block_display_update = true; if(categoryCombo->isEnabled() && categoryCombo->isVisible()) { categoryCombo->blockSignals(true); descriptionCombo->blockSignals(true); categoryCombo->clear(); if(sourceCombo->currentIndex() == 1) { categoryCombo->updateAccounts(ACCOUNT_TYPE_EXPENSES); } else { categoryCombo->updateAccounts(ACCOUNT_TYPE_INCOMES); } if(categoryCombo->allAccountsSelected()) { descriptionCombo->clear(); descriptionCombo->setEnabled(false); if(sourceCombo->currentIndex() == 2) { current_source = 1; } else { current_source = 2; } descriptionCombo->setEnabled(false); } else { categoryChanged(); } categoryCombo->blockSignals(false); descriptionCombo->blockSignals(false); } accountCombo->blockSignals(true); accountCombo->updateAccounts(ACCOUNT_TYPE_ASSETS); accountCombo->blockSignals(false); block_display_update = false; updateDisplay(); } Eqonomize-1.5.3/src/overtimereport.h000066400000000000000000000135031416454732000175240ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016-2020 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifndef OVER_TIME_REPORT_H #define OVER_TIME_REPORT_H #include #include #include #include #include #include class QCheckBox; class QComboBox; class QTextEdit; class QLabel; class QRadioButton; class QAction; class QKeyEvent; class Account; class AssetsAccount; class Budget; class Transactions; class AccountsMenu : public QMenu { Q_OBJECT public: AccountsMenu(Budget*, QWidget *parent = NULL, bool shows_assets = false); bool accountSelected(Account *account); bool allAccountsSelected(); void setAccountSelected(Account *account, bool selected); int selectedAccountsCount(); QString selectedAccountsText(int type); void updateAccounts(int type); QList selected_accounts; protected: QHash account_actions; void keyPressEvent(QKeyEvent *e); void mouseReleaseEvent(QMouseEvent *e); Budget *budget; bool b_assets; protected slots: void accountToggled(); public slots: void selectAll(); void deselectAll(); void toggleAll(); signals: void selectedAccountsChanged(); }; class AccountsCombo : public QPushButton { Q_OBJECT public: AccountsCombo(Budget *budg, QWidget *parent = NULL, bool shows_assets = false); bool accountSelected(Account *account); bool allAccountsSelected(); void setAccountSelected(Account *account, bool selected); void updateAccounts(int type); QString selectedAccountsText(int type = 1); QList &selectedAccounts(); bool testTransactionRelation(Transactions *trans, bool exclude_securities = false); double transactionChange(Transactions *trans, bool exclude_securities = false); public slots: void resizeAccountsMenu(); void updateText(); void selectAll(); void deselectAll(); void clear(); signals: void selectedAccountsChanged(); protected: AccountsMenu *accountsMenu; }; class DescriptionsMenu : public QMenu { Q_OBJECT public: DescriptionsMenu(int type, Budget*, QWidget *parent = NULL, bool show_all = true); bool itemSelected(const QString &str); bool allItemsSelected(); void setItemSelected(const QString &str, bool selected); int selectedItemsCount(); QString selectedItemsText(int type); void addItem(QString str); void updateItems(const QStringList &list); void clearItems(); bool testTransaction(Transactions *trans); void setItemType(int type); int itemType(); QStringList selected_items; protected: QHash item_actions; void keyPressEvent(QKeyEvent *e); void mouseReleaseEvent(QMouseEvent *e); Budget *budget; bool b_all; int i_type; protected slots: void itemToggled(); public slots: void selectAll(); void deselectAll(); void toggleAll(); signals: void selectedItemsChanged(); }; class DescriptionsCombo : public QPushButton { Q_OBJECT public: DescriptionsCombo(int type, Budget *budg, QWidget *parent = NULL, bool show_all = true); bool itemSelected(const QString &str); bool allItemsSelected(); void setItemSelected(const QString &str, bool selected); void addItem(QString str); void updateItems(const QStringList &list); QString selectedItemsText(int type = 1); QStringList &selectedItems(); bool testTransaction(Transactions *trans); void setItemType(int type); int itemType(); public slots: void resizeDescriptionsMenu(); void updateText(); void selectAll(); void deselectAll(); void clear(); signals: void selectedItemsChanged(); protected: DescriptionsMenu *itemsMenu; }; class OverTimeReport : public QWidget { Q_OBJECT public: OverTimeReport(Budget *budg, QWidget *parent); protected: Budget *budget; QString source; int current_source; QTextEdit *htmlview; QComboBox *sourceCombo; DescriptionsCombo *tagCombo, *descriptionCombo; AccountsCombo *categoryCombo, *accountCombo; QPushButton *saveButton, *printButton; QCheckBox *valueButton, *dailyButton, *monthlyButton, *yearlyButton, *countButton, *perButton; QRadioButton *catsButton, *tagsButton, *totalButton; QLabel *columnsLabel; bool block_display_update; public slots: void resetOptions(); void sourceChanged(int); void categoryChanged(); void tagChanged(); void descriptionChanged(); void updateTransactions(); void updateAccounts(); void updateTags(); void updateDisplay(); void columnsToggled(int, bool); void save(); void print(); void saveConfig(); }; #endif Eqonomize-1.5.3/src/qifimportexport.cpp000066400000000000000000002047431416454732000202550ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "eqonomize.h" #include "qifimportexport.h" #include #include #include #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) # define DATE_TO_MSECS(d) QDateTime(d.startOfDay()).toMSecsSinceEpoch() #else # define DATE_TO_MSECS(d) QDateTime(d).toMSecsSinceEpoch() #endif extern QString last_document_directory; ImportQIFDialog::ImportQIFDialog(Budget *budg, QWidget *parent, bool extra_parameters) : QWizard(parent), budget(budg), b_extra(extra_parameters) { setWindowTitle(tr("Import QIF file")); setModal(true); next_id = -1; QIFWizardPage *page1 = new QIFWizardPage(); page1->setTitle(tr("File Selection")); page1->setSubTitle(tr("Select a QIF file to import. When you click next, the file be analysed and you might need to answer some questions about the format of the file.")); setPage(0, page1); QGridLayout *layout1 = new QGridLayout(page1); layout1->addWidget(new QLabel(tr("File:"), page1), 0, 0); QHBoxLayout *layout1h = new QHBoxLayout(); fileEdit = new QLineEdit(page1); QCompleter *completer = new QCompleter(this); QFileSystemModel *fsModel = new QFileSystemModel(completer); fsModel->setRootPath(QString()); completer->setModel(fsModel); fileEdit->setCompleter(completer); layout1h->addWidget(fileEdit); fileButton = new QPushButton(LOAD_ICON("document-open"), QString(), page1); layout1h->addWidget(fileButton); layout1->addLayout(layout1h, 0, 1); QIFWizardPage *page1_2 = new QIFWizardPage(); page1_2->setTitle(tr("Local Definitions")); page1_2->setSubTitle(tr("Unknown elements where found in the QIF file. It is possible that this is because of localized type names. Please map them to the correct standard names.")); setPage(1, page1_2); QGridLayout *layout1_2 = new QGridLayout(page1_2); defsView = new QTreeWidget(page1_2); layout1_2->addWidget(defsView, 0, 0, 1, 2); QStringList headers; headers << tr("Local Text"); headers << tr("Standard Text"); defsView->setColumnCount(2); defsView->setHeaderLabels(headers); layout1_2->addWidget(new QLabel(tr("Select standard text:"), page1_2), 1, 0); defsCombo = new QComboBox(page1_2); defsCombo->setEditable(false); layout1_2->addWidget(defsCombo, 1, 1); QIFWizardPage *page2 = new QIFWizardPage(); page2->setTitle(tr("Date Format")); page2->setSubTitle(tr("The date format in the QIF file is ambiguous. Please select the correct format.")); setPage(2, page2); QGridLayout *layout2 = new QGridLayout(page2); layout2->addWidget(new QLabel(tr("Date format:"), page2), 0, 0); dateFormatCombo = new QComboBox(page2); dateFormatCombo->setEditable(false); layout2->addWidget(dateFormatCombo, 0, 1); QIFWizardPage *page3 = new QIFWizardPage(); page3->setTitle(tr("Default Account")); page3->setSubTitle(tr("Could not find any account definitions in the QIF file. Please select a default account. It is also possible that this is caused by a localized opening balance text.")); setPage(3, page3); QGridLayout *layout3 = new QGridLayout(page3); layout3->addWidget(new QLabel(tr("Default account:"), page3), 0, 0); accountCombo = new QComboBox(page3); accountCombo->setEditable(false); for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { AssetsAccount *account = *it; if(account != budget->balancingAccount && account->accountType() != ASSETS_TYPE_SECURITIES) { accountCombo->addItem(account->name(), QVariant::fromValue((void*) account)); } } layout3->addWidget(accountCombo, 0, 1); layout3->addWidget(new QLabel(tr("Opening balance text:"), page3), 1, 0); openingBalanceEdit = new QLineEdit(page3); openingBalanceEdit->setText("Opening Balance"); layout3->addWidget(openingBalanceEdit, 1, 1); QIFWizardPage *page4 = new QIFWizardPage(); page4->setTitle(tr("Import File")); page4->setSubTitle(tr("No (further) issues were found. Press finish to import the selected QIF file.")); setPage(4, page4); QGridLayout *layout4 = new QGridLayout(page4); ignoreDuplicateTransactionsButton = new QCheckBox(tr("Ignore duplicate transactions"), page4); layout4->addWidget(ignoreDuplicateTransactionsButton, 0, 0, 1, -1); setOption(QWizard::HaveHelpButton, false); page1->setCommitPage(true); page1_2->setCommitPage(true); page2->setCommitPage(true); page3->setCommitPage(true); page4->setCommitPage(true); page4->setFinalPage(true); page1->setComplete(false); page1_2->setComplete(true); page2->setComplete(true); page3->setComplete(true); page4->setComplete(true); fileEdit->setFocus(); setButtonText(CommitButton, buttonText(NextButton)); disconnect(button(CommitButton), SIGNAL(clicked()), this, 0); connect(button(CommitButton), SIGNAL(clicked()), this, SLOT(nextClicked())); connect(fileEdit, SIGNAL(textChanged(const QString&)), this, SLOT(onFileChanged(const QString&))); connect(fileButton, SIGNAL(clicked()), this, SLOT(selectFile())); connect(defsView, SIGNAL(itemSelectionChanged()), this, SLOT(defSelectionChanged())); connect(defsCombo, SIGNAL(activated(int)), this, SLOT(defSelected(int))); } ImportQIFDialog::~ImportQIFDialog() {} void ImportQIFDialog::showPage(int index) { next_id = index; QWizard::next(); next_id = -1; } int ImportQIFDialog::nextId() const { if(next_id < 0) return QWizard::nextId(); return next_id; } void ImportQIFDialog::defSelectionChanged() { QList list = defsView->selectedItems(); if(!list.isEmpty()) { QTreeWidgetItem *i = list.first(); defsCombo->setEnabled(true); int type = qi.unknown_defs[qi.unknown_defs_pre[i->text(0)]]; switch(type) { case -2: {defsCombo->setCurrentIndex(0); break;} case 1: {defsCombo->setCurrentIndex(1); break;} case 10: {defsCombo->setCurrentIndex(2); break;} case 11: {defsCombo->setCurrentIndex(3); break;} case 2: {defsCombo->setCurrentIndex(4); break;} case 12: {defsCombo->setCurrentIndex(5); break;} case 9: {defsCombo->setCurrentIndex(6); break;} case 13: {defsCombo->setCurrentIndex(7); break;} case 14: {defsCombo->setCurrentIndex(8); break;} case 3: {defsCombo->setCurrentIndex(9); break;} case -1: {defsCombo->setCurrentIndex(10); break;} } } else { defsCombo->setEnabled(false); } } void ImportQIFDialog::defSelected(int index) { QList list = defsView->selectedItems(); if(!list.isEmpty()) { QTreeWidgetItem *i = list.first(); int type = -2; switch(index) { case 0: {type = -2; break;} case 1: {type = 1; break;} case 2: {type = 10; break;} case 3: {type = 11; break;} case 4: {type = 2; break;} case 5: {type = 12; break;} case 6: {type = 9; break;} case 7: {type = 13; break;} case 8: {type = 14; break;} case 9: {type = 3; break;} case 10: {type = -1; break;} } qi.unknown_defs[qi.unknown_defs_pre[i->text(0)]] = type; i->setText(1, defsCombo->itemText(index)); } } void ImportQIFDialog::onFileChanged(const QString &str) { ((QIFWizardPage*) page(0))->setComplete(!str.isEmpty()); } void ImportQIFDialog::selectFile() { QMimeDatabase db; QString url = QFileDialog::getOpenFileName(this, QString(), fileEdit->text().isEmpty() ? last_document_directory + "/" : fileEdit->text().trimmed(), db.mimeTypeForName("application/x-qw").filterString()); if(!url.isEmpty()) fileEdit->setText(url); } void ImportQIFDialog::nextClicked() { if(currentId() == 0 || currentId() == 1) { bool b_page1 = (currentId() == 1); QString url = fileEdit->text().trimmed(); if(!b_page1) { if(url.isEmpty()) { QMessageBox::critical(this, tr("Error"), tr("A file must be selected.")); fileEdit->setFocus(); return; } QFileInfo info(url); if(info.isDir()) { QMessageBox::critical(this, tr("Error"), tr("Selected file is a directory.")); fileEdit->setFocus(); return; } else if(!info.exists()) { QMessageBox::critical(this, tr("Error"), tr("Selected file does not exist.")); fileEdit->setFocus(); return; } url = info.absoluteFilePath(); fileEdit->setText(url); } QFile file(url); if(!file.open(QIODevice::ReadOnly) ) { QMessageBox::critical(this, tr("Error"), tr("Couldn't open %1 for reading.").arg(url)); return; } else if(!file.size()) { QMessageBox::critical(this, tr("Error"), tr("Error reading %1.").arg(url)); file.close(); return; } QTextStream fstream(&file); importQIF(fstream, true, qi, budget, ignoreDuplicateTransactionsButton->isChecked()); int ps = qi.p1 + qi.p2 + qi.p3 + qi.p4; file.close(); if(b_page1 && (int) qi.unknown_defs.count() > defsView->topLevelItemCount()) { QMap::iterator it_e = qi.unknown_defs_pre.end(); QMap unknown_defs_old; QTreeWidgetItemIterator it(defsView); QTreeWidgetItem *qli = *it; while(qli) { unknown_defs_old[qli->text(0)] = true; ++it; qli = *it; } qli = NULL; for(QMap::iterator it = qi.unknown_defs_pre.begin(); it != it_e; ++it) { if(!unknown_defs_old.contains(it.key())) { QTreeWidgetItem *tmp_i = new QTreeWidgetItem(defsView); tmp_i->setText(0, it.key()); tmp_i->setText(1, tr("Unknown")); if(!qli) qli = tmp_i; } } qli->setSelected(true); defsCombo->setCurrentIndex(0); return; } else if(!b_page1 && qi.unknown_defs.count() > 0) { defsCombo->addItem(tr("Unknown")); defsCombo->addItem(tr("Account")); defsCombo->addItem(tr("Bank")); defsCombo->addItem(tr("Cash")); defsCombo->addItem(tr("Cat (Category)")); defsCombo->addItem(tr("CCard (Credit Card)")); defsCombo->addItem(tr("Invst (Investment)")); defsCombo->addItem(tr("Oth A (Other Assets)")); defsCombo->addItem(tr("Oth L (Other Liabilities)")); defsCombo->addItem(tr("Security")); defsCombo->addItem(tr("Other")); defsCombo->setCurrentIndex(0); QMap::iterator it_e = qi.unknown_defs_pre.end(); for(QMap::iterator it = qi.unknown_defs_pre.begin(); it != it_e; ++it) { QTreeWidgetItem *tmp_i = new QTreeWidgetItem(defsView); tmp_i->setText(0, it.key()); tmp_i->setText(1, tr("Unknown")); } if(defsView->topLevelItem(0)) { defsView->topLevelItem(0)->setSelected(true); } } else { if(ps == 0) { QMessageBox::critical(this, tr("Error"), tr("Unrecognized date format.")); return; } if(ps > 1) { dateFormatCombo->clear(); if(qi.p1) { QString date_format = qi.lz == 0 ? "M" : "MM"; if(qi.separator > 0) date_format += qi.separator; date_format += qi.lz == 0 ? "D" : "DD"; if(qi.separator > 0) date_format += qi.separator; date_format += "YY"; if(qi.ly) date_format += "YY"; dateFormatCombo->addItem(date_format); } if(qi.p2) { QString date_format = qi.lz == 0 ? "D" : "DD"; if(qi.separator > 0) date_format += qi.separator; date_format += qi.lz == 0 ? "M" : "MM"; if(qi.separator > 0) date_format += qi.separator; date_format += "YY"; if(qi.ly) date_format += "YY"; dateFormatCombo->addItem(date_format); } if(qi.p3) { QString date_format = "YY"; if(qi.ly) date_format += "YY"; if(qi.separator > 0) date_format += qi.separator; date_format += qi.lz == 0 ? "M" : "MM"; if(qi.separator > 0) date_format += qi.separator; date_format += qi.lz == 0 ? "D" : "DD"; dateFormatCombo->addItem(date_format); } if(qi.p4) { QString date_format = "YY"; if(qi.ly) date_format += "YY"; if(qi.separator > 0) date_format += qi.separator; date_format += qi.lz == 0 ? "D" : "DD"; if(qi.separator > 0) date_format += qi.separator; date_format += qi.lz == 0 ? "M" : "MM"; dateFormatCombo->addItem(date_format); } showPage(2); return; } else { if(!qi.had_transaction || qi.account_defined) { showPage(4); button(CommitButton)->setEnabled(false); } else { showPage(3); } return; } } } else if(currentId() == 2) { bool p1 = false, p2 = false, p3 = false, p4 = false; int p[4]; int i = 0; if(qi.p1) {p[i] = 1; i++;} if(qi.p2) {p[i] = 2; i++;} if(qi.p3) {p[i] = 3; i++;} if(qi.p4) {p[i] = 4; i++;} switch(p[dateFormatCombo->currentIndex()]) { case 1: {p1 = true; break;} case 2: {p2 = true; break;} case 3: {p3 = true; break;} case 4: {p4 = true; break;} } qi.p1 = p1; qi.p2 = p2; qi.p3 = p3; qi.p4 = p4; if(qi.lz < 0) qi.lz = 1; if(!qi.had_transaction || qi.account_defined) { button(CommitButton)->setEnabled(false); showPage(4); return; } } else if(currentId() == 3) { if(accountCombo->currentData().isValid()) qi.current_account = (AssetsAccount*) accountCombo->currentData().value(); button(CommitButton)->setEnabled(false); } QWizard::next(); } void ImportQIFDialog::accept() { QString url = fileEdit->text().trimmed(); if(url.isEmpty()) { return; } QFile file(url); if(!file.open(QIODevice::ReadOnly) ) { QMessageBox::critical(this, tr("Error"), tr("Couldn't open %1 for reading.").arg(url)); return; } else if(!file.size()) { QMessageBox::critical(this, tr("Error"), tr("Error reading %1.").arg(url)); file.close(); return; } QFileInfo fileInfo(url); last_document_directory = fileInfo.absoluteDir().absolutePath(); QTextStream fstream(&file); importQIF(fstream, false, qi, budget, ignoreDuplicateTransactionsButton->isChecked()); file.close(); QString info = ""; info += tr("Successfully imported %n transaction(s).", "", qi.transactions); if(qi.accounts > 0) { info += "\n"; info += tr("Successfully imported %n account(s).", "", qi.accounts); } if(qi.categories > 0) { info += "\n"; info += tr("Successfully imported %n category/categories.", "", qi.categories); } if(qi.duplicates > 0) { info += "\n"; info += tr("%n duplicate transaction(s) was ignored.", "", qi.duplicates); } if(qi.failed_transactions > 0) { info += "\n"; info += tr("Failed to import %n transaction(s).", "", qi.failed_transactions); } if(qi.securities > 0) { info += "\n"; info += tr("%n security/securities were not imported.", "Financial security (e.g. stock, mutual fund)", qi.securities); } if(qi.security_transactions > 0) { info += "\n"; info += tr("%n security transaction(s) were not imported.", "Financial security (e.g. stock, mutual fund)", qi.security_transactions); } QMessageBox::information(this, tr("Information"), info); if(qi.transactions || qi.accounts || qi.categories) return QWizard::accept(); return QWizard::reject(); } ExportQIFDialog::ExportQIFDialog(Budget *budg, QWidget *parent, bool extra_parameters) : QDialog(parent), budget(budg), b_extra(extra_parameters) { setWindowTitle(tr("Export QIF File")); setModal(true); QVBoxLayout *box1 = new QVBoxLayout(this); QGridLayout *grid = new QGridLayout(); box1->addLayout(grid); grid->addWidget(new QLabel(tr("Account:"), this), 0, 0); accountCombo = new QComboBox(this); accountCombo->setEditable(false); for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { AssetsAccount *account = *it; if(account != budget->balancingAccount) { accountCombo->addItem(account->name(), QVariant::fromValue((void*) account)); } } accountCombo->addItem(tr("All", "All accounts"), QVariant::fromValue((void*) NULL)); grid->addWidget(accountCombo, 0, 1); accountCombo->setFocus(); grid->addWidget(new QLabel(tr("Date format:"), this), 1, 0); dateFormatCombo = new QComboBox(this); dateFormatCombo->setEditable(false); dateFormatCombo->addItem("Standard (YYYY-MM-DD)"); dateFormatCombo->addItem("Local"); dateFormatCombo->addItem("US (MM/DD/YY)"); grid->addWidget(dateFormatCombo, 1, 1); grid->addWidget(new QLabel(tr("Value format:"), this), 2, 0); valueFormatCombo = new QComboBox(this); valueFormatCombo->setEditable(false); valueFormatCombo->addItem("1,000,000.00"); valueFormatCombo->addItem("1.000.000,00"); grid->addWidget(valueFormatCombo, 2, 1); grid->addWidget(new QLabel(tr("File:"), this), 3, 0); QHBoxLayout *layouth = new QHBoxLayout(); fileEdit = new QLineEdit(this); QCompleter *completer = new QCompleter(this); QFileSystemModel *fsModel = new QFileSystemModel(completer); fsModel->setRootPath(QString()); completer->setModel(fsModel); fileEdit->setCompleter(completer); layouth->addWidget(fileEdit); fileButton = new QPushButton(LOAD_ICON("document-open"), QString(), this); layouth->addWidget(fileButton); grid->addLayout(layouth, 3, 1); buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, this); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Cancel)->setShortcut(Qt::CTRL | Qt::Key_Return); buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept())); box1->addWidget(buttonBox); connect(fileEdit, SIGNAL(textChanged(const QString&)), this, SLOT(onFileChanged(const QString&))); connect(fileButton, SIGNAL(clicked()), this, SLOT(selectFile())); } ExportQIFDialog::~ExportQIFDialog() {} void ExportQIFDialog::onFileChanged(const QString &str) { buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!str.isEmpty()); } void ExportQIFDialog::selectFile() { QFileDialog fileDialog(this); QMimeDatabase db; fileDialog.setNameFilter(db.mimeTypeForName("application/x-qw").filterString()); fileDialog.setDefaultSuffix(db.mimeTypeForName("application/x-qw").preferredSuffix()); fileDialog.setAcceptMode(QFileDialog::AcceptSave); #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) fileDialog.setSupportedSchemes(QStringList("file")); #endif fileDialog.setOption(QFileDialog::DontConfirmOverwrite, true); fileDialog.setDirectory(fileEdit->text().isEmpty() ? last_document_directory + "/" : fileEdit->text().trimmed()); if(fileDialog.exec()) { QStringList urls = fileDialog.selectedFiles(); if(!urls.isEmpty()) fileEdit->setText(urls[0]); } } void ExportQIFDialog::accept() { QString url = fileEdit->text().trimmed(); if(url.isEmpty()) { return; } AssetsAccount *account = NULL; if(accountCombo->currentData().isValid()) account = (AssetsAccount*) accountCombo->currentData().value(); qi.current_account = account; qi.value_format = valueFormatCombo->currentIndex() + 1; qi.date_format = dateFormatCombo->currentIndex() + 1; QFileInfo info(url); if(info.isDir()) { QMessageBox::critical(this, tr("Error"), tr("Selected file is a directory.")); fileEdit->setFocus(); return; } url = info.absoluteFilePath(); fileEdit->setText(url); if(QFile::exists(url)) { if(QMessageBox::warning(this, tr("Overwrite"), tr("The selected file already exists. Would you like to overwrite the old copy?"), QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return; } QSaveFile ofile(url); ofile.open(QIODevice::WriteOnly); ofile.setPermissions((QFile::Permissions) 0x0660); if(!ofile.isOpen()) { ofile.cancelWriting(); QMessageBox::critical(this, tr("Error"), tr("Couldn't open file for writing.")); return; } QFileInfo fileInfo(url); last_document_directory = fileInfo.absoluteDir().absolutePath(); QTextStream stream(&ofile); exportQIF(stream, qi, budget, true); if(!ofile.commit()) { QMessageBox::critical(this, tr("Error"), tr("Error while writing file; file was not saved.")); return; } return QDialog::accept(); } QDate readQIFDate(const QString &str, const QString &date_format, const QString &alt_date_format) { QDate date = QDate::fromString(str, date_format); if(!date.isValid() && !alt_date_format.isEmpty()) { date = QDate::fromString(str, alt_date_format); if(date.year() < 1970 && alt_date_format.count('y') < 4) { date = date.addYears(100); } } else if(date.year() < 1970 && date_format.count('y') < 4) { date = date.addYears(100); } return date; } double readQIFValue(const QString &str, int value_format) { if(value_format == 2) { QString str2 = str; str2.replace(".", ""); str2.replace(",", "."); return str2.toDouble(); } else if(value_format == 1) { QString str2 = str; str2.replace(",", ""); return str2.toDouble(); } return str.toDouble(); } //p1 MDY //p2 DMY //p3 YMD //p4 YDM void testQIFDate(const QString &str, bool &p1, bool &p2, bool &p3, bool &p4, bool &ly, char &separator, int & lz) { if(separator < 0) { for(int i = 0; i < (int) str.length(); i++) { if(str[i] < '0' || str[i] > '9') { separator = str[i].toLatin1(); break; } } if(separator < 0) separator = 0; p1 = (separator != 0 || str.length() == 6); p2 = (separator != 0 || str.length() == 6); p3 = true; p4 = (separator != 0 || str.length() == 6); ly = (separator == 0 && str.length() >= 8); } if(p1 + p2 + p3 + p4 <= 1) { lz = 1; return; } QStringList strlist; if(separator == 0) { strlist << str.left(2); strlist << str.mid(2, 2); strlist << str.right(2); } else { #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) strlist = str.split(separator, Qt::SkipEmptyParts); #else strlist = str.split(separator, QString::SkipEmptyParts); #endif } if(strlist.count() == 2 && (p1 || p2)) { int i = strlist[1].indexOf('\''); if(i >= 0) { strlist.append(strlist[1]); strlist[2].remove(0, i + 1); strlist[1].truncate(i); p3 = false; p4 = false; ly = false; } } if(strlist.count() < 3) return; if(p1 || p2) { int v1 = strlist[0].toInt(); if(v1 > 12) p1 = false; if(v1 > 31 || v1 < 1) { p2 = false; if(v1 >= 100) ly = true; else ly = false; } } int v2 = strlist[1].toInt(); if(v2 > 12) {p2 = false; p3 = false;} int v3 = strlist[2].toInt(); if(v3 > 12) p4 = false; if(v3 > 31 || v3 < 1) { p3 = false; if(v3 >= 100) ly = true; else ly = false; } if(strlist[1].length() == 1) lz = 0; else if(strlist[1][0] == '0') lz = 1; else if(!p3 && !p4 && strlist[0].length() == 1) lz = 0; else if(!p3 && !p4 && strlist[0][0] == '0') lz = 1; else if(!p1 && !p2 && strlist[2].length() == 1) lz = 0; else if(!p1 && !p2 && strlist[2][0] == '0') lz = 1; } void testQIFValue(const QString &str, int &value_format) { if(value_format == 0) { int i = str.lastIndexOf('.'); int i2 = str.lastIndexOf(','); if(i2 >= 0 && i >= 0) { if(i2 > i) value_format = 2; else value_format = 1; return; } if(i >= 0) { value_format = 1; return; } if(i2 >= 0) { value_format = 2; return; } } } bool importQIFFile(Budget *budget, QWidget *parent, bool extra_parameters) { ImportQIFDialog *dialog = new ImportQIFDialog(budget, parent, extra_parameters); bool ret = (dialog->exec() == QDialog::Accepted); dialog->deleteLater(); return ret; } struct qif_split { QString memo, category, subcategory; double value, percentage; }; void importQIF(QTextStream &fstream, bool test, qif_info &qi, Budget *budget, bool ignore_duplicates) { QDate date; QString memo, description, payee, category, subcategory, atype, atype_bak, name, subname, ticker_symbol, security; bool incomecat = false; double value = 0.0; //double commission = 0.0, price = 0.0, sec_amount = 0.0; QString line = fstream.readLine().trimmed(), line_bak; QString date_format = "", alt_date_format = ""; QList transfers; QList previous_transfers; QVector splits; qif_split *current_split = NULL; int type = -1; QHash def_income_cats; QHash def_expense_cats; if(test) { qi.current_account = NULL; qi.unhandled = false; qi.unknown = false; qi.had_type = false; qi.had_type_def = false; qi.had_account_def = false; qi.account_defined = false; qi.had_transaction = false; qi.value_format = 0; qi.shares_format = 0; qi.price_format = 0; qi.percentage_format = 0; qi.separator = -1; qi.opening_balance_str = "opening balance"; qi.p1 = true; qi.p2 = true; qi.p3 = true; qi.p4 = true; qi.ly = true; qi.lz = -1; } else { qi.duplicates = 0; qi.transactions = 0; qi.securities = 0; qi.security_transactions = 0; qi.failed_transactions = 0; qi.accounts = 0; qi.categories = 0; qi.opening_balance_str = qi.opening_balance_str.toLower(); if(qi.p1) { date_format += qi.lz == 0 ? "M" : "MM"; if(qi.separator > 0) date_format += qi.separator; date_format += qi.lz == 0 ? "d" : "dd"; if(qi.separator > 0) date_format += qi.separator; if(qi.ly) { date_format += "yyyy"; } else { if(qi.separator > 0) { alt_date_format = date_format; alt_date_format += '\''; alt_date_format += "yy"; } date_format += "yy"; } } else if(qi.p2) { date_format += qi.lz == 0 ? "d" : "dd"; if(qi.separator > 0) date_format += qi.separator; date_format += qi.lz == 0 ? "M" : "MM"; if(qi.separator > 0) date_format += qi.separator; if(qi.ly) { date_format += "yyyy"; } else { if(qi.separator > 0) { alt_date_format = date_format; alt_date_format += '\''; alt_date_format += "yy"; } date_format += "yy"; } } else if(qi.p3) { if(qi.ly) date_format += "yyyy"; else date_format += "yy"; if(qi.separator > 0) date_format += qi.separator; date_format += qi.lz == 0 ? "M" : "MM"; if(qi.separator > 0) date_format += qi.separator; date_format += qi.lz == 0 ? "d" : "dd"; } else if(qi.p4) { if(qi.ly) date_format += "yyyy"; else date_format += "yy"; if(qi.separator > 0) date_format += qi.separator; date_format += qi.lz == 0 ? "d" : "dd"; if(qi.separator > 0) date_format += qi.separator; date_format += qi.lz == 0 ? "M" : "MM"; } } QMap datestamps; while(!line.isNull()) { if(!line.isEmpty()) { char field = line[0].toLatin1(); line.remove(0, 1); line = line.trimmed(); switch(field) { case '!': { line_bak = line.trimmed(); line = line_bak.toLower(); if(qi.unknown_defs.contains(line)) { type = qi.unknown_defs[line]; if(type > 1) type = -1; if(type == 1) { qi.had_account_def = true; } else if(type == -1) { qi.had_type_def = true; qi.unhandled = true; } else if(type == -2) { qi.unknown = true; } } else if(line == "account") { qi.had_account_def = true; type = 1; } else if(line.startsWith("option")) { } else if(line.startsWith("clear")) { } else { bool is_type = false; if(line.startsWith("type:") || line.startsWith("type ")) { qi.had_type = true; line.remove(0, 5); line = line.trimmed(); is_type = true; } else { int i = line.indexOf(":"); if(i < 0) i = line.indexOf(" "); if(i >= 0) { line.remove(0, i + 1); is_type = true; } } if(is_type) { if(qi.unknown_defs.contains(line)) { type = qi.unknown_defs[line]; if(type == 1) { type = -1; } if(type == -1) { qi.had_type_def = true; qi.unhandled = true; } else if(type >= 9) { qi.had_type_def = true; } else if(type == -2) { qi.unknown = true; } } else if(line == "cat") { type = 2; } else if(line == "security") { type = 3; } else if(line == "invst") { qi.had_type_def = true; type = 9; } else if(line.startsWith("ban")) { qi.had_type_def = true; type = 10; } else if(line == "cash" || line == "kas") { qi.had_type_def = true; type = 11; } else if(line == "ccard") { qi.had_type_def = true; type = 12; } else if(line == "oth a" || line == "ov b") { qi.had_type_def = true; type = 13; } else if(line == "oth l" || line == "ov s") { qi.had_type_def = true; type = 14; } else if(line == "prices" || line == "budget" || line == "tax" || line == "invoice" || line == "bill" || line == "memorized" || line == "class") { qi.had_type_def = true; qi.unhandled = true; type = -1; } else { if(test) { int i = line_bak.indexOf(":"); if(i < 0) i = line_bak.indexOf(" "); if(i >= 0) { line_bak.remove(0, i + 1); } qi.unknown_defs_pre[line_bak] = line; qi.unknown_defs[line] = -2; } qi.unknown = true; type = -2; } } else { if(test) { qi.unknown_defs_pre[line_bak] = line; qi.unknown_defs[line] = -2; } qi.unknown = true; type = -3; } } break; } case '/': { //Balance date (Account) if(type == 1) { /*if(test) testQIFDate(line, qi.p1, qi.p2, qi.p3, qi.p4, qi.ly, qi.separator); else date = readQIFDate(line, date_format, alt_date_format);*/ } break; } case '%': { //Percentage of split if percentages are used (Transaction) if(type >= 10) { if(test) testQIFValue(line, qi.percentage_format); else if(current_split) current_split->percentage = readQIFValue(line, qi.percentage_format); } break; } case -35: {} case -36: {} case '$': { //Balance (Account), amount transfered (Security transaction), amount of split (Memorized, Transaction) if(type == 9) { if(test) testQIFValue(line, qi.value_format); //else sec_amount = readQIFValue(line, qi.value_format); } else if(type >= 10) { if(test) testQIFValue(line, qi.value_format); else if(current_split) current_split->value = readQIFValue(line, qi.value_format); } break; } case 1: {} case 2: {} case 3: {} case 4: {} case 5: {} case 6: {} case 7: { //Amortization (Memorized) break; } case 'A': { //Address (Memorized, Transaction) break; } case 'B': { //Budget amount (Category, Budget), balance (account) break; } case 'C': { //Cleared status (Security transaction, Memorized, Transaction) break; } case 'D': { //Description (Account, Category, Class, Budget) if(type == 1 || type == 2 || type == 3) description = line; //Date (Security transaction, Transaction) else if(type >= 9) { if(test) { if(qi.p1 + qi.p2 + qi.p3 + qi.p4 > 1 || qi.lz < 0) testQIFDate(line, qi.p1, qi.p2, qi.p3, qi.p4, qi.ly, qi.separator, qi.lz); } else { date = readQIFDate(line, date_format, alt_date_format); } } break; } case 'E': { //Expense category (Category) or memo in split (Memorized, Transaction) if(type == 2) incomecat = false; else if(type >= 10 && !test && current_split) current_split->memo = line; break; } case 'F': { //Reimbursable business expense flag (Transaction) break; } case 'I': { //Income category (Category) or price (Security transaction) if(type == 2) incomecat = true; else if(type == 9) { if(test) testQIFValue(line, qi.price_format); //else price = readQIFValue(line, qi.price_format); } break; } case 'K': { //Memorized break; } case 'L': { //Category (Memorized, Security transaction, Transaction) or credit limit (Account) if(type >= 9) { int i = line.indexOf('/'); if(i >= 0) line.truncate(i); category = line; i = line.indexOf(':'); if(i >= 0) { bool is_transfer = line.length() >= 2 && line[0] == '[' && line.endsWith("]"); if(is_transfer) line.truncate(line.length() - 1); category.truncate(i); category = category.trimmed(); if(is_transfer) category += "]"; subcategory = line; subcategory.remove(0, i + 1); subcategory = subcategory.trimmed(); } } break; } case 'M': { //Memo (Memorized, Security transaction, Transaction) if(type >= 9) memo = line; break; } case 'N': { //Name (Class, Account, Category, Budget, Security) or action (Security transaction) or num (Transaction) if(type == 1 || type == 2 || type == 3) name = line; else if(type == 9) { } break; } case 'O': { //Commission (Security transaction) if(type == 9) { if(test) testQIFValue(line, qi.value_format); //else commission = readQIFValue(line, qi.value_format); } break; } case 'P': { //Payee (Memorized, Security transaction, Transaction) if(type >= 9) payee = line; break; } case 'Q': { //Quantity (Security transaction) if(type == 9) { if(test) testQIFValue(line, qi.shares_format); else value = readQIFValue(line, qi.shares_format); } break; } case 'R': { //Tax schedule information (Category) break; } case 'S': { //Category/class in split (Memorized, Transaction), stock ticker symbol (Security) if(type == 3) { ticker_symbol = line; } else if(type >= 10 && !test) { splits.push_back(qif_split()); current_split = &splits.last(); current_split->value = 0.0; current_split->percentage = 0.0; int i = line.indexOf('/'); if(i >= 0) line.truncate(i); current_split->category = line; i = line.indexOf(':'); if(i >= 0) { bool is_transfer = line.length() >= 2 && line[0] == '[' && line.endsWith("]"); if(is_transfer) line.truncate(line.length() - 1); current_split->category.truncate(i); current_split->category = current_split->category.trimmed(); if(is_transfer) current_split->category += "]"; current_split->subcategory = line; current_split->subcategory.remove(0, i + 1); current_split->subcategory = current_split->subcategory.trimmed(); } } break; } case 'T': { //Type (Account, Security), tax related (Category) if(type == 1 || type == 3) { atype_bak = line; atype = line.toLower(); } //Value (Memorized, Security transaction, Transaction) else if(type >= 9) { if(test) testQIFValue(line, qi.value_format); else value = readQIFValue(line, qi.value_format); } break; } case 'U': { //Value (Memorized, Security transaction, Transaction) if(type >= 9) { if(test) testQIFValue(line, qi.value_format); else value = readQIFValue(line, qi.value_format); } break; } case 'X': { //? (Account), small business extensions (Transaction) break; } case 'Y': { //Security (Security transaction) if(type == 9) { security = line; } break; } case '^': { //End of entry if(type >= 10) { //Transaction bool is_transfer = category.length() >= 2 && category[0] == '[' && category.endsWith("]"); QString payee_lower = payee.toLower(); bool is_opening_balance = splits.empty() && is_transfer && (payee_lower == qi.opening_balance_str || payee_lower == "opening balance" || payee_lower == "opening"); if(test && !qi.account_defined && is_opening_balance && !qi.had_transaction) qi.account_defined = true; if(!test && !splits.empty()) { if(!date.isValid() || !qi.current_account) { qi.failed_transactions++; } else { MultiItemTransaction *split = new MultiItemTransaction(budget, date, qi.current_account, memo); QVector::size_type c = splits.count(); for(QVector::size_type i = 0; i < c; i++) { current_split = &splits[i]; bool is_transfer = current_split->category.length() >= 2 && current_split->category[0] == '[' && current_split->category.endsWith("]"); if(current_split->percentage != 0.0 && current_split->value == 0.0) { if(i == c - 1) current_split->value = value; else current_split->value = (value * current_split->percentage) / 100; } value -= current_split->value; if(!test && is_transfer) { //Transfer current_split->category.remove(0, 1); current_split->category.truncate(current_split->category.length() - 1); if(current_split->category.isEmpty()) { current_split->category = Budget::tr("Unnamed"); } AssetsAccount *acc = budget->findAssetsAccount(current_split->category); if(!acc) { acc = new AssetsAccount(budget, ASSETS_TYPE_CURRENT, current_split->category); budget->addAccount(acc); qi.accounts++; } Transfer *tra = NULL; if(current_split->value < 0.0) tra = new Transfer(budget, -current_split->value, date, qi.current_account, acc, current_split->memo); else tra = new Transfer(budget, current_split->value, date, acc, qi.current_account, current_split->memo); bool duplicate = false; QList::iterator it_e = previous_transfers.end(); for(QList::iterator it = previous_transfers.begin(); it != it_e; ++it) { if(tra->equals(*it, false)) { duplicate = true; break; } } if(duplicate) { delete tra; } else if(ignore_duplicates && budget->findDuplicateTransaction(tra)) { qi.duplicates++; delete tra; } else { split->addTransaction(tra); transfers.append(tra); } } else { bool empty = current_split->category.isEmpty(); bool b_exp = current_split->value < 0.0; if(empty) { current_split->category = Budget::tr("Uncategorized"); } CategoryAccount *cat = NULL, *parent_cat = NULL; if(!b_exp) parent_cat = budget->findIncomesAccount(current_split->category, NULL); else parent_cat = budget->findExpensesAccount(current_split->category, NULL); if(!empty && !parent_cat) { if(!b_exp) { QHash::const_iterator it = def_expense_cats.find(current_split->category); if(it != def_expense_cats.constEnd()) parent_cat = *it; } else { QHash::const_iterator it = def_income_cats.find(current_split->category); if(it != def_income_cats.constEnd()) parent_cat = *it; } if(parent_cat) b_exp = !b_exp; } if(!parent_cat) { if(!b_exp) parent_cat = new IncomesAccount(budget, current_split->category); else parent_cat = new ExpensesAccount(budget, current_split->category); budget->addAccount(parent_cat); qi.categories++; } if(subcategory.isEmpty()) { cat = parent_cat; parent_cat = NULL; } else { if(!b_exp) cat = budget->findIncomesAccount(current_split->subcategory, parent_cat); else cat = budget->findExpensesAccount(current_split->subcategory, parent_cat); if(!cat) { if(!b_exp) cat = new IncomesAccount(budget, current_split->subcategory); else cat = new ExpensesAccount(budget, current_split->subcategory); cat->setParentCategory(parent_cat); budget->addAccount(cat); qi.categories++; } } if(b_exp) { //Expense Expense *exp = new Expense(budget, -current_split->value, date, (ExpensesAccount*) cat, qi.current_account, current_split->memo); if(value > 0.0) exp->setQuantity(-1.0); if(ignore_duplicates && budget->findDuplicateTransaction(exp)) { qi.duplicates++; delete exp; } else { split->addTransaction(exp); } } else { //Income Income *inc = new Income(budget, current_split->value, date, (IncomesAccount*) cat, qi.current_account, current_split->memo); if(value < 0.0) inc->setQuantity(-1.0); if(ignore_duplicates && budget->findDuplicateTransaction(inc)) { qi.duplicates++; delete inc; } else { split->addTransaction(inc); } } } } if(!payee.isEmpty()) split->setPayee(payee); split->setTimestamp(datestamps.contains(split->date()) ? datestamps[split->date()] + 1 : DATE_TO_MSECS(split->date()) / 1000); datestamps[split->date()] = split->timestamp(); if(split->count() >= 2) { budget->addSplitTransaction(split); qi.transactions++; } else if(split->count() == 1) { budget->addTransaction(split->at(0)); qi.transactions++; split->clear(); delete split; } else { delete split; } } } else if(!test && is_transfer) { //Transfer category.remove(0, 1); category.truncate(category.length() - 1); if(category.isEmpty()) { category = Budget::tr("Unnamed"); } AssetsAccount *acc = budget->findAssetsAccount(category); if(is_opening_balance || acc == qi.current_account) { if(!acc) { AssetsType account_type = ASSETS_TYPE_OTHER; if(type == 11) account_type = ASSETS_TYPE_CASH; else if(type == 12) account_type = ASSETS_TYPE_CREDIT_CARD; else if(type == 10) account_type = ASSETS_TYPE_CURRENT; else if(type == 14) account_type = ASSETS_TYPE_LIABILITIES; acc = new AssetsAccount(budget, account_type, category); budget->addAccount(acc); qi.accounts++; } if(!budget->accountHasTransactions(acc) && acc->accountType() != ASSETS_TYPE_SECURITIES && acc->initialBalance() == 0.0) { acc->setInitialBalance(value); } qi.current_account = acc; previous_transfers << transfers; transfers.clear(); } else { if(!acc) { acc = new AssetsAccount(budget, ASSETS_TYPE_CURRENT, category); budget->addAccount(acc); qi.accounts++; } Transfer *tra = NULL; if(!date.isValid() || !qi.current_account) { qi.failed_transactions++; } else { if(value < 0.0) tra = new Transfer(budget, -value, date, qi.current_account, acc, memo); else tra = new Transfer(budget, value, date, acc, qi.current_account, memo); bool duplicate = false; QList::iterator it_e = previous_transfers.end(); for(QList::iterator it = previous_transfers.begin(); it != it_e; ++it) { if(tra->equals(*it, false)) { duplicate = true; break; } } if(duplicate) { delete tra; } else if(ignore_duplicates && budget->findDuplicateTransaction(tra)) { qi.duplicates++; delete tra; } else { tra->setTimestamp(datestamps.contains(tra->date()) ? datestamps[tra->date()] + 1 : DATE_TO_MSECS(tra->date()) / 1000); datestamps[tra->date()] = tra->timestamp(); budget->addTransaction(tra); transfers.append(tra); qi.transactions++; } } } } else if(!test) { bool empty = category.isEmpty(); bool b_exp = value < 0.0; if(empty) { category = Budget::tr("Uncategorized"); } CategoryAccount *cat = NULL, *parent_cat = NULL; if(!b_exp) parent_cat = budget->findIncomesAccount(category, NULL); else parent_cat = budget->findExpensesAccount(category, NULL); if(!empty && !parent_cat) { if(!b_exp) { QHash::const_iterator it = def_expense_cats.find(category); if(it != def_expense_cats.constEnd()) parent_cat = *it; } else { QHash::const_iterator it = def_income_cats.find(category); if(it != def_income_cats.constEnd()) parent_cat = *it; } if(parent_cat) b_exp = !b_exp; } if(!parent_cat) { if(!b_exp) parent_cat = new IncomesAccount(budget, category); else parent_cat = new ExpensesAccount(budget, category); budget->addAccount(parent_cat); qi.categories++; } if(subcategory.isEmpty()) { cat = parent_cat; parent_cat = NULL; } else { if(!b_exp) cat = budget->findIncomesAccount(subcategory, parent_cat); else cat = budget->findExpensesAccount(subcategory, parent_cat); if(!cat) { if(!b_exp) cat = new IncomesAccount(budget, subcategory); else cat = new ExpensesAccount(budget, subcategory); cat->setParentCategory(parent_cat); budget->addAccount(cat); qi.categories++; } } if(b_exp) { //Expense if(!date.isValid() || !qi.current_account) { qi.failed_transactions++; } else { Expense *exp = new Expense(budget, -value, date, (ExpensesAccount*) cat, qi.current_account, memo); if(value > 0.0) exp->setQuantity(-1.0); exp->setPayee(payee); if(ignore_duplicates && budget->findDuplicateTransaction(exp)) { qi.duplicates++; delete exp; } else { exp->setTimestamp(datestamps.contains(exp->date()) ? datestamps[exp->date()] + 1 : DATE_TO_MSECS(exp->date()) / 1000); datestamps[exp->date()] = exp->timestamp(); budget->addTransaction(exp); qInfo() << exp->description(); qi.transactions++; } } } else { //Income if(!date.isValid() || !qi.current_account) { qi.failed_transactions++; } else { Income *inc = new Income(budget, value, date, (IncomesAccount*) cat, qi.current_account, memo); if(value < 0.0) inc->setQuantity(-1.0); inc->setPayer(payee); if(ignore_duplicates && budget->findDuplicateTransaction(inc)) { qi.duplicates++; delete inc; } else { inc->setTimestamp(datestamps.contains(inc->date()) ? datestamps[inc->date()] + 1 : DATE_TO_MSECS(inc->date()) / 1000); datestamps[inc->date()] = inc->timestamp(); budget->addTransaction(inc); qInfo() << inc->description(); qi.transactions++; } } } } qi.had_transaction = true; } else if(type == 9 && !test) { //Security transaction qi.security_transactions++; } else if(type == 1 && (!test || !qi.account_defined)) { //account if(!qi.had_transaction) qi.account_defined = true; if(name.isEmpty()) name = Budget::tr("Unnamed"); qi.current_account = budget->findAssetsAccount(name); if(!qi.current_account) { AssetsType account_type = ASSETS_TYPE_OTHER; if(qi.unknown_defs.contains(atype)) { int ut_type = qi.unknown_defs[atype]; if(ut_type == 9) account_type = ASSETS_TYPE_SECURITIES; else if(ut_type == 11) account_type = ASSETS_TYPE_CASH; else if(ut_type == 12) account_type = ASSETS_TYPE_CREDIT_CARD; else if(ut_type == 10) account_type = ASSETS_TYPE_CURRENT; else if(ut_type == 14) account_type = ASSETS_TYPE_LIABILITIES; } else if(atype == "cash") account_type = ASSETS_TYPE_CASH; else if(atype == "invst" || atype == "mutual") account_type = ASSETS_TYPE_SECURITIES; else if(atype == "ccard" || atype == "creditcard") account_type = ASSETS_TYPE_CREDIT_CARD; else if(atype == "oth l") account_type = ASSETS_TYPE_LIABILITIES; else if(atype == "oth a") account_type = ASSETS_TYPE_OTHER; else if(atype != "bank" && atype != "port") { if(test) { qi.unknown_defs_pre[atype_bak] = atype; qi.unknown_defs[atype] = -2; } qi.unknown = true; } if(!test) { qi.current_account = new AssetsAccount(budget, account_type, name, 0.0, description); budget->addAccount(qi.current_account); qi.accounts++; } } previous_transfers << transfers; transfers.clear(); } else if(type == 2 && !test) { //category subname = name.section(':', 1).trimmed(); name = name.section(':', 0, 0).trimmed(); if(!name.isEmpty()) { if(incomecat) { IncomesAccount *acc = budget->findIncomesAccount(name, NULL); if(!acc) { acc = new IncomesAccount(budget, name, subname.isEmpty() ? description : QString()); budget->addAccount(acc); qi.categories++; } def_income_cats[name] = acc; if(!subname.isEmpty() && !budget->findIncomesAccount(subname, acc)) { IncomesAccount *subacc = new IncomesAccount(budget, subname, description); subacc->setParentCategory(acc); budget->addAccount(subacc); qi.categories++; } } else { ExpensesAccount *acc = budget->findExpensesAccount(name, NULL); if(!acc) { acc = new ExpensesAccount(budget, name, subname.isEmpty() ? description : QString()); budget->addAccount(acc); qi.categories++; } def_expense_cats[name] = acc; if(!subname.isEmpty() && !budget->findExpensesAccount(subname, acc)) { ExpensesAccount *subacc = new ExpensesAccount(budget, subname, description); subacc->setParentCategory(acc); budget->addAccount(subacc); qi.categories++; } } } } else if(type == 3 && !test) { //security /*if(name.isEmpty()) name = Budget::tr("Unnamed"); Security *sec = budget->findSecurity(name); if(!sec) { SecurityType sectype = SECURITY_TYPE_STOCK; if(atype == "mutual fund" || atype == "fund" || atype == "mf") sectype = SECURITY_TYPE_MUTUAL_FUND; else if(atype == "bond" || atype == "dept") sectype = SECURITY_TYPE_BOND; else if(atype == "other" || atype != "oth") sectype = SECURITY_TYPE_OTHER; else if(atype != "stock" && atype != "st") qi.unknown = true; AssetsAccount *saccount = NULL; if(qi.current_account && qi.current_account->accountType() == ASSETS_TYPE_SECURITIES) { saccount = qi.current_account; } else { for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { saccount = *it; if(saccount->accountType() == ASSETS_TYPE_SECURITIES) break; } if(!saccount) { saccount = new AssetsAccount(budget, ASSETS_TYPE_SECURITIES, Budget::tr("Securities")); budget->addAccount(saccount); qi.accounts++; } } sec = new Security(budget, saccount, sectype, 0.0, 4, name, description); budget->addSecurity(sec); }*/ qi.securities++; } memo = QString(); description = QString(); payee = QString(); category = QString(); subcategory = QString(); atype = QString(); atype_bak = QString(); name = QString(); ticker_symbol = QString(); security = QString(); date = QDate(); splits.clear(); current_split = NULL; value = 0.0; //sec_amount = 0.0; //price = 0.0; //commission = 0.0; incomecat = false; break; } } } line = fstream.readLine().trimmed(); } if(qi.value_format == 0) qi.value_format = 1; if(qi.shares_format == 0) qi.shares_format = 1; if(qi.price_format == 0) qi.price_format = 1; if(qi.percentage_format == 0) qi.percentage_format = 1; } QString writeQIFDate(const QDate &date, int date_format) { if(date_format == 1) return date.toString(Qt::ISODate); else if(date_format == 2) return QLocale().toString(date, QLocale::ShortFormat); if(date.year() >= 2000) return date.toString("MM/dd'yy"); return date.toString("MM/dd/yy"); } QString writeQIFValue(double value, int value_format, int decimals) { if(value_format == 1) return QString::number(value, 'f', decimals); QString str = QString::number(value, 'f', decimals); str.replace(".", ","); return str; } void exportQIFTransaction(QTextStream &fstream, qif_info &qi, Transaction *trans) { bool sectrans = false; bool secacc = false; Account *cat = NULL; const QString *payee = NULL; bool neg = false; double d_com = 0.0; fstream << "D" << writeQIFDate(trans->date(), qi.date_format) << "\n"; switch(trans->type()) { case TRANSACTION_TYPE_EXPENSE: { cat = ((Expense*) trans)->category(); payee = &((Expense*) trans)->payee(); neg = true; break; } case TRANSACTION_TYPE_INCOME: { if(trans->subtype() == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND) { fstream << "N" << "ReinvDiv" << "\n"; fstream << "Y" << ((ReinvestedDividend*) trans)->security()->name() << "\n"; fstream << "I" << writeQIFValue(((ReinvestedDividend*) trans)->shareValue(), qi.value_format, SAVE_MONETARY_DECIMAL_PLACES) << "\n"; fstream << "Q" << writeQIFValue(((ReinvestedDividend*) trans)->shares(), qi.value_format, ((ReinvestedDividend*) trans)->security()->decimals()) << "\n"; secacc = true; } else if(((Income*) trans)->security() && ((Income*) trans)->security()->account() == qi.current_account) { fstream << "N" << "DivX" << "\n"; fstream << "Y" << ((Income*) trans)->security()->name() << "\n"; secacc = true; } cat = ((Income*) trans)->category(); payee = &((Income*) trans)->payer(); break; } case TRANSACTION_TYPE_TRANSFER: { if(((Transfer*) trans)->from() == qi.current_account) {cat = ((Transfer*) trans)->to(); neg = true;} else cat = ((Transfer*) trans)->from(); break; } case TRANSACTION_TYPE_SECURITY_SELL: {} case TRANSACTION_TYPE_SECURITY_BUY: { SecurityTransaction *sec = (SecurityTransaction*) trans; sectrans = true; if(sec->security()->account() != qi.current_account) { if(trans->type() == TRANSACTION_TYPE_SECURITY_BUY) { neg = true; } break; } secacc = true; if(trans->type() == TRANSACTION_TYPE_SECURITY_BUY) { fstream << "N" << "BuyX" << "\n"; d_com = sec->value() - sec->shares() * sec->shareValue(); } else { fstream << "N" << "SellX" << "\n"; d_com = sec->shares() * sec->shareValue() - sec->value(); } if(d_com != 0.0) { double deci_pow = pow(10, SAVE_MONETARY_DECIMAL_PLACES); d_com = round(d_com * deci_pow) / deci_pow; } fstream << "Y" << sec->security()->name() << "\n"; fstream << "I" << writeQIFValue(sec->shareValue(), qi.value_format, SAVE_MONETARY_DECIMAL_PLACES) << "\n"; fstream << "Q" << writeQIFValue(sec->shares(), qi.value_format, sec->security()->decimals()) << "\n"; cat = ((SecurityTransaction*) trans)->account(); break; } } fstream << "T" << writeQIFValue(neg ? -trans->value() : trans->value(), qi.value_format, SAVE_MONETARY_DECIMAL_PLACES) << "\n"; fstream << "C" << "X" << "\n"; if(payee && !payee->isEmpty()) fstream << "P" << *payee << "\n"; if(!secacc && !trans->description().isEmpty()) fstream << "M" << trans->description() << "\n"; if(sectrans && secacc && d_com != 0.0) { fstream << "O" << writeQIFValue(d_com, qi.value_format, SAVE_MONETARY_DECIMAL_PLACES) << "\n"; } if(!cat) fstream << "L" << "[" << ((SecurityTransaction*) trans)->security()->account()->name() << ":" << ((SecurityTransaction*) trans)->security()->name() << "]" << "\n"; else if(cat->type() == ACCOUNT_TYPE_ASSETS) fstream << "L" << "[" << cat->name() << "]" << "\n"; else if(cat != trans->budget()->null_incomes_account) fstream << "L" << cat->nameWithParent(false) << "\n"; if(sectrans && secacc) fstream << "$" << writeQIFValue((trans->type() == TRANSACTION_TYPE_SECURITY_SELL) ? -trans->value() : trans->value(), qi.value_format, SAVE_MONETARY_DECIMAL_PLACES) << "\n"; fstream << "^" << "\n"; } void exportQIFSplitTransaction(QTextStream &fstream, qif_info &qi, MultiItemTransaction *split) { fstream << "D" << writeQIFDate(split->date(), qi.date_format) << "\n"; fstream << "T" << writeQIFValue(split->value(), qi.value_format, SAVE_MONETARY_DECIMAL_PLACES) << "\n"; fstream << "C" << "X" << "\n"; QVector::size_type c = split->count(); if(!split->payee().isEmpty()) fstream << "P" << split->payee() << "\n"; if(!split->description().isEmpty()) fstream << "M" << split->description() << "\n"; bool b_more = false; for(QVector::size_type i = 0; i < c; i++) { Transaction *trans = split->at(i); Account *cat = NULL; bool neg = false; switch(trans->type()) { case TRANSACTION_TYPE_EXPENSE: { cat = ((Expense*) trans)->category(); neg = true; break; } case TRANSACTION_TYPE_INCOME: { cat = ((Income*) trans)->category(); break; } case TRANSACTION_TYPE_TRANSFER: { if(((Transfer*) trans)->from() == qi.current_account) {cat = ((Transfer*) trans)->to(); neg = true;} else cat = ((Transfer*) trans)->from(); break; } default: {b_more = true; break;} } if(cat->type() == ACCOUNT_TYPE_ASSETS) fstream << "S" << "[" << cat->name() << "]" << "\n"; else fstream << "S" << cat->nameWithParent(false) << "\n"; if(!trans->description().isEmpty()) fstream << "E" << trans->description() << "\n"; fstream << "$" << writeQIFValue(neg ? -trans->value() : trans->value(), qi.value_format, SAVE_MONETARY_DECIMAL_PLACES) << "\n"; } fstream << "^" << "\n"; if(b_more) { for(QVector::size_type i = 0; i < c; i++) { Transaction *trans = split->at(i); switch(trans->type()) { case TRANSACTION_TYPE_EXPENSE: {} case TRANSACTION_TYPE_INCOME: {} case TRANSACTION_TYPE_TRANSFER: {break;} default: {exportQIFTransaction(fstream, qi, trans); break;} } } } } void exportQIFOpeningBalance(QTextStream &fstream, qif_info &qi, AssetsAccount *account, const QDate &date) { fstream << "!Type:"; switch(account->accountType()) { case ASSETS_TYPE_CURRENT: {fstream << "Bank"; break;} case ASSETS_TYPE_SAVINGS: {fstream << "Bank"; break;} case ASSETS_TYPE_CREDIT_CARD: {fstream << "CCard"; break;} case ASSETS_TYPE_LIABILITIES: {fstream << "Oth L"; break;} case ASSETS_TYPE_SECURITIES: {fstream << "Invst"; break;} case ASSETS_TYPE_BALANCING: {fstream << "Oth A"; break;} case ASSETS_TYPE_CASH: {fstream << "Cash"; break;} default: {fstream << "Oth A"; break;} } fstream << "\n"; if(account->accountType() == ASSETS_TYPE_SECURITIES) { Budget *budget = account->budget(); for(SecurityList::const_iterator it = budget->securities.constBegin(); it != budget->securities.constEnd(); ++it) { Security *sec = *it; if(sec->account() == account && sec->initialShares() > 0.0) { QMap::const_iterator it = sec->quotations.begin(); if(it == sec->quotations.end()) fstream << "D" << writeQIFDate(date, qi.date_format) << "\n"; else fstream << "D" << writeQIFDate(it.key(), qi.date_format) << "\n"; fstream << "N" << "ShrsIn" << "\n"; fstream << "Y" << sec->name() << "\n"; if(it != sec->quotations.end()) fstream << "I" << writeQIFValue(it.value(), qi.value_format, SAVE_MONETARY_DECIMAL_PLACES) << "\n"; fstream << "Q" << writeQIFValue(sec->initialShares(), qi.value_format, sec->decimals()) << "\n"; if(it != sec->quotations.end()) fstream << "T" << writeQIFValue(sec->initialBalance(), qi.value_format, SAVE_MONETARY_DECIMAL_PLACES) << "\n"; fstream << "C" << "X" << "\n"; fstream << "P" << "Opening Balance" << "\n"; fstream << "M" << "Opening" << "\n"; fstream << "^" << "\n"; } } } else { fstream << "D" << writeQIFDate(date, qi.date_format) << "\n"; fstream << "T" << writeQIFValue(account->initialBalance(), qi.value_format, SAVE_MONETARY_DECIMAL_PLACES) << "\n"; fstream << "C" << "X" << "\n"; fstream << "P" << "Opening Balance" << "\n"; fstream << "L" << "[" << account->name() << "]" << "\n"; fstream << "^" << "\n"; } } void exportQIFAccount(QTextStream &fstream, qif_info&, Account *account) { if(account->type() == ACCOUNT_TYPE_ASSETS) fstream << "!Account" << "\n"; else fstream << "!Type:Cat" << "\n"; fstream << "N" << account->nameWithParent(false) << "\n"; if(account->type() == ACCOUNT_TYPE_ASSETS) { fstream << "T"; switch(((AssetsAccount*) account)->accountType()) { case ASSETS_TYPE_CURRENT: {fstream << "Bank"; break;} case ASSETS_TYPE_SAVINGS: {fstream << "Bank"; break;} case ASSETS_TYPE_CREDIT_CARD: {fstream << "CCard"; break;} case ASSETS_TYPE_LIABILITIES: {fstream << "Oth L"; break;} case ASSETS_TYPE_SECURITIES: {fstream << "Invst"; break;} case ASSETS_TYPE_BALANCING: {fstream << "Oth A"; break;} case ASSETS_TYPE_CASH: {fstream << "Cash"; break;} default: {fstream << "Oth A"; break;} } fstream << "\n"; } if(!account->description().isEmpty()) fstream << "D" << account->description() << "\n"; if(account->type() == ACCOUNT_TYPE_EXPENSES) fstream << "E" << "\n"; else if(account->type() == ACCOUNT_TYPE_INCOMES) fstream << "I" << "\n"; fstream << "^" << "\n"; } void exportQIFSecurity(QTextStream &fstream, qif_info&, Security *sec) { fstream << "!Type:Security" << "\n"; fstream << "N" << sec->name() << "\n"; fstream << "T"; switch(sec->type()) { case SECURITY_TYPE_BOND: {fstream << "Bond"; break;} case SECURITY_TYPE_STOCK: {fstream << "Stock"; break;} case SECURITY_TYPE_MUTUAL_FUND: {fstream << "Mutual Fund"; break;} case SECURITY_TYPE_OTHER: {fstream << "Other"; break;} } fstream << "\n"; if(!sec->description().isEmpty()) fstream << "D" << sec->description() << "\n"; fstream << "^" << "\n"; } void exportQIF(QTextStream &fstream, qif_info &qi, Budget *budget, bool export_cats) { if(qi.current_account) { if(export_cats) { QMap icats; QMap ecats; for(TransactionList::const_iterator it = budget->incomes.constBegin(); it != budget->incomes.constEnd(); ++it) { Income *inc = *it; if(inc->to() == qi.current_account) { icats[inc->category()] = true; } } for(TransactionList::const_iterator it = budget->expenses.constBegin(); it != budget->expenses.constEnd(); ++it) { Expense *exp = *it; if(exp->from() == qi.current_account) { ecats[exp->category()] = true; } } QMap::iterator iit_e = icats.end(); for(QMap::iterator iit = icats.begin(); iit != iit_e; ++iit) { exportQIFAccount(fstream, qi, iit.key()); } QMap::iterator eit_e = ecats.end(); for(QMap::iterator eit = ecats.begin(); eit != eit_e; ++eit) { exportQIFAccount(fstream, qi, eit.key()); } for(SecurityList::const_iterator it = budget->securities.constBegin(); it != budget->securities.constEnd(); ++it) { Security *sec = *it; if(sec->account() == qi.current_account) { exportQIFSecurity(fstream, qi, sec); } } } exportQIFAccount(fstream, qi, qi.current_account); bool first = true; SplitTransaction *split = NULL; for(TransactionList::const_iterator it = budget->transactions.constBegin(); it != budget->transactions.constEnd(); ++it) { Transaction *trans = *it; if(trans->fromAccount() == qi.current_account || trans->toAccount() == qi.current_account) { if(first) { exportQIFOpeningBalance(fstream, qi, qi.current_account, trans->date()); first = false; } if(trans->parentSplit() && trans->parentSplit()->type() == SPLIT_TRANSACTION_TYPE_MULTIPLE_ITEMS && ((MultiItemTransaction*) trans->parentSplit())->account() == qi.current_account) { if(!split || split != trans->parentSplit()) { split = trans->parentSplit(); exportQIFSplitTransaction(fstream, qi, (MultiItemTransaction*) split); } } else { exportQIFTransaction(fstream, qi, trans); } } } if(first) { exportQIFOpeningBalance(fstream, qi, qi.current_account, QDate::currentDate()); } for(SecurityList::const_iterator it = budget->securities.constBegin(); it != budget->securities.constEnd(); ++it) { Security *sec = *it; if(sec->account() == qi.current_account) { for(SecurityTransactionList::const_iterator it2 = sec->dividends.constBegin(); it2 != sec->dividends.constEnd(); ++it2) { Income *inc = *it2; exportQIFTransaction(fstream, qi, inc); } for(SecurityTransactionList::const_iterator it2 = sec->reinvestedDividends.constBegin(); it2 != sec->reinvestedDividends.constEnd(); ++it2) { Income *inc = *it2; exportQIFTransaction(fstream, qi, inc); } } } } else { if(export_cats) { for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) { IncomesAccount *iaccount = *it; exportQIFAccount(fstream, qi, iaccount); } for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) { ExpensesAccount *eaccount = *it; exportQIFAccount(fstream, qi, eaccount); } for(SecurityList::const_iterator it = budget->securities.constBegin(); it != budget->securities.constEnd(); ++it) { Security *sec = *it; exportQIFSecurity(fstream, qi, sec); } } for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { AssetsAccount *account = *it; qi.current_account = account; exportQIF(fstream, qi, budget, false); } } } bool exportQIFFile(Budget *budget, QWidget *parent, bool extra_parameters) { if(budget->accounts.count() <= 1) { return false; } ExportQIFDialog *dialog = new ExportQIFDialog(budget, parent, extra_parameters); bool ret = (dialog->exec() == QDialog::Accepted); dialog->deleteLater(); return ret; } Eqonomize-1.5.3/src/qifimportexport.h000066400000000000000000000076601416454732000177210ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifndef QIF_IMPORT_EXPORT_H #define QIF_IMPORT_EXPORT_H #include #include #include #include #include #include "budget.h" class QCheckBox; class QComboBox; class QDialogButtonBox; class QLineEdit; class QPushButton; class QRadioButton; class QTreeWidget; class QTreeWidgetItem; class Budget; class AssetsAccount; struct qif_info { AssetsAccount *current_account; QMap unknown_defs; QMap unknown_defs_pre; bool unhandled; bool unknown; bool had_type, had_type_def, had_account_def; bool account_defined; bool had_transaction; int value_format, date_format, shares_format, price_format, percentage_format; char separator; bool p1, p2, p3, p4, ly; int lz; QString opening_balance_str; int accounts, categories, transactions, securities, security_transactions, duplicates, failed_transactions; }; class ImportQIFDialog : public QWizard { Q_OBJECT protected: Budget *budget; qif_info qi; bool b_extra; int next_id; QLineEdit *fileEdit; QPushButton *fileButton; QTreeWidget *defsView; QComboBox *defsCombo, *dateFormatCombo, *accountCombo; QLineEdit *openingBalanceEdit; QCheckBox *ignoreDuplicateTransactionsButton; public: ImportQIFDialog(Budget *budg, QWidget *parent, bool extra_parameters); ~ImportQIFDialog(); void showPage(int index); int nextId() const; protected slots: void nextClicked(); void accept(); void onFileChanged(const QString&); void selectFile(); void defSelectionChanged(); void defSelected(int); }; class ExportQIFDialog : public QDialog { Q_OBJECT protected: Budget *budget; qif_info qi; bool b_extra; QRadioButton *descriptionAsSubcategoryButton, *descriptionAsPayeeButton, *descriptionAsMemoButton, *descriptionIgnoreButton; QComboBox *accountCombo, *dateFormatCombo, *valueFormatCombo; QDialogButtonBox *buttonBox; QLineEdit *fileEdit; QPushButton *fileButton; public: ExportQIFDialog(Budget *budg, QWidget *parent, bool extra_parameters = false); ~ExportQIFDialog(); protected slots: void accept(); void onFileChanged(const QString&); void selectFile(); }; void importQIF(QTextStream &fstream, bool test, qif_info &qi, Budget *budget, bool ignore_duplicates); bool importQIFFile(Budget *budget, QWidget *parent, bool extra_parameters = false); void exportQIF(QTextStream &fstream, qif_info &qi, Budget *budget, bool export_cats = true); bool exportQIFFile(Budget *budget, QWidget *parent, bool extra_parameters = false); #endif Eqonomize-1.5.3/src/recurrence.cpp000066400000000000000000001170051416454732000171300ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016-2020 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include "budget.h" #include "recurrence.h" int months_between_dates(const QDate &date1, const QDate &date2) { if(date1.year() == date2.year()) { return date2.month() - date1.month(); } int months = 12 - date1.month(); months += (date2.year() - (date1.year() + 1)) * 12; months += date2.month(); return months; } int weeks_between_dates(const QDate &date1, const QDate &date2) { return (date1.dayOfWeek() - date2.dayOfWeek() + date1.daysTo(date2)) / 7; } int get_day_in_month(const QDate &date, int week, int day_of_week) { if(week > 0) { int fwd = date.dayOfWeek(); fwd -= date.day() % 7 - 1; if(fwd <= 0) fwd = 7 + fwd; int day = 1; if(fwd < day_of_week) { day += day_of_week - fwd; } else if(fwd > day_of_week) { day += 7 - (fwd - day_of_week); } day += (week - 1) * 7; if(day > date.daysInMonth()) return 0; return day; } else { int lwd = date.dayOfWeek(); int day = date.daysInMonth(); lwd += (day - date.day()) % 7; if(lwd > 7) lwd = lwd - 7; if(lwd > day_of_week) { day -= lwd - day_of_week; } else if(lwd < day_of_week) { day -= 7 - (day_of_week - lwd); } day -= (-week) * 7; if(day < 1) return 0; return day; } } int get_day_in_month(int year, int month, int week, int day_of_week) { QDate date; date.setDate(year, month, 1); return get_day_in_month(date, week, day_of_week); } Recurrence::Recurrence(Budget *parent_budget) : o_budget(parent_budget) { i_count = -1; } Recurrence::Recurrence(Budget *parent_budget, QXmlStreamReader *xml, bool *valid) : o_budget(parent_budget) { QXmlStreamAttributes attr = xml->attributes(); readAttributes(&attr, valid); readElements(xml, valid); } Recurrence::Recurrence(const Recurrence *rec) : o_budget(rec->budget()), d_startdate(rec->startDate()), d_enddate(rec->endDate()), i_count(rec->fixedOccurrenceCount()), exceptions(rec->exceptions) {} Recurrence::~Recurrence() {} void Recurrence::readAttributes(QXmlStreamAttributes *attr, bool *valid) { d_startdate = QDate::fromString(attr->value("startdate").toString(), Qt::ISODate); if(!attr->value("enddate").isEmpty()) { d_enddate = QDate::fromString(attr->value("enddate").toString(), Qt::ISODate); } if(attr->hasAttribute("recurrences")) i_count = attr->value("recurrences").toInt(); else i_count = -1; if(valid && !d_startdate.isValid()) { *valid = false; } if(!d_enddate.isValid() && !d_enddate.isNull()) d_enddate = QDate(); } bool Recurrence::readElement(QXmlStreamReader *xml, bool*) { if(xml->name() == XML_COMPARE_CONST_CHAR("exception")) { QDate date = QDate::fromString(xml->attributes().value("date").toString(), Qt::ISODate); if(date.isValid() && date >= d_startdate && (d_enddate.isNull() || date <= d_enddate)) { exceptions.append(date); } } return false; } bool Recurrence::readElements(QXmlStreamReader *xml, bool *valid) { while(xml->readNextStartElement()) { if(!readElement(xml, valid)) xml->skipCurrentElement(); } std::sort(exceptions.begin(), exceptions.end()); return true; } void Recurrence::save(QXmlStreamWriter *xml) { QXmlStreamAttributes attr; writeAttributes(&attr); xml->writeAttributes(attr); writeElements(xml); } void Recurrence::writeAttributes(QXmlStreamAttributes *attr) { attr->append("startdate", d_startdate.toString(Qt::ISODate)); if(d_enddate.isValid()) attr->append("enddate", d_enddate.toString(Qt::ISODate)); } void Recurrence::writeElements(QXmlStreamWriter *xml) { for(QVector::iterator it = exceptions.begin(); it != exceptions.end(); ++it) { xml->writeStartElement("exception"); xml->writeAttribute("date", it->toString(Qt::ISODate)); xml->writeEndElement(); } } void Recurrence::updateDates() { if(!d_startdate.isValid()) return; if(!d_enddate.isNull() && i_count <= 0) { d_enddate = prevOccurrence(d_enddate, true); while(exceptions.count() > 0) { if(exceptions.last() == d_enddate) { d_enddate = prevOccurrence(d_enddate, false); exceptions.pop_back(); } else if(exceptions.last() > d_enddate) { exceptions.pop_back(); } else { break; } } } //d_startdate = nextOccurrence(d_startdate, true); while(exceptions.count() > 0) { if(exceptions.first() == d_startdate) { d_startdate = nextOccurrence(d_startdate, false); exceptions.erase(exceptions.begin()); } else if(exceptions.first() < d_startdate) { exceptions.erase(exceptions.begin()); } else { break; } } if(i_count > 0) { d_enddate = QDate(); QDate new_enddate = d_startdate; for(int i = 1; i < i_count; i++) { new_enddate = nextOccurrence(new_enddate); if(new_enddate.isNull()) { i_count = i; break; } } d_enddate = new_enddate; if(d_enddate.isNull()) { d_enddate = d_startdate; } } if(d_enddate.isNull() && nextOccurrence(d_startdate).isNull()) { d_enddate = d_startdate; } } const QDate &Recurrence::firstOccurrence() const { return d_startdate; } const QDate &Recurrence::lastOccurrence() const { return d_enddate; } int Recurrence::countOccurrences(const QDate &startdate, const QDate &enddate) const { if(enddate < d_startdate) return 0; if(!d_enddate.isNull() && startdate > d_enddate) return 0; if(i_count > 0 && startdate <= d_startdate && enddate <= d_enddate) return i_count; QDate date1 = nextOccurrence(startdate, true); if(date1.isNull() || date1 > enddate) return 0; int n = 0; do { n++; date1 = nextOccurrence(date1); } while(!date1.isNull() && date1 <= enddate); return n; } int Recurrence::countOccurrences(const QDate &enddate) const { return countOccurrences(d_startdate, enddate); } bool Recurrence::removeOccurrence(const QDate &date) { addException(date); return true; } const QDate &Recurrence::endDate() const { return d_enddate; } const QDate &Recurrence::startDate() const { return d_startdate; } void Recurrence::setEndDate(const QDate &new_end_date) { i_count = -1; d_enddate = new_end_date; if(!new_end_date.isNull()) { d_enddate = prevOccurrence(d_enddate, true); while(exceptions.count() > 0) { if(exceptions.last() == d_enddate) { d_enddate = prevOccurrence(d_enddate, false); exceptions.pop_back(); } else if(exceptions.last() > d_enddate) { exceptions.pop_back(); } else { break; } } } else if(nextOccurrence(d_startdate).isNull()) { d_enddate = d_startdate; } } void Recurrence::setStartDate(const QDate &new_start_date) { d_startdate = new_start_date; bool set_end_date = false; if(!d_enddate.isNull() && d_startdate > d_enddate) { d_enddate = QDate(); set_end_date = true; } //d_startdate = nextOccurrence(d_startdate, true); while(exceptions.count() > 0) { if(exceptions.first() == d_startdate) { d_startdate = nextOccurrence(d_startdate, false); exceptions.erase(exceptions.begin()); } else if(exceptions.first() < d_startdate) { exceptions.erase(exceptions.begin()); } else { break; } } if(i_count > 0) setFixedOccurrenceCount(i_count); else if(set_end_date) d_enddate = d_startdate; if(d_enddate.isNull() && nextOccurrence(d_startdate).isNull()) { d_enddate = d_startdate; } } int Recurrence::fixedOccurrenceCount() const { return i_count; } void Recurrence::setFixedOccurrenceCount(int new_count) { if(new_count <= 0) { i_count = -1; setEndDate(d_enddate); } else { i_count = new_count; d_enddate = QDate(); QDate new_enddate = d_startdate; for(int i = 1; i < i_count; i++) { new_enddate = nextOccurrence(new_enddate); if(new_enddate.isNull()) { i_count = i; break; } } d_enddate = new_enddate; if(d_enddate.isNull()) { d_enddate = d_startdate; } } } void Recurrence::addException(const QDate &date) { if(hasException(date) || !date.isValid()) return; if(date == d_startdate) { d_startdate = nextOccurrence(d_startdate); if(d_startdate.isNull()) d_enddate = QDate(); return; } if(date == d_enddate) { d_enddate = prevOccurrence(d_enddate); if(d_enddate.isNull()) d_startdate = QDate(); return; } exceptions.append(date); std::sort(exceptions.begin(), exceptions.end()); } int Recurrence::findException(const QDate &date) const { for(QVector::size_type i = 0; i < exceptions.count(); i++) { if(exceptions[i] == date) { return (int) i; } if(exceptions[i] > date) break; } return -1; } bool Recurrence::hasException(const QDate &date) const { return findException(date) >= 0; } bool Recurrence::removeException(const QDate &date) { for(QVector::iterator it = exceptions.begin(); it != exceptions.end(); ++it) { if(*it == date) { exceptions.erase(it); return true; } if(*it > date) break; } return false; } void Recurrence::clearExceptions() { exceptions.clear(); } Budget *Recurrence::budget() const {return o_budget;} DailyRecurrence::DailyRecurrence(Budget *parent_budget) : Recurrence(parent_budget) { i_frequency = 1; } DailyRecurrence::DailyRecurrence(Budget *parent_budget, QXmlStreamReader *xml, bool *valid) : Recurrence(parent_budget) { QXmlStreamAttributes attr = xml->attributes(); readAttributes(&attr, valid); readElements(xml, valid); } DailyRecurrence::DailyRecurrence(const DailyRecurrence *rec) : Recurrence(rec), i_frequency(rec->frequency()) {} DailyRecurrence::~DailyRecurrence() {} Recurrence *DailyRecurrence::copy() const {return new DailyRecurrence(this);} void DailyRecurrence::readAttributes(QXmlStreamAttributes *attr, bool *valid) { Recurrence::readAttributes(attr, valid); if(attr->hasAttribute("frequency")) i_frequency = attr->value("frequency").toInt(); else i_frequency = 1; if(valid && i_frequency < 1) { *valid = false; } updateDates(); } void DailyRecurrence::writeAttributes(QXmlStreamAttributes *attr) { Recurrence::writeAttributes(attr); attr->append("frequency", QString::number(i_frequency)); } QDate DailyRecurrence::nextOccurrence(const QDate &date, bool include_equals) const { if(include_equals) { if(date == startDate()) return date; } QDate nextdate = date; if(!include_equals) nextdate = nextdate.addDays(1); if(!endDate().isNull() && nextdate > endDate()) return QDate(); if(nextdate <= startDate()) return firstOccurrence(); if(i_frequency != 1) { int days = startDate().daysTo(nextdate); if(days % i_frequency != 0) { nextdate = nextdate.addDays(i_frequency - (days % i_frequency)); } } if(!endDate().isNull() && nextdate > endDate()) return QDate(); if(hasException(nextdate)) return nextOccurrence(nextdate); return nextdate; } QDate DailyRecurrence::prevOccurrence(const QDate &date, bool include_equals) const { if(!include_equals) { if(!endDate().isNull() && date > endDate()) return lastOccurrence(); } QDate prevdate = date; if(!include_equals) prevdate = prevdate.addDays(-1); if(prevdate < startDate()) return QDate(); if(prevdate == startDate()) return startDate(); if(i_frequency != 1) { int days = startDate().daysTo(prevdate); if(days % i_frequency != 0) { prevdate = prevdate.addDays(-(days % i_frequency)); } } if(prevdate < startDate()) return QDate(); if(hasException(prevdate)) return prevOccurrence(prevdate); return prevdate; } RecurrenceType DailyRecurrence::type() const { return RECURRENCE_TYPE_DAILY; } int DailyRecurrence::frequency() const { return i_frequency; } void DailyRecurrence::set(const QDate &new_start_date, const QDate &new_end_date, int new_frequency, int occurrences) { i_frequency = new_frequency; setStartDate(new_start_date); if(occurrences <= 0) setEndDate(new_end_date); else setFixedOccurrenceCount(occurrences); } WeeklyRecurrence::WeeklyRecurrence(Budget *parent_budget) : Recurrence(parent_budget) { i_frequency = 1; b_daysofweek[0] = false; b_daysofweek[1] = false; b_daysofweek[2] = false; b_daysofweek[3] = false; b_daysofweek[4] = false; b_daysofweek[5] = false; b_daysofweek[6] = false; } WeeklyRecurrence::WeeklyRecurrence(Budget *parent_budget, QXmlStreamReader *xml, bool *valid) : Recurrence(parent_budget) { QXmlStreamAttributes attr = xml->attributes(); readAttributes(&attr, valid); readElements(xml, valid); } WeeklyRecurrence::WeeklyRecurrence(const WeeklyRecurrence *rec) : Recurrence(rec), i_frequency(rec->frequency()) { b_daysofweek[0] = rec->dayOfWeek(1); b_daysofweek[1] = rec->dayOfWeek(2); b_daysofweek[2] = rec->dayOfWeek(3); b_daysofweek[3] = rec->dayOfWeek(4); b_daysofweek[4] = rec->dayOfWeek(5); b_daysofweek[5] = rec->dayOfWeek(6); b_daysofweek[6] = rec->dayOfWeek(7); } WeeklyRecurrence::~WeeklyRecurrence() {} Recurrence *WeeklyRecurrence::copy() const {return new WeeklyRecurrence(this);} void WeeklyRecurrence::readAttributes(QXmlStreamAttributes *attr, bool *valid) { Recurrence::readAttributes(attr, valid); if(attr->hasAttribute("frequency")) i_frequency = attr->value("frequency").toInt(); else i_frequency = 1; #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) QStringView days = attr->value("days"); #else QStringRef days = attr->value("days"); #endif b_daysofweek[0] = days.indexOf('1') >= 0; b_daysofweek[1] = days.indexOf('2') >= 0; b_daysofweek[2] = days.indexOf('3') >= 0; b_daysofweek[3] = days.indexOf('4') >= 0; b_daysofweek[4] = days.indexOf('5') >= 0; b_daysofweek[5] = days.indexOf('6') >= 0; b_daysofweek[6] = days.indexOf('7') >= 0; if(valid) { bool b = false; for(int i = 0; i < 7; i++) { if(b_daysofweek[i]) { b = true; break; } } if(!b) *valid = false; } if(valid && i_frequency < 1) { *valid = false; } updateDates(); } void WeeklyRecurrence::writeAttributes(QXmlStreamAttributes *attr) { Recurrence::writeAttributes(attr); attr->append("frequency", QString::number(i_frequency)); QString days; if(b_daysofweek[0]) days += '1'; if(b_daysofweek[1]) days += '2'; if(b_daysofweek[2]) days += '3'; if(b_daysofweek[3]) days += '4'; if(b_daysofweek[4]) days += '5'; if(b_daysofweek[5]) days += '6'; if(b_daysofweek[6]) days += '7'; attr->append("days", days); } QDate WeeklyRecurrence::nextOccurrence(const QDate &date, bool include_equals) const { if(!include_equals) { if(date < startDate()) return firstOccurrence(); } else { if(date <= startDate()) return firstOccurrence(); } QDate nextdate = date; if(!include_equals) nextdate = nextdate.addDays(1); if(!endDate().isNull() && nextdate > endDate()) return QDate(); if(i_frequency != 1 && (nextdate.year() != startDate().year() || nextdate.weekNumber() != startDate().weekNumber())) { int i = weeks_between_dates(startDate(), nextdate) % i_frequency; if(i != 0) { nextdate = nextdate.addDays((i_frequency - i) * 7 - (nextdate.dayOfWeek() - 1)); } } int dow = nextdate.dayOfWeek(); int i = dow; for(; i <= 7; i++) { if(b_daysofweek[i - 1]) { break; } } if(i > 7) { for(i = 1; i <= 7; i++) { if(b_daysofweek[i - 1]) { break; } } if(i > 7) return QDate(); } if(i < dow) { nextdate = nextdate.addDays((i_frequency * 7) + i - dow); } else if(i > dow) { nextdate = nextdate.addDays(i - dow); } if(!endDate().isNull() && nextdate > endDate()) return QDate(); if(hasException(nextdate)) return nextOccurrence(nextdate); return nextdate; } QDate WeeklyRecurrence::prevOccurrence(const QDate &date, bool include_equals) const { if(!include_equals) { if(!endDate().isNull() && date > endDate()) return lastOccurrence(); } QDate prevdate = date; if(!include_equals) prevdate = prevdate.addDays(-1); if(prevdate < startDate()) return QDate(); if(prevdate == startDate()) return startDate(); if(i_frequency != 1 && (prevdate.year() != startDate().year() || prevdate.weekNumber() != startDate().weekNumber())) { int i = weeks_between_dates(startDate(), prevdate) % i_frequency; if(i != 0) { prevdate = prevdate.addDays(-(i * 7) + 7 - prevdate.dayOfWeek()); } } int dow_s = startDate().dayOfWeek(); bool s_week = prevdate.year() == startDate().year() && prevdate.weekNumber() == startDate().weekNumber(); int dow = prevdate.dayOfWeek(); int i = dow; for(; i <= 7; i++) { if(b_daysofweek[i - 1] || (s_week && dow_s == i)) { break; } } if(i > 7) { for(i = 1; i <= 7; i++) { if(b_daysofweek[i - 1] || (s_week && dow_s == i)) { break; } } if(i > 7) return QDate(); } if(i > dow) { prevdate = prevdate.addDays(-(i_frequency * 7) + dow - i); } else if(i < dow) { prevdate = prevdate.addDays(dow - i); } if(prevdate < startDate()) return QDate(); if(hasException(prevdate)) return prevOccurrence(prevdate); return prevdate; } RecurrenceType WeeklyRecurrence::type() const { return RECURRENCE_TYPE_WEEKLY; } int WeeklyRecurrence::frequency() const { return i_frequency; } bool WeeklyRecurrence::dayOfWeek(int i) const { if(i >= 1 && i <= 7) return b_daysofweek[i - 1]; return false; } void WeeklyRecurrence::set(const QDate &new_start_date, const QDate &new_end_date, bool d1, bool d2, bool d3, bool d4, bool d5, bool d6, bool d7, int new_frequency, int occurrences) { b_daysofweek[0] = d1; b_daysofweek[1] = d2; b_daysofweek[2] = d3; b_daysofweek[3] = d4; b_daysofweek[4] = d5; b_daysofweek[5] = d6; b_daysofweek[6] = d7; i_frequency = new_frequency; setStartDate(new_start_date); if(occurrences <= 0) setEndDate(new_end_date); else setFixedOccurrenceCount(occurrences); } MonthlyRecurrence::MonthlyRecurrence(Budget *parent_budget) : Recurrence(parent_budget) { i_day = 1; i_frequency = 1; i_week = 1; i_dayofweek = -1; wh_weekendhandling = WEEKEND_HANDLING_NONE; } MonthlyRecurrence::MonthlyRecurrence(Budget *parent_budget, QXmlStreamReader *xml, bool *valid) : Recurrence(parent_budget) { QXmlStreamAttributes attr = xml->attributes(); readAttributes(&attr, valid); readElements(xml, valid); } MonthlyRecurrence::MonthlyRecurrence(const MonthlyRecurrence *rec) : Recurrence(rec), i_frequency(rec->frequency()), i_day(rec->day()), i_week(rec->week()), i_dayofweek(rec->dayOfWeek()), wh_weekendhandling(rec->weekendHandling()) {} MonthlyRecurrence::~MonthlyRecurrence() {} Recurrence *MonthlyRecurrence::copy() const {return new MonthlyRecurrence(this);} void MonthlyRecurrence::readAttributes(QXmlStreamAttributes *attr, bool *valid) { Recurrence::readAttributes(attr, valid); if(attr->hasAttribute("day")) i_day = attr->value("day").toInt(); else i_day = 1; if(attr->hasAttribute("frequency")) i_frequency = attr->value("frequency").toInt(); else i_frequency = 1; if(attr->hasAttribute("week")) i_week = attr->value("week").toInt(); else i_week = 1; if(attr->hasAttribute("dayofweek")) i_dayofweek = attr->value("dayofweek").toInt(); else i_dayofweek = -1; if(attr->hasAttribute("weekendhandling")) wh_weekendhandling = (WeekendHandling) attr->value("weekendhandling").toInt(); else wh_weekendhandling = (WeekendHandling) 0; if(valid && (i_day > 31 || i_day < -27 || i_frequency < 1 || i_week > 5 || i_week < -4 || i_dayofweek > 7)) { *valid = false; } updateDates(); } void MonthlyRecurrence::writeAttributes(QXmlStreamAttributes *attr) { Recurrence::writeAttributes(attr); attr->append("frequency", QString::number(i_frequency)); if(i_dayofweek <= 0) { attr->append("day", QString::number(i_day)); attr->append("weekendhandling", QString::number(wh_weekendhandling)); } else { attr->append("dayofweek", QString::number(i_dayofweek)); attr->append("week", QString::number(i_week)); } } QDate MonthlyRecurrence::nextOccurrence(const QDate &date, bool include_equals) const { if(!include_equals) { if(date < startDate()) return firstOccurrence(); } else { if(date <= startDate()) return firstOccurrence(); } QDate nextdate = date; if(!include_equals) nextdate = nextdate.addDays(1); if(!endDate().isNull() && nextdate > endDate()) return QDate(); int prevday = -1; if(nextdate.year() == startDate().year() && nextdate.month() == startDate().month()) { if(i_frequency > 1) prevday = 1; else prevday = nextdate.day(); nextdate = nextdate.addMonths(i_frequency); nextdate.setDate(nextdate.year(), nextdate.month(), 1); } else if(i_frequency != 1) { int i = months_between_dates(startDate(), nextdate) % i_frequency; if(i != 0) { if(i_frequency - i > 1) prevday = 1; else prevday = nextdate.day(); nextdate = nextdate.addMonths(i_frequency - i); nextdate.setDate(nextdate.year(), nextdate.month(), 1); } } int day = i_day; if(i_dayofweek > 0) day = get_day_in_month(nextdate, i_week, i_dayofweek); else if(i_day < 1) day = nextdate.daysInMonth() + i_day; if(wh_weekendhandling == WEEKEND_HANDLING_BEFORE) { QDate date2; date2.setDate(nextdate.year(), nextdate.month(), day); int wday = date2.dayOfWeek(); if(wday == 6) day -= 1; else if(wday == 7) day -= 2; if(day <= 0 && prevday > 0 && prevday <= nextdate.addMonths(-1).daysInMonth() + day) { nextdate = nextdate.addMonths(-1); day = nextdate.daysInMonth() + day; } } else if(wh_weekendhandling == WEEKEND_HANDLING_AFTER) { QDate date2; date2.setDate(nextdate.year(), nextdate.month(), day); int wday = date2.dayOfWeek(); if(wday == 6) day += 2; else if(wday == 7) day += 1; if(day > nextdate.daysInMonth()) { day -= nextdate.daysInMonth(); nextdate = nextdate.addMonths(1); nextdate.setDate(nextdate.year(), nextdate.month(), day); } } else if(wh_weekendhandling == WEEKEND_HANDLING_NEAREST) { QDate date2; date2.setDate(nextdate.year(), nextdate.month(), day); int wday = date2.dayOfWeek(); if(wday == 6) { day -= 1; if(day <= 0 && prevday > 0 && prevday <= nextdate.addMonths(-1).daysInMonth() + day) { nextdate = nextdate.addMonths(-1); day = nextdate.daysInMonth() + day; } } else if(wday == 7) { day += 1; if(day > nextdate.daysInMonth()) { day -= nextdate.daysInMonth(); nextdate = nextdate.addMonths(1); nextdate.setDate(nextdate.year(), nextdate.month(), day); } } } if(day <= 0 || nextdate.day() > day || day > nextdate.daysInMonth()) { int i = 0; do { if(i >= 1200 / i_frequency) return QDate(); i++; if(i_frequency > 1) prevday = 1; else prevday = nextdate.day(); nextdate = nextdate.addMonths(i_frequency); if(!endDate().isNull() && (nextdate.year() > endDate().year() || (nextdate.year() == endDate().year() && nextdate.month() > endDate().month()))) return QDate(); day = i_day; if(i_dayofweek > 0) day = get_day_in_month(nextdate, i_week, i_dayofweek); else if(i_day < 1) day = nextdate.daysInMonth() + i_day; if(wh_weekendhandling == WEEKEND_HANDLING_BEFORE) { QDate date2; date2.setDate(nextdate.year(), nextdate.month(), day); int wday = date2.dayOfWeek(); if(wday == 6) day -= 1; else if(wday == 7) day -= 2; if(day <= 0 && prevday > 0 && prevday <= nextdate.addMonths(-1).daysInMonth() + day) { nextdate = nextdate.addMonths(-1); day = nextdate.daysInMonth() + day; } else { nextdate.setDate(nextdate.year(), nextdate.month(), 1); } } else if(wh_weekendhandling == WEEKEND_HANDLING_AFTER) { QDate date2; date2.setDate(nextdate.year(), nextdate.month(), day); int wday = date2.dayOfWeek(); if(wday == 6) day += 2; else if(wday == 7) day += 1; if(day > nextdate.daysInMonth()) { day -= nextdate.daysInMonth(); nextdate = nextdate.addMonths(1); nextdate.setDate(nextdate.year(), nextdate.month(), day); } } else if(wh_weekendhandling == WEEKEND_HANDLING_NEAREST) { QDate date2; date2.setDate(nextdate.year(), nextdate.month(), day); int wday = date2.dayOfWeek(); if(wday == 6) { day -= 1; if(day <= 0 && prevday > 0 && prevday <= nextdate.addMonths(-1).daysInMonth() + day) { nextdate = nextdate.addMonths(-1); day = nextdate.daysInMonth() + day; } else { nextdate.setDate(nextdate.year(), nextdate.month(), 1); } } else if(wday == 7) { day += 1; if(day > nextdate.daysInMonth()) { day -= nextdate.daysInMonth(); nextdate = nextdate.addMonths(1); nextdate.setDate(nextdate.year(), nextdate.month(), day); } } } } while(day <= 0 || day > nextdate.daysInMonth()); } nextdate.setDate(nextdate.year(), nextdate.month(), day); if(!endDate().isNull() && nextdate > endDate()) return QDate(); if(hasException(nextdate)) return nextOccurrence(nextdate); return nextdate; } QDate MonthlyRecurrence::prevOccurrence(const QDate &date, bool include_equals) const { if(!include_equals) { if(!endDate().isNull() && date > endDate()) return lastOccurrence(); } QDate prevdate = date; if(!include_equals) prevdate = prevdate.addDays(-1); if(prevdate < startDate()) return QDate(); if(prevdate == startDate()) return startDate(); int prevday = -1; if(i_frequency != 1 && (prevdate.year() != startDate().year() || prevdate.month() != startDate().month())) { int i = months_between_dates(startDate(), prevdate) % i_frequency; if(i != 0) { if(i > 1) prevday = 1; else prevday = prevdate.day(); prevdate = prevdate.addMonths(-i); prevdate.setDate(prevdate.year(), prevdate.month(), prevdate.daysInMonth()); } } if(prevdate.year() == startDate().year() && prevdate.month() == startDate().month()) return startDate(); int day = i_day; if(i_dayofweek > 0) day = get_day_in_month(prevdate, i_week, i_dayofweek); else if(i_day < 1) day = prevdate.daysInMonth() + i_day; if(wh_weekendhandling == WEEKEND_HANDLING_BEFORE) { QDate date2; date2.setDate(prevdate.year(), prevdate.month(), day); int wday = date2.dayOfWeek(); if(wday == 6) day -= 1; else if(wday == 7) day -= 2; if(day <= 0) { prevdate = prevdate.addMonths(-1); day = prevdate.daysInMonth() + day; } } else if(wh_weekendhandling == WEEKEND_HANDLING_AFTER) { QDate date2; date2.setDate(prevdate.year(), prevdate.month(), day); int wday = date2.dayOfWeek(); if(wday == 6) day += 2; else if(wday == 7) day += 1; if(day > prevdate.daysInMonth() && prevday > 0 && prevday >= day - prevdate.daysInMonth()) { day -= prevdate.daysInMonth(); prevdate = prevdate.addMonths(1); prevdate.setDate(prevdate.year(), prevdate.month(), day); } } else if(wh_weekendhandling == WEEKEND_HANDLING_NEAREST) { QDate date2; date2.setDate(prevdate.year(), prevdate.month(), day); int wday = date2.dayOfWeek(); if(wday == 6) { day -= 1; if(day <= 0) { prevdate = prevdate.addMonths(-1); day = prevdate.daysInMonth() + day; } } else if(wday == 7) { day += 1; if(day > prevdate.daysInMonth() && prevday > 0 && prevday >= day - prevdate.daysInMonth()) { day -= prevdate.daysInMonth(); prevdate = prevdate.addMonths(1); prevdate.setDate(prevdate.year(), prevdate.month(), day); } } } if(day <= 0 || prevdate.day() < day) { int i = 0; do { if(i >= 1200 / i_frequency) return QDate(); i++; if(i_frequency > 1) prevday = 1; else prevday = prevdate.day(); prevdate = prevdate.addMonths(-i_frequency); if(prevdate.year() == startDate().year() && prevdate.month() == startDate().month()) return startDate(); if(prevdate.year() <= startDate().year() && prevdate.month() < startDate().month()) return QDate(); day = i_day; if(i_dayofweek > 0) day = get_day_in_month(prevdate, i_week, i_dayofweek); else if(i_day < 1) day = prevdate.daysInMonth() + i_day; if(wh_weekendhandling == WEEKEND_HANDLING_BEFORE) { QDate date2; date2.setDate(prevdate.year(), prevdate.month(), day); int wday = date2.dayOfWeek(); if(wday == 6) day -= 1; else if(wday == 7) day -= 2; if(day <= 0) { prevdate = prevdate.addMonths(-1); day = prevdate.daysInMonth() + day; } } else if(wh_weekendhandling == WEEKEND_HANDLING_AFTER) { QDate date2; date2.setDate(prevdate.year(), prevdate.month(), day); int wday = date2.dayOfWeek(); if(wday == 6) day += 2; else if(wday == 7) day += 1; if(day > prevdate.daysInMonth() && prevday > 0 && prevday >= day - prevdate.daysInMonth()) { day -= prevdate.daysInMonth(); prevdate = prevdate.addMonths(1); prevdate.setDate(prevdate.year(), prevdate.month(), day); } else { prevdate.setDate(prevdate.year(), prevdate.month(), prevdate.daysInMonth()); } } else if(wh_weekendhandling == WEEKEND_HANDLING_NEAREST) { QDate date2; date2.setDate(prevdate.year(), prevdate.month(), day); int wday = date2.dayOfWeek(); if(wday == 6) { day -= 1; if(day <= 0) { prevdate = prevdate.addMonths(-1); day = prevdate.daysInMonth() + day; } } else if(wday == 7) { day += 1; if(day > prevdate.daysInMonth() && prevday > 0 && prevday >= day - prevdate.daysInMonth()) { day -= prevdate.daysInMonth(); prevdate = prevdate.addMonths(1); prevdate.setDate(prevdate.year(), prevdate.month(), day); } else { prevdate.setDate(prevdate.year(), prevdate.month(), prevdate.daysInMonth()); } } } } while(day <= 0 || day > prevdate.daysInMonth()); } prevdate.setDate(prevdate.year(), prevdate.month(), day); if(prevdate < startDate()) return QDate(); if(hasException(prevdate)) return prevOccurrence(prevdate); return prevdate; } RecurrenceType MonthlyRecurrence::type() const { return RECURRENCE_TYPE_MONTHLY; } int MonthlyRecurrence::frequency() const { return i_frequency; } int MonthlyRecurrence::day() const { return i_day; } WeekendHandling MonthlyRecurrence::weekendHandling() const { return wh_weekendhandling; } int MonthlyRecurrence::week() const { return i_week; } int MonthlyRecurrence::dayOfWeek() const { return i_dayofweek; } void MonthlyRecurrence::setOnDayOfWeek(const QDate &new_start_date, const QDate &new_end_date, int new_dayofweek, int new_week, int new_frequency, int occurrences) { i_week = new_week; i_frequency = new_frequency; i_dayofweek = new_dayofweek; wh_weekendhandling = WEEKEND_HANDLING_NONE; setStartDate(new_start_date); if(occurrences <= 0) setEndDate(new_end_date); else setFixedOccurrenceCount(occurrences); } void MonthlyRecurrence::setOnDay(const QDate &new_start_date, const QDate &new_end_date, int new_day, WeekendHandling new_weekendhandling, int new_frequency, int occurrences) { i_dayofweek = -1; i_day = new_day; i_frequency = new_frequency; wh_weekendhandling = new_weekendhandling; setStartDate(new_start_date); if(occurrences <= 0) setEndDate(new_end_date); else setFixedOccurrenceCount(occurrences); } YearlyRecurrence::YearlyRecurrence(Budget *parent_budget) : Recurrence(parent_budget) { i_dayofmonth = 1; i_month = 1; i_frequency = 1; i_week = 1; i_dayofweek = -1; i_dayofyear = -1; wh_weekendhandling = WEEKEND_HANDLING_NONE; } YearlyRecurrence::YearlyRecurrence(Budget *parent_budget, QXmlStreamReader *xml, bool *valid) : Recurrence(parent_budget) { QXmlStreamAttributes attr = xml->attributes(); readAttributes(&attr, valid); readElements(xml, valid); } YearlyRecurrence::YearlyRecurrence(const YearlyRecurrence *rec) : Recurrence(rec), i_frequency(rec->frequency()), i_dayofmonth(rec->dayOfMonth()), i_month(rec->month()), i_week(rec->week()), i_dayofweek(rec->dayOfWeek()), i_dayofyear(rec->dayOfYear()), wh_weekendhandling(rec->weekendHandling()) {} YearlyRecurrence::~YearlyRecurrence() {} Recurrence *YearlyRecurrence::copy() const {return new YearlyRecurrence(this);} void YearlyRecurrence::readAttributes(QXmlStreamAttributes *attr, bool *valid) { Recurrence::readAttributes(attr, valid); if(attr->hasAttribute("frequency")) i_frequency = attr->value("frequency").toInt(); else i_frequency = 1; if(attr->hasAttribute("dayofmonth")) i_dayofmonth = attr->value("dayofmonth").toInt(); else i_dayofmonth = 1; if(attr->hasAttribute("month")) i_month = attr->value("month").toInt(); else i_month = 1; if(attr->hasAttribute("week")) i_week = attr->value("week").toInt(); else i_week = 1; if(attr->hasAttribute("dayofweek")) i_dayofweek = attr->value("dayofweek").toInt(); else i_dayofweek = -1; if(attr->hasAttribute("dayofyear")) i_dayofyear = attr->value("dayofyear").toInt(); else i_dayofyear = -1; if(attr->hasAttribute("weekendhandling")) wh_weekendhandling = (WeekendHandling) attr->value("weekendhandling").toInt(); else wh_weekendhandling = (WeekendHandling) 0; if(valid && (i_dayofmonth > 31 || i_frequency < 1 || i_week > 5 || i_week < -4 || i_dayofweek > 7)) { *valid = false; } updateDates(); } void YearlyRecurrence::writeAttributes(QXmlStreamAttributes *attr) { Recurrence::writeAttributes(attr); attr->append("frequency", QString::number(i_frequency)); if(i_dayofyear > 0) { attr->append("dayofyear", QString::number(i_dayofyear)); attr->append("weekendhandling", QString::number(wh_weekendhandling)); } else if(i_dayofweek > 0) { attr->append("month", QString::number(i_month)); attr->append("dayofweek", QString::number(i_dayofweek)); attr->append("week", QString::number(i_week)); } else { attr->append("month", QString::number(i_month)); attr->append("dayofmonth", QString::number(i_dayofmonth)); attr->append("weekendhandling", QString::number(wh_weekendhandling)); } } QDate YearlyRecurrence::nextOccurrence(const QDate &date, bool include_equals) const { if(!include_equals) { if(date < startDate()) return firstOccurrence(); } else { if(date <= startDate()) return firstOccurrence(); } QDate nextdate = date; if(!include_equals) nextdate = nextdate.addDays(1); if(!endDate().isNull() && nextdate > endDate()) return QDate(); if(nextdate.year() == startDate().year()) { nextdate = nextdate.addYears(i_frequency); nextdate.setDate(nextdate.year(), 1, 1); } else if(i_frequency != 1) { int i = (nextdate.year() - startDate().year()) % i_frequency; if(i != 0) { nextdate = nextdate.addYears(i_frequency - i); nextdate.setDate(nextdate.year(), 1, 1); } } if(i_dayofyear > 0) { if(nextdate.dayOfYear() > i_dayofyear) { nextdate = nextdate.addYears(i_frequency); } if(i_dayofyear > nextdate.daysInYear()) { int i = 10; do { if(i == 0) return QDate(); nextdate = nextdate.addYears(i_frequency); i--; } while(i_dayofyear > nextdate.daysInYear()); } nextdate = nextdate.addDays(i_dayofyear - nextdate.dayOfYear()); } else { int day = i_dayofmonth; if(i_dayofweek > 0) day = get_day_in_month(nextdate.year(), i_month, i_week, i_dayofweek); if(day == 0 || nextdate.month() > i_month || (nextdate.month() == i_month && nextdate.day() > day)) { do { nextdate = nextdate.addYears(i_frequency); if(i_dayofweek > 0) day = get_day_in_month(nextdate.year(), i_month, i_week, i_dayofweek); if(!endDate().isNull() && nextdate.year() > endDate().year()) return QDate(); } while(day == 0); } if(i_dayofweek <= 0) { nextdate.setDate(nextdate.year(), i_month, 1); if(day > nextdate.daysInMonth()) { int i = 10; do { if(i == 0) return QDate(); nextdate = nextdate.addYears(i_frequency); nextdate.setDate(nextdate.year(), i_month, 1); i--; } while(day > nextdate.daysInMonth()); } } nextdate.setDate(nextdate.year(), i_month, day); } if(!endDate().isNull() && nextdate > endDate()) return QDate(); if(hasException(nextdate)) return nextOccurrence(nextdate); return nextdate; } QDate YearlyRecurrence::prevOccurrence(const QDate &date, bool include_equals) const { if(!include_equals) { if(!endDate().isNull() && date > endDate()) return lastOccurrence(); } QDate prevdate = date; if(!include_equals) prevdate = prevdate.addDays(-1); if(prevdate < startDate()) return QDate(); if(prevdate == startDate()) return startDate(); if(i_frequency != 1) { int i = (prevdate.year() - startDate().year()) % i_frequency; if(i != 0) { prevdate = prevdate.addYears(-i); } } if(prevdate.year() == startDate().year()) return startDate(); if(i_dayofyear > 0) { if(prevdate.dayOfYear() < i_dayofyear) { prevdate = prevdate.addYears(-i_frequency); if(prevdate.year() == startDate().year()) return startDate(); } if(i_dayofyear > prevdate.daysInYear()) { do { prevdate = prevdate.addYears(-i_frequency); if(prevdate.year() <= startDate().year()) return startDate(); } while(i_dayofyear > prevdate.daysInYear()); } prevdate = prevdate.addDays(i_dayofyear - prevdate.dayOfYear()); } else { int day = i_dayofmonth; if(i_dayofweek > 0) day = get_day_in_month(prevdate.year(), i_month, i_week, i_dayofweek); if(day <= 0 || prevdate.month() < i_month || (prevdate.month() == i_month && prevdate.day() < day)) { do { prevdate = prevdate.addYears(-i_frequency); if(i_dayofweek > 0) day = get_day_in_month(prevdate.year(), i_month, i_week, i_dayofweek); if(prevdate.year() == startDate().year()) return startDate(); } while(day <= 0); } if(i_dayofweek <= 0) { prevdate.setDate(prevdate.year(), i_month, 1); if(day > prevdate.daysInMonth()) { do { prevdate = prevdate.addYears(-i_frequency); prevdate.setDate(prevdate.year(), i_month, 1); if(prevdate.year() <= startDate().year()) return startDate(); } while(day > prevdate.daysInMonth()); } } prevdate.setDate(prevdate.year(), i_month, day); } if(prevdate < startDate()) return QDate(); if(hasException(prevdate)) return prevOccurrence(prevdate); return prevdate; } RecurrenceType YearlyRecurrence::type() const { return RECURRENCE_TYPE_YEARLY; } int YearlyRecurrence::frequency() const { return i_frequency; } int YearlyRecurrence::dayOfYear() const { return i_dayofyear; } int YearlyRecurrence::month() const { return i_month; } int YearlyRecurrence::dayOfMonth() const { return i_dayofmonth; } WeekendHandling YearlyRecurrence::weekendHandling() const { return wh_weekendhandling; } int YearlyRecurrence::week() const { return i_week; } int YearlyRecurrence::dayOfWeek() const { return i_dayofweek; } void YearlyRecurrence::setOnDayOfWeek(const QDate &new_start_date, const QDate &new_end_date, int new_month, int new_dayofweek, int new_week, int new_frequency, int occurrences) { i_dayofyear = -1; wh_weekendhandling = WEEKEND_HANDLING_NONE; i_dayofweek = new_dayofweek; i_week = new_week; i_month = new_month; i_frequency = new_frequency; setStartDate(new_start_date); if(occurrences <= 0) setEndDate(new_end_date); else setFixedOccurrenceCount(occurrences); } void YearlyRecurrence::setOnDayOfMonth(const QDate &new_start_date, const QDate &new_end_date, int new_month, int new_day, WeekendHandling new_weekendhandling, int new_frequency, int occurrences) { i_dayofweek = -1; i_dayofyear = -1; i_dayofmonth = new_day; i_month = new_month; i_frequency = new_frequency; wh_weekendhandling = new_weekendhandling; setStartDate(new_start_date); if(occurrences <= 0) setEndDate(new_end_date); else setFixedOccurrenceCount(occurrences); } void YearlyRecurrence::setOnDayOfYear(const QDate &new_start_date, const QDate &new_end_date, int new_day, WeekendHandling new_weekendhandling, int new_frequency, int occurrences) { i_dayofyear = new_day; wh_weekendhandling = new_weekendhandling; i_frequency = new_frequency; setStartDate(new_start_date); if(occurrences <= 0) setEndDate(new_end_date); else setFixedOccurrenceCount(occurrences); } Eqonomize-1.5.3/src/recurrence.h000066400000000000000000000174441416454732000166030ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifndef RECURRENCE_H #define RECURRENCE_H #include #include #include class QXmlStreamReader; class QXmlStreamWriter; class QXmlStreamAttributes; class Budget; typedef enum { RECURRENCE_TYPE_DAILY, RECURRENCE_TYPE_WEEKLY, RECURRENCE_TYPE_MONTHLY, RECURRENCE_TYPE_YEARLY } RecurrenceType; class Recurrence { protected: Budget *o_budget; QDate d_startdate, d_enddate; int i_count; public: Recurrence(Budget *parent_budget); Recurrence(Budget *parent_budget, QXmlStreamReader *xml, bool *valid); Recurrence(const Recurrence *rec); virtual ~Recurrence(); virtual Recurrence *copy() const = 0; virtual void readAttributes(QXmlStreamAttributes *attr, bool *valid); virtual bool readElement(QXmlStreamReader *xml, bool *valid); virtual bool readElements(QXmlStreamReader *xml, bool *valid); virtual void save(QXmlStreamWriter *xml); virtual void writeAttributes(QXmlStreamAttributes *attr); virtual void writeElements(QXmlStreamWriter *xml); void updateDates(); virtual QDate nextOccurrence(const QDate &date, bool include_equals = false) const = 0; virtual QDate prevOccurrence(const QDate &date, bool include_equals = false) const = 0; const QDate &firstOccurrence() const; const QDate &lastOccurrence() const; int countOccurrences(const QDate &startdate, const QDate &enddate) const; int countOccurrences(const QDate &enddate) const; bool removeOccurrence(const QDate &date); const QDate &endDate() const; const QDate &startDate() const; int fixedOccurrenceCount() const; void setFixedOccurrenceCount(int new_count); void setEndDate(const QDate &new_end_date); void setStartDate(const QDate &new_start_date); virtual RecurrenceType type() const = 0; void addException(const QDate &date); int findException(const QDate &date) const; bool hasException(const QDate &date) const; bool removeException(const QDate &date); void clearExceptions(); Budget *budget() const; QVector exceptions; }; class DailyRecurrence : public Recurrence { protected: int i_frequency; public: DailyRecurrence(Budget *parent_budget); DailyRecurrence(Budget *parent_budget, QXmlStreamReader *xml, bool *valid); DailyRecurrence(const DailyRecurrence *rec); virtual ~DailyRecurrence(); Recurrence *copy() const; virtual void readAttributes(QXmlStreamAttributes *attr, bool *valid); virtual void writeAttributes(QXmlStreamAttributes *attr); QDate nextOccurrence(const QDate &date, bool include_equals = false) const; QDate prevOccurrence(const QDate &date, bool include_equals = false) const; RecurrenceType type() const; int frequency() const; void set(const QDate &new_start_date, const QDate &new_end_date, int new_frequency, int occurrences = -1); }; class WeeklyRecurrence : public Recurrence { protected: int i_frequency; bool b_daysofweek[7]; public: WeeklyRecurrence(Budget *parent_budget); WeeklyRecurrence(Budget *parent_budget, QXmlStreamReader *xml, bool *valid); WeeklyRecurrence(const WeeklyRecurrence *rec); virtual ~WeeklyRecurrence(); Recurrence *copy() const; virtual void readAttributes(QXmlStreamAttributes *attr, bool *valid); virtual void writeAttributes(QXmlStreamAttributes *attr); QDate nextOccurrence(const QDate &date, bool include_equals = false) const; QDate prevOccurrence(const QDate &date, bool include_equals = false) const; RecurrenceType type() const; int frequency() const; bool dayOfWeek(int i) const; void set(const QDate &new_start_date, const QDate &new_end_date, bool d1, bool d2, bool d3, bool d4, bool d5, bool d6, bool d7, int new_frequency, int occurrences = -1); }; typedef enum { WEEKEND_HANDLING_NONE = 0, WEEKEND_HANDLING_BEFORE = 1, WEEKEND_HANDLING_AFTER = 2, WEEKEND_HANDLING_NEAREST = 3 } WeekendHandling; class MonthlyRecurrence : public Recurrence { protected: int i_frequency; int i_day; int i_week; int i_dayofweek; WeekendHandling wh_weekendhandling; public: MonthlyRecurrence(Budget *parent_budget); MonthlyRecurrence(Budget *parent_budget, QXmlStreamReader *xml, bool *valid); MonthlyRecurrence(const MonthlyRecurrence *rec); virtual ~MonthlyRecurrence(); Recurrence *copy() const; virtual void readAttributes(QXmlStreamAttributes *attr, bool *valid); virtual void writeAttributes(QXmlStreamAttributes *attr); QDate nextOccurrence(const QDate &date, bool include_equals = false) const; QDate prevOccurrence(const QDate &date, bool include_equals = false) const; RecurrenceType type() const; int frequency() const; int day() const; WeekendHandling weekendHandling() const; int week() const; int dayOfWeek() const; void setOnDayOfWeek(const QDate &new_start_date, const QDate &new_end_date, int new_dayofweek, int new_week, int new_frequency, int occurrences = -1); void setOnDay(const QDate &new_start_date, const QDate &new_end_date, int new_day, WeekendHandling new_weekendhandling, int new_frequency, int occurrences = -1); }; class YearlyRecurrence : public Recurrence { protected: int i_frequency; int i_dayofmonth; int i_month; int i_week; int i_dayofweek; int i_dayofyear; WeekendHandling wh_weekendhandling; public: YearlyRecurrence(Budget *parent_budget); YearlyRecurrence(Budget *parent_budget, QXmlStreamReader *xml, bool *valid); YearlyRecurrence(const YearlyRecurrence *rec); virtual ~YearlyRecurrence(); Recurrence *copy() const; virtual void readAttributes(QXmlStreamAttributes *attr, bool *valid); virtual void writeAttributes(QXmlStreamAttributes *attr); QDate nextOccurrence(const QDate &date, bool include_equals = false) const; QDate prevOccurrence(const QDate &date, bool include_equals = false) const; RecurrenceType type() const; int frequency() const; int month() const; int dayOfMonth() const; int week() const; int dayOfWeek() const; int dayOfYear() const; WeekendHandling weekendHandling() const; void setOnDayOfWeek(const QDate &new_start_date, const QDate &new_end_date, int new_month, int new_dayofweek, int new_week, int new_frequency, int occurrences = -1); void setOnDayOfMonth(const QDate &new_start_date, const QDate &new_end_date, int new_month, int new_day, WeekendHandling new_weekendhandling, int new_frequency, int occurrences = -1); void setOnDayOfYear(const QDate &new_start_date, const QDate &new_end_date, int new_day, WeekendHandling new_weekendhandling, int new_frequency, int occurrences = -1); }; #endif Eqonomize-1.5.3/src/recurrenceeditwidget.cpp000066400000000000000000001001011416454732000211670ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "budget.h" #include "eqonomizevalueedit.h" #include "recurrence.h" #include "recurrenceeditwidget.h" EditExceptionsDialog::EditExceptionsDialog(QWidget *parent) : QDialog(parent) { setWindowTitle(tr("Edit Exceptions")); setModal(true); QVBoxLayout *box1 = new QVBoxLayout(this); QGridLayout *layout = new QGridLayout(); box1->addLayout(layout); layout->addWidget(new QLabel(tr("Occurrences:"), this), 0, 0); occurrencesList = new QListWidget(this); occurrencesList->setSelectionMode(QListWidget::ExtendedSelection); layout->addWidget(occurrencesList, 1, 0); QVBoxLayout *buttonsLayout = new QVBoxLayout(); layout->addLayout(buttonsLayout, 0, 1, -1, 1); buttonsLayout->addStretch(1); addButton = new QPushButton(tr("Add Exception"), this); addButton->setEnabled(false); buttonsLayout->addWidget(addButton); deleteButton = new QPushButton(tr("Remove Exception"), this); deleteButton->setEnabled(false); buttonsLayout->addWidget(deleteButton); buttonsLayout->addStretch(1); layout->addWidget(new QLabel(tr("Exceptions:"), this), 0, 2); exceptionsList = new QListWidget(this); exceptionsList->setSelectionMode(QListWidget::ExtendedSelection); layout->addWidget(exceptionsList, 1, 2); infoLabel = new QLabel(QString("") + tr("Only the first fifty occurrences are shown.") + QString(""), this); infoLabel->hide(); layout->addWidget(infoLabel, 2, 0, 1, -1); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, this); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept())); box1->addWidget(buttonBox); connect(occurrencesList, SIGNAL(itemSelectionChanged()), this, SLOT(onSelectionChanged())); connect(exceptionsList, SIGNAL(itemSelectionChanged()), this, SLOT(onSelectionChanged())); connect(addButton, SIGNAL(clicked()), this, SLOT(addException())); connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteException())); } EditExceptionsDialog::~EditExceptionsDialog() { } void EditExceptionsDialog::setRecurrence(Recurrence *rec) { occurrencesList->clear(); exceptionsList->clear(); if(rec) { QDate next_date = rec->firstOccurrence(); int i = 0; for(; i < 50 && next_date.isValid(); i++) { occurrencesList->addItem(QLocale().toString(next_date, QLocale::ShortFormat)); next_date = rec->nextOccurrence(next_date); } if(i == 50) { infoLabel->show(); } else { infoLabel->hide(); } for(QVector::size_type i = 0; i < rec->exceptions.size(); i++) { exceptionsList->addItem(QLocale().toString(rec->exceptions[i], QLocale::ShortFormat)); } exceptionsList->sortItems(); } o_rec = rec; saveValues(); } void EditExceptionsDialog::modifyExceptions(Recurrence *rec) { for(int i = 0; i < exceptionsList->count(); i++) { rec->addException(QLocale().toDate(exceptionsList->item(i)->text(), QLocale::ShortFormat)); } } bool EditExceptionsDialog::validValues() { return true; } void EditExceptionsDialog::saveValues() { savedExceptions.clear(); for(int i = 0; i < exceptionsList->count(); i++) { savedExceptions.append(exceptionsList->item(i)->text()); } } void EditExceptionsDialog::restoreValues() { exceptionsList->clear(); exceptionsList->addItems(savedExceptions); } void EditExceptionsDialog::accept() { if(!validValues()) return; saveValues(); QDialog::accept(); } void EditExceptionsDialog::reject() { restoreValues(); QDialog::reject(); } void EditExceptionsDialog::onSelectionChanged() { QList list = exceptionsList->selectedItems(); deleteButton->setEnabled(!list.isEmpty()); list = occurrencesList->selectedItems(); if(!list.isEmpty() && list.first() == occurrencesList->item(0)) { occurrencesList->item(0)->setSelected(false); list.removeFirst(); } addButton->setEnabled(!list.isEmpty()); } void EditExceptionsDialog::addException() { QList list = occurrencesList->selectedItems(); for(int i = 0; i < list.count(); i++) { exceptionsList->addItem(list[i]->text()); delete list[i]; } exceptionsList->sortItems(); } void EditExceptionsDialog::deleteException() { QList list = exceptionsList->selectedItems(); for(int i = 0; i < list.count(); i++) { delete list[i]; } modifyExceptions(o_rec); occurrencesList->clear(); QDate next_date = o_rec->firstOccurrence(); for(int i = 0; i < 50 && next_date.isValid(); i++) { occurrencesList->addItem(QLocale().toString(next_date, QLocale::ShortFormat)); next_date = o_rec->nextOccurrence(next_date); } } EditRangeDialog::EditRangeDialog(const QDate &startdate, QWidget *parent) : QDialog(parent), date(startdate) { setWindowTitle(tr("Edit Recurrence Range")); setModal(true); QVBoxLayout *box1 = new QVBoxLayout(this); QGridLayout *rangeLayout = new QGridLayout(); box1->addLayout(rangeLayout); startLabel = new QLabel(tr("Begins on: %1").arg(QLocale().toString(startdate)), this); rangeLayout->addWidget(startLabel, 0, 0, 1, 3); rangeButtonGroup = new QButtonGroup(this); foreverButton = new QRadioButton(tr("No ending date"), this); rangeButtonGroup->addButton(foreverButton); rangeLayout->addWidget(foreverButton, 1, 0, 1, 3); fixedCountButton = new QRadioButton(tr("End after"), this); rangeButtonGroup->addButton(fixedCountButton); rangeLayout->addWidget(fixedCountButton, 2, 0); fixedCountEdit = new QSpinBox(this); fixedCountEdit->setRange(1, 9999); rangeLayout->addWidget(fixedCountEdit, 2, 1); rangeLayout ->addWidget(new QLabel(tr("occurrence(s)"), this), 2, 2); endDateButton = new QRadioButton(tr("End on"), this); rangeButtonGroup->addButton(endDateButton); rangeLayout->addWidget(endDateButton, 3, 0); endDateEdit = new EqonomizeDateEdit(startdate, this); endDateEdit->setCalendarPopup(true); rangeLayout->addWidget(endDateEdit, 3, 1, 1, 2); setRecurrence(NULL); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, this); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept())); box1->addWidget(buttonBox); connect(fixedCountButton, SIGNAL(toggled(bool)), fixedCountEdit, SLOT(setEnabled(bool))); connect(endDateButton, SIGNAL(toggled(bool)), endDateEdit, SLOT(setEnabled(bool))); } EditRangeDialog::~EditRangeDialog() { } void EditRangeDialog::setStartDate(const QDate &startdate) { startLabel->setText(tr("Begins on: %1").arg(QLocale().toString(startdate))); date = startdate; if(!endDateButton->isChecked() && date > endDateEdit->date()) { endDateEdit->setDate(date); } } void EditRangeDialog::setRecurrence(Recurrence *rec) { if(rec && rec->fixedOccurrenceCount() > 0) { fixedCountButton->setChecked(true); fixedCountEdit->setValue(rec->fixedOccurrenceCount()); endDateEdit->setEnabled(false); fixedCountEdit->setEnabled(true); endDateEdit->setDate(date); } else if(rec && !rec->endDate().isNull()) { endDateButton->setChecked(true); endDateEdit->setDate(rec->endDate()); endDateEdit->setEnabled(true); fixedCountEdit->setEnabled(false); fixedCountEdit->setValue(1); } else { foreverButton->setChecked(true); endDateEdit->setEnabled(false); fixedCountEdit->setEnabled(false); endDateEdit->setDate(date); fixedCountEdit->setValue(1); } saveValues(); } int EditRangeDialog::fixedCount() { if(fixedCountButton->isChecked()) { return fixedCountEdit->value(); } return -1; } QDate EditRangeDialog::endDate() { if(endDateButton->isChecked()) { return endDateEdit->date(); } return QDate(); } void EditRangeDialog::accept() { if(!validValues()) return; saveValues(); QDialog::accept(); } void EditRangeDialog::reject() { restoreValues(); QDialog::reject(); } void EditRangeDialog::saveValues() { fixedCountEdit_value = fixedCountEdit->value(); endDateEdit_value = endDateEdit->date(); if(foreverButton->isChecked()) checkedButton = foreverButton; else if(endDateButton->isChecked()) checkedButton = endDateButton; else checkedButton = fixedCountButton; } void EditRangeDialog::restoreValues() { fixedCountEdit->setValue(fixedCountEdit_value); endDateEdit->setDate(endDateEdit_value); checkedButton->setChecked(true); } bool EditRangeDialog::validValues() { if(endDateButton->isChecked()) { if(!endDateEdit->date().isValid()) { QMessageBox::critical(this, tr("Error"), tr("Invalid date.")); endDateEdit->setFocus(); endDateEdit->setCurrentSection(QDateTimeEdit::DaySection); return false; } if(endDateEdit->date() < date) { QMessageBox::critical(this, tr("Error"), tr("End date before start date.")); endDateEdit->setFocus(); endDateEdit->setCurrentSection(QDateTimeEdit::DaySection); return false; } } return true; } RecurrenceEditWidget::RecurrenceEditWidget(const QDate &startdate, Budget *budg, QWidget *parent) : QWidget(parent), date(startdate), budget(budg) { QVBoxLayout *recurrenceLayout = new QVBoxLayout(this); //recurrenceLayout->setContentsMargins(0, 0, 0, 0); recurrenceButton = new QCheckBox(tr("Enable recurrence"), this); recurrenceLayout->addWidget(recurrenceButton); ruleGroup = new QGroupBox(tr("Recurrence Rule"), this); QVBoxLayout *ruleGroup_layout = new QVBoxLayout(ruleGroup); typeCombo = new QComboBox(ruleGroup); typeCombo->setEditable(false); typeCombo->addItem(tr("Daily")); typeCombo->addItem(tr("Weekly")); typeCombo->addItem(tr("Monthly")); typeCombo->addItem(tr("Yearly")); typeCombo->setCurrentIndex(2); ruleGroup_layout->addWidget(typeCombo); ruleStack = new QStackedWidget(ruleGroup); ruleGroup_layout->addWidget(ruleStack); QWidget *dailyRuleWidget = new QWidget(ruleStack); ruleStack->addWidget(dailyRuleWidget); QWidget *weeklyRuleWidget = new QWidget(ruleStack); ruleStack->addWidget(weeklyRuleWidget); QWidget *monthlyRuleWidget = new QWidget(ruleStack); ruleStack->addWidget(monthlyRuleWidget); QWidget *yearlyRuleWidget = new QWidget(ruleStack); ruleStack->addWidget(yearlyRuleWidget); QVBoxLayout *dailyRuleLayout = new QVBoxLayout(dailyRuleWidget); QHBoxLayout *dailyFrequencyLayout = new QHBoxLayout(); dailyRuleLayout->addLayout(dailyFrequencyLayout); dailyFrequencyLayout->addWidget(new QLabel(tr("Recur every"), dailyRuleWidget)); dailyFrequencyEdit = new QSpinBox(dailyRuleWidget); dailyFrequencyEdit->setRange(1, 9999); dailyFrequencyLayout->addWidget(dailyFrequencyEdit); dailyFrequencyLayout->addWidget(new QLabel(tr("day(s)"), dailyRuleWidget)); dailyFrequencyLayout->addStretch(1); dailyRuleLayout->addStretch(1); QVBoxLayout *weeklyRuleLayout = new QVBoxLayout(weeklyRuleWidget); QHBoxLayout *weeklyFrequencyLayout = new QHBoxLayout(); weeklyRuleLayout->addLayout(weeklyFrequencyLayout); weeklyFrequencyLayout->addWidget(new QLabel(tr("Recur every"), weeklyRuleWidget)); weeklyFrequencyEdit = new QSpinBox(weeklyRuleWidget); weeklyFrequencyEdit->setRange(1, 9999); weeklyFrequencyLayout->addWidget(weeklyFrequencyEdit); weeklyFrequencyLayout->addWidget(new QLabel(tr("week(s) on:"), weeklyRuleWidget)); weeklyFrequencyLayout->addStretch(1); QHBoxLayout *weeklyDaysLayout = new QHBoxLayout(); weeklyRuleLayout->addLayout(weeklyDaysLayout); int weekStart = QLocale().firstDayOfWeek(); for(int i = 0; i < 7; ++i ) { weeklyButtons[i] = new QCheckBox(QLocale().standaloneDayName(i + 1, QLocale::ShortFormat), weeklyRuleWidget); } for(int i = weekStart - 1; i < 7; ++i ) { weeklyDaysLayout->addWidget(weeklyButtons[i]); } for(int i = 0; i < weekStart - 1; ++i ) { weeklyDaysLayout->addWidget(weeklyButtons[i]); } weeklyRuleLayout->addStretch(1); QVBoxLayout *monthlyRuleLayout = new QVBoxLayout(monthlyRuleWidget); QHBoxLayout *monthlyFrequencyLayout = new QHBoxLayout(); monthlyRuleLayout->addLayout(monthlyFrequencyLayout); monthlyFrequencyLayout->addWidget(new QLabel(tr("Recur every"), monthlyRuleWidget)); monthlyFrequencyEdit = new QSpinBox(monthlyRuleWidget); monthlyFrequencyEdit->setRange(1, 9999); monthlyFrequencyLayout->addWidget(monthlyFrequencyEdit); monthlyFrequencyLayout->addWidget(new QLabel(tr("month(s), after the start month"), monthlyRuleWidget)); monthlyFrequencyLayout->addStretch(1); QButtonGroup *monthlyButtonGroup = new QButtonGroup(this); QGridLayout *monthlyButtonLayout = new QGridLayout(); monthlyRuleLayout->addLayout(monthlyButtonLayout, 1); monthlyOnDayButton = new QRadioButton(tr("Recur on the"), monthlyRuleWidget); monthlyOnDayButton->setChecked(true); monthlyButtonGroup->addButton(monthlyOnDayButton); monthlyButtonLayout->addWidget(monthlyOnDayButton, 0, 0); QBoxLayout *monthlyDayLayout = new QHBoxLayout(); monthlyDayCombo = new QComboBox(monthlyRuleWidget); monthlyDayCombo->addItem(tr("1st")); monthlyDayCombo->addItem(tr("2nd")); monthlyDayCombo->addItem(tr("3rd")); monthlyDayCombo->addItem(tr("4th")); monthlyDayCombo->addItem(tr("5th")); monthlyDayCombo->addItem(tr("6th")); monthlyDayCombo->addItem(tr("7th")); monthlyDayCombo->addItem(tr("8th")); monthlyDayCombo->addItem(tr("9th")); monthlyDayCombo->addItem(tr("10th")); monthlyDayCombo->addItem(tr("11th")); monthlyDayCombo->addItem(tr("12th")); monthlyDayCombo->addItem(tr("13th")); monthlyDayCombo->addItem(tr("14th")); monthlyDayCombo->addItem(tr("15th")); monthlyDayCombo->addItem(tr("16th")); monthlyDayCombo->addItem(tr("17th")); monthlyDayCombo->addItem(tr("18th")); monthlyDayCombo->addItem(tr("19th")); monthlyDayCombo->addItem(tr("20th")); monthlyDayCombo->addItem(tr("21st")); monthlyDayCombo->addItem(tr("22nd")); monthlyDayCombo->addItem(tr("23rd")); monthlyDayCombo->addItem(tr("24th")); monthlyDayCombo->addItem(tr("25th")); monthlyDayCombo->addItem(tr("26th")); monthlyDayCombo->addItem(tr("27th")); monthlyDayCombo->addItem(tr("28th")); monthlyDayCombo->addItem(tr("29th")); monthlyDayCombo->addItem(tr("30th")); monthlyDayCombo->addItem(tr("31st")); monthlyDayCombo->addItem(tr("Last")); monthlyDayCombo->addItem(tr("2nd Last")); monthlyDayCombo->addItem(tr("3rd Last")); monthlyDayCombo->addItem(tr("4th Last")); monthlyDayCombo->addItem(tr("5th Last")); monthlyDayLayout->addWidget(monthlyDayCombo); monthlyDayLayout->addWidget(new QLabel(tr("day"), monthlyRuleWidget)); monthlyWeekendCombo = new QComboBox(monthlyRuleWidget); monthlyWeekendCombo->addItem(tr("possibly on weekend")); monthlyWeekendCombo->addItem(tr("but before weekend")); monthlyWeekendCombo->addItem(tr("but after weekend")); monthlyWeekendCombo->addItem(tr("on nearest weekday")); monthlyDayLayout->addWidget(monthlyWeekendCombo); monthlyDayLayout->addStretch(1); monthlyButtonLayout->addLayout(monthlyDayLayout, 0, 1); monthlyOnDayOfWeekButton = new QRadioButton(tr("Recur on the"), monthlyRuleWidget); monthlyButtonGroup->addButton(monthlyOnDayOfWeekButton); monthlyButtonLayout->addWidget(monthlyOnDayOfWeekButton, 1, 0); QBoxLayout *monthlyWeekLayout = new QHBoxLayout(); monthlyWeekCombo = new QComboBox(monthlyRuleWidget); monthlyWeekCombo->addItem(tr("1st")); monthlyWeekCombo->addItem(tr("2nd")); monthlyWeekCombo->addItem(tr("3rd")); monthlyWeekCombo->addItem(tr("4th")); monthlyWeekCombo->addItem(tr("5th")); monthlyWeekCombo->addItem(tr("Last")); monthlyWeekCombo->addItem(tr("2nd Last")); monthlyWeekCombo->addItem(tr("3rd Last")); monthlyWeekCombo->addItem(tr("4th Last")); monthlyWeekLayout->addWidget(monthlyWeekCombo); monthlyDayOfWeekCombo = new QComboBox(monthlyRuleWidget); monthlyWeekLayout->addWidget(monthlyDayOfWeekCombo); monthlyWeekLayout->addStretch(1); monthlyButtonLayout->addLayout(monthlyWeekLayout, 1, 1); monthlyRuleLayout->addStretch(1); QVBoxLayout *yearlyRuleLayout = new QVBoxLayout(yearlyRuleWidget); QHBoxLayout *yearlyFrequencyLayout = new QHBoxLayout(); yearlyRuleLayout->addLayout(yearlyFrequencyLayout); yearlyFrequencyLayout->addWidget(new QLabel(tr("Recur every"), yearlyRuleWidget)); yearlyFrequencyEdit = new QSpinBox(yearlyRuleWidget); yearlyFrequencyEdit->setRange(1, 9999); yearlyFrequencyLayout->addWidget(yearlyFrequencyEdit); yearlyFrequencyLayout->addWidget(new QLabel(tr("year(s), after the start year"), yearlyRuleWidget)); yearlyFrequencyLayout->addStretch(1); QButtonGroup *yearlyButtonGroup = new QButtonGroup(this); QGridLayout *yearlyButtonLayout = new QGridLayout(); yearlyRuleLayout->addLayout(yearlyButtonLayout, 1); yearlyOnDayOfMonthButton = new QRadioButton(tr("Recur on day", "part before XXX of 'Recur on day XXX of month YYY'"), yearlyRuleWidget); yearlyButtonGroup->addButton(yearlyOnDayOfMonthButton); yearlyOnDayOfMonthButton->setChecked(true); yearlyButtonLayout->addWidget(yearlyOnDayOfMonthButton, 0, 0); QBoxLayout *yearlyMonthLayout = new QHBoxLayout(); yearlyDayOfMonthEdit = new QSpinBox(yearlyRuleWidget); yearlyDayOfMonthEdit->setRange(1, 31); yearlyMonthLayout->addWidget(yearlyDayOfMonthEdit); yearlyMonthLayout->addWidget(new QLabel(tr("of", "part between XXX and YYY of 'Recur on day XXX of month YYY'"), yearlyRuleWidget)); yearlyMonthCombo = new QComboBox(yearlyRuleWidget); yearlyMonthLayout->addWidget(yearlyMonthCombo); yearlyWeekendCombo_month = new QComboBox(yearlyRuleWidget); yearlyWeekendCombo_month->addItem(tr("possibly on weekend")); yearlyWeekendCombo_month->addItem(tr("but before weekend")); yearlyWeekendCombo_month->addItem(tr("but after weekend")); yearlyWeekendCombo_month->addItem(tr("nearest weekend day")); yearlyMonthLayout->addWidget(yearlyWeekendCombo_month); yearlyMonthLayout->addStretch(1); yearlyButtonLayout->addLayout(yearlyMonthLayout, 0, 1); yearlyOnDayOfWeekButton = new QRadioButton(tr("On the", "Part before NNN in 'Recur on the NNN. WEEKDAY of MONTH'"), yearlyRuleWidget); yearlyButtonGroup->addButton(yearlyOnDayOfWeekButton); yearlyButtonLayout->addWidget(yearlyOnDayOfWeekButton, 1, 0); QBoxLayout *yearlyWeekLayout = new QHBoxLayout(); yearlyWeekCombo = new QComboBox(yearlyRuleWidget); yearlyWeekCombo->addItem(tr("1st")); yearlyWeekCombo->addItem(tr("2nd")); yearlyWeekCombo->addItem(tr("3rd")); yearlyWeekCombo->addItem(tr("4th")); yearlyWeekCombo->addItem(tr("5th")); yearlyWeekCombo->addItem(tr("Last")); yearlyWeekCombo->addItem(tr("2nd Last")); yearlyWeekCombo->addItem(tr("3rd Last")); yearlyWeekCombo->addItem(tr("4th Last")); yearlyWeekCombo->addItem(tr("5th Last")); yearlyWeekLayout->addWidget(yearlyWeekCombo); yearlyDayOfWeekCombo = new QComboBox(yearlyRuleWidget); yearlyWeekLayout->addWidget(yearlyDayOfWeekCombo); yearlyWeekLayout->addWidget(new QLabel(tr("of", "part between WEEKDAY and MONTH in 'Recur on NNN. WEEKDAY of MONTH'"), yearlyRuleWidget)); yearlyMonthCombo_week = new QComboBox(yearlyRuleWidget); yearlyWeekLayout->addWidget(yearlyMonthCombo_week); yearlyWeekLayout->addStretch(1); yearlyButtonLayout->addLayout(yearlyWeekLayout, 1, 1); yearlyOnDayOfYearButton = new QRadioButton(tr("Recur on day #"), yearlyRuleWidget); yearlyButtonGroup->addButton(yearlyOnDayOfYearButton); yearlyButtonLayout->addWidget(yearlyOnDayOfYearButton, 2, 0); QBoxLayout *yearlyDayLayout = new QHBoxLayout(); yearlyDayOfYearEdit = new QSpinBox(yearlyRuleWidget); yearlyDayOfYearEdit->setRange(1, 366); yearlyDayLayout->addWidget(yearlyDayOfYearEdit); yearlyDayLayout->addWidget(new QLabel(tr(" of the year", "part after NNN of 'Recur on day #NNN of the year'"), yearlyRuleWidget)); yearlyWeekendCombo_day = new QComboBox(yearlyRuleWidget); yearlyWeekendCombo_day->addItem(tr("possibly on weekend")); yearlyWeekendCombo_day->addItem(tr("but before weekend")); yearlyWeekendCombo_day->addItem(tr("but after weekend")); yearlyWeekendCombo_day->addItem(tr("nearest weekend day")); yearlyDayLayout->addWidget(yearlyWeekendCombo_day); yearlyDayLayout->addStretch(1); yearlyButtonLayout->addLayout(yearlyDayLayout, 2, 1); yearlyRuleLayout->addStretch(1); recurrenceLayout->addWidget(ruleGroup); QHBoxLayout *buttonLayout = new QHBoxLayout(); recurrenceLayout->addLayout(buttonLayout); rangeButton = new QPushButton(tr("Range…"), this); buttonLayout->addWidget(rangeButton); exceptionsButton = new QPushButton(tr("Occurrences/Exceptions…"), this); buttonLayout->addWidget(exceptionsButton); recurrenceLayout->addStretch(1); ruleStack->setCurrentIndex(2); recurrenceButton->setChecked(false); ruleGroup->setEnabled(false); rangeButton->setEnabled(false); exceptionsButton->setEnabled(false); rangeDialog = new EditRangeDialog(date, this); rangeDialog->hide(); exceptionsDialog = new EditExceptionsDialog(this); exceptionsDialog->hide(); int months = 0; QDate date = QDate::currentDate(); for(int i = 0; i < 10; i++) { int months2 = 12; if(months2 > months) { for(int i2 = months + 1; i2 <= months2; i2++) { yearlyMonthCombo_week->addItem(QLocale().monthName(i2, QLocale::LongFormat)); yearlyMonthCombo->addItem(QLocale().monthName(i2, QLocale::LongFormat)); } months = months2; } date = date.addYears(1); } for(int i = 1; i <= 7; i++) { yearlyDayOfWeekCombo->addItem(QLocale().standaloneDayName(i)); monthlyDayOfWeekCombo->addItem(QLocale().standaloneDayName(i)); } connect(typeCombo, SIGNAL(activated(int)), ruleStack, SLOT(setCurrentIndex(int))); connect(rangeButton, SIGNAL(clicked()), this, SLOT(editRange())); connect(exceptionsButton, SIGNAL(clicked()), this, SLOT(editExceptions())); connect(recurrenceButton, SIGNAL(toggled(bool)), ruleGroup, SLOT(setEnabled(bool))); connect(recurrenceButton, SIGNAL(toggled(bool)), rangeButton, SLOT(setEnabled(bool))); connect(recurrenceButton, SIGNAL(toggled(bool)), exceptionsButton, SLOT(setEnabled(bool))); } RecurrenceEditWidget::~RecurrenceEditWidget() { } void RecurrenceEditWidget::editExceptions() { Recurrence *rec = createRecurrence(); exceptionsDialog->setRecurrence(rec); exceptionsDialog->exec(); exceptionsDialog->hide(); delete rec; } void RecurrenceEditWidget::editRange() { rangeDialog->exec(); rangeDialog->hide(); } void RecurrenceEditWidget::setRecurrence(Recurrence *rec) { rangeDialog->setRecurrence(rec); exceptionsDialog->setRecurrence(rec); if(!rec) { recurrenceButton->setChecked(false); recurrenceButton->setChecked(false); ruleGroup->setEnabled(false); rangeButton->setEnabled(false); exceptionsButton->setEnabled(false); return; } switch(rec->type()) { case RECURRENCE_TYPE_DAILY: { DailyRecurrence *drec = (DailyRecurrence*) rec; dailyFrequencyEdit->setValue(drec->frequency()); typeCombo->setCurrentIndex(0); break; } case RECURRENCE_TYPE_WEEKLY: { WeeklyRecurrence *wrec = (WeeklyRecurrence*) rec; weeklyFrequencyEdit->setValue(wrec->frequency()); for(int i = 0; i < 7; i++) { weeklyButtons[i]->setChecked(wrec->dayOfWeek(i + 1)); } typeCombo->setCurrentIndex(1); break; } case RECURRENCE_TYPE_MONTHLY: { MonthlyRecurrence *mrec = (MonthlyRecurrence*) rec; monthlyFrequencyEdit->setValue(mrec->frequency()); if(mrec->dayOfWeek() > 0) { monthlyOnDayOfWeekButton->setChecked(true); monthlyDayOfWeekCombo->setCurrentIndex(mrec->dayOfWeek() - 1); int week = mrec->week(); if(week <= 0) week = 6 - week; monthlyWeekCombo->setCurrentIndex(week - 1); } else { monthlyOnDayButton->setChecked(true); int day = mrec->day(); if(day <= 0) day = 32 - day; monthlyDayCombo->setCurrentIndex(day - 1); monthlyWeekendCombo->setCurrentIndex(mrec->weekendHandling()); } typeCombo->setCurrentIndex(2); break; } case RECURRENCE_TYPE_YEARLY: { YearlyRecurrence *yrec = (YearlyRecurrence*) rec; yearlyFrequencyEdit->setValue(yrec->frequency()); if(yrec->dayOfYear() > 0) { yearlyOnDayOfYearButton->setChecked(true); yearlyDayOfYearEdit->setValue(yrec->dayOfYear()); yearlyWeekendCombo_day->setCurrentIndex(yrec->weekendHandling()); yearlyWeekendCombo_month->setCurrentIndex(yrec->weekendHandling()); } else if(yrec->dayOfWeek() > 0) { yearlyOnDayOfWeekButton->setChecked(true); yearlyDayOfWeekCombo->setCurrentIndex(yrec->dayOfWeek() - 1); int week = yrec->week(); if(week <= 0) week = 6 - week; yearlyWeekCombo->setCurrentIndex(week - 1); yearlyMonthCombo_week->setCurrentIndex(yrec->month() - 1); } else { yearlyOnDayOfMonthButton->setChecked(true); yearlyDayOfMonthEdit->setValue(yrec->dayOfMonth()); yearlyMonthCombo->setCurrentIndex(yrec->month() - 1); yearlyWeekendCombo_day->setCurrentIndex(yrec->weekendHandling()); yearlyWeekendCombo_month->setCurrentIndex(yrec->weekendHandling()); } typeCombo->setCurrentIndex(3); break; } } ruleStack->setCurrentIndex(typeCombo->currentIndex()); recurrenceButton->setChecked(true); ruleGroup->setEnabled(true); rangeButton->setEnabled(true); exceptionsButton->setEnabled(true); } Recurrence *RecurrenceEditWidget::createRecurrence() { if(!recurrenceButton->isChecked() || !validValues()) return NULL; switch(typeCombo->currentIndex()) { case 0: { DailyRecurrence *rec = new DailyRecurrence(budget); rec->set(date, rangeDialog->endDate(), dailyFrequencyEdit->value(), rangeDialog->fixedCount()); exceptionsDialog->modifyExceptions(rec); return rec; } case 1: { WeeklyRecurrence *rec = new WeeklyRecurrence(budget); rec->set(date, rangeDialog->endDate(), weeklyButtons[0]->isChecked(), weeklyButtons[1]->isChecked(), weeklyButtons[2]->isChecked(), weeklyButtons[3]->isChecked(), weeklyButtons[4]->isChecked(), weeklyButtons[5]->isChecked(), weeklyButtons[6]->isChecked(), weeklyFrequencyEdit->value(), rangeDialog->fixedCount()); exceptionsDialog->modifyExceptions(rec); return rec; } case 2: { MonthlyRecurrence *rec = new MonthlyRecurrence(budget); if(monthlyOnDayButton->isChecked()) { int day = monthlyDayCombo->currentIndex() + 1; if(day > 31) day = 32 - day; rec->setOnDay(date, rangeDialog->endDate(), day, (WeekendHandling) monthlyWeekendCombo->currentIndex(), monthlyFrequencyEdit->value(), rangeDialog->fixedCount()); } else { int week = monthlyWeekCombo->currentIndex() + 1; if(week > 5) week = 6 - week; rec->setOnDayOfWeek(date, rangeDialog->endDate(), monthlyDayOfWeekCombo->currentIndex() + 1, week, monthlyFrequencyEdit->value(), rangeDialog->fixedCount()); } exceptionsDialog->modifyExceptions(rec); return rec; } case 3: { YearlyRecurrence *rec = new YearlyRecurrence(budget); if(yearlyOnDayOfMonthButton->isChecked()) { rec->setOnDayOfMonth(date, rangeDialog->endDate(), yearlyMonthCombo->currentIndex() + 1, yearlyDayOfMonthEdit->value(), (WeekendHandling) yearlyWeekendCombo_month->currentIndex(), yearlyFrequencyEdit->value(), rangeDialog->fixedCount()); } else if(yearlyOnDayOfWeekButton->isChecked()) { int week = yearlyWeekCombo->currentIndex() + 1; if(week > 5) week = 6 - week; rec->setOnDayOfWeek(date, rangeDialog->endDate(), yearlyMonthCombo_week->currentIndex() + 1, yearlyDayOfWeekCombo->currentIndex() + 1, week, yearlyFrequencyEdit->value(), rangeDialog->fixedCount()); } else { rec->setOnDayOfYear(date, rangeDialog->endDate(), yearlyDayOfYearEdit->value(), (WeekendHandling) yearlyWeekendCombo_day->currentIndex(), yearlyFrequencyEdit->value(), rangeDialog->fixedCount()); } exceptionsDialog->modifyExceptions(rec); return rec; } } return NULL; } bool RecurrenceEditWidget::validValues() { if(!recurrenceButton->isChecked()) return true; switch(typeCombo->currentIndex()) { case 0: { break; } case 1: { bool b = false; for(int i = 0; i < 7; i++) { if(weeklyButtons[i]->isChecked()) { b = true; break; } } if(!b) { QMessageBox::critical(this, tr("Error"), tr("No day of week selected for weekly recurrence.")); weeklyButtons[0]->setFocus(); return false; } break; } case 2: { int i_frequency = monthlyFrequencyEdit->value(); if(i_frequency % 12 == 0) { int i_dayofmonth = monthlyDayCombo->currentIndex() + 1; int i_month = date.month(); if(i_dayofmonth <= 31 && ((i_month == 2 && i_dayofmonth > 29) || (i_dayofmonth > 30 && (i_month == 4 || i_month == 6 || i_month == 9 || i_month == 11)))) { QMessageBox::critical(this, tr("Error"), tr("Selected day will never occur with selected frequency and start date.")); monthlyDayCombo->setFocus(); return false; } } break; } case 3: { if(yearlyOnDayOfMonthButton->isChecked()) { int i_frequency = yearlyFrequencyEdit->value(); int i_dayofmonth = yearlyDayOfMonthEdit->value(); int i_month = yearlyMonthCombo->currentIndex() + 1; if(IS_GREGORIAN_CALENDAR) { if((i_month == 2 && i_dayofmonth > 29) || (i_dayofmonth > 30 && (i_month == 4 || i_month == 6 || i_month == 9 || i_month == 11))) { QMessageBox::critical(this, tr("Error"), tr("Selected day does not exist in selected month.")); yearlyDayOfMonthEdit->setFocus(); return false; } else if(i_month != 2 || i_dayofmonth < 29) { break; } } QDate nextdate; nextdate.setDate(date.year(), i_month, 1); if(i_dayofmonth > nextdate.daysInMonth()) { int i = 10; do { if(i == 0) { QMessageBox::critical(this, tr("Error"), tr("Selected day will never occur with selected frequency and start date.")); yearlyDayOfMonthEdit->setFocus(); return false; } nextdate = nextdate.addYears(i_frequency); nextdate.setDate(nextdate.year(), i_month, 1); i--; } while(i_dayofmonth > nextdate.daysInMonth()); } } else if(yearlyOnDayOfYearButton->isChecked()) { int i_frequency = yearlyFrequencyEdit->value(); int i_dayofyear = yearlyDayOfYearEdit->value(); if(i_dayofyear > date.daysInYear()) { QDate nextdate = date; int i = 10; do { if(i == 0) { QMessageBox::critical(this, tr("Error"), tr("Selected day will never occur with selected frequency and start date.")); yearlyDayOfYearEdit->setFocus(); return false; } nextdate = nextdate.addYears(i_frequency); i--; } while(i_dayofyear > nextdate.daysInYear()); } } break; } } if(!rangeDialog->validValues()) return false; if(!exceptionsDialog->validValues()) return false; return true; } void RecurrenceEditWidget::setStartDate(const QDate &startdate) { if(!startdate.isValid()) return; date = startdate; rangeDialog->setStartDate(date); } Eqonomize-1.5.3/src/recurrenceeditwidget.h000066400000000000000000000105461416454732000206510ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifndef RECURRENCE_EDIT_WIDGET_H #define RECURRENCE_EDIT_WIDGET_H #include #include #include #include class QButtonGroup; class QCheckBox; class QComboBox; class QGroupBox; class QLabel; class QListWidget; class QPushButton; class QRadioButton; class QSpinBox; class QStackedWidget; class QDateEdit; class Budget; class EditRangeDialog; class EditExceptionsDialog; class Recurrence; class RecurrenceEditWidget : public QWidget { Q_OBJECT public: RecurrenceEditWidget(const QDate &startdate, Budget *budg, QWidget *parent = 0); ~RecurrenceEditWidget(); void setRecurrence(Recurrence *rec); Recurrence *createRecurrence(); bool validValues(); protected: QDate date; Budget *budget; QGroupBox *ruleGroup; QStackedWidget *ruleStack; QCheckBox *recurrenceButton; QComboBox *typeCombo; QPushButton *exceptionsButton, *rangeButton; QSpinBox *dailyFrequencyEdit; QCheckBox *weeklyButtons[7]; QSpinBox *weeklyFrequencyEdit; QRadioButton *monthlyOnDayButton, *monthlyOnDayOfWeekButton; QComboBox *monthlyDayCombo, *monthlyWeekendCombo, *monthlyWeekCombo, *monthlyDayOfWeekCombo; QSpinBox *monthlyFrequencyEdit; QSpinBox *yearlyFrequencyEdit, *yearlyDayOfYearEdit, *yearlyDayOfMonthEdit; QRadioButton *yearlyOnDayOfYearButton, *yearlyOnDayOfWeekButton, *yearlyOnDayOfMonthButton; QComboBox *yearlyMonthCombo_week, *yearlyWeekendCombo_month, *yearlyWeekendCombo_day, *yearlyDayOfWeekCombo, *yearlyWeekCombo, *yearlyMonthCombo; EditRangeDialog *rangeDialog; EditExceptionsDialog *exceptionsDialog; public slots: void editExceptions(); void editRange(); void setStartDate(const QDate&); }; class EditRangeDialog : public QDialog { Q_OBJECT protected: QDateEdit *endDateEdit; QSpinBox *fixedCountEdit; QRadioButton *foreverButton, *endDateButton, *fixedCountButton; QLabel *startLabel; QDate date; QButtonGroup *rangeButtonGroup; QRadioButton *checkedButton; QDate endDateEdit_value; int fixedCountEdit_value; public: EditRangeDialog(const QDate &startdate, QWidget *parent); ~EditRangeDialog(); void setStartDate(const QDate &startdate); void setRecurrence(Recurrence *rec); int fixedCount(); QDate endDate(); bool validValues(); void saveValues(); void restoreValues(); protected slots: void accept(); void reject(); }; class EditExceptionsDialog : public QDialog { Q_OBJECT protected: QPushButton *addButton, *deleteButton; QListWidget *occurrencesList, *exceptionsList; QLabel *infoLabel; QStringList savedExceptions; Recurrence *o_rec; public: EditExceptionsDialog(QWidget *parent); ~EditExceptionsDialog(); void setRecurrence(Recurrence *rec); void modifyExceptions(Recurrence *rec); bool validValues(); void saveValues(); void restoreValues(); protected slots: void accept(); void reject(); void onSelectionChanged(); void addException(); void deleteException(); }; #endif Eqonomize-1.5.3/src/security.cpp000066400000000000000000000703731416454732000166500ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include "budget.h" #include "recurrence.h" #include "security.h" #include void Security::init() { transactions.setAutoDelete(false); dividends.setAutoDelete(false); scheduledTransactions.setAutoDelete(false); scheduledDividends.setAutoDelete(false); tradedShares.setAutoDelete(false); reinvestedDividends.setAutoDelete(false); scheduledReinvestedDividends.setAutoDelete(false); } Security::Security(Budget *parent_budget, AssetsAccount *parent_account, SecurityType initial_type, double initial_shares, int initial_decimals, int initial_quotation_decimals, QString initial_name, QString initial_description) : o_budget(parent_budget), i_id(parent_budget->getNewId()), i_first_revision(parent_budget->revision()), i_last_revision(parent_budget->revision()), o_account(parent_account), st_type(initial_type), d_initial_shares(initial_shares), i_decimals(initial_decimals), i_quotation_decimals(initial_quotation_decimals), s_name(initial_name.trimmed()), s_description(initial_description) { init(); } Security::Security(Budget *parent_budget, QXmlStreamReader *xml, bool *valid) : o_budget(parent_budget) { init(); QXmlStreamAttributes attr = xml->attributes(); readAttributes(&attr, valid); readElements(xml, valid); } Security::Security(Budget *parent_budget) : o_budget(parent_budget), i_id(parent_budget->getNewId()), i_first_revision(parent_budget->revision()), i_last_revision(parent_budget->revision()) {} Security::Security() : o_budget(NULL), i_id(0), i_first_revision(1), i_last_revision(1), o_account(NULL), st_type(SECURITY_TYPE_STOCK), d_initial_shares(0.0), i_decimals(-1), i_quotation_decimals(-1) {init();} Security::Security(const Security *security) : o_budget(security->budget()), i_id(security->id()), i_first_revision(security->firstRevision()), i_last_revision(security->lastRevision()), o_account(security->account()), st_type(security->type()), d_initial_shares(security->initialShares()), i_decimals(security->decimals()), i_quotation_decimals(security->quotationDecimals()), s_name(security->name()), s_description(security->description()) {init();} Security::~Security() {} void Security::set(const Security *security) { i_id = security->id(); i_first_revision = security->firstRevision(); i_last_revision = security->lastRevision(); s_name = security->name(); s_description = security->description(); st_type = security->type(); d_initial_shares = security->initialShares(); i_decimals = security->decimals(); quotations = security->quotations; quotations_auto = security->quotations_auto; } void Security::setMergeQuotes(const Security *security) { i_id = security->id(); i_first_revision = security->firstRevision(); i_last_revision = security->lastRevision(); s_name = security->name(); s_description = security->description(); st_type = security->type(); d_initial_shares = security->initialShares(); i_decimals = security->decimals(); mergeQuotes(security, false); } void Security::mergeQuotes(const Security *security, bool keep) { for(QMap::const_iterator it = security->quotations.begin(); it != security->quotations.end(); ++it) { if(!keep || !quotations.contains(it.key())) quotations[it.key()] = it.value(); } for(QMap::const_iterator it = security->quotations_auto.begin(); it != security->quotations_auto.end(); ++it) { if(!keep || !quotations_auto.contains(it.key())) quotations_auto[it.key()] = it.value(); } } void Security::readAttributes(QXmlStreamAttributes *attr, bool *valid) { read_id(attr, i_id, i_first_revision, i_last_revision); #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) QStringView type = attr->value("type"); #else QStringRef type = attr->value("type"); #endif if(type == XML_COMPARE_CONST_CHAR("bond")) { st_type = SECURITY_TYPE_BOND; } else if(type == XML_COMPARE_CONST_CHAR("stock")) { st_type = SECURITY_TYPE_STOCK; } else if(type == XML_COMPARE_CONST_CHAR("mutual fund")) { st_type = SECURITY_TYPE_MUTUAL_FUND; } else { st_type = SECURITY_TYPE_OTHER; } d_initial_shares = attr->value("initialshares").toDouble(); if(attr->hasAttribute("decimals")) i_decimals = attr->value("decimals").toInt(); else i_decimals = -1; if(attr->hasAttribute("quotationdecimals")) i_quotation_decimals = attr->value("quotationdecimals").toInt(); else i_quotation_decimals = -1; s_name = attr->value("name").trimmed().toString(); s_description = attr->value("description").toString(); qlonglong id_account = attr->value("account").toLongLong(); if(budget()->assetsAccounts_id.contains(id_account)) { o_account = budget()->assetsAccounts_id[id_account]; if(valid && (*valid)) *valid = (o_account->accountType() == ASSETS_TYPE_SECURITIES); } else { o_account = NULL; if(valid) *valid = false; } } bool Security::readElement(QXmlStreamReader *xml, bool*) { if(xml->name() == XML_COMPARE_CONST_CHAR("quotation")) { QXmlStreamAttributes attr = xml->attributes(); QDate date = QDate::fromString(attr.value("date").toString(), Qt::ISODate); quotations[date] = attr.value("value").toDouble(); quotations_auto[date] = attr.value("auto").toInt(); } return false; } bool Security::readElements(QXmlStreamReader *xml, bool *valid) { while(xml->readNextStartElement()) { if(!readElement(xml, valid)) xml->skipCurrentElement(); } return true; } void Security::save(QXmlStreamWriter *xml) { QXmlStreamAttributes attr; writeAttributes(&attr); xml->writeAttributes(attr); writeElements(xml); } void Security::writeAttributes(QXmlStreamAttributes *attr) { write_id(attr, i_id, i_first_revision, i_last_revision); attr->append("name", s_name); switch(st_type) { case SECURITY_TYPE_BOND: {attr->append("type", "bond"); break;} case SECURITY_TYPE_STOCK: {attr->append("type", "stock"); break;} case SECURITY_TYPE_MUTUAL_FUND: {attr->append("type", "mutual fund"); break;} case SECURITY_TYPE_OTHER: {attr->append("type", "other"); break;} } if(i_decimals >= 0) attr->append("decimals", QString::number(i_decimals)); if(i_quotation_decimals >= 0) attr->append("quotationdecimals", QString::number(i_quotation_decimals)); attr->append("initialshares", QString::number(d_initial_shares, 'f', i_decimals)); if(!s_description.isEmpty()) attr->append("description", s_description); attr->append("account", QString::number(o_account->id())); } void Security::writeElements(QXmlStreamWriter *xml) { QMap::const_iterator it_end = quotations.end(); QMap::const_iterator it = quotations.begin(); QMap::const_iterator it_auto = quotations_auto.begin(); for(; it != it_end; ++it, ++it_auto) { xml->writeStartElement("quotation"); xml->writeAttribute("value", QString::number(it.value(), 'f', quotationDecimals() > SAVE_MONETARY_DECIMAL_PLACES ? quotationDecimals() : SAVE_MONETARY_DECIMAL_PLACES)); xml->writeAttribute("date", it.key().toString(Qt::ISODate)); if(it_auto.value()) xml->writeAttribute("auto", QString::number(it_auto.value())); xml->writeEndElement(); } } const QString &Security::name() const {return s_name;} void Security::setName(QString new_name) {s_name = new_name.trimmed(); o_budget->securityNameModified(this);} const QString &Security::description() const {return s_description;} void Security::setDescription(QString new_description) {s_description = new_description;} Budget *Security::budget() const {return o_budget;} double Security::initialBalance() const { QMap::const_iterator it = quotations.begin(); if(it == quotations.end()) return 0.0; return it.value() * d_initial_shares; } double Security::initialShares() const {return d_initial_shares;} void Security::setInitialShares(double initial_shares) {d_initial_shares = initial_shares;} SecurityType Security::type() const {return st_type;} void Security::setType(SecurityType new_type) {st_type = new_type;} AssetsAccount *Security::account() const {return o_account;} Currency *Security::currency() const { if(o_account) return o_account->currency(); return budget()->defaultCurrency(); } void Security::setAccount(AssetsAccount *new_account) {o_account = new_account;} qlonglong Security::id() const {return i_id;} void Security::setId(qlonglong new_id) {i_id = new_id;} int Security::firstRevision() const {return i_first_revision;} void Security::setFirstRevision(int new_rev) {i_first_revision = new_rev; if(i_first_revision > i_last_revision) i_last_revision = i_first_revision;} int Security::lastRevision() const {return i_last_revision;} void Security::setLastRevision(int new_rev) {i_last_revision = new_rev;} void Security::setQuotation(const QDate &date, double value, bool auto_added) { if(!auto_added) { quotations[date] = value; quotations_auto[date] = false; } else if(!quotations.count(date) || quotations_auto[date]) { quotations[date] = value; quotations_auto[date] = true; } } void Security::removeQuotation(const QDate &date, bool auto_added) { if(quotations.count(date) && (!auto_added || quotations_auto[date])) { quotations.remove(date); quotations_auto.remove(date); } } void Security::clearQuotations() { quotations.clear(); quotations_auto.clear(); } double Security::getQuotation(const QDate &date, QDate *actual_date) const { if(quotations.contains(date)) { if(actual_date) *actual_date = date; return quotations[date]; } QMap::const_iterator it_begin = quotations.begin(); QMap::const_iterator it = quotations.end(); if(it != it_begin) { --it; while(true) { if(it.key() <= date || it == it_begin) { if(actual_date) *actual_date = it.key(); return it.value(); } --it; } } if(actual_date) *actual_date = QDate(); return 0.0; } bool Security::hasQuotation(const QDate &date) const { return quotations.contains(date); } int Security::decimals() const { if(i_decimals < 0) return o_budget->defaultShareDecimals(); return i_decimals; } int Security::quotationDecimals() const { if(i_quotation_decimals < 0) return o_budget->defaultQuotationDecimals(); return i_quotation_decimals; } void Security::setDecimals(int new_decimals) {i_decimals = new_decimals;} void Security::setQuotationDecimals(int new_decimals) {i_quotation_decimals = new_decimals;} double Security::shares() { double n = d_initial_shares; for(SecurityTransactionList::const_iterator it = transactions.constBegin(); it != transactions.constEnd(); ++it) { SecurityTransaction *trans = *it; if(trans->type() == TRANSACTION_TYPE_SECURITY_BUY) n += trans->shares(); else n -= trans->shares(); } for(TradedSharesList::const_iterator it = tradedShares.constBegin(); it != tradedShares.constEnd(); ++it) { SecurityTrade *ts = *it; if(ts->from_security == this) n -= ts->from_shares; else n += ts->to_shares; } for(SecurityTransactionList::const_iterator it = reinvestedDividends.constBegin(); it != reinvestedDividends.constEnd(); ++it) { ReinvestedDividend *rediv = *it; n += rediv->shares(); } return n; } double Security::shares(const QDate &date, bool estimate, bool no_scheduled_shares) { double n = d_initial_shares; for(SecurityTransactionList::const_iterator it = transactions.constBegin(); it != transactions.constEnd(); ++it) { SecurityTransaction *trans = *it; if(trans->date() > date) break; if(trans->type() == TRANSACTION_TYPE_SECURITY_BUY) n += trans->shares(); else n -= trans->shares(); } for(TradedSharesList::const_iterator it = tradedShares.constBegin(); it != tradedShares.constEnd(); ++it) { SecurityTrade *ts = *it; if(ts->date > date) break; if(ts->from_security == this) n -= ts->from_shares; else n += ts->to_shares; } if(!no_scheduled_shares) { for(ScheduledSecurityTransactionList::const_iterator it = scheduledTransactions.constBegin(); it != scheduledTransactions.constEnd(); ++it) { ScheduledTransaction *strans = *it; if(strans->date() > date) break; int no = strans->recurrence() ? strans->recurrence()->countOccurrences(date) : 1; if(no > 0) { if(strans->transactiontype() == TRANSACTION_TYPE_SECURITY_BUY) n += ((SecurityTransaction*) strans->transaction())->shares() * no; else n -= ((SecurityTransaction*) strans->transaction())->shares() * no; } } } for(SecurityTransactionList::const_iterator it = reinvestedDividends.constBegin(); it != reinvestedDividends.constEnd(); ++it) { ReinvestedDividend *rediv = *it; if(rediv->date() > date) break; n += rediv->shares(); } bool b; if(!no_scheduled_shares) { for(ScheduledSecurityTransactionList::const_iterator it = scheduledReinvestedDividends.constBegin(); it != scheduledReinvestedDividends.constEnd(); ++it) { ScheduledTransaction *strans = *it; if(strans->date() > date) break; int no = strans->recurrence() ? strans->recurrence()->countOccurrences(date) : 1; if(no > 0) { n += ((ReinvestedDividend*) strans->transaction())->shares() * no; b = true; } } } if(!b && estimate && date > QDate::currentDate() && reinvestedDividends.count() > 0) { QDate date1 = QDate::currentDate(); int days = date1.daysTo(date); int days2 = 0; if(quotations.begin() != quotations.end()) days2 = quotations.begin().key().daysTo(date1); if(days2 > days) { days2 = days; } int years = days2 / date1.daysInYear(); if(years == 0) years = 1; QDate date2 = date1.addYears(-years); double n2 = 0.0; for(SecurityTransactionList::const_iterator it = reinvestedDividends.constBegin(); it != reinvestedDividends.constEnd(); ++it) { ReinvestedDividend *rediv = *it; if(rediv->date() > date2) { n2 += rediv->shares(); } } if(n2 > 0.0) { n += (n2 * days) / date2.daysTo(date1); } } return n; } double Security::value() { return shares() * getQuotation(QDate::currentDate()); } double Security::value(const QDate &date, int estimate, bool no_scheduled_shares) { if(estimate > 0 && date > QDate::currentDate()) return shares(date, true, no_scheduled_shares) * expectedQuotation(date); else if(estimate < 0 && quotations.count() >= 2 && quotations.firstKey() < date && quotations.lastKey() > date) return shares(date, false, no_scheduled_shares) * expectedQuotation(date); return shares(date, false, no_scheduled_shares) * getQuotation(date); } double Security::cost(const QDate &date, bool no_scheduled_shares, Currency *cur) { if(!cur) cur = currency(); double c = d_initial_shares; QMap::const_iterator it_q = quotations.begin(); if(it_q == quotations.end()) { c = 0.0; } else { c *= it_q.value(); if(cur != currency()) { if(budget()->defaultTransactionConversionRateDate() == TRANSACTION_CONVERSION_RATE_AT_DATE) { c = currency()->convertTo(c, cur, it_q.key()); } else { c = currency()->convertTo(c, cur, date); } } } for(SecurityTransactionList::const_iterator it = transactions.constBegin(); it != transactions.constEnd(); ++it) { SecurityTransaction *trans = *it; if(trans->date() > date) break; double v = trans->value(); if(cur != trans->currency()) { if(budget()->defaultTransactionConversionRateDate() == TRANSACTION_CONVERSION_RATE_AT_DATE) { v = trans->currency()->convertTo(v, cur, trans->date()); } else { v = trans->currency()->convertTo(v, cur, date); } } if(trans->type() == TRANSACTION_TYPE_SECURITY_BUY) c += v; else c -= v; } for(TradedSharesList::const_iterator it = tradedShares.constBegin(); it != tradedShares.constEnd(); ++it) { SecurityTrade *ts = *it; if(ts->date > date) break; double v = ts->from_shares * ts->from_security->getQuotation(ts->date); if(cur != ts->from_security->currency()) { if(budget()->defaultTransactionConversionRateDate() == TRANSACTION_CONVERSION_RATE_AT_DATE) { v = ts->from_security->currency()->convertTo(v, cur, ts->date); } else { v = ts->from_security->currency()->convertTo(v, cur, date); } } if(ts->from_security == this) c -= v; else c += v; } if(!no_scheduled_shares) { for(ScheduledSecurityTransactionList::const_iterator it = scheduledTransactions.constBegin(); it != scheduledTransactions.constEnd(); ++it) { ScheduledTransaction *strans = *it; if(strans->date() > date) break; int n = strans->recurrence() ? strans->recurrence()->countOccurrences(date) : 1; if(n > 0) { double v = strans->value(); if(cur != strans->currency()) { v = strans->currency()->convertTo(v, cur); } if(strans->transactiontype() == TRANSACTION_TYPE_SECURITY_BUY) c += v * n; else c -= v * n; } } } return c; } double Security::cost(Currency *cur) { if(!cur) cur = currency(); double c = d_initial_shares; QMap::const_iterator it_q = quotations.begin(); if(it_q == quotations.end()) { c = 0.0; } else { c *= it_q.value(); if(cur != currency()) { if(budget()->defaultTransactionConversionRateDate() == TRANSACTION_CONVERSION_RATE_AT_DATE) { c = currency()->convertTo(c, cur, it_q.key()); } else { c = currency()->convertTo(c, cur); } } } for(SecurityTransactionList::const_iterator it = transactions.constBegin(); it != transactions.constEnd(); ++it) { SecurityTransaction *trans = *it; double v = trans->value(); if(cur != trans->currency()) { if(budget()->defaultTransactionConversionRateDate() == TRANSACTION_CONVERSION_RATE_AT_DATE) { v = trans->currency()->convertTo(v, cur, trans->date()); } else { v = trans->currency()->convertTo(v, cur); } } if(trans->type() == TRANSACTION_TYPE_SECURITY_BUY) c += v; else c -= v; } for(TradedSharesList::const_iterator it = tradedShares.constBegin(); it != tradedShares.constEnd(); ++it) { SecurityTrade *ts = *it; double v = ts->from_shares * ts->from_security->getQuotation(ts->date); if(cur != ts->from_security->currency()) { if(budget()->defaultTransactionConversionRateDate() == TRANSACTION_CONVERSION_RATE_AT_DATE) { v = ts->from_security->currency()->convertTo(v, cur, ts->date); } else { v = ts->from_security->currency()->convertTo(v, cur); } } if(ts->from_security == this) c -= v; else c += v; } return c; } double Security::profit(Currency *cur) { if(!cur) cur = currency(); double p = value(); if(cur != currency()) { p = currency()->convertTo(p, cur); } p -= cost(cur); for(SecurityTransactionList::const_iterator it = dividends.constBegin(); it != dividends.constEnd(); ++it) { Income *trans = *it; if(cur != trans->currency()) { if(budget()->defaultTransactionConversionRateDate() == TRANSACTION_CONVERSION_RATE_AT_DATE) { p += trans->currency()->convertTo(trans->income(), cur, trans->date()); } else { p += trans->currency()->convertTo(trans->income(), cur); } } else { p += trans->income(); } } return p; } double Security::profit(const QDate &date, bool estimate, bool no_scheduled_shares, Currency *cur) { if(!cur) cur = currency(); double p = value(date, estimate, no_scheduled_shares); if(cur != currency()) { p = currency()->convertTo(p, cur, date); } p -= cost(date, no_scheduled_shares, cur); for(SecurityTransactionList::const_iterator it = dividends.constBegin(); it != dividends.constEnd(); ++it) { Income *trans = *it; if(trans->date() > date) break; if(cur != trans->currency()) { if(budget()->defaultTransactionConversionRateDate() == TRANSACTION_CONVERSION_RATE_AT_DATE) { p += trans->currency()->convertTo(trans->income(), cur, trans->date()); } else { p += trans->currency()->convertTo(trans->income(), cur, date); } } else { p += trans->income(); } } if(estimate && date > QDate::currentDate() && dividends.count() > 0) { QDate date1 = QDate::currentDate(); int days = date1.daysTo(date); int days2 = 0; if(quotations.begin() != quotations.end()) days2 = quotations.begin().key().daysTo(date1); if(days2 > days) { days2 = days; } int years = days2 / date1.daysInYear(); if(years == 0) years = 1; QDate date2 = date1.addYears(-years); double p2 = 0.0; for(SecurityTransactionList::const_iterator it = dividends.constBegin(); it != dividends.constEnd(); ++it) { Income *trans = *it; if(trans->date() > date2) { if(cur != trans->currency()) { p2 += trans->currency()->convertTo(trans->income(), cur); } else { p2 += trans->income(); } } } if(p2 > 0.0) { p += (p2 * days) / date2.daysTo(date1); } } else if(!no_scheduled_shares) { for(ScheduledSecurityTransactionList::const_iterator it = scheduledDividends.constBegin(); it != scheduledDividends.constEnd(); ++it) { ScheduledTransaction *strans = *it; if(strans->date() > date) break; int n = strans->recurrence() ? strans->recurrence()->countOccurrences(date) : 1; if(n > 0) { if(cur != strans->currency()) { p += strans->currency()->convertTo(strans->value() * n, cur); } else { p += strans->value() * n; } } } } return p; } double Security::profit(const QDate &date1, const QDate &date2, bool estimate, bool no_scheduled_shares, Currency *cur) { return profit(date2, estimate, no_scheduled_shares) - profit(date1, estimate, no_scheduled_shares, cur); } double Security::yearlyRate() { QMap::const_iterator it_begin = quotations.begin(); QMap::const_iterator it_end = quotations.end(); if(it_end == it_begin) return 0.0; it_end--; QDate date1 = it_begin.key(), date2 = QDate::currentDate(); double q1 = it_begin.value(), q2 = it_end.value(); int days = date1.daysTo(date2); if(it_end.key() != date2 && q1 != q2) { int days2 = it_end.key().daysTo(date2); q2 *= pow(q2 / q1, days2 / (days - days2)); } for(SecurityTransactionList::const_iterator it = dividends.constBegin(); it != dividends.constEnd(); ++it) { Income *trans = *it; double s = shares(trans->date()); if(s > 0.0) q2 += trans->income() / s; } double shares_change = 0.0; for(SecurityTransactionList::const_iterator it = reinvestedDividends.constBegin(); it != reinvestedDividends.constEnd(); ++it) { ReinvestedDividend *rediv = *it; double s = shares(rediv->date()); if(s > 0.0) shares_change += rediv->shares() / (s - rediv->shares()); } if(date1 == date2) return 0.0; double change = q2 / q1 + shares_change; return pow(change, 1 / o_budget->yearsBetweenDates(date1, date2, false)) - 1; } double Security::yearlyRate(const QDate &date) { QMap::const_iterator it_begin = quotations.begin(); if(it_begin == quotations.end()) return 0.0; QDate date1 = it_begin.key(); QDate date2 = date; if(date1 >= date2) return 0.0; QDate curdate = QDate::currentDate(); if(date2 > curdate) { double rate1 = yearlyRate(); double rate2 = yearlyRate(curdate, date2); int days1 = date1.daysTo(curdate); int days2 = curdate.daysTo(date2); return ((rate1 * days1) + (rate2 * days2)) / (days1 + days2); } QDate date2_q; double q1 = it_begin.value(), q2 = getQuotation(date2, &date2_q); int days = date1.daysTo(date2); if(date2 != date2_q && q1 != q2) { int days2 = date2_q.daysTo(date2); q2 *= pow(q2 / q1, days2 / (days - days2)); } for(SecurityTransactionList::const_iterator it = dividends.constBegin(); it != dividends.constEnd(); ++it) { Income *trans = *it; if(trans->date() > date2) break; double s = shares(trans->date()); if(s > 0.0) q2 += trans->income() / s; } double shares_change = 0.0; for(SecurityTransactionList::const_iterator it = reinvestedDividends.constBegin(); it != reinvestedDividends.constEnd(); ++it) { ReinvestedDividend *rediv = *it; if(rediv->date() > date2) break; double s = shares(rediv->date()); if(s > 0.0) shares_change += rediv->shares() / (s - rediv->shares()); } double change = q2 / q1 + shares_change; return pow(change, 1 / o_budget->yearsBetweenDates(date1, date2, false)) - 1; } double Security::yearlyRate(const QDate &date1, const QDate &date2) { if(date1 > date2) return yearlyRate(date2, date1); if(date1 == date2) return 0.0; QMap::const_iterator it_begin = quotations.begin(); if(it_begin == quotations.end()) return 0.0; QDate curdate = QDate::currentDate(); if(date1 >= curdate) { double dp = profit(date1, date2, true, true), dv = value(date1, true, true); if(is_zero(dp)) dp = 0.0; if(is_zero(dv)) return 0.0; return pow(1 + (dp / dv), 1 / (o_budget->yearsBetweenDates(date1, date2, false))) - 1; } if(date2 > curdate) { double rate1 = yearlyRate(date1, curdate); double rate2 = yearlyRate(curdate, date2); int days1 = date1.daysTo(curdate); int days2 = curdate.daysTo(date2); return ((rate1 * days1) + (rate2 * days2)) / (days1 + days2); } if(date2 < it_begin.key()) { return 0.0; } if(date1 < it_begin.key()) { return yearlyRate(it_begin.key(), date2); } QDate date1_q, date2_q; double q1 = getQuotation(date1, &date1_q); double q2 = getQuotation(date2, &date2_q); int days = date1.daysTo(date2); if(q1 != q2) { double q1_bak = q1; if(date1 != date1_q) { double rate = q1 / q2; int days1 = date1_q.daysTo(date1); q1 *= pow(rate, days1 / (days - days1)); } if(date2 != date2_q) { double rate = q2 / q1_bak; int days2 = date2_q.daysTo(date2); q2 *= pow(rate, days2 / (days - days2)); } } for(SecurityTransactionList::const_iterator it = dividends.constBegin(); it != dividends.constEnd(); ++it) { Income *trans = *it; if(trans->date() > date2) break; if(trans->date() >= date1) { double s = shares(trans->date()); if(s > 0.0) q2 += trans->income() / s; } } double shares_change = 0.0; for(SecurityTransactionList::const_iterator it = reinvestedDividends.constBegin(); it != reinvestedDividends.constEnd(); ++it) { ReinvestedDividend *rediv = *it; if(rediv->date() > date2) break; if(rediv->date() >= date1) { double s = shares(rediv->date()); if(s > 0.0) shares_change += rediv->shares() / (s - rediv->shares()); } } double change = q2 / q1 + shares_change; return pow(change, 1 / o_budget->yearsBetweenDates(date1, date2, false)) - 1; } double Security::expectedQuotation(const QDate &date) { if(quotations.contains(date)) { return quotations[date]; } QMap::const_iterator it_begin = quotations.begin(); QMap::const_iterator it = quotations.end(); if(it == it_begin) return 0.0; --it; if(it == it_begin) return it_begin.value(); if(date < it_begin.key()) { int days = date.daysTo(it_begin.key()); double q2 = expectedQuotation(it_begin.key().addDays(days)); return it_begin.value() * (it_begin.value() / q2); } if(it.key() < date) { int days = it.key().daysTo(date); double q1 = expectedQuotation(it.key().addDays(-days)); return it.value() * (it.value() / q1); } --it; while(true) { if(it.key() < date) { it_begin = it; ++it; double days = it_begin.key().daysTo(date), days2 = it_begin.key().daysTo(it.key()); if(it.value() == it_begin.value()) return it.value(); double rate = it.value() / it_begin.value(); return it_begin.value() * pow(rate, days / days2); } if(it == it_begin) break; --it; } return 0.0; } Eqonomize-1.5.3/src/security.h000066400000000000000000000163041416454732000163070ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifndef SECURITY_H #define SECURITY_H #include #include #include #include #include "transaction.h" #include "eqonomizelist.h" class AssetsAccount; class QXmlStreamReader; class QXmlStreamWriter; class QXmlStreamAttributes; class Security; class Budget; class Currency; typedef enum { SECURITY_TYPE_BOND, SECURITY_TYPE_STOCK, SECURITY_TYPE_MUTUAL_FUND, SECURITY_TYPE_OTHER } SecurityType; static bool security_transaction_list_less_than(Transaction *t1, Transaction *t2) { return t1->date() < t2->date(); } template class SecurityTransactionList : public EqonomizeList { public: SecurityTransactionList() : EqonomizeList() {}; void sort() { std::sort(QList::begin(), QList::end(), security_transaction_list_less_than); } void inSort(type value) { QList::insert(std::lower_bound(QList::begin(), QList::end(), value, security_transaction_list_less_than), value); } }; static bool scheduled_security_list_less_than(ScheduledTransaction *t1, ScheduledTransaction *t2) { return t1->date() < t2->date(); } template class ScheduledSecurityTransactionList : public EqonomizeList { public: ScheduledSecurityTransactionList() : EqonomizeList() {}; void sort() { std::sort(QList::begin(), QList::end(), scheduled_security_list_less_than); } void inSort(type value) { QList::insert(std::lower_bound(QList::begin(), QList::end(), value, scheduled_security_list_less_than), value); } }; static bool traded_shares_list_less_than(SecurityTrade *t1, SecurityTrade *t2) { return t1->date < t2->date; } template class TradedSharesList : public EqonomizeList { public: TradedSharesList() : EqonomizeList() {}; void sort() { std::sort(QList::begin(), QList::end(), traded_shares_list_less_than); } void inSort(type value) { QList::insert(std::lower_bound(QList::begin(), QList::end(), value, traded_shares_list_less_than), value); } }; class Security { protected: Budget *o_budget; qlonglong i_id; int i_first_revision, i_last_revision; AssetsAccount *o_account; SecurityType st_type; double d_initial_shares; int i_decimals, i_quotation_decimals; QString s_name; QString s_description; void init(); public: Security(Budget *parent_budget, AssetsAccount *parent_account, SecurityType initial_type, double initial_shares = 0.0, int initial_decimals = -1, int initial_quotation_decimals = -1, QString initial_name = QString(), QString initial_description = QString()); Security(Budget *parent_budget, QXmlStreamReader *xml, bool *valid); Security(Budget *parent_budget); Security(); Security(const Security *security); virtual ~Security(); void set(const Security *security); void setMergeQuotes(const Security *security); void mergeQuotes(const Security *security, bool keep = true); virtual void readAttributes(QXmlStreamAttributes *attr, bool *valid); virtual bool readElement(QXmlStreamReader *xml, bool *valid); virtual bool readElements(QXmlStreamReader *xml, bool *valid); virtual void save(QXmlStreamWriter *xml); virtual void writeAttributes(QXmlStreamAttributes *attr); virtual void writeElements(QXmlStreamWriter *xml); const QString &name() const; void setName(QString new_name); const QString &description() const; void setDescription(QString new_description); Budget *budget() const; double initialBalance() const; double initialShares() const; void setInitialShares(double initial_shares); virtual SecurityType type() const; void setType(SecurityType new_type); qlonglong id() const; void setId(qlonglong new_id); int firstRevision() const; void setFirstRevision(int new_rev); int lastRevision() const; void setLastRevision(int new_rev); bool hasQuotation(const QDate &date) const; void setQuotation(const QDate &date, double value, bool auto_added = false); void removeQuotation(const QDate &date, bool auto_added = false); void clearQuotations(); double getQuotation(const QDate &date, QDate *actual_date = NULL) const; AssetsAccount *account() const; Currency *currency() const; int decimals() const; int quotationDecimals() const; void setDecimals(int new_decimals); void setQuotationDecimals(int new_decimals); void setAccount(AssetsAccount *new_account); double shares(); double shares(const QDate &date, bool estimate = false, bool no_scheduled_shares = false); double value(); // estime > 0: estimate future value; estimate < 0: estimate value between quotations double value(const QDate &date, int estimate = 0, bool no_scheduled_shares = false); double cost(Currency *cur = NULL); double cost(const QDate &date, bool no_scheduled_shares = false, Currency *cur = NULL); double profit(Currency *cur = NULL); double profit(const QDate &date, bool estimate = false, bool no_scheduled_shares = false, Currency *cur = NULL); double profit(const QDate &date1, const QDate &date2, bool estimate = false, bool no_scheduled_shares = false, Currency *cur = NULL); double yearlyRate(); double yearlyRate(const QDate &date); double yearlyRate(const QDate &date_from, const QDate &date_to); double expectedQuotation(const QDate &date); QMap quotations; QMap quotations_auto; TradedSharesList tradedShares; SecurityTransactionList transactions; SecurityTransactionList dividends; SecurityTransactionList reinvestedDividends; ScheduledSecurityTransactionList scheduledTransactions; ScheduledSecurityTransactionList scheduledDividends; ScheduledSecurityTransactionList scheduledReinvestedDividends; }; #endif Eqonomize-1.5.3/src/transaction.cpp000066400000000000000000003744771416454732000173420ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016-2020 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include "account.h" #include "budget.h" #include "recurrence.h" #include "security.h" #include "transaction.h" static const QString emptystr; static const QDate emptydate; static qint64 zero_timestamp; Transactions::Transactions(Budget *parent_budget) : i_id(0), i_first_revision(parent_budget->revision()), i_last_revision(parent_budget->revision()), o_budget(parent_budget) {} Transactions::Transactions() : i_id(0), i_first_revision(1), i_last_revision(1), o_budget(NULL) {} Transactions::Transactions(const Transactions *trans) : i_id(trans->id()), i_first_revision(trans->firstRevision()), i_last_revision(trans->lastRevision()), o_budget(trans->budget()) { for(int i = 0; !trans->getTag(i).isEmpty(); i++) { tags << trans->getTag(i); } for(int i = 0; i < trans->linksCount(false); i++) { links << trans->getLinkId(i, false); } } void Transactions::set(const Transactions *trans) { i_id = trans->id(); i_first_revision = trans->firstRevision(); i_last_revision = trans->lastRevision(); tags.clear(); for(int i = 0; !trans->getTag(i).isEmpty(); i++) { tags << trans->getTag(i); } links.clear(); for(int i = 0; i < trans->linksCount(false); i++) { links << trans->getLinkId(i, false); } } QString Transactions::valueString(int precision) const { return valueString(value(), precision); } QString Transactions::valueString(double value_, int precision) const { Currency *cur = currency(); if(!cur) cur = budget()->defaultCurrency(); return cur->formatValue(value_, precision); } void Transactions::setTimestamp() { setTimestamp(QDateTime::currentMSecsSinceEpoch() / 1000); } Budget *Transactions::budget() const {return o_budget;} qlonglong Transactions::id() const {return i_id;} void Transactions::setId(qlonglong new_id) { i_id = new_id; } int Transactions::firstRevision() const {return i_first_revision;} void Transactions::setFirstRevision(int new_rev) {i_first_revision = new_rev; if(i_first_revision > i_last_revision) i_last_revision = i_first_revision;} int Transactions::lastRevision() const {return i_last_revision;} void Transactions::setLastRevision(int new_rev) {i_last_revision = new_rev;} bool Transactions::isModified() const {return i_last_revision == o_budget->revision();} void Transactions::setModified() {i_last_revision = o_budget->revision();} void Transactions::addTag(QString tag) { if(!tag.isEmpty() && !tags.contains(tag)) { tags << tag; tags.sort(Qt::CaseInsensitive); } } bool Transactions::removeTag(QString tag) { return tags.removeAll(tag) > 0; } void Transactions::removeTag(int index) { if(index >= 0 && index < tags.count()) tags.removeAt(index); } int Transactions::tagsCount(bool) const {return tags.count();} bool Transactions::hasTag(const QString &tag, bool, bool case_insensitive) const {return tags.contains(tag, case_insensitive ? Qt::CaseInsensitive : Qt::CaseSensitive);} const QString &Transactions::getTag(int index, bool) const { if(index >= 0 && index < tags.count()) return tags[index]; return emptystr; } QString Transactions::tagsText(bool) const { if(tags.isEmpty()) return QString(); if(tags.count() == 1) { if(tags[0].contains(",")) return QString("\"") + tags[0] + "\""; else return tags[0]; } QString tagstr; for(int i = 0; i < tags.count(); i++) { if(i > 0) tagstr += ", "; if(tags[i].contains(",")) { tagstr += "\""; tagstr += tags[i]; tagstr += "\""; } else { tagstr += tags[i]; } } return tagstr; } void Transactions::clearTags() { tags.clear(); } void Transactions::readTags(const QString &text) { tags.clear(); #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) QStringView tagstr(text); #else QStringRef tagstr(&text); #endif tagstr = tagstr.trimmed(); if(tagstr.isEmpty()) return; while(true) { int i = 0; if(tagstr.at(0) == '\"' || tagstr.at(0) == '\'') { i = tagstr.indexOf(tagstr.at(0), 1); if(i < 0) { tags << tagstr.toString(); break; } i++; } i = tagstr.indexOf(',', i); if(i < 0) { if(tagstr.length() >= 2 && ((tagstr.at(0) == '\"' && tagstr.at(tagstr.size() - 1) == '\"') || (tagstr.at(0) == '\'' && tagstr.at(tagstr.size() - 1) == '\''))) tagstr = tagstr.mid(1, tagstr.length() - 2).trimmed(); tags << tagstr.toString(); break; } #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) QStringView tagi = tagstr.left(i).trimmed(); #else QStringRef tagi = tagstr.left(i).trimmed(); #endif if(tagi.length() >= 2 && ((tagi.at(0) == '\"' && tagi.at(tagstr.size() - 1) == '\"') || (tagi.at(0) == '\'' && tagi.at(tagstr.size() - 1) == '\''))) tagi = tagi.mid(1, tagi.length() - 2).trimmed(); if(!tagi.isEmpty()) tags << tagi.toString(); tagstr = tagstr.right(tagstr.length() - i - 1).trimmed(); if(tagstr.isEmpty()) break; } tags.sort(Qt::CaseInsensitive); } QString Transactions::writeTags(bool) const { if(tags.count() == 1) { if(tags[0][0] == '"') { return QString("\'") + tags[0] + "\'"; } else if(tags[0][0] == '\'') { return QString("\"") + tags[0] + "\""; } else if(tags[0].contains(",")) { if(tags[0].contains("\"")) return QString("\'") + tags[0] + "\'"; else return QString("\"") + tags[0] + "\""; } else { return tags[0]; } } else if(!tags.isEmpty()) { QString tagstr; for(int i = 0; i < tags.count(); i++) { if(i > 0) tagstr += ","; if(tags[i][0] == '"') { tagstr += "\'"; tagstr += tags[i]; tagstr += "\'"; } else if(tags[i][0] == '\'') { tagstr += "\""; tagstr += tags[i]; tagstr += "\""; } else if(tags[i].contains(",")) { if(tags[i].contains("\"")) {tagstr += "\'"; tagstr += tags[i]; tagstr += "\'";} else {tagstr += "\""; tagstr += tags[i]; tagstr += "\"";} } else { tagstr += tags[i]; } } return tagstr; } return QString(); } int Transactions::linksCount(bool) const { return links.count(); } qlonglong Transactions::getLinkId(int index, bool) const { if(index >= 0 && index < links.count()) return links[index]; return -1; } Transactions *Transactions::getLink(int index, bool include_parent) const { qlonglong lid = getLinkId(index, include_parent); if(lid >= 0) { return o_budget->getTransaction(lid); } return NULL; } void Transactions::clearLinks() { links.clear(); } void Transactions::addLink(Transactions *trans) { if(trans) addLinkId(trans->id()); } void Transactions::addLinkId(qlonglong lid) { if(!links.contains(lid)) { links << lid; } } void Transactions::removeLink(int index) { if(index >= 0 && index < links.count()) links.removeAt(index); } bool Transactions::removeLink(Transactions *trans) { return removeLinkId(trans->id()); } bool Transactions::removeLinkId(qlonglong lid) { return links.removeAll(lid) > 0; } bool Transactions::hasLinkId(qlonglong lid, bool) const {return links.contains(lid);} bool Transactions::hasLink(Transactions *trans, bool include_parent) const {return hasLinkId(trans->id(), include_parent);} void Transactions::readLinks(const QString &text) { links.clear(); if(text.isEmpty()) return; if(!text.contains(',')) { bool ok; qlonglong lid = text.toLongLong(&ok); if(ok) links << lid; } else { #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) QStringList strs = text.split(",", Qt::SkipEmptyParts); #else QStringList strs = text.split(",", QString::SkipEmptyParts); #endif for(int i = 0; i < strs.count(); i++) { bool ok; qlonglong lid = strs[i].toLongLong(&ok); if(ok) links << lid; } } } QString Transactions::writeLinks(bool) const { QString str; for(int i = 0; i < links.count(); i++) { if(i > 0) str += ","; str += QString::number(links[i]); } return str; } Transaction::Transaction(Budget *parent_budget, double initial_value, QDate initial_date, Account *from, Account *to, QString initial_description, QString initial_comment, qlonglong initial_id) : Transactions(parent_budget), d_value(initial_value), d_date(initial_date), o_from(from), o_to(to), s_description(initial_description.trimmed()), s_comment(initial_comment.trimmed()), d_quantity(1.0), o_split(NULL), i_time(QDateTime::currentMSecsSinceEpoch() / 1000) { if(initial_id < 0) i_id = o_budget->getNewId(); else i_id = initial_id; } Transaction::Transaction(Budget *parent_budget, QXmlStreamReader *xml, bool *valid) : Transactions(parent_budget) { QXmlStreamAttributes attr = xml->attributes(); readAttributes(&attr, valid); readElements(xml, valid); } Transaction::Transaction(Budget *parent_budget) : Transactions(parent_budget), d_value(0.0), o_from(NULL), o_to(NULL), d_quantity(1.0), o_split(NULL), i_time(QDateTime::currentMSecsSinceEpoch() / 1000) {} Transaction::Transaction() : Transactions(), d_value(0.0), o_from(NULL), o_to(NULL), d_quantity(1.0), o_split(NULL), i_time(QDateTime::currentMSecsSinceEpoch() / 1000) {} Transaction::Transaction(const Transaction *transaction) : Transactions(transaction), d_value(transaction->value()), d_date(transaction->date()), o_from(transaction->fromAccount()), o_to(transaction->toAccount()), s_description(transaction->description()), s_comment(transaction->comment()), s_file(transaction->associatedFile()), d_quantity(transaction->quantity()), o_split(NULL), i_time(transaction->timestamp()) {} Transaction::~Transaction() {} void Transaction::set(const Transactions *trans) { Transactions::set(trans); if(trans->generaltype() == generaltype()) { d_value = ((Transaction*) trans)->value(); d_date = ((Transaction*) trans)->date(); o_from = ((Transaction*) trans)->fromAccount(); o_to = ((Transaction*) trans)->toAccount(); s_description = ((Transaction*) trans)->description(); s_comment = ((Transaction*) trans)->comment(); s_file = ((Transaction*) trans)->associatedFile(); d_quantity = ((Transaction*) trans)->quantity(); i_time = ((Transaction*) trans)->timestamp(); } } void Transaction::readAttributes(QXmlStreamAttributes *attr, bool *valid) { o_split = NULL; o_from = NULL; o_to = NULL; d_date = QDate::fromString(attr->value("date").toString(), Qt::ISODate); i_time = attr->value("timestamp").toLongLong(); s_description = attr->value("description").trimmed().toString(); s_comment = attr->value("comment").trimmed().toString(); s_file = attr->value("file").trimmed().toString(); if(attr->hasAttribute("tags")) readTags(attr->value("tags").toString()); if(attr->hasAttribute("links")) readLinks(attr->value("links").toString()); read_id(attr, i_id, i_first_revision, i_last_revision); if(attr->hasAttribute("quantity")) d_quantity = attr->value("quantity").toDouble(); else d_quantity = 1.0; if(valid && (*valid)) *valid = d_date.isValid(); } bool Transaction::readElement(QXmlStreamReader*, bool*) {return false;} bool Transaction::readElements(QXmlStreamReader *xml, bool *valid) { while(xml->readNextStartElement()) { if(!readElement(xml, valid)) xml->skipCurrentElement(); } return true; } void Transaction::save(QXmlStreamWriter *xml) { QXmlStreamAttributes attr; writeAttributes(&attr); xml->writeAttributes(attr); writeElements(xml); } void Transaction::writeAttributes(QXmlStreamAttributes *attr) { attr->append("date", d_date.toString(Qt::ISODate)); write_id(attr, i_id, i_first_revision, i_last_revision); if(i_time != 0) attr->append("timestamp", QString::number(i_time)); if(!s_description.isEmpty()) attr->append("description", s_description); if(!tags.isEmpty()) attr->append("tags", writeTags(false)); if(!links.isEmpty()) attr->append("links", writeLinks(false)); if(!s_comment.isEmpty()) attr->append("comment", s_comment); if(!s_file.isEmpty()) attr->append("file", s_file); if(d_quantity != 1.0) attr->append("quantity", QString::number(d_quantity, 'f', QUANTITY_DECIMAL_PLACES)); } void Transaction::writeElements(QXmlStreamWriter*) {} bool Transaction::equals(const Transactions *trans, bool strict_comparison) const { if(trans->generaltype() != GENERAL_TRANSACTION_TYPE_SINGLE) return false; Transaction *transaction = (Transaction*) trans; if(type() != transaction->type()) return false; if(fromAccount() != transaction->fromAccount()) return false; if(toAccount() != transaction->toAccount()) return false; if(value() != transaction->value()) return false; if(date() != transaction->date()) return false; if(description() != transaction->description()) return false; if(strict_comparison && quantity() != transaction->quantity()) return false; if(comment() != transaction->comment() && (strict_comparison || comment().isEmpty() == transaction->comment().isEmpty())) return false; if(associatedFile() != transaction->associatedFile() && (strict_comparison || associatedFile().isEmpty() == transaction->associatedFile().isEmpty())) return false; if(strict_comparison || (transaction->tagsCount() > 0 && tags.count() > 0)) { if(transaction->tagsCount() != tags.count()) return false; for(int i = 0; i < tags.count(); i++) { if(!transaction->hasTag(tags[i], false)) return false; } } if(strict_comparison || (transaction->linksCount() > 0 && links.count() > 0)) { if(transaction->linksCount() != links.count()) return false; for(int i = 0; i < links.count(); i++) { if(!transaction->hasLinkId(links[i], false)) return false; } } if(budget() != transaction->budget()) return false; return true; } bool Transaction::hasTag(const QString &tag, bool include_parent, bool case_insensitive) const { if(Transactions::hasTag(tag, false, case_insensitive)) return true; return include_parent && o_split && o_split->hasTag(tag, false, case_insensitive); } QString Transaction::tagsText(bool include_parent) const { if(!include_parent || !o_split) return Transactions::tagsText(); QString tagstr = Transactions::tagsText(); QString tagstr2 = o_split->tagsText(false); if(!tagstr2.isEmpty()) { if(!tagstr.isEmpty()) tagstr += ", "; tagstr += tagstr2; } return tagstr; } int Transaction::tagsCount(bool include_parent) const { if(!include_parent || !o_split) return tags.count(); return tags.count() + o_split->tagsCount(); } const QString &Transaction::getTag(int index, bool include_parent) const { if(index >= 0 && index < tags.count()) return tags[index]; if(include_parent && o_split) { index -= tags.count(); return o_split->getTag(index); } return emptystr; } QString Transaction::writeTags(bool include_parent) const { if(!include_parent || !o_split || o_split->tagsCount(false) == 0) return Transactions::writeTags(false); QString str = Transactions::writeTags(false); if(!str.isEmpty()) str += ","; str += o_split->writeTags(false); return str; } int Transaction::linksCount(bool include_parent) const { if(!include_parent || !o_split) return links.count(); return links.count() + o_split->linksCount(); } qlonglong Transaction::getLinkId(int index, bool include_parent) const { if(index >= 0 && index < links.count()) return links[index]; if(include_parent && o_split) { index -= links.count(); return o_split->getLinkId(index); } return -1; } QString Transaction::writeLinks(bool include_parent) const { if(!include_parent || !o_split || o_split->linksCount(false) == 0) return Transactions::writeLinks(false); QString str = Transactions::writeLinks(false); if(!str.isEmpty()) str += ","; str += o_split->writeLinks(false); return str; } bool Transaction::hasLinkId(qlonglong lid, bool include_parent) const { if(Transactions::hasLinkId(lid, false)) return true; return include_parent && o_split && o_split->hasLinkId(lid, false); } SplitTransaction *Transaction::parentSplit() const {return o_split;} void Transaction::setParentSplit(SplitTransaction *parent) { if(o_split == parent) return; o_split = parent; if(o_split) i_time = o_split->timestamp(); //o_budget->transactionSortModified(this); } double Transaction::value(bool convert) const { if(convert && currency() && currency() != budget()->defaultCurrency()) { if(budget()->defaultTransactionConversionRateDate() == TRANSACTION_CONVERSION_RATE_AT_DATE) return currency()->convertTo(d_value, budget()->defaultCurrency(), d_date); else return currency()->convertTo(d_value, budget()->defaultCurrency()); } return d_value; } double Transaction::fromValue(bool convert) const {return value(convert);} double Transaction::toValue(bool convert) const {return value(convert);} Currency *Transaction::currency() const { if(fromAccount()->type() == ACCOUNT_TYPE_ASSETS && ((AssetsAccount*) fromAccount())->currency()) return ((AssetsAccount*) fromAccount())->currency(); if(toAccount()->type() == ACCOUNT_TYPE_ASSETS) return ((AssetsAccount*) toAccount())->currency(); return NULL; } Currency *Transaction::fromCurrency() const { if(fromAccount()->type() == ACCOUNT_TYPE_ASSETS && ((AssetsAccount*) fromAccount())->currency()) return ((AssetsAccount*) fromAccount())->currency(); if(toAccount()->type() == ACCOUNT_TYPE_ASSETS) return ((AssetsAccount*) toAccount())->currency(); return NULL; } Currency *Transaction::toCurrency() const { if(toAccount()->type() == ACCOUNT_TYPE_ASSETS && ((AssetsAccount*) toAccount())->currency()) return ((AssetsAccount*) toAccount())->currency(); if(fromAccount()->type() == ACCOUNT_TYPE_ASSETS) return ((AssetsAccount*) fromAccount())->currency(); return NULL; } void Transaction::setValue(double new_value) {d_value = new_value;} double Transaction::quantity() const {return d_quantity;} void Transaction::setQuantity(double new_quantity) {d_quantity = new_quantity;} const QDate &Transaction::date() const {return d_date;} void Transaction::setDate(QDate new_date) { if(new_date == d_date) return; QDate old_date = d_date; d_date = new_date; o_budget->transactionSortModified(this); o_budget->transactionDateModified(this, old_date); } const qint64 &Transaction::timestamp() const {return i_time;} void Transaction::setTimestamp(qint64 cr_time) { if(i_time == cr_time) return; i_time = cr_time; o_budget->transactionSortModified(this); } QString Transaction::description() const {return s_description;} void Transaction::setDescription(QString new_description) { if(new_description == s_description) return; s_description = new_description.trimmed(); o_budget->transactionSortModified(this); } const QString &Transaction::comment() const {return s_comment;} void Transaction::setComment(QString new_comment) {s_comment = new_comment.trimmed();} const QString &Transaction::associatedFile() const {return s_file;} void Transaction::setAssociatedFile(QString new_attachment) {s_file = new_attachment.trimmed();} Account *Transaction::fromAccount() const {return o_from;} void Transaction::setFromAccount(Account *new_from) {o_from = new_from;} Account *Transaction::toAccount() const {return o_to;} void Transaction::setToAccount(Account *new_to) {o_to = new_to;} GeneralTransactionType Transaction::generaltype() const {return GENERAL_TRANSACTION_TYPE_SINGLE;} TransactionSubType Transaction::subtype() const {return (TransactionSubType) type();} bool Transaction::relatesToAccount(Account *account, bool include_subs, bool) const {return o_from == account || o_to == account || (include_subs && (o_from->topAccount() == account || o_to->topAccount() == account));} void Transaction::replaceAccount(Account *old_account, Account *new_account) { if(o_from == old_account) o_from = new_account; if(o_to == old_account) o_to = new_account; } double Transaction::accountChange(Account *account, bool include_subs, bool convert) const { if(o_from == account || (include_subs && o_from->topAccount() == account)) return -fromValue(convert); if(o_to == account || (include_subs && o_to->topAccount() == account)) return toValue(convert); return 0.0; } QString Transaction::payeeText() const {return payee();} const QString &Transaction::payee() const {return emptystr;} Expense::Expense(Budget *parent_budget, double initial_cost, QDate initial_date, ExpensesAccount *initial_category, AssetsAccount *initial_from, QString initial_description, QString initial_comment, qlonglong initial_id) : Transaction(parent_budget, initial_cost, initial_date, initial_from, initial_category, initial_description, initial_comment, initial_id), b_reconciled(false) {} Expense::Expense(Budget *parent_budget, QXmlStreamReader *xml, bool *valid) : Transaction(parent_budget) { QXmlStreamAttributes attr = xml->attributes(); readAttributes(&attr, valid); readElements(xml, valid); } Expense::Expense(Budget *parent_budget) : Transaction(parent_budget), b_reconciled(false) {} Expense::Expense() : Transaction() {} Expense::Expense(const Expense *expense) : Transaction(expense), s_payee(expense->payee()), b_reconciled(expense->isReconciled(expense->from())) {} Expense::~Expense() {} Transaction *Expense::copy() const {return new Expense(this);} void Expense::set(const Transactions *trans) { Transaction::set(trans); if(trans->generaltype() == generaltype() && ((Transaction*) trans)->type() == type()) { s_payee = ((Expense*) trans)->payee(); b_reconciled = ((Expense*) trans)->isReconciled(from()); } } void Expense::readAttributes(QXmlStreamAttributes *attr, bool *valid) { Transaction::readAttributes(attr, valid); qlonglong id_category, id_from; bool b_neg = false; if(attr->hasAttribute("category")) { id_category = attr->value("category").toLongLong(); id_from = attr->value("from").toLongLong(); } else { id_category = attr->value("to").toLongLong(); if(budget()->expensesAccounts_id.contains(id_category)) { id_from = attr->value("from").toLongLong(); } else { id_from = id_category; id_category = attr->value("from").toLongLong(); b_neg = true; } } if(budget()->expensesAccounts_id.contains(id_category) && budget()->assetsAccounts_id.contains(id_from)) { setCategory(budget()->expensesAccounts_id[id_category]); setFrom(budget()->assetsAccounts_id[id_from]); if(attr->hasAttribute("income")) setCost(b_neg ? attr->value("income").toDouble() : -attr->value("income").toDouble()); else if(attr->hasAttribute("value")) setCost(b_neg ? -attr->value("value").toDouble() : attr->value("value").toDouble()); else setCost(b_neg ? -attr->value("cost").toDouble() : attr->value("cost").toDouble()); s_payee = attr->value("payee").trimmed().toString(); b_reconciled = attr->value("reconciled").toInt(); } else { if(valid) *valid = false; } } void Expense::writeAttributes(QXmlStreamAttributes *attr) { Transaction::writeAttributes(attr); if(cost() < 0.0) attr->append("income", QString::number(-cost(), 'f', SAVE_MONETARY_DECIMAL_PLACES)); else attr->append("cost", QString::number(cost(), 'f', SAVE_MONETARY_DECIMAL_PLACES)); attr->append("category", QString::number(category()->id())); attr->append("from", QString::number(from()->id())); if(!s_payee.isEmpty()) attr->append("payee", s_payee); if(b_reconciled) attr->append("reconciled", QString::number(b_reconciled)); } bool Expense::equals(const Transactions *transaction, bool strict_comparison) const { if(!Transaction::equals(transaction, strict_comparison)) return false; Expense *expense = (Expense*) transaction; if(s_payee != expense->payee() && (strict_comparison || s_payee.isEmpty() == expense->payee().isEmpty())) return false; return true; } ExpensesAccount *Expense::category() const {return (ExpensesAccount*) toAccount();} void Expense::setCategory(ExpensesAccount *new_category) {setToAccount(new_category);} AssetsAccount *Expense::from() const {return (AssetsAccount*) fromAccount();} void Expense::setFrom(AssetsAccount *new_from) {setFromAccount(new_from);} double Expense::cost(bool convert) const {return value(convert);} void Expense::setCost(double new_cost) {setValue(new_cost);} const QString &Expense::payee() const {return s_payee;} void Expense::setPayee(QString new_payee) {s_payee = new_payee.trimmed();} QString Expense::description() const {return Transaction::description();} TransactionType Expense::type() const {return TRANSACTION_TYPE_EXPENSE;} TransactionSubType Expense::subtype() const {return TRANSACTION_SUBTYPE_EXPENSE;} bool Expense::relatesToAccount(Account *account, bool include_subs, bool include_non_value) const {return Transaction::relatesToAccount(account, include_subs, include_non_value);} void Expense::replaceAccount(Account *old_account, Account *new_account) {Transaction::replaceAccount(old_account, new_account);} bool Expense::isReconciled(AssetsAccount *account) const { if(account == from()) return b_reconciled; return false; } void Expense::setReconciled(AssetsAccount *account, bool is_reconciled) { if(account == from()) b_reconciled = is_reconciled; } DebtFee::DebtFee(Budget *parent_budget, double initial_cost, QDate initial_date, ExpensesAccount *initial_category, AssetsAccount *initial_from, AssetsAccount *initial_loan, QString initial_comment, qlonglong initial_id) : Expense(parent_budget, initial_cost, initial_date, initial_category, initial_from, QString(), initial_comment, initial_id), o_loan(initial_loan) { } DebtFee::DebtFee(Budget *parent_budget, QXmlStreamReader *xml, bool *valid) : Expense(parent_budget) { QXmlStreamAttributes attr = xml->attributes(); readAttributes(&attr, valid); readElements(xml, valid); } DebtFee::DebtFee(Budget *parent_budget) : Expense(parent_budget), o_loan(NULL) {} DebtFee::DebtFee() : Expense(), o_loan(NULL) {} DebtFee::DebtFee(const DebtFee *loanfee) : Expense(loanfee) { o_loan = loanfee->loan(); } bool DebtFee::relatesToAccount(Account *account, bool include_subs, bool include_non_value) const {return (include_non_value && o_loan == account) || Expense::relatesToAccount(account, include_subs, include_non_value);} DebtFee::~DebtFee() {} Transaction *DebtFee::copy() const {return new DebtFee(this);} void DebtFee::set(const Transactions *trans) { Expense::set(trans); if(trans->generaltype() == generaltype() && ((Transaction*) trans)->type() == type() && ((Transaction*) trans)->subtype() == subtype()) { o_loan = ((DebtFee*) trans)->loan(); } } void DebtFee::readAttributes(QXmlStreamAttributes *attr, bool *valid) { Expense::readAttributes(attr, valid); qlonglong id_loan = attr->value("debt").toLongLong(); if(budget()->assetsAccounts_id.contains(id_loan)) { o_loan = budget()->assetsAccounts_id[id_loan]; } else { if(valid) *valid = false; } } void DebtFee::writeAttributes(QXmlStreamAttributes *attr) { Expense::writeAttributes(attr); attr->append("debt", QString::number(o_loan->id())); } AssetsAccount *DebtFee::loan() const {return o_loan;} void DebtFee::setLoan(AssetsAccount *new_loan) {o_loan = new_loan;} const QString &DebtFee::payee() const { if(o_loan) return o_loan->maintainer(); return s_payee; } QString DebtFee::description() const {return tr("Debt payment: %1 (fee)").arg(o_loan->name());} TransactionSubType DebtFee::subtype() const {return TRANSACTION_SUBTYPE_DEBT_FEE;} void DebtFee::replaceAccount(Account *old_account, Account *new_account) { if(o_loan == old_account && new_account->type() == ACCOUNT_TYPE_ASSETS) o_loan = (AssetsAccount*) new_account; Transaction::replaceAccount(old_account, new_account); } DebtInterest::DebtInterest(Budget *parent_budget, double initial_cost, QDate initial_date, ExpensesAccount *initial_category, AssetsAccount *initial_from, AssetsAccount *initial_loan, QString initial_comment, qlonglong initial_id) : Expense(parent_budget, initial_cost, initial_date, initial_category, initial_from, QString(), initial_comment, initial_id), o_loan(initial_loan) { } DebtInterest::DebtInterest(Budget *parent_budget, QXmlStreamReader *xml, bool *valid) : Expense(parent_budget) { QXmlStreamAttributes attr = xml->attributes(); readAttributes(&attr, valid); readElements(xml, valid); } DebtInterest::DebtInterest(Budget *parent_budget) : Expense(parent_budget), o_loan(NULL) {} DebtInterest::DebtInterest() : Expense(), o_loan(NULL) {} DebtInterest::DebtInterest(const DebtInterest *loaninterest) : Expense(loaninterest) { o_loan = loaninterest->loan(); } DebtInterest::~DebtInterest() {} Transaction *DebtInterest::copy() const {return new DebtInterest(this);} void DebtInterest::set(const Transactions *trans) { Expense::set(trans); if(trans->generaltype() == generaltype() && ((Transaction*) trans)->type() == type() && ((Transaction*) trans)->subtype() == subtype()) { o_loan = ((DebtInterest*) trans)->loan(); } } void DebtInterest::readAttributes(QXmlStreamAttributes *attr, bool *valid) { Expense::readAttributes(attr, valid); qlonglong id_loan = attr->value("debt").toLongLong(); if(budget()->assetsAccounts_id.contains(id_loan)) { o_loan = budget()->assetsAccounts_id[id_loan]; } else { if(valid) *valid = false; } } void DebtInterest::writeAttributes(QXmlStreamAttributes *attr) { Expense::writeAttributes(attr); attr->append("debt", QString::number(o_loan->id())); } AssetsAccount *DebtInterest::loan() const {return o_loan;} void DebtInterest::setLoan(AssetsAccount *new_loan) {o_loan = new_loan;} const QString &DebtInterest::payee() const { if(o_loan) return o_loan->maintainer(); return s_payee; } QString DebtInterest::description() const {return tr("Debt payment: %1 (interest)").arg(o_loan->name());} TransactionSubType DebtInterest::subtype() const {return TRANSACTION_SUBTYPE_DEBT_INTEREST;} bool DebtInterest::relatesToAccount(Account *account, bool include_subs, bool include_non_value) const {return (include_non_value && o_loan == account) || Expense::relatesToAccount(account, include_subs, include_non_value);} void DebtInterest::replaceAccount(Account *old_account, Account *new_account) { if(o_loan == old_account && new_account->type() == ACCOUNT_TYPE_ASSETS) o_loan = (AssetsAccount*) new_account; Transaction::replaceAccount(old_account, new_account); } Income::Income(Budget *parent_budget, double initial_income, QDate initial_date, IncomesAccount *initial_category, AssetsAccount *initial_to, QString initial_description, QString initial_comment, qlonglong initial_id) : Transaction(parent_budget, initial_income, initial_date, initial_category, initial_to, initial_description, initial_comment, initial_id), o_security(NULL), b_reconciled(false) {} Income::Income(Budget *parent_budget, QXmlStreamReader *xml, bool *valid) : Transaction(parent_budget) { QXmlStreamAttributes attr = xml->attributes(); readAttributes(&attr, valid); readElements(xml, valid); } Income::Income(Budget *parent_budget) : Transaction(parent_budget), o_security(NULL), b_reconciled(false) {} Income::Income() : Transaction(), o_security(NULL), b_reconciled(false) {} Income::Income(const Income *income_) : Transaction(income_), o_security(income_->security()), s_payer(income_->payer()), b_reconciled(income_->isReconciled(income_->to())) {} Income::~Income() {} Transaction *Income::copy() const {return new Income(this);} void Income::set(const Transactions *trans) { Transaction::set(trans); if(trans->generaltype() == generaltype() && ((Transaction*) trans)->type() == type()) { s_payer = ((Income*) trans)->payer(); b_reconciled = ((Income*) trans)->isReconciled(to()); o_security = ((Income*) trans)->security(); } } void Income::readAttributes(QXmlStreamAttributes *attr, bool *valid) { Transaction::readAttributes(attr, valid); qlonglong id_category, id_to; bool b_neg = false; if(attr->hasAttribute("category")) { id_category = attr->value("category").toLongLong(); id_to = attr->value("to").toLongLong(); } else { id_category = attr->value("from").toLongLong(); if(budget()->incomesAccounts_id.contains(id_category)) { id_to = attr->value("to").toLongLong(); } else { id_to = id_category; id_category = attr->value("to").toLongLong(); b_neg = true; } } if(budget()->incomesAccounts_id.contains(id_category) && budget()->assetsAccounts_id.contains(id_to)) { setCategory(budget()->incomesAccounts_id[id_category]); setTo(budget()->assetsAccounts_id[id_to]); if(attr->hasAttribute("cost")) setIncome(b_neg ? attr->value("cost").toDouble() : -attr->value("cost").toDouble()); else if(attr->hasAttribute("value")) setIncome(b_neg ? -attr->value("value").toDouble() : attr->value("value").toDouble()); else setIncome(b_neg ? -attr->value("income").toDouble() : attr->value("income").toDouble()); b_reconciled = attr->value("reconciled").toInt(); } else { if(valid) *valid = false; } qlonglong id = -1; if(attr->hasAttribute("security")) id = attr->value("security").toLongLong(); if(id >= 0 && budget()->securities_id.contains(id)) { o_security = budget()->securities_id[id]; } else { o_security = NULL; } if(!o_security) { s_payer = attr->value("payer").trimmed().toString(); } } void Income::writeAttributes(QXmlStreamAttributes *attr) { Transaction::writeAttributes(attr); if(income() < 0.0 && !o_security) attr->append("cost", QString::number(-income(), 'f', SAVE_MONETARY_DECIMAL_PLACES)); else attr->append("income", QString::number(income(), 'f', SAVE_MONETARY_DECIMAL_PLACES)); attr->append("category", QString::number(category()->id())); attr->append("to", QString::number(to()->id())); if(o_security) attr->append("security", QString::number(o_security->id())); else if(!s_payer.isEmpty()) attr->append("payer", s_payer); if(b_reconciled) attr->append("reconciled", QString::number(b_reconciled)); } bool Income::equals(const Transactions *transaction, bool strict_comparison) const { if(!Transaction::equals(transaction, strict_comparison)) return false; Income *income = (Income*) transaction; if(s_payer != income->payer() && (strict_comparison || s_payer.isEmpty() == income->payer().isEmpty())) return false; if(o_security != income->security()) return false; return true; } IncomesAccount *Income::category() const {return (IncomesAccount*) fromAccount();} void Income::setCategory(IncomesAccount *new_category) {setFromAccount(new_category);} AssetsAccount *Income::to() const {return (AssetsAccount*) toAccount();} void Income::setTo(AssetsAccount *new_to) {setToAccount(new_to);} double Income::income(bool convert) const {return value(convert);} void Income::setIncome(double new_income) {setValue(new_income);} const QString &Income::payer() const { if(o_security) return o_security->name(); return s_payer; } const QString &Income::payee() const { if(o_security) return o_security->name(); return s_payer; } void Income::setPayer(QString new_payer) {s_payer = new_payer.trimmed();} QString Income::description() const { if(o_security) return tr("Dividend: %1").arg(o_security->name()); return Transaction::description(); } TransactionType Income::type() const {return TRANSACTION_TYPE_INCOME;} TransactionSubType Income::subtype() const {return TRANSACTION_SUBTYPE_INCOME;} void Income::setSecurity(Security *parent_security) { o_security = parent_security; if(o_security) { setDescription(QString()); } } Security *Income::security() const {return o_security;} bool Income::isReconciled(AssetsAccount *account) const { if(account == to()) return b_reconciled; return false; } void Income::setReconciled(AssetsAccount *account, bool is_reconciled) { if(account == to()) b_reconciled = is_reconciled; } ReinvestedDividend::ReinvestedDividend(Budget *parent_budget, double initial_value, double initial_shares, QDate initial_date, Security *initial_security, IncomesAccount *initial_category, QString initial_comment) : Income(parent_budget, initial_value, initial_date, initial_category, initial_security ? initial_security->account() : NULL, QString(), initial_comment), d_shares(initial_shares) { o_security = initial_security; } ReinvestedDividend::ReinvestedDividend(Budget *parent_budget, QXmlStreamReader *xml, bool *valid) : Income(parent_budget) { QXmlStreamAttributes attr = xml->attributes(); readAttributes(&attr, valid); readElements(xml, valid); } ReinvestedDividend::ReinvestedDividend(Budget *parent_budget) : Income(parent_budget), d_shares(0.0) {} ReinvestedDividend::ReinvestedDividend() : Income(), d_shares(0.0) {} ReinvestedDividend::ReinvestedDividend(const ReinvestedDividend *reinv) : Income(reinv), d_shares(reinv->shares()) {} ReinvestedDividend::~ReinvestedDividend() {} Transaction *ReinvestedDividend::copy() const {return new ReinvestedDividend(this);} void ReinvestedDividend::set(const Transactions *trans) { Income::set(trans); if(trans->generaltype() == generaltype() && ((Transaction*) trans)->type() == type() && ((Transaction*) trans)->subtype() == subtype()) { d_shares = ((ReinvestedDividend*) trans)->shares(); } } void ReinvestedDividend::readAttributes(QXmlStreamAttributes *attr, bool *valid) { Transaction::readAttributes(attr, valid); qlonglong id_category = attr->value("category").toLongLong(); qlonglong id_sec = attr->value("security").toLongLong(); if(budget()->securities_id.contains(id_sec)) { if(budget()->incomesAccounts_id.contains(id_category)) setCategory(budget()->incomesAccounts_id[id_category]); else setCategory(budget()->null_incomes_account); o_security = budget()->securities_id[id_sec]; setTo(o_security->account()); d_value = attr->value("value").toDouble(); d_shares = attr->value("shares").toDouble(); if(attr->hasAttribute("sharevalue")) { double v = attr->value("sharevalue").toDouble(); if(d_shares <= 0.0 && v != 0.0) d_shares = d_value / v; else if(d_value == 0.0) d_value = d_shares * v; } } else { if(valid) *valid = false; } } void ReinvestedDividend::writeAttributes(QXmlStreamAttributes *attr) { Transaction::writeAttributes(attr); attr->append("value", QString::number(income(), 'f', SAVE_MONETARY_DECIMAL_PLACES)); attr->append("shares", QString::number(d_shares, 'f', o_security->decimals())); if(category() && category() != budget()->null_incomes_account) attr->append("category", QString::number(category()->id())); attr->append("security", QString::number(o_security->id())); } bool ReinvestedDividend::equals(const Transactions *transaction, bool strict_comparison) const { if(!Income::equals(transaction, strict_comparison) || ((Income*) transaction)->subtype() != subtype()) return false; ReinvestedDividend *reinv = (ReinvestedDividend*) transaction; if(d_shares != reinv->shares()) return false; return true; } double ReinvestedDividend::shares() const {return d_shares;} double ReinvestedDividend::shareValue(bool convert) const { double v = 0.0; if(o_security) v = o_security->getQuotation(date()); if(convert && o_security && o_security->currency()) { if(budget()->defaultTransactionConversionRateDate() == TRANSACTION_CONVERSION_RATE_AT_DATE) return o_security->currency()->convertTo(v, budget()->defaultCurrency(), date()); else return o_security->currency()->convertTo(v, budget()->defaultCurrency()); } return v; } void ReinvestedDividend::setShares(double new_shares) { d_shares = new_shares; } QString ReinvestedDividend::description() const { return tr("Reinvested dividend: %1").arg(o_security->name()); } TransactionSubType ReinvestedDividend::subtype() const {return TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND;} void ReinvestedDividend::setSecurity(Security *parent_security) { o_security = parent_security; setTo(o_security->account()); } Transfer::Transfer(Budget *parent_budget, double initial_amount, QDate initial_date, AssetsAccount *initial_from, AssetsAccount *initial_to, QString initial_description, QString initial_comment, qlonglong initial_id) : Transaction(parent_budget, initial_amount < 0.0 ? -initial_amount : initial_amount, initial_date, initial_amount < 0.0 ? initial_to : initial_from, initial_amount < 0.0 ? initial_from : initial_to, initial_description, initial_comment, initial_id), b_from_reconciled(false), b_to_reconciled(false) { d_deposit = amount(); } Transfer::Transfer(Budget *parent_budget, double initial_withdrawal, double initial_deposit, QDate initial_date, AssetsAccount *initial_from, AssetsAccount *initial_to, QString initial_description, QString initial_comment, qlonglong initial_id) : Transaction(parent_budget, initial_withdrawal < 0.0 ? -initial_deposit : initial_withdrawal, initial_date, initial_withdrawal < 0.0 ? initial_to : initial_from, initial_withdrawal < 0.0 ? initial_from : initial_to, initial_description, initial_comment, initial_id), b_from_reconciled(false), b_to_reconciled(false) { if(initial_withdrawal < 0.0) { d_deposit = -initial_withdrawal; } else { d_deposit = initial_deposit; } } Transfer::Transfer(Budget *parent_budget, QXmlStreamReader *xml, bool *valid) : Transaction(parent_budget) { QXmlStreamAttributes attr = xml->attributes(); readAttributes(&attr, valid); readElements(xml, valid); } Transfer::Transfer(Budget *parent_budget) : Transaction(parent_budget), b_from_reconciled(false), b_to_reconciled(false) {} Transfer::Transfer() : Transaction() {} Transfer::Transfer(const Transfer *transfer) : Transaction(transfer), b_from_reconciled(transfer->isReconciled(transfer->from())), b_to_reconciled(transfer->isReconciled(transfer->to())) { d_deposit = transfer->deposit(); } Transfer::~Transfer() {} Transaction *Transfer::copy() const {return new Transfer(this);} void Transfer::set(const Transactions *trans) { Transaction::set(trans); if(trans->generaltype() == generaltype() && ((Transaction*) trans)->type() == type()) { b_from_reconciled = ((Transfer*) trans)->isReconciled(from()); b_to_reconciled = ((Transfer*) trans)->isReconciled(to()); } } void Transfer::readAttributes(QXmlStreamAttributes *attr, bool *valid) { Transaction::readAttributes(attr, valid); qlonglong id_from = attr->value("from").toLongLong(); qlonglong id_to = attr->value("to").toLongLong(); if(budget()->assetsAccounts_id.contains(id_from) && budget()->assetsAccounts_id.contains(id_to)) { setFrom(budget()->assetsAccounts_id[id_from]); setTo(budget()->assetsAccounts_id[id_to]); if(attr->hasAttribute("amount")) { setAmount(attr->value("amount").toDouble()); } else if(attr->hasAttribute("value")) { setAmount(attr->value("value").toDouble()); } else { setAmount(attr->value("withdrawal").toDouble(), attr->value("deposit").toDouble()); } b_from_reconciled = attr->value("fromreconciled").toInt(); b_to_reconciled = attr->value("toreconciled").toInt(); } else { if(valid) *valid =false; } } void Transfer::writeAttributes(QXmlStreamAttributes *attr) { Transaction::writeAttributes(attr); if(d_deposit != amount()) { attr->append("withdrawal", QString::number(amount(), 'f', SAVE_MONETARY_DECIMAL_PLACES)); attr->append("deposit", QString::number(d_deposit, 'f', SAVE_MONETARY_DECIMAL_PLACES)); } else { attr->append("amount", QString::number(amount(), 'f', SAVE_MONETARY_DECIMAL_PLACES)); } attr->append("from", QString::number(from()->id())); attr->append("to", QString::number(to()->id())); if(b_from_reconciled) attr->append("fromreconciled", QString::number(b_from_reconciled)); if(b_to_reconciled) attr->append("toreconciled", QString::number(b_to_reconciled)); } AssetsAccount *Transfer::to() const {return (AssetsAccount*) toAccount();} void Transfer::setTo(AssetsAccount *new_to) {setToAccount(new_to);} AssetsAccount *Transfer::from() const {return (AssetsAccount*) fromAccount();} void Transfer::setFrom(AssetsAccount *new_from) {setFromAccount(new_from);} double Transfer::amount(bool convert) const {return value(convert);} void Transfer::setValue(double new_value) { Transaction::setValue(new_value); d_deposit = new_value; } void Transfer::setAmount(double new_amount) { if(new_amount < 0.0) { setValue(-new_amount); AssetsAccount *from_bak = from(); setFrom(to()); setTo(from_bak); } else { setValue(new_amount); } } void Transfer::setAmount(double withdrawal_amount, double deposit_amount) { if(withdrawal_amount < 0.0) { setValue(-withdrawal_amount); AssetsAccount *from_bak = from(); setFrom(to()); setTo(from_bak); d_deposit = -deposit_amount; } else { setValue(withdrawal_amount); d_deposit = deposit_amount; } } Currency *Transfer::withdrawalCurrency() const { return from()->currency(); } Currency *Transfer::depositCurrency() const { if(!to()->currency()) return from()->currency(); return to()->currency(); } double Transfer::withdrawal(bool convert) const { return value(convert); } double Transfer::deposit(bool convert) const { if(convert && to() && to()->currency()) { if(budget()->defaultTransactionConversionRateDate() == TRANSACTION_CONVERSION_RATE_AT_DATE) return to()->currency()->convertTo(d_deposit, budget()->defaultCurrency(), date()); else return to()->currency()->convertTo(d_deposit, budget()->defaultCurrency()); } else if(convert) return withdrawal(true); return d_deposit; } double Transfer::fromValue(bool convert) const {return withdrawal(convert);} double Transfer::toValue(bool convert) const {return deposit(convert);} QString Transfer::description() const {return Transaction::description();} TransactionType Transfer::type() const {return TRANSACTION_TYPE_TRANSFER;} TransactionSubType Transfer::subtype() const {return TRANSACTION_SUBTYPE_TRANSFER;} bool Transfer::isReconciled(AssetsAccount *account) const { if(account == from()) return b_from_reconciled; if(account == to()) return b_to_reconciled; return false; } void Transfer::setReconciled(AssetsAccount *account, bool is_reconciled) { if(account == from()) b_from_reconciled = is_reconciled; if(account == to()) b_to_reconciled = is_reconciled; } QString Transfer::payeeText() const {return QString();} DebtReduction::DebtReduction(Budget *parent_budget, double initial_amount, QDate initial_date, AssetsAccount *initial_from, AssetsAccount *initial_loan, QString initial_comment, qlonglong initial_id) : Transfer(parent_budget, initial_amount, initial_date, initial_from, initial_loan, QString(), initial_comment, initial_id) {} DebtReduction::DebtReduction(Budget *parent_budget, double initial_payment, double initial_reduction, QDate initial_date, AssetsAccount *initial_from, AssetsAccount *initial_loan, QString initial_comment, qlonglong initial_id) : Transfer(parent_budget, initial_payment, initial_reduction, initial_date, initial_from, initial_loan, QString(), initial_comment, initial_id) {} DebtReduction::DebtReduction(Budget *parent_budget, QXmlStreamReader *xml, bool *valid) : Transfer(parent_budget) { QXmlStreamAttributes attr = xml->attributes(); readAttributes(&attr, valid); readElements(xml, valid); } DebtReduction::DebtReduction(Budget *parent_budget) : Transfer(parent_budget) {} DebtReduction::DebtReduction() : Transfer() {} DebtReduction::DebtReduction(const DebtReduction *loanpayment) : Transfer(loanpayment) {} DebtReduction::~DebtReduction() {} Transaction *DebtReduction::copy() const {return new DebtReduction(this);} void DebtReduction::set(const Transactions *trans) { Transfer::set(trans); } void DebtReduction::readAttributes(QXmlStreamAttributes *attr, bool *valid) { Transfer::readAttributes(attr, valid); qlonglong id_loan = attr->value("debt").toLongLong(); if(budget()->assetsAccounts_id.contains(id_loan)) { setTo(budget()->assetsAccounts_id[id_loan]); } else { if(valid) *valid = false; } } void DebtReduction::writeAttributes(QXmlStreamAttributes *attr) { Transfer::writeAttributes(attr); attr->append("debt", QString::number(loan()->id())); } AssetsAccount *DebtReduction::loan() const {return (AssetsAccount*) to();} void DebtReduction::setLoan(AssetsAccount *new_loan) {setTo(new_loan);} QString DebtReduction::description() const {return tr("Debt payment: %1 (reduction)").arg(loan()->name());} TransactionSubType DebtReduction::subtype() const {return TRANSACTION_SUBTYPE_DEBT_REDUCTION;} QString DebtReduction::payeeText() const {return loan()->maintainer();} Balancing::Balancing(Budget *parent_budget, double initial_amount, QDate initial_date, AssetsAccount *initial_account, QString initial_comment) : Transfer(parent_budget) { d_value = -initial_amount; d_deposit = -initial_amount; d_date = initial_date; s_comment = initial_comment; o_from = initial_account; o_to = budget()->balancingAccount; } Balancing::Balancing(Budget *parent_budget, QXmlStreamReader *xml, bool *valid) : Transfer(parent_budget) { QXmlStreamAttributes attr = xml->attributes(); readAttributes(&attr, valid); readElements(xml, valid); } Balancing::Balancing(Budget *parent_budget) : Transfer(parent_budget) {} Balancing::Balancing() : Transfer() {} Balancing::Balancing(const Balancing *balancing) : Transfer(balancing) {} Balancing::~Balancing() {} Transaction *Balancing::copy() const {return new Balancing(this);} void Balancing::set(const Transactions *trans) { Transfer::set(trans); if(trans->generaltype() == generaltype() && ((Transaction*) trans)->subtype() != subtype()) { setToAccount(budget()->balancingAccount); } } QString Balancing::description() const { if(s_description.isEmpty()) return tr("Account Balance Adjustment"); return s_description; } TransactionSubType Balancing::subtype() const {return TRANSACTION_SUBTYPE_BALANCING;} void Balancing::readAttributes(QXmlStreamAttributes *attr, bool *valid) { Transaction::readAttributes(attr, valid); if(attr->hasAttribute("value")) { d_value = -attr->value("value").toDouble(); } else { d_value = -attr->value("amount").toDouble(); } setToAccount(budget()->balancingAccount); setFromAccount(NULL); qlonglong id_account = attr->value("account").toLongLong(); if(budget()->assetsAccounts_id.contains(id_account)) { setFromAccount(budget()->assetsAccounts_id[id_account]); } else { if(valid) *valid = false; } } void Balancing::writeAttributes(QXmlStreamAttributes *attr) { Transaction::writeAttributes(attr); attr->append("amount", QString::number(-amount(), 'f', SAVE_MONETARY_DECIMAL_PLACES)); attr->append("account", QString::number(account()->id())); } void Balancing::setAmount(double new_amount) { setValue(-new_amount); } void Balancing::setAmount(double withdrawal_amount, double) { setValue(withdrawal_amount); } AssetsAccount *Balancing::account() const {return toAccount() == o_budget->balancingAccount ? (AssetsAccount*) fromAccount() : (AssetsAccount*) toAccount();} void Balancing::setAccount(AssetsAccount *new_account) {toAccount() == o_budget->balancingAccount ? setFromAccount(new_account) : setToAccount(new_account);} SecurityTransaction::SecurityTransaction(Security *parent_security, double initial_value, double initial_shares, QDate initial_date, QString initial_comment) : Transaction(parent_security->budget(), initial_value, initial_date, NULL, NULL, QString(), initial_comment), o_security(parent_security), d_shares(initial_shares), b_reconciled(false) { } SecurityTransaction::SecurityTransaction(Budget *parent_budget, QXmlStreamReader *xml, bool *valid) : Transaction(parent_budget, xml, valid) {} SecurityTransaction::SecurityTransaction(Budget *parent_budget) : Transaction(parent_budget), b_reconciled(false) {} SecurityTransaction::SecurityTransaction() : Transaction(), o_security(NULL), d_shares(0.0), b_reconciled(false) {} SecurityTransaction::SecurityTransaction(const SecurityTransaction *transaction) : Transaction(transaction), o_security(transaction->security()), d_shares(transaction->shares()), b_reconciled(transaction->account() && transaction->account()->type() == ACCOUNT_TYPE_ASSETS ? transaction->isReconciled((AssetsAccount*) transaction->account()) : false) {} SecurityTransaction::~SecurityTransaction() {} void SecurityTransaction::set(const Transactions *trans) { Transaction::set(trans); if(trans->generaltype() == generaltype() && ((Transaction*) trans)->type() == type()) { d_shares = ((SecurityTransaction*) trans)->shares(); o_security = ((SecurityTransaction*) trans)->security(); b_reconciled = (account() && account()->type() == ACCOUNT_TYPE_ASSETS ? ((SecurityTransaction*) trans)->isReconciled((AssetsAccount*) account()) : false); } } void SecurityTransaction::readAttributes(QXmlStreamAttributes *attr, bool *valid) { Transaction::readAttributes(attr, valid); d_shares = attr->value("shares").toDouble(); if(attr->hasAttribute("sharevalue")) { double v = attr->value("sharevalue").toDouble(); if(d_shares <= 0.0 && v != 0.0) d_shares = d_value / v; else if(d_value == 0.0) d_value = d_shares * v; } b_reconciled = attr->value("reconciled").toInt(); qlonglong id = attr->value("security").toLongLong(); if(budget()->securities_id.contains(id)) { o_security = budget()->securities_id[id]; } else { if(valid) *valid = false; } } void SecurityTransaction::writeAttributes(QXmlStreamAttributes *attr) { Transaction::writeAttributes(attr); attr->append("shares", QString::number(d_shares, 'f', o_security->decimals())); attr->append("security", QString::number(o_security->id())); if(b_reconciled) attr->append("reconciled", QString::number(b_reconciled)); } bool SecurityTransaction::equals(const Transactions *transaction, bool strict_comparison) const { if(!Transaction::equals(transaction, strict_comparison)) return false; SecurityTransaction *sectrans = (SecurityTransaction*) transaction; if(d_shares != sectrans->shares()) return false; if(o_security != sectrans->security()) return false; return true; } double SecurityTransaction::shares() const {return d_shares;} double SecurityTransaction::shareValue(bool convert) const { double v = 0.0; if(o_security) v = o_security->getQuotation(date()); if(convert && o_security && o_security->currency()) { if(budget()->defaultTransactionConversionRateDate() == TRANSACTION_CONVERSION_RATE_AT_DATE) return o_security->currency()->convertTo(v, budget()->defaultCurrency(), date()); else return o_security->currency()->convertTo(v, budget()->defaultCurrency()); } return v; } void SecurityTransaction::setShares(double new_shares) { d_shares = new_shares; } double SecurityTransaction::value(bool convert) const { return Transaction::value(convert); } Currency *SecurityTransaction::currency() const { return account()->currency(); } double SecurityTransaction::fromValue(bool convert) const { return Transaction::value(convert); } double SecurityTransaction::toValue(bool convert) const { return Transaction::value(convert); } Account *SecurityTransaction::fromAccount() const {return o_security->account();} Account *SecurityTransaction::toAccount() const {return o_security->account();} QString SecurityTransaction::description() const {return Transaction::description();} void SecurityTransaction::setSecurity(Security *parent_security) { o_security = parent_security; } Security *SecurityTransaction::security() const {return o_security;} bool SecurityTransaction::relatesToAccount(Account *account, bool, bool) const {return fromAccount() == account || toAccount() == account;} double SecurityTransaction::accountChange(Account *account, bool, bool convert) const { if(fromAccount() == account) return -fromValue(convert); if(toAccount() == account) return toValue(convert); return 0.0; } bool SecurityTransaction::isReconciled(AssetsAccount *account_) const { if(account_ == account()) return b_reconciled; return false; } void SecurityTransaction::setReconciled(AssetsAccount *account_, bool is_reconciled) { if(account_ == account()) b_reconciled = is_reconciled; } SecurityBuy::SecurityBuy(Security *parent_security, double initial_value, double initial_shares, QDate initial_date, Account *from_account, QString initial_comment) : SecurityTransaction(parent_security, initial_value, initial_shares, initial_date, initial_comment) { setAccount(from_account); } SecurityBuy::SecurityBuy(Budget *parent_budget, QXmlStreamReader *xml, bool *valid) : SecurityTransaction(parent_budget) { QXmlStreamAttributes attr = xml->attributes(); readAttributes(&attr, valid); readElements(xml, valid); } SecurityBuy::SecurityBuy(Budget *parent_budget) : SecurityTransaction(parent_budget) {} SecurityBuy::SecurityBuy() : SecurityTransaction() {} SecurityBuy::SecurityBuy(const SecurityBuy *transaction) : SecurityTransaction(transaction) { setAccount(transaction->account()); } SecurityBuy::~SecurityBuy() {} Transaction *SecurityBuy::copy() const {return new SecurityBuy(this);} void SecurityBuy::set(const Transactions *trans) { SecurityTransaction::set(trans); } void SecurityBuy::readAttributes(QXmlStreamAttributes *attr, bool *valid) { if(attr->hasAttribute("value")) d_value = attr->value("value").toDouble(); else d_value = attr->value("cost").toDouble(); SecurityTransaction::readAttributes(attr, valid); qlonglong id_account; if(attr->hasAttribute("from")) id_account = attr->value("from").toLongLong(); else id_account = attr->value("account").toLongLong(); if(budget()->assetsAccounts_id.contains(id_account)) { setAccount(budget()->assetsAccounts_id[id_account]); } else if(budget()->incomesAccounts_id.contains(id_account)) { setAccount(budget()->incomesAccounts_id[id_account]); } else { if(valid) *valid = false; } } void SecurityBuy::writeAttributes(QXmlStreamAttributes *attr) { SecurityTransaction::writeAttributes(attr); attr->append("cost", QString::number(d_value, 'f', SAVE_MONETARY_DECIMAL_PLACES)); attr->append("account", QString::number(account()->id())); } double SecurityBuy::toValue(bool convert) const { return shareValue(convert) * d_shares; } QString SecurityBuy::description() const {return tr("Security: %1 (bought)", "Financial security (e.g. stock, mutual fund)").arg(o_security->name());} Account *SecurityBuy::fromAccount() const {return Transaction::fromAccount();} Account *SecurityBuy::account() const {return fromAccount();} void SecurityBuy::setAccount(Account *new_account) {setFromAccount(new_account);} TransactionType SecurityBuy::type() const {return TRANSACTION_TYPE_SECURITY_BUY;} SecuritySell::SecuritySell(Security *parent_security, double initial_value, double initial_shares, QDate initial_date, Account *to_account, QString initial_comment) : SecurityTransaction(parent_security, initial_value, initial_shares, initial_date, initial_comment) { setAccount(to_account); } SecuritySell::SecuritySell(Budget *parent_budget, QXmlStreamReader *xml, bool *valid) : SecurityTransaction(parent_budget) { QXmlStreamAttributes attr = xml->attributes(); readAttributes(&attr, valid); readElements(xml, valid); } SecuritySell::SecuritySell(Budget *parent_budget) : SecurityTransaction(parent_budget) {} SecuritySell::SecuritySell() : SecurityTransaction() {} SecuritySell::SecuritySell(const SecuritySell *transaction) : SecurityTransaction(transaction) { setAccount(transaction->account()); } SecuritySell::~SecuritySell() {} Transaction *SecuritySell::copy() const {return new SecuritySell(this);} void SecuritySell::set(const Transactions *trans) { SecurityTransaction::set(trans); } void SecuritySell::readAttributes(QXmlStreamAttributes *attr, bool *valid) { if(attr->hasAttribute("value")) d_value = attr->value("value").toDouble(); else d_value = attr->value("income").toDouble(); SecurityTransaction::readAttributes(attr, valid); qlonglong id_account; if(attr->hasAttribute("to")) id_account = attr->value("to").toLongLong(); else id_account = attr->value("account").toLongLong(); if(budget()->assetsAccounts_id.contains(id_account)) { setAccount(budget()->assetsAccounts_id[id_account]); } else if(budget()->expensesAccounts_id.contains(id_account)) { setAccount(budget()->expensesAccounts_id[id_account]); } else { if(valid) *valid = false; } } void SecuritySell::writeAttributes(QXmlStreamAttributes *attr) { SecurityTransaction::writeAttributes(attr); attr->append("income", QString::number(d_value, 'f', SAVE_MONETARY_DECIMAL_PLACES)); attr->append("account", QString::number(account()->id())); } double SecuritySell::fromValue(bool convert) const { return shareValue(convert) * d_shares; } QString SecuritySell::description() const {return tr("Security: %1 (sold)", "Financial security (e.g. stock, mutual fund)").arg(o_security->name());} Account *SecuritySell::toAccount() const {return Transaction::toAccount();} Account *SecuritySell::account() const {return toAccount();} void SecuritySell::setAccount(Account *new_account) {setToAccount(new_account);} TransactionType SecuritySell::type() const {return TRANSACTION_TYPE_SECURITY_SELL;} ScheduledTransaction::ScheduledTransaction(Budget *parent_budget) : Transactions(parent_budget) { i_id = o_budget->getNewId(); o_rec = NULL; o_trans = NULL; } ScheduledTransaction::ScheduledTransaction(Budget *parent_budget, Transactions *trans, Recurrence *rec) : Transactions(parent_budget) { i_id = o_budget->getNewId(); o_rec = rec; o_trans = trans; if(o_trans && o_rec && o_rec->startDate() != o_trans->date()) o_trans->setDate(o_rec->startDate()); } ScheduledTransaction::ScheduledTransaction(Budget *parent_budget, QXmlStreamReader *xml, bool *valid) : Transactions(parent_budget) { QXmlStreamAttributes attr = xml->attributes(); readAttributes(&attr, valid); readElements(xml, valid); } ScheduledTransaction::ScheduledTransaction(const ScheduledTransaction *strans) : Transactions(strans), o_rec(NULL) { if(strans->recurrence()) o_rec = strans->recurrence()->copy(); if(strans->transaction()) o_trans = strans->transaction()->copy(); } ScheduledTransaction::~ScheduledTransaction() { if(o_rec) delete o_rec; if(o_trans) delete o_trans; } ScheduledTransaction *ScheduledTransaction::copy() const {return new ScheduledTransaction(this);} void ScheduledTransaction::set(const Transactions *trans) { Transactions::set(trans); if(trans->generaltype() == generaltype()) { setTransaction(((ScheduledTransaction*) trans)->transaction(), true); } } void ScheduledTransaction::readAttributes(QXmlStreamAttributes *attr, bool*) { read_id(attr, i_id, i_first_revision, i_last_revision); } bool ScheduledTransaction::readElement(QXmlStreamReader *xml, bool*) { if(xml->name() == XML_COMPARE_CONST_CHAR("recurrence")) { #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) QStringView type = xml->attributes().value("type"); #else QStringRef type = xml->attributes().value("type"); #endif bool valid2 = true; if(type == XML_COMPARE_CONST_CHAR("daily")) { if(o_rec) delete o_rec; o_rec = new DailyRecurrence(budget(), xml, &valid2); } else if(type == XML_COMPARE_CONST_CHAR("weekly")) { if(o_rec) delete o_rec; o_rec = new WeeklyRecurrence(budget(), xml, &valid2); } else if(type == XML_COMPARE_CONST_CHAR("monthly")) { if(o_rec) delete o_rec; o_rec = new MonthlyRecurrence(budget(), xml, &valid2); } else if(type == XML_COMPARE_CONST_CHAR("yearly")) { if(o_rec) delete o_rec; o_rec = new YearlyRecurrence(budget(), xml, &valid2); } else { xml->skipCurrentElement(); } if(!valid2) { delete o_rec; o_rec = NULL; } return true; } else if(xml->name() == XML_COMPARE_CONST_CHAR("transaction")) { #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) QStringView type = xml->attributes().value("type"); #else QStringRef type = xml->attributes().value("type"); #endif if(type.isEmpty()) { QXmlStreamAttributes attr = xml->attributes(); if(attr.hasAttribute("shares") && attr.hasAttribute("security")) { if(attr.hasAttribute("cost")) attr.append("type", "security_buy"); else if(attr.hasAttribute("income")) attr.append("type", "security_sell"); else if(attr.hasAttribute("from")) attr.append("type", "security_buy"); else if(attr.hasAttribute("to")) attr.append("type", "security_sell"); } else if(attr.hasAttribute("cost") || (attr.hasAttribute("category") && attr.hasAttribute("from"))) { attr.append("type", "expense"); } else if(attr.hasAttribute("income") || (attr.hasAttribute("category") && attr.hasAttribute("to"))) { attr.append("type", "income"); } else if(attr.hasAttribute("amount") || attr.hasAttribute("withdrawal")) { attr.append("type", "transfer"); } else if(attr.hasAttribute("from") && attr.hasAttribute("to")) { qlonglong id_from = attr.value("from").toLongLong(); qlonglong id_to = attr.value("to").toLongLong(); if(budget()->expensesAccounts_id.contains(id_to) || budget()->expensesAccounts_id.contains(id_from)) attr.append("type", "expense"); else if(budget()->incomesAccounts_id.contains(id_from) || budget()->incomesAccounts_id.contains(id_to)) attr.append("type", "income"); else if(budget()->assetsAccounts_id.contains(id_from) && budget()->assetsAccounts_id.contains(id_to)) attr.append("type", "transfer"); } type = attr.value("type"); } bool valid2 = true; if(type == XML_COMPARE_CONST_CHAR("expense") || type == XML_COMPARE_CONST_CHAR("refund")) { if(o_trans) delete o_trans; o_trans = new Expense(budget(), xml, &valid2); } else if(type == XML_COMPARE_CONST_CHAR("income") || type == XML_COMPARE_CONST_CHAR("repayment")) { if(o_trans) delete o_trans; o_trans = new Income(budget(), xml, &valid2); } else if(type == XML_COMPARE_CONST_CHAR("dividend")) { if(o_trans) delete o_trans; o_trans = new Income(budget(), xml, &valid2); if(!((Income*) o_trans)->security()) valid2 = false; } else if(type == XML_COMPARE_CONST_CHAR("reinvested_dividend")) { if(o_trans) delete o_trans; o_trans = new ReinvestedDividend(budget(), xml, &valid2); } else if(type == XML_COMPARE_CONST_CHAR("transfer")) { if(o_trans) delete o_trans; o_trans = new Transfer(budget(), xml, &valid2); } else if(type == XML_COMPARE_CONST_CHAR("balancing")) { if(o_trans) delete o_trans; o_trans = new Balancing(budget(), xml, &valid2); } else if(type == XML_COMPARE_CONST_CHAR("security_buy")) { if(o_trans) delete o_trans; o_trans = new SecurityBuy(budget(), xml, &valid2); } else if(type == XML_COMPARE_CONST_CHAR("security_sell")) { if(o_trans) delete o_trans; o_trans = new SecuritySell(budget(), xml, &valid2); } else if(type == XML_COMPARE_CONST_CHAR("multiitem") || type == XML_COMPARE_CONST_CHAR("split")) { if(o_trans) delete o_trans; o_trans = new MultiItemTransaction(budget(), xml, &valid2); } else if(type == XML_COMPARE_CONST_CHAR("multiaccount")) { if(o_trans) delete o_trans; o_trans = new MultiAccountTransaction(budget(), xml, &valid2); } else if(type == XML_COMPARE_CONST_CHAR("debtpayment")) { if(o_trans) delete o_trans; o_trans = new DebtPayment(budget(), xml, &valid2); } else { xml->skipCurrentElement(); } if(!valid2) { delete o_trans; o_trans = NULL; } return true; } return false; } bool ScheduledTransaction::readElements(QXmlStreamReader *xml, bool *valid) { o_rec = NULL; o_trans = NULL; while(xml->readNextStartElement()) { if(!readElement(xml, valid)) xml->skipCurrentElement(); } if(!o_trans && valid) *valid = false; if(o_rec && o_trans && o_rec->startDate() != o_trans->date()) { o_trans->setDate(o_rec->startDate()); } return true; } void ScheduledTransaction::save(QXmlStreamWriter *xml) { QXmlStreamAttributes attr; writeAttributes(&attr); if(!attr.isEmpty()) xml->writeAttributes(attr); writeElements(xml); } void ScheduledTransaction::writeAttributes(QXmlStreamAttributes *attr) { write_id(attr, i_id, i_first_revision, i_last_revision); } void ScheduledTransaction::writeElements(QXmlStreamWriter *xml) { if(!o_trans) return; if(o_trans->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE) { Transaction *trans = (Transaction*) o_trans; xml->writeStartElement("transaction"); switch(trans->type()) { case TRANSACTION_TYPE_TRANSFER: { if(trans->fromAccount() == o_budget->balancingAccount) xml->writeAttribute("type", "balancing"); else xml->writeAttribute("type", "transfer"); break; } case TRANSACTION_TYPE_INCOME: { if(trans->subtype() == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND) { xml->writeAttribute("type", "reinvested_dividend"); } else if(((Income*) trans)->security()) { xml->writeAttribute("type", "dividend"); } else { xml->writeAttribute("type", "income"); } break; } case TRANSACTION_TYPE_EXPENSE: { xml->writeAttribute("type", "expense"); break; } case TRANSACTION_TYPE_SECURITY_BUY: { xml->writeAttribute("type", "security_buy"); break; } case TRANSACTION_TYPE_SECURITY_SELL: { xml->writeAttribute("type", "security_sell"); break; } } trans->save(xml); xml->writeEndElement(); } else if(o_trans->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { SplitTransaction *o_split = (SplitTransaction*) o_trans; xml->writeStartElement("transaction"); switch(o_split->type()) { case SPLIT_TRANSACTION_TYPE_MULTIPLE_ITEMS: { xml->writeAttribute("type", "multiitem"); break; } case SPLIT_TRANSACTION_TYPE_MULTIPLE_ACCOUNTS: { xml->writeAttribute("type", "multiaccount"); break; } case SPLIT_TRANSACTION_TYPE_LOAN: { xml->writeAttribute("type", "debtpayment"); break; } } o_split->save(xml); xml->writeEndElement(); } if(o_rec) { xml->writeStartElement("recurrence"); switch(o_rec->type()) { case RECURRENCE_TYPE_DAILY: { xml->writeAttribute("type", "daily"); break; } case RECURRENCE_TYPE_WEEKLY: { xml->writeAttribute("type", "weekly"); break; } case RECURRENCE_TYPE_MONTHLY: { xml->writeAttribute("type", "monthly"); break; } case RECURRENCE_TYPE_YEARLY: { xml->writeAttribute("type", "yearly"); break; } } o_rec->save(xml); xml->writeEndElement(); } } bool ScheduledTransaction::equals(const Transactions *transaction, bool strict_comparison) const { if(transaction->generaltype() != GENERAL_TRANSACTION_TYPE_SCHEDULE) return false; ScheduledTransaction *strans = (ScheduledTransaction*) transaction; if(!o_trans || strict_comparison || !strans->transaction() || !o_trans->equals(strans->transaction(), strict_comparison)) return false; if(budget() != strans->budget()) return false; return true; } Recurrence *ScheduledTransaction::recurrence() const { return o_rec; } void ScheduledTransaction::setRecurrence(Recurrence *rec, bool delete_old) { if(o_rec && delete_old) delete o_rec; o_rec = rec; if(o_trans && o_rec && o_rec->startDate() != o_trans->date()) o_trans->setDate(o_rec->startDate()); if(o_rec) { o_budget->scheduledTransactionSortModified(this); o_budget->scheduledTransactionDateModified(this); } } const QDate &ScheduledTransaction::firstOccurrence() const { if(o_rec) return o_rec->firstOccurrence(); if(o_trans) return o_trans->date(); return emptydate; } bool ScheduledTransaction::isOneTimeTransaction() const { return !o_rec || o_rec->firstOccurrence() == o_rec->lastOccurrence(); } const QDate &ScheduledTransaction::date() const { return firstOccurrence(); } void ScheduledTransaction::setDate(QDate newdate) { if(o_rec) { o_rec->setStartDate(newdate); if(o_trans) { o_trans->setDate(o_rec->startDate()); } o_budget->scheduledTransactionSortModified(this); o_budget->scheduledTransactionDateModified(this); } else if(o_trans && newdate != o_trans->date()) { o_trans->setDate(newdate); o_budget->scheduledTransactionSortModified(this); o_budget->scheduledTransactionDateModified(this); } } const qint64 &ScheduledTransaction::timestamp() const { if(o_trans) return o_trans->timestamp(); return zero_timestamp; } void ScheduledTransaction::setTimestamp(qint64 cr_time) { if(!o_trans || cr_time == o_trans->timestamp()) return; o_budget->scheduledTransactionSortModified(this); o_trans->setTimestamp(cr_time); } void ScheduledTransaction::addException(QDate exceptiondate) { if(!o_rec) return; if(o_trans && exceptiondate == o_rec->startDate()) { o_rec->addException(exceptiondate); o_trans->setDate(o_rec->startDate()); o_budget->scheduledTransactionSortModified(this); o_budget->scheduledTransactionDateModified(this); } else { o_rec->addException(exceptiondate); } } Transactions *ScheduledTransaction::realize(QDate date) { if(!o_trans) return NULL; if(o_rec && !o_rec->removeOccurrence(date)) return NULL; if(!o_rec && date != o_trans->date()) return NULL; Transactions *trans = o_trans->copy(); trans->setTimestamp(); if(o_rec) { if(o_rec->startDate() != o_trans->date()) o_trans->setDate(o_rec->startDate()); o_budget->scheduledTransactionSortModified(this); o_budget->scheduledTransactionDateModified(this); } if(o_rec && trans->date().isValid()) { trans->setId(o_budget->getNewId()); trans->setFirstRevision(o_budget->revision()); } else { trans->setModified(); } if(date != trans->date()) trans->setDate(date); return trans; } Transactions *ScheduledTransaction::transaction() const { return o_trans; } void ScheduledTransaction::setTransaction(Transactions *trans, bool delete_old) { if(o_trans && delete_old) delete o_trans; o_trans = trans; if(o_rec && o_trans) { if(o_rec->startDate() != o_trans->date()) o_trans->setDate(o_rec->startDate()); } else if(o_trans) { o_budget->scheduledTransactionSortModified(this); o_budget->scheduledTransactionDateModified(this); } } double ScheduledTransaction::value(bool convert) const { if(!o_trans) return 0.0; return o_trans->value(convert); } Currency *ScheduledTransaction::currency() const { if(!o_trans) return NULL; return o_trans->currency(); } double ScheduledTransaction::quantity() const { if(!o_trans) return 0.0; return o_trans->quantity(); } QString ScheduledTransaction::description() const { if(o_trans) return o_trans->description(); return QString(); } const QString &ScheduledTransaction::comment() const { if(o_trans) return o_trans->comment(); return emptystr; } const QString &ScheduledTransaction::associatedFile() const { if(o_trans) return o_trans->associatedFile(); return emptystr; } void ScheduledTransaction::setAssociatedFile(QString new_attachment) { if(o_trans) o_trans->setAssociatedFile(new_attachment); } GeneralTransactionType ScheduledTransaction::generaltype() const {return GENERAL_TRANSACTION_TYPE_SCHEDULE;} int ScheduledTransaction::transactiontype() const { if(o_trans && o_trans->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE) return ((Transaction*) o_trans)->type(); return -1; } int ScheduledTransaction::transactionsubtype() const { if(o_trans && o_trans->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE) return ((Transaction*) o_trans)->subtype(); return -1; } bool ScheduledTransaction::relatesToAccount(Account *account, bool include_subs, bool include_non_value) const {return o_trans && o_trans->relatesToAccount(account, include_subs, include_non_value);} void ScheduledTransaction::replaceAccount(Account *old_account, Account *new_account) {if(o_trans) o_trans->replaceAccount(old_account, new_account);} double ScheduledTransaction::accountChange(Account *account, bool include_subs, bool convert) const { if(o_trans) return o_trans->accountChange(account, include_subs, convert); return 0.0; } bool ScheduledTransaction::isReconciled(AssetsAccount*) const {return false;} void ScheduledTransaction::setReconciled(AssetsAccount*, bool) {return;} void ScheduledTransaction::addTag(QString tag) {if(o_trans) o_trans->addTag(tag);} bool ScheduledTransaction::removeTag(QString tag) {if(o_trans) {return o_trans->removeTag(tag);} return false;} void ScheduledTransaction::removeTag(int index) {if(o_trans) o_trans->removeTag(index);} int ScheduledTransaction::tagsCount(bool include_parent) const {if(o_trans) {return o_trans->tagsCount(include_parent);} return 0;} bool ScheduledTransaction::hasTag(const QString &tag, bool include_parent, bool case_insensitive) const {if(o_trans) {return o_trans->hasTag(tag, include_parent, case_insensitive);} return false;} const QString &ScheduledTransaction::getTag(int index, bool include_parent) const {if(o_trans) {o_trans->getTag(index, include_parent);} return emptystr;} QString ScheduledTransaction::tagsText(bool include_parent_child) const {if(o_trans) {o_trans->tagsText(include_parent_child);} return QString();} void ScheduledTransaction::clearTags() {if(o_trans) o_trans->clearTags();} void ScheduledTransaction::readTags(const QString &text) {if(o_trans) o_trans->readTags(text);} QString ScheduledTransaction::writeTags(bool include_parent) const {if(o_trans) {return o_trans->writeTags(include_parent);} return QString();} const QString &ScheduledTransaction::payee() const { if(o_trans) return o_trans->payee(); return emptystr; } QString ScheduledTransaction::payeeText() const { if(o_trans) return o_trans->payeeText(); return QString(); } int ScheduledTransaction::linksCount(bool include_parent) const { if(o_trans) return o_trans->linksCount(include_parent); return 0; } qlonglong ScheduledTransaction::getLinkId(int index, bool include_parent) const { if(o_trans) return o_trans->getLinkId(index, include_parent); return 0; } void ScheduledTransaction::clearLinks() {if(o_trans) o_trans->clearLinks();} void ScheduledTransaction::removeLink(int index) {if(o_trans) o_trans->removeLink(index);} bool ScheduledTransaction::removeLinkId(qlonglong lid) { if(o_trans) return o_trans->removeLinkId(lid); return false; } void ScheduledTransaction::addLinkId(qlonglong lid) {if(o_trans) o_trans->addLinkId(lid);} bool ScheduledTransaction::hasLinkId(qlonglong lid, bool include_parent) const { if(o_trans) return o_trans->hasLinkId(lid, include_parent); return false; } void ScheduledTransaction::readLinks(const QString &text) {if(o_trans) o_trans->readLinks(text);} QString ScheduledTransaction::writeLinks(bool include_parent) const {if(o_trans) {return o_trans->writeLinks(include_parent);} return QString();} SplitTransaction::SplitTransaction(Budget *parent_budget, QDate initial_date, QString initial_description) : Transactions(parent_budget), d_date(initial_date), s_description(initial_description.trimmed()), i_time(QDateTime::currentMSecsSinceEpoch() / 1000), b_reconciled(false) {i_id = o_budget->getNewId();} SplitTransaction::SplitTransaction(Budget *parent_budget, QXmlStreamReader *xml, bool *valid) : Transactions(parent_budget) { QXmlStreamAttributes attr = xml->attributes(); readAttributes(&attr, valid); readElements(xml, valid); } SplitTransaction::SplitTransaction(const SplitTransaction *split) : Transactions(split), d_date(split->date()), s_description(split->description()), s_comment(split->comment()), s_file(split->associatedFile()), i_time(split->timestamp()), b_reconciled(false) { for(int i = 0; i < split->count(); i++) { Transaction *trans = split->at(i)->copy(); trans->setParentSplit(this); splits.push_back(trans); } } SplitTransaction::SplitTransaction(Budget *parent_budget) : Transactions(parent_budget), i_time(QDateTime::currentMSecsSinceEpoch() / 1000), b_reconciled(false) {} SplitTransaction::SplitTransaction() : Transactions(), i_time(QDateTime::currentMSecsSinceEpoch() / 1000), b_reconciled(false) {} SplitTransaction::~SplitTransaction() { clear(); } void SplitTransaction::set(const Transactions *trans) { Transactions::set(trans); if(trans->generaltype() == generaltype()) { SplitTransaction *split = (SplitTransaction*) trans; i_time = split->timestamp(); clear(); for(int i = 0; i < split->count(); i++) { Transaction *trans = split->at(i)->copy(); trans->setParentSplit(this); splits.push_back(trans); } } } void SplitTransaction::readAttributes(QXmlStreamAttributes *attr, bool*) { if(attr->hasAttribute("date")) d_date = QDate::fromString(attr->value("date").toString(), Qt::ISODate); read_id(attr, i_id, i_first_revision, i_last_revision); i_time = attr->value("timestamp").toLongLong(); s_description = attr->value("description").trimmed().toString(); if(attr->hasAttribute("tags")) readTags(attr->value("tags").toString()); if(attr->hasAttribute("links")) readLinks(attr->value("links").toString()); s_comment = attr->value("comment").trimmed().toString(); s_file = attr->value("file").trimmed().toString(); b_reconciled = attr->value("reconciled").toInt(); } bool SplitTransaction::readElement(QXmlStreamReader*, bool*) { return false; } bool SplitTransaction::readElements(QXmlStreamReader *xml, bool *valid) { while(xml->readNextStartElement()) { if(!readElement(xml, valid)) xml->skipCurrentElement(); } return true; } void SplitTransaction::save(QXmlStreamWriter *xml) { QXmlStreamAttributes attr; writeAttributes(&attr); xml->writeAttributes(attr); writeElements(xml); } void SplitTransaction::writeAttributes(QXmlStreamAttributes *attr) { if(d_date.isValid()) attr->append("date", d_date.toString(Qt::ISODate)); write_id(attr, i_id, i_first_revision, i_last_revision); if(i_time != 0) attr->append("timestamp", QString::number(i_time)); if(!s_description.isEmpty()) attr->append("description", s_description); if(!tags.isEmpty()) attr->append("tags", writeTags(false)); if(!links.isEmpty()) attr->append("links", writeLinks(false)); if(!s_comment.isEmpty()) attr->append("comment", s_comment); if(!s_file.isEmpty()) attr->append("file", s_file); if(b_reconciled) attr->append("reconciled", QString::number(b_reconciled)); } void SplitTransaction::writeElements(QXmlStreamWriter*) {} bool SplitTransaction::equals(const Transactions *transaction, bool strict_comparison) const { if(transaction->generaltype() != GENERAL_TRANSACTION_TYPE_SPLIT) return false; SplitTransaction *split = (SplitTransaction*) transaction; if(split->type() != type()) return false; if(count() != split->count()) return false; for(int i = 0; i < count(); i++) { if(!at(i)->equals(split->at(i), strict_comparison)) return false; } if(date() != split->date()) return false; if(description() != split->description()) return false; if(comment() != split->comment() && (strict_comparison || comment().isEmpty() == split->comment().isEmpty())) return false; if(associatedFile() != split->associatedFile() && (strict_comparison || associatedFile().isEmpty() == split->associatedFile().isEmpty())) return false; if(strict_comparison || (tags.count() > 0 && split->tagsCount() > 0)) { if(split->tagsCount() != tags.count()) return false; for(int i = 0; i < tags.count(); i++) { if(!transaction->hasTag(tags[i], false)) return false; } } if(strict_comparison || (links.count() > 0 && split->linksCount() > 0)) { if(split->linksCount() != links.count()) return false; for(int i = 0; i < links.count(); i++) { if(!transaction->hasLinkId(links[i], false)) return false; } } if(budget() != split->budget()) return false; return true; } double SplitTransaction::income() const { return -cost(); } void SplitTransaction::addTransaction(Transaction *trans) { trans->setDate(d_date); splits.push_back(trans); trans->setParentSplit(this); } void SplitTransaction::removeTransaction(Transaction *trans, bool keep) { QVector::iterator it_e = splits.end(); for(QVector::iterator it = splits.begin(); it != it_e; ++it) { if(*it == trans) { splits.erase(it); break; } } trans->setParentSplit(NULL); o_budget->removeTransaction(trans, keep); } void SplitTransaction::clear(bool keep) { QVector::iterator it_e = splits.end(); for(QVector::iterator it = splits.begin(); it != it_e; ++it) { (*it)->setParentSplit(NULL); if(!keep) o_budget->removeTransaction(*it); } splits.clear(); } const QDate &SplitTransaction::date() const {return d_date;} void SplitTransaction::setDate(QDate new_date) { if(new_date != d_date) { QDate old_date = d_date; d_date = new_date; o_budget->splitTransactionSortModified(this); o_budget->splitTransactionDateModified(this, old_date); } QVector::size_type c = splits.count(); for(QVector::size_type i = 0; i < c; i++) { splits[i]->setDate(d_date); } } const qint64 &SplitTransaction::timestamp() const {return i_time;} void SplitTransaction::setTimestamp(qint64 cr_time) { if(i_time == cr_time) return; i_time = cr_time; o_budget->splitTransactionSortModified(this); QVector::size_type c = splits.count(); for(QVector::size_type i = 0; i < c; i++) { splits[i]->setTimestamp(i_time); } } QString SplitTransaction::description() const {return s_description;} void SplitTransaction::setDescription(QString new_description) {s_description = new_description.trimmed();} const QString &SplitTransaction::comment() const {return s_comment;} void SplitTransaction::setComment(QString new_comment) {s_comment = new_comment;} const QString &SplitTransaction::associatedFile() const {return s_file;} void SplitTransaction::setAssociatedFile(QString new_attachment) {s_file = new_attachment;} int SplitTransaction::count() const {return splits.count();} Transaction *SplitTransaction::operator[] (int index) const {return splits[index];} Transaction *SplitTransaction::at(int index) const {return splits.at(index);} GeneralTransactionType SplitTransaction::generaltype() const {return GENERAL_TRANSACTION_TYPE_SPLIT;} bool SplitTransaction::isIncomesAndExpenses() const { for(int i = 0; i < splits.count(); i++) { if(splits[i]->type() != TRANSACTION_TYPE_EXPENSE && splits[i]->type() != TRANSACTION_TYPE_INCOME) return false; } return true; } bool SplitTransaction::relatesToAccount(Account *account, bool include_subs, bool include_non_value) const { int c = splits.count(); for(int i = 0; i < c; i++) { if(splits[i]->relatesToAccount(account, include_subs, include_non_value)) return true; } return false; } void SplitTransaction::replaceAccount(Account *old_account, Account *new_account) { int c = splits.count(); for(int i = 0; i < c; i++) { splits[i]->replaceAccount(old_account, new_account); } } double SplitTransaction::accountChange(Account *account, bool include_subs, bool convert) const { double v = 0.0; int c = splits.count(); for(int i = 0; i < c; i++) { v += splits[i]->accountChange(account, include_subs, convert); } return v; } bool SplitTransaction::isReconciled(AssetsAccount*) const { return b_reconciled; } void SplitTransaction::setReconciled(AssetsAccount*, bool is_reconciled) { b_reconciled = is_reconciled; } QString SplitTransaction::tagsText(bool include_child) const { if(!include_child) return Transactions::tagsText(); QString tagstr = Transactions::tagsText(); int c = count(); for(int i = 0; i < c; i++) { QString str = at(i)->tagsText(false); if(!str.isEmpty()) { if(!tagstr.isEmpty()) tagstr += ", "; tagstr += str; } } return tagstr; } const QString &SplitTransaction::payee() const {return emptystr;} QString SplitTransaction::payeeText() const { QVector::size_type c = splits.count(); if(c == 0) return payee(); QStringList payee_list; if(!payee().isEmpty()) payee_list << payee(); for(int i = 0; i < c; i++) { if(!splits[i]->payee().isEmpty() && !payee_list.contains(splits[i]->payee(), Qt::CaseInsensitive)) payee_list << splits[i]->payee(); } if(payee_list.isEmpty()) return QString(); if(payee_list.count() == 1) return payee_list.first(); QString payee_string = payee_list.first(); for(int i = 1; i < payee_list.count(); i++) { payee_string += " / "; payee_string += payee_list[i]; } return payee_string; } void SplitTransaction::splitTags() { int c = count(); for(int i2 = 0; i2 < tags.count(); i2++) { for(int i = 0; i < c; i++) { at(i)->addTag(tags[i2]); } } clearTags(); } void SplitTransaction::joinTags() { int c = count(); if(c == 0) return; for(int i2 = 0; i2 < at(0)->tagsCount(false);) { bool b = true; for(int i = 1; i < c; i++) { if(!at(i)->hasTag(at(0)->getTag(i2, false), false)) { b = false; break; } } if(b) { QString tag = at(0)->getTag(i2, false); addTag(tag); for(int i = 0; i < c; i++) { at(i)->removeTag(tag); } } else { i2++; } } } void SplitTransaction::splitLinks() { int c = count(); for(int i2 = 0; i2 < links.count(); i2++) { for(int i = 0; i < c; i++) { at(i)->addLinkId(links[i2]); } } clearLinks(); } void SplitTransaction::joinLinks() { int c = count(); if(c == 0) return; for(int i2 = 0; i2 < at(0)->linksCount(false);) { bool b = true; for(int i = 1; i < c; i++) { if(!at(i)->hasLinkId(at(0)->getLinkId(i2, false), false)) { b = false; break; } } if(b) { qlonglong lid = at(0)->getLinkId(i2, false); addLinkId(lid); for(int i = 0; i < c; i++) { at(i)->removeLinkId(lid); } } else { i2++; } } } MultiItemTransaction::MultiItemTransaction(Budget *parent_budget, QDate initial_date, AssetsAccount *initial_account, QString initial_description) : SplitTransaction(parent_budget, initial_date, initial_description), o_account(initial_account) {} MultiItemTransaction::MultiItemTransaction(Budget *parent_budget, QXmlStreamReader *xml, bool *valid) : SplitTransaction(parent_budget) { QXmlStreamAttributes attr = xml->attributes(); readAttributes(&attr, valid); readElements(xml, valid); if(s_payee.isEmpty()) { QVector::size_type c = splits.count(); for(QVector::size_type i = 0; i < c; i++) { Transaction *trans = splits[i]; switch(trans->type()) { case TRANSACTION_TYPE_EXPENSE: { if(s_payee.isEmpty()) s_payee = ((Expense*) trans)->payee(); else if(s_payee != ((Expense*) trans)->payee()) s_payee = ""; break; } case TRANSACTION_TYPE_INCOME: { if(s_payee.isEmpty()) s_payee = ((Income*) trans)->payer(); else if(s_payee != ((Income*) trans)->payer()) s_payee = ""; break; } default: { s_payee = ""; break; } } if(s_payee.isEmpty()) break; } } if(valid && splits.count() == 0) *valid = false; } MultiItemTransaction::MultiItemTransaction(const MultiItemTransaction *split) : SplitTransaction(split), o_account(split->account()), s_payee(split->payee()) { b_reconciled = split->isReconciled(split->account()); } MultiItemTransaction::MultiItemTransaction(Budget *parent_budget) : SplitTransaction(parent_budget), o_account(NULL) {} MultiItemTransaction::MultiItemTransaction() : SplitTransaction(), o_account(NULL) {} MultiItemTransaction::~MultiItemTransaction() {} SplitTransaction *MultiItemTransaction::copy() const {return new MultiItemTransaction(this);} void MultiItemTransaction::set(const Transactions *trans) { SplitTransaction::set(trans); if(trans->generaltype() == generaltype() && ((SplitTransaction*) trans)->type() == type()) { o_account = ((MultiItemTransaction*) trans)->account(); s_payee = ((MultiItemTransaction*) trans)->payee(); b_reconciled = ((MultiItemTransaction*) trans)->isReconciled(o_account); } } void MultiItemTransaction::readAttributes(QXmlStreamAttributes *attr, bool *valid) { o_account = NULL; SplitTransaction::readAttributes(attr, valid); s_payee = attr->value("payee").trimmed().toString(); qlonglong id = attr->value("account").toLongLong(); if(d_date.isValid() && budget()->assetsAccounts_id.contains(id)) { o_account = budget()->assetsAccounts_id[id]; } else { if(valid) *valid = false; } } bool MultiItemTransaction::readElement(QXmlStreamReader *xml, bool*) { if(!o_account) return false; if(xml->name() == XML_COMPARE_CONST_CHAR("transaction")) { QString id; for(QHash::iterator it = o_budget->assetsAccounts_id.begin(); it != o_budget->assetsAccounts_id.end(); ++it) { if(it.value() == o_account) { id = QString::number(it.key()); break; } } if(id.isEmpty()) id = QString::number(o_account->id()); QXmlStreamAttributes attr = xml->attributes(); #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) QStringView type = attr.value("type"); #else QStringRef type = attr.value("type"); #endif if(type.isEmpty()) { QXmlStreamAttributes attr = xml->attributes(); if(attr.hasAttribute("shares") && attr.hasAttribute("security")) { if(attr.hasAttribute("cost")) attr.append("type", "security_buy"); else if(attr.hasAttribute("income")) attr.append("type", "security_sell"); } else if(attr.hasAttribute("cost") || (attr.hasAttribute("category") && budget()->expensesAccounts_id.contains(attr.value("category").toLongLong()))) { attr.append("type", "expense"); } else if(attr.hasAttribute("income") || attr.hasAttribute("category")) { attr.append("type", "income"); } else if(attr.hasAttribute("amount") || attr.hasAttribute("withdrawal")) { attr.append("type", "transfer"); } else if(attr.hasAttribute("from")) { qlonglong id_from = attr.value("from").toLongLong(); if(budget()->incomesAccounts_id.contains(id_from)) attr.append("type", "income"); else if(budget()->assetsAccounts_id.contains(id_from)) attr.append("type", "transfer"); } else if(attr.hasAttribute("to")) { qlonglong id_to = attr.value("to").toLongLong(); if(budget()->expensesAccounts_id.contains(id_to)) attr.append("type", "expense"); else if(budget()->assetsAccounts_id.contains(id_to)) attr.append("type", "transfer"); } type = attr.value("type"); } attr.append("date", d_date.toString(Qt::ISODate)); bool valid2 = true; bool is_dividend = false; Transaction *trans = NULL; if(type == XML_COMPARE_CONST_CHAR("expense") || type == XML_COMPARE_CONST_CHAR("refund")) { attr.append("from", id); if(!s_payee.isEmpty() && !attr.hasAttribute("payee")) attr.append("payee", s_payee); trans = new Expense(budget()); } else if(type == XML_COMPARE_CONST_CHAR("income") || type == XML_COMPARE_CONST_CHAR("repayment")) { attr.append("to", id); if(!s_payee.isEmpty() && !attr.hasAttribute("payer")) attr.append("payer", s_payee); trans = new Income(budget()); } else if(type == XML_COMPARE_CONST_CHAR("dividend")) { attr.append("to", id); trans = new Income(budget()); is_dividend = true; } else if(type == XML_COMPARE_CONST_CHAR("balancing")) { attr.append("account", id); trans = new Balancing(budget()); } else if(type == XML_COMPARE_CONST_CHAR("transfer")) { if(attr.hasAttribute("to")) attr.append("from", id); else attr.append("to", id); trans = new Transfer(budget()); } else if(type == XML_COMPARE_CONST_CHAR("security_buy")) { attr.append("account", id); trans = new SecurityBuy(budget()); } else if(type == XML_COMPARE_CONST_CHAR("security_sell")) { attr.append("account", id); trans = new SecuritySell(budget()); } if(trans) { trans->readAttributes(&attr, &valid2); trans->readElements(xml, &valid2); if(is_dividend && !((Income*) trans)->security()) valid2 = false; if(!valid2) { delete trans; trans = NULL; } if(trans) { trans->setParentSplit(this); splits.push_back(trans); } return true; } } return false; } void MultiItemTransaction::writeAttributes(QXmlStreamAttributes *attr) { SplitTransaction::writeAttributes(attr); attr->append("account", QString::number(o_account->id())); if(!s_payee.isEmpty()) attr->append("payee", s_payee); } void remove_attributes(QXmlStreamAttributes *attr, QString s1, QString s2 = QString(), QString s3 = QString()) { bool b1 = false, b2 = false, b3 = false; if(s2.isEmpty()) b2 = true; if(s3.isEmpty()) b3 = true; for(int i = 0; i < attr->count(); i++) { if(!b1 && attr->at(i).name() == s1) { attr->remove(i); if(b2 && b3) break; b1 = true; i--; } else if(!b2 && attr->at(i).name() == s2) { attr->remove(i); if(b1 && b3) break; b2 = true; i--; } else if(!b3 && attr->at(i).name() == s3) { attr->remove(i); if(b1 && b2) break; b3 = true; i--; } } } void MultiItemTransaction::writeElements(QXmlStreamWriter *xml) { QVector::iterator it_end = splits.end(); for(QVector::iterator it = splits.begin(); it != it_end; ++it) { xml->writeStartElement("transaction"); Transaction *trans = *it; QXmlStreamAttributes attr; switch(trans->type()) { case TRANSACTION_TYPE_TRANSFER: { if(trans->fromAccount() == o_budget->balancingAccount) { attr.append("type", "balancing"); trans->writeAttributes(&attr); remove_attributes(&attr, "date", "account"); } else { attr.append("type", "transfer"); trans->writeAttributes(&attr); if(((Transfer*) trans)->from() == o_account) { remove_attributes(&attr, "date", "from"); } else { remove_attributes(&attr, "date", "to"); } } break; } case TRANSACTION_TYPE_INCOME: { if(((Income*) trans)->security()) { attr.append("type", "dividend"); } else { attr.append("type", "income"); } trans->writeAttributes(&attr); if(((Income*) trans)->payer() == s_payee) remove_attributes(&attr, "date", "to", "payer"); else remove_attributes(&attr, "date", "to"); break; } case TRANSACTION_TYPE_EXPENSE: { attr.append("type", "expense"); trans->writeAttributes(&attr); if(((Expense*) trans)->payee() == s_payee) remove_attributes(&attr, "date", "from", "payee"); else remove_attributes(&attr, "date", "from"); break; } case TRANSACTION_TYPE_SECURITY_BUY: { attr.append("type", "security_buy"); trans->writeAttributes(&attr); remove_attributes(&attr, "date", "account"); break; } case TRANSACTION_TYPE_SECURITY_SELL: { attr.append("type", "security_sell"); trans->writeAttributes(&attr); remove_attributes(&attr, "date", "account"); break; } default: {} } xml->writeAttributes(attr); trans->writeElements(xml); xml->writeEndElement(); } } double MultiItemTransaction::value(bool convert) const { double d_value = 0.0; QVector::size_type c = splits.size(); for(QVector::size_type i = 0; i < c; i++) { d_value += splits[i]->accountChange(o_account, false, convert); } return d_value; } Currency *MultiItemTransaction::currency() const { if(!o_account) return NULL; return o_account->currency(); } double MultiItemTransaction::quantity() const { double d_quantity = 0.0; QVector::size_type c = splits.size(); for(QVector::size_type i = 0; i < c; i++) { d_quantity += splits[i]->quantity(); } return d_quantity; } double MultiItemTransaction::cost(bool convert) const { double d_value = 0.0; QVector::size_type c = splits.size(); for(QVector::size_type i = 0; i < c; i++) { Transaction *trans = splits[i]; if(trans->type() == TRANSACTION_TYPE_INCOME) d_value -= trans->value(convert); if(trans->type() == TRANSACTION_TYPE_EXPENSE) d_value += trans->value(convert); } return d_value; } void MultiItemTransaction::addTransaction(Transaction *trans) { trans->setDate(d_date); switch(trans->type()) { case TRANSACTION_TYPE_EXPENSE: { ((Expense*) trans)->setFrom(o_account); if(((Expense*) trans)->payee().isEmpty()) ((Expense*) trans)->setPayee(s_payee); break; } case TRANSACTION_TYPE_INCOME: { ((Income*) trans)->setTo(o_account); if(((Income*) trans)->payer().isEmpty()) ((Income*) trans)->setPayer(s_payee); break; } case TRANSACTION_TYPE_TRANSFER: { if(((Transfer*) trans)->from() && ((Transfer*) trans)->to()) { if(((Transfer*) trans)->from() == o_account || ((Transfer*) trans)->to() == o_account) break; } if(!((Transfer*) trans)->from()) { ((Transfer*) trans)->setFrom(o_account); } else { ((Transfer*) trans)->setTo(o_account); } break; } case TRANSACTION_TYPE_SECURITY_BUY: {} case TRANSACTION_TYPE_SECURITY_SELL: { ((SecurityTransaction*) trans)->setAccount(o_account); break; } } for(int i = 0; i < trans->tagsCount(false);) { if(hasTag(trans->getTag(i, false), false)) { trans->removeTag(i); } else { i++; } } for(int i = 0; i < trans->linksCount(false);) { if(hasLinkId(trans->getLinkId(i, false), false)) { trans->removeLink(i); } else { i++; } } splits.push_back(trans); trans->setParentSplit(this); } AssetsAccount *MultiItemTransaction::account() const {return o_account;} void MultiItemTransaction::setAccount(AssetsAccount *new_account) { QVector::size_type c = splits.count(); for(QVector::size_type i = 0; i < c; i++) { Transaction *trans = splits[i]; switch(trans->type()) { case TRANSACTION_TYPE_EXPENSE: { ((Expense*) trans)->setFrom(new_account); break; } case TRANSACTION_TYPE_INCOME: { ((Income*) trans)->setTo(new_account); break; } case TRANSACTION_TYPE_TRANSFER: { if(((Transfer*) trans)->from() == o_account) { ((Transfer*) trans)->setFrom(new_account); } else { ((Transfer*) trans)->setTo(new_account); } break; } case TRANSACTION_TYPE_SECURITY_BUY: {} case TRANSACTION_TYPE_SECURITY_SELL: { ((SecurityTransaction*) trans)->setAccount(new_account); break; } } } o_account = new_account; } const QString &MultiItemTransaction::payee() const {return s_payee;} void MultiItemTransaction::setPayee(QString new_payee) { QVector::size_type c = splits.count(); for(QVector::size_type i = 0; i < c; i++) { Transaction *trans = splits[i]; switch(trans->type()) { case TRANSACTION_TYPE_EXPENSE: { if(((Expense*) trans)->payee() == s_payee) ((Expense*) trans)->setPayee(new_payee.trimmed()); break; } case TRANSACTION_TYPE_INCOME: { if(((Income*) trans)->payer() == s_payee) ((Income*) trans)->setPayer(new_payee.trimmed()); break; } default: {} } } s_payee = new_payee.trimmed(); } QString MultiItemTransaction::fromAccountsString() const { QVector::size_type c = splits.count(); if(c == 0) return ""; QList account_list; for(QVector::size_type i = 0; i < c; i++) { if(splits[i]->fromAccount() == o_account && !account_list.contains(splits[i]->toAccount())) account_list << splits[i]->toAccount(); if(splits[i]->toAccount() == o_account && !account_list.contains(splits[i]->fromAccount())) account_list << splits[i]->fromAccount(); } if(account_list.count() == 1) return account_list.first()->name(); QString account_string = account_list.first()->name(); for(int i = 1; i < account_list.size(); i++) { account_string += " / "; account_string += account_list[i]->name(); } return account_string; } int MultiItemTransaction::transactiontype() const { if(splits.count() == 0) return -1; TransactionType transtype = splits[0]->type(); for(int i = 1; i < splits.count(); i++) { if(splits[i]->type() != transtype) return -1; } return transtype; } SplitTransactionType MultiItemTransaction::type() const { return SPLIT_TRANSACTION_TYPE_MULTIPLE_ITEMS; } bool MultiItemTransaction::relatesToAccount(Account *account, bool include_subs, bool include_non_value) const { return (include_non_value && o_account == account) || SplitTransaction::relatesToAccount(account, include_subs, include_non_value); } void MultiItemTransaction::replaceAccount(Account *old_account, Account *new_account) { if(o_account == old_account && new_account->type() == ACCOUNT_TYPE_ASSETS) o_account = (AssetsAccount*) new_account; SplitTransaction::replaceAccount(old_account, new_account); } bool MultiItemTransaction::isReconciled(AssetsAccount *account) const { if(account == o_account) return b_reconciled; return false; } void MultiItemTransaction::setReconciled(AssetsAccount *account, bool is_reconciled) { if(account == o_account) b_reconciled = is_reconciled; } MultiAccountTransaction::MultiAccountTransaction(Budget *parent_budget, CategoryAccount *initial_category, QString initial_description) : SplitTransaction(parent_budget, QDate(), initial_description), o_category(initial_category), d_quantity(1.0) {} MultiAccountTransaction::MultiAccountTransaction(Budget *parent_budget, QXmlStreamReader *xml, bool *valid) : SplitTransaction(parent_budget), d_quantity(1.0) { QXmlStreamAttributes attr = xml->attributes(); readAttributes(&attr, valid); readElements(xml, valid); QVector::size_type c = splits.size(); for(QVector::size_type i = 0; i < c; i++) { if(i == 0) d_date = splits[i]->date(); else if(splits[i]->date() < d_date) d_date = splits[i]->date(); splits[i]->setQuantity(d_quantity / c); } if(valid && splits.count() == 0) *valid = false; } MultiAccountTransaction::MultiAccountTransaction() : SplitTransaction(), o_category(NULL) {} MultiAccountTransaction::MultiAccountTransaction(const MultiAccountTransaction *split) : SplitTransaction(split), o_category(split->category()), d_quantity(split->quantity()) {} MultiAccountTransaction::MultiAccountTransaction(Budget *parent_budget) : SplitTransaction(parent_budget), o_category(NULL), d_quantity(1.0) {} MultiAccountTransaction::~MultiAccountTransaction() {} SplitTransaction *MultiAccountTransaction::copy() const {return new MultiAccountTransaction(this);} void MultiAccountTransaction::set(const Transactions *trans) { SplitTransaction::set(trans); if(trans->generaltype() == generaltype() && ((SplitTransaction*) trans)->type() == type()) { o_category = ((MultiAccountTransaction*) trans)->category(); d_quantity = ((MultiAccountTransaction*) trans)->quantity(); } } void MultiAccountTransaction::readAttributes(QXmlStreamAttributes *attr, bool *valid) { o_category = NULL; SplitTransaction::readAttributes(attr, valid); qlonglong id = attr->value("category").toLongLong(); if(budget()->expensesAccounts_id.contains(id)) { o_category = budget()->expensesAccounts_id[id]; } else if(budget()->incomesAccounts_id.contains(id)) { o_category = budget()->incomesAccounts_id[id]; } else { if(valid) *valid = false; } if(attr->hasAttribute("quantity")) d_quantity = attr->value("quantity").toDouble(); else d_quantity = 1.0; } bool MultiAccountTransaction::readElement(QXmlStreamReader *xml, bool*) { if(!o_category) return false; if(xml->name() == XML_COMPARE_CONST_CHAR("transaction")) { QXmlStreamAttributes attr = xml->attributes(); #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) QStringView type = attr.value("type"); #else QStringRef type = attr.value("type"); #endif QString id; if(type == XML_COMPARE_CONST_CHAR("income")) { for(QHash::iterator it = o_budget->incomesAccounts_id.begin(); it != o_budget->incomesAccounts_id.end(); ++it) { if(it.value() == o_category) { id = QString::number(it.key()); break; } } } else { for(QHash::iterator it = o_budget->expensesAccounts_id.begin(); it != o_budget->expensesAccounts_id.end(); ++it) { if(it.value() == o_category) { id = QString::number(it.key()); break; } } } if(id.isEmpty()) id = QString::number(o_category->id()); bool valid2 = true; Transaction *trans = NULL; if(o_category->type() == ACCOUNT_TYPE_EXPENSES && type == XML_COMPARE_CONST_CHAR("expense")) { attr.append("category", id); attr.append("description", s_description); trans = new Expense(budget()); } else if(o_category->type() == ACCOUNT_TYPE_INCOMES && type == XML_COMPARE_CONST_CHAR("income")) { attr.append("category", id); attr.append("description", s_description); trans = new Income(budget()); } if(trans) { trans->readAttributes(&attr, &valid2); trans->readElements(xml, &valid2); if(!valid2) { delete trans; trans = NULL; } if(trans) { trans->setParentSplit(this); splits.push_back(trans); } return true; } } return false; } void MultiAccountTransaction::writeAttributes(QXmlStreamAttributes *attr) { if(d_date.isValid()) attr->append("date", d_date.toString(Qt::ISODate)); write_id(attr, i_id, i_first_revision, i_last_revision); if(!s_description.isEmpty()) attr->append("description", s_description); if(!tags.isEmpty()) attr->append("tags", writeTags(false)); if(!links.isEmpty()) attr->append("links", writeLinks(false)); if(!s_comment.isEmpty()) attr->append("comment", s_comment); attr->append("category", QString::number(o_category->id())); if(d_quantity != 1.0) attr->append("quantity", QString::number(d_quantity, 'f', QUANTITY_DECIMAL_PLACES)); if(i_time != 0) attr->append("timestamp", QString::number(i_time)); if(!s_file.isEmpty()) attr->append("file", s_file); if(b_reconciled) attr->append("reconciled", QString::number(b_reconciled)); } void MultiAccountTransaction::writeElements(QXmlStreamWriter *xml) { QVector::iterator it_end = splits.end(); for(QVector::iterator it = splits.begin(); it != it_end; ++it) { xml->writeStartElement("transaction"); Transaction *trans = *it; QXmlStreamAttributes attr; if(trans->type() == TRANSACTION_TYPE_INCOME) { attr.append("type", "income"); } else { attr.append("type", "expense"); } trans->writeAttributes(&attr); remove_attributes(&attr, "description", "category", "quantity"); xml->writeAttributes(attr); trans->writeElements(xml); xml->writeEndElement(); } } double MultiAccountTransaction::value(bool convert) const { double d_value = 0.0; Currency *cur = currency(); QVector::size_type c = splits.size(); for(QVector::size_type i = 0; i < c; i++) { Transaction *trans = splits[i]; if(!convert && cur != trans->currency()) { if(budget()->defaultTransactionConversionRateDate() == TRANSACTION_CONVERSION_RATE_AT_DATE) d_value += cur->convertFrom(trans->value(), trans->currency(), trans->date()); else d_value += cur->convertFrom(trans->value(), trans->currency()); } else { d_value += trans->value(convert); } } return d_value; } Currency *MultiAccountTransaction::currency() const { if(splits.isEmpty()) return budget()->defaultCurrency(); Currency *cur = splits[0]->currency(); if(cur != budget()->defaultCurrency()) { for(QVector::size_type i = 1; i < splits.size(); i++) { if(splits[i]->currency() == budget()->defaultCurrency()) return budget()->defaultCurrency(); } } return cur; } double MultiAccountTransaction::quantity() const {return d_quantity;} void MultiAccountTransaction::setQuantity(double new_quantity) { d_quantity = new_quantity; QVector::size_type c = splits.size(); for(QVector::size_type i = 0; i < c; i++) { splits[i]->setQuantity(d_quantity / c); } } double MultiAccountTransaction::cost(bool convert) const { if(o_category->type() == ACCOUNT_TYPE_INCOMES) return -value(convert); return value(convert); } void MultiAccountTransaction::addTransaction(Transaction *trans) { if(o_category->type() == ACCOUNT_TYPE_EXPENSES && trans->type() == TRANSACTION_TYPE_EXPENSE) { if(!d_date.isValid() || trans->date() < d_date) d_date = trans->date(); ((Expense*) trans)->setCategory((ExpensesAccount*) o_category); splits.push_back(trans); trans->setParentSplit(this); } else if(o_category->type() == ACCOUNT_TYPE_INCOMES && trans->type() == TRANSACTION_TYPE_INCOME) { if(!d_date.isValid() || trans->date() < d_date) d_date = trans->date(); ((Income*) trans)->setCategory((IncomesAccount*) o_category); splits.push_back(trans); trans->setParentSplit(this); } trans->setDescription(s_description); QVector::size_type c = splits.size(); for(QVector::size_type i = 0; i < c; i++) { splits[i]->setQuantity(d_quantity / c); } } CategoryAccount *MultiAccountTransaction::category() const {return o_category;} void MultiAccountTransaction::setCategory(CategoryAccount *new_category) { QVector::size_type c = splits.count(); for(QVector::size_type i = 0; i < c; i++) { Transaction *trans = splits[i]; if(trans->type() == TRANSACTION_TYPE_EXPENSE) { ((Expense*) trans)->setCategory((ExpensesAccount*) new_category); } else if(trans->type() == TRANSACTION_TYPE_INCOME) { ((Income*) trans)->setCategory((IncomesAccount*) new_category); } } o_category = new_category; } AssetsAccount *MultiAccountTransaction::account() const { QVector::size_type c = splits.count(); if(c == 0) return NULL; if(splits[0]->type() == TRANSACTION_TYPE_EXPENSE) { AssetsAccount *acc = (AssetsAccount*) splits[0]->fromAccount(); for(QVector::size_type i = 1; i < c; i++) { if(splits[i]->fromAccount() != acc) return NULL; } return acc; } else { AssetsAccount *acc = (AssetsAccount*) splits[0]->toAccount(); for(QVector::size_type i = 1; i < c; i++) { if(splits[i]->toAccount() != acc) return NULL; } return acc; } } QString MultiAccountTransaction::accountsString() const { QVector::size_type c = splits.count(); if(c == 0) return ""; QList account_list; if(splits[0]->type() == TRANSACTION_TYPE_EXPENSE) { for(QVector::size_type i = 0; i < c; i++) { if(!account_list.contains(splits[i]->fromAccount())) account_list << splits[i]->fromAccount(); } } else { for(QVector::size_type i = 0; i < c; i++) { if(!account_list.contains(splits[i]->toAccount())) account_list << splits[i]->toAccount(); } } if(account_list.count() == 1) return account_list.first()->name(); QString account_string = account_list.first()->name(); for(int i = 1; i < account_list.size(); i++) { account_string += " / "; account_string += account_list[i]->name(); } return account_string; } void MultiAccountTransaction::setDescription(QString new_description) { QVector::size_type c = splits.count(); for(QVector::size_type i = 0; i < c; i++) { splits[i]->setDescription(new_description); } s_description = new_description; } SplitTransactionType MultiAccountTransaction::type() const { return SPLIT_TRANSACTION_TYPE_MULTIPLE_ACCOUNTS; } TransactionType MultiAccountTransaction::transactiontype() const { if(o_category->type() == ACCOUNT_TYPE_INCOMES) return TRANSACTION_TYPE_INCOME; return TRANSACTION_TYPE_EXPENSE; } bool MultiAccountTransaction::isIncomesAndExpenses() const {return true;} bool MultiAccountTransaction::relatesToAccount(Account *account, bool include_subs, bool include_non_value) const { return (include_non_value && o_category && (o_category == account || (include_subs && o_category->topAccount() == account))) || SplitTransaction::relatesToAccount(account, include_subs, include_non_value); } void MultiAccountTransaction::replaceAccount(Account *old_account, Account *new_account) { if(o_category == old_account && (new_account->type() == ACCOUNT_TYPE_INCOMES || new_account->type() == ACCOUNT_TYPE_EXPENSES)) o_category = (CategoryAccount*) new_account; if(new_account->type() == ACCOUNT_TYPE_ASSETS && ((AssetsAccount*) new_account)->currency() != currency()) return; SplitTransaction::replaceAccount(old_account, new_account); } DebtPayment::DebtPayment(Budget *parent_budget, QDate initial_date, AssetsAccount *initial_loan, AssetsAccount *initial_account) : SplitTransaction(parent_budget, initial_date), o_loan(initial_loan), o_fee(NULL), o_interest(NULL), o_payment(NULL), o_account(initial_account) {} DebtPayment::DebtPayment(Budget *parent_budget, QXmlStreamReader *xml, bool *valid) : SplitTransaction(parent_budget), o_loan(NULL), o_fee(NULL), o_interest(NULL), o_payment(NULL), o_account(NULL) { QXmlStreamAttributes attr = xml->attributes(); readAttributes(&attr, valid); readElements(xml, valid); } DebtPayment::DebtPayment(const DebtPayment *split) : SplitTransaction(split), o_loan(split->loan()), o_fee(NULL), o_interest(NULL), o_payment(NULL), o_account(split->account()) { if(split->fee() != 0.0) setFee(split->fee()); if(split->interest() != 0.0) setInterest(split->interest(), split->interestPaid()); if(split->payment() != 0.0) setPayment(split->payment(), split->reduction()); setExpenseCategory(split->expenseCategory()); b_reconciled = split->isReconciled(split->account()); } DebtPayment::DebtPayment(Budget *parent_budget) : SplitTransaction(parent_budget), o_loan(NULL), o_fee(NULL), o_interest(NULL), o_payment(NULL), o_account(NULL) {} DebtPayment::DebtPayment() : SplitTransaction(), o_loan(NULL), o_fee(NULL), o_interest(NULL), o_payment(NULL), o_account(NULL) {} DebtPayment::~DebtPayment() {} SplitTransaction *DebtPayment::copy() const {return new DebtPayment(this);} void DebtPayment::set(const Transactions *trans) { SplitTransaction::set(trans); if(trans->generaltype() == generaltype() && ((SplitTransaction*) trans)->type() == type()) { DebtPayment *split = (DebtPayment*) trans; o_account = split->account(); if(split->fee() != 0.0) setFee(split->fee()); if(split->interest() != 0.0) setInterest(split->interest(), split->interestPaid()); if(split->payment() != 0.0) setPayment(split->payment(), split->reduction()); setExpenseCategory(split->expenseCategory()); b_reconciled = split->isReconciled(split->account()); } } double DebtPayment::value(bool convert) const {return interest(convert) + fee(convert) + payment(convert);} Currency *DebtPayment::currency() const { if(!o_loan) return NULL; return o_loan->currency(); } double DebtPayment::quantity() const { return 1.0; } double DebtPayment::cost(bool convert) const {return interest(convert) + fee(convert);} void DebtPayment::setInterest(double new_value, bool paid_from_account) { if(!o_interest) { if(new_value != 0.0) { o_interest = new DebtInterest(o_budget, new_value, d_date, o_fee ? o_fee->category() : NULL, paid_from_account ? o_account : o_loan, o_loan, QString(), id()); o_interest->setParentSplit(this); } } else { o_interest->setValue(new_value); } } void DebtPayment::setInterestPaid(bool paid_from_account) { if(o_interest) { if(paid_from_account) o_interest->setFrom(o_account); else o_interest->setFrom(o_loan); } } void DebtPayment::setFee(double new_value) { if(!o_fee) { if(new_value != 0.0) { o_fee = new DebtFee(o_budget, new_value, d_date, o_interest ? o_interest->category() : NULL, o_account, o_loan, QString(), id()); o_fee->setParentSplit(this); } } else { o_fee->setValue(new_value); } } void DebtPayment::setPayment(double new_value) { if(!o_payment) { if(new_value != 0.0) { o_payment = new DebtReduction(o_budget, new_value, d_date, o_account, o_loan, QString(), id()); o_payment->setParentSplit(this); } } else { o_payment->setValue(new_value); } } void DebtPayment::setPayment(double new_payment, double new_reduction) { if(!o_payment) { if(new_payment != 0.0 || new_reduction != 0.0) { o_payment = new DebtReduction(o_budget, new_payment, new_reduction, d_date, o_account, o_loan, QString(), id()); o_payment->setParentSplit(this); } } else { o_payment->setAmount(new_payment, new_reduction); } } double DebtPayment::interest(bool convert) const { if(o_interest) return o_interest->value(convert); return 0.0; } bool DebtPayment::interestPaid() const { return !o_interest || o_interest->from() != o_loan; } double DebtPayment::fee(bool convert) const { if(o_fee) return o_fee->value(convert); return 0.0; } double DebtPayment::payment(bool convert) const { if(o_payment) return o_payment->fromValue(convert); return 0.0; } double DebtPayment::reduction(bool convert) const { if(o_payment) return o_payment->toValue(convert); return 0.0; } DebtFee *DebtPayment::feeTransaction() const {return o_fee;} DebtInterest *DebtPayment::interestTransaction() const {return o_interest;} DebtReduction *DebtPayment::paymentTransaction() const {return o_payment;} void DebtPayment::clear(bool keep) { if(o_fee) { o_fee->setParentSplit(NULL); if(!keep) o_budget->removeTransaction(o_fee); o_fee = NULL; } if(o_interest) { o_interest->setParentSplit(NULL); if(!keep) o_budget->removeTransaction(o_interest); o_interest = NULL; } if(o_payment) { o_payment->setParentSplit(NULL); if(!keep) o_budget->removeTransaction(o_payment); o_payment = NULL; } } void DebtPayment::readAttributes(QXmlStreamAttributes *attr, bool *valid) { SplitTransaction::readAttributes(attr, valid); o_loan = NULL; qlonglong loan_id = attr->value("debt").toLongLong(); if(budget()->assetsAccounts_id.contains(loan_id)) { o_loan = budget()->assetsAccounts_id[loan_id]; } else { if(valid) *valid = false; return; } if(attr->hasAttribute("from")) { qlonglong account_id = attr->value("from").toLongLong(); if(budget()->assetsAccounts_id.contains(account_id)) { o_account = budget()->assetsAccounts_id[account_id]; } else { if(valid) *valid = false; return; } } else { o_account = o_loan; } ExpensesAccount *cat = NULL; if(attr->hasAttribute("expensecategory")) { qlonglong category_id = attr->value("expensecategory").toLongLong(); if(budget()->expensesAccounts_id.contains(category_id)) { cat = budget()->expensesAccounts_id[category_id]; } } if(attr->hasAttribute("reduction")) { if(attr->hasAttribute("payment")) { o_payment = new DebtReduction(o_budget, attr->value("payment").toDouble(), attr->value("reduction").toDouble(), d_date, o_account, o_loan, QString(), id()); } else { o_payment = new DebtReduction(o_budget, attr->value("reduction").toDouble(), d_date, o_account, o_loan, QString(), id()); } o_payment->setParentSplit(this); } if(attr->hasAttribute("interest")) { bool interest_paid = true; if(attr->hasAttribute("interestpaid")) interest_paid = attr->value("interestpaid").toInt(); else if(attr->hasAttribute("interestpayed")) interest_paid = attr->value("interestpayed").toInt(); o_interest = new DebtInterest(o_budget, attr->value("interest").toDouble(), d_date, cat, interest_paid ? o_account : o_loan, o_loan, QString(), id()); o_interest->setParentSplit(this); if(valid && !cat) *valid = false; } if(attr->hasAttribute("fee")) { o_fee = new DebtFee(o_budget, attr->value("fee").toDouble(), d_date, cat, o_account, o_loan, QString(), id()); o_fee->setParentSplit(this); if(valid && !cat) *valid = false; } if(valid && !o_fee && !o_interest && !o_payment) *valid = false; } bool DebtPayment::readElement(QXmlStreamReader*, bool*) { return false; } void DebtPayment::writeAttributes(QXmlStreamAttributes *attr) { SplitTransaction::writeAttributes(attr); attr->append("debt", QString::number(o_loan->id())); if(o_account && o_account != o_loan && (o_payment || o_fee || (o_interest && o_interest->from() != o_loan))) { attr->append("from", QString::number(o_account->id())); if(o_interest && o_interest->from() == o_loan) { attr->append("interestpaid", QString::number(false)); } } if(expenseCategory()) attr->append("expensecategory", QString::number(expenseCategory()->id())); if(o_payment) { attr->append("reduction", QString::number(o_payment->toValue(), 'f', SAVE_MONETARY_DECIMAL_PLACES)); if(o_payment->toValue() != o_payment->fromValue()) attr->append("payment", QString::number(o_payment->fromValue(), 'f', SAVE_MONETARY_DECIMAL_PLACES)); } if(o_interest) attr->append("interest", QString::number(o_interest->value(), 'f', SAVE_MONETARY_DECIMAL_PLACES)); if(o_fee) attr->append("fee", QString::number(o_fee->value(), 'f', SAVE_MONETARY_DECIMAL_PLACES)); } void DebtPayment::writeElements(QXmlStreamWriter*) {} AssetsAccount *DebtPayment::loan() const {return o_loan;} void DebtPayment::setLoan(AssetsAccount *new_loan) { if(o_fee) o_fee->setLoan(new_loan); if(o_interest) o_interest->setLoan(new_loan); if(o_payment) o_payment->setLoan(new_loan); o_loan = new_loan; } ExpensesAccount *DebtPayment::expenseCategory() const { if(o_interest) return o_interest->category(); else if(o_fee) return o_fee->category(); return NULL; } void DebtPayment::setExpenseCategory(ExpensesAccount *new_category) { if(o_interest) o_interest->setCategory(new_category); if(o_fee) o_fee->setCategory(new_category); } AssetsAccount *DebtPayment::account() const {return o_account;} void DebtPayment::setAccount(AssetsAccount *new_account) { if(o_fee) o_fee->setFrom(new_account); if(o_interest) o_interest->setFrom(new_account); if(o_payment) o_payment->setFrom(new_account); o_account = new_account; } void DebtPayment::setDate(QDate new_date) { if(new_date != d_date) { QDate old_date = d_date; d_date = new_date; o_budget->splitTransactionSortModified(this); o_budget->splitTransactionDateModified(this, old_date); } if(o_fee) o_fee->setDate(d_date); if(o_interest) o_interest->setDate(d_date); if(o_payment) o_payment->setDate(d_date); } void DebtPayment::setId(qlonglong new_id) { SplitTransaction::setId(new_id); if(o_fee) o_fee->setId(new_id); if(o_interest) o_interest->setId(new_id); if(o_payment) o_payment->setId(new_id); } QString DebtPayment::description() const { return tr("Debt payment: %1").arg(o_loan->name()); } SplitTransactionType DebtPayment::type() const { return SPLIT_TRANSACTION_TYPE_LOAN; } bool DebtPayment::isIncomesAndExpenses() const {return true;} int DebtPayment::count() const { int c = 0; if(o_fee) c++; if(o_interest) c++; if(o_payment) c++; return c; } Transaction *DebtPayment::operator[] (int index) const { return at(index); } Transaction *DebtPayment::at(int index) const { if(index == 0) { if(o_payment) return o_payment; if(o_interest) return o_interest; return o_fee; } if(index == 1) { if(o_payment) { if(o_interest) return o_interest; return o_fee; } if(o_interest) return o_fee; return NULL; } if(index == 2 && o_payment && o_interest) return o_fee; return NULL; } void DebtPayment::removeTransaction(Transaction *trans, bool keep) { if(trans == o_interest) o_interest = NULL; else if(trans == o_fee) o_fee = NULL; else if(trans == o_payment) o_payment = NULL; trans->setParentSplit(NULL); o_budget->removeTransaction(trans, keep); } bool DebtPayment::relatesToAccount(Account *account, bool include_subs, bool include_non_value) const { return (include_non_value && (o_account == account || o_loan == account)) || (o_fee && o_fee->relatesToAccount(account, include_subs, include_non_value)) || (o_interest && o_interest->relatesToAccount(account, include_subs, include_non_value)) || (o_payment && o_payment->relatesToAccount(account, include_subs, include_non_value)); } void DebtPayment::replaceAccount(Account *old_account, Account *new_account) { if(new_account->type() == ACCOUNT_TYPE_ASSETS && ((AssetsAccount*) new_account)->currency() != currency()) return; if(o_account == old_account && new_account->type() == ACCOUNT_TYPE_ASSETS) o_account = (AssetsAccount*) new_account; if(o_loan == old_account && new_account->type() == ACCOUNT_TYPE_ASSETS) o_loan = (AssetsAccount*) new_account; if(o_fee) o_fee->replaceAccount(old_account, new_account); if(o_interest) o_interest->replaceAccount(old_account, new_account); if(o_payment) o_payment->replaceAccount(old_account, new_account); } double DebtPayment::accountChange(Account *account, bool include_subs, bool convert) const { double v = 0.0; if(o_fee) v += o_fee->accountChange(account, include_subs, convert); if(o_interest) v += o_interest->accountChange(account, include_subs, convert); if(o_payment) v += o_payment->accountChange(account, include_subs, convert); return v; } bool DebtPayment::isReconciled(AssetsAccount *account) const { if(account == o_account) return b_reconciled; return false; } void DebtPayment::setReconciled(AssetsAccount *account, bool is_reconciled) { if(account == o_account) b_reconciled = is_reconciled; } SecurityTrade::SecurityTrade(Budget *budget, QXmlStreamReader *xml, bool *valid) { QXmlStreamAttributes attr = xml->attributes(); date = QDate::fromString(attr.value("date").toString(), Qt::ISODate); from_shares = attr.value("from_shares").toDouble(); to_shares = attr.value("to_shares").toDouble(); int from_id = attr.value("from_security").toInt(); int to_id = attr.value("to_security").toInt(); timestamp = attr.value("timestamp").toLongLong(); read_id(&attr, id, first_revision, last_revision); if(budget->securities_id.contains(from_id)) { from_security = budget->securities_id[from_id]; } else { from_security = NULL; } if(budget->securities_id.contains(to_id)) { to_security = budget->securities_id[to_id]; } else { to_security = NULL; } if(valid && (!date.isValid() || !from_security || !to_security || from_security == to_security)) *valid = false; } void SecurityTrade::save(QXmlStreamWriter *xml) { xml->writeAttribute("from_security", QString::number(from_security->id())); xml->writeAttribute("to_security", QString::number(to_security->id())); xml->writeAttribute("date", date.toString(Qt::ISODate)); write_id(xml, id, first_revision, last_revision); xml->writeAttribute("timestamp", QString::number(timestamp)); xml->writeAttribute("from_shares", QString::number(from_shares, 'f', from_security->decimals())); xml->writeAttribute("to_shares", QString::number(to_shares, 'f', to_security->decimals())); } Eqonomize-1.5.3/src/transaction.h000066400000000000000000001110421416454732000167600ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016-2020 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifndef TRANSACTION_H #define TRANSACTION_H #include #include #include #include #include class QXmlStreamReader; class QXmlStreamWriter; class QXmlStreamAttributes; class Account; class AssetsAccount; class CategoryAccount; class Budget; class ExpensesAccount; class IncomesAccount; class Recurrence; class ScheduledTransaction; class Security; class SplitTransaction; class Currency; typedef enum { TRANSACTION_TYPE_EXPENSE, TRANSACTION_TYPE_INCOME, TRANSACTION_TYPE_TRANSFER, TRANSACTION_TYPE_SECURITY_BUY, TRANSACTION_TYPE_SECURITY_SELL } TransactionType; typedef enum { TRANSACTION_SUBTYPE_EXPENSE = 100, TRANSACTION_SUBTYPE_INCOME = 101, TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND = 102, TRANSACTION_SUBTYPE_TRANSFER = 103, TRANSACTION_SUBTYPE_SECURITY_BUY = 104, TRANSACTION_SUBTYPE_SECURITY_SELL = 105, TRANSACTION_SUBTYPE_DEBT_REDUCTION = 106, TRANSACTION_SUBTYPE_DEBT_INTEREST = 107, TRANSACTION_SUBTYPE_DEBT_FEE = 108, TRANSACTION_SUBTYPE_BALANCING = 109 } TransactionSubType; typedef enum { SPLIT_TRANSACTION_TYPE_MULTIPLE_ITEMS, SPLIT_TRANSACTION_TYPE_MULTIPLE_ACCOUNTS, SPLIT_TRANSACTION_TYPE_LOAN } SplitTransactionType; typedef enum { GENERAL_TRANSACTION_TYPE_SINGLE, GENERAL_TRANSACTION_TYPE_SPLIT, GENERAL_TRANSACTION_TYPE_SCHEDULE } GeneralTransactionType; class Transactions { Q_DECLARE_TR_FUNCTIONS(Transactions) protected: qlonglong i_id; int i_first_revision, i_last_revision; Budget *o_budget; QStringList tags; QList links; public: Transactions(Budget *parent_budget); Transactions(const Transactions *trans); Transactions(); virtual ~Transactions() {} virtual Transactions *copy() const = 0; virtual void set(const Transactions *trans); virtual bool equals(const Transactions *transaction, bool strict_comparison = true) const = 0; virtual double value(bool convert = false) const = 0; virtual Currency *currency() const = 0; virtual QString valueString(int precision = -1) const; virtual QString valueString(double value_, int precision = -1) const; virtual double quantity() const = 0; virtual const QDate &date() const = 0; virtual const qint64 ×tamp() const = 0; virtual void setTimestamp(qint64 cr_time) = 0; virtual void setTimestamp(); virtual void setDate(QDate new_date) = 0; virtual QString description() const = 0; virtual const QString &comment() const = 0; virtual const QString &associatedFile() const = 0; virtual void setAssociatedFile(QString new_attachment) = 0; Budget *budget() const; virtual GeneralTransactionType generaltype() const = 0; virtual bool relatesToAccount(Account *account, bool include_subs = true, bool include_non_value = false) const = 0; virtual void replaceAccount(Account *old_account, Account *new_account) = 0; virtual double accountChange(Account *account, bool include_subs = true, bool convert = false) const = 0; virtual bool isReconciled(AssetsAccount *account) const = 0; virtual void setReconciled(AssetsAccount *account, bool is_reconciled) = 0; qlonglong id() const; virtual void setId(qlonglong new_id); int firstRevision() const; void setFirstRevision(int new_rev); int lastRevision() const; void setLastRevision(int new_rev); bool isModified() const; void setModified(); virtual void addTag(QString tag); virtual bool removeTag(QString tag); virtual void removeTag(int index); virtual bool hasTag(const QString &tag, bool include_parent = true, bool case_insensitive = false) const; virtual const QString &getTag(int index, bool include_parent = false) const; virtual QString tagsText(bool include_parent_child = true) const; virtual void clearTags(); virtual int tagsCount(bool include_parent = false) const; virtual void readTags(const QString &text); virtual QString writeTags(bool include_parent = false) const; virtual QString payeeText() const = 0; virtual const QString &payee() const = 0; virtual int linksCount(bool include_parent = false) const; virtual qlonglong getLinkId(int index, bool include_parent = false) const; Transactions *getLink(int index, bool include_parent = false) const; virtual void clearLinks(); void addLink(Transactions *trans); virtual void addLinkId(qlonglong lid); virtual void removeLink(int index); bool removeLink(Transactions *trans); virtual bool removeLinkId(qlonglong lid); virtual bool hasLinkId(qlonglong lid, bool include_parent = true) const; bool hasLink(Transactions *trans, bool include_parent = true) const; virtual void readLinks(const QString &text); virtual QString writeLinks(bool include_parent = false) const; }; class Transaction : public Transactions { Q_DECLARE_TR_FUNCTIONS(Transaction) protected: double d_value; QDate d_date; Account *o_from; Account *o_to; QString s_description; QString s_comment; QString s_file; double d_quantity; SplitTransaction *o_split; qint64 i_time; public: Transaction(Budget *parent_budget, double initial_value, QDate initial_date, Account *from, Account *to, QString initial_description = QString(), QString initial_comment = QString(), qlonglong initial_id = -1); Transaction(Budget *parent_budget, QXmlStreamReader *xml, bool *valid); Transaction(Budget *parent_budget); Transaction(); Transaction(const Transaction *transaction); virtual ~Transaction(); virtual Transaction *copy() const = 0; virtual void set(const Transactions *trans); virtual bool equals(const Transactions *transaction, bool strict_comparison = true) const; virtual void readAttributes(QXmlStreamAttributes *attr, bool *valid); virtual bool readElement(QXmlStreamReader *xml, bool *valid); virtual bool readElements(QXmlStreamReader *xml, bool *valid); virtual void save(QXmlStreamWriter *xml); virtual void writeAttributes(QXmlStreamAttributes *attr); virtual void writeElements(QXmlStreamWriter *xml); SplitTransaction *parentSplit() const; void setParentSplit(SplitTransaction *parent); virtual double value(bool convert = false) const; virtual double fromValue(bool convert = false) const; virtual double toValue(bool convert = false) const; virtual Currency *currency() const; virtual Currency *fromCurrency() const; virtual Currency *toCurrency() const; virtual void setValue(double new_value); virtual double quantity() const; void setQuantity(double new_quantity); const QDate &date() const; void setDate(QDate new_date); const qint64 ×tamp() const; void setTimestamp(qint64 cr_time); virtual QString description() const; void setDescription(QString new_description); virtual const QString &comment() const; void setComment(QString new_comment); const QString &associatedFile() const; void setAssociatedFile(QString new_attachment); virtual Account *fromAccount() const; void setFromAccount(Account *new_from); virtual Account *toAccount() const; void setToAccount(Account *new_to); virtual GeneralTransactionType generaltype() const; virtual TransactionType type() const = 0; virtual TransactionSubType subtype() const; virtual bool relatesToAccount(Account *account, bool include_subs = true, bool include_non_value = false) const; virtual void replaceAccount(Account *old_account, Account *new_account); virtual double accountChange(Account *account, bool include_subs = true, bool convert = false) const; virtual bool isReconciled(AssetsAccount *account) const = 0; virtual void setReconciled(AssetsAccount *account, bool is_reconciled) = 0; virtual bool hasTag(const QString &tag, bool include_parent = true, bool case_insensitive = false) const; virtual QString tagsText(bool include_parent = true) const; virtual const QString &getTag(int index, bool include_parent = false) const; virtual int tagsCount(bool include_parent = false) const; virtual QString writeTags(bool include_parent = false) const; virtual int linksCount(bool include_parent = false) const; virtual qlonglong getLinkId(int index, bool include_parent = false) const; virtual bool hasLinkId(qlonglong lid, bool include_parent = true) const; virtual QString writeLinks(bool include_parent = false) const; virtual QString payeeText() const; virtual const QString &payee() const; }; class Expense : public Transaction { Q_DECLARE_TR_FUNCTIONS(Expense) protected: QString s_payee; bool b_reconciled; public: Expense(Budget *parent_budget, double initial_cost, QDate initial_date, ExpensesAccount *initial_category, AssetsAccount *initial_from, QString initial_description = QString(), QString initial_comment = QString(), qlonglong initial_id = -1); Expense(Budget *parent_budget, QXmlStreamReader *xml, bool *valid); Expense(Budget *parent_budget); Expense(); Expense(const Expense *expense); virtual ~Expense(); Transaction *copy() const; virtual void set(const Transactions *trans); virtual void readAttributes(QXmlStreamAttributes *attr, bool *valid); virtual void writeAttributes(QXmlStreamAttributes *attr); bool equals(const Transactions *transactions, bool strict_comparison = true) const; ExpensesAccount *category() const; void setCategory(ExpensesAccount *new_category); AssetsAccount *from() const; void setFrom(AssetsAccount *new_from); double cost(bool convert = false) const; void setCost(double new_cost); virtual const QString &payee() const; void setPayee(QString new_payee); virtual QString description() const; TransactionType type() const; virtual TransactionSubType subtype() const; virtual bool relatesToAccount(Account *account, bool include_subs = true, bool include_non_value = false) const; virtual void replaceAccount(Account *old_account, Account *new_account); virtual bool isReconciled(AssetsAccount *account) const; virtual void setReconciled(AssetsAccount *account, bool is_reconciled); }; class DebtFee : public Expense { Q_DECLARE_TR_FUNCTIONS(DebtFee) protected: AssetsAccount *o_loan; public: DebtFee(Budget *parent_budget, double initial_cost, QDate initial_date, ExpensesAccount *initial_category, AssetsAccount *initial_from, AssetsAccount *initial_loan, QString initial_comment = QString(), qlonglong initial_id = -1); DebtFee(Budget *parent_budget, QXmlStreamReader *xml, bool *valid); DebtFee(Budget *parent_budget); DebtFee(); DebtFee(const DebtFee *loanfee); virtual ~DebtFee(); Transaction *copy() const; virtual void set(const Transactions *trans); virtual void readAttributes(QXmlStreamAttributes *attr, bool *valid); virtual void writeAttributes(QXmlStreamAttributes *attr); AssetsAccount *loan() const; void setLoan(AssetsAccount *new_loan); const QString &payee() const; virtual QString description() const; TransactionSubType subtype() const; virtual bool relatesToAccount(Account *account, bool include_subs = true, bool include_non_value = false) const; virtual void replaceAccount(Account *old_account, Account *new_account); }; class DebtInterest : public Expense { Q_DECLARE_TR_FUNCTIONS(DebtInterest) protected: AssetsAccount *o_loan; public: DebtInterest(Budget *parent_budget, double initial_cost, QDate initial_date, ExpensesAccount *initial_category, AssetsAccount *initial_from, AssetsAccount *initial_loan, QString initial_comment = QString(), qlonglong initial_id = -1); DebtInterest(Budget *parent_budget, QXmlStreamReader *xml, bool *valid); DebtInterest(Budget *parent_budget); DebtInterest(); DebtInterest(const DebtInterest *interest); virtual ~DebtInterest(); Transaction *copy() const; virtual void set(const Transactions *trans); virtual void readAttributes(QXmlStreamAttributes *attr, bool *valid); virtual void writeAttributes(QXmlStreamAttributes *attr); AssetsAccount *loan() const; void setLoan(AssetsAccount *new_loan); const QString &payee() const; virtual QString description() const; TransactionSubType subtype() const; virtual bool relatesToAccount(Account *account, bool include_subs = true, bool include_non_value = false) const; virtual void replaceAccount(Account *old_account, Account *new_account); }; class Income : public Transaction { Q_DECLARE_TR_FUNCTIONS(Income) protected: Security *o_security; QString s_payer; bool b_reconciled; public: Income(Budget *parent_budget, double initial_income, QDate initial_date, IncomesAccount *initial_category, AssetsAccount *initial_to, QString initial_description = QString(), QString initial_comment = QString(), qlonglong initial_id = -1); Income(Budget *parent_budget, QXmlStreamReader *xml, bool *valid); Income(Budget *parent_budget); Income(); Income(const Income *income_); virtual ~Income(); Transaction *copy() const; virtual void set(const Transactions *trans); virtual void readAttributes(QXmlStreamAttributes *attr, bool *valid); virtual void writeAttributes(QXmlStreamAttributes *attr); bool equals(const Transactions *transaction, bool strict_comparison = true) const; IncomesAccount *category() const; void setCategory(IncomesAccount *new_category); AssetsAccount *to() const; void setTo(AssetsAccount *new_to); double income(bool convert = false) const; void setIncome(double new_income); const QString &payer() const; const QString &payee() const; void setPayer(QString new_payer); TransactionType type() const; void setSecurity(Security *parent_security); Security *security() const; virtual QString description() const; virtual TransactionSubType subtype() const; virtual bool isReconciled(AssetsAccount *account) const; virtual void setReconciled(AssetsAccount *account, bool is_reconciled); }; class ReinvestedDividend : public Income { Q_DECLARE_TR_FUNCTIONS(Income) protected: double d_shares; public: ReinvestedDividend(Budget *parent_budget, double initial_value, double initial_shares, QDate initial_date, Security *initial_security, IncomesAccount *initial_category, QString initial_comment = QString()); ReinvestedDividend(Budget *parent_budget, QXmlStreamReader *xml, bool *valid); ReinvestedDividend(Budget *parent_budget); ReinvestedDividend(); ReinvestedDividend(const ReinvestedDividend *dividend_); virtual ~ReinvestedDividend(); Transaction *copy() const; virtual void set(const Transactions *trans); virtual void readAttributes(QXmlStreamAttributes *attr, bool *valid); virtual void writeAttributes(QXmlStreamAttributes *attr); bool equals(const Transactions *transaction, bool strict_comparison = true) const; void setSecurity(Security *parent_security); double shareValue(bool convert = false) const; double shares() const; void setShares(double new_shares); virtual QString description() const; virtual TransactionSubType subtype() const; }; class Transfer : public Transaction { Q_DECLARE_TR_FUNCTIONS(Transfer) protected: double d_deposit; bool b_from_reconciled, b_to_reconciled; public: Transfer(Budget *parent_budget, double initial_amount, QDate initial_date, AssetsAccount *initial_from, AssetsAccount *initial_to, QString initial_description = QString(), QString initial_comment = QString(), qlonglong initial_id = -1); Transfer(Budget *parent_budget, double initial_withdrawal, double initial_deposit, QDate initial_date, AssetsAccount *initial_from, AssetsAccount *initial_to, QString initial_description = QString(), QString initial_comment = QString(), qlonglong initial_id = -1); Transfer(Budget *parent_budget, QXmlStreamReader *xml, bool *valid); Transfer(Budget *parent_budget); Transfer(); Transfer(const Transfer *transfer); virtual ~Transfer(); virtual Transaction *copy() const; virtual void set(const Transactions *trans); virtual void readAttributes(QXmlStreamAttributes *attr, bool *valid); virtual void writeAttributes(QXmlStreamAttributes *attr); AssetsAccount *to() const; void setTo(AssetsAccount *new_to); AssetsAccount *from() const; void setFrom(AssetsAccount *new_from); double amount(bool convert = false) const; void setValue(double new_value); virtual void setAmount(double new_amount); virtual void setAmount(double withdrawal, double deposit); Currency *withdrawalCurrency() const; Currency *depositCurrency() const; double withdrawal(bool convert = false) const; double deposit(bool convert = false) const; double fromValue(bool convert = false) const; double toValue(bool convert = false) const; virtual QString description() const; TransactionType type() const; virtual TransactionSubType subtype() const; virtual QString payeeText() const; virtual bool isReconciled(AssetsAccount *account) const; virtual void setReconciled(AssetsAccount *account, bool is_reconciled); }; class DebtReduction : public Transfer { Q_DECLARE_TR_FUNCTIONS(DebtReduction) public: DebtReduction(Budget *parent_budget, double initial_amount, QDate initial_date, AssetsAccount *initial_from, AssetsAccount *initial_loan, QString initial_comment = QString(), qlonglong initial_id = -1); DebtReduction(Budget *parent_budget, double initial_payment, double initial_reduction, QDate initial_date, AssetsAccount *initial_from, AssetsAccount *initial_loan, QString initial_comment = QString(), qlonglong initial_id = -1); DebtReduction(Budget *parent_budget, QXmlStreamReader *xml, bool *valid); DebtReduction(Budget *parent_budget); DebtReduction(); DebtReduction(const DebtReduction *loanpayment); virtual ~DebtReduction(); Transaction *copy() const; virtual void set(const Transactions *trans); virtual void readAttributes(QXmlStreamAttributes *attr, bool *valid); virtual void writeAttributes(QXmlStreamAttributes *attr); AssetsAccount *loan() const; void setLoan(AssetsAccount *new_loan); virtual QString description() const; TransactionSubType subtype() const; QString payeeText() const; }; class Balancing : public Transfer { Q_DECLARE_TR_FUNCTIONS(Balancing) public: Balancing(Budget *parent_budget, double initial_amount, QDate initial_date, AssetsAccount *initial_account, QString initial_comment = QString()); Balancing(Budget *parent_budget, QXmlStreamReader *xml, bool *valid); Balancing(Budget *parent_budget); Balancing(); Balancing(const Balancing *balancing); virtual ~Balancing(); Transaction *copy() const; virtual void set(const Transactions *trans); virtual void readAttributes(QXmlStreamAttributes *attr, bool *valid); virtual void writeAttributes(QXmlStreamAttributes *attr); virtual void setAmount(double new_amount); virtual void setAmount(double withdrawal, double deposit); AssetsAccount *account() const; void setAccount(AssetsAccount *new_account); virtual QString description() const; TransactionSubType subtype() const; }; class SecurityTransaction : public Transaction { Q_DECLARE_TR_FUNCTIONS(SecurityTransaction) protected: Security *o_security; double d_shares; bool b_reconciled; public: SecurityTransaction(Security *parent_security, double initial_value, double initial_shares, QDate initial_date, QString initial_comment = QString()); SecurityTransaction(Budget *parent_budget, QXmlStreamReader *xml, bool *valid); SecurityTransaction(Budget *parent_budget); SecurityTransaction(); SecurityTransaction(const SecurityTransaction *transaction); virtual ~SecurityTransaction(); virtual Transaction *copy() const = 0; virtual void set(const Transactions *trans); virtual void readAttributes(QXmlStreamAttributes *attr, bool *valid); virtual void writeAttributes(QXmlStreamAttributes *attr); bool equals(const Transactions *transaction, bool strict_comparison = true) const; virtual Account *fromAccount() const; virtual Account *toAccount() const; virtual Account *account() const = 0; virtual void setAccount(Account *account) = 0; virtual TransactionType type() const = 0; virtual QString description() const; virtual double value(bool convert = false) const; virtual Currency *currency() const; virtual double fromValue(bool convert = false) const; virtual double toValue(bool convert = false) const; double shareValue(bool convert = false) const; double shares() const; void setShares(double new_shares); void setSecurity(Security *parent_security); Security *security() const; virtual bool relatesToAccount(Account *account, bool include_subs = true, bool include_non_value = false) const; virtual double accountChange(Account *account, bool include_subs = true, bool convert = false) const; virtual bool isReconciled(AssetsAccount *account) const; virtual void setReconciled(AssetsAccount *account, bool is_reconciled); }; class SecurityBuy : public SecurityTransaction { Q_DECLARE_TR_FUNCTIONS(SecurityBuy) public: SecurityBuy(Security *parent_security, double initial_value, double initial_shares, QDate initial_date, Account *from_account, QString initial_comment = QString()); SecurityBuy(Budget *parent_budget, QXmlStreamReader *xml, bool *valid); SecurityBuy(Budget *parent_budget); SecurityBuy(); SecurityBuy(const SecurityBuy *transaction); virtual ~SecurityBuy(); Transaction *copy() const; virtual void set(const Transactions *trans); virtual void readAttributes(QXmlStreamAttributes *attr, bool *valid); virtual void writeAttributes(QXmlStreamAttributes *attr); Account *account() const; void setAccount(Account *account); double toValue(bool convert = false) const; Account *fromAccount() const; QString description() const; TransactionType type() const; }; class SecuritySell : public SecurityTransaction { Q_DECLARE_TR_FUNCTIONS(SecuritySell) public: SecuritySell(Security *parent_security, double initial_value, double initial_shares, QDate initial_date, Account *to_account, QString initial_comment = QString()); SecuritySell(Budget *parent_budget, QXmlStreamReader *xml, bool *valid); SecuritySell(Budget *parent_budget); SecuritySell(); SecuritySell(const SecuritySell *transaction); virtual ~SecuritySell(); Transaction *copy() const; virtual void set(const Transactions *trans); virtual void readAttributes(QXmlStreamAttributes *attr, bool *valid); virtual void writeAttributes(QXmlStreamAttributes *attr); Account *account() const; void setAccount(Account *account); double fromValue(bool convert = false) const; Account *toAccount() const; QString description() const; TransactionType type() const; }; class ScheduledTransaction : public Transactions { Q_DECLARE_TR_FUNCTIONS(ScheduledTransaction) protected: Recurrence *o_rec; Transactions *o_trans; public: ScheduledTransaction(Budget *parent_budget); ScheduledTransaction(Budget *parent_budget, Transactions *trans, Recurrence *rec); ScheduledTransaction(Budget *parent_budget, QXmlStreamReader *xml, bool *valid); ScheduledTransaction(const ScheduledTransaction *strans); virtual ~ScheduledTransaction(); virtual ScheduledTransaction *copy() const; virtual void set(const Transactions *trans); virtual void readAttributes(QXmlStreamAttributes *attr, bool *valid); virtual bool readElement(QXmlStreamReader *xml, bool *valid); virtual bool readElements(QXmlStreamReader *xml, bool *valid); virtual void save(QXmlStreamWriter *xml); virtual void writeAttributes(QXmlStreamAttributes *attr); virtual void writeElements(QXmlStreamWriter *xml); virtual bool equals(const Transactions *transaction, bool strict_comparison = true) const; virtual Recurrence *recurrence() const; virtual void setRecurrence(Recurrence *rec, bool delete_old = true); Transactions *realize(QDate date); Transactions *transaction() const; void setTransaction(Transactions *trans, bool delete_old = true); virtual const QDate &date() const; const qint64 ×tamp() const; void setTimestamp(qint64 cr_time); virtual const QDate &firstOccurrence() const; virtual bool isOneTimeTransaction() const; virtual void setDate(QDate newdate); virtual void addException(QDate exceptiondate); virtual double value(bool convert = false) const; virtual Currency *currency() const; virtual double quantity() const; virtual QString description() const; virtual const QString &comment() const; virtual const QString &associatedFile() const; virtual void setAssociatedFile(QString new_attachment); virtual GeneralTransactionType generaltype() const; virtual int transactiontype() const; virtual int transactionsubtype() const; virtual bool relatesToAccount(Account *account, bool include_subs = true, bool include_non_value = false) const; virtual void replaceAccount(Account *old_account, Account *new_account); virtual double accountChange(Account *account, bool include_subs = true, bool convert = false) const; virtual bool isReconciled(AssetsAccount *account) const; virtual void setReconciled(AssetsAccount *account, bool is_reconciled); virtual int tagsCount(bool include_parent = false) const; virtual void addTag(QString tag); virtual bool removeTag(QString tag); virtual void removeTag(int index); virtual bool hasTag(const QString &tag, bool include_parent = true, bool case_insensitive = false) const; virtual const QString &getTag(int index, bool include_parent = false) const; virtual QString tagsText(bool include_parent_child = true) const; virtual void clearTags(); virtual void readTags(const QString &text); virtual QString writeTags(bool include_parent = false) const; int linksCount(bool include_parent = false) const; qlonglong getLinkId(int index, bool include_parent = false) const; void clearLinks(); void removeLink(int index); bool removeLinkId(qlonglong lid); void addLinkId(qlonglong lid); bool hasLinkId(qlonglong lid, bool include_parent = false) const; void readLinks(const QString &text); QString writeLinks(bool include_parent = false) const; virtual QString payeeText() const; virtual const QString &payee() const; }; class SplitTransaction : public Transactions { Q_DECLARE_TR_FUNCTIONS(SplitTransaction) protected: QDate d_date; QString s_description; QString s_comment; QString s_file; QVector splits; qint64 i_time; bool b_reconciled; public: SplitTransaction(Budget *parent_budget, QDate initial_date, QString initial_description = QString()); SplitTransaction(Budget *parent_budget, QXmlStreamReader *xml, bool *valid); SplitTransaction(const SplitTransaction *split); SplitTransaction(Budget *parent_budget); SplitTransaction(); virtual ~SplitTransaction(); virtual SplitTransaction *copy() const = 0; virtual void set(const Transactions *trans); virtual double value(bool convert = false) const = 0; virtual Currency *currency() const = 0; virtual double cost(bool convert = false) const = 0; virtual double quantity() const = 0; double income() const; virtual void readAttributes(QXmlStreamAttributes *attr, bool *valid); virtual bool readElement(QXmlStreamReader *xml, bool *valid); virtual bool readElements(QXmlStreamReader *xml, bool *valid); virtual void save(QXmlStreamWriter *xml); virtual void writeAttributes(QXmlStreamAttributes *attr); virtual void writeElements(QXmlStreamWriter *xml); virtual bool equals(const Transactions *transaction, bool strict_comparison = true) const; virtual void addTransaction(Transaction *trans); virtual void removeTransaction(Transaction *trans, bool keep = false); virtual void clear(bool keep = false); const QDate &date() const; virtual void setDate(QDate new_date); const qint64 ×tamp() const; void setTimestamp(qint64 cr_time); QString description() const; virtual void setDescription(QString new_description); const QString &comment() const; virtual void setComment(QString new_comment); const QString &associatedFile() const; virtual void setAssociatedFile(QString new_attachment); virtual int count() const; virtual Transaction *operator[] (int index) const; virtual Transaction *at(int index) const; virtual void setId(qlonglong new_id) {Transactions::setId(new_id);} virtual GeneralTransactionType generaltype() const; virtual SplitTransactionType type() const = 0; virtual bool isIncomesAndExpenses() const; virtual bool relatesToAccount(Account *account, bool include_subs = true, bool include_non_value = false) const; virtual void replaceAccount(Account *old_account, Account *new_account); virtual double accountChange(Account *account, bool include_subs = true, bool convert = false) const; virtual bool isReconciled(AssetsAccount *account) const; virtual void setReconciled(AssetsAccount *account, bool is_reconciled); virtual QString tagsText(bool include_parent_child = true) const; virtual void splitTags(); virtual void joinTags(); virtual void splitLinks(); virtual void joinLinks(); virtual QString payeeText() const; virtual const QString &payee() const; }; class MultiItemTransaction : public SplitTransaction { Q_DECLARE_TR_FUNCTIONS(MultiItemTransaction) protected: AssetsAccount *o_account; QString s_payee; public: MultiItemTransaction(Budget *parent_budget, QDate initial_date, AssetsAccount *initial_account, QString initial_description = QString()); MultiItemTransaction(Budget *parent_budget, QXmlStreamReader *xml, bool *valid); MultiItemTransaction(const MultiItemTransaction *split); MultiItemTransaction(Budget *parent_budget); MultiItemTransaction(); virtual ~MultiItemTransaction(); virtual SplitTransaction *copy() const; virtual void set(const Transactions *trans); virtual void readAttributes(QXmlStreamAttributes *attr, bool *valid); virtual bool readElement(QXmlStreamReader *xml, bool *valid); virtual void writeAttributes(QXmlStreamAttributes *attr); virtual void writeElements(QXmlStreamWriter *xml); virtual double value(bool convert = false) const; virtual Currency *currency() const; virtual double quantity() const; virtual double cost(bool convert = false) const; double income() const; AssetsAccount *account() const; void setAccount(AssetsAccount *new_account); QString fromAccountsString() const; virtual const QString &payee() const; void setPayee(QString new_payee); void addTransaction(Transaction *trans); virtual SplitTransactionType type() const; int transactiontype() const; virtual bool relatesToAccount(Account *account, bool include_subs = true, bool include_non_value = false) const; virtual void replaceAccount(Account *old_account, Account *new_account); virtual bool isReconciled(AssetsAccount *account) const; virtual void setReconciled(AssetsAccount *account, bool is_reconciled); }; class MultiAccountTransaction : public SplitTransaction { Q_DECLARE_TR_FUNCTIONS(MultiAccountTransaction) protected: CategoryAccount *o_category; double d_quantity; public: MultiAccountTransaction(Budget *parent_budget, CategoryAccount *initial_category, QString initial_description = QString()); MultiAccountTransaction(Budget *parent_budget, QXmlStreamReader *xml, bool *valid); MultiAccountTransaction(const MultiAccountTransaction *split); MultiAccountTransaction(Budget *parent_budget); MultiAccountTransaction(); virtual ~MultiAccountTransaction(); virtual SplitTransaction *copy() const; virtual void set(const Transactions *trans); virtual void readAttributes(QXmlStreamAttributes *attr, bool *valid); virtual bool readElement(QXmlStreamReader *xml, bool *valid); virtual void writeAttributes(QXmlStreamAttributes *attr); virtual void writeElements(QXmlStreamWriter *xml); virtual double value(bool convert = false) const; virtual Currency *currency() const; virtual double quantity() const; void setQuantity(double new_quantity); virtual double cost(bool convert = false) const; CategoryAccount *category() const; void setCategory(CategoryAccount *new_category); void setDescription(QString new_description); AssetsAccount *account() const; QString accountsString() const; void addTransaction(Transaction *trans); virtual SplitTransactionType type() const; virtual TransactionType transactiontype() const; virtual bool isIncomesAndExpenses() const; virtual bool relatesToAccount(Account *account, bool include_subs = true, bool include_non_value = false) const; virtual void replaceAccount(Account *old_account, Account *new_account); }; class DebtPayment : public SplitTransaction { Q_DECLARE_TR_FUNCTIONS(DebtPayment) protected: AssetsAccount *o_loan; DebtFee *o_fee; DebtInterest *o_interest; DebtReduction *o_payment; AssetsAccount *o_account; public: DebtPayment(Budget *parent_budget, QDate initial_date, AssetsAccount *initial_loan, AssetsAccount *initial_account); DebtPayment(Budget *parent_budget, QXmlStreamReader *xml, bool *valid); DebtPayment(const DebtPayment *split); DebtPayment(Budget *parent_budget); DebtPayment(); virtual ~DebtPayment(); virtual SplitTransaction *copy() const; virtual void set(const Transactions *trans); virtual void readAttributes(QXmlStreamAttributes *attr, bool *valid); virtual bool readElement(QXmlStreamReader *xml, bool *valid); virtual void writeAttributes(QXmlStreamAttributes *attr); virtual void writeElements(QXmlStreamWriter *xml); virtual double value(bool convert = false) const; virtual Currency *currency() const; virtual double quantity() const; virtual double cost(bool convert = false) const; DebtFee *feeTransaction() const; DebtInterest *interestTransaction() const; DebtReduction *paymentTransaction() const; void setInterest(double new_value, bool paid_from_account = true); void setInterestPaid(bool paid_from_account); void setFee(double new_value); void setPayment(double new_value); void setPayment(double new_payment, double new_reduction); double interest(bool convert = false) const; bool interestPaid() const; double fee(bool convert = false) const; double payment(bool convert = false) const; double reduction(bool convert = false) const; void clear(bool keep = false); AssetsAccount *loan() const; void setLoan(AssetsAccount *new_loan); AssetsAccount *account() const; void setAccount(AssetsAccount *new_account); ExpensesAccount *expenseCategory() const; void setExpenseCategory(ExpensesAccount *new_category); void setId(qlonglong new_id); QString description() const; virtual void setDate(QDate new_date); SplitTransactionType type() const; virtual bool isIncomesAndExpenses() const; int count() const; virtual Transaction *operator[] (int index) const; virtual Transaction *at(int index) const; virtual void removeTransaction(Transaction *trans, bool keep = false); virtual bool relatesToAccount(Account *account, bool include_subs = true, bool include_non_value = false) const; virtual void replaceAccount(Account *old_account, Account *new_account); virtual double accountChange(Account *account, bool include_subs = true, bool convert = false) const; virtual bool isReconciled(AssetsAccount *account) const; virtual void setReconciled(AssetsAccount *account, bool is_reconciled); }; class SecurityTrade { public: SecurityTrade(const QDate &date_, double from_shares_, Security *from_security_, double to_shares_, Security *to_security_, qlonglong id_ = 0, int rev1 = 1, int rev2 = 1) : date(date_), from_shares(from_shares_), to_shares(to_shares_), from_security(from_security_), to_security(to_security_), timestamp(QDateTime::currentMSecsSinceEpoch() * 1000), id(id_), first_revision(rev1), last_revision(rev2) {} SecurityTrade(Budget *parent_budget, QXmlStreamReader *xml, bool *valid); void save(QXmlStreamWriter *xml); QDate date; double from_shares, to_shares; Security *from_security, *to_security; qint64 timestamp; qlonglong id; int first_revision, last_revision; }; #endif Eqonomize-1.5.3/src/transactioneditwidget.cpp000066400000000000000000003361421416454732000213770ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016-2020 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "budget.h" #include "accountcombobox.h" #include "editaccountdialogs.h" #include "eqonomizevalueedit.h" #include "recurrence.h" #include "eqonomize.h" #include "transactioneditwidget.h" #include #define CURROW(row, col) (b_autoedit ? row % rows : row) #define CURCOL(row, col) (b_autoedit ? ((row / rows) * 2) + col : col) #define TEROWCOL(row, col) CURROW(row, col), CURCOL(row, col) LinksWidget::LinksWidget(QWidget *parent, bool is_active) : QWidget(parent), b_editable(is_active), b_links(is_active) { first_parent_link = 0; QHBoxLayout *box = new QHBoxLayout(this); box->setContentsMargins(0, 0, 0, 0); linksLabel = new QLabel(this); linksLabel->setWordWrap(true); linksLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); box->addWidget(linksLabel, 1); if(b_editable) { removeButton = new QPushButton(LOAD_ICON("edit-delete"), QString(), this); removeButton->setEnabled(false); box->addWidget(removeButton, 0); connect(removeButton, SIGNAL(clicked()), this, SLOT(removeLink())); } else { removeButton = NULL; } connect(linksLabel, SIGNAL(linkActivated(const QString&)), this, SLOT(linkClicked(const QString&))); } void LinksWidget::linkClicked(const QString &str) { qlonglong lid = str.toLongLong(); for(int i = 0; i < links.count(); i++) { if(links.at(i) && links.at(i)->id() == lid) { Eqonomize::openLink(links.at(i), parentWidget()); return; } } } void LinksWidget::removeLink() { if(first_parent_link == 1) { links.removeAt(0); first_parent_link = 0; updateLabel(); removeButton->setEnabled(false); } else if(first_parent_link > 0) { QDialog *dialog = new QDialog(this); dialog->setWindowTitle(tr("Remove Link")); dialog->setModal(true); QVBoxLayout *box1 = new QVBoxLayout(dialog); QComboBox *combo = new QComboBox(dialog); combo->addItem(tr("All")); for(int i = 0; i < first_parent_link; i++) { Transactions *tlink = links.at(i); if(tlink) { if(tlink->description().isEmpty()) { combo->addItem(QLocale().toString(tlink->date(), QLocale::ShortFormat)); } else { bool b_date = false; for(int i2 = 0; i2 < links.count(); i2++) { if(i != i2 && links.at(i2) && tlink->description().compare(links.at(i2)->description(), Qt::CaseInsensitive) == 0) { b_date = true; break; } } combo->addItem(b_date ? tlink->description() + " (" + QLocale().toString(tlink->date(), QLocale::ShortFormat) + ")" : tlink->description()); } } } combo->setCurrentIndex(0); box1->addWidget(combo); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel); QPushButton *delButton = new QPushButton(LOAD_ICON("edit-delete"), tr("Remove")); buttonBox->addButton(delButton, QDialogButtonBox::AcceptRole); delButton->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), dialog, SLOT(reject())); connect(delButton, SIGNAL(clicked()), dialog, SLOT(accept())); box1->addWidget(buttonBox); if(dialog->exec() == QDialog::Accepted) { if(combo->currentIndex() > 0) { links.removeAt(combo->currentIndex() - 1); first_parent_link--; } else { while(first_parent_link > 0) { links.removeAt(0); first_parent_link--; } removeButton->setEnabled(false); } updateLabel(); } dialog->deleteLater(); } } bool LinksWidget::isEmpty() { return linksLabel->text().isEmpty(); } void LinksWidget::updateLabel() { QString str; for(int i = 0; i < links.count(); i++) { Transactions *ltrans = links.at(i); if(ltrans) { if(!str.isEmpty()) str += ", "; if(b_links) {str += "id()); str += "\">";} if(i >= first_parent_link) str += ""; if(ltrans->description().isEmpty()) { str += QLocale().toString(ltrans->date(), QLocale::ShortFormat); } else { str += ltrans->description(); for(int i2 = 0; i2 < links.count(); i2++) { if(i != i2 && links.at(i2) && ltrans->description().compare(links.at(i2)->description(), Qt::CaseInsensitive) == 0) { str += " ("; str += QLocale().toString(ltrans->date(), QLocale::ShortFormat); str += ")"; break; } } } if(i >= first_parent_link) str += ""; if(b_links) {str += "";} } } linksLabel->setText(str); } void LinksWidget::setTransaction(Transactions *trans) { links.clear(); if(removeButton) removeButton->setEnabled(false); if(trans) { int n = trans->linksCount(true); first_parent_link = trans->linksCount(false); if(n > 0) { for(int i = 0; i < n; i++) { Transactions *ltrans = trans->getLink(i, true); links << ltrans; if(removeButton && i < first_parent_link) removeButton->setEnabled(true); } } } updateLabel(); } void LinksWidget::updateTransaction(Transactions *trans) { trans->clearLinks(); for(int i = 0; i < first_parent_link; i++) trans->addLink(links.at(i)); } TagButton::TagButton(bool small_button, bool allow_new_tag, Budget *budg, QWidget *parent) : QPushButton(parent), b_small(small_button) { tagMenu = new TagMenu(budg, this, allow_new_tag); setMenu(tagMenu); icon_shown = true; if(b_small) { #if defined (Q_OS_WIN32) setIcon(LOAD_ICON2("tag", "eqz-tag")); #else setText("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); int w1 = sizeHint().width(); setIcon(LOAD_ICON2("tag", "eqz-tag")); int w2 = sizeHint().width(); if(w1 == w2) { setIcon(QIcon()); icon_shown = false; } #endif setText("(0)"); setToolTip(tr("no tags")); } else { setText(tr("no tags")); } connect(tagMenu, SIGNAL(newTagRequested()), this, SIGNAL(newTagRequested())); if(!b_small) connect(tagMenu, SIGNAL(aboutToShow()), this, SLOT(resizeTagMenu())); connect(tagMenu, SIGNAL(selectedTagsChanged()), this, SLOT(updateText())); } void TagButton::resizeTagMenu() { tagMenu->setMinimumWidth(width()); } void TagButton::updateText() { QString str = tagMenu->selectedTagsText(); if(str.isEmpty()) str = tr("no tags"); if(b_small) { setText(QString("(") + QString::number(tagMenu->selectedTagsCount()) + ")"); setToolTip(str); } else { setText(str.replace("&", "&&")); } } void TagButton::keyPressEvent(QKeyEvent *e) { if(e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) { emit returnPressed(); e->accept(); return; } QPushButton::keyPressEvent(e); } void TagButton::updateTags() { tagMenu->updateTags(); updateText(); } void TagButton::setTagSelected(QString tag, bool b, bool inconsistent) { tagMenu->setTagSelected(tag, b, inconsistent); updateText(); } void TagButton::setTransaction(Transactions *trans) { tagMenu->setTransaction(trans); updateText(); } void TagButton::setTransactions(QList list) { tagMenu->setTransactions(list); updateText(); } void TagButton::modifyTransaction(Transactions *trans, bool append) { tagMenu->modifyTransaction(trans, append); updateText(); } QString TagButton::createTag() { QString new_tag = tagMenu->createTag(); updateText(); click(); return new_tag; } TagMenu::TagMenu(Budget *budg, QWidget *parent, bool allow_new_tag) : QMenu(parent), budget(budg), allow_new(allow_new_tag) {} void TagMenu::updateTags() { QHash tagb; QHash tagi; for(QHash::const_iterator it = tag_actions.constBegin(); it != tag_actions.constEnd(); ++it) { tagb[it.key()] = it.value()->isChecked(); tagi[it.key()] = it.value()->data().toBool(); } clear(); tag_actions.clear(); if(allow_new) { addAction(tr("New tag…"), this, SIGNAL(newTagRequested())); if(!budget->tags.isEmpty()) addSeparator(); } for(int i = 0; i < budget->tags.count(); i++) { QAction *action = addAction(budget->tags[i].replace("&", "&&"), this, SLOT(tagToggled())); action->setData(false); action->setCheckable(true); if(tagb.contains(budget->tags[i])) { action->setChecked(tagb[budget->tags[i]]); if(tagi[budget->tags[i]]) { action->setData(true); action->setText(budget->tags[i] + "*"); } } tag_actions[budget->tags[i]] = action; } } void TagMenu::setTagSelected(QString tag, bool b, bool inconsistent) { QHash::iterator it = tag_actions.find(tag); if(it != tag_actions.end()) { if(it.value()->data().toBool() != inconsistent) { if(inconsistent) it.value()->setText(it.key() + "*"); else it.value()->setText(it.key()); } it.value()->setChecked(b); it.value()->setData(inconsistent); } } void TagMenu::setTransaction(Transactions *trans) { for(QHash::const_iterator it = tag_actions.constBegin(); it != tag_actions.constEnd(); ++it) { if(it.value()->data().toBool()) it.value()->setText(it.key()); } for(QHash::const_iterator it = tag_actions.constBegin(); it != tag_actions.constEnd(); ++it) { it.value()->setData(false); if(trans && trans->hasTag(it.key(), true)) it.value()->setChecked(true); else it.value()->setChecked(false); } } void TagMenu::setTransactions(QList list) { if(list.count() == 0) { setTransaction(NULL); } else if(list.count() == 1) { setTransaction(list[0]); } else { QHash tagb; QHash tagi; Transactions *trans = list[0]; for(QHash::const_iterator it = tag_actions.constBegin(); it != tag_actions.constEnd(); ++it) { tagb[it.key()] = trans->hasTag(it.key(), true); tagi[it.key()] = false; } for(int i = 1; i < list.count(); i++) { trans = list[i]; for(QHash::const_iterator it = tag_actions.constBegin(); it != tag_actions.constEnd(); ++it) { if(tagb[it.key()] != trans->hasTag(it.key(), true)) { tagb[it.key()] = false; tagi[it.key()] = true; } } } for(QHash::const_iterator it = tag_actions.constBegin(); it != tag_actions.constEnd(); ++it) { if(it.value()->data() != tagi[it.key()]) { if(tagi[it.key()]) it.value()->setText(it.key() + "*"); else it.value()->setText(it.key()); it.value()->setData(tagi[it.key()]); } it.value()->setChecked(tagb[it.key()]); } } } void TagMenu::modifyTransaction(Transactions *trans, bool append) { QStringList tags; for(QHash::const_iterator it = tag_actions.constBegin(); it != tag_actions.constEnd(); ++it) { if(it.value()->data().toBool()) { if(trans->hasTag(it.key(), true)) tags << it.key(); } else if(it.value()->isChecked()) { tags << it.key(); } } if(trans->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE && ((Transaction*) trans)->parentSplit() && ((Transaction*) trans)->parentSplit()->count() > 1) ((Transaction*) trans)->parentSplit()->splitTags(); if(!append) trans->clearTags(); for(int i = 0; i < tags.count(); i++) { trans->addTag(tags[i]); } if(trans->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE && ((Transaction*) trans)->parentSplit() && ((Transaction*) trans)->parentSplit()->count() > 1) ((Transaction*) trans)->parentSplit()->joinTags(); } int TagMenu::selectedTagsCount() { int n = 0; for(QHash::const_iterator it = tag_actions.constBegin(); it != tag_actions.constEnd(); ++it) { if(it.value()->isChecked()) n++; } return n; } QString TagMenu::selectedTagsText() { QString str; for(QHash::const_iterator it = tag_actions.constBegin(); it != tag_actions.constEnd(); ++it) { if(it.value()->isChecked()) { if(!str.isEmpty()) str += ", "; str += it.key(); } } return str; } void TagMenu::tagToggled() { QAction *action = qobject_cast(sender()); if(action->data().toBool()) { action->setData(false); for(QHash::const_iterator it = tag_actions.constBegin(); it != tag_actions.constEnd(); ++it) { if(it.value() == action) { action->setText(it.key()); break; } } } emit selectedTagsChanged(); } void TagMenu::keyPressEvent(QKeyEvent *e) { if(e->key() == Qt::Key_Space) { QAction *action = activeAction(); if(action) action->trigger(); e->setAccepted(true); } else { QMenu::keyPressEvent(e); } } void TagMenu::mouseReleaseEvent(QMouseEvent *e) { if(e->button() == Qt::LeftButton) { QAction *action = actionAt(e->pos()); if(action) action->trigger(); e->setAccepted(true); } else { QMenu::mouseReleaseEvent(e); } } QString TagMenu::createTag() { QString new_tag = QInputDialog::getText(this, tr("New Tag"), tr("Tag:")).trimmed(); if(!new_tag.isEmpty()) { if((new_tag.contains(",") && new_tag.contains("\"") && new_tag.contains("\'")) || (new_tag[0] == '\'' && new_tag.contains("\"")) || (new_tag[0] == '\"' && new_tag.contains("\'"))) { if(new_tag[0] == '\'') new_tag.remove("\'"); else new_tag.remove("\""); } QString str = budget->findTag(new_tag); if(str.isEmpty()) { budget->tagAdded(new_tag); updateTags(); setTagSelected(new_tag, true); return new_tag; } else { setTagSelected(str, true); } } return QString(); } extern QString last_associated_file_directory; CommentsTextEdit::CommentsTextEdit(QWidget *parent) : QPlainTextEdit(parent) { setLineWrapMode(QPlainTextEdit::WidgetWidth); } QSize CommentsTextEdit::sizeHint() const { QSize size = QPlainTextEdit::sizeHint(); QFontMetrics fm(font()); #if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)) size.setHeight(fm.lineSpacing() * 2 + frameWidth() * 2 + contentsMargins().top() + contentsMargins().bottom() + document()->documentMargin() * 2 + viewportMargins().bottom() + viewportMargins().top()); #else size.setHeight(fm.lineSpacing() * 2 + frameWidth() * 2 + contentsMargins().top() + contentsMargins().bottom() + document()->documentMargin() * 2); #endif return size; } void CommentsTextEdit::keyPressEvent(QKeyEvent *e) { if(e->key() == Qt::Key_Tab || e->key() == Qt::Key_Tab) { e->ignore(); return; } QPlainTextEdit::keyPressEvent(e); } TransactionEditWidget::TransactionEditWidget(bool auto_edit, bool extra_parameters, int transaction_type, Currency *split_currency, bool transfer_to, Security *sec, SecurityValueDefineType security_value_type, bool select_security, Budget *budg, QWidget *parent, bool allow_account_creation, bool multiaccount, bool withloan) : QWidget(parent), transtype(transaction_type), budget(budg), security(sec), b_autoedit(auto_edit), b_extra(extra_parameters), b_create_accounts(allow_account_creation), b_select_security(select_security && !security) { bool split = (split_currency != NULL); splitcurrency = split_currency; value_set = false; shares_set = false; sharevalue_set = false; b_sec = (transtype == TRANSACTION_TYPE_SECURITY_BUY || transtype == TRANSACTION_TYPE_SECURITY_SELL || transtype == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND); QVBoxLayout *editVLayout = new QVBoxLayout(this); int cols = 1; if(auto_edit) cols = 2; int rows = 6; if(b_sec && security_value_type == SECURITY_ALL_VALUES) rows += 1; else if(b_extra && !security && !select_security && transtype == TRANSACTION_TYPE_EXPENSE) rows += (multiaccount ? 1 : 2); else if(b_extra && !security && !select_security && transtype == TRANSACTION_TYPE_INCOME && !multiaccount) rows ++; else if(transtype == TRANSACTION_TYPE_TRANSFER) rows++; if(b_sec && security_value_type != SECURITY_VALUE_AND_SHARES) rows++; if(withloan) rows += 2; if(multiaccount) rows -= 4; if(split && !b_sec) rows -= 2; if(rows % cols > 0) rows = rows / cols + 1; else rows = rows / cols; editLayout = new QGridLayout(); editVLayout->addLayout(editLayout); if(auto_edit) editVLayout->addStretch(1); valueEdit = NULL; depositEdit = NULL; downPaymentEdit = NULL; dateEdit = NULL; sharesEdit = NULL; quotationEdit = NULL; setQuoteButton = NULL; descriptionEdit = NULL; payeeEdit = NULL; lenderEdit = NULL; quantityEdit = NULL; toCombo = NULL; fromCombo = NULL; securityCombo = NULL; currencyCombo = NULL; commentsEdit = NULL; commentsEditT = NULL; commentsEditL = NULL; dateLabel = NULL; depositLabel = NULL; withdrawalLabel = NULL; fileEdit = NULL; tagButton = NULL; linksWidget = NULL; int i = 0; if(b_sec) { int decimals = budget->defaultShareDecimals(); editLayout->addWidget(new QLabel(tr("Security:", "Financial security (e.g. stock, mutual fund)"), this), TEROWCOL(i, 0)); if(select_security) { securityCombo = new EqonomizeComboBox(this); securityCombo->setEditable(false); if(b_create_accounts) securityCombo->addItem(tr("New Security…", "Financial security (e.g. stock, mutual fund)"), QVariant::fromValue((void*) NULL)); int i2 = (b_create_accounts ? 1 : 0); for(SecurityList::const_iterator it = budget->securities.constBegin(); it != budget->securities.constEnd(); ++it) { Security *c_sec = *it; securityCombo->addItem(c_sec->name(), QVariant::fromValue((void*) c_sec)); if(c_sec == security || it == budget->securities.constBegin()) securityCombo->setCurrentIndex(i2); i2++; } if(b_create_accounts && i2 == 1) securityCombo->setCurrentIndex(-1); else if(b_create_accounts) securityCombo->insertSeparator(1); editLayout->addWidget(securityCombo, TEROWCOL(i, 1)); if(!security) security = selectedSecurity(); } else { editLayout->addWidget(new QLabel(security->name(), this), TEROWCOL(i, 1)); } if(security) decimals = security->decimals(); i++; if(security_value_type != SECURITY_SHARES_AND_QUOTATION && transtype != TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND) { if(transtype == TRANSACTION_TYPE_SECURITY_BUY) editLayout->addWidget(new QLabel(tr("Cost:"), this), TEROWCOL(i, 0)); else editLayout->addWidget(new QLabel(tr("Income:"), this), TEROWCOL(i, 0)); valueEdit = new EqonomizeValueEdit(false, this, budget); editLayout->addWidget(valueEdit, TEROWCOL(i, 1)); i++; } if(security_value_type != SECURITY_VALUE_AND_QUOTATION) { if(transtype == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND) { editLayout->addWidget(new QLabel(tr("Shares added:", "Financial shares"), this), TEROWCOL(i, 0)); sharesEdit = new EqonomizeValueEdit(0.0, decimals, false, false, this, budget); editLayout->addWidget(sharesEdit, TEROWCOL(i, 1)); i++; } else if(transtype == TRANSACTION_TYPE_SECURITY_BUY) { editLayout->addWidget(new QLabel(tr("Shares bought:", "Financial shares"), this), TEROWCOL(i, 0)); sharesEdit = new EqonomizeValueEdit(0.0, decimals, false, false, this, budget); editLayout->addWidget(sharesEdit, TEROWCOL(i, 1)); i++; } else { editLayout->addWidget(new QLabel(tr("Shares sold:", "Financial shares"), this), TEROWCOL(i, 0)); QHBoxLayout *sharesLayout = new QHBoxLayout(); sharesEdit = new EqonomizeValueEdit(0.0, decimals, false, false, this, budget); sharesEdit->setSizePolicy(QSizePolicy::Expanding, sharesEdit->sizePolicy().verticalPolicy()); sharesLayout->addWidget(sharesEdit); maxSharesButton = new QPushButton(tr("All"), this); maxSharesButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); sharesLayout->addWidget(maxSharesButton); editLayout->addLayout(sharesLayout, TEROWCOL(i, 1), Qt::AlignRight); i++; } } if(security_value_type != SECURITY_VALUE_AND_SHARES) { editLayout->addWidget(new QLabel(tr("Price per share:", "Financial shares"), this), TEROWCOL(i, 0)); quotationEdit = new EqonomizeValueEdit(0.0, security ? security->quotationDecimals() : budget->defaultQuotationDecimals(), false, true, this, budget); editLayout->addWidget(quotationEdit, TEROWCOL(i, 1)); i++; setQuoteButton = new QCheckBox(tr("Set security share value"), this); QSettings settings; settings.beginGroup("GeneralOptions"); setQuoteButton->setChecked(settings.value("setShareValueFromPrice", true).toBool()); settings.endGroup(); editLayout->addWidget(setQuoteButton, TEROWCOL(i, 1), Qt::AlignRight); i++; } if(security_value_type != SECURITY_SHARES_AND_QUOTATION && transtype == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND) { editLayout->addWidget(new QLabel(tr("Total value:"), this), TEROWCOL(i, 0)); valueEdit = new EqonomizeValueEdit(false, this, budget); editLayout->addWidget(valueEdit, TEROWCOL(i, 1)); i++; } if(!split) { dateLabel = new QLabel(tr("Date:"), this); editLayout->addWidget(dateLabel, TEROWCOL(i, 0)); dateRow = CURROW(i, 0); dateLabelCol = CURCOL(i, 0); dateEdit = new EqonomizeDateEdit(this); dateEdit->setCalendarPopup(true); editLayout->addWidget(dateEdit, TEROWCOL(i, 1)); dateEditCol = CURCOL(i, 1); } i++; } else { if(transtype == TRANSACTION_TYPE_INCOME && (security || select_security)) { editLayout->addWidget(new QLabel(tr("Security:", "Financial security (e.g. stock, mutual fund)"), this), TEROWCOL(i, 0)); if(select_security) { securityCombo = new EqonomizeComboBox(this); securityCombo->setEditable(false); if(b_create_accounts) securityCombo->addItem(tr("New Security…", "Financial security (e.g. stock, mutual fund)"), QVariant::fromValue((void*) NULL)); int i2 = (b_create_accounts ? 1 : 0); for(SecurityList::const_iterator it = budget->securities.constBegin(); it != budget->securities.constEnd(); ++it) { Security *c_sec = *it; securityCombo->addItem(c_sec->name(), QVariant::fromValue((void*) c_sec)); if(c_sec == security || it == budget->securities.constBegin()) securityCombo->setCurrentIndex(i2); i2++; } if(b_create_accounts && i2 == 1) securityCombo->setCurrentIndex(-1); else if(b_create_accounts) securityCombo->insertSeparator(1); editLayout->addWidget(securityCombo, TEROWCOL(i, 1)); if(!security) security = selectedSecurity(); } else { editLayout->addWidget(new QLabel(security->name(), this), TEROWCOL(i, 1)); } i++; } else if(!multiaccount) { editLayout->addWidget(new QLabel(tr("Description:", "Transaction description property (transaction title/generic article name)"), this), TEROWCOL(i, 0)); descriptionEdit = new QLineEdit(this); descriptionEdit->setCompleter(new QCompleter(this)); descriptionEdit->completer()->setModel(new QStandardItemModel(this)); descriptionEdit->completer()->setModelSorting(QCompleter::CaseInsensitivelySortedModel); descriptionEdit->setToolTip(tr("Transaction title/generic article name")); editLayout->addWidget(descriptionEdit, TEROWCOL(i, 1)); i++; } if(transtype == TRANSACTION_TYPE_TRANSFER) { withdrawalLabel = new QLabel(tr("Withdrawal:", "Money taken out from account"), this); editLayout->addWidget(withdrawalLabel, TEROWCOL(i, 0)); } else if(transtype == TRANSACTION_TYPE_INCOME) { editLayout->addWidget(new QLabel(tr("Income:"), this), TEROWCOL(i, 0)); } else { editLayout->addWidget(new QLabel(tr("Cost:"), this), TEROWCOL(i, 0)); } valueEdit = new EqonomizeValueEdit(0.0, budget->defaultCurrency()->fractionalDigits(true), !withloan, !withloan, this, budget); if(withloan) { valueEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); QHBoxLayout *valueLayout = new QHBoxLayout(); valueLayout->addWidget(valueEdit); currencyCombo = new QComboBox(this); currencyCombo->setEditable(false); int i2 = 0; for(CurrencyList::const_iterator it = budget->currencies.constBegin(); it != budget->currencies.constEnd(); ++it) { Currency *currency = *it; currencyCombo->addItem(QIcon(":/data/flags/" + currency->code() + ".png"), currency->code()); currencyCombo->setItemData(i2, QVariant::fromValue((void*) currency)); if(currency == budget->defaultCurrency()) currencyCombo->setCurrentIndex(i2); i2++; } valueLayout->addWidget(currencyCombo); editLayout->addLayout(valueLayout, TEROWCOL(i, 1)); } else { editLayout->addWidget(valueEdit, TEROWCOL(i, 1)); } i++; if(transtype == TRANSACTION_TYPE_TRANSFER) { depositLabel = new QLabel(tr("Deposit:", "Money put into account"), this); editLayout->addWidget(depositLabel, TEROWCOL(i, 0)); depositRow = CURROW(i, 0); depositLabelCol = CURCOL(i, 0); depositEdit = new EqonomizeValueEdit(true, this, budget); editLayout->addWidget(depositEdit, TEROWCOL(i, 1)); depositEditCol = CURCOL(i, 1); i++; } if(withloan) { editLayout->addWidget(new QLabel(tr("Downpayment:"), this), TEROWCOL(i, 0)); downPaymentEdit = new EqonomizeValueEdit(false, this, budget); editLayout->addWidget(downPaymentEdit, TEROWCOL(i, 1)); i++; } if(b_extra && !multiaccount && !select_security && !security && transtype == TRANSACTION_TYPE_EXPENSE) { editLayout->addWidget(new QLabel(tr("Quantity:"), this), TEROWCOL(i, 0)); quantityEdit = new EqonomizeValueEdit(1.0, QUANTITY_DECIMAL_PLACES, true, false, this, budget); quantityEdit->setToolTip(tr("Number of items included in the transaction. Entered cost is total cost for all items.")); editLayout->addWidget(quantityEdit, TEROWCOL(i, 1)); i++; } if(!split) { dateLabel = new QLabel(tr("Date:"), this); editLayout->addWidget(dateLabel, TEROWCOL(i, 0)); dateRow = CURROW(i, 0); dateLabelCol = CURCOL(i, 0); dateEdit = new EqonomizeDateEdit(this); dateEdit->setCalendarPopup(true); editLayout->addWidget(dateEdit, TEROWCOL(i, 1)); dateEditCol = CURCOL(i, 1); i++; if(b_extra && cols == 2 && !multiaccount && !select_security && !security && transtype == TRANSACTION_TYPE_INCOME) { i++; } } } switch(transtype) { case TRANSACTION_TYPE_TRANSFER: { if(!split || transfer_to) { editLayout->addWidget(new QLabel(tr("From:"), this), TEROWCOL(i, 0)); fromCombo = new AccountComboBox(ACCOUNT_TYPE_ASSETS, budget, b_create_accounts, false, false, !b_autoedit, true, this); editLayout->addWidget(fromCombo, TEROWCOL(i, 1)); i++; } if(!split || !transfer_to) { editLayout->addWidget(new QLabel(tr("To:"), this), TEROWCOL(i, 0)); toCombo = new AccountComboBox(ACCOUNT_TYPE_ASSETS, budget, b_create_accounts, false, false, !b_autoedit, false, this); editLayout->addWidget(toCombo, TEROWCOL(i, 1)); i++; } break; } case TRANSACTION_TYPE_INCOME: { if(!multiaccount) { editLayout->addWidget(new QLabel(tr("Category:"), this), TEROWCOL(i, 0)); fromCombo = new AccountComboBox(ACCOUNT_TYPE_INCOMES, budget, b_create_accounts, false, false, false, false, this); editLayout->addWidget(fromCombo, TEROWCOL(i, 1)); i++; } if(!split) { editLayout->addWidget(new QLabel(tr("To account:"), this), TEROWCOL(i, 0)); toCombo = new AccountComboBox(ACCOUNT_TYPE_ASSETS, budget, b_create_accounts, b_create_accounts && b_autoedit, b_autoedit, !b_autoedit, true, this); editLayout->addWidget(toCombo, TEROWCOL(i, 1)); i++; } if(b_extra && !select_security && !security) { editLayout->addWidget(new QLabel(tr("Payer:"), this), TEROWCOL(i, 0)); payeeEdit = new QLineEdit(this); if(split) payeeEdit->setPlaceholderText(tr("Payer of parent split transaction")); editLayout->addWidget(payeeEdit, TEROWCOL(i, 1)); i++; } break; } case TRANSACTION_TYPE_SECURITY_BUY: { if(!split) { editLayout->addWidget(new QLabel(tr("From account:"), this), TEROWCOL(i, 0)); fromCombo = new AccountComboBox(-1, budget, b_create_accounts, false, false, true, true, this); editLayout->addWidget(fromCombo, TEROWCOL(i, 1)); i++; } break; } case TRANSACTION_TYPE_SECURITY_SELL: { if(!split) { editLayout->addWidget(new QLabel(tr("To account:"), this), TEROWCOL(i, 0)); toCombo = new AccountComboBox(-2, budget, b_create_accounts, false, false, true, true, this); editLayout->addWidget(toCombo, TEROWCOL(i, 1)); i++; } break; } case TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND: { editLayout->addWidget(new QLabel(tr("Category:"), this), TEROWCOL(i, 0)); fromCombo = new AccountComboBox(ACCOUNT_TYPE_INCOMES, budget, b_create_accounts, false, false, false, false, this); editLayout->addWidget(fromCombo, TEROWCOL(i, 1)); i++; break; } default: { if(!multiaccount) { editLayout->addWidget(new QLabel(tr("Category:"), this), TEROWCOL(i, 0)); toCombo = new AccountComboBox(ACCOUNT_TYPE_EXPENSES, budget, b_create_accounts, false, false, false, false, this); editLayout->addWidget(toCombo, TEROWCOL(i, 1)); i++; } if(!split) { if(withloan) { editLayout->addWidget(new QLabel(tr("Downpayment account:"), this), TEROWCOL(i, 0)); fromCombo = new AccountComboBox(ACCOUNT_TYPE_ASSETS, budget, b_create_accounts, false, false, true, true, this); } else { editLayout->addWidget(new QLabel(tr("From account:"), this), TEROWCOL(i, 0)); fromCombo = new AccountComboBox(ACCOUNT_TYPE_ASSETS, budget, b_create_accounts, b_create_accounts && b_autoedit, b_autoedit, true, true, this); } editLayout->addWidget(fromCombo, TEROWCOL(i, 1)); i++; } if(b_extra) { editLayout->addWidget(new QLabel(tr("Payee:"), this), TEROWCOL(i, 0)); payeeEdit = new QLineEdit(this); if(split) payeeEdit->setPlaceholderText(tr("Payee of parent split transaction")); editLayout->addWidget(payeeEdit, TEROWCOL(i, 1)); i++; } } } if(withloan) { editLayout->addWidget(new QLabel(tr("Lender:"), this), TEROWCOL(i, 0)); lenderEdit = new QLineEdit(this); editLayout->addWidget(lenderEdit, TEROWCOL(i, 1)); i++; } if(!b_autoedit && (transtype == TRANSACTION_TYPE_INCOME || transtype == TRANSACTION_TYPE_EXPENSE) && !multiaccount && !sec) { editLayout->addWidget(new QLabel(tr("Tags:"), this), TEROWCOL(i, 0)); tagButton = new TagButton(false, allow_account_creation, budget, this); editLayout->addWidget(tagButton, TEROWCOL(i, 1)); tagsModified(); i++; connect(tagButton, SIGNAL(newTagRequested()), this, SLOT(newTag())); } if(!b_autoedit && !split && !multiaccount) { editLayout->addWidget(new QLabel(tr("Associated file:"), this), TEROWCOL(i, 0)); QHBoxLayout *fileLayout = new QHBoxLayout(); fileEdit = new QLineEdit(this); QCompleter *completer = new QCompleter(this); QFileSystemModel *fsModel = new QFileSystemModel(completer); fsModel->setRootPath(QString()); completer->setModel(fsModel); fileEdit->setCompleter(completer); fileLayout->addWidget(fileEdit); QPushButton *selectFileButton = new QPushButton(LOAD_ICON("document-open"), QString(), this); selectFileButton->setToolTip(tr("Select a file")); selectFileButton->setAutoDefault(false); fileLayout->addWidget(selectFileButton); QPushButton *openFileButton = new QPushButton(LOAD_ICON("system-run"), QString(), this); openFileButton->setToolTip(tr("Open the file")); openFileButton->setAutoDefault(false); fileLayout->addWidget(openFileButton); openFileButton->setFocusPolicy(Qt::ClickFocus); editLayout->addLayout(fileLayout, TEROWCOL(i, 1)); i++; connect(selectFileButton, SIGNAL(clicked()), this, SLOT(selectFile())); connect(openFileButton, SIGNAL(clicked()), this, SLOT(openFile())); } QLabel *commentsLabel = new QLabel(tr("Comments:"), this); if(auto_edit) { editLayout->addWidget(commentsLabel, TEROWCOL(i, 0)); commentsEditL = new QLineEdit(this); commentsEdit = commentsEditL; } else { int h = 0; if(descriptionEdit) h = descriptionEdit->sizeHint().height(); else if(valueEdit) h = valueEdit->sizeHint().height(); else if(sharesEdit) h = sharesEdit->sizeHint().height(); if(h > 0) commentsLabel->setMinimumHeight(h); editLayout->addWidget(commentsLabel, TEROWCOL(i, 0), Qt::AlignTop | Qt::AlignLeft); commentsEditT = new CommentsTextEdit(this); commentsEdit = commentsEditT; } if(b_autoedit && (transtype == TRANSACTION_TYPE_INCOME || transtype == TRANSACTION_TYPE_EXPENSE) && !sec) { QHBoxLayout *box = new QHBoxLayout(); editLayout->addLayout(box, TEROWCOL(i, 1)); box->addWidget(commentsEdit, 1); tagButton = new TagButton(true, allow_account_creation, budget, this); if(!tagButton->icon_shown) { QLabel *tagIcon = new QLabel(this); tagIcon->setPixmap(LOAD_ICON2("tag", "eqz-tag").pixmap(tagButton->style()->pixelMetric(QStyle::PM_ButtonIconSize))); box->addWidget(tagIcon, 0); } box->addWidget(tagButton, 0); tagsModified(); connect(tagButton, SIGNAL(newTagRequested()), this, SLOT(newTag())); } else { editLayout->addWidget(commentsEdit, TEROWCOL(i, 1)); } i++; if(!b_autoedit) { linksWidget = new LinksWidget(this, b_create_accounts); linksWidget->hide(); //: Label for linked transactions linksLabelLabel = new QLabel(tr("Related to:"), this); linksLabelLabel->hide(); editLayout->addWidget(linksLabelLabel, TEROWCOL(i, 0)); editLayout->addWidget(linksWidget, TEROWCOL(i, 1)); i++; } bottom_layout = new QHBoxLayout(); editVLayout->addLayout(bottom_layout); if(auto_edit) editVLayout->addStretch(1); description_changed = false; payee_changed = false; if(descriptionEdit) { descriptionEdit->completer()->setCaseSensitivity(Qt::CaseInsensitive); } if(payeeEdit) { payeeEdit->setCompleter(new QCompleter(this)); payeeEdit->completer()->setModel(new QStandardItemModel(this)); payeeEdit->completer()->setModelSorting(QCompleter::CaseInsensitivelySortedModel); payeeEdit->completer()->setCaseSensitivity(Qt::CaseInsensitive); } if(splitcurrency) { if(valueEdit && !transfer_to) valueEdit->setCurrency(splitcurrency); if(quotationEdit && !transfer_to) quotationEdit->setCurrency(splitcurrency); if(depositEdit && transfer_to) depositEdit->setCurrency(splitcurrency); } if(dateEdit) connect(dateEdit, SIGNAL(dateChanged(const QDate&)), this, SIGNAL(dateChanged(const QDate&))); if(valueEdit) { connect(valueEdit, SIGNAL(valueChanged(double)), this, SLOT(valueChanged(double))); if(depositEdit) { connect(valueEdit, SIGNAL(editingFinished()), this, SLOT(valueEditingFinished())); } } if(b_sec) { switch(security_value_type) { case SECURITY_ALL_VALUES: { connect(sharesEdit, SIGNAL(returnPressed()), quotationEdit, SLOT(enterFocus())); if(transtype == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND) { connect(quotationEdit, SIGNAL(returnPressed()), valueEdit, SLOT(enterFocus())); if(dateEdit) connect(valueEdit, SIGNAL(returnPressed()), this, SLOT(focusDate())); } else if(dateEdit) { connect(quotationEdit, SIGNAL(returnPressed()), this, SLOT(focusDate())); } if(transtype == TRANSACTION_TYPE_SECURITY_SELL) connect(maxSharesButton, SIGNAL(clicked()), this, SLOT(maxShares())); break; } case SECURITY_SHARES_AND_QUOTATION: { connect(sharesEdit, SIGNAL(returnPressed()), quotationEdit, SLOT(enterFocus())); if(dateEdit) { connect(quotationEdit, SIGNAL(returnPressed()), this, SLOT(focusDate())); } if(transtype == TRANSACTION_TYPE_SECURITY_SELL) connect(maxSharesButton, SIGNAL(clicked()), this, SLOT(maxShares())); break; } case SECURITY_VALUE_AND_SHARES: { if(transtype == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND) { connect(sharesEdit, SIGNAL(returnPressed()), valueEdit, SLOT(enterFocus())); if(dateEdit) connect(valueEdit, SIGNAL(returnPressed()), this, SLOT(focusDate())); } else if(dateEdit) { connect(sharesEdit, SIGNAL(returnPressed()), this, SLOT(focusDate())); } if(transtype == TRANSACTION_TYPE_SECURITY_SELL) connect(maxSharesButton, SIGNAL(clicked()), this, SLOT(maxShares())); break; } case SECURITY_VALUE_AND_QUOTATION: { if(dateEdit) { connect(quotationEdit, SIGNAL(returnPressed()), this, SLOT(focusDate())); } break; } } if(sharesEdit) connect(sharesEdit, SIGNAL(valueChanged(double)), this, SLOT(sharesChanged(double))); if(quotationEdit) connect(quotationEdit, SIGNAL(valueChanged(double)), this, SLOT(quotationChanged(double))); } else { if(downPaymentEdit) { if(quantityEdit) { connect(downPaymentEdit, SIGNAL(returnPressed()), quantityEdit, SLOT(enterFocus())); if(dateEdit) { connect(quantityEdit, SIGNAL(returnPressed()), this, SLOT(focusDate())); } } else { if(dateEdit) { connect(downPaymentEdit, SIGNAL(returnPressed()), this, SLOT(focusDate())); } } } else if(quantityEdit && dateEdit) { connect(quantityEdit, SIGNAL(returnPressed()), this, SLOT(focusDate())); } else if(depositEdit && dateEdit) { connect(depositEdit, SIGNAL(returnPressed()), this, SLOT(focusDate())); } else if(quantityEdit && fromCombo) { connect(quantityEdit, SIGNAL(returnPressed()), fromCombo, SLOT(focusAndSelectAll())); } else if(quantityEdit && toCombo) { connect(quantityEdit, SIGNAL(returnPressed()), toCombo, SLOT(focusAndSelectAll())); } if(descriptionEdit) { connect(descriptionEdit, SIGNAL(returnPressed()), valueEdit, SLOT(enterFocus())); connect(descriptionEdit, SIGNAL(editingFinished()), this, SLOT(setDefaultValue())); connect(descriptionEdit, SIGNAL(textChanged(const QString&)), this, SLOT(descriptionChanged(const QString&))); } } if(valueEdit && transtype != TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND) connect(valueEdit, SIGNAL(returnPressed()), this, SLOT(valueNextField())); if(payeeEdit) { connect(payeeEdit, SIGNAL(editingFinished()), this, SLOT(setDefaultValueFromPayee())); connect(payeeEdit, SIGNAL(textChanged(const QString&)), this, SLOT(payeeChanged(const QString&))); } if(dateEdit) { if(b_autoedit) connect(dateEdit, SIGNAL(returnPressed()), this, SIGNAL(addmodify())); else if(fromCombo && transtype != TRANSACTION_TYPE_EXPENSE) connect(dateEdit, SIGNAL(returnPressed()), fromCombo, SLOT(focusAndSelectAll())); else if(toCombo) connect(dateEdit, SIGNAL(returnPressed()), toCombo, SLOT(focusAndSelectAll())); } if(payeeEdit && lenderEdit) connect(payeeEdit, SIGNAL(returnPressed()), lenderEdit, SLOT(setFocus())); else if(payeeEdit && tagButton && (!b_autoedit || !commentsEdit)) connect(payeeEdit, SIGNAL(returnPressed()), tagButton, SLOT(setFocus())); else if(payeeEdit && fileEdit) connect(payeeEdit, SIGNAL(returnPressed()), fileEdit, SLOT(setFocus())); else if(payeeEdit && commentsEdit) connect(payeeEdit, SIGNAL(returnPressed()), commentsEdit, SLOT(setFocus())); if(lenderEdit && tagButton) connect(lenderEdit, SIGNAL(returnPressed()), tagButton, SLOT(setFocus())); else if(lenderEdit && fileEdit) connect(lenderEdit, SIGNAL(returnPressed()), fileEdit, SLOT(setFocus())); else if(lenderEdit && commentsEdit) connect(lenderEdit, SIGNAL(returnPressed()), commentsEdit, SLOT(setFocus())); if(fileEdit && commentsEdit) connect(fileEdit, SIGNAL(returnPressed()), commentsEdit, SLOT(setFocus())); if(commentsEditL) { if(b_autoedit && tagButton) connect(commentsEditL, SIGNAL(returnPressed()), tagButton, SLOT(setFocus())); else connect(commentsEditL, SIGNAL(returnPressed()), this, SIGNAL(addmodify())); } if(tagButton) { if(b_autoedit) connect(tagButton, SIGNAL(returnPressed()), this, SIGNAL(addmodify())); else if(fileEdit) connect(tagButton, SIGNAL(returnPressed()), fileEdit, SLOT(setFocus())); else if(commentsEdit) connect(tagButton, SIGNAL(returnPressed()), commentsEdit, SLOT(setFocus())); } if(securityCombo) connect(securityCombo, SIGNAL(activated(int)), this, SLOT(securityChanged(int))); if(transtype == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND && securityCombo && sharesEdit) { connect(securityCombo, SIGNAL(returnPressed()), sharesEdit, SLOT(enterFocus())); connect(securityCombo, SIGNAL(itemSelected(int)), sharesEdit, SLOT(enterFocus())); } else if(securityCombo && valueEdit) { connect(securityCombo, SIGNAL(returnPressed()), valueEdit, SLOT(enterFocus())); connect(securityCombo, SIGNAL(itemSelected(int)), valueEdit, SLOT(enterFocus())); } if(currencyCombo) connect(currencyCombo, SIGNAL(activated(int)), this, SLOT(currencyChanged(int))); if(setQuoteButton) connect(setQuoteButton, SIGNAL(toggled(bool)), this, SLOT(setQuoteToggled(bool))); if(fromCombo) { connect(fromCombo, SIGNAL(newAccountRequested()), this, SLOT(newFromAccount())); connect(fromCombo, SIGNAL(newLoanRequested()), this, SIGNAL(newLoanRequested())); connect(fromCombo, SIGNAL(multipleAccountsRequested()), this, SIGNAL(multipleAccountsRequested())); connect(fromCombo, SIGNAL(accountSelected(Account*)), this, SLOT(fromActivated())); connect(fromCombo, SIGNAL(currentAccountChanged(Account*)), this, SLOT(fromChanged(Account*))); if(toCombo && transtype != TRANSACTION_TYPE_EXPENSE) connect(fromCombo, SIGNAL(returnPressed()), toCombo, SLOT(focusAndSelectAll())); else if(payeeEdit) connect(fromCombo, SIGNAL(returnPressed()), payeeEdit, SLOT(setFocus())); else if(tagButton) connect(fromCombo, SIGNAL(returnPressed()), tagButton, SLOT(setFocus())); else if(fileEdit) connect(fromCombo, SIGNAL(returnPressed()), fileEdit, SLOT(setFocus())); else if(commentsEdit) connect(fromCombo, SIGNAL(returnPressed()), commentsEdit, SLOT(setFocus())); } if(toCombo) { connect(toCombo, SIGNAL(newAccountRequested()), this, SLOT(newToAccount())); connect(toCombo, SIGNAL(newLoanRequested()), this, SIGNAL(newLoanRequested())); connect(toCombo, SIGNAL(multipleAccountsRequested()), this, SIGNAL(multipleAccountsRequested())); connect(toCombo, SIGNAL(accountSelected(Account*)), this, SLOT(toActivated())); connect(toCombo, SIGNAL(currentAccountChanged(Account*)), this, SLOT(toChanged(Account*))); if(fromCombo && transtype == TRANSACTION_TYPE_EXPENSE) connect(toCombo, SIGNAL(returnPressed()), fromCombo, SLOT(focusAndSelectAll())); else if(payeeEdit) connect(toCombo, SIGNAL(returnPressed()), payeeEdit, SLOT(setFocus())); else if(tagButton) connect(toCombo, SIGNAL(returnPressed()), tagButton, SLOT(setFocus())); else if(fileEdit) connect(toCombo, SIGNAL(returnPressed()), fileEdit, SLOT(setFocus())); else if(commentsEdit) connect(toCombo, SIGNAL(returnPressed()), commentsEdit, SLOT(setFocus())); } if(auto_edit) { if(valueEdit) connect(valueEdit, SIGNAL(valueChanged(double)), this, SIGNAL(propertyChanged())); if(depositEdit) connect(depositEdit, SIGNAL(valueChanged(double)), this, SIGNAL(propertyChanged())); if(quantityEdit) connect(quantityEdit, SIGNAL(valueChanged(double)), this, SIGNAL(propertyChanged())); if(dateEdit) connect(dateEdit, SIGNAL(dateChanged(const QDate&)), this, SIGNAL(propertyChanged())); if(commentsEdit) connect(commentsEdit, SIGNAL(textChanged(const QString&)), this, SIGNAL(propertyChanged())); if(descriptionEdit) connect(descriptionEdit, SIGNAL(textChanged(const QString&)), this, SIGNAL(propertyChanged())); if(payeeEdit) connect(payeeEdit, SIGNAL(textChanged(const QString&)), this, SIGNAL(propertyChanged())); } b_multiple_currencies = true; useMultipleCurrencies(budget->usesMultipleCurrencies()); if(security) securityChanged(); } void TransactionEditWidget::setQuoteToggled(bool b) { QSettings settings; settings.beginGroup("GeneralOptions"); settings.setValue("setShareValueFromPrice", b); settings.endGroup(); } void TransactionEditWidget::selectFile() { QStringList urls = QFileDialog::getOpenFileNames(this, QString(), (fileEdit->text().isEmpty() || fileEdit->text().contains(",")) ? last_associated_file_directory : fileEdit->text()); if(!urls.isEmpty()) { QFileInfo fileInfo(urls[0]); last_associated_file_directory = fileInfo.absoluteDir().absolutePath(); if(urls.size() == 1) { fileEdit->setText(urls[0]); } else { QString url; for(int i = 0; i < urls.size(); i++) { if(i > 0) url += ", "; if(urls[i].contains("\"")) {url += "\'"; url += urls[i]; url += "\'";} else {url += "\""; url += urls[i]; url += "\"";} } fileEdit->setText(url); } } } void TransactionEditWidget::openFile() { open_file_list(fileEdit->text().trimmed()); } void TransactionEditWidget::useMultipleCurrencies(bool b) { if(b == b_multiple_currencies) return; b_multiple_currencies = b; if(!depositEdit) return; if(b_autoedit && dateEdit) { editLayout->removeWidget(dateLabel); editLayout->removeWidget(depositLabel); editLayout->removeWidget(dateEdit); editLayout->removeWidget(depositEdit); if(b) { editLayout->addWidget(depositEdit, depositRow, depositEditCol); editLayout->addWidget(depositLabel, depositRow, depositLabelCol); editLayout->addWidget(dateEdit, dateRow, dateEditCol); editLayout->addWidget(dateLabel, dateRow, dateLabelCol); } else { editLayout->addWidget(dateEdit, depositRow, depositEditCol); editLayout->addWidget(dateLabel, depositRow, depositLabelCol); editLayout->addWidget(depositEdit, dateRow, dateEditCol); editLayout->addWidget(depositLabel, dateRow, dateLabelCol); } } depositEdit->setVisible(b); depositLabel->setVisible(b); if(b) { if(withdrawalLabel) withdrawalLabel->setText(tr("Withdrawal:", "Money taken out from account")); } else { if(withdrawalLabel) withdrawalLabel->setText(tr("Amount:")); } } void TransactionEditWidget::valueNextField() { if(depositEdit && depositEdit->isEnabled()) { depositEdit->enterFocus(); } else if(sharesEdit) { sharesEdit->enterFocus(); } else if(downPaymentEdit) { downPaymentEdit->enterFocus(); } else if(quantityEdit) { quantityEdit->enterFocus(); } else if(dateEdit) { focusDate(); } } void TransactionEditWidget::newFromAccount() { budget->resetDefaultCurrencyChanged(); budget->resetCurrenciesModified(); Account *account = fromCombo->createAccount(); if(account) { emit accountAdded(account); if(toCombo) toCombo->updateAccounts(); } if(budget->currenciesModified() || budget->defaultCurrencyChanged()) emit currenciesModified(); } void TransactionEditWidget::newToAccount() { budget->resetDefaultCurrencyChanged(); budget->resetCurrenciesModified(); Account *account = toCombo->createAccount(); if(account) { emit accountAdded(account); if(fromCombo) fromCombo->updateAccounts(); } if(budget->currenciesModified() || budget->defaultCurrencyChanged()) emit currenciesModified(); } void TransactionEditWidget::fromActivated() { if(toCombo && transtype != TRANSACTION_TYPE_EXPENSE) toCombo->focusAndSelectAll(); else if(payeeEdit) payeeEdit->setFocus(); else if(commentsEdit) commentsEdit->setFocus(); if(transtype == TRANSACTION_TYPE_INCOME) { setDefaultValueFromCategory(); } } void TransactionEditWidget::toActivated() { if(fromCombo && transtype == TRANSACTION_TYPE_EXPENSE) fromCombo->focusAndSelectAll(); else if(payeeEdit) payeeEdit->setFocus(); else if(commentsEdit) commentsEdit->setFocus(); if(transtype == TRANSACTION_TYPE_EXPENSE) { setDefaultValueFromCategory(); } } void TransactionEditWidget::fromChanged(Account *acc) { if(!acc) return; if(downPaymentEdit) { downPaymentEdit->setCurrency(acc->currency()); } else if(valueEdit && acc->type() == ACCOUNT_TYPE_ASSETS) { valueEdit->setCurrency(acc->currency()); if(quotationEdit && selectedSecurity()) { quotationEdit->setCurrency(acc->currency()); security = selectedSecurity(); bool b = (security->currency() == quotationEdit->currency()); if(setQuoteButton->isEnabled() != b) { setQuoteButton->setEnabled(b); setQuoteButton->blockSignals(true); if(b) { setQuoteButton->setChecked(b_prev_update_quote); } else { b_prev_update_quote = setQuoteButton->isChecked(); setQuoteButton->setChecked(false); } setQuoteButton->blockSignals(false); } } } if(transtype == TRANSACTION_TYPE_TRANSFER) { Currency *cur2 = splitcurrency; if(toCombo && toCombo->currentAccount()) { cur2 = toCombo->currentAccount()->currency(); } if(depositEdit) { if(cur2 && acc->currency() && acc->currency() != cur2) { depositEdit->setEnabled(true); } else { depositEdit->setEnabled(false); if(is_zero(valueEdit->value())) valueEdit->setValue(depositEdit->value()); else depositEdit->setValue(valueEdit->value()); } } } } void TransactionEditWidget::toChanged(Account *acc) { if(!acc) return; if(transtype == TRANSACTION_TYPE_TRANSFER) { if(depositEdit) { depositEdit->setCurrency(acc->currency()); Currency *cur2 = splitcurrency; if(fromCombo && fromCombo->currentAccount()) { cur2 = fromCombo->currentAccount()->currency(); } if(cur2 && acc->currency() && acc->currency() != cur2) { depositEdit->setEnabled(true); } else { depositEdit->setEnabled(false); if(is_zero(valueEdit->value())) valueEdit->setValue(depositEdit->value()); else depositEdit->setValue(valueEdit->value()); } } } else { if(valueEdit && acc->type() == ACCOUNT_TYPE_ASSETS) { valueEdit->setCurrency(acc->currency()); if(quotationEdit && selectedSecurity()) { quotationEdit->setCurrency(acc->currency()); security = selectedSecurity(); bool b = (security->currency() == quotationEdit->currency()); if(setQuoteButton->isEnabled() != b) { setQuoteButton->setEnabled(b); setQuoteButton->blockSignals(true); if(b) { setQuoteButton->setChecked(b_prev_update_quote); } else { b_prev_update_quote = setQuoteButton->isChecked(); setQuoteButton->setChecked(false); } setQuoteButton->blockSignals(false); } } } } } void TransactionEditWidget::focusDate() { if(!dateEdit) return; dateEdit->setFocus(); dateEdit->setCurrentSection(QDateTimeEdit::DaySection); } void TransactionEditWidget::currentDateChanged(const QDate &olddate, const QDate &newdate) { if(dateEdit && olddate == dateEdit->date() && valueEdit && valueEdit->value() == 0.0 && descriptionEdit && descriptionEdit->text().isEmpty()) { dateEdit->setDate(newdate); } } void TransactionEditWidget::securityChanged(int index) { if(b_create_accounts && index == 0) { // New security EditSecurityDialog *dialog = new EditSecurityDialog(budget, this, tr("New Security", "Financial security (e.g. stock, mutual fund)"), b_create_accounts); if((b_create_accounts || dialog->checkAccount()) && dialog->exec() == QDialog::Accepted) { Security *sec = dialog->newSecurity(); if(sec) { budget->addSecurity(sec); securityCombo->blockSignals(true); securityCombo->clear(); securityCombo->addItem(tr("New Security…", "Financial security (e.g. stock, mutual fund)"), QVariant::fromValue((void*) NULL)); securityCombo->insertSeparator(1); int i2 = 2; for(SecurityList::const_iterator it = budget->securities.constBegin(); it != budget->securities.constEnd(); ++it) { Security *c_sec = *it; securityCombo->addItem(c_sec->name(), QVariant::fromValue((void*) c_sec)); if(c_sec == sec) securityCombo->setCurrentIndex(i2); i2++; } security = sec; securityCombo->blockSignals(false); dialog->deleteLater(); securityChanged(); return; } } if(security) { securityCombo->setCurrentIndex(securityCombo->findData(QVariant::fromValue((void*) security))); } else { securityCombo->setCurrentIndex(-1); } dialog->deleteLater(); return; } security = selectedSecurity(); if(security) { if(sharesEdit) sharesEdit->setPrecision(security->decimals()); if(quotationEdit) { if(quotationEdit->value() == 0.0 && date().isValid() && security->currency() == quotationEdit->currency() && security->hasQuotation(date())) { quotationEdit->blockSignals(true); quotationEdit->setValue(security->getQuotation(date())); quotationEdit->blockSignals(false); } quotationEdit->setPrecision(security->quotationDecimals()); bool b = (security->currency() == quotationEdit->currency()); if(setQuoteButton->isEnabled() != b) { setQuoteButton->setEnabled(b); setQuoteButton->blockSignals(true); if(b) { setQuoteButton->setChecked(b_prev_update_quote); } else { b_prev_update_quote = setQuoteButton->isChecked(); setQuoteButton->setChecked(false); } setQuoteButton->blockSignals(false); } } if(sharesEdit && security && shares_date.isValid()) sharesEdit->setMaximum(security->shares(shares_date)); } } void TransactionEditWidget::currencyChanged(int index) { Currency *cur = (Currency*) currencyCombo->itemData(index).value(); valueEdit->setPrecision(cur->fractionalDigits()); } void TransactionEditWidget::valueEditingFinished() { if(valueEdit && depositEdit && depositEdit->isEnabled() && depositEdit->value() == 0.0 && valueEdit->currency() && depositEdit->currency()) { depositEdit->setValue(valueEdit->currency()->convertTo(valueEdit->value(), depositEdit->currency())); } } void TransactionEditWidget::valueChanged(double value) { if(valueEdit && depositEdit) { if(!depositEdit->isEnabled()) depositEdit->setValue(value); } if(valueEdit && commentsEdit && calculatedText_object == valueEdit && !calculatedText.isEmpty()) { if(commentsEditT) { if(commentsEditT->toPlainText().isEmpty()) commentsEditT->setPlainText(calculatedText); } else { if(commentsEditL->text().isEmpty()) commentsEditL->setText(calculatedText); } calculatedText = ""; } if(!quotationEdit || !sharesEdit || !valueEdit) return; value_set = value != 0.0; if(!shares_set && quotationEdit->value() != 0.0) { sharesEdit->blockSignals(true); sharesEdit->setValue(value / quotationEdit->value()); sharesEdit->blockSignals(false); } else if(sharesEdit->value() != 0.0) { quotationEdit->blockSignals(true); quotationEdit->setValue(value / sharesEdit->value()); quotationEdit->blockSignals(false); } } void TransactionEditWidget::sharesChanged(double value) { if(!quotationEdit || !sharesEdit || !valueEdit) return; shares_set = value != 0.0; if((!value_set && quotationEdit->value() != 0.0) || (transtype == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND && sharevalue_set)) { valueEdit->blockSignals(true); valueEdit->setValue(value * quotationEdit->value()); valueEdit->blockSignals(false); } else if(value != 0.0) { quotationEdit->blockSignals(true); quotationEdit->setValue(valueEdit->value() / value); quotationEdit->blockSignals(false); } } void TransactionEditWidget::quotationChanged(double value) { if(!quotationEdit || !sharesEdit || !valueEdit) return; sharevalue_set = value != 0.0; if(!value_set || (transtype == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND && shares_set && sharesEdit->value() != 0.0)) { valueEdit->blockSignals(true); valueEdit->setValue(value * sharesEdit->value()); valueEdit->blockSignals(false); } else if(value != 0.0) { sharesEdit->blockSignals(true); sharesEdit->setValue(valueEdit->value() / value); sharesEdit->blockSignals(false); } } void TransactionEditWidget::setMaxShares(double max) { if(sharesEdit) sharesEdit->setMaximum(max); } void TransactionEditWidget::setMaxSharesDate(QDate quotation_date) { shares_date = quotation_date; if(sharesEdit && security && shares_date.isValid()) sharesEdit->setMaximum(security->shares(shares_date)); } void TransactionEditWidget::maxShares() { if(selectedSecurity() && sharesEdit) { sharesEdit->setValue(selectedSecurity()->shares(dateEdit->date())); } } QHBoxLayout *TransactionEditWidget::bottomLayout() { return bottom_layout; } void TransactionEditWidget::focusFirst() { if(!descriptionEdit) { if(b_select_security && securityCombo) securityCombo->setFocus(); else if(valueEdit && transtype != TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND) valueEdit->setFocus(); else if(sharesEdit) sharesEdit->setFocus(); } else { descriptionEdit->setFocus(); } } bool TransactionEditWidget::firstHasFocus() const { if(!descriptionEdit) { if(b_select_security && securityCombo) return securityCombo->hasFocus(); else if(valueEdit && transtype != TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND) return valueEdit->hasFocus(); else if(sharesEdit) return sharesEdit->hasFocus(); } return descriptionEdit->hasFocus(); } void TransactionEditWidget::setValues(QString description_value, double value_value, double quantity_value, QDate date_value, Account *from_account_value, Account *to_account_value, QString payee_value, QString comment_value) { if(descriptionEdit) descriptionEdit->setText(description_value); if(valueEdit) valueEdit->setValue(value_value); if(quantityEdit) quantityEdit->setValue(quantity_value); if(dateEdit && date_value.isValid()) dateEdit->setDate(date_value); if(fromCombo && from_account_value) fromCombo->setCurrentAccount(from_account_value); if(toCombo && to_account_value) toCombo->setCurrentAccount(to_account_value); if(payeeEdit) payeeEdit->setText(payee_value); if(commentsEditL) commentsEditL->setText(comment_value); else if(commentsEditT) commentsEditT->setPlainText(comment_value); } void TransactionEditWidget::setPayee(QString payee) { if(payeeEdit) payeeEdit->setText(payee); } QString TransactionEditWidget::description() const { if(!descriptionEdit) return QString(); return descriptionEdit->text(); } QString TransactionEditWidget::payee() const { if(!payeeEdit) return QString(); return payeeEdit->text(); } QString TransactionEditWidget::comments() const { if(commentsEditL) return commentsEditL->text(); if(commentsEditT) return commentsEditT->toPlainText(); return QString(); } double TransactionEditWidget::value() const { if(!valueEdit) return 0.0; return valueEdit->value(); } double TransactionEditWidget::quantity() const { if(!quantityEdit) return 1.0; return quantityEdit->value(); } Account *TransactionEditWidget::fromAccount() const { if(!fromCombo) return NULL; return fromCombo->currentAccount(); } Account *TransactionEditWidget::toAccount() const { if(!toCombo) return NULL; return toCombo->currentAccount(); } QDate TransactionEditWidget::date() { if(!dateEdit) return QDate(); return dateEdit->date(); } void TransactionEditWidget::descriptionChanged(const QString&) { description_changed = true; } void TransactionEditWidget::payeeChanged(const QString&) { payee_changed = true; } void TransactionEditWidget::setDefaultValue() { if(descriptionEdit && description_changed && !descriptionEdit->text().isEmpty() && valueEdit && valueEdit->value() == 0.0) { Transaction *trans = NULL; if(default_values.contains(descriptionEdit->text().toLower())) trans = default_values[descriptionEdit->text().toLower()]; if(trans) { if(trans->parentSplit() && trans->parentSplit()->type() == SPLIT_TRANSACTION_TYPE_MULTIPLE_ACCOUNTS) valueEdit->setValue(trans->parentSplit()->value()); else valueEdit->setValue(trans->value()); if(toCombo) toCombo->setCurrentAccount(trans->toAccount()); if(fromCombo) fromCombo->setCurrentAccount(trans->fromAccount()); if(quantityEdit) { if(trans->quantity() <= 0.0) quantityEdit->setValue(1.0); else quantityEdit->setValue(trans->quantity()); } if(payeeEdit && trans->type() == TRANSACTION_TYPE_EXPENSE) payeeEdit->setText(((Expense*) trans)->payee()); if(payeeEdit && trans->type() == TRANSACTION_TYPE_INCOME) payeeEdit->setText(((Income*) trans)->payer()); } } } void TransactionEditWidget::setDefaultValueFromPayee() { if(payeeEdit && payee_changed && !payeeEdit->text().isEmpty() && valueEdit && valueEdit->value() == 0.0 && descriptionEdit && descriptionEdit->text().isEmpty()) { Transaction *trans = NULL; if(default_payee_values.contains(payeeEdit->text().toLower())) trans = default_payee_values[payeeEdit->text().toLower()]; if(trans) { if(trans->parentSplit() && trans->parentSplit()->type() == SPLIT_TRANSACTION_TYPE_MULTIPLE_ACCOUNTS) valueEdit->setValue(trans->parentSplit()->value()); else valueEdit->setValue(trans->value()); if(toCombo) toCombo->setCurrentAccount(trans->toAccount()); if(fromCombo) fromCombo->setCurrentAccount(trans->fromAccount()); if(quantityEdit) { if(trans->quantity() <= 0.0) quantityEdit->setValue(1.0); else quantityEdit->setValue(trans->quantity()); } if(descriptionEdit) descriptionEdit->setText(trans->description()); if(valueEdit) { valueEdit->enterFocus(); } } } } void TransactionEditWidget::setDefaultValueFromCategory() { if(((transtype == TRANSACTION_TYPE_INCOME && fromCombo) || (transtype == TRANSACTION_TYPE_EXPENSE && toCombo)) && valueEdit && valueEdit->value() == 0.0 && descriptionEdit && descriptionEdit->text().isEmpty()) { Transaction *trans = NULL; if(transtype == TRANSACTION_TYPE_INCOME && default_category_values.contains(fromAccount())) trans = default_category_values[fromAccount()]; else if(transtype == TRANSACTION_TYPE_EXPENSE && default_category_values.contains(toAccount())) trans = default_category_values[toAccount()]; if(trans) { if(trans->parentSplit() && trans->parentSplit()->type() == SPLIT_TRANSACTION_TYPE_MULTIPLE_ACCOUNTS) valueEdit->setValue(trans->parentSplit()->value()); else valueEdit->setValue(trans->value()); if(toCombo && transtype == TRANSACTION_TYPE_INCOME) toCombo->setCurrentAccount(trans->toAccount()); if(fromCombo && transtype == TRANSACTION_TYPE_EXPENSE) fromCombo->setCurrentAccount(trans->fromAccount()); if(quantityEdit) { if(trans->quantity() <= 0.0) quantityEdit->setValue(1.0); else quantityEdit->setValue(trans->quantity()); } if(descriptionEdit) descriptionEdit->setText(trans->description()); if(payeeEdit && trans->type() == TRANSACTION_TYPE_EXPENSE) payeeEdit->setText(((Expense*) trans)->payee()); if(payeeEdit && trans->type() == TRANSACTION_TYPE_INCOME) payeeEdit->setText(((Income*) trans)->payer()); if(valueEdit) { valueEdit->enterFocus(); } } } } void TransactionEditWidget::updateFromAccounts(Account *exclude_account, Currency *force_currency, bool set_default) { if(!fromCombo) return; fromCombo->updateAccounts(exclude_account, force_currency); if(set_default) setDefaultFromAccount(); } void TransactionEditWidget::updateToAccounts(Account *exclude_account, Currency *force_currency, bool set_default) { if(!toCombo) return; toCombo->updateAccounts(exclude_account, force_currency); if(set_default) setDefaultToAccount(); } void TransactionEditWidget::updateAccounts(Account *exclude_account, Currency *force_currency, bool set_default) { Account *afrom = NULL; if(fromCombo) { afrom = fromCombo->currentAccount(); fromCombo->clear(); } updateToAccounts(exclude_account, force_currency, set_default); updateFromAccounts(exclude_account, force_currency, set_default); if(fromCombo) fromCombo->setCurrentAccount(afrom); } void TransactionEditWidget::transactionAdded(Transaction *trans) { if(descriptionEdit && trans->type() == transtype && (transtype != TRANSACTION_TYPE_INCOME || !((Income*) trans)->security()) && trans->subtype() != TRANSACTION_SUBTYPE_DEBT_FEE && trans->subtype() != TRANSACTION_SUBTYPE_DEBT_INTEREST) { if(!trans->description().isEmpty()) { if(!default_values.contains(trans->description().toLower())) { QList row; row << new QStandardItem(trans->description()); row << new QStandardItem(trans->description().toLower()); ((QStandardItemModel*) descriptionEdit->completer()->model())->appendRow(row); ((QStandardItemModel*) descriptionEdit->completer()->model())->sort(1); } default_values[trans->description().toLower()] = trans; } if(payeeEdit && transtype == TRANSACTION_TYPE_EXPENSE && !((Expense*) trans)->payee().isEmpty()) { if(!default_payee_values.contains(((Expense*) trans)->payee().toLower())) { QList row; row << new QStandardItem(((Expense*) trans)->payee()); row << new QStandardItem(((Expense*) trans)->payee().toLower()); ((QStandardItemModel*) payeeEdit->completer()->model())->appendRow(row); ((QStandardItemModel*) payeeEdit->completer()->model())->sort(1); } default_payee_values[((Expense*) trans)->payee().toLower()] = trans; } else if(payeeEdit && transtype == TRANSACTION_TYPE_INCOME && !((Income*) trans)->security() && !((Income*) trans)->payer().isEmpty()) { if(!default_payee_values.contains(((Income*) trans)->payer().toLower())) { QList row; row << new QStandardItem(((Income*) trans)->payer()); row << new QStandardItem(((Income*) trans)->payer().toLower()); ((QStandardItemModel*) payeeEdit->completer()->model())->appendRow(row); ((QStandardItemModel*) payeeEdit->completer()->model())->sort(1); } default_payee_values[((Income*) trans)->payer().toLower()] = trans; } if(transtype == TRANSACTION_TYPE_INCOME && fromCombo) { default_category_values[trans->fromAccount()] = trans; } else if(transtype == TRANSACTION_TYPE_EXPENSE && toCombo) { default_category_values[trans->toAccount()] = trans; } } } void TransactionEditWidget::tagsModified() { if(tagButton) tagButton->updateTags(); } void TransactionEditWidget::transactionModified(Transaction *trans) { transactionAdded(trans); } bool TransactionEditWidget::checkAccounts() { switch(transtype) { case TRANSACTION_TYPE_TRANSFER: { if(fromCombo && !fromCombo->hasAccount()) { QMessageBox::critical(this, tr("Error"), tr("No suitable account available.")); return false; } if(toCombo && !toCombo->hasAccount()) { QMessageBox::critical(this, tr("Error"), tr("No suitable account available.")); return false; } break; } case TRANSACTION_TYPE_INCOME: { if(fromCombo && !fromCombo->hasAccount()) { QMessageBox::critical(this, tr("Error"), tr("No income category available.")); return false; } if(toCombo && !toCombo->hasAccount()) { QMessageBox::critical(this, tr("Error"), tr("No suitable account available.")); return false; } break; } case TRANSACTION_TYPE_SECURITY_BUY: { if(fromCombo && !fromCombo->hasAccount()) { QMessageBox::critical(this, tr("Error"), tr("No suitable account or income category available.")); return false; } break; } case TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND: { if(fromCombo && !fromCombo->hasAccount()) { QMessageBox::critical(this, tr("Error"), tr("No income category available.")); return false; } break; } case TRANSACTION_TYPE_SECURITY_SELL: { if(toCombo && !toCombo->hasAccount()) { QMessageBox::critical(this, tr("Error"), tr("No suitable account available.")); return false; } break; } default: { if(toCombo && !toCombo->hasAccount()) { QMessageBox::critical(this, tr("Error"), tr("No expense category available.")); return false; } if(fromCombo && !fromCombo->hasAccount() && (!downPaymentEdit || !is_zero(downPaymentEdit->value()))) { QMessageBox::critical(this, tr("Error"), tr("No suitable account available.")); return false; } break; } } if(securityCombo && securityCombo->count() <= (b_create_accounts ? 2 : 0)) { QMessageBox::critical(this, tr("Error"), tr("No security available.", "Financial security (e.g. stock, mutual fund)")); return false; } return true; } bool TransactionEditWidget::isCleared() { return (!valueEdit || valueEdit->value() == 0.0) && (!dateEdit || dateEdit->date() == QDate::currentDate()) && (!quantityEdit || quantityEdit->value() == 1.0) && (!depositEdit || depositEdit->value() == 0.0) && comments().isEmpty() && (!descriptionEdit || descriptionEdit->text().isEmpty()) && (!payeeEdit || payeeEdit->text().isEmpty()); } bool TransactionEditWidget::validValues(bool) { if(dateEdit && !dateEdit->date().isValid()) { QMessageBox::critical(this, tr("Error"), tr("Invalid date.")); dateEdit->setFocus(); dateEdit->selectAll(); return false; } if(!checkAccounts()) return false; if((toCombo && !toCombo->currentAccount()) || (fromCombo && !downPaymentEdit && !fromCombo->currentAccount())) return false; if(toCombo && fromCombo && toCombo->currentAccount() == fromCombo->currentAccount()) { QMessageBox::critical(this, tr("Error"), tr("Cannot transfer money to and from the same account.")); return false; } if(downPaymentEdit && downPaymentEdit->value() >= valueEdit->value()) { QMessageBox::critical(this, tr("Error"), tr("Downpayment must be less than total cost.")); downPaymentEdit->setFocus(); return false; } switch(transtype) { case TRANSACTION_TYPE_TRANSFER: { if((toCombo && toCombo->currentAccount()->type() == ACCOUNT_TYPE_ASSETS && ((AssetsAccount*) toCombo->currentAccount())->accountType() == ASSETS_TYPE_SECURITIES) || (fromCombo && fromCombo->currentAccount()->type() == ACCOUNT_TYPE_ASSETS && ((AssetsAccount*) fromCombo->currentAccount())->accountType() == ASSETS_TYPE_SECURITIES)) { QMessageBox::critical(this, tr("Error"), tr("Cannot create a regular transfer to/from a securities account.")); return false; } break; } case TRANSACTION_TYPE_INCOME: { if(toCombo && toCombo->currentAccount()->type() == ACCOUNT_TYPE_ASSETS && ((AssetsAccount*) toCombo->currentAccount())->accountType() == ASSETS_TYPE_SECURITIES) { QMessageBox::critical(this, tr("Error"), tr("Cannot create a regular income to a securities account.")); return false; } break; } case TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND: { if(sharesEdit && sharesEdit->value() == 0.0) { QMessageBox::critical(this, tr("Error"), tr("Zero shares not allowed.")); return false; } break; } case TRANSACTION_TYPE_SECURITY_BUY: {} case TRANSACTION_TYPE_SECURITY_SELL: { if(sharesEdit && sharesEdit->value() == 0.0) { QMessageBox::critical(this, tr("Error"), tr("Zero shares not allowed.")); return false; } if(valueEdit && valueEdit->value() == 0.0) { QMessageBox::critical(this, tr("Error"), tr("Zero value not allowed.")); return false; } if(quotationEdit && quotationEdit->value() == 0.0) { QMessageBox::critical(this, tr("Error"), tr("Zero price per share not allowed.")); return false; } /*if(ask_questions && sharesEdit && selectedSecurity() && sharesEdit->value() > selectedSecurity()->shares(dateEdit->date())) { if(QMessageBox::warning(this, tr("Warning"), tr("Number of sold shares are greater than available shares at selected date. Do you want to create the transaction nevertheless?"), QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) { return false; } }*/ break; } default: { if(fromCombo && fromCombo->currentAccount() && fromCombo->currentAccount()->type() == ACCOUNT_TYPE_ASSETS && ((AssetsAccount*) fromCombo->currentAccount())->accountType() == ASSETS_TYPE_SECURITIES) { QMessageBox::critical(this, tr("Error"), tr("Cannot create a regular expense from a securities account.")); return false; } break; } } return true; } bool TransactionEditWidget::modifyTransaction(Transaction *trans) { if(!validValues()) return false; bool b_transsec = (trans->type() == TRANSACTION_TYPE_SECURITY_BUY || trans->type() == TRANSACTION_TYPE_SECURITY_SELL || trans->subtype() == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND); if(b_sec) { if((transtype != TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND || transtype != trans->subtype()) && trans->type() != transtype) return false; if(trans->subtype() == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND) { if(securityCombo) ((ReinvestedDividend*) trans)->setSecurity(selectedSecurity()); if(fromCombo) ((ReinvestedDividend*) trans)->setFromAccount(fromCombo->currentAccount()); } else { if(trans->type() == TRANSACTION_TYPE_SECURITY_BUY) { if(fromCombo) ((SecurityTransaction*) trans)->setAccount(fromCombo->currentAccount()); } else { if(toCombo) ((SecurityTransaction*) trans)->setAccount(toCombo->currentAccount()); } if(securityCombo) ((SecurityTransaction*) trans)->setSecurity(selectedSecurity()); } if(dateEdit) trans->setDate(dateEdit->date()); double shares = 0.0, value = 0.0, share_value = 0.0; if(valueEdit) value = valueEdit->value(); if(sharesEdit) shares = sharesEdit->value(); if(quotationEdit) share_value = quotationEdit->value(); if(!quotationEdit) share_value = value / shares; else if(!sharesEdit) shares = value / share_value; else if(!valueEdit) value = shares * share_value; if(trans->subtype() == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND) { ((ReinvestedDividend*) trans)->setValue(value); ((ReinvestedDividend*) trans)->setShares(shares); if(setQuoteButton && setQuoteButton->isChecked()) ((ReinvestedDividend*) trans)->security()->setQuotation(trans->date(), share_value); } else { ((SecurityTransaction*) trans)->setValue(value); ((SecurityTransaction*) trans)->setShares(shares); if(setQuoteButton && setQuoteButton->isChecked()) ((SecurityTransaction*) trans)->security()->setQuotation(trans->date(), share_value); } if(commentsEdit) trans->setComment(comments()); if(fileEdit) trans->setAssociatedFile(fileEdit->text()); trans->setModified(); return true; } else if(b_transsec) { return false; } if(dateEdit) trans->setDate(dateEdit->date()); if(fromCombo) trans->setFromAccount(fromCombo->currentAccount()); if(toCombo) { if(toCombo->currentAccount() != budget->balancingAccount && trans->toAccount() != budget->balancingAccount) { trans->setToAccount(toCombo->currentAccount()); } } if(depositEdit && trans->type() == TRANSACTION_TYPE_TRANSFER) { ((Transfer*) trans)->setAmount(valueEdit->value(), depositEdit->value()); } else { trans->setValue(valueEdit->value()); } if(descriptionEdit && (trans->type() != TRANSACTION_TYPE_INCOME || !((Income*) trans)->security())) trans->setDescription(descriptionEdit->text()); if(commentsEdit) trans->setComment(comments()); if(fileEdit) trans->setAssociatedFile(fileEdit->text()); if(quantityEdit) trans->setQuantity(quantityEdit->value()); if(payeeEdit && trans->type() == TRANSACTION_TYPE_EXPENSE) ((Expense*) trans)->setPayee(payeeEdit->text()); if(payeeEdit && trans->type() == TRANSACTION_TYPE_INCOME) ((Income*) trans)->setPayer(payeeEdit->text()); if(tagButton) tagButton->modifyTransaction(trans); if(linksWidget) linksWidget->updateTransaction(trans); trans->setModified(); return true; } Security *TransactionEditWidget::selectedSecurity() { if(securityCombo && securityCombo->currentData().isValid()) { return (Security*) securityCombo->currentData().value(); } return security; } Transactions *TransactionEditWidget::createTransactionWithLoan() { if(!validValues()) return NULL; AssetsAccount *loan = new AssetsAccount(budget, ASSETS_TYPE_LIABILITIES, tr("Loan for %1").arg(descriptionEdit->text().isEmpty() ? toCombo->currentAccount()->name() : descriptionEdit->text())); loan->setCurrency((Currency*) currencyCombo->currentData().value()); if(payeeEdit && lenderEdit->text().isEmpty()) loan->setMaintainer(payeeEdit->text()); else loan->setMaintainer(lenderEdit->text()); budget->addAccount(loan); if(is_zero(downPaymentEdit->value())) { Expense *expense = new Expense(budget, valueEdit->value(), dateEdit->date(), (ExpensesAccount*) toCombo->currentAccount(), loan, descriptionEdit->text(), comments()); if(quantityEdit) expense->setQuantity(quantityEdit->value()); if(payeeEdit) expense->setPayee(payeeEdit->text()); if(tagButton) tagButton->modifyTransaction(expense); return expense; } MultiAccountTransaction *split = new MultiAccountTransaction(budget, (CategoryAccount*) toCombo->currentAccount(), descriptionEdit->text()); if(linksWidget) linksWidget->updateTransaction(split); split->setComment(comments()); if(fileEdit) split->setAssociatedFile(fileEdit->text()); if(quantityEdit) split->setQuantity(quantityEdit->value()); Expense *expense = new Expense(budget, valueEdit->value() - downPaymentEdit->value(), dateEdit->date(), (ExpensesAccount*) toCombo->currentAccount(), loan); split->addTransaction(expense); Expense *down_payment = new Expense(budget, downPaymentEdit->value(), dateEdit->date(), (ExpensesAccount*) toCombo->currentAccount(), (AssetsAccount*) fromCombo->currentAccount()); down_payment->setPayee(loan->maintainer()); split->addTransaction(down_payment); if(tagButton) tagButton->modifyTransaction(split); return split; } Transaction *TransactionEditWidget::createTransaction() { if(!validValues()) return NULL; Transaction *trans; if(transtype == TRANSACTION_TYPE_TRANSFER) { if(toCombo && toCombo->currentAccount() == budget->balancingAccount) { trans = new Balancing(budget, -valueEdit->value(), dateEdit ? dateEdit->date() : QDate(), fromCombo ? (AssetsAccount*) fromCombo->currentAccount() : NULL); } else if(fromCombo && fromCombo->currentAccount() == budget->balancingAccount) { trans = new Balancing(budget, valueEdit->value(), dateEdit ? dateEdit->date() : QDate(), toCombo ? (AssetsAccount*) toCombo->currentAccount() : NULL); } else { Transfer *transfer = new Transfer(budget, valueEdit->value(), depositEdit->value(), dateEdit ? dateEdit->date() : QDate(), fromCombo ? (AssetsAccount*) fromCombo->currentAccount() : NULL, toCombo ? (AssetsAccount*) toCombo->currentAccount() : NULL, descriptionEdit ? descriptionEdit->text() : QString(), comments()); trans = transfer; } } else if(transtype == TRANSACTION_TYPE_INCOME) { Income *income = new Income(budget, valueEdit->value(), dateEdit ? dateEdit->date() : QDate(), fromCombo ? (IncomesAccount*) fromCombo->currentAccount() : NULL, toCombo ? (AssetsAccount*) toCombo->currentAccount() : NULL, descriptionEdit ? descriptionEdit->text() : QString(), comments()); if(selectedSecurity()) income->setSecurity(selectedSecurity()); if(quantityEdit) income->setQuantity(quantityEdit->value()); if(payeeEdit) income->setPayer(payeeEdit->text()); trans = income; } else if(transtype == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND) { if(!selectedSecurity()) return NULL; double shares = 0.0, value = 0.0, share_value = 0.0; if(valueEdit) value = valueEdit->value(); if(sharesEdit) shares = sharesEdit->value(); if(quotationEdit) share_value = quotationEdit->value(); if(!quotationEdit) share_value = value / shares; else if(!sharesEdit) shares = value / share_value; else if(!valueEdit) value = shares * share_value; ReinvestedDividend *rediv = new ReinvestedDividend(budget, value, shares, dateEdit ? dateEdit->date() : QDate(), selectedSecurity(), fromCombo ? (IncomesAccount*) fromCombo->currentAccount() : NULL, comments()); if(setQuoteButton && setQuoteButton->isChecked()) selectedSecurity()->setQuotation(rediv->date(), share_value); trans = rediv; } else if(transtype == TRANSACTION_TYPE_SECURITY_BUY) { if(!selectedSecurity()) return NULL; double shares = 0.0, value = 0.0, share_value = 0.0; if(valueEdit) value = valueEdit->value(); if(sharesEdit) shares = sharesEdit->value(); if(quotationEdit) share_value = quotationEdit->value(); if(!quotationEdit) share_value = value / shares; else if(!sharesEdit) shares = value / share_value; else if(!valueEdit) value = shares * share_value; SecurityBuy *secbuy = new SecurityBuy(selectedSecurity(), value, shares, dateEdit ? dateEdit->date() : QDate(), fromCombo ? fromCombo->currentAccount() : NULL, comments()); if(setQuoteButton && setQuoteButton->isChecked()) selectedSecurity()->setQuotation(secbuy->date(), share_value); trans = secbuy; } else if(transtype == TRANSACTION_TYPE_SECURITY_SELL) { if(!selectedSecurity()) return NULL; double shares = 0.0, value = 0.0, share_value = 0.0; if(valueEdit) value = valueEdit->value(); if(sharesEdit) shares = sharesEdit->value(); if(quotationEdit) share_value = quotationEdit->value(); if(!quotationEdit) share_value = value / shares; else if(!sharesEdit) shares = value / share_value; else if(!valueEdit) value = shares * share_value; SecuritySell *secsell = new SecuritySell(selectedSecurity(), value, shares, dateEdit ? dateEdit->date() : QDate(), toCombo ? toCombo->currentAccount() : NULL, comments()); if(setQuoteButton && setQuoteButton->isChecked()) selectedSecurity()->setQuotation(secsell->date(), share_value); trans = secsell; } else { Expense *expense = new Expense(budget, valueEdit->value(), dateEdit ? dateEdit->date() : QDate(), toCombo ? (ExpensesAccount*) toCombo->currentAccount() : NULL, fromCombo ? (AssetsAccount*) fromCombo->currentAccount() : NULL, descriptionEdit ? descriptionEdit->text() : QString(), comments()); if(quantityEdit) expense->setQuantity(quantityEdit->value()); if(payeeEdit) expense->setPayee(payeeEdit->text()); trans = expense; } if(fileEdit) trans->setAssociatedFile(fileEdit->text()); if(tagButton) tagButton->modifyTransaction(trans); if(linksWidget) linksWidget->updateTransaction(trans); return trans; } void TransactionEditWidget::transactionRemoved(Transaction *trans) { if(descriptionEdit && trans->type() == transtype && !trans->description().isEmpty() && default_values.contains(trans->description().toLower()) && default_values[trans->description().toLower()] == trans) { QString lower_description = trans->description().toLower(); default_values[trans->description().toLower()] = NULL; switch(transtype) { case TRANSACTION_TYPE_EXPENSE: { for(TransactionList::const_iterator it = budget->expenses.constEnd(); it != budget->expenses.constBegin();) { --it; Expense *expense = *it; if(expense != trans && expense->description().toLower() == lower_description && expense->subtype() != TRANSACTION_SUBTYPE_DEBT_FEE && expense->subtype() != TRANSACTION_SUBTYPE_DEBT_INTEREST) { default_values[lower_description] = expense; break; } } break; } case TRANSACTION_TYPE_INCOME: { for(TransactionList::const_iterator it = budget->incomes.constEnd(); it != budget->incomes.constBegin();) { --it; Income *income = *it; if(income != trans && !income->security() && income->description().toLower() == lower_description) { default_values[lower_description] = income; break; } } break; } case TRANSACTION_TYPE_TRANSFER: { for(TransactionList::const_iterator it = budget->transfers.constEnd(); it != budget->transfers.constBegin();) { --it; Transfer *transfer = *it; if(transfer != trans && transfer->description().toLower() == lower_description) { default_values[lower_description] = transfer; break; } } break; } default: {} } } if(payeeEdit && transtype == TRANSACTION_TYPE_INCOME && trans->type() == transtype && !((Income*) trans)->payer().isEmpty() && default_payee_values.contains(((Income*) trans)->payer().toLower()) && default_payee_values[((Income*) trans)->payer().toLower()] == trans) { default_payee_values[((Income*) trans)->payer().toLower()] = NULL; QString lower_payee = ((Income*) trans)->payer().toLower(); for(TransactionList::const_iterator it = budget->incomes.constEnd(); it != budget->incomes.constBegin();) { --it; Income *income = *it; if(income != trans && !income->security() && income->payer().toLower() == lower_payee) { default_payee_values[lower_payee] = income; break; } } } if(payeeEdit && transtype == TRANSACTION_TYPE_EXPENSE && trans->type() == transtype && !((Expense*) trans)->payee().isEmpty() && default_payee_values.contains(((Expense*) trans)->payee().toLower()) && default_payee_values[((Expense*) trans)->payee().toLower()] == trans) { default_payee_values[((Expense*) trans)->payee().toLower()] = NULL; QString lower_payee = ((Expense*) trans)->payee().toLower(); for(TransactionList::const_iterator it = budget->expenses.constEnd(); it != budget->expenses.constBegin();) { --it; Expense *expense = *it; if(expense != trans && expense->payee().toLower() == lower_payee && expense->subtype() != TRANSACTION_SUBTYPE_DEBT_FEE && expense->subtype() != TRANSACTION_SUBTYPE_DEBT_INTEREST) { default_payee_values[lower_payee] = expense; break; } } } if(transtype == TRANSACTION_TYPE_INCOME && fromCombo && trans->type() == transtype && default_category_values.contains(trans->fromAccount()) && default_category_values[trans->fromAccount()] == trans) { bool category_found = false; Account *cat = trans->fromAccount(); for(TransactionList::const_iterator it = budget->incomes.constEnd(); it != budget->incomes.constBegin();) { --it; Income *income = *it; if(income != trans && !income->security() && income->fromAccount() == cat) { default_category_values[cat] = income; category_found = true; break; } } if(!category_found) default_category_values.remove(cat); } else if(transtype == TRANSACTION_TYPE_EXPENSE && toCombo && trans->type() == transtype && default_category_values.contains(trans->toAccount()) && default_category_values[trans->toAccount()] == trans) { bool category_found = false; Account *cat = trans->toAccount(); for(TransactionList::const_iterator it = budget->expenses.constEnd(); it != budget->expenses.constBegin();) { --it; Expense *expense = *it; if(expense != trans && expense->toAccount() == cat && expense->subtype() != TRANSACTION_SUBTYPE_DEBT_FEE && expense->subtype() != TRANSACTION_SUBTYPE_DEBT_INTEREST) { default_category_values[cat] = expense; category_found = true; break; } } if(!category_found) default_category_values.remove(cat); } } void TransactionEditWidget::transactionsReset() { if(descriptionEdit) ((QStandardItemModel*) descriptionEdit->completer()->model())->clear(); if(payeeEdit) ((QStandardItemModel*) payeeEdit->completer()->model())->clear(); default_values.clear(); default_payee_values.clear(); default_category_values.clear(); switch(transtype) { case TRANSACTION_TYPE_EXPENSE: { for(TransactionList::const_iterator it = budget->expenses.constEnd(); it != budget->expenses.constBegin();) { --it; Expense *expense = *it; if(expense->subtype() != TRANSACTION_SUBTYPE_DEBT_FEE && expense->subtype() != TRANSACTION_SUBTYPE_DEBT_INTEREST) { if(descriptionEdit && !expense->description().isEmpty() && !default_values.contains(expense->description().toLower())) { QList row; row << new QStandardItem(expense->description()); row << new QStandardItem(expense->description().toLower()); ((QStandardItemModel*) descriptionEdit->completer()->model())->appendRow(row); default_values[expense->description().toLower()] = expense; } if(payeeEdit && !expense->payee().isEmpty() && !default_payee_values.contains(expense->payee().toLower())) { QList row; row << new QStandardItem(expense->payee()); row << new QStandardItem(expense->payee().toLower()); ((QStandardItemModel*) payeeEdit->completer()->model())->appendRow(row); default_payee_values[expense->payee().toLower()] = expense; } if(toCombo && !default_category_values.contains(expense->category())) { default_category_values[expense->category()] = expense; } } } break; } case TRANSACTION_TYPE_INCOME: { for(TransactionList::const_iterator it = budget->incomes.constEnd(); it != budget->incomes.constBegin();) { --it; Income *income = *it; if(!income->security()) { if(descriptionEdit && !income->description().isEmpty() && !default_values.contains(income->description().toLower())) { QList row; row << new QStandardItem(income->description()); row << new QStandardItem(income->description().toLower()); ((QStandardItemModel*) descriptionEdit->completer()->model())->appendRow(row); default_values[income->description().toLower()] = income; } if(payeeEdit && !income->payer().isEmpty() && !default_payee_values.contains(income->payer().toLower())) { QList row; row << new QStandardItem(income->payer()); row << new QStandardItem(income->payer().toLower()); ((QStandardItemModel*) payeeEdit->completer()->model())->appendRow(row); default_payee_values[income->payer().toLower()] = income; } if(fromCombo && !default_category_values.contains(income->category())) { default_category_values[income->category()] = income; } } } break; } case TRANSACTION_TYPE_TRANSFER: { for(TransactionList::const_iterator it = budget->transfers.constEnd(); it != budget->transfers.constBegin();) { --it; Transfer *transfer = *it; if(descriptionEdit && !transfer->description().isEmpty() && !default_values.contains(transfer->description().toLower())) { QList row; row << new QStandardItem(transfer->description()); row << new QStandardItem(transfer->description().toLower()); ((QStandardItemModel*) descriptionEdit->completer()->model())->appendRow(row); default_values[transfer->description().toLower()] = transfer; } } break; } default: {} } if(descriptionEdit) ((QStandardItemModel*) descriptionEdit->completer()->model())->sort(1); if(payeeEdit) ((QStandardItemModel*) payeeEdit->completer()->model())->sort(1); } void TransactionEditWidget::newTag() { QString new_tag = tagButton->createTag(); if(!new_tag.isEmpty()) emit tagAdded(new_tag); } void TransactionEditWidget::setDefaultFromAccount() { if(!fromCombo) return; if((transtype == TRANSACTION_TYPE_INCOME && security) || transtype == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND) { for(TransactionList::const_iterator it = budget->incomes.constEnd(); it != budget->incomes.constBegin();) { --it; Income *income = *it; if(income->security()) { fromCombo->setCurrentAccount(income->category()); break; } } } else if(transtype == TRANSACTION_TYPE_INCOME) { if(budget->incomes.isEmpty()) return; Income *trans = budget->incomes.last(); if(trans) fromCombo->setCurrentAccount(trans->category()); } else if(transtype == TRANSACTION_TYPE_EXPENSE) { if(budget->expenses.isEmpty()) return; Expense *trans = budget->expenses.last(); if(trans) fromCombo->setCurrentAccount(trans->from()); } else if(transtype == TRANSACTION_TYPE_TRANSFER) { if(budget->transfers.isEmpty()) return; Transaction *trans = budget->transfers.last(); if(trans) fromCombo->setCurrentAccount(trans->fromAccount()); } else if(transtype == TRANSACTION_TYPE_SECURITY_BUY) { if(budget->securityTransactions.isEmpty()) return; SecurityTransaction *trans = budget->securityTransactions.last(); if(trans) fromCombo->setCurrentAccount(trans->account()); } } void TransactionEditWidget::setDefaultToAccount() { if(!toCombo) return; if(transtype == TRANSACTION_TYPE_INCOME) { if(budget->incomes.isEmpty()) return; Income *trans = budget->incomes.last(); if(trans) toCombo->setCurrentAccount(trans->to()); } else if(transtype == TRANSACTION_TYPE_EXPENSE) { if(budget->expenses.isEmpty()) return; Expense *trans = budget->expenses.last(); if(trans) toCombo->setCurrentAccount(trans->category()); } else if(transtype == TRANSACTION_TYPE_TRANSFER) { if(budget->transfers.isEmpty()) return; Transaction *trans = budget->transfers.last(); if(trans) toCombo->setCurrentAccount(trans->toAccount()); } else if(transtype == TRANSACTION_TYPE_SECURITY_SELL) { if(budget->securityTransactions.isEmpty()) return; SecurityTransaction *trans = budget->securityTransactions.last(); if(trans) toCombo->setCurrentAccount(trans->account()); } } void TransactionEditWidget::setDefaultAccounts() { setDefaultToAccount(); setDefaultFromAccount(); } void TransactionEditWidget::setAccount(Account *account) { if(fromCombo && (transtype == TRANSACTION_TYPE_EXPENSE || transtype == TRANSACTION_TYPE_TRANSFER || transtype == TRANSACTION_TYPE_SECURITY_BUY)) { fromCombo->setCurrentAccount(account); } else if(toCombo) { toCombo->setCurrentAccount(account); } } void TransactionEditWidget::setFromAccount(Account *account) { if(fromCombo) fromCombo->setCurrentAccount(account); } void TransactionEditWidget::setToAccount(Account *account) { if(toCombo) toCombo->setCurrentAccount(account); } void TransactionEditWidget::setTransaction(Transaction *trans) { if(valueEdit) valueEdit->blockSignals(true); if(sharesEdit) sharesEdit->blockSignals(true); if(quotationEdit) quotationEdit->blockSignals(true); blockSignals(true); b_select_security = false; if(linksWidget) { linksWidget->setTransaction(trans); if(linksWidget->isEmpty()) { linksWidget->hide(); linksLabelLabel->hide(); } else { linksWidget->show(); linksLabelLabel->show(); } } if(trans == NULL) { value_set = false; shares_set = false; sharevalue_set = false; description_changed = false; payee_changed = false; if(dateEdit) dateEdit->setDate(QDate::currentDate()); if(b_sec) { if(sharesEdit) sharesEdit->setValue(0.0); if(quotationEdit) quotationEdit->setValue(0.0); if(valueEdit) valueEdit->setValue(0.0); if(valueEdit) valueEdit->setFocus(); else sharesEdit->setFocus(); } else { if(descriptionEdit) { descriptionEdit->clear(); if(isVisible()) descriptionEdit->setFocus(); } else { if(isVisible()) valueEdit->setFocus(); } valueEdit->setValue(0.0); } if(commentsEditL) commentsEditL->clear(); else if(commentsEditT) commentsEditT->clear(); if(fileEdit) fileEdit->clear(); if(quantityEdit) quantityEdit->setValue(1.0); if(depositEdit) depositEdit->setValue(0.0); if(payeeEdit) payeeEdit->clear(); if(dateEdit) emit dateChanged(dateEdit->date()); } else { value_set = true; shares_set = true; sharevalue_set = true; if(dateEdit) dateEdit->setDate(trans->date()); if(commentsEditL) commentsEditL->setText(trans->comment()); else if(commentsEditT) commentsEditT->setPlainText(trans->comment()); if(fileEdit) fileEdit->setText(trans->associatedFile()); if(toCombo && (!b_sec || transtype == TRANSACTION_TYPE_SECURITY_SELL)) { toCombo->setCurrentAccount(trans->toAccount()); } if(fromCombo && (!b_sec || transtype == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND || transtype == TRANSACTION_TYPE_SECURITY_BUY)) { fromCombo->setCurrentAccount(trans->fromAccount()); } if(depositEdit) { if(valueEdit) valueEdit->setValue(trans->fromValue()); depositEdit->setValue(trans->toValue()); } else if(valueEdit) { valueEdit->setValue(trans->value()); } if(b_sec) { if((transtype != TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND || transtype != trans->subtype()) && trans->type() != transtype) return; //if(transtype == TRANSACTION_TYPE_SECURITY_SELL) setMaxShares(((SecurityTransaction*) trans)->security()->shares(QDate::currentDate()) + ((SecurityTransaction*) trans)->shares()); if(sharesEdit) sharesEdit->setValue(trans->subtype() == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND ? ((ReinvestedDividend*) trans)->shares() : ((SecurityTransaction*) trans)->shares()); if(quotationEdit) { quotationEdit->setValue(trans->value() / (trans->subtype() == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND ? ((ReinvestedDividend*) trans)->shares() : ((SecurityTransaction*) trans)->shares())); if(setQuoteButton) { Security *sec = (trans->subtype() == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND ? ((ReinvestedDividend*) trans)->security() : ((SecurityTransaction*) trans)->security()); setQuoteButton->blockSignals(true); if(sec->currency() == quotationEdit->currency()) { setQuoteButton->setChecked(sec->hasQuotation(trans->date()) && sec->getQuotation(trans->date()) == quotationEdit->value()); setQuoteButton->setEnabled(true); } else { b_prev_update_quote = setQuoteButton->isChecked(); setQuoteButton->setChecked(false); setQuoteButton->setEnabled(false); } setQuoteButton->blockSignals(false); } } if(isVisible()) { if(valueEdit) valueEdit->setFocus(); else sharesEdit->setFocus(); } } else { description_changed = false; payee_changed = false; if(descriptionEdit) { descriptionEdit->setText(trans->description()); if(isVisible()) { descriptionEdit->setFocus(); descriptionEdit->selectAll(); } } else { if(isVisible()) valueEdit->setFocus(); } if(quantityEdit) quantityEdit->setValue(trans->quantity()); if(payeeEdit && trans->type() == TRANSACTION_TYPE_EXPENSE) payeeEdit->setText(((Expense*) trans)->payee()); if(payeeEdit && trans->type() == TRANSACTION_TYPE_INCOME) payeeEdit->setText(((Income*) trans)->payer()); } if(dateEdit) emit dateChanged(trans->date()); } if(tagButton) tagButton->setTransaction(trans); blockSignals(false); if(valueEdit) valueEdit->blockSignals(false); if(sharesEdit) sharesEdit->blockSignals(false); if(quotationEdit) quotationEdit->blockSignals(false); emit propertyChanged(); } void TransactionEditWidget::setTransaction(Transaction *trans, const QDate &date) { if(dateEdit) dateEdit->blockSignals(true); setTransaction(trans); if(dateEdit) { dateEdit->setDate(date); dateEdit->blockSignals(false); emit dateChanged(date); } } void TransactionEditWidget::setMultiAccountTransaction(MultiAccountTransaction *split, QDate date) { if(!split) { setTransaction(NULL); return; } if(linksWidget) { linksWidget->setTransaction(split); if(linksWidget->isEmpty()) { linksWidget->hide(); linksLabelLabel->hide(); } else { linksWidget->show(); linksLabelLabel->show(); } } blockSignals(true); b_select_security = false; if(valueEdit) valueEdit->blockSignals(true); if(dateEdit) dateEdit->setDate(date.isValid() ? date : split->date()); if(dateEdit) emit dateChanged(date.isValid() ? date : split->date()); if(commentsEditL) commentsEditL->setText(split->comment()); else if(commentsEditT) commentsEditT->setPlainText(split->comment()); if(fileEdit) fileEdit->setText(split->associatedFile()); double v = 0.0; int split_i = -1; for(int i = 0; i < split->count(); i++) { if(i == 0 || split->at(i)->value(true) > v) {split_i = i; v = split->at(i)->value(true);} } v = split->value(); if(split->transactiontype() == TRANSACTION_TYPE_EXPENSE) { if(toCombo) { toCombo->setCurrentAccount(split->category()); } if(fromCombo && split_i >= 0) { Account *acc = split->at(split_i)->fromAccount(); if(acc) { fromCombo->setCurrentAccount(acc); if(budget->defaultTransactionConversionRateDate() == TRANSACTION_CONVERSION_RATE_AT_DATE) v = budget->defaultCurrency()->convertTo(v, acc->currency(), date.isValid() ? date : split->at(split_i)->date()); else v = budget->defaultCurrency()->convertTo(v, acc->currency()); } } } else { if(fromCombo) { fromCombo->setCurrentAccount(split->category()); } if(toCombo && split_i >= 0) { Account *acc = split->at(split_i)->toAccount(); if(acc) { toCombo->setCurrentAccount(acc); if(budget->defaultTransactionConversionRateDate() == TRANSACTION_CONVERSION_RATE_AT_DATE) v = budget->defaultCurrency()->convertTo(v, acc->currency(), date.isValid() ? date : split->at(split_i)->date()); else v = budget->defaultCurrency()->convertTo(v, acc->currency()); } } } description_changed = false; payee_changed = false; if(descriptionEdit) { descriptionEdit->setText(split->description()); if(isVisible()) { descriptionEdit->setFocus(); descriptionEdit->selectAll(); } } else { if(isVisible()) valueEdit->enterFocus(); } valueEdit->setValue(v); if(quantityEdit) quantityEdit->setValue(split->quantity()); if(payeeEdit) payeeEdit->setText(split->payeeText()); if(tagButton) tagButton->setTransaction(split); blockSignals(false); emit propertyChanged(); } TransactionEditDialog::TransactionEditDialog(bool extra_parameters, int transaction_type, Currency *split_currency, bool transfer_to, Security *security, SecurityValueDefineType security_value_type, bool select_security, Budget *budg, QWidget *parent, bool allow_account_creation, bool multiaccount, bool withloan) : QDialog(parent) { setModal(true); QVBoxLayout *box1 = new QVBoxLayout(this); switch(transaction_type) { case TRANSACTION_TYPE_EXPENSE: {setWindowTitle(tr("Edit Expense")); break;} case TRANSACTION_TYPE_INCOME: { if(security || select_security) setWindowTitle(tr("Edit Dividend")); else setWindowTitle(tr("Edit Income")); break; } case TRANSACTION_TYPE_TRANSFER: {setWindowTitle(tr("Edit Transfer")); break;} case TRANSACTION_TYPE_SECURITY_BUY: {setWindowTitle(tr("Edit Securities Purchase", "Financial security (e.g. stock, mutual fund)")); break;} case TRANSACTION_TYPE_SECURITY_SELL: {setWindowTitle(tr("Edit Securities Sale", "Financial security (e.g. stock, mutual fund)")); break;} case TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND: {setWindowTitle(tr("Edit Reinvested Dividend")); break;} } editWidget = new TransactionEditWidget(false, extra_parameters, transaction_type, split_currency, transfer_to, security, security_value_type, select_security, budg, this, allow_account_creation, multiaccount, withloan); box1->addWidget(editWidget); editWidget->transactionsReset(); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, this); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept())); box1->addWidget(buttonBox); } void TransactionEditDialog::accept() { if(editWidget->validValues(true)) { QDialog::accept(); } } void TransactionEditDialog::keyPressEvent(QKeyEvent *e) { if(e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) return; QDialog::keyPressEvent(e); } MultipleTransactionsEditDialog::MultipleTransactionsEditDialog(bool extra_parameters, int transaction_type, Budget *budg, QWidget *parent, bool allow_account_creation) : QDialog(parent), transtype(transaction_type), budget(budg), b_extra(extra_parameters), b_create_accounts(allow_account_creation) { setWindowTitle(tr("Modify Transactions")); setModal(true); added_account = NULL; /*int rows = 4; if(b_extra && (transtype == TRANSACTION_TYPE_EXPENSE || transtype == TRANSACTION_TYPE_INCOME)) rows= 5; else if(transtype == TRANSACTION_TYPE_TRANSFER) rows = 3; else rows = 2;*/ QVBoxLayout *box1 = new QVBoxLayout(this); QGridLayout *editLayout = new QGridLayout(); box1->addLayout(editLayout); descriptionButton = new QCheckBox(tr("Description:", "Transaction description property (transaction title/generic article name)"), this); descriptionButton->setChecked(false); editLayout->addWidget(descriptionButton, 0, 0); descriptionEdit = new QLineEdit(this); descriptionEdit->setEnabled(false); editLayout->addWidget(descriptionEdit, 0, 1); valueButton = NULL; valueEdit = NULL; if(transtype == TRANSACTION_TYPE_EXPENSE || transtype == TRANSACTION_TYPE_INCOME || transtype == TRANSACTION_TYPE_TRANSFER) { if(transtype == TRANSACTION_TYPE_TRANSFER) valueButton = new QCheckBox(tr("Amount:"), this); else if(transtype == TRANSACTION_TYPE_INCOME) valueButton = new QCheckBox(tr("Income:"), this); else valueButton = new QCheckBox(tr("Cost:"), this); valueButton->setChecked(false); editLayout->addWidget(valueButton, 1, 0); valueEdit = new EqonomizeValueEdit(false, this, budget); valueEdit->setEnabled(false); editLayout->addWidget(valueEdit, 1, 1); } dateButton = new QCheckBox(tr("Date:"), this); dateButton->setChecked(false); editLayout->addWidget(dateButton, 2, 0); dateEdit = new EqonomizeDateEdit(QDate::currentDate(), this); dateEdit->setCalendarPopup(true); dateEdit->setEnabled(false); editLayout->addWidget(dateEdit, 2, 1); categoryButton = NULL; categoryCombo = NULL; if(transtype == TRANSACTION_TYPE_EXPENSE || transtype == TRANSACTION_TYPE_INCOME) { categoryButton = new QCheckBox(tr("Category:"), this); categoryButton->setChecked(false); editLayout->addWidget(categoryButton, 3, 0); categoryCombo = new AccountComboBox(transtype == TRANSACTION_TYPE_EXPENSE ? ACCOUNT_TYPE_EXPENSES : ACCOUNT_TYPE_INCOMES, budget, b_create_accounts, false, false, true, true, this); categoryCombo->setEnabled(false); updateAccounts(); editLayout->addWidget(categoryCombo, 3, 1); connect(categoryButton, SIGNAL(toggled(bool)), categoryCombo, SLOT(setEnabled(bool))); } payeeButton = NULL; payeeEdit = NULL; if(b_extra && (transtype == TRANSACTION_TYPE_EXPENSE || transtype == TRANSACTION_TYPE_INCOME)) { if(transtype == TRANSACTION_TYPE_INCOME) payeeButton = new QCheckBox(tr("Payer:"), this); else payeeButton = new QCheckBox(tr("Payee:"), this); payeeButton->setChecked(false); editLayout->addWidget(payeeButton, 4, 0); payeeEdit = new QLineEdit(this); payeeEdit->setEnabled(false); editLayout->addWidget(payeeEdit, 4, 1); connect(payeeButton, SIGNAL(toggled(bool)), payeeEdit, SLOT(setEnabled(bool))); } QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, this); buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject())); connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept())); box1->addWidget(buttonBox); if(categoryCombo) connect(categoryCombo, SIGNAL(newAccountRequested()), this, SLOT(newCategory())); connect(descriptionButton, SIGNAL(toggled(bool)), descriptionEdit, SLOT(setEnabled(bool))); if(valueButton) connect(valueButton, SIGNAL(toggled(bool)), valueEdit, SLOT(setEnabled(bool))); connect(dateButton, SIGNAL(toggled(bool)), dateEdit, SLOT(setEnabled(bool))); } void MultipleTransactionsEditDialog::newCategory() { categoryCombo->createAccount(); } void MultipleTransactionsEditDialog::setTransaction(Transaction *trans) { if(trans) { descriptionEdit->setText(trans->description()); dateEdit->setDate(trans->date()); if(valueEdit) { valueEdit->setValue(trans->value()); valueEdit->setCurrency(trans->currency()); } if(transtype == TRANSACTION_TYPE_EXPENSE) { categoryCombo->setCurrentAccount(((Expense*) trans)->category()); if(payeeEdit) payeeEdit->setText(((Expense*) trans)->payee()); } else if(transtype == TRANSACTION_TYPE_INCOME) { categoryCombo->setCurrentAccount(((Income*) trans)->category()); if(payeeEdit) payeeEdit->setText(((Income*) trans)->payer()); } } else { descriptionEdit->clear(); dateEdit->setDate(QDate::currentDate()); if(valueEdit) { valueEdit->setValue(0.0); valueEdit->setCurrency(budget->defaultCurrency()); } if(payeeEdit) payeeEdit->clear(); } } void MultipleTransactionsEditDialog::setTransaction(Transaction *trans, const QDate &date) { setTransaction(trans); dateEdit->setDate(date); } void MultipleTransactionsEditDialog::updateAccounts() { if(!categoryCombo) return; categoryCombo->updateAccounts(); } bool MultipleTransactionsEditDialog::modifyTransaction(Transaction *trans, bool change_parent) { if(!validValues()) return false; bool b_descr = true, b_value = true, b_payee = true, b_category = true, b_date = true; if(trans->parentSplit()) { switch(trans->parentSplit()->type()) { case SPLIT_TRANSACTION_TYPE_MULTIPLE_ITEMS: { b_date = false; if(change_parent) { MultiItemTransaction *split = (MultiItemTransaction*) trans->parentSplit(); if(dateButton->isChecked()) split->setDate(dateEdit->date()); if(payeeEdit && payeeButton->isChecked()) split->setPayee(payeeEdit->text()); } break; } case SPLIT_TRANSACTION_TYPE_MULTIPLE_ACCOUNTS: { b_descr = false; b_category = false; if(change_parent) { MultiAccountTransaction *split = (MultiAccountTransaction*) trans->parentSplit(); if(dateButton->isChecked()) split->setDate(dateEdit->date()); if(descriptionButton->isChecked()) split->setDescription(descriptionEdit->text()); if(categoryButton && categoryButton->isChecked()) split->setCategory((CategoryAccount*) categoryCombo->currentAccount()); } break; } case SPLIT_TRANSACTION_TYPE_LOAN: { b_payee = false; b_category = false; b_date = false; b_descr = false; if(change_parent) { DebtPayment *split = (DebtPayment*) trans->parentSplit(); if(dateButton->isChecked()) split->setDate(dateEdit->date()); if(categoryButton && categoryButton->isChecked()) split->setExpenseCategory((ExpensesAccount*) categoryCombo->currentAccount()); } break; } } } switch(trans->type()) { case TRANSACTION_TYPE_EXPENSE: { if(b_category && categoryButton && transtype == trans->type() && categoryButton->isChecked()) ((Expense*) trans)->setCategory((ExpensesAccount*) categoryCombo->currentAccount()); if(b_payee && payeeEdit && payeeButton->isChecked()) ((Expense*) trans)->setPayee(payeeEdit->text()); break; } case TRANSACTION_TYPE_INCOME: { if(((Income*) trans)->security()) b_descr = false; else if(b_payee && payeeEdit && payeeButton->isChecked()) ((Income*) trans)->setPayer(payeeEdit->text()); if(b_category && categoryButton && transtype == trans->type() && categoryButton->isChecked()) ((Income*) trans)->setCategory((IncomesAccount*) categoryCombo->currentAccount()); break; } case TRANSACTION_TYPE_TRANSFER: { break; } case TRANSACTION_TYPE_SECURITY_BUY: { if(b_category && categoryButton && transtype == TRANSACTION_TYPE_INCOME && categoryButton->isChecked()) ((SecurityTransaction*) trans)->setAccount(categoryCombo->currentAccount()); b_descr = false; b_value = false; break; } case TRANSACTION_TYPE_SECURITY_SELL: { if(b_category && categoryButton && transtype == TRANSACTION_TYPE_INCOME && categoryButton->isChecked()) ((SecurityTransaction*) trans)->setAccount(categoryCombo->currentAccount()); b_descr = false; b_value = false; break; } } if(b_descr && descriptionButton->isChecked()) trans->setDescription(descriptionEdit->text()); if(valueEdit && b_value && valueButton->isChecked()) trans->setValue(valueEdit->value()); if(b_date && dateButton->isChecked()) trans->setDate(dateEdit->date()); trans->setModified(); return true; } bool MultipleTransactionsEditDialog::modifySplitTransaction(SplitTransaction *trans) { if(!validValues()) return false; if(!dateButton->isChecked() && (!payeeEdit || !payeeButton->isChecked())) return false; switch(trans->type()) { case SPLIT_TRANSACTION_TYPE_MULTIPLE_ITEMS: { MultiItemTransaction *split = (MultiItemTransaction*) trans; if(dateButton->isChecked()) split->setDate(dateEdit->date()); if(payeeEdit && payeeButton->isChecked()) split->setPayee(payeeEdit->text()); trans->setModified(); return true; } case SPLIT_TRANSACTION_TYPE_MULTIPLE_ACCOUNTS: { break; } case SPLIT_TRANSACTION_TYPE_LOAN: { DebtPayment *split = (DebtPayment*) trans; if(dateButton->isChecked()) { split->setDate(dateEdit->date()); trans->setModified(); return true; } break; } } return false; } bool MultipleTransactionsEditDialog::checkAccounts() { if(!categoryCombo) return true; switch(transtype) { case TRANSACTION_TYPE_INCOME: { if(!categoryButton->isChecked()) return true; if(!categoryCombo->hasAccount()) { QMessageBox::critical(this, tr("Error"), tr("No income category available.")); return false; } break; } case TRANSACTION_TYPE_EXPENSE: { if(!categoryButton->isChecked()) return true; if(!categoryCombo->hasAccount()) { QMessageBox::critical(this, tr("Error"), tr("No expense category available.")); return false; } break; } default: {} } return true; } bool MultipleTransactionsEditDialog::validValues() { if(dateButton->isChecked() && !dateEdit->date().isValid()) { QMessageBox::critical(this, tr("Error"), tr("Invalid date.")); dateEdit->setFocus(); dateEdit->selectAll(); return false; } if(!checkAccounts()) return false; if(categoryCombo && !categoryCombo->currentAccount()) return false; return true; } void MultipleTransactionsEditDialog::accept() { if(!descriptionButton->isChecked() && (!valueButton || !valueButton->isChecked()) && !dateButton->isChecked() && (!categoryButton || !categoryButton->isChecked()) && (!payeeButton || !payeeButton->isChecked())) { reject(); } else if(validValues()) { QDialog::accept(); } } QDate MultipleTransactionsEditDialog::date() { if(!dateButton->isChecked()) return QDate(); return dateEdit->date(); } Eqonomize-1.5.3/src/transactioneditwidget.h000066400000000000000000000242011416454732000210320ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016-2020 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifndef TRANSACTION_EDIT_WIDGET_H #define TRANSACTION_EDIT_WIDGET_H #include #include #include #include #include #include #include #include #include #include class QCheckBox; class QLabel; class QLineEdit; class QComboBox; class QHBoxLayout; class QGridLayout; class QPlainTextEdit; class EqonomizeDateEdit; class QDateEdit; class TagMenu; class TagButton; class LinksWidget; class Budget; class Account; class AccountComboBox; class EqonomizeValueEdit; class Security; class Transaction; class Transactions; class MultiAccountTransaction; class SplitTransaction; class Currency; typedef enum { SECURITY_ALL_VALUES, SECURITY_SHARES_AND_QUOTATION, SECURITY_VALUE_AND_SHARES, SECURITY_VALUE_AND_QUOTATION } SecurityValueDefineType; class TransactionEditWidget : public QWidget { Q_OBJECT public: TransactionEditWidget(bool auto_edit, bool extra_parameters, int transaction_type, Currency *split_currency, bool transfer_to, Security *security, SecurityValueDefineType security_value_type, bool select_security, Budget *budg, QWidget *parent = 0, bool allow_account_creation = false, bool multiaccount = false, bool withloan = false); void useMultipleCurrencies(bool b); void setTransaction(Transaction *trans); void setMultiAccountTransaction(MultiAccountTransaction *split, QDate date = QDate()); void setTransaction(Transaction *strans, const QDate &date); void updateFromAccounts(Account *exclude_account = NULL, Currency *force_currency = NULL, bool set_default = false); void updateToAccounts(Account *exclude_account = NULL, Currency *force_currency = NULL, bool set_default = false); void updateAccounts(Account *exclude_account = NULL, Currency *force_currency = NULL, bool set_default = false); void transactionsReset(); void setDefaultFromAccount(); void setDefaultToAccount(); void setDefaultAccounts(); void setAccount(Account *account); void setToAccount(Account *account); void setFromAccount(Account *account); void focusFirst(); bool firstHasFocus() const; QHBoxLayout *bottomLayout(); void transactionRemoved(Transaction *trans); void transactionAdded(Transaction *trans); void transactionModified(Transaction *trans); void tagsModified(); bool modifyTransaction(Transaction *trans); Transaction *createTransaction(); Transactions *createTransactionWithLoan(); bool validValues(bool ask_questions = false); void setValues(QString description_value, double value_value, double quantity_value, QDate date_value, Account *from_account_value, Account *to_account_value, QString payee_value, QString comment_value); void setPayee(QString payee); QDate date(); QString description() const; QString payee() const; QString comments() const; double value() const; double quantity() const; Account *fromAccount() const; Account *toAccount() const; Security *selectedSecurity(); void setMaxShares(double max); void setMaxSharesDate(QDate quotation_date); bool checkAccounts(); void currentDateChanged(const QDate &olddate, const QDate &newdate); bool isCleared(); protected: QHash default_values; QHash default_payee_values; QHash default_category_values; int transtype; bool description_changed, payee_changed; Budget *budget; Security *security; bool b_autoedit, b_sec, b_extra; bool value_set, shares_set, sharevalue_set; QDate shares_date; bool b_create_accounts; bool b_multiple_currencies; bool b_select_security; int b_prev_update_quote; Currency *splitcurrency; int dateRow, dateLabelCol, dateEditCol, depositRow, depositLabelCol, depositEditCol; QLineEdit *descriptionEdit, *lenderEdit, *payeeEdit, *fileEdit, *commentsEditL; QWidget *commentsEdit; QPlainTextEdit *commentsEditT; AccountComboBox *fromCombo, *toCombo; QComboBox *securityCombo, *currencyCombo; QCheckBox *setQuoteButton; QLabel *withdrawalLabel, *depositLabel, *dateLabel, *linksLabelLabel; LinksWidget *linksWidget; EqonomizeValueEdit *valueEdit, *depositEdit, *downPaymentEdit, *sharesEdit, *quotationEdit, *quantityEdit; QPushButton *maxSharesButton; TagButton *tagButton; EqonomizeDateEdit *dateEdit; QHBoxLayout *bottom_layout; QGridLayout *editLayout; signals: void addmodify(); void dateChanged(const QDate&); void accountAdded(Account*); void currenciesModified(); void multipleAccountsRequested(); void newLoanRequested(); void propertyChanged(); void tagAdded(QString); public slots: void selectFile(); void openFile(); void newFromAccount(); void newToAccount(); void valueNextField(); void fromActivated(); void toActivated(); void fromChanged(Account*); void toChanged(Account*); void focusDate(); void valueEditingFinished(); void valueChanged(double); void securityChanged(int = -1); void currencyChanged(int); void sharesChanged(double); void quotationChanged(double); void descriptionChanged(const QString&); void setDefaultValue(); void payeeChanged(const QString&); void setDefaultValueFromPayee(); void setDefaultValueFromCategory(); void maxShares(); void setQuoteToggled(bool); void newTag(); }; class TransactionEditDialog : public QDialog { Q_OBJECT public: TransactionEditDialog(bool extra_parameters, int transaction_type, Currency *split_currency, bool transfer_to, Security *security, SecurityValueDefineType security_value_type, bool select_security, Budget *budg, QWidget *parent, bool allow_account_creation = false, bool multiaccount = false, bool withloan = false); TransactionEditWidget *editWidget; protected: void keyPressEvent(QKeyEvent*); protected slots: void accept(); }; class MultipleTransactionsEditDialog : public QDialog { Q_OBJECT public: MultipleTransactionsEditDialog(bool extra_parameters, int transaction_type, Budget *budg, QWidget *parent = 0, bool allow_account_creation = false); void setTransaction(Transaction *trans); void setTransaction(Transaction *strans, const QDate &date); void updateAccounts(); bool modifyTransaction(Transaction *trans, bool change_parent = false); bool modifySplitTransaction(SplitTransaction *trans); bool validValues(); bool checkAccounts(); QDate date(); QCheckBox *descriptionButton, *valueButton, *categoryButton, *dateButton, *payeeButton; protected: int transtype; Budget *budget; bool b_extra; bool b_create_accounts; QVector categories; QLineEdit *descriptionEdit, *payeeEdit; AccountComboBox *categoryCombo; EqonomizeValueEdit *valueEdit; QDateEdit *dateEdit; Account *added_account; protected slots: void newCategory(); void accept(); }; class TagMenu : public QMenu { Q_OBJECT public: TagMenu(Budget*, QWidget *parent = NULL, bool allow_new = false); void setTransaction(Transactions *trans); void setTransactions(QList list); void modifyTransaction(Transactions *trans, bool append = false); int selectedTagsCount(); QString selectedTagsText(); void setTagSelected(QString, bool b = true, bool inconsistent = false); QString createTag(); protected: QHash tag_actions; void keyPressEvent(QKeyEvent *e); void mouseReleaseEvent(QMouseEvent *e); Budget *budget; bool allow_new; protected slots: void tagToggled(); public slots: void updateTags(); signals: void selectedTagsChanged(); void newTagRequested(); }; class TagButton : public QPushButton { Q_OBJECT public: TagButton(bool small_button, bool allow_new_tag, Budget *budg, QWidget *parent = NULL); void setTagSelected(QString tag, bool b = true, bool inconsistent = false); void setTransaction(Transactions *trans); void setTransactions(QList list); void modifyTransaction(Transactions *trans, bool append = false); QString createTag(); bool icon_shown; public slots: void resizeTagMenu(); void updateText(); void updateTags(); protected: TagMenu *tagMenu; bool b_small; void keyPressEvent(QKeyEvent *e); signals: void returnPressed(); void newTagRequested(); }; class LinksWidget : public QWidget { Q_OBJECT protected: QLabel *linksLabel; QPushButton *removeButton; bool b_editable, b_links; int first_parent_link; QList links; public: LinksWidget(QWidget *parent, bool is_active = true); void setTransaction(Transactions *trans); void updateTransaction(Transactions *trans); void updateLabel(); bool isEmpty(); public slots: void linkClicked(const QString&); void removeLink(); }; class CommentsTextEdit : public QPlainTextEdit { public: CommentsTextEdit(QWidget *parent = 0); QSize sizeHint() const; protected: void keyPressEvent(QKeyEvent *e); }; #endif Eqonomize-1.5.3/src/transactionfilterwidget.cpp000066400000000000000000001145271416454732000217400ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016-2020 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "budget.h" #include "eqonomizevalueedit.h" #include "transactionfilterwidget.h" #include TransactionFilterWidget::TransactionFilterWidget(bool extra_parameters, int transaction_type, Budget *budg, QWidget *parent) : QWidget(parent), transtype(transaction_type), budget(budg), b_extra(extra_parameters) { tagCombo = NULL; excludeSubsButton = NULL; QGridLayout *filterLayout = new QGridLayout(this); dateFromButton = new QCheckBox(tr("From:"), this); dateFromButton->setChecked(false); filterLayout->addWidget(dateFromButton, 0, 0); dateFromEdit = new EqonomizeDateEdit(QDate::currentDate(), this); dateFromEdit->setCalendarPopup(true); dateFromEdit->setEnabled(false); filterLayout->addWidget(dateFromEdit, 0, 1); filterLayout->addWidget(new QLabel(tr("To:"), this), 0, 2); dateToEdit = new EqonomizeDateEdit(QDate::currentDate(), this); dateToEdit->setCalendarPopup(true); filterLayout->addWidget(dateToEdit, 0, 3); QDate curdate = QDate::currentDate(); from_date.setDate(curdate.year(), curdate.month(), 1); dateFromEdit->setDate(from_date); to_date = curdate; dateToEdit->setDate(to_date); if(transtype == TRANSACTION_TYPE_TRANSFER) { filterLayout->addWidget(new QLabel(tr("From:"), this), 2, 0); fromCombo = new QComboBox(this); fromCombo->setEditable(false); filterLayout->addWidget(fromCombo, 2, 1); filterLayout->addWidget(new QLabel(tr("To:"), this), 2, 2); toCombo = new QComboBox(this); toCombo->setEditable(false); filterLayout->addWidget(toCombo, 2, 3); minButton = new QCheckBox(tr("Min amount:"), this); maxButton = new QCheckBox(tr("Max amount:"), this); } else if(transtype == TRANSACTION_TYPE_INCOME) { filterLayout->addWidget(new QLabel(tr("Category:"), this), 2, 0); fromCombo = new QComboBox(this); fromCombo->setEditable(false); filterLayout->addWidget(fromCombo, 2, 1); filterLayout->addWidget(new QLabel(tr("To account:"), this), 2, 2); toCombo = new QComboBox(this); toCombo->setEditable(false); filterLayout->addWidget(toCombo, 2, 3); minButton = new QCheckBox(tr("Min income:"), this); maxButton = new QCheckBox(tr("Max income:"), this); } else { filterLayout->addWidget(new QLabel(tr("Category:"), this), 2, 0); toCombo = new QComboBox(this); toCombo->setEditable(false); filterLayout->addWidget(toCombo, 2, 1); filterLayout->addWidget(new QLabel(tr("From account:"), this), 2, 2); fromCombo = new QComboBox(this); fromCombo->setEditable(false); filterLayout->addWidget(fromCombo, 2, 3); minButton = new QCheckBox(tr("Min cost:"), this); maxButton = new QCheckBox(tr("Max cost:"), this); } filterLayout->addWidget(minButton, 1, 0); minEdit = new EqonomizeValueEdit(false, this, budget); minEdit->setEnabled(false); filterLayout->addWidget(minEdit, 1, 1); filterLayout->addWidget(maxButton, 1, 2); maxEdit = new EqonomizeValueEdit(false, this, budget); maxEdit->setEnabled(false); QSizePolicy sp = maxEdit->sizePolicy(); sp.setHorizontalPolicy(QSizePolicy::Expanding); maxEdit->setSizePolicy(sp); filterLayout->addWidget(maxEdit, 1, 3); filterLayout->addWidget(new QLabel(tr("Description:", "Transaction description property (transaction title/generic article name)"), this), 3, 0); descriptionEdit = new QLineEdit(this); descriptionEdit->setCompleter(new QCompleter(this)); descriptionEdit->completer()->setModel(new QStandardItemModel(this)); descriptionEdit->completer()->setModelSorting(QCompleter::CaseInsensitivelySortedModel); descriptionEdit->completer()->setCaseSensitivity(Qt::CaseInsensitive); filterLayout->addWidget(descriptionEdit, 3, 1); if(b_extra && (transtype == TRANSACTION_TYPE_EXPENSE || transtype == TRANSACTION_TYPE_INCOME)) { filterLayout->addWidget(new QLabel(tr("Tag:"), this), 3, 2); tagCombo = new QComboBox(this); tagCombo->setEditable(false); filterLayout->addWidget(tagCombo, 3, 3); } QHBoxLayout *filterExcludeLayout = new QHBoxLayout(); group = new QButtonGroup(this); includeButton = new QRadioButton(tr("Include"), this); includeButton->setChecked(true); group->addButton(includeButton); filterExcludeLayout->addWidget(includeButton); excludeButton = new QRadioButton(tr("Exclude"), this); group->addButton(excludeButton); filterExcludeLayout->addWidget(excludeButton); exactMatchButton = new QCheckBox(tr("Exact match"), this); filterExcludeLayout->addWidget(exactMatchButton); if(b_extra && (transtype == TRANSACTION_TYPE_EXPENSE || transtype == TRANSACTION_TYPE_INCOME)) { excludeSubsButton = new QCheckBox(tr("Exclude subcategories"), this); filterExcludeLayout->addWidget(excludeSubsButton); } filterExcludeLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum)); clearButton = new QPushButton(tr("Clear"), this); clearButton->setEnabled(false); filterExcludeLayout->addWidget(clearButton); if(b_extra) { filterLayout->addLayout(filterExcludeLayout, 4, 0, 1, 4); } else { filterLayout->addLayout(filterExcludeLayout, 3, 2, 1, 2); filterLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Expanding), 4, 0, 1, 4); } fromCombo->addItem(tr("All"), QVariant::fromValue((void*) NULL)); toCombo->addItem(tr("All"), QVariant::fromValue((void*) NULL)); if(tagCombo) { tagCombo->addItem(tr("All")); connect(tagCombo, SIGNAL(activated(int)), this, SIGNAL(filter())); connect(tagCombo, SIGNAL(activated(int)), this, SLOT(checkEnableClear())); } connect(clearButton, SIGNAL(clicked()), this, SLOT(clearFilter())); #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) connect(group, SIGNAL(idClicked(int)), this, SIGNAL(filter())); #else connect(group, SIGNAL(buttonClicked(int)), this, SIGNAL(filter())); #endif connect(dateFromButton, SIGNAL(toggled(bool)), dateFromEdit, SLOT(setEnabled(bool))); connect(dateFromButton, SIGNAL(toggled(bool)), this, SIGNAL(filter())); connect(dateFromButton, SIGNAL(toggled(bool)), this, SLOT(checkEnableClear())); connect(dateFromEdit, SIGNAL(dateChanged(const QDate&)), this, SLOT(fromChanged(const QDate&))); connect(dateToEdit, SIGNAL(dateChanged(const QDate&)), this, SLOT(toChanged(const QDate&))); connect(dateToEdit, SIGNAL(dateChanged(const QDate&)), this, SLOT(checkEnableClear())); connect(toCombo, SIGNAL(activated(int)), this, SIGNAL(filter())); connect(fromCombo, SIGNAL(activated(int)), this, SIGNAL(filter())); connect(toCombo, SIGNAL(activated(int)), this, SLOT(checkEnableClear())); connect(fromCombo, SIGNAL(activated(int)), this, SLOT(checkEnableClear())); connect(toCombo, SIGNAL(activated(int)), this, SLOT(onToActivated(int))); connect(fromCombo, SIGNAL(activated(int)), this, SLOT(onFromActivated(int))); connect(descriptionEdit, SIGNAL(textChanged(const QString&)), this, SIGNAL(filter())); connect(descriptionEdit, SIGNAL(textChanged(const QString&)), this, SLOT(checkEnableClear())); connect(minButton, SIGNAL(toggled(bool)), this, SIGNAL(filter())); connect(minButton, SIGNAL(toggled(bool)), this, SLOT(checkEnableClear())); connect(minButton, SIGNAL(toggled(bool)), minEdit, SLOT(setEnabled(bool))); connect(minEdit, SIGNAL(valueChanged(double)), this, SIGNAL(filter())); connect(maxButton, SIGNAL(toggled(bool)), this, SIGNAL(filter())); connect(maxButton, SIGNAL(toggled(bool)), this, SLOT(checkEnableClear())); connect(maxButton, SIGNAL(toggled(bool)), maxEdit, SLOT(setEnabled(bool))); connect(maxEdit, SIGNAL(valueChanged(double)), this, SIGNAL(filter())); connect(exactMatchButton, SIGNAL(toggled(bool)), this, SIGNAL(filter())); if(excludeSubsButton) connect(excludeSubsButton, SIGNAL(toggled(bool)), this, SIGNAL(filter())); } TransactionFilterWidget::~TransactionFilterWidget() { delete group; } void TransactionFilterWidget::currentDateChanged(const QDate &olddate, const QDate &newdate) { if(olddate == to_date) { dateToEdit->blockSignals(true); dateToEdit->setDate(newdate); dateToEdit->blockSignals(false); toChanged(newdate); } } void TransactionFilterWidget::clearFilter() { dateFromButton->blockSignals(true); dateToEdit->blockSignals(true); minButton->blockSignals(true); maxButton->blockSignals(true); fromCombo->blockSignals(true); toCombo->blockSignals(true); descriptionEdit->blockSignals(true); if(tagCombo) tagCombo->blockSignals(true); dateFromButton->setChecked(false); dateFromEdit->setEnabled(false); to_date = QDate::currentDate(); dateToEdit->setDate(to_date); minButton->setChecked(false); minEdit->setEnabled(false); maxButton->setChecked(false); maxEdit->setEnabled(false); fromCombo->setCurrentIndex(0); toCombo->setCurrentIndex(0); descriptionEdit->setText(QString()); if(tagCombo) tagCombo->setCurrentIndex(0); dateFromButton->blockSignals(false); dateToEdit->blockSignals(false); minButton->blockSignals(false); maxButton->blockSignals(false); fromCombo->blockSignals(false); toCombo->blockSignals(false); descriptionEdit->blockSignals(false); if(tagCombo) tagCombo->blockSignals(false); clearButton->setEnabled(false); emit filter(); } void TransactionFilterWidget::checkEnableClear() { clearButton->setEnabled(dateFromButton->isChecked() || minButton->isChecked() || maxButton->isChecked() || fromCombo->currentIndex() || toCombo->currentIndex() || !descriptionEdit->text().isEmpty() || (tagCombo && tagCombo->currentIndex()) || to_date != QDate::currentDate()); } void TransactionFilterWidget::focusFirst() { descriptionEdit->setFocus(); descriptionEdit->selectAll(); } void TransactionFilterWidget::setFilter(QDate fromdate, QDate todate, double min, double max, Account *from_account, Account *to_account, QString description, QString tag, bool exclude, bool exact_match, bool exclude_subs) { dateFromButton->blockSignals(true); dateFromEdit->blockSignals(true); dateToEdit->blockSignals(true); minButton->blockSignals(true); maxButton->blockSignals(true); minEdit->blockSignals(true); maxEdit->blockSignals(true); fromCombo->blockSignals(true); toCombo->blockSignals(true); descriptionEdit->blockSignals(true); if(tagCombo) tagCombo->blockSignals(true); excludeButton->blockSignals(true); includeButton->blockSignals(true); exactMatchButton->blockSignals(true); if(excludeSubsButton) excludeSubsButton->blockSignals(true); dateToEdit->setDate(todate); to_date = todate; if(fromdate.isNull()) { dateFromButton->setChecked(false); dateFromEdit->setEnabled(false); if(dateFromEdit->date() > todate) { dateFromEdit->setDate(todate); from_date = todate; } } else { dateFromButton->setChecked(true); dateFromEdit->setEnabled(true); dateFromEdit->setDate(fromdate); from_date = fromdate; } if(min < 0.0) { minButton->setChecked(false); minEdit->setEnabled(false); } else { minButton->setChecked(true); minEdit->setEnabled(true); minEdit->setValue(min); } if(max < 0.0) { maxButton->setChecked(false); maxEdit->setEnabled(false); } else { maxButton->setChecked(true); maxEdit->setEnabled(true); maxEdit->setValue(max); } if(from_account) { int i = fromCombo->findData(QVariant::fromValue((void*) from_account)); if(i >= 0) { fromCombo->setCurrentIndex(i); emit fromActivated(from_account); } } else { fromCombo->setCurrentIndex(0); emit fromActivated(NULL); } if(to_account) { int i = toCombo->findData(QVariant::fromValue((void*) to_account)); if(i >= 0) { toCombo->setCurrentIndex(i); emit toActivated(to_account); } } else { toCombo->setCurrentIndex(0); emit toActivated(NULL); } descriptionEdit->setText(description); if(tagCombo) { int i = 0; if(!tag.isEmpty()) i = tagCombo->findText(tag, Qt::MatchExactly); if(i < 0) i = 0; tagCombo->setCurrentIndex(i); } excludeButton->setChecked(exclude); exactMatchButton->setChecked(exact_match); if(excludeSubsButton) excludeSubsButton->setChecked(exclude_subs); checkEnableClear(); dateFromButton->blockSignals(false); dateFromEdit->blockSignals(false); dateToEdit->blockSignals(false); minButton->blockSignals(false); maxButton->blockSignals(false); minEdit->blockSignals(false); maxEdit->blockSignals(false); fromCombo->blockSignals(false); toCombo->blockSignals(false); descriptionEdit->blockSignals(false); if(tagCombo) tagCombo->blockSignals(false); excludeButton->blockSignals(false); includeButton->blockSignals(false); exactMatchButton->blockSignals(false); if(excludeSubsButton) excludeSubsButton->blockSignals(false); emit filter(); } void TransactionFilterWidget::updateTags() { if(tagCombo) { tagCombo->clear(); tagCombo->addItem(tr("All")); tagCombo->addItems(budget->tags); tagCombo->setCurrentIndex(0); } } void TransactionFilterWidget::updateFromAccounts() { fromCombo->clear(); fromCombo->addItem(tr("All"), QVariant::fromValue((void*) NULL)); switch(transtype) { case TRANSACTION_TYPE_TRANSFER: { for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { Account *account = *it; fromCombo->addItem(account->name(), QVariant::fromValue((void*) account)); } break; } case TRANSACTION_TYPE_EXPENSE: { for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { Account *account = *it; if(account != budget->balancingAccount && ((AssetsAccount*) account)->accountType() != ASSETS_TYPE_SECURITIES) { fromCombo->addItem(account->name(), QVariant::fromValue((void*) account)); } } break; } case TRANSACTION_TYPE_INCOME: { for(AccountList::const_iterator it = budget->incomesAccounts.constBegin(); it != budget->incomesAccounts.constEnd(); ++it) { Account *account = *it; fromCombo->addItem(account->name(), QVariant::fromValue((void*) account)); } break; } } fromCombo->setCurrentIndex(0); } void TransactionFilterWidget::updateToAccounts() { toCombo->clear(); toCombo->addItem(tr("All"), QVariant::fromValue((void*) NULL)); switch(transtype) { case TRANSACTION_TYPE_TRANSFER: { for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { Account *account = *it; toCombo->addItem(account->name(), QVariant::fromValue((void*) account)); } break; } case TRANSACTION_TYPE_INCOME: { for(AccountList::const_iterator it = budget->assetsAccounts.constBegin(); it != budget->assetsAccounts.constEnd(); ++it) { Account *account = *it; if(account != budget->balancingAccount) { toCombo->addItem(account->name(), QVariant::fromValue((void*) account)); } } break; } case TRANSACTION_TYPE_EXPENSE: { for(AccountList::const_iterator it = budget->expensesAccounts.constBegin(); it != budget->expensesAccounts.constEnd(); ++it) { Account *account = *it; toCombo->addItem(account->nameWithParent(), QVariant::fromValue((void*) account)); } break; } } toCombo->setCurrentIndex(0); } void TransactionFilterWidget::updateAccounts() { updateFromAccounts(); updateToAccounts(); maxEdit->setCurrency(budget->defaultCurrency()); minEdit->setCurrency(budget->defaultCurrency()); } bool TransactionFilterWidget::filterTransaction(Transactions *transs, bool checkdate) { Transaction *trans = NULL; MultiAccountTransaction *split = NULL; switch(transs->generaltype()) { case GENERAL_TRANSACTION_TYPE_SINGLE: { trans = (Transaction*) transs; if(trans->parentSplit() && trans->parentSplit()->type() == SPLIT_TRANSACTION_TYPE_MULTIPLE_ACCOUNTS) return true; if(trans->subtype() == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND && trans->value() == 0.0) return true; break; } case GENERAL_TRANSACTION_TYPE_SPLIT: { if(((SplitTransaction*) transs)->type() != SPLIT_TRANSACTION_TYPE_MULTIPLE_ACCOUNTS) return true; split = (MultiAccountTransaction*) transs; break; } case GENERAL_TRANSACTION_TYPE_SCHEDULE: {return filterTransaction(((ScheduledTransaction*) transs)->transaction(), checkdate);} } if(trans) { if(trans->type() == TRANSACTION_TYPE_SECURITY_BUY || trans->type() == TRANSACTION_TYPE_SECURITY_SELL) { if(transtype == TRANSACTION_TYPE_TRANSFER && ((SecurityTransaction*) trans)->account()->type() != ACCOUNT_TYPE_ASSETS) return true; if(transtype == TRANSACTION_TYPE_EXPENSE && ((SecurityTransaction*) trans)->account()->type() != ACCOUNT_TYPE_EXPENSES) return true; if(transtype == TRANSACTION_TYPE_INCOME && ((SecurityTransaction*) trans)->account()->type() != ACCOUNT_TYPE_INCOMES) return true; } else if(trans->type() != transtype) { return true; } } else { if(split->transactiontype() != transtype) return true; if(split->count() == 0) return true; trans = split->at(0); } bool b_exact = exactMatchButton->isChecked(); bool b_exclude_subs = excludeSubsButton ? excludeSubsButton->isChecked() : b_exact; if(includeButton->isChecked()) { Account *account = (Account*) toCombo->currentData().value(); if(toCombo->currentIndex() > 0 && account != trans->toAccount() && (b_exclude_subs || account != trans->toAccount()->topAccount())) { if(split) { bool b = false; for(int split_i = 1; split_i < split->count(); split_i++) { if(account == split->at(split_i)->toAccount() || (!b_exclude_subs && account == split->at(split_i)->toAccount()->topAccount())) { b = true; break; } } if(!b) return true; } else { return true; } } account = (Account*) fromCombo->currentData().value(); if(fromCombo->currentIndex() > 0 && account != trans->fromAccount() && (b_exclude_subs || account != trans->fromAccount()->topAccount())) { if(split) { bool b = false; for(int split_i = 1; split_i < split->count(); split_i++) { if(account == split->at(split_i)->fromAccount() || (!b_exclude_subs && account == split->at(split_i)->fromAccount()->topAccount())) { b = true; break; } } if(!b) return true; } else { return true; } } if(tagCombo && tagCombo->currentIndex() > 0 && !transs->hasTag(tagCombo->currentText(), true)) return true; if(b_exact && !descriptionEdit->text().isEmpty()) { bool b = transs->description().compare(descriptionEdit->text(), Qt::CaseInsensitive) != 0 && (tagCombo || !transs->hasTag(descriptionEdit->text(), true, true)); if(b_extra && b && transtype == TRANSACTION_TYPE_EXPENSE) { b = ((Expense*) trans)->payee().compare(descriptionEdit->text(), Qt::CaseInsensitive) != 0; if(b && split) { for(int split_i = 1; split_i < split->count(); split_i++) { if(((Expense*) split->at(split_i))->payee().compare(descriptionEdit->text(), Qt::CaseInsensitive) == 0) { b = false; break; } } } } if(b_extra && b && transtype == TRANSACTION_TYPE_INCOME) { b = ((Income*) trans)->payer().compare(descriptionEdit->text(), Qt::CaseInsensitive) != 0; if(b && split) { for(int split_i = 1; split_i < split->count(); split_i++) { if(((Income*) split->at(split_i))->payer().compare(descriptionEdit->text(), Qt::CaseInsensitive) == 0) { b = false; break; } } if(!b) return true; } else { return true; } } if(b) return true; } else if(!descriptionEdit->text().isEmpty()) { bool b = !transs->description().contains(descriptionEdit->text(), Qt::CaseInsensitive) && !transs->comment().contains(descriptionEdit->text(), Qt::CaseInsensitive) && (tagCombo || !transs->hasTag(descriptionEdit->text(), true, true)); if(b_extra && b && transtype == TRANSACTION_TYPE_EXPENSE) { b = !((Expense*) trans)->payee().contains(descriptionEdit->text(), Qt::CaseInsensitive); if(b && split) { for(int split_i = 1; split_i < split->count(); split_i++) { if(((Expense*) split->at(split_i))->payee().contains(descriptionEdit->text(), Qt::CaseInsensitive)) { b = false; break; } } } } if(b_extra && b && transtype == TRANSACTION_TYPE_INCOME) { b = !((Income*) trans)->payer().contains(descriptionEdit->text(), Qt::CaseInsensitive); if(b && split) { for(int split_i = 1; split_i < split->count(); split_i++) { if(((Income*) split->at(split_i))->payer().contains(descriptionEdit->text(), Qt::CaseInsensitive)) { b = false; break; } } } } if(b) return true; } } else { Account *account = (Account*) toCombo->currentData().value(); if(toCombo->currentIndex() > 0 && (account == trans->toAccount() || (!b_exclude_subs && account == trans->toAccount()->topAccount()))) { if(!split || transtype != TRANSACTION_TYPE_INCOME || !split->account()) return true; } account = (Account*) fromCombo->currentData().value(); if(fromCombo->currentIndex() > 0 && (account == trans->fromAccount() || (!b_exclude_subs && account == trans->fromAccount()->topAccount()))) { if(!split || transtype != TRANSACTION_TYPE_EXPENSE || !split->account()) return true; } if(tagCombo && tagCombo->currentIndex() > 0 && transs->hasTag(tagCombo->currentText(), true)) return true; if(b_exact && !descriptionEdit->text().isEmpty()) { if((transs->description().compare(descriptionEdit->text(), Qt::CaseInsensitive) == 0 || (!tagCombo && transs->hasTag(descriptionEdit->text(), true, true)))) { return true; } if(b_extra && transtype == TRANSACTION_TYPE_EXPENSE && ((Expense*) trans)->payee().compare(descriptionEdit->text(), Qt::CaseInsensitive) == 0) { if(split) { bool b = false; for(int split_i = 1; split_i < split->count(); split_i++) { if(((Expense*) split->at(split_i))->payee().compare(descriptionEdit->text(), Qt::CaseInsensitive) != 0) { b = true; break; } } if(!b) return true; } else { return true; } } if(b_extra && transtype == TRANSACTION_TYPE_INCOME && ((Income*) trans)->payer().compare(descriptionEdit->text(), Qt::CaseInsensitive) == 0) { if(split) { bool b = false; for(int split_i = 1; split_i < split->count(); split_i++) { if(((Income*) split->at(split_i))->payer().compare(descriptionEdit->text(), Qt::CaseInsensitive) != 0) { b = true; break; } } if(!b) return true; } else { return true; } } } else if(!descriptionEdit->text().isEmpty()) { if(!descriptionEdit->text().isEmpty() && (transs->description().contains(descriptionEdit->text(), Qt::CaseInsensitive) || (!tagCombo && transs->hasTag(descriptionEdit->text(), true, true)))) { return true; } if(b_extra && transtype == TRANSACTION_TYPE_EXPENSE && ((Expense*) trans)->payee().contains(descriptionEdit->text(), Qt::CaseInsensitive)) { if(split) { bool b = false; for(int split_i = 1; split_i < split->count(); split_i++) { if(!((Expense*) split->at(split_i))->payee().contains(descriptionEdit->text(), Qt::CaseInsensitive)) { b = true; break; } } if(!b) return true; } else { return true; } return true; } if(b_extra && transtype == TRANSACTION_TYPE_INCOME && ((Income*) trans)->payer().contains(descriptionEdit->text(), Qt::CaseInsensitive)) { if(split) { bool b = false; for(int split_i = 1; split_i < split->count(); split_i++) { if(!((Income*) split->at(split_i))->payer().contains(descriptionEdit->text(), Qt::CaseInsensitive)) { b = true; break; } } if(!b) return true; } else { return true; } } } } if(minButton->isChecked() && transs->value(true) < minEdit->value()) { return true; } if(maxButton->isChecked() && transs->value(true) > maxEdit->value()) { return true; } if(checkdate && dateFromButton->isChecked() && transs->date() < from_date) { return true; } if(checkdate && transs->date() > to_date) { return true; } return false; } QDate TransactionFilterWidget::startDate() { if(!dateFromButton->isChecked()) return QDate(); return from_date; } QDate TransactionFilterWidget::endDate() { return to_date; } void TransactionFilterWidget::transactionsReset() { ((QStandardItemModel*) descriptionEdit->completer()->model())->clear(); QStringList descr_list; switch(transtype) { case TRANSACTION_TYPE_EXPENSE: { for(TransactionList::const_iterator it = budget->expenses.constEnd(); it != budget->expenses.constBegin();) { --it; Expense *expense = *it; if(!expense->description().isEmpty() && !descr_list.contains(expense->description(), Qt::CaseInsensitive)) { QList row; row << new QStandardItem(expense->description()); row << new QStandardItem(expense->description().toLower()); ((QStandardItemModel*) descriptionEdit->completer()->model())->appendRow(row); descr_list << expense->description().toLower(); } if(b_extra && !expense->payee().isEmpty() && !descr_list.contains(expense->payee(), Qt::CaseInsensitive)) { QList row; row << new QStandardItem(expense->payee()); row << new QStandardItem(expense->payee().toLower()); ((QStandardItemModel*) descriptionEdit->completer()->model())->appendRow(row); descr_list << expense->payee().toLower(); } } break; } case TRANSACTION_TYPE_INCOME: { for(TransactionList::const_iterator it = budget->incomes.constEnd(); it != budget->incomes.constBegin();) { --it; Income *income = *it; if(!income->security() && !income->description().isEmpty() && !descr_list.contains(income->description(), Qt::CaseInsensitive)) { QList row; row << new QStandardItem(income->description()); row << new QStandardItem(income->description().toLower()); ((QStandardItemModel*) descriptionEdit->completer()->model())->appendRow(row); descr_list << income->description().toLower(); } if(b_extra && !income->security() && !income->payer().isEmpty() && !descr_list.contains(income->payer(), Qt::CaseInsensitive)) { QList row; row << new QStandardItem(income->payer()); row << new QStandardItem(income->payer().toLower()); ((QStandardItemModel*) descriptionEdit->completer()->model())->appendRow(row); descr_list << income->payer().toLower(); } } break; } case TRANSACTION_TYPE_TRANSFER: { for(TransactionList::const_iterator it = budget->transfers.constEnd(); it != budget->transfers.constBegin();) { --it; Transfer *transfer = *it; if(!transfer->description().isEmpty() && !descr_list.contains(transfer->description(), Qt::CaseInsensitive)) { QList row; row << new QStandardItem(transfer->description()); row << new QStandardItem(transfer->description().toLower()); ((QStandardItemModel*) descriptionEdit->completer()->model())->appendRow(row); descr_list << transfer->description().toLower(); } } break; } default: {} } if(transtype != TRANSACTION_TYPE_TRANSFER) { for(int i = 0; i < budget->tags.count(); i++) { QList row; row << new QStandardItem(budget->tags[i]); row << new QStandardItem(budget->tags[i].toLower()); ((QStandardItemModel*) descriptionEdit->completer()->model())->appendRow(row); } } ((QStandardItemModel*) descriptionEdit->completer()->model())->sort(1); } void TransactionFilterWidget::transactionAdded(Transaction *trans) { if(descriptionEdit && trans->type() == transtype && (transtype != TRANSACTION_TYPE_INCOME || !((Income*) trans)->security())) { if(!trans->description().isEmpty()) { if(((QStandardItemModel*) descriptionEdit->completer()->model())->findItems(trans->description().toLower(), Qt::MatchExactly, 1).isEmpty()) { QList row; row << new QStandardItem(trans->description()); row << new QStandardItem(trans->description().toLower()); ((QStandardItemModel*) descriptionEdit->completer()->model())->appendRow(row); ((QStandardItemModel*) descriptionEdit->completer()->model())->sort(1); } } if(b_extra && transtype == TRANSACTION_TYPE_EXPENSE && !((Expense*) trans)->payee().isEmpty()) { if(((QStandardItemModel*) descriptionEdit->completer()->model())->findItems(((Expense*) trans)->payee().toLower(), Qt::MatchExactly, 1).isEmpty()) { QList row; row << new QStandardItem(((Expense*) trans)->payee()); row << new QStandardItem(((Expense*) trans)->payee().toLower()); ((QStandardItemModel*) descriptionEdit->completer()->model())->appendRow(row); ((QStandardItemModel*) descriptionEdit->completer()->model())->sort(1); } } else if(b_extra && transtype == TRANSACTION_TYPE_INCOME && !((Income*) trans)->security() && !((Income*) trans)->payer().isEmpty()) { if(((QStandardItemModel*) descriptionEdit->completer()->model())->findItems(((Income*) trans)->payer().toLower(), Qt::MatchExactly, 1).isEmpty()) { QList row; row << new QStandardItem(((Income*) trans)->payer()); row << new QStandardItem(((Income*) trans)->payer().toLower()); ((QStandardItemModel*) descriptionEdit->completer()->model())->appendRow(row); ((QStandardItemModel*) descriptionEdit->completer()->model())->sort(1); } } } } void TransactionFilterWidget::transactionModified(Transaction *trans) { transactionAdded(trans); } void TransactionFilterWidget::toChanged(const QDate &date) { bool error = false; if(!date.isValid()) { QMessageBox::critical(this, tr("Error"), tr("Invalid date.")); error = true; } if(!error && dateFromEdit->date() > date) { /*if(dateFromButton->isChecked()) { QMessageBox::critical(this, tr("Error"), tr("To date is before from date.")); }*/ if(budget->isFirstBudgetDay(to_date)) { from_date = budget->firstBudgetDay(date); } else { from_date = date.addDays(-from_date.daysTo(to_date)); } from_date = date; dateFromEdit->blockSignals(true); dateFromEdit->setDate(from_date); dateFromEdit->blockSignals(false); } if(error) { dateToEdit->setFocus(); dateToEdit->blockSignals(true); dateToEdit->setDate(to_date); dateToEdit->blockSignals(false); dateToEdit->selectAll(); return; } to_date = date; emit filter(); } void TransactionFilterWidget::fromChanged(const QDate &date) { bool error = false; if(!date.isValid()) { QMessageBox::critical(this, tr("Error"), tr("Invalid date.")); error = true; } if(!error && date > dateToEdit->date()) { //QMessageBox::critical(this, tr("Error"), tr("From date is after to date.")); if(budget->isLastBudgetDay(to_date)) { to_date = budget->lastBudgetDay(date); } else { to_date = date.addDays(from_date.daysTo(to_date)); } if(to_date > QDate::currentDate() && from_date <= QDate::currentDate()) to_date = QDate::currentDate(); dateToEdit->blockSignals(true); dateToEdit->setDate(to_date); dateToEdit->blockSignals(false); } if(error) { dateFromEdit->setFocus(); dateFromEdit->blockSignals(true); dateFromEdit->setDate(from_date); dateFromEdit->blockSignals(false); dateFromEdit->selectAll(); return; } from_date = date; if(dateFromButton->isChecked()) emit filter(); } double TransactionFilterWidget::countYears() { QDate first_date = firstDate(); if(first_date.isNull()) return 0.0; return budget->yearsBetweenDates(first_date, to_date, true); } double TransactionFilterWidget::countMonths() { QDate first_date = firstDate(); if(first_date.isNull()) return 0.0; return budget->monthsBetweenDates(first_date, to_date, true); } int TransactionFilterWidget::countDays() { QDate first_date = firstDate(); if(first_date.isNull()) return 0; return first_date.daysTo(to_date) + 1; } QDate TransactionFilterWidget::firstDate() { if(dateFromButton->isChecked()) return from_date; QDate first_date; switch(transtype) { case TRANSACTION_TYPE_EXPENSE: { if(!budget->expenses.isEmpty()) first_date = budget->expenses.first()->date(); for(SecurityTransactionList::const_iterator it = budget->securityTransactions.constBegin(); it != budget->securityTransactions.constEnd(); ++it) { SecurityTransaction *sectrans = *it; if(!first_date.isNull() && sectrans->date() >= first_date) break; if(sectrans->account()->type() == ACCOUNT_TYPE_EXPENSES) { first_date = sectrans->date(); break; } } if(first_date.isNull()) { for(ScheduledTransactionList::const_iterator it = budget->scheduledTransactions.constBegin(); it != budget->scheduledTransactions.constEnd(); ++it) { ScheduledTransaction *strans = *it; if(strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { for(int i = 0; i < ((SplitTransaction*) strans->transaction())->count(); i++) { Transaction *trans = ((SplitTransaction*) strans->transaction())->at(i); if(trans->type() == TRANSACTION_TYPE_EXPENSE || ((trans->type() == TRANSACTION_TYPE_SECURITY_SELL || trans->type() == TRANSACTION_TYPE_SECURITY_BUY) && ((SecurityTransaction*) trans)->account()->type() == ACCOUNT_TYPE_EXPENSES)) { first_date = trans->date(); break; } } } else { if(strans->transactiontype() == TRANSACTION_TYPE_EXPENSE || ((strans->transactiontype() == TRANSACTION_TYPE_SECURITY_SELL || strans->transactiontype() == TRANSACTION_TYPE_SECURITY_BUY) && ((SecurityTransaction*) strans->transaction())->account()->type() == ACCOUNT_TYPE_EXPENSES)) { first_date = strans->transaction()->date(); break; } } } } break; } case TRANSACTION_TYPE_INCOME: { if(!budget->incomes.isEmpty()) first_date = budget->incomes.first()->date(); for(SecurityTransactionList::const_iterator it = budget->securityTransactions.constBegin(); it != budget->securityTransactions.constEnd(); ++it) { SecurityTransaction *sectrans = *it; if(!first_date.isNull() && sectrans->date() >= first_date) break; if(sectrans->account()->type() == ACCOUNT_TYPE_INCOMES) { first_date = sectrans->date(); break; } } if(first_date.isNull()) { for(ScheduledTransactionList::const_iterator it = budget->scheduledTransactions.constBegin(); it != budget->scheduledTransactions.constEnd(); ++it) { ScheduledTransaction *strans = *it; if(strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { for(int i = 0; i < ((SplitTransaction*) strans->transaction())->count(); i++) { Transaction *trans = ((SplitTransaction*) strans->transaction())->at(i); if(trans->type() == TRANSACTION_TYPE_INCOME || ((trans->type() == TRANSACTION_TYPE_SECURITY_SELL || trans->type() == TRANSACTION_TYPE_SECURITY_BUY) && ((SecurityTransaction*) trans)->account()->type() == ACCOUNT_TYPE_INCOMES)) { first_date = trans->date(); break; } } } else { if(strans->transactiontype() == TRANSACTION_TYPE_INCOME || ((strans->transactiontype() == TRANSACTION_TYPE_SECURITY_SELL || strans->transactiontype() == TRANSACTION_TYPE_SECURITY_BUY) && ((SecurityTransaction*) strans->transaction())->account()->type() == ACCOUNT_TYPE_INCOMES)) { first_date = strans->transaction()->date(); break; } } } } break; } case TRANSACTION_TYPE_TRANSFER: { if(!budget->transfers.isEmpty()) first_date = budget->transfers.first()->date(); for(SecurityTransactionList::const_iterator it = budget->securityTransactions.constBegin(); it != budget->securityTransactions.constEnd(); ++it) { SecurityTransaction *sectrans = *it; if(!first_date.isNull() && sectrans->date() >= first_date) break; if(sectrans->account()->type() == ACCOUNT_TYPE_ASSETS) { first_date = sectrans->date(); break; } } if(first_date.isNull()) { for(ScheduledTransactionList::const_iterator it = budget->scheduledTransactions.constBegin(); it != budget->scheduledTransactions.constEnd(); ++it) { ScheduledTransaction *strans = *it; if(strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { for(int i = 0; i < ((SplitTransaction*) strans->transaction())->count(); i++) { Transaction *trans = ((SplitTransaction*) strans->transaction())->at(i); if(trans->type() == TRANSACTION_TYPE_TRANSFER || ((trans->type() == TRANSACTION_TYPE_SECURITY_SELL || trans->type() == TRANSACTION_TYPE_SECURITY_BUY) && ((SecurityTransaction*) trans)->account()->type() == ACCOUNT_TYPE_ASSETS)) { first_date = trans->date(); break; } } } else { if(strans->transactiontype() == TRANSACTION_TYPE_TRANSFER || ((strans->transactiontype() == TRANSACTION_TYPE_SECURITY_SELL || strans->transactiontype() == TRANSACTION_TYPE_SECURITY_BUY) && ((SecurityTransaction*) strans->transaction())->account()->type() == ACCOUNT_TYPE_ASSETS)) { first_date = strans->transaction()->date(); break; } } } } break; } default: {break;} } return first_date; } void TransactionFilterWidget::onFromActivated(int index) { if(index > 0) { emit fromActivated((Account*) fromCombo->itemData(index).value()); } else { emit fromActivated(NULL); } } void TransactionFilterWidget::onToActivated(int index) { if(index > 0) { emit toActivated((Account*) toCombo->itemData(index).value()); } else { emit toActivated(NULL); } } Eqonomize-1.5.3/src/transactionfilterwidget.h000066400000000000000000000070041416454732000213740ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016-2020 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifndef TRANSACTION_FILTER_WIDGET_H #define TRANSACTION_FILTER_WIDGET_H #include #include #include class QButtonGroup; class QCheckBox; class QLabel; class QPushButton; class QRadioButton; class QCheckBox; class QComboBox; class QDateEdit; class QLineEdit; class Account; class Budget; class Transaction; class Transactions; class EqonomizeValueEdit; class TransactionFilterWidget : public QWidget { Q_OBJECT public: TransactionFilterWidget(bool extra_parameters, int transaction_type, Budget *budg, QWidget *parent = 0); ~TransactionFilterWidget(); bool filterTransaction(Transactions *transs, bool checkdate = true); void updateFromAccounts(); void updateToAccounts(); void updateAccounts(); void transactionsReset(); void transactionAdded(Transaction*); void transactionModified(Transaction*); double countYears(); double countMonths(); int countDays(); QDate startDate(); QDate endDate(); void currentDateChanged(const QDate &olddate, const QDate &newdate); void focusFirst(); void updateTags(); void setFilter(QDate fromdate, QDate todate, double min = -1.0, double max = -1.0, Account *from_account = NULL, Account *to_account = NULL, QString description = QString(), QString payee = QString(), bool exclude = false, bool exact_match = false, bool exclude_subs = false); protected: QDate firstDate(); int transtype; Budget *budget; bool b_extra; QComboBox *fromCombo, *toCombo, *tagCombo; QCheckBox *minButton, *maxButton, *dateFromButton; EqonomizeValueEdit *minEdit, *maxEdit; QDateEdit *dateFromEdit, *dateToEdit; QLineEdit *descriptionEdit; QDate from_date, to_date; QRadioButton *includeButton, *excludeButton; QCheckBox *exactMatchButton, *excludeSubsButton; QPushButton *clearButton; QButtonGroup *group; protected slots: void toChanged(const QDate&); void fromChanged(const QDate&); void clearFilter(); void checkEnableClear(); void onToActivated(int); void onFromActivated(int); signals: void filter(); void toActivated(Account*); void fromActivated(Account*); }; #endif Eqonomize-1.5.3/src/transactionlistwidget.cpp000066400000000000000000003201051416454732000214150ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016-2020 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "budget.h" #include "editscheduledtransactiondialog.h" #include "eqonomize.h" #include "recurrence.h" #include "transactioneditwidget.h" #include "transactionfilterwidget.h" #include "transactionlistwidget.h" #include #include extern QString last_associated_file_directory; extern void setColumnTextWidth(QTreeWidget *w, int i, QString str); extern void setColumnDateWidth(QTreeWidget *w, int i); void setColumnMoneyWidth(QTreeWidget *w, int i, Budget *budget, double v = 9999999.99, int d = -1); extern void setColumnStrlenWidth(QTreeWidget *w, int i, int l); extern void setColumnValueWidth(QTreeWidget *w, int i, double v, int d, Budget *budget); extern QColor createExpenseColor(QTreeWidgetItem *i, int = 0); extern QColor createIncomeColor(QTreeWidgetItem *i, int = 0); extern QColor createTransferColor(QTreeWidgetItem *i, int = 0); class TransactionListViewItem : public QTreeWidgetItem { protected: Transaction *o_trans; ScheduledTransaction *o_strans; MultiAccountTransaction *o_split; QDate d_date; public: TransactionListViewItem(const QDate &trans_date, Transaction *trans, ScheduledTransaction *strans, MultiAccountTransaction *split, QString, QString = QString(), QString = QString(), QString = QString(), QString = QString(), QString = QString(), QString = QString(), QString = QString()); bool operator<(const QTreeWidgetItem &i_pre) const; Transaction *transaction() const; ScheduledTransaction *scheduledTransaction() const; MultiAccountTransaction *splitTransaction() const; const QDate &date() const; void setDate(const QDate &newdate); }; TransactionListWidget::TransactionListWidget(bool extra_parameters, int transaction_type, Budget *budg, Eqonomize *main_win, QWidget *parent) : QWidget(parent), transtype(transaction_type), budget(budg), mainWin(main_win), b_extra(extra_parameters) { current_value = 0.0; current_quantity = 0.0; right_align_values = true; key_event = NULL; selected_trans = NULL; listPopupMenu = NULL; headerPopupMenu = NULL; QVBoxLayout *transactionsLayout = new QVBoxLayout(this); transactionsLayout->setContentsMargins(0, 0, 0, 0); QVBoxLayout *transactionsViewLayout = new QVBoxLayout(); transactionsLayout->addLayout(transactionsViewLayout); transactionsView = new EqonomizeTreeWidget(this); transactionsView->setSortingEnabled(true); transactionsView->sortByColumn(0, Qt::DescendingOrder); transactionsView->setAllColumnsShowFocus(true); QStringList headers; headers << tr("Date"); headers << tr("Description", "Transaction description property (transaction title/generic article name)"); comments_col = 5; tags_col = -1; payee_col = -1; quantity_col = -1; switch(transtype) { case TRANSACTION_TYPE_EXPENSE: { headers << tr("Cost"); headers << tr("Category"); headers << tr("From Account"); headers << tr("Payee"); headers << tr("Quantity"); quantity_col = 6; payee_col = 5; comments_col = 8; tags_col = 7; headers << tr("Tags"); from_col = 4; to_col = 3; break; } case TRANSACTION_TYPE_INCOME: { headers << tr("Income"); headers << tr("Category"); headers << tr("To Account"); headers << tr("Payer"); payee_col = 5; comments_col = 7; tags_col = 6; headers << tr("Tags"); from_col = 3; to_col = 4; break; } default: { headers << tr("Amount"); headers << tr("From"); headers << tr("To"); from_col = 3; to_col = 4; break; } } headers << tr("Comments"); headers << "t"; transactionsView->setColumnCount(comments_col + 2); transactionsView->setHeaderLabels(headers); transactionsView->setColumnHidden(transactionsView->columnCount() - 1, true); setColumnDateWidth(transactionsView, 0); setColumnStrlenWidth(transactionsView, 1, 25); setColumnMoneyWidth(transactionsView, 2, budget); setColumnStrlenWidth(transactionsView, from_col, 20); setColumnStrlenWidth(transactionsView, to_col, 20); if(payee_col >= 0) { setColumnStrlenWidth(transactionsView, payee_col, 15); transactionsView->setColumnHidden(payee_col, !b_extra); } if(tags_col >= 0) { setColumnStrlenWidth(transactionsView, tags_col, 15); transactionsView->setColumnHidden(tags_col, true); } if(quantity_col >= 0) transactionsView->setColumnHidden(quantity_col, true); transactionsView->setRootIsDecorated(false); transactionsView->setSelectionMode(QAbstractItemView::ExtendedSelection); transactionsViewLayout->addWidget(transactionsView); statLabel = new QLabel(this); transactionsViewLayout->addWidget(statLabel); QSizePolicy sp = transactionsView->sizePolicy(); sp.setVerticalPolicy(QSizePolicy::MinimumExpanding); transactionsView->setSizePolicy(sp); tabs = new QTabWidget(this); tabs->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); editWidget = new TransactionEditWidget(true, b_extra, transtype, NULL, false, NULL, SECURITY_SHARES_AND_QUOTATION, false, budget, this, true); editInfoLabel = new QLabel(QString()); editWidget->bottomLayout()->addWidget(editInfoLabel, 1); QDialogButtonBox *buttons = new QDialogButtonBox(); editWidget->bottomLayout()->addWidget(buttons); addButton = buttons->addButton(tr("Add"), QDialogButtonBox::ActionRole); modifyButton = buttons->addButton(tr("Apply"), QDialogButtonBox::ActionRole); clearButton = buttons->addButton(tr("Clear"), QDialogButtonBox::ActionRole); removeButton = buttons->addButton(tr("Delete"), QDialogButtonBox::ActionRole); modifyButton->setEnabled(false); removeButton->setEnabled(false); clearButton->setEnabled(false); filterWidget = new TransactionFilterWidget(b_extra, transtype, budget, this); QString editTabTitle; switch (transtype) { case TRANSACTION_TYPE_EXPENSE: {editTabTitle = tr("New/Edit Expense"); break;} case TRANSACTION_TYPE_INCOME: editTabTitle = tr("New/Edit Income"); break; case TRANSACTION_TYPE_TRANSFER: editTabTitle = tr("New/Edit Transfer"); break; } tabs->addTab(editWidget, editTabTitle); tabs->addTab(filterWidget, tr("Filter")); transactionsLayout->addWidget(tabs); updateStatistics(); connect(tabs, SIGNAL(currentChanged(int)), this, SLOT(currentTabChanged(int))); connect(addButton, SIGNAL(clicked()), this, SLOT(addTransaction())); connect(modifyButton, SIGNAL(clicked()), this, SLOT(modifyTransaction())); connect(editWidget, SIGNAL(addmodify()), this, SLOT(addModifyTransaction())); connect(removeButton, SIGNAL(clicked()), this, SLOT(removeTransaction())); connect(clearButton, SIGNAL(clicked()), this, SLOT(editClear())); connect(filterWidget, SIGNAL(filter()), this, SLOT(filterTransactions())); connect(filterWidget, SIGNAL(toActivated(Account*)), this, SLOT(filterToActivated(Account*))); connect(filterWidget, SIGNAL(fromActivated(Account*)), this, SLOT(filterFromActivated(Account*))); connect(transactionsView, SIGNAL(itemSelectionChanged()), this, SLOT(transactionSelectionChanged())); transactionsView->header()->setContextMenuPolicy(Qt::CustomContextMenu); connect(transactionsView->header(), SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(popupHeaderMenu(const QPoint&))); transactionsView->setContextMenuPolicy(Qt::CustomContextMenu); connect(transactionsView, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(popupListMenu(const QPoint&))); connect(transactionsView, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(transactionExecuted(QTreeWidgetItem*))); connect(transactionsView, SIGNAL(returnPressed(QTreeWidgetItem*)), this, SLOT(transactionExecuted(QTreeWidgetItem*))); connect(editWidget, SIGNAL(accountAdded(Account*)), this, SIGNAL(accountAdded(Account*))); connect(editWidget, SIGNAL(currenciesModified()), this, SIGNAL(currenciesModified())); connect(editWidget, SIGNAL(newLoanRequested()), this, SLOT(newTransactionWithLoan())); connect(editWidget, SIGNAL(multipleAccountsRequested()), this, SLOT(newMultiAccountTransaction())); connect(editWidget, SIGNAL(propertyChanged()), this, SLOT(updateClearButton())); connect(editWidget, SIGNAL(tagAdded(QString)), this, SIGNAL(tagAdded(QString))); connect(editInfoLabel, SIGNAL(linkActivated(const QString&)), this, SLOT(editSplitTransaction())); } //QSize TransactionListWidget::minimumSizeHint() const {return filterWidget->minimumSizeHint().expandedTo(editWidget->minimumSizeHint());} //QSize TransactionListWidget::sizeHint() const {return QSize(filterWidget->sizeHint().expandedTo(editWidget->sizeHint()).width() + 12, QWidget::sizeHint().height());} QSize TransactionListWidget::minimumSizeHint() const {return QWidget::minimumSizeHint();} QSize TransactionListWidget::sizeHint() const {return minimumSizeHint();} QByteArray TransactionListWidget::saveState() { return transactionsView->header()->saveState(); } void TransactionListWidget::restoreState(const QByteArray &state) { QSettings settings; if(settings.value("GeneralOptions/version", 0).toInt() >= 140) { transactionsView->header()->restoreState(state); } transactionsView->sortByColumn(0, Qt::DescendingOrder); transactionsView->setColumnHidden(transactionsView->columnCount() - 1, true); } void TransactionListWidget::updateClearButton() { clearButton->setEnabled(!editWidget->isCleared()); } void TransactionListWidget::selectAssociatedFile() { QList selection = transactionsView->selectedItems(); if(selection.count() > 0) { TransactionListViewItem *i = (TransactionListViewItem*) selection.first(); Transactions *transs = i->transaction(); if(i->splitTransaction()) transs = i->splitTransaction(); else if(i->transaction()->parentSplit()) transs = i->transaction()->parentSplit(); if(transs) { QStringList urls = QFileDialog::getOpenFileNames(this, QString(), (transs->associatedFile().isEmpty() || transs->associatedFile().contains(",")) ? last_associated_file_directory : transs->associatedFile()); if(!urls.isEmpty()) { QFileInfo fileInfo(urls[0]); last_associated_file_directory = fileInfo.absoluteDir().absolutePath(); if(urls.size() == 1) { transs->setAssociatedFile(urls[0]); } else { QString url; for(int i = 0; i < urls.size(); i++) { if(i > 0) url += ", "; if(urls[i].contains("\"")) {url += "\'"; url += urls[i]; url += "\'";} else {url += "\""; url += urls[i]; url += "\"";} } transs->setAssociatedFile(url); } mainWin->ActionOpenAssociatedFile->setEnabled(true); if(transs->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { mainWin->transactionRemoved(transs); mainWin->transactionAdded(transs); } else { mainWin->transactionModified(transs, transs); } } } } } void TransactionListWidget::openAssociatedFile() { QList selection = transactionsView->selectedItems(); if(selection.count() > 0) { TransactionListViewItem *i = (TransactionListViewItem*) selection.first(); Transactions *transs = i->transaction(); if(i->splitTransaction()) transs = i->splitTransaction(); else if(i->transaction()->parentSplit() && transs->associatedFile().isEmpty()) transs = i->transaction()->parentSplit(); if(transs) { open_file_list(transs->associatedFile()); } } } void TransactionListWidget::useMultipleCurrencies(bool b) { editWidget->useMultipleCurrencies(b); } void TransactionListWidget::currentDateChanged(const QDate &olddate, const QDate &newdate) { QList selection = transactionsView->selectedItems(); if(selection.isEmpty()) editWidget->currentDateChanged(olddate, newdate); filterWidget->currentDateChanged(olddate, newdate); } void TransactionListWidget::transactionExecuted(QTreeWidgetItem*) { editTransaction(); } void TransactionListWidget::updateStatistics() { QList selection = transactionsView->selectedItems(); if((transtype == TRANSACTION_TYPE_EXPENSE || transtype == TRANSACTION_TYPE_INCOME) && selection.count() > 1) { double value = 0.0, quantity = 0.0; for(int index = 0; index < selection.count(); index++) { TransactionListViewItem *i = (TransactionListViewItem*) selection.at(index); Transactions *transs = i->splitTransaction(); if(!transs) transs = i->transaction(); value += transs->value(true); quantity += transs->quantity(); } int i_count_frac = 0; double intpart = 0.0; if(modf(quantity, &intpart) != 0.0) i_count_frac = 2; statLabel->setText(QString("
    %1 %4   %2 %5   %3 %6
    ").arg(tr("Quantity:")).arg(transtype == TRANSACTION_TYPE_INCOME ? tr("Income") : tr("Cost:")).arg(tr("Average:")).arg(budget->formatValue(quantity, i_count_frac)).arg(budget->formatMoney(value)).arg(budget->formatMoney(quantity == 0.0 ? 0.0 : value / quantity))); } else { int i_count_frac = 0; double intpart = 0.0; if(modf(current_quantity, &intpart) != 0.0) i_count_frac = 2; statLabel->setText(QString("
    %1 %5   %2 %6   %3 %7   %4 %8
    ").arg(tr("Quantity:")).arg(tr("Total:")).arg(tr("Average:")).arg(tr("Monthly:")).arg(budget->formatValue(current_quantity, i_count_frac)).arg(budget->formatMoney(current_value)).arg(budget->formatMoney(current_quantity == 0.0 ? 0.0 : current_value / current_quantity)).arg(budget->formatMoney(current_value == 0.0 ? current_value : current_value / filterWidget->countMonths()))); } } void TransactionListWidget::keyPressEvent(QKeyEvent *e) { if(e == key_event) return; QWidget::keyPressEvent(e); if(!e->isAccepted() && editWidget->firstHasFocus() && e->key() != Qt::Key_Enter && e->key() != Qt::Key_Return) { #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) key_event = new QKeyEvent(e->type(), e->key(), e->modifiers(), e->nativeScanCode(), e->nativeVirtualKey(), e->nativeModifiers(), e->text(), e->isAutoRepeat(), e->count()); #else key_event = new QKeyEvent(*e); #endif QApplication::sendEvent(transactionsView, key_event); delete key_event; } } void TransactionListWidget::tagsModified() { editWidget->tagsModified(); filterWidget->updateTags(); } void TransactionListWidget::popupListMenu(const QPoint &p) { if(!listPopupMenu) { listPopupMenu = new QMenu(this); switch(transtype) { case TRANSACTION_TYPE_EXPENSE: {listPopupMenu->addAction(mainWin->ActionNewExpense); listPopupMenu->addAction(mainWin->ActionNewRefund); break;} case TRANSACTION_TYPE_INCOME: {listPopupMenu->addAction(mainWin->ActionNewIncome); listPopupMenu->addAction(mainWin->ActionNewRepayment); break;} case TRANSACTION_TYPE_TRANSFER: {listPopupMenu->addAction(mainWin->ActionNewTransfer); break;} } listPopupMenu->addAction(mainWin->ActionNewMultiItemTransaction); listPopupMenu->addSeparator(); listPopupMenu->addAction(mainWin->ActionCloneTransaction); listPopupMenu->addSeparator(); listPopupMenu->addAction(mainWin->ActionEditTransaction); listPopupMenu->addAction(mainWin->ActionEditScheduledTransaction); listPopupMenu->addAction(mainWin->ActionEditSplitTransaction); listPopupMenu->addAction(mainWin->ActionJoinTransactions); listPopupMenu->addAction(mainWin->ActionSplitUpTransaction); listPopupMenu->addSeparator(); listPopupMenu->addAction(mainWin->ActionTags); listPopupMenu->addAction(mainWin->ActionLinks); listPopupMenu->addAction(mainWin->ActionCreateLink); listPopupMenu->addAction(mainWin->ActionSelectAssociatedFile); listPopupMenu->addAction(mainWin->ActionOpenAssociatedFile); listPopupMenu->addAction(mainWin->ActionEditTimestamp); listPopupMenu->addSeparator(); listPopupMenu->addAction(mainWin->ActionDeleteTransaction); listPopupMenu->addAction(mainWin->ActionDeleteScheduledTransaction); listPopupMenu->addAction(mainWin->ActionDeleteSplitTransaction); } listPopupMenu->popup(transactionsView->viewport()->mapToGlobal(p)); } void TransactionListWidget::hideColumn(bool do_show) { transactionsView->setColumnHidden(sender()->property("column_index").toInt(), !do_show); } void TransactionListWidget::popupHeaderMenu(const QPoint &p) { if(!headerPopupMenu) { headerPopupMenu = new QMenu(this); QTreeWidgetItem *header = transactionsView->headerItem(); QAction *a = NULL; a = headerPopupMenu->addAction(header->text(3)); a->setProperty("column_index", QVariant::fromValue(3)); a->setCheckable(true); a->setChecked(!transactionsView->isColumnHidden(3)); connect(a, SIGNAL(toggled(bool)), this, SLOT(hideColumn(bool))); a = headerPopupMenu->addAction(header->text(4)); a->setProperty("column_index", QVariant::fromValue(4)); a->setCheckable(true); a->setChecked(!transactionsView->isColumnHidden(4)); connect(a, SIGNAL(toggled(bool)), this, SLOT(hideColumn(bool))); if(quantity_col >= 0) { a = headerPopupMenu->addAction(header->text(quantity_col)); a->setProperty("column_index", QVariant::fromValue(quantity_col)); a->setCheckable(true); a->setChecked(!transactionsView->isColumnHidden(quantity_col)); connect(a, SIGNAL(toggled(bool)), this, SLOT(hideColumn(bool))); } if(payee_col >= 0) { a = headerPopupMenu->addAction(header->text(payee_col)); a->setProperty("column_index", QVariant::fromValue(payee_col)); a->setCheckable(true); a->setChecked(!transactionsView->isColumnHidden(payee_col)); connect(a, SIGNAL(toggled(bool)), this, SLOT(hideColumn(bool))); } if(tags_col >= 0) { a = headerPopupMenu->addAction(header->text(tags_col)); a->setProperty("column_index", QVariant::fromValue(tags_col)); a->setCheckable(true); a->setChecked(!transactionsView->isColumnHidden(tags_col)); connect(a, SIGNAL(toggled(bool)), this, SLOT(hideColumn(bool))); } if(comments_col >= 0) { a = headerPopupMenu->addAction(header->text(comments_col)); a->setProperty("column_index", QVariant::fromValue(comments_col)); a->setCheckable(true); a->setChecked(!transactionsView->isColumnHidden(comments_col)); connect(a, SIGNAL(toggled(bool)), this, SLOT(hideColumn(bool))); } headerPopupMenu->addSeparator(); ActionSortByCreationTime = headerPopupMenu->addAction(tr("Sort by creation time")); ActionSortByCreationTime->setCheckable(true); connect(ActionSortByCreationTime, SIGNAL(toggled(bool)), this, SLOT(sortByCreationTime(bool))); SeparatorRightAlignValues = headerPopupMenu->addSeparator(); ActionRightAlignValues = headerPopupMenu->addAction(tr("Right align")); ActionRightAlignValues->setCheckable(true); connect(ActionRightAlignValues, SIGNAL(toggled(bool)), this, SLOT(rightAlignValues(bool))); } int c = transactionsView->columnAt(p.x()); SeparatorRightAlignValues->setVisible(c == 2); ActionRightAlignValues->setVisible(c == 2); if(c == 2) { QSettings settings; ActionRightAlignValues->blockSignals(true); ActionRightAlignValues->setChecked(settings.value("GeneralOptions/rightAlignValues", true).toBool()); ActionRightAlignValues->blockSignals(false); } ActionSortByCreationTime->blockSignals(true); ActionSortByCreationTime->setChecked(transactionsView->sortColumn() == transactionsView->columnCount() - 1); ActionSortByCreationTime->blockSignals(false); headerPopupMenu->popup(transactionsView->header()->viewport()->mapToGlobal(p)); } void TransactionListWidget::sortByCreationTime(bool b) { if(b) transactionsView->sortByColumn(transactionsView->columnCount() - 1, Qt::DescendingOrder); else transactionsView->sortByColumn(0, Qt::DescendingOrder); } void TransactionListWidget::rightAlignValues(bool b) { emit valueAlignmentUpdated(b); } extern QString htmlize_string(QString str); bool TransactionListWidget::isEmpty() { return transactionsView->topLevelItemCount() == 0; } bool TransactionListWidget::exportList(QTextStream &outf, int fileformat) { switch(fileformat) { case 'h': { #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) outf.setCodec("UTF-8"); #endif outf << "" << '\n'; outf << "" << '\n'; outf << "\t" << '\n'; outf << "\t\t"; switch(transtype) { case TRANSACTION_TYPE_EXPENSE: {outf << htmlize_string(tr("Expenses")); break;} case TRANSACTION_TYPE_INCOME: {outf << htmlize_string(tr("Incomes")); break;} default: {outf << htmlize_string(tr("Transfers")); break;} } outf << "" << '\n'; outf << "\t\t" << '\n'; outf << "\t\tapplicationDisplayName() << "\">" << '\n'; outf << "\t" << '\n'; outf << "\t" << '\n'; outf << "\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t\t" << '\n'; QTreeWidgetItem *header = transactionsView->headerItem(); outf << "\t\t\t\t\t"; for(int index = 0; index <= comments_col; index++) { if(!transactionsView->isColumnHidden(index)) { outf << ""; } } outf << "\n"; outf << "\t\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; QTreeWidgetItemIterator it(transactionsView); TransactionListViewItem *i = (TransactionListViewItem*) *it; while(i) { Transactions *trans = i->transaction(); if(!trans) trans = i->splitTransaction(); outf << "\t\t\t\t" << '\n'; outf << "\t\t\t\t\t"; for(int index = 0; index <= comments_col; index++) { if(!transactionsView->isColumnHidden(index)) { if(index == 0) { outf << ""; } else if(index == 1) { outf << ""; } else if(index == 2) { outf << ""; } else { outf << ""; } } } outf << "\n"; outf << "\t\t\t\t" << '\n'; ++it; i = (TransactionListViewItem*) *it; } outf << "\t\t\t" << '\n'; outf << "\t\t
    "; switch(transtype) { case TRANSACTION_TYPE_EXPENSE: {outf << htmlize_string(tr("Expenses")); break;} case TRANSACTION_TYPE_INCOME: {outf << htmlize_string(tr("Incomes")); break;} default: {outf << htmlize_string(tr("Transfers")); break;} } outf << "
    " << htmlize_string(header->text(index)) << "
    " << htmlize_string(QLocale().toString(trans->date(), QLocale::ShortFormat)) << "" << htmlize_string(trans->description()) << "" << htmlize_string(trans->valueString()) << "" << htmlize_string(i->text(index)) << "
    " << '\n'; outf << "\t\t
    "; double intpart = 0.0; outf << htmlize_string(tr("Quantity:")) << " " << htmlize_string(budget->formatValue(current_quantity, modf(current_quantity, &intpart) != 0.0 ? 2 : 0)); outf << ", "; switch(transtype) { case TRANSACTION_TYPE_EXPENSE: { outf << htmlize_string(tr("Total cost:")) << " "; break; } case TRANSACTION_TYPE_INCOME: { outf << htmlize_string(tr("Total income:")) << " "; break; } default: { outf << htmlize_string(tr("Total amount:")) << " "; break; } } outf << htmlize_string(budget->formatMoney(current_value)); outf << ", "; outf << htmlize_string(tr("Average:")) << " " << htmlize_string(budget->formatMoney(current_value == 0.0 ? current_value : current_value / current_quantity)); outf << ", "; outf << htmlize_string(tr("Monthly average:")) << " " << htmlize_string(budget->formatMoney(current_value == 0.0 ? current_value : current_value / filterWidget->countMonths())); outf << "
    \n"; outf << "\t" << '\n'; outf << "" << '\n'; break; } case 'c': { //outf.setEncoding(Q3TextStream::Locale); QTreeWidgetItem *header = transactionsView->headerItem(); outf << "\"" << header->text(0) << "\",\"" << header->text(1) << "\",\"" << header->text(2) << "\",\"" << header->text(3) << "\",\"" << header->text(4); if(quantity_col >= 0 && b_extra) outf << "\",\"" << header->text(quantity_col); if(payee_col >= 0 && b_extra) outf << "\",\"" << header->text(payee_col); if(tags_col >= 0) outf << "\",\"" << header->text(tags_col); outf << "\",\"" << header->text(comments_col); outf << "\"\n"; QTreeWidgetItemIterator it(transactionsView); TransactionListViewItem *i = (TransactionListViewItem*) *it; while(i) { if(i->transaction()) { Transaction *trans = i->transaction(); outf << "\"" << QLocale().toString(trans->date(), QLocale::ShortFormat) << "\",\"" << trans->description() << "\",\"" << trans->valueString().replace("−", "-").remove(" ") << "\",\"" << ((trans->type() == TRANSACTION_TYPE_EXPENSE) ? trans->toAccount()->nameWithParent() : trans->fromAccount()->nameWithParent()) << "\",\"" << ((trans->type() == TRANSACTION_TYPE_EXPENSE) ? trans->fromAccount()->nameWithParent() : trans->toAccount()->nameWithParent()); if(b_extra && transtype == TRANSACTION_TYPE_EXPENSE) outf << "\",\"" << budget->formatValue(trans->quantity(), 2).replace("−", "-").remove(" "); } else { MultiAccountTransaction *trans = i->splitTransaction(); outf << "\"" << QLocale().toString(trans->date(), QLocale::ShortFormat) << "\",\"" << trans->description() << "\",\"" << trans->valueString().replace("−", "-").remove(" ") << "\",\"" << trans->category()->nameWithParent() << "\",\"" << trans->accountsString(); if(b_extra && transtype == TRANSACTION_TYPE_EXPENSE) outf << "\",\"" << budget->formatValue(trans->quantity(), 2).replace("−", "-").remove(" "); } if(payee_col >= 0 && b_extra) outf << "\",\"" << i->text(payee_col); if(tags_col >= 0) outf << "\",\"" << i->text(tags_col).replace("\"", "\'"); outf << "\",\"" << i->text(comments_col); outf << "\"\n"; ++it; i = (TransactionListViewItem*) *it; } break; } } return true; } void TransactionListWidget::transactionsReset() { filterWidget->transactionsReset(); editWidget->transactionsReset(); clearTransaction(); filterTransactions(); } void TransactionListWidget::addTransaction() { Transaction *trans = editWidget->createTransaction(); if(!trans) return; clearTransaction(); ScheduledTransaction *strans = NULL; if(trans->date() > QDate::currentDate()) { strans = new ScheduledTransaction(budget, trans, NULL); budget->addScheduledTransaction(strans); } else { budget->addTransaction(trans); } if(strans) mainWin->transactionAdded(strans); else mainWin->transactionAdded(trans); QTreeWidgetItemIterator it(transactionsView); TransactionListViewItem *i = (TransactionListViewItem*) *it; while(i) { if(i->transaction() == trans) { transactionsView->scrollToItem(i); break; } ++it; i = (TransactionListViewItem*) *it; } } void TransactionListWidget::editScheduledTransaction() { QList selection = transactionsView->selectedItems(); if(selection.count() == 1) { TransactionListViewItem *i = (TransactionListViewItem*) selection.first(); if(i->scheduledTransaction()) { mainWin->editScheduledTransaction(i->scheduledTransaction()); } } } void TransactionListWidget::cloneTransaction() { QList selection = transactionsView->selectedItems(); if(selection.count() == 1) { TransactionListViewItem *i = (TransactionListViewItem*) selection.first(); if(i->scheduledTransaction()) { mainWin->editScheduledTransaction(i->scheduledTransaction(), mainWin, true); } else if(i->splitTransaction()) { mainWin->editSplitTransaction(i->splitTransaction(), mainWin, false, true); } else if(i->transaction()) { if(i->transaction()->parentSplit()) mainWin->editSplitTransaction(i->transaction()->parentSplit(), mainWin, false, true); else mainWin->editTransaction(i->transaction(), mainWin, true); } } } void TransactionListWidget::editSplitTransaction() { QList selection = transactionsView->selectedItems(); if(selection.count() >= 1) { TransactionListViewItem *i = (TransactionListViewItem*) selection.first(); if(!i->scheduledTransaction() && i->transaction()->parentSplit()) { if(mainWin->editSplitTransaction(i->transaction()->parentSplit())) clearTransaction(); } } } void TransactionListWidget::editTimestamp() { QList selection = transactionsView->selectedItems(); if(selection.count() >= 1) { QList trans; for(int index = 0; index < selection.size(); index++) { TransactionListViewItem *i = (TransactionListViewItem*) selection.at(index); if(i->scheduledTransaction()) { trans << i->scheduledTransaction(); } else if(i->splitTransaction()) { trans << i->splitTransaction(); } else { trans << i->transaction(); } } if(mainWin->editTimestamp(trans)) { transactionSelectionChanged(); transactionsView->setSortingEnabled(false); transactionsView->setSortingEnabled(true); } } } void TransactionListWidget::createLink(bool link_to) { QList selection = transactionsView->selectedItems(); if(selection.count() >= 1) { QList transactions; for(int index = 0; index < selection.count(); index++) { TransactionListViewItem *i = (TransactionListViewItem*) selection.at(index); if(i->scheduledTransaction()) transactions << i->scheduledTransaction(); else if(i->splitTransaction()) transactions << i->splitTransaction(); else if(i->transaction()) transactions << i->transaction(); } for(int index = 0; index < transactions.count(); index++) { Transactions *itrans = transactions.at(index); if(itrans->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE) { Transaction *trans = (Transaction*) itrans; if(trans->parentSplit()) { SplitTransaction *split = trans->parentSplit(); if(split->type() == SPLIT_TRANSACTION_TYPE_LOAN) { transactions.replace(index, split); for(int i = index + 1; i < transactions.count();) { if(transactions.at(i)->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE && ((Transaction*) transactions.at(i))->parentSplit() == split) { transactions.removeAt(i); } else { i++; } } } else { int n = split->count(); bool b = true; for(int i = 0; i < n; i++) { if(!transactions.contains(split->at(i))) { b = false; break; } } if(b) { transactions.replace(index, split); for(int i = 0; i < n; i++) { transactions.removeAll(split->at(i)); } } } } } } mainWin->createLink(transactions, link_to); } } void TransactionListWidget::modifyTags() { QList selection = transactionsView->selectedItems(); if(selection.count() >= 1) { QList trans; if(selection.count() > 1) mainWin->startBatchEdit(); for(int index = 0; index < selection.size(); index++) { TransactionListViewItem *i = (TransactionListViewItem*) selection.at(index); Transactions *trans = i->splitTransaction(); if(!trans) { if(i->transaction()->parentSplit() && i->transaction()->parentSplit()->type() == SPLIT_TRANSACTION_TYPE_LOAN) trans = i->transaction()->parentSplit(); else trans = i->transaction(); } if(i->scheduledTransaction()) { Transactions *oldtrans = i->scheduledTransaction()->copy(); mainWin->tagMenu->modifyTransaction(trans); mainWin->transactionModified(i->scheduledTransaction(), oldtrans); delete oldtrans; } else { Transactions *oldtrans = trans->copy(); mainWin->tagMenu->modifyTransaction(trans); mainWin->transactionModified(trans, oldtrans); delete oldtrans; } } if(selection.count() > 1) mainWin->endBatchEdit(); transactionSelectionChanged(); } } void TransactionListWidget::editTransaction() { QList selection = transactionsView->selectedItems(); if(selection.count() == 1) { TransactionListViewItem *i = (TransactionListViewItem*) selection.first(); if(i->scheduledTransaction()) { if(i->scheduledTransaction()->isOneTimeTransaction()) { if(mainWin->editScheduledTransaction(i->scheduledTransaction())) clearTransaction(); } else { if(mainWin->editOccurrence(i->scheduledTransaction(), i->date())) clearTransaction(); } } else if(i->splitTransaction()) { if(mainWin->editSplitTransaction(i->splitTransaction())) clearTransaction(); } else { if(mainWin->editTransaction(i->transaction())) clearTransaction(); } } else if(selection.count() > 1) { budget->setRecordNewAccounts(true); budget->resetDefaultCurrencyChanged(); budget->resetCurrenciesModified(); bool warned1 = false, warned2 = false, warned3 = false, warned4 = false, warned5 = false; MultipleTransactionsEditDialog *dialog = new MultipleTransactionsEditDialog(b_extra, transtype, budget, this, true); TransactionListViewItem *i = (TransactionListViewItem*) transactionsView->currentItem(); if(!i->isSelected()) i = (TransactionListViewItem*) selection.first(); if(i) { if(i->scheduledTransaction()) dialog->setTransaction(i->transaction(), i->date()); else dialog->setTransaction(i->transaction()); } bool equal_date = true, equal_description = true, equal_value = true, equal_category = (transtype != TRANSACTION_TYPE_TRANSFER), equal_payee = (dialog->payeeButton != NULL), equal_currency = true; Transaction *comptrans = NULL; Account *compcat = NULL; Currency *compcur = NULL; QDate compdate; QString compdesc; double compvalue = 0.0; bool incomplete_split = false; QList splits; for(int index = 0; index < selection.size(); index++) { TransactionListViewItem *i = (TransactionListViewItem*) selection.at(index); if(!comptrans) { if(i->splitTransaction()) { comptrans = i->splitTransaction()->at(0); compvalue = i->splitTransaction()->value(); compcur = i->splitTransaction()->currency(); for(int split_i = 1; split_i < i->splitTransaction()->count(); split_i++) { Transaction *i_trans = i->splitTransaction()->at(split_i); if((comptrans->type() == TRANSACTION_TYPE_EXPENSE && ((Expense*) comptrans)->payee() != ((Expense*) i_trans)->payee()) || (comptrans->type() == TRANSACTION_TYPE_INCOME && ((Income*) comptrans)->payer() != ((Income*) i_trans)->payer())) { equal_payee = false; } if(i_trans->date() != comptrans->date()) { equal_date = false; } if(equal_currency && (i_trans->fromCurrency() != compcur || i_trans->toCurrency() != compcur)) equal_currency = false; } compcat = i->splitTransaction()->category(); compdesc = i->splitTransaction()->description(); } else { comptrans = i->transaction(); compvalue = comptrans->value(); if(i->transaction()->parentSplit()) { if(i->transaction()->parentSplit()->type() == SPLIT_TRANSACTION_TYPE_LOAN) { equal_category = false; equal_description = false; equal_payee = false; equal_date = false; } else if(i->transaction()->parentSplit()->type() == SPLIT_TRANSACTION_TYPE_MULTIPLE_ITEMS) { MultiItemTransaction *split = (MultiItemTransaction*) i->transaction()->parentSplit(); for(int index2 = 0; index2 < split->count(); index2++) { Transaction *split_trans = split->at(index2); if(split_trans != i->transaction()) { bool b_match = false; for(int index3 = index + 1; index3 < selection.size(); index3++) { if(((TransactionListViewItem*) selection.at(index3))->transaction() == split_trans) { b_match = true; break; } } if(b_match) { if(!i->scheduledTransaction()) splits << split; } else { equal_payee = false; equal_date = false; incomplete_split = true; break; } } } } } if(i->transaction()->type() != TRANSACTION_TYPE_EXPENSE && i->transaction()->type() != TRANSACTION_TYPE_INCOME) equal_payee = false; if(i->transaction()->type() == TRANSACTION_TYPE_SECURITY_BUY || i->transaction()->type() == TRANSACTION_TYPE_SECURITY_SELL) { equal_value = false; equal_description = false; compcat = ((SecurityTransaction*) i->transaction())->account(); if(compcat->type() == ACCOUNT_TYPE_ASSETS) { equal_category = false; } } if(i->transaction()->type() == TRANSACTION_TYPE_INCOME) { compcat = ((Income*) i->transaction())->category(); } else if(i->transaction()->type() == TRANSACTION_TYPE_EXPENSE) { compcat = ((Expense*) i->transaction())->category(); } compcur = i->transaction()->fromCurrency(); if(i->transaction()->toCurrency() != compcur) equal_currency = false; compdesc != i->transaction()->description(); } compdate = i->date(); } else { Transaction *trans = i->transaction(); if(i->splitTransaction()) { trans = i->splitTransaction()->at(0); for(int split_i = 0; split_i < i->splitTransaction()->count(); split_i++) { Transaction *i_trans = i->splitTransaction()->at(split_i); if(equal_payee && ((comptrans->type() == TRANSACTION_TYPE_EXPENSE && ((Expense*) comptrans)->payee() != ((Expense*) i_trans)->payee()) || (comptrans->type() == TRANSACTION_TYPE_INCOME && ((Income*) comptrans)->payer() != ((Income*) i_trans)->payer()))) { equal_payee = false; } if(equal_date && i_trans->date() != comptrans->date()) { equal_date = false; } if(equal_currency && (i_trans->fromCurrency() != compcur || i_trans->toCurrency() != compcur)) equal_currency = false; } if(equal_value && i->splitTransaction()->value() != compvalue) equal_value = false; if(equal_category && i->splitTransaction()->category() != compcat) equal_category = false; if(equal_description && compdesc != i->splitTransaction()->description()) equal_description = false; } else { if(equal_date && compdate != i->date()) { equal_date = false; } if(equal_payee && (trans->type() != comptrans->type() || (comptrans->type() == TRANSACTION_TYPE_EXPENSE && ((Expense*) comptrans)->payee() != ((Expense*) trans)->payee()) || (comptrans->type() == TRANSACTION_TYPE_INCOME && ((Income*) comptrans)->payer() != ((Income*) trans)->payer()))) { equal_payee = false; } if(i->transaction()->parentSplit()) { if(i->transaction()->parentSplit()->type() == SPLIT_TRANSACTION_TYPE_LOAN) { equal_payee = false; equal_date = false; equal_payee = false; equal_date = false; } else if(i->transaction()->parentSplit()->type() == SPLIT_TRANSACTION_TYPE_MULTIPLE_ITEMS) { MultiItemTransaction *split = (MultiItemTransaction*) i->transaction()->parentSplit(); if(!splits.contains(split)) { for(int index2 = 0; index2 < split->count(); index2++) { Transaction *split_trans = split->at(index2); if(split_trans != i->transaction()) { bool b_match = false; for(int index3 = index + 1; index3 < selection.size(); index3++) { if(((TransactionListViewItem*) selection.at(index3))->transaction() == split_trans) { b_match = true; break; } } if(b_match) { if(!i->scheduledTransaction()) splits << split; } else { equal_date = false; incomplete_split = true; break; } } } } } } if(equal_value && (trans->type() == TRANSACTION_TYPE_SECURITY_BUY || trans->type() == TRANSACTION_TYPE_SECURITY_SELL || compvalue != trans->value())) { equal_value = false; } if(equal_category) { if(trans->type() == TRANSACTION_TYPE_INCOME) { if(compcat != ((Income*) trans)->category()) { equal_category = false; } } else if(trans->type() == TRANSACTION_TYPE_EXPENSE) { if(compcat != ((Expense*) trans)->category()) { equal_category = false; } } else if(trans->type() == TRANSACTION_TYPE_SECURITY_BUY || trans->type() == TRANSACTION_TYPE_SECURITY_SELL) { if(compcat != ((SecurityTransaction*) trans)->account()) { equal_category = false; } } } if(equal_description && (trans->type() == TRANSACTION_TYPE_SECURITY_BUY || trans->type() == TRANSACTION_TYPE_SECURITY_SELL || compdesc != trans->description())) { equal_description = false; } if(equal_currency && (i->transaction()->toCurrency() != compcur || i->transaction()->fromCurrency() != compcur)) equal_currency = false; } } } if(equal_description) dialog->descriptionButton->setChecked(true); if(equal_payee) dialog->payeeButton->setChecked(true); if(equal_value && equal_currency) dialog->valueButton->setChecked(true); if(!equal_currency) dialog->valueButton->setEnabled(false); if(equal_date) dialog->dateButton->setChecked(true); if(equal_category && dialog->categoryButton) dialog->categoryButton->setChecked(true); if(dialog->exec() == QDialog::Accepted) { foreach(Account* acc, budget->newAccounts) emit accountAdded(acc); if(!budget->newAccounts.isEmpty()) updateAccounts(); budget->newAccounts.clear(); QDate date = dialog->date(); bool future = !date.isNull() && date > QDate::currentDate(); mainWin->startBatchEdit(); for(int index = 0; index < selection.size(); index++) { TransactionListViewItem *i = (TransactionListViewItem*) selection.at(index); if(i->scheduledTransaction() && (i->splitTransaction() || (i->transaction() && i->transaction()->parentSplit()))) { } else if(i->splitTransaction()) { bool b = false; SplitTransaction *new_split = i->splitTransaction()->copy(); for(int split_i = 0; split_i < new_split->count(); split_i++) { Transaction *i_trans = new_split->at(split_i); b = dialog->modifyTransaction(i_trans, split_i == 0); } if(b) { SplitTransaction *old_split = i->splitTransaction(); budget->removeSplitTransaction(old_split, true); mainWin->transactionRemoved(old_split); delete old_split; budget->addSplitTransaction(new_split); mainWin->transactionAdded(new_split); } else { delete new_split; } } else { if(!warned1 && (i->transaction()->type() == TRANSACTION_TYPE_SECURITY_BUY || i->transaction()->type() == TRANSACTION_TYPE_SECURITY_SELL)) { if(dialog->valueButton->isChecked()) { QMessageBox::critical(this, tr("Error"), tr("Cannot set the value of security transactions using the dialog for modifying multiple transactions.", "Financial security (e.g. stock, mutual fund)")); warned1 = true; } } if(!warned2 && (i->transaction()->type() == TRANSACTION_TYPE_SECURITY_BUY || i->transaction()->type() == TRANSACTION_TYPE_SECURITY_SELL || (i->transaction()->type() == TRANSACTION_TYPE_INCOME && ((Income*) i->transaction())->security()))) { if(dialog->descriptionButton->isChecked()) { QMessageBox::critical(this, tr("Error"), tr("Cannot change description of dividends and security transactions.", "Referring to the transaction description property (transaction title/generic article name); Financial security (e.g. stock, mutual fund)")); warned2 = true; } } if(!warned3 && dialog->payeeButton && (i->transaction()->type() == TRANSACTION_TYPE_SECURITY_BUY || i->transaction()->type() == TRANSACTION_TYPE_SECURITY_SELL || (i->transaction()->type() == TRANSACTION_TYPE_INCOME && ((Income*) i->transaction())->security()))) { if(dialog->payeeButton->isChecked()) { QMessageBox::critical(this, tr("Error"), tr("Cannot change payer of dividends and security transactions.", "Financial security (e.g. stock, mutual fund)")); warned3 = true; } } if(i->transaction()->parentSplit()) { if(i->transaction()->parentSplit()->type() == SPLIT_TRANSACTION_TYPE_LOAN) { if(!warned5) { if(dialog->dateButton->isChecked() || dialog->descriptionButton->isChecked() || dialog->categoryButton->isChecked() || (dialog->payeeButton && dialog->payeeButton->isChecked())) { QMessageBox::critical(this, tr("Error"), tr("Cannot change date, description, expense category or payee of transactions that are part of a debt payment using the dialog for modifying multiple transactions.", "Referring to the transaction description property (transaction title/generic article name)")); warned5 = true; } } } else if(incomplete_split && !warned4) { if(dialog->dateButton->isChecked()) { QMessageBox::critical(this, tr("Error"), tr("Cannot change date of transactions that are part of a split transaction, unless all individual transactions are selected.")); warned4 = true; } } } ScheduledTransaction *strans = i->scheduledTransaction(); if(strans && strans->isOneTimeTransaction() && (date.isNull() || date == strans->transaction()->date())) { ScheduledTransaction *old_strans = strans->copy(); Transaction *trans = (Transaction*) strans->transaction(); if(dialog->modifyTransaction(trans)) { mainWin->transactionModified(strans, old_strans); } delete old_strans; } else if(strans) { if(strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE) { date = i->date(); Transaction *trans = (Transaction*) strans->transaction()->copy(); trans->setDate(date); if(dialog->modifyTransaction(trans)) { if(future) { ScheduledTransaction *strans_new = new ScheduledTransaction(budget, trans, NULL); budget->addScheduledTransaction(strans_new); mainWin->transactionAdded(strans_new); } else { budget->addTransaction(trans); mainWin->transactionAdded(trans); } if(strans->isOneTimeTransaction()) { budget->removeScheduledTransaction(strans, true); mainWin->transactionRemoved(strans); delete strans; } else { ScheduledTransaction *old_strans = strans->copy(); strans->addException(date); mainWin->transactionModified(strans, old_strans); delete old_strans; } } else { delete trans; } } } else { Transaction *trans = i->transaction(); Transaction *oldtrans = trans->copy(); if(dialog->modifyTransaction(trans)) { if(future && !trans->parentSplit()) { budget->removeTransaction(trans, true); mainWin->transactionRemoved(trans); strans = new ScheduledTransaction(budget, trans, NULL); budget->addScheduledTransaction(strans); mainWin->transactionAdded(strans); } else { mainWin->transactionModified(trans, oldtrans); } } delete oldtrans; } } } for(int index = 0; index < splits.size(); index++) { MultiItemTransaction *old_split = splits.at(index); SplitTransaction *new_split = old_split->copy(); if(dialog->modifySplitTransaction(new_split)) { budget->removeSplitTransaction(old_split, true); mainWin->transactionRemoved(old_split); delete old_split; if(!future) { budget->addSplitTransaction(new_split); mainWin->transactionAdded(new_split); } else { ScheduledTransaction *strans = new ScheduledTransaction(budget, new_split, NULL); budget->addScheduledTransaction(strans); mainWin->transactionAdded(strans); } } else { delete new_split; } } mainWin->endBatchEdit(); transactionSelectionChanged(); } else { foreach(Account* acc, budget->newAccounts) emit accountAdded(acc); if(!budget->newAccounts.isEmpty()) updateAccounts(); budget->newAccounts.clear(); } if(budget->currenciesModified() || budget->defaultCurrencyChanged()) emit currenciesModified(); budget->setRecordNewAccounts(false); dialog->deleteLater(); } } void TransactionListWidget::modifyTransaction() { QList selection = transactionsView->selectedItems(); if(selection.isEmpty()) return; if(selection.count() > 1) { editTransaction(); return; } TransactionListViewItem *i = (TransactionListViewItem*) selection.first(); if(!i) return; if(((TransactionListViewItem*) i)->splitTransaction()) { editTransaction(); return; } if(((TransactionListViewItem*) i)->transaction()->parentSplit()) { Transaction *trans = ((TransactionListViewItem*) i)->transaction(); if(trans->parentSplit()->type() == SPLIT_TRANSACTION_TYPE_MULTIPLE_ITEMS && trans->type() == transtype) { MultiItemTransaction *split = (MultiItemTransaction*) trans->parentSplit(); int index = 0; for(; index < split->count(); index++) { if(split->at(index) == trans) break; } MultiItemTransaction *split_new = NULL; if(transtype == TRANSACTION_TYPE_EXPENSE && trans->subtype() == TRANSACTION_SUBTYPE_EXPENSE) { split_new = (MultiItemTransaction*) split->copy(); Expense *expense = (Expense*) split_new->at(index); editWidget->modifyTransaction(expense); split_new->setAccount(expense->from()); split_new->setDate(expense->date()); } else if(transtype == TRANSACTION_TYPE_INCOME && trans->subtype() == TRANSACTION_SUBTYPE_INCOME && !((Income*) trans)->security()) { split_new = (MultiItemTransaction*) split->copy(); Income *income = (Income*) split_new->at(index); editWidget->modifyTransaction(income); split_new->setAccount(income->to()); split_new->setDate(income->date()); } else if(transtype == TRANSACTION_TYPE_TRANSFER && trans->subtype() == TRANSACTION_SUBTYPE_TRANSFER) { split_new = (MultiItemTransaction*) split->copy(); Transfer *transfer = (Transfer*) split_new->at(index); bool b_from = (transfer->from() == split->account()); editWidget->modifyTransaction(transfer); if(b_from) { AssetsAccount *new_account = transfer->from(); transfer->setFrom(split->account()); split_new->setAccount(new_account); } else { AssetsAccount *new_account = transfer->to(); transfer->setTo(split->account()); split_new->setAccount(new_account); } split_new->setDate(transfer->date()); } if(split_new) { if(mainWin->editSplitTransaction(split_new, this, true)) { budget->removeSplitTransaction(split, true); mainWin->transactionRemoved(split); delete split; clearTransaction(); } delete split_new; return; } } editSplitTransaction(); return; } if(((TransactionListViewItem*) i)->transaction()->type() == TRANSACTION_TYPE_SECURITY_BUY || ((TransactionListViewItem*) i)->transaction()->type() == TRANSACTION_TYPE_SECURITY_SELL || (((TransactionListViewItem*) i)->transaction()->type() == TRANSACTION_TYPE_INCOME && ((Income*) ((TransactionListViewItem*) i)->transaction())->security())) { editTransaction(); return; } if(i->scheduledTransaction() && i->scheduledTransaction()->transaction()->generaltype() != GENERAL_TRANSACTION_TYPE_SINGLE) { editTransaction(); return; } if(!editWidget->validValues(true)) return; ScheduledTransaction *curstranscopy = i->scheduledTransaction(); QDate curdate_copy = i->date(); if(i->scheduledTransaction()) { if(i->scheduledTransaction()->isOneTimeTransaction()) { Transaction *trans = (Transaction*) i->scheduledTransaction()->transaction()->copy(); if(!editWidget->modifyTransaction(trans)) { delete trans; return; } mainWin->removeScheduledTransaction(i->scheduledTransaction()); ScheduledTransaction *strans = NULL; if(trans->date() > QDate::currentDate()) { strans = new ScheduledTransaction(budget, trans, NULL); budget->addScheduledTransaction(strans); } else { budget->addTransaction(trans); } if(strans) mainWin->transactionAdded(strans); else mainWin->transactionAdded(trans); QTreeWidgetItemIterator it(transactionsView); TransactionListViewItem *i = (TransactionListViewItem*) *it; while(i) { if(i->transaction() == trans) { transactionsView->setCurrentItem(i); i->setSelected(true); break; } ++it; i = (TransactionListViewItem*) *it; } clearTransaction(); return; } } if(editWidget->date() > QDate::currentDate() || curstranscopy) { Transaction *newtrans = i->transaction()->copy(); if(editWidget->modifyTransaction(newtrans)) { Transactions *trans = newtrans; if(editWidget->date() > QDate::currentDate()) trans = new ScheduledTransaction(budget, newtrans, NULL); removeTransaction(); budget->addTransactions(trans); mainWin->transactionAdded(trans); QTreeWidgetItemIterator it(transactionsView); TransactionListViewItem *i = (TransactionListViewItem*) *it; while(i) { if(i->scheduledTransaction() == trans || i->transaction() == trans) { transactionsView->setCurrentItem(i); i->setSelected(true); break; } ++it; i = (TransactionListViewItem*) *it; } } else { delete newtrans; } } else { Transaction *oldtrans = (Transaction*) i->transaction()->copy(); if(editWidget->modifyTransaction(i->transaction())) { mainWin->transactionModified(i->transaction(), oldtrans); } delete oldtrans; transactionsView->scrollToItem(i); } if(curstranscopy) { ScheduledTransaction *oldstrans = curstranscopy->copy(); curstranscopy->addException(curdate_copy); mainWin->transactionModified(curstranscopy, oldstrans); delete oldstrans; } clearTransaction(); } void TransactionListWidget::removeScheduledTransaction() { QList selection = transactionsView->selectedItems(); if(selection.count() == 1) { TransactionListViewItem *i = (TransactionListViewItem*) selection.first(); if(!i->scheduledTransaction()) return; if(i->transaction() && i->transaction()->parentSplit()) { ScheduledTransaction *strans = i->scheduledTransaction(); Transaction *trans = i->transaction(); budget->removeScheduledTransaction(i->scheduledTransaction(), true); mainWin->transactionRemoved(i->scheduledTransaction()); SplitTransaction *split = (SplitTransaction*) strans->transaction(); if(split->count() == 1) { delete strans; } else if(split->type() != SPLIT_TRANSACTION_TYPE_LOAN && split->count() == 2) { split->removeTransaction(trans); ScheduledTransaction *strans_new = new ScheduledTransaction(budget, split->at(0)->copy(), strans->recurrence()->copy()); delete strans; budget->addScheduledTransaction(strans_new); mainWin->transactionAdded(strans_new); } else { split->removeTransaction(trans); budget->addScheduledTransaction(strans); mainWin->transactionAdded(strans); } } else { mainWin->removeScheduledTransaction(i->scheduledTransaction()); clearTransaction(); } } } void TransactionListWidget::removeSplitTransaction() { QList selection = transactionsView->selectedItems(); if(selection.count() >= 1) { TransactionListViewItem *i = (TransactionListViewItem*) selection.first(); if(i->splitTransaction() || i->transaction()->parentSplit()) { SplitTransaction *split = i->splitTransaction(); if(!split) split = i->transaction()->parentSplit(); if(QMessageBox::warning(this, tr("Delete transactions?"), tr("Are you sure you want to delete all (%1) transactions in the selected split transaction?").arg(split->count()), QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) { return; } budget->removeSplitTransaction(split, true); mainWin->transactionRemoved(split); delete split; clearTransaction(); } } } void TransactionListWidget::splitUpTransaction() { QList selection = transactionsView->selectedItems(); if(selection.count() >= 1) { TransactionListViewItem *i = (TransactionListViewItem*) selection.first(); if(i->splitTransaction()) { mainWin->splitUpTransaction(i->splitTransaction()); transactionSelectionChanged(); } else if(i->transaction() && i->transaction()->parentSplit()) { mainWin->splitUpTransaction(i->transaction()->parentSplit()); transactionSelectionChanged(); } } } void TransactionListWidget::joinTransactions() { QList selection = transactionsView->selectedItems(); SplitTransaction *split = NULL; QString payee; bool use_payee = true; QList sel_bak; int b_multiaccount = -1; QString description; bool different_descriptions = false, different_dates = false; Account *account = NULL, *category = NULL; QDate date; for(int index = 0; index < selection.size(); index++) { TransactionListViewItem *i = (TransactionListViewItem*) selection.at(index); Transaction *trans = i->transaction(); if(trans && !i->scheduledTransaction() && !i->splitTransaction() && !trans->parentSplit()) { if(trans->type() != transtype || (trans->type() != TRANSACTION_TYPE_EXPENSE && trans->type() != TRANSACTION_TYPE_INCOME)) { b_multiaccount = 0; break; } else if(!account) { if(trans->fromAccount()->type() == ACCOUNT_TYPE_ASSETS) {account = trans->fromAccount(); category = trans->toAccount();} else {account = trans->toAccount(); category = trans->fromAccount();} date = trans->date(); description = trans->description(); } else { if(trans->fromAccount()->type() == ACCOUNT_TYPE_ASSETS) { if(trans->toAccount() != category) { b_multiaccount = 0; break; } else if(b_multiaccount < 1 && trans->fromAccount() != account) { b_multiaccount = 1; } } else { if(trans->fromAccount() != category) { b_multiaccount = 0; break; } else if(b_multiaccount < 1 && trans->toAccount() != account) { b_multiaccount = 1; } } if(!different_dates && trans->date() != date) different_dates = true; if(description.isEmpty()) description = trans->description(); else if(!different_descriptions && !trans->description().isEmpty() && description != trans->description()) different_descriptions = true; } } } if(b_multiaccount != 0) { if(different_descriptions && b_multiaccount == 1) b_multiaccount = -1; else if(b_multiaccount < 0 && different_descriptions && !different_dates) b_multiaccount = 0; } if(b_multiaccount < 0) { QMessageBox::StandardButton b = QMessageBox::question(this, tr("Join as multiple accounts/payments?"), transtype == TRANSACTION_TYPE_EXPENSE ? tr("Do you wish join the selected expenses as an expense with multiple accounts/payments?") : tr("Do you wish join the selected incomes as an income with multiple accounts/payments?"), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel); if(b == QMessageBox::Yes) b_multiaccount = 1; else if(b == QMessageBox::Cancel) return; else b_multiaccount = 0; } if(b_multiaccount > 0) { for(int index = 0; index < selection.size(); index++) { TransactionListViewItem *i = (TransactionListViewItem*) selection.at(index); Transaction *trans = i->transaction(); if(trans && !i->scheduledTransaction() && !i->splitTransaction() && !trans->parentSplit()) { sel_bak << trans; if(!split) { if(trans->fromAccount()->type() == ACCOUNT_TYPE_ASSETS) split = new MultiAccountTransaction(budget, (CategoryAccount*) trans->toAccount(), trans->description()); else split = new MultiAccountTransaction(budget, (CategoryAccount*) trans->fromAccount(), trans->description()); } else { if(((MultiAccountTransaction*) split)->description().isEmpty() && !trans->description().isEmpty()) { ((MultiAccountTransaction*) split)->setDescription(trans->description()); } } if(!trans->associatedFile().isEmpty()) { if(split->associatedFile().isEmpty()) { split->setAssociatedFile(trans->associatedFile()); } else { QString str; if((split->associatedFile().startsWith("\"") && split->associatedFile().endsWith("\"")) || (split->associatedFile().startsWith("\'") && split->associatedFile().endsWith("\'"))) str += split->associatedFile(); else if(split->associatedFile().contains("\"")) {str += "\'"; str += split->associatedFile(); str += "\'";} else {str += "\""; str += split->associatedFile(); str += "\"";} str += ", "; if((trans->associatedFile().startsWith("\"") && trans->associatedFile().endsWith("\"")) || (trans->associatedFile().startsWith("\'") && trans->associatedFile().endsWith("\'"))) str += trans->associatedFile(); else if(trans->associatedFile().contains("\"")) {str += "\'"; str += trans->associatedFile(); str += "\'";} else {str += "\""; str += trans->associatedFile(); str += "\"";} split->setAssociatedFile(str); } } if(!trans->comment().isEmpty()) { if(split->comment().isEmpty()) split->setComment(trans->comment()); else split->setComment(split->comment() + " / " + trans->comment()); } split->addTransaction(trans->copy()); } } } else { for(int index = 0; index < selection.size(); index++) { TransactionListViewItem *i = (TransactionListViewItem*) selection.at(index); Transaction *trans = i->transaction(); if(trans && !i->scheduledTransaction() && !i->splitTransaction() && !trans->parentSplit()) { sel_bak << trans; if(!split) { if((trans->type() == TRANSACTION_TYPE_SECURITY_BUY || trans->type() == TRANSACTION_TYPE_SECURITY_SELL) && ((SecurityTransaction*) trans)->account()->type() == ACCOUNT_TYPE_ASSETS) split = new MultiItemTransaction(budget, i->transaction()->date(), (AssetsAccount*) ((SecurityTransaction*) trans)->account()); else if(trans->type() == TRANSACTION_TYPE_TRANSFER && selection.size() > index + 1) { TransactionListViewItem *i_next = (TransactionListViewItem*) selection.at(index + 1); Transaction *trans_next = i_next->transaction(); if(trans_next && !i_next->scheduledTransaction() && !i_next->splitTransaction() && !trans_next->parentSplit()) { if((trans_next->type() == TRANSACTION_TYPE_SECURITY_BUY || trans_next->type() == TRANSACTION_TYPE_SECURITY_SELL) && ((SecurityTransaction*) trans_next)->account()->type() == ACCOUNT_TYPE_ASSETS) split = new MultiItemTransaction(budget, i->transaction()->date(), (AssetsAccount*) ((SecurityTransaction*) trans_next)->account()); else if(trans->type() == TRANSACTION_TYPE_TRANSFER) { if(trans->fromAccount() == trans_next->toAccount() || trans->fromAccount() == trans_next->fromAccount()) split = new MultiItemTransaction(budget, i->transaction()->date(), (AssetsAccount*) trans->fromAccount()); else if(trans->toAccount() == trans_next->toAccount() || trans->toAccount() == trans_next->fromAccount()) split = new MultiItemTransaction(budget, i->transaction()->date(), (AssetsAccount*) trans->toAccount()); else split = new MultiItemTransaction(budget, i->transaction()->date(), (AssetsAccount*) trans->fromAccount()); } else if(trans_next->fromAccount()->type() == ACCOUNT_TYPE_ASSETS) split = new MultiItemTransaction(budget, i->transaction()->date(), (AssetsAccount*) trans_next->fromAccount()); else split = new MultiItemTransaction(budget, i->transaction()->date(), (AssetsAccount*) trans_next->toAccount()); } if(!split) split = new MultiItemTransaction(budget, i->transaction()->date(), (AssetsAccount*) trans->fromAccount()); } else if(trans->fromAccount()->type() == ACCOUNT_TYPE_ASSETS) split = new MultiItemTransaction(budget, i->transaction()->date(), (AssetsAccount*) trans->fromAccount()); else split = new MultiItemTransaction(budget, i->transaction()->date(), (AssetsAccount*) trans->toAccount()); } if(!trans->associatedFile().isEmpty()) { if(split->associatedFile().isEmpty()) { split->setAssociatedFile(trans->associatedFile()); } else { QString str; if((split->associatedFile().startsWith("\"") && split->associatedFile().endsWith("\"")) || (split->associatedFile().startsWith("\'") && split->associatedFile().endsWith("\'"))) str += split->associatedFile(); else if(split->associatedFile().contains("\"")) {str += "\'"; str += split->associatedFile(); str += "\'";} else {str += "\""; str += split->associatedFile(); str += "\"";} str += ", "; if((trans->associatedFile().startsWith("\"") && trans->associatedFile().endsWith("\"")) || (trans->associatedFile().startsWith("\'") && trans->associatedFile().endsWith("\'"))) str += trans->associatedFile(); else if(trans->associatedFile().contains("\"")) {str += "\'"; str += trans->associatedFile(); str += "\'";} else {str += "\""; str += trans->associatedFile(); str += "\"";} split->setAssociatedFile(str); } } if(use_payee) { if(payee.isEmpty()) { if(trans->type() == TRANSACTION_TYPE_EXPENSE) payee = ((Expense*) trans)->payee(); else if(trans->type() == TRANSACTION_TYPE_INCOME) payee = ((Income*) trans)->payer(); } else { if(trans->type() == TRANSACTION_TYPE_EXPENSE && !((Expense*) trans)->payee().isEmpty() && payee != ((Expense*) trans)->payee()) use_payee = false; else if(trans->type() == TRANSACTION_TYPE_INCOME && !((Income*) trans)->payer().isEmpty() && payee != ((Income*) trans)->payer()) use_payee = false; } } split->addTransaction(trans->copy()); } } } if(!split) return; if(!b_multiaccount && use_payee && !payee.isEmpty()) ((MultiItemTransaction*) split)->setPayee(payee); if(mainWin->editSplitTransaction(split, mainWin, true)) { delete split; for(int index = 0; index < sel_bak.size(); index++) { Transaction *trans = sel_bak.at(index); budget->removeTransaction(trans, true); mainWin->transactionRemoved(trans); delete trans; } clearTransaction(); } else { delete split; } } void TransactionListWidget::removeTransaction() { QList selection = transactionsView->selectedItems(); if(selection.count() > 1) { if(QMessageBox::warning(this, tr("Delete transactions?"), tr("Are you sure you want to delete all (%1) selected transactions?").arg(selection.count()), QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) { return; } mainWin->startBatchEdit(); } transactionsView->clearSelection(); for(int index = 0; index < selection.count(); index++) { TransactionListViewItem *i = (TransactionListViewItem*) selection.at(index); if(i->scheduledTransaction()) { ScheduledTransaction *strans = i->scheduledTransaction(); if(i->splitTransaction()) { if(strans->isOneTimeTransaction()) { budget->removeScheduledTransaction(strans, true); mainWin->transactionRemoved(strans, NULL, true); delete strans; } else { QList exception_dates; exception_dates << i->date(); for(int index2 = index; index2 < selection.count(); index2++) { TransactionListViewItem *i = (TransactionListViewItem*) selection.at(index); if(i->scheduledTransaction() == strans) { exception_dates << i->date(); } } mainWin->transactionRemoved(strans); for(int date_index = 0; date_index < exception_dates.count(); date_index++) { if(strans->isOneTimeTransaction()) { mainWin->removeTransactionLinks(strans); budget->removeScheduledTransaction(strans, true); delete strans; strans = NULL; break; } strans->addException(exception_dates[date_index]); } if(strans) mainWin->transactionAdded(strans); } } else if(i->transaction() && i->transaction()->parentSplit()) { if(index == 0 && selection.count() == 1) { QDate date = i->date(); SplitTransaction *split = (SplitTransaction*) strans->transaction()->copy(); split->setDate(date); for(int split_i = 0; split_i < split->count(); split_i++) { if(((SplitTransaction*) strans->transaction())->at(split_i) == i->transaction()) { split->removeTransaction(split->at(split_i)); break; } } ScheduledTransaction *strans_new = new ScheduledTransaction(budget, split, NULL); mainWin->transactionAdded(strans_new); if(strans->isOneTimeTransaction()) { mainWin->transactionRemoved(strans, NULL, true); budget->removeScheduledTransaction(strans, true); delete strans; } else { mainWin->transactionRemoved(strans); strans->addException(date); mainWin->transactionAdded(strans); } } } else { if(strans->isOneTimeTransaction()) { budget->removeScheduledTransaction(strans, true); mainWin->transactionRemoved(strans, NULL, true); delete strans; } else { ScheduledTransaction *oldstrans = strans->copy(); strans->addException(i->date()); mainWin->transactionModified(strans, oldstrans); delete oldstrans; } } } else if(i->splitTransaction()) { MultiAccountTransaction *split = i->splitTransaction(); budget->removeSplitTransaction(split, true); mainWin->transactionRemoved(split, NULL, true); delete split; } else { Transaction *trans = i->transaction(); if(trans->parentSplit() && trans->parentSplit()->count() == 1) { SplitTransaction *split = trans->parentSplit(); budget->removeSplitTransaction(split, true); mainWin->transactionRemoved(split, NULL, true); delete split; } else if(trans->parentSplit() && trans->parentSplit()->type() != SPLIT_TRANSACTION_TYPE_LOAN && trans->parentSplit()->count() == 2) { SplitTransaction *split = trans->parentSplit(); mainWin->splitUpTransaction(split); budget->removeTransaction(trans, true); mainWin->transactionRemoved(trans, NULL, true); delete trans; } else { budget->removeTransaction(trans, true); mainWin->transactionRemoved(trans, NULL, true); delete trans; } } } mainWin->endBatchEdit(); } void TransactionListWidget::editClear() { editWidget->setTransaction(NULL); } void TransactionListWidget::addModifyTransaction() { addTransaction(); } void TransactionListWidget::appendFilterTransaction(Transactions *transs, bool update_total_value, ScheduledTransaction *strans) { Transaction *trans = NULL; MultiAccountTransaction *split = NULL; switch(transs->generaltype()) { case GENERAL_TRANSACTION_TYPE_SINGLE: { if(filterWidget->filterTransaction(transs, !strans)) return; trans = (Transaction*) transs; break; } case GENERAL_TRANSACTION_TYPE_SPLIT: { if(((SplitTransaction*) transs)->type() != SPLIT_TRANSACTION_TYPE_MULTIPLE_ACCOUNTS) return; if(filterWidget->filterTransaction(transs, !strans)) return; split = (MultiAccountTransaction*) transs; break; } case GENERAL_TRANSACTION_TYPE_SCHEDULE: { strans = (ScheduledTransaction*) transs; transs = strans->transaction(); if(transs->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { if(((SplitTransaction*) transs)->type() != SPLIT_TRANSACTION_TYPE_MULTIPLE_ACCOUNTS) { SplitTransaction *split2 = (SplitTransaction*) transs; int c = split2->count(); for(int i = 0; i < c; i++) { appendFilterTransaction(split2->at(i), update_total_value, strans); } return; } split = (MultiAccountTransaction*) transs; } else { trans = (Transaction*) transs; } if(filterWidget->filterTransaction(transs, false)) return; break; } } QDate date = filterWidget->startDate(); QDate enddate = filterWidget->endDate(); if(strans) { if(strans->isOneTimeTransaction()) { if(date.isNull()) date = strans->firstOccurrence(); else if(date > strans->firstOccurrence()) date = QDate(); else date = strans->firstOccurrence(); } else { if(date.isNull()) date = strans->recurrence()->firstOccurrence(); else date = strans->recurrence()->nextOccurrence(date, true); } if(date.isNull() || date > enddate) update_total_value = false; } else { date = transs->date(); } QSettings settings; right_align_values = settings.value("GeneralOptions/rightAlignValues", true).toBool(); while(!strans || (!date.isNull() && date <= enddate)) { QTreeWidgetItem *i = new TransactionListViewItem(date, trans, strans, split, QString(), QString(), right_align_values ? transs->valueString() + " " : transs->valueString()); if(strans && strans->recurrence()) i->setText(0, QLocale().toString(date, QLocale::ShortFormat) + "**"); else i->setText(0, QLocale().toString(date, QLocale::ShortFormat)); transactionsView->insertTopLevelItem(0, i); if(right_align_values) i->setTextAlignment(2, Qt::AlignRight | Qt::AlignVCenter); if((split && split->cost() > 0.0) || (trans && ((trans->type() == TRANSACTION_TYPE_EXPENSE && trans->value() > 0.0) || (trans->type() == TRANSACTION_TYPE_INCOME && trans->value() < 0.0)))) { if(!expenseColor.isValid()) expenseColor = createExpenseColor(i, 2); i->setForeground(2, expenseColor); } else if((split && split->cost() < 0.0) || (trans && ((trans->type() == TRANSACTION_TYPE_EXPENSE && trans->value() < 0.0) || (trans->type() == TRANSACTION_TYPE_INCOME && trans->value() > 0.0)))) { if(!incomeColor.isValid()) incomeColor = createIncomeColor(i, 2); i->setForeground(2, incomeColor); } else { if(!transferColor.isValid()) transferColor = createTransferColor(i, 2); i->setForeground(2, transferColor); } if(strans) { QFont font = i->font(0); font.setItalic(true); i->setFont(0, font); i->setFont(1, font); i->setFont(2, font); i->setFont(3, font); i->setFont(4, font); i->setFont(5, font); i->setFont(6, font); i->setFont(7, font); } if((trans && trans == selected_trans) || (split && split == selected_trans)) { transactionsView->blockSignals(true); i->setSelected(true); transactionsView->blockSignals(false); } if(trans && trans->parentSplit()) i->setText(1, trans->description() + "*"); else i->setText(1, transs->description()); if(trans) { i->setText(from_col, trans->fromAccount()->name()); i->setText(to_col, trans->toAccount()->name()); if(payee_col >= 0) { if(trans->type() == TRANSACTION_TYPE_EXPENSE) i->setText(payee_col, ((Expense*) trans)->payee()); else if(trans->type() == TRANSACTION_TYPE_INCOME) i->setText(payee_col, ((Income*) trans)->payer()); } if(trans->parentSplit() && trans->comment().isEmpty()) i->setText(comments_col, trans->parentSplit()->comment()); else i->setText(comments_col, trans->comment()); if(quantity_col >= 0) i->setText(quantity_col, budget->formatValue(trans->quantity())); if(tags_col >= 0) i->setText(tags_col, trans->tagsText(true)); if(!trans->associatedFile().isEmpty() || (trans->parentSplit() && !trans->parentSplit()->associatedFile().isEmpty())) i->setIcon(2, LOAD_ICON_STATUS("mail-attachment")); if(trans->linksCount(true) > 0) i->setIcon(comments_col, LOAD_ICON_STATUS("go-jump")); } else if(split) { i->setText(3, split->category()->name()); i->setText(4, split->accountsString()); if(payee_col >= 0) i->setText(payee_col, split->payeeText()); if(quantity_col >= 0) i->setText(quantity_col, budget->formatValue(split->quantity())); i->setText(comments_col, transs->comment()); if(tags_col >= 0) i->setText(tags_col, transs->tagsText()); if(!split->associatedFile().isEmpty()) i->setIcon(2, LOAD_ICON_STATUS("mail-attachment")); if(split->linksCount() > 0) i->setIcon(comments_col, LOAD_ICON_STATUS("go-jump")); } current_value += transs->value(true); current_quantity += transs->quantity(); if(strans && !strans->isOneTimeTransaction()) date = strans->recurrence()->nextOccurrence(date); else break; } if(update_total_value) { updateStatistics(); transactionsView->setSortingEnabled(true); } } void TransactionListWidget::onTransactionSplitUp(SplitTransaction *split) { if(split->type() == SPLIT_TRANSACTION_TYPE_MULTIPLE_ACCOUNTS) { for(int i = 0; i < split->count(); i++) { split->at(i)->setParentSplit(NULL); appendFilterTransaction(split->at(i), false); split->at(i)->setParentSplit(split); updateStatistics(); transactionsView->setSortingEnabled(true); } } else { QTreeWidgetItemIterator it(transactionsView); TransactionListViewItem *i = (TransactionListViewItem*) *it; while(i) { if(i->transaction() && i->transaction()->parentSplit() == split) { i->setText(1, i->transaction()->description()); if(!split->associatedFile().isEmpty() && i->transaction()->associatedFile().isEmpty()) i->setIcon(2, QIcon()); if(split->linksCount() > 0 && i->transaction()->linksCount(true) == 0) i->setIcon(comments_col, QIcon()); } ++it; i = (TransactionListViewItem*) *it; } transactionSelectionChanged(); } } void TransactionListWidget::onTransactionAdded(Transactions *trans) { appendFilterTransaction(trans, true); switch(trans->generaltype()) { case GENERAL_TRANSACTION_TYPE_SINGLE: { filterWidget->transactionAdded((Transaction*) trans); editWidget->transactionAdded((Transaction*) trans); break; } case GENERAL_TRANSACTION_TYPE_SCHEDULE: { ScheduledTransaction *strans = (ScheduledTransaction*) trans; if(strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE) { editWidget->transactionAdded((Transaction*) strans->transaction()); filterWidget->transactionAdded((Transaction*) strans->transaction()); } else if(strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { SplitTransaction *split = (SplitTransaction*) strans->transaction(); int n = split->count(); for(int split_i = 0; split_i < n; split_i++) { editWidget->transactionAdded(split->at(split_i)); filterWidget->transactionAdded(split->at(split_i)); } } break; } case GENERAL_TRANSACTION_TYPE_SPLIT: { break; } } } void TransactionListWidget::onTransactionModified(Transactions *transs, Transactions *oldtranss) { switch(transs->generaltype()) { case GENERAL_TRANSACTION_TYPE_SINGLE: { Transaction *trans = (Transaction*) transs; Transaction *oldtrans = (Transaction*) oldtranss; QTreeWidgetItemIterator it(transactionsView); TransactionListViewItem *i = (TransactionListViewItem*) *it; while(i) { if(i->transaction() == trans) { current_value -= oldtrans->value(true); current_quantity -= oldtrans->quantity(); break; } ++it; i = (TransactionListViewItem*) *it; } if(!i) { appendFilterTransaction(trans, true); } else { if(filterWidget->filterTransaction(trans)) { delete i; } else { current_value += trans->value(true); current_quantity += trans->quantity(); i->setDate(trans->date()); i->setText(0, QLocale().toString(trans->date(), QLocale::ShortFormat)); if(trans->parentSplit()) i->setText(1, trans->description() + "*"); else i->setText(1, trans->description()); i->setText(2, right_align_values ? trans->valueString() + " " : transs->valueString()); i->setText(from_col, trans->fromAccount()->name()); i->setText(to_col, trans->toAccount()->name()); if(payee_col >= 0) { if(trans->type() == TRANSACTION_TYPE_EXPENSE) i->setText(payee_col, ((Expense*) trans)->payee()); else if(trans->type() == TRANSACTION_TYPE_INCOME) i->setText(payee_col, ((Income*) trans)->payer()); } if(trans->parentSplit() && trans->comment().isEmpty()) i->setText(comments_col, trans->parentSplit()->comment()); else i->setText(comments_col, trans->comment()); if(tags_col >= 0) i->setText(tags_col, transs->tagsText(true)); if(quantity_col >= 0) i->setText(quantity_col, budget->formatValue(transs->quantity())); if(!trans->associatedFile().isEmpty() || (trans->parentSplit() && !trans->parentSplit()->associatedFile().isEmpty())) i->setIcon(2, LOAD_ICON_STATUS("mail-attachment")); else i->setIcon(2, QIcon()); if(trans->linksCount(true) > 0) i->setIcon(comments_col, LOAD_ICON_STATUS("go-jump")); else i->setIcon(comments_col, QIcon()); } updateStatistics(); } if(oldtrans->description() != trans->description()) filterWidget->transactionModified(trans); editWidget->transactionModified(trans); break; } case GENERAL_TRANSACTION_TYPE_SCHEDULE: { ScheduledTransaction *strans = (ScheduledTransaction*) transs; ScheduledTransaction *oldstrans = (ScheduledTransaction*) oldtranss; QTreeWidgetItemIterator it(transactionsView); TransactionListViewItem *i = (TransactionListViewItem*) *it; while(i) { if(i->scheduledTransaction() == strans) { current_value -= oldstrans->transaction()->value(true); current_quantity -= oldstrans->transaction()->quantity(); QTreeWidgetItem *i_del = i; ++it; i = (TransactionListViewItem*) *it; delete i_del; } else { ++it; i = (TransactionListViewItem*) *it; } } appendFilterTransaction(strans, true); updateStatistics(); if(strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE) { if(oldstrans->transaction()->description() != strans->transaction()->description()) filterWidget->transactionModified((Transaction*) strans->transaction()); editWidget->transactionModified((Transaction*) strans->transaction()); } else if(strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { SplitTransaction *split = (SplitTransaction*) strans->transaction(); bool b_filter = (oldstrans->transaction()->description() != strans->transaction()->description()); int n = split->count(); for(int split_i = 0; split_i < n; split_i++) { editWidget->transactionModified(split->at(split_i)); if(b_filter) filterWidget->transactionModified(split->at(split_i)); } } break; } case GENERAL_TRANSACTION_TYPE_SPLIT: { if(((SplitTransaction*) transs)->type() != SPLIT_TRANSACTION_TYPE_MULTIPLE_ACCOUNTS) { if(((SplitTransaction*) transs)->count() == ((SplitTransaction*) oldtranss)->count()) { for(int i = 0; i < ((SplitTransaction*) transs)->count(); i++) { onTransactionModified(((SplitTransaction*) transs)->at(i), ((SplitTransaction*) oldtranss)->at(i)); } } else { for(int i = 0; i < ((SplitTransaction*) transs)->count(); i++) { onTransactionRemoved(((SplitTransaction*) oldtranss)->at(i)); appendFilterTransaction(((SplitTransaction*) transs)->at(i), true); } } break; } MultiAccountTransaction *split = (MultiAccountTransaction*) transs; MultiAccountTransaction *oldsplit = (MultiAccountTransaction*) oldtranss; QTreeWidgetItemIterator it(transactionsView); TransactionListViewItem *i = (TransactionListViewItem*) *it; while(i) { if(i->splitTransaction() == split) { current_value -= oldsplit->value(true); current_quantity -= oldsplit->quantity(); break; } ++it; i = (TransactionListViewItem*) *it; } if(!i) { appendFilterTransaction(split, true); } else { if(filterWidget->filterTransaction(split)) { delete i; } else { current_value += split->value(true); current_quantity += split->quantity(); i->setDate(split->date()); i->setText(0, QLocale().toString(split->date(), QLocale::ShortFormat)); i->setText(1, split->description() + "*"); i->setText(2, right_align_values ? split->valueString() + " " : split->valueString()); i->setText(3, split->category()->name()); i->setText(4, split->accountsString()); if(payee_col >= 0) i->setText(payee_col, split->payeeText()); i->setText(comments_col, split->comment()); if(tags_col >= 0) i->setText(tags_col, split->tagsText()); if(quantity_col >= 0) i->setText(quantity_col, budget->formatValue(split->quantity())); if(!split->associatedFile().isEmpty()) i->setIcon(2, LOAD_ICON_STATUS("mail-attachment")); else i->setIcon(2, QIcon()); if(split->linksCount() > 0) i->setIcon(comments_col, LOAD_ICON_STATUS("go-jump")); else i->setIcon(comments_col, QIcon()); } updateStatistics(); } break; } } } void TransactionListWidget::onTransactionRemoved(Transactions *transs) { switch(transs->generaltype()) { case GENERAL_TRANSACTION_TYPE_SINGLE: { Transaction *trans = (Transaction*) transs; QTreeWidgetItemIterator it(transactionsView); TransactionListViewItem *i = (TransactionListViewItem*) *it; while(i) { if(i->transaction() == trans) { delete i; current_value -= trans->value(true); current_quantity -= trans->quantity(); updateStatistics(); break; } ++it; i = (TransactionListViewItem*) *it; } editWidget->transactionRemoved(trans); break; } case GENERAL_TRANSACTION_TYPE_SCHEDULE: { ScheduledTransaction *strans = (ScheduledTransaction*) transs; QTreeWidgetItemIterator it(transactionsView); TransactionListViewItem *i = (TransactionListViewItem*) *it; while(i) { if(i->scheduledTransaction() == strans) { current_value -= strans->transaction()->value(true); current_quantity -= strans->transaction()->quantity(); QTreeWidgetItem *i_del = i; ++it; i = (TransactionListViewItem*) *it; delete i_del; } else { ++it; i = (TransactionListViewItem*) *it; } } updateStatistics(); if(strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE) { editWidget->transactionRemoved((Transaction*) strans->transaction()); } else if(strans->transaction()->generaltype() == GENERAL_TRANSACTION_TYPE_SPLIT) { SplitTransaction *split = (SplitTransaction*) strans->transaction(); int n = split->count(); for(int split_i = 0; split_i < n; split_i++) { editWidget->transactionRemoved(split->at(split_i)); } } break; } case GENERAL_TRANSACTION_TYPE_SPLIT: { if(((SplitTransaction*) transs)->type() != SPLIT_TRANSACTION_TYPE_MULTIPLE_ACCOUNTS) break; MultiAccountTransaction *split = (MultiAccountTransaction*) transs; QTreeWidgetItemIterator it(transactionsView); TransactionListViewItem *i = (TransactionListViewItem*) *it; while(i) { if(i->splitTransaction() == split) { delete i; current_value -= split->value(true); current_quantity -= split->quantity(); updateStatistics(); break; } ++it; i = (TransactionListViewItem*) *it; } break; } } } void TransactionListWidget::clearTransaction() { transactionsView->clearSelection(); editInfoLabel->setText(QString()); editWidget->setTransaction(NULL); } void TransactionListWidget::filterTransactions() { expenseColor = QColor(); incomeColor = QColor(); transferColor = QColor(); //QList selection = transactionsView->selectedItems(); selected_trans = NULL; /*if(selection.count() == 1) { TransactionListViewItem *i = (TransactionListViewItem*) selection.first(); if(!i->scheduledTransaction()) { if(i->splitTransaction()) selected_trans = i->splitTransaction(); else selected_trans = i->transaction(); } }*/ transactionsView->clear(); current_value = 0.0; current_quantity = 0.0; switch(transtype) { case TRANSACTION_TYPE_EXPENSE: { for(TransactionList::const_iterator it = budget->expenses.constBegin(); it != budget->expenses.constEnd(); ++it) { Expense *expense = *it; appendFilterTransaction(expense, false); } for(SecurityTransactionList::const_iterator it = budget->securityTransactions.constBegin(); it != budget->securityTransactions.constEnd(); ++it) { SecurityTransaction *sectrans = *it; if(sectrans->account()->type() == ACCOUNT_TYPE_EXPENSES) { appendFilterTransaction(sectrans, false); } } break; } case TRANSACTION_TYPE_INCOME: { for(TransactionList::const_iterator it = budget->incomes.constBegin(); it != budget->incomes.constEnd(); ++it) { Income *income = *it; appendFilterTransaction(income, false); } for(SecurityTransactionList::const_iterator it = budget->securityTransactions.constBegin(); it != budget->securityTransactions.constEnd(); ++it) { SecurityTransaction *sectrans = *it; if(sectrans->account()->type() == ACCOUNT_TYPE_INCOMES) { appendFilterTransaction(sectrans, false); } } break; } default: { for(TransactionList::const_iterator it = budget->transfers.constBegin(); it != budget->transfers.constEnd(); ++it) { Transfer *transfer = *it; appendFilterTransaction(transfer, false); } for(SecurityTransactionList::const_iterator it = budget->securityTransactions.constBegin(); it != budget->securityTransactions.constEnd(); ++it) { SecurityTransaction *sectrans = *it; if(sectrans->account()->type() == ACCOUNT_TYPE_ASSETS) { appendFilterTransaction(sectrans, false); } } break; } } for(ScheduledTransactionList::const_iterator it = budget->scheduledTransactions.constBegin(); it != budget->scheduledTransactions.constEnd(); ++it) { ScheduledTransaction *strans = *it; appendFilterTransaction(strans, false); } for(SplitTransactionList::const_iterator it = budget->splitTransactions.constBegin(); it != budget->splitTransactions.constEnd(); ++it) { SplitTransaction *split = *it; appendFilterTransaction(split, false); } /*selected_trans = NULL; selection = transactionsView->selectedItems(); if(selection.count() == 0) {*/ editInfoLabel->setText(""); //} updateStatistics(); transactionsView->setSortingEnabled(true); } void TransactionListWidget::currentTransactionChanged(QTreeWidgetItem *i) { if(i == NULL) { editWidget->setTransaction(NULL); editInfoLabel->setText(QString()); } else if(((TransactionListViewItem*) i)->scheduledTransaction()) { if(((TransactionListViewItem*) i)->splitTransaction()) { editWidget->setMultiAccountTransaction(((TransactionListViewItem*) i)->splitTransaction(), ((TransactionListViewItem*) i)->date() == ((TransactionListViewItem*) i)->splitTransaction()->date() ? QDate() : ((TransactionListViewItem*) i)->date()); } else { editWidget->setTransaction(((TransactionListViewItem*) i)->transaction(), ((TransactionListViewItem*) i)->date()); } if(((TransactionListViewItem*) i)->scheduledTransaction()->isOneTimeTransaction()) editInfoLabel->setText(QString()); else editInfoLabel->setText(tr("** Recurring (editing occurrence)")); } else if(((TransactionListViewItem*) i)->splitTransaction()) { editWidget->setMultiAccountTransaction(((TransactionListViewItem*) i)->splitTransaction()); editInfoLabel->setText(QString()); } else if(((TransactionListViewItem*) i)->transaction()->parentSplit()) { editWidget->setTransaction(((TransactionListViewItem*) i)->transaction()); SplitTransaction *split = ((TransactionListViewItem*) i)->transaction()->parentSplit(); QFontMetrics fm(editInfoLabel->font()); int tw = fm.boundingRect(tr("* Part of split (%1)").arg(split->description())).width() + 20; if(split->description().isEmpty() || tw > editInfoLabel->width()) editInfoLabel->setText(tr("* Part of split transaction").arg("split transaction")); else editInfoLabel->setText(tr("* Part of split (%1)").arg("" + split->description() + "")); } else { editWidget->setTransaction(((TransactionListViewItem*) i)->transaction()); editInfoLabel->setText(QString()); } } void TransactionListWidget::transactionSelectionChanged() { QList selection = transactionsView->selectedItems(); if(selection.count() == 0) { editInfoLabel->setText(QString()); modifyButton->setEnabled(false); removeButton->setEnabled(false); currentTransactionChanged(NULL); } else { QTreeWidgetItem *i = selection.first(); if(selection.count() > 1) { modifyButton->setText(tr("Modify…")); } else if(((TransactionListViewItem*) i)->splitTransaction() || ((TransactionListViewItem*) i)->transaction()->parentSplit() || ((TransactionListViewItem*) i)->transaction()->type() == TRANSACTION_TYPE_SECURITY_BUY || ((TransactionListViewItem*) i)->transaction()->type() == TRANSACTION_TYPE_SECURITY_SELL || (((TransactionListViewItem*) i)->transaction()->type() == TRANSACTION_TYPE_INCOME && ((Income*) ((TransactionListViewItem*) i)->transaction())->security())) { modifyButton->setText(tr("Edit…")); } else { modifyButton->setText(tr("Apply")); } modifyButton->setEnabled(true); removeButton->setEnabled(true); if(selection.count() > 1) { for(int index = 0; index < selection.size(); index++) { TransactionListViewItem *i = (TransactionListViewItem*) selection.at(index); if(i->transaction() && i->transaction()->subtype() == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND) { modifyButton->setEnabled(false); break; } if(i->scheduledTransaction()) { if(i->transaction() && i->transaction()->parentSplit()) { modifyButton->setEnabled(false); removeButton->setEnabled(false); break; } else if(i->splitTransaction()) { modifyButton->setEnabled(false); } } } } if(transactionsView->currentItem()->isSelected()) { currentTransactionChanged(transactionsView->currentItem()); } else if(selection.count() == 1) { currentTransactionChanged(i); } } updateTransactionActions(); if(transtype == TRANSACTION_TYPE_INCOME || transtype == TRANSACTION_TYPE_EXPENSE) updateStatistics(); } void TransactionListWidget::newMultiAccountTransaction() { if(mainWin->newMultiAccountTransaction(transtype == TRANSACTION_TYPE_EXPENSE, editWidget->description(), transtype == TRANSACTION_TYPE_EXPENSE ? (CategoryAccount*) editWidget->toAccount() : (CategoryAccount*) editWidget->fromAccount(), editWidget->quantity(), editWidget->comments())) { clearTransaction(); } } void TransactionListWidget::newTransactionWithLoan() { if(mainWin->newExpenseWithLoan(editWidget->description(), editWidget->value(), editWidget->quantity(), editWidget->date(), (ExpensesAccount*) editWidget->toAccount(), editWidget->payee(), editWidget->comments())) { clearTransaction(); } } void TransactionListWidget::newRefundRepayment() { QList selection = transactionsView->selectedItems(); if(selection.count() == 1) { TransactionListViewItem *i = (TransactionListViewItem*) selection.first(); if(i->splitTransaction()) { if(i->splitTransaction()->value() > 0.0) mainWin->newRefundRepayment(i->splitTransaction()); } else if((i->transaction()->type() == TRANSACTION_TYPE_EXPENSE && i->transaction()->value() > 0.0) || (i->transaction()->type() == TRANSACTION_TYPE_INCOME && i->transaction()->value() > 0.0 && !((Income*) i->transaction())->security())) { mainWin->newRefundRepayment(i->transaction()); } } } void TransactionListWidget::updateTransactionActions() { QList selection = transactionsView->selectedItems(); bool b_transaction = false, b_scheduledtransaction = false, b_split = false, b_split2 = false, b_join = false, b_delete = false, b_attachment = false, b_select = false, b_time = false, b_tags = false, b_clone = false, b_link = false, b_link_to = false, b_edit = true; bool refundable = false, repayable = false; QList list; Transactions *link_trans = mainWin->getLinkTransaction(); SplitTransaction *link_parent = NULL; if(link_trans && link_trans->generaltype() == GENERAL_TRANSACTION_TYPE_SINGLE) link_parent = ((Transaction*) link_trans)->parentSplit(); if(selection.count() == 1) { TransactionListViewItem *i = (TransactionListViewItem*) selection.first(); b_scheduledtransaction = i->scheduledTransaction() && i->scheduledTransaction()->recurrence(); b_split = !b_scheduledtransaction && (i->transaction() && i->transaction()->parentSplit()); b_split2 = i->splitTransaction(); b_transaction = !b_scheduledtransaction || !i->scheduledTransaction()->isOneTimeTransaction(); b_link = !i->scheduledTransaction() || i->scheduledTransaction()->isOneTimeTransaction(); b_link_to = link_trans && b_link && i->transaction() != link_trans && i->splitTransaction() != link_trans && (!b_split || (i->transaction()->parentSplit() != link_trans && i->transaction()->parentSplit() != link_parent)); b_time = !i->scheduledTransaction(); b_delete = b_transaction; refundable = (i->splitTransaction() || (i->transaction()->type() == TRANSACTION_TYPE_EXPENSE && i->transaction()->value() > 0.0)); repayable = (i->splitTransaction() || (i->transaction()->type() == TRANSACTION_TYPE_INCOME && i->transaction()->value() > 0.0 && !((Income*) i->transaction())->security())); if(i->splitTransaction()) { list << i->splitTransaction(); b_attachment = !i->splitTransaction()->associatedFile().isEmpty(); } else { if(b_split) { b_attachment = !i->transaction()->parentSplit()->associatedFile().isEmpty(); } if(!b_attachment && i->transaction()) { b_attachment = !i->transaction()->associatedFile().isEmpty(); } list << i->transaction(); } b_clone = true; b_select = true; mainWin->updateLinksAction(list[0], !b_scheduledtransaction || i->scheduledTransaction()->isOneTimeTransaction()); } else if(selection.count() > 1) { b_transaction = true; b_delete = true; b_join = true; b_split = true; b_time = true; b_link = true; b_link_to = (link_trans != NULL); SplitTransaction *split = NULL; TransactionListViewItem *i = (TransactionListViewItem*) selection.first(); if(i->transaction() && i->transaction()->parentSplit() && selection.size() < i->transaction()->parentSplit()->count()) { split = i->transaction()->parentSplit(); b_link = false; for(int index = 1; index < selection.size(); index++) { i = (TransactionListViewItem*) selection.at(index); if(!i->transaction() || i->transaction()->parentSplit() != split) { b_link = true; break; } } split = NULL; } for(int index = 0; index < selection.size(); index++) { if(index >= 10) b_link = false; i = (TransactionListViewItem*) selection.at(index); if((b_edit || b_join) && i->transaction() && i->transaction()->subtype() == TRANSACTION_SUBTYPE_REINVESTED_DIVIDEND) { b_join = false; b_edit = false; } if(b_join && (i->splitTransaction() || i->scheduledTransaction() || i->transaction()->parentSplit())) { b_join = false; } if(i->scheduledTransaction()) { if((b_link || b_link_to) && !i->scheduledTransaction()->isOneTimeTransaction()) { b_link = false; b_link_to = false; } b_time = false; } if(b_transaction && i->scheduledTransaction() && (i->splitTransaction() || (i->transaction() && i->transaction()->parentSplit()))) { b_transaction = false; if(!i->splitTransaction()) b_delete = false; } Transaction *trans = i->transaction(); if(b_link_to && i->transaction() != link_trans && i->splitTransaction() != link_trans && trans && trans->parentSplit() && (trans->parentSplit() == link_trans || trans->parentSplit() == link_parent)) b_link_to = false; if(b_split) { if(!trans) { b_split = false; } else { if(!split) split = trans->parentSplit(); if(!trans->parentSplit() || trans->parentSplit() != split) { b_split = false; } } } if(!b_split && !b_join && !b_transaction && !b_delete) break; if(i->splitTransaction()) list << i->splitTransaction(); else if(i->transaction()) list << i->transaction(); } b_select = b_split && split; b_attachment = b_select && !split->associatedFile().isEmpty(); mainWin->updateLinksAction(NULL); } else { mainWin->updateLinksAction(NULL); } b_tags = b_transaction; if(b_tags) { mainWin->tagMenu->setTransactions(list); mainWin->ActionTags->setText(tr("Tags") + QString(" (") + QString::number(mainWin->tagMenu->selectedTagsCount()) + ")"); } if(b_link && list.count() >= 2) { b_link = false; for(int i = 0; i < list.count() - 1; i++) { for(int i2 = i + 1; i2 < list.count(); i2++) { if(!list.at(i)->hasLink(list.at(i2), true)) { b_link = true; break; } } } } if(b_link_to && list.count() >= 1) { b_link_to = false; for(int i = 0; i < list.count(); i++) { if(!list.at(i)->hasLink(link_trans, true)) { b_link_to = true; break; } } } if(!b_transaction) b_edit = false; mainWin->ActionCreateLink->setEnabled(b_link); mainWin->ActionLinkTo->setEnabled(b_link_to); mainWin->ActionNewRefund->setEnabled(refundable); mainWin->ActionNewRepayment->setEnabled(repayable); mainWin->ActionNewRefundRepayment->setEnabled(refundable || repayable); mainWin->ActionEditTransaction->setEnabled(b_edit); mainWin->ActionEditTimestamp->setEnabled(b_time); mainWin->ActionDeleteTransaction->setEnabled(b_transaction); mainWin->ActionSelectAssociatedFile->setEnabled(b_select); mainWin->ActionOpenAssociatedFile->setEnabled(b_attachment); mainWin->ActionEditScheduledTransaction->setEnabled(b_scheduledtransaction); mainWin->ActionDeleteScheduledTransaction->setEnabled(b_scheduledtransaction); mainWin->ActionEditSplitTransaction->setEnabled(b_split); mainWin->ActionDeleteSplitTransaction->setEnabled(b_split); mainWin->ActionJoinTransactions->setEnabled(b_join); mainWin->ActionSplitUpTransaction->setEnabled(b_split || b_split2); mainWin->ActionCloneTransaction->setEnabled(b_clone); if(b_tags) { mainWin->ActionTags->setEnabled(true); } else { mainWin->ActionTags->setText(tr("Tags")); mainWin->ActionTags->setEnabled(false); } } void TransactionListWidget::filterToActivated(Account *acc) { if(acc && (acc->type() != ACCOUNT_TYPE_ASSETS || (acc != budget->balancingAccount && ((AssetsAccount*) acc)->accountType() != ASSETS_TYPE_SECURITIES && !((AssetsAccount*) acc)->isClosed()))) editWidget->setToAccount(acc); } void TransactionListWidget::filterFromActivated(Account *acc) { if(acc && (acc->type() != ACCOUNT_TYPE_ASSETS || (acc != budget->balancingAccount && ((AssetsAccount*) acc)->accountType() != ASSETS_TYPE_SECURITIES && !((AssetsAccount*) acc)->isClosed()))) editWidget->setFromAccount(acc); } void TransactionListWidget::onDisplay() { if(tabs->currentWidget() == editWidget) editWidget->focusFirst(); } void TransactionListWidget::updateFromAccounts() { editWidget->updateFromAccounts(); filterWidget->updateFromAccounts(); } void TransactionListWidget::updateToAccounts() { editWidget->updateToAccounts(); filterWidget->updateToAccounts(); } void TransactionListWidget::updateAccounts() { editWidget->updateAccounts(); filterWidget->updateAccounts(); } void TransactionListWidget::setDefaultAccounts() { editWidget->setDefaultAccounts(); } void TransactionListWidget::showFilter(bool focus_description) { tabs->setCurrentWidget(filterWidget); if(focus_description) filterWidget->focusFirst(); } void TransactionListWidget::showEdit() {tabs->setCurrentWidget(editWidget);} void TransactionListWidget::setFilter(QDate fromdate, QDate todate, double min, double max, Account *from_account, Account *to_account, QString description, QString tag, bool exclude, bool exact_match) { filterWidget->setFilter(fromdate, todate, min, max, from_account, to_account, description, tag, exclude, exact_match); } void TransactionListWidget::currentTabChanged(int index) { if(index == 0) editWidget->focusFirst(); else if(index == 1) filterWidget->focusFirst(); } TransactionListViewItem::TransactionListViewItem(const QDate &trans_date, Transaction *trans, ScheduledTransaction *strans, MultiAccountTransaction *split, QString s1, QString s2, QString s3, QString s4, QString s5, QString s6, QString s7, QString s8) : QTreeWidgetItem(), o_trans(trans), o_strans(strans), o_split(split), d_date(trans_date) { setText(0, s1); setText(1, s2); setText(2, s3); setText(3, s4); setText(4, s5); setText(5, s6); setText(6, s7); setText(7, s8); } bool TransactionListViewItem::operator<(const QTreeWidgetItem &i_pre) const { int col = 0; if(treeWidget()) col = treeWidget()->sortColumn(); TransactionListViewItem *i = (TransactionListViewItem*) &i_pre; Transactions *t1 = o_split; if(!t1) t1 = o_trans; Transactions *t2 = i->splitTransaction(); if(!t2) t2 = i->transaction(); if(treeWidget() && col == treeWidget()->columnCount() - 1) { if(t1->timestamp() < t2->timestamp()) return true; if(t1->timestamp() > t2->timestamp()) return false; col = 0; } if(col == 0) { if(d_date < i->date()) return true; if(d_date > i->date()) return false; if((o_strans == NULL) != (i->scheduledTransaction() == NULL)) return o_strans == NULL; if(t1->timestamp() < t2->timestamp()) return true; if(t1->timestamp() > t2->timestamp()) return false; } else if(col == 2) { double d1 = t1->value(true), d2 = t2->value(true); if(d1 < d2) return true; if(d1 > d2) return false; } return QTreeWidgetItem::operator<(i_pre); } Transaction *TransactionListViewItem::transaction() const { return o_trans; } ScheduledTransaction *TransactionListViewItem::scheduledTransaction() const { return o_strans; } MultiAccountTransaction *TransactionListViewItem::splitTransaction() const { return o_split; } const QDate &TransactionListViewItem::date() const { return d_date; } void TransactionListViewItem::setDate(const QDate &newdate) { d_date = newdate; } Eqonomize-1.5.3/src/transactionlistwidget.h000066400000000000000000000123011416454732000210560ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2006-2008, 2014, 2016-2020 by Hanna Knutsson * * hanna.knutsson@protonmail.com * * * * This file is part of Eqonomize!. * * * * Eqonomize! 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. * * * * Eqonomize! 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 Eqonomize!. If not, see . * ***************************************************************************/ #ifndef TRANSACTION_LIST_WIDGET_H #define TRANSACTION_LIST_WIDGET_H #include #include #include #include #include class QLabel; class QMenu; class QPushButton; class QTabWidget; class QTreeWidget; class QTreeWidgetItem; class Account; class Budget; class Eqonomize; class ScheduledTransaction; class SplitTransaction; class Transaction; class Transactions; class TransactionEditWidget; class TransactionFilterWidget; class TransactionListWidget : public QWidget { Q_OBJECT public: TransactionListWidget(bool extra_parameters, int transaction_type, Budget *budg, Eqonomize *main_win, QWidget *parent = 0); void useMultipleCurrencies(bool b); void transactionsReset(); void updateFromAccounts(); void updateToAccounts(); void updateAccounts(); void onDisplay(); void appendFilterTransaction(Transactions*, bool, ScheduledTransaction* = NULL); void setDefaultAccounts(); QSize minimumSizeHint() const; QSize sizeHint() const; void setFilter(QDate fromdate, QDate todate, double min = -1.0, double max = -1.0, Account *from_account = NULL, Account *to_account = NULL, QString description = QString(), QString tag = QString(), bool exclude = false, bool exact_match = false); bool exportList(QTextStream &outf, int fileformat); bool isEmpty(); void currentDateChanged(const QDate &olddate, const QDate &newdate); QByteArray saveState(); void restoreState(const QByteArray&); void createLink(bool link_to); protected: int transtype; int from_col, to_col, comments_col, tags_col, payee_col, quantity_col; bool right_align_values; Budget *budget; Eqonomize *mainWin; bool b_extra; QTabWidget *tabs; QTreeWidget *transactionsView; QLabel *statLabel; QPushButton *addButton, *modifyButton, *removeButton, *clearButton; QMenu *listPopupMenu, *headerPopupMenu; TransactionFilterWidget *filterWidget; TransactionEditWidget *editWidget; QLabel *editInfoLabel; double current_value, current_quantity; Transactions *selected_trans; QColor expenseColor, incomeColor, transferColor; QAction *ActionSortByCreationTime, *ActionRightAlignValues, *SeparatorRightAlignValues; QKeyEvent *key_event; void keyPressEvent(QKeyEvent*); signals: void accountAdded(Account*); void currenciesModified(); void valueAlignmentUpdated(bool); void tagAdded(QString); public slots: void selectAssociatedFile(); void openAssociatedFile(); void editClear(); void updateStatistics(); void updateTransactionActions(); void editTimestamp(); void editTransaction(); void newMultiAccountTransaction(); void newTransactionWithLoan(); void newRefundRepayment(); void cloneTransaction(); void editScheduledTransaction(); void editSplitTransaction(); void splitUpTransaction(); void joinTransactions(); void modifyTags(); void onTransactionSplitUp(SplitTransaction*); void onTransactionAdded(Transactions*); void onTransactionModified(Transactions*, Transactions*); void onTransactionRemoved(Transactions*); void filterTransactions(); void currentTransactionChanged(QTreeWidgetItem*); void transactionSelectionChanged(); void filterToActivated(Account*); void filterFromActivated(Account*); void addTransaction(); void modifyTransaction(); void removeTransaction(); void clearTransaction(); void removeSplitTransaction(); void removeScheduledTransaction(); void addModifyTransaction(); void popupHeaderMenu(const QPoint&); void popupListMenu(const QPoint&); void sortByCreationTime(bool = true); void rightAlignValues(bool = true); void showFilter(bool focus_description = false); void showEdit(); void transactionExecuted(QTreeWidgetItem*); void currentTabChanged(int); void updateClearButton(); void tagsModified(); void hideColumn(bool); }; #endif Eqonomize-1.5.3/translations.qrc000066400000000000000000000012731416454732000167270ustar00rootroot00000000000000 translations/eqonomize_bg.qm translations/eqonomize_cs.qm translations/eqonomize_da.qm translations/eqonomize_de.qm translations/eqonomize_es.qm translations/eqonomize_fr.qm translations/eqonomize_hu.qm translations/eqonomize_it.qm translations/eqonomize_nl.qm translations/eqonomize_pt.qm translations/eqonomize_pt_BR.qm translations/eqonomize_ro.qm translations/eqonomize_ru.qm translations/eqonomize_sk.qm translations/eqonomize_sv.qm Eqonomize-1.5.3/translations/000077500000000000000000000000001416454732000162155ustar00rootroot00000000000000Eqonomize-1.5.3/translations/eqonomize_bg.ts000066400000000000000000020766211416454732000212610ustar00rootroot00000000000000 Balancing балансиране Couldn't open %1 for reading Не може да се отвори %1 за четене Not a valid Eqonomize! file (XML parse error: "%2" at line %3, col %4) Невалиден Eqonomize! файл (XML синтактична грешка: "%2" ред %3, колона %4) Invalid root element %1 in XML document Невалиден основен елемент %1 в XML документ Unable to load 1 account. Не може да се зареди %n сметка Не може да се заредят %n сметки Unable to load 1 category. Не може да се зареди 1 група Не може да се заредят %n групи Unable to load 1 security. Не може да се зареди 1 ценна книга Не може да се заредят %n ценни книжа Unable to load 1 transaction. Не може да се зареди 1 транзакция Не може да се заредят %n транзакции File is a directory Файлът е папка Couldn't open file for writing Не мога да отворя файл за писане Error while writing file; file was not saved Грешка при запис на файл; файлът не е бил запазен From От To До Source: Източник: All Expenses Всички разходи All Incomes Всички приходи All Accounts Всички сметки Expenses: %1 Разходи: %1 Incomes: %1 Приходи: %1 Invalid date. Грешна дата. To date is before from date. Към настоящия момент е преди считано от датата. From date is after to date. Към настоящия момент е след датата. The selected file already exists. Would you like to overwrite the old copy? Избраният файл вече съществува. Бихте ли искали да го замените с по-стар? You selected a directory! Избрали сте директория! Couldn't open file for writing. Не мога да отворя файла за писане. Error while writing file; file was not saved. Грешка при запис на файл; файлът не е запазен. No description Няма описание All Categories Всички категории Descriptions for Описания за Payees/payers for Получатели на плащане / платци за Period: Период: Columns: Колони: Value Стойност Daily ежедневно Monthly Месечно Yearly Годишно Quantity Количество Average value Средна стойност All descriptions Всички описания All payees Всички получатели на пари All payers Всички платци No payee Няма получател на пари No payer Няма платец Expenses: %2, %1 Разходи: %2, %1 Incomes: %2, %1 Приходи: %2, %1 Incomes & Expenses Приходи & Разходи %1 (%2&ndash;%3) html format; %1: title; %2: from date; %3: to date %1 (%2&ndash;%3) %1 (to %2) html format; %1: title; %2: to date %1 (до %2) Category Категория Cost Цена Income Приход Daily Average Средно Дневно Monthly Average Средно на месец Yearly Average Средно годишно Average Cost Средна цена Average Income Среден доход Average Value Средна стойност Total Общо Total incomes Общо приходи Total expenses Общо разходи Total (Profits) Общо (печалбите) Expense Разход Transfer Прехвърляне Security Buy Покупка споръчител Security Sell Продажба с поръчител Recurrence Повторение New Expense Нов разход New Dividend Нов дивидент New Income Нов приход New Transfer Нов трансфер New Security Buy Нова покупка с поръчител New Security Sell Нова продажба с поръчител Edit Expense Редактиране на разходи Edit Dividend Редактиране на дивиденти Edit Income Редактиране на приходи Edit Transfer Редактиране на трансфери Edit Securities Bought Редактиране на покупка на ценни книжа Edit Securities Sold Редактиране на продажба на ценни книжа Dividend Дивиденти Repayment Върната сума Refund Обезщетение Split Transaction Разделяне на транзакциите Description: Описание: Date: Дата: Account: Сметка: Transactions: Транзакции: Type Вид Description Описание Account/Category Сметка/Категория Payment Плащане Deposit Депозит/внос New Нов New Expense… Нов разход … New Income… Нов приход… New Deposit… Нова вноска… New Withdrawal… Ново теглене … New Security Shares Bought… Покупка на нови ценни книжа и акции Security Shares Sold… Продажба на акции… New Dividend… Нов дивидент… Edit… Редактиране… Total value: Обща стойност: No suitable account available. Няма подходяща сметка на разположение. Future dates is not allowed. Бъдещи дати не са позволени. A split must contain at least two transactions. Разделянето трябва да съдържа най-малко две транзакции. Cannot transfer money to and from the same account. Не можете да прехвърляте пари от една и съща сметка. Cost: Разходи: Income: Приход: Quantity: Количество: Comments: Коментари: Reinvested Dividend Реинвестирани дивиденти Security: Ценна книга: Shares added: Добавяне на акции: Security Trade Сигурност на търговията From security: От ценна книга: Shares moved: Преместни акции: All Всичко To security: На ценна книга: Shares received: Получени акции: Value: Стойност: No other security available for trade in the account. Няма друга защита за търговия по сметката. Selected to and from securities are the same. Избраните и тези ценни книжа са едни и същи. Zero shares not allowed. Нулеви акции не са разрешени. Zero value not allowed. Нулева стойност, не се допуска. Quotations Оферти Date Дата Price per Share Цена на акция Quotations for %1 Котировки на %1 The following transactions was scheduled to occur today or before today. Confirm that they have indeed occurred (or will occur today). Следните транзакции бе насрочено да се състоят днес или вчера. Уверете се, че те наистина са се случили (или ще се появят днес). Amount Сума Postpone… Отлагане… Can only postpone to future dates. Може само да се отложи за бъдещи дати. Transactions for %1 Транзакции за %1 Shares Акции Shares Bought Изкупени акции Shares Sold Изкупени акции Shares Sold (Traded) Акции Продадени (търгувани) Shares Bought (Traded) Изкупени акции (търгувани) Shares Bought (Recurring) Изкупени акции (повтарящи се) Shares Sold (Recurring) Акции Продадени (повтарящи се) Shares Bought (Scheduled) Изкупени акции (по график) Shares Sold (Scheduled) Акции Продадени (по график) Recurring Dividend Повтарящи се дивиденти Scheduled Dividend Планирани дивиденти Type: Вид: Mutual Fund Взаимен фонд Bond Облигация Stock Наличност Other Друг Name: Име: Decimals in Shares: Десетични в акции: Initial Shares: Първоначални акции: Initial quotation: Първоначален оферта: No suitable account or income category available. Няма свободна подходяща сметка или категория доходи. Cash Пари в брой Current Account Текуща сметка Savings Account Спестовна сметка Credit Card Кредитна карта Liabilities Задължения Securities Ценни книжа Initial balance: Начален баланс: Default account for budgeted transactions Основна сметка за бюджетни транзакции Empty name. Празно име. The entered name is used by another account. Въведеното име се използва от друга сметка. Monthly budget: Месечен бюджет: The entered name is used by another income category. Въведеното име се използва от друга категория доходи. The entered name is used by another expense category. Въведеното име се използва от друга категория сметки. Accounts Сметки Accounts & Categories Сметки и категории Expenses Разходи Incomes Приходи Transfers Трансфери Schedule График Scheduled Transactions Планирани Транзакции Account / Category Сметка / Категория Remaining Budget (%1) Оставащ бюджет (%1) Change (%1) Смени (%1) Total (%1) Общо (%1) %2 of %1 %2 remains of %1 budget %2 от %1 Includes budgeted transactions Включва бюджетни транзакции Period Период Select Period Избор на период Current Month Текущ месец Current Year Текуща година Current Whole Month Целият текущ месец Current Whole Year Цялата текуща година Whole Past Month Целият изминал месец Whole Past Year Цялата изминала година Previous Month Предходния месец Previous Year Предходната година Show partial budget Покажи частично бюджета Edit Budget Редактиране на бюджета Budget: Бюджет: Month: Месец: Result previous month: Резултат за предходния месец: New Security… Нов поръчител… New Transaction Нова транзакция Set Quotation… Задаване оферта … Name Име Quotation Оферта Profit Печалба Yearly Rate Годишен темп Account Сметка Statistics Period Статистически период New Schedule Нов график Edit Редактиране Next Occurrence Следващо появяване Comments Коментари New Security Нов поръчител Edit Security Редактирай поръчителя Profit: Печалба: Rate: Оценка: Are you sure you want to delete the security "%1" and all associated transactions? Сигурен ли сте, че искате да изтриете поръчител "%1" и всички свързани сделки? No security available. Няма свободен поръчител Set Quotation (%1) Направи оферта (%1) Price per share: Цена за една акция: Future dates are not allowed. Бъдещи дати не са позволени. Security Transactions Сделки с ценни книжа Ledger Главна счетоводна книга Untitled Неозаглавен Check Account Проверка на сметка Salary Заплата Bills Сметки Clothing Облекло Groceries Хранителни Leisure Свободно време Couldn't fetch %1. Не можа да бъде извлечен %1. Error loading %1: %2. Грешка при зареждане на %1: %2. Couldn't open file Не мога да отворя файл Error saving %1: %2. грешка при запазване %1: %2. Couldn't save file Файлът не може да се запази Failed to upload file to %1. Неуспешно качване на файл в %1. Report Отчет Chart Диаграма Transaction Schedule График на транзакциите Accounts &amp; Categories html format Сметки &amp; Категории Accounts &amp; Categories (%1&ndash;%2) html format Сметки &amp; Категории (%1&ndash;%2) Accounts &amp; Categories (to %1) html format Сметки &amp; Категории (to %1) Change Промяна Balance Баланс Budget Бюджет Remaining Budget Оставащ бюджет Total Incomes Общо приходи Costs Разходи Total Expenses Общо разходи Empty expenses list. Празен списък с разходи. Empty incomes list. Празен списък с приходи. Empty transfers list. Празен списък с трансфери. Empty securities list. Празен списък с поръчители. Empty schedule list. Празен списък с графици. Export View… Преглед на износа … Print View… Покажи страницата за печат… Initial Period Първоначален период Remember Last Dates Запомни последните дати Import CSV File… Импортиране CSV файла … Import QIF File… Импортиране QIF файла … Export As QIF File… Износ като файл QIF … Add Account… Добави сметка New Account… Нова сметка New Income Category… Нова категория доходи … New Expense Category… Нова категория разходи… Balance… Баланс… Show Transactions Покажи транзакцията New Transfer… Нов трансфер… New Split Transaction… Ново разделяне на на транзакция … Edit Transaction(s) (Occurrence)… Редактиране на транзакцията(ите) (в действителност) … Edit Occurrence… Редактирай събитието… Edit Schedule (Recurrence)… Редактирай графика (повторяемост) … Edit Schedule… Редактирай графика Remove Transaction(s) (Occurrence) Премахване на транзакцията (е) (събитие) Remove Occurrence Премахни събитието Delete Schedule (Recurrence) Изтриване на график (Повторение) Delete Schedule Изтриване на график Edit Split Transaction… Редактиране на разделянето на транзакциите… Remove Split Transaction Премахни разделянето на транзакциите… Join Transactions… Присъединете се към транзакциите… Split Up Transaction Разделяне на транзакциите Refund… Възстановяване… Repayment… Изплащане… New Refund/Repayment… Ново Възстановяване/Изплащане Edit Security… Редактиране на поръчител… Remove Security Премахни поръчител Shares Sold… Продадени акции … Shares Bought… Изкупени акции… Dividend… Дивиденти… Reinvested Dividend… Реинвестирани дивиденти… Shares Moved… Преместени акции… Edit Quotations… Редактиране на офертите… Transactions… Транзакции… Development Over Time Report… Разработка през време на доклада… Categories Comparison Report… Доклад за сравнение на категориите… Categories Comparison Chart… Диаграма за сравнение на категориите… Development Over Time Chart… Развитие на графиката с времето… Use Additional Transaction Properties Използвайте допълнителни свойства по сделката Eqonomize! exited unexpectedly before the file was saved and data was lost. Do you want to load the last auto-saved version of the file? Eqonomize! завърши неочаквано преди файлът е бъде запазен и данните бяха изгубени. Искате ли да заредите последната автоматично записана версия на файла? Crash Recovery Възстановяване след срив The current file has been modified. Do you want to save it? Текущия файл е бил променен. Искате ли да го запазите? Confirm Schedule Потвърдете списъка New Account Нова сметка New Income Category Нова категория доходи New Expense Category Нова категория разходи Balance Account Баланс на сметката Book value: Счетоводна стойност: Real value: Реална стойност: Edit Account Редактиране на сметка Edit Income Category Редактиране на категория доходи Edit Expense Category Редактиране на категория разходи Move transactions? Преместване на транзакцията? Move to: Преместване в: The category contains some expenses. What do you want to do with them? Категорията съдържа някои разходи. Какво желаете да правя с тях? The category contains some incomes. What do you want to do with them? Категорията съдържа някои доходи. Какво желаете да правя с тях? The account contains some transactions. What do you want to do with them? Сметката съдържа някои транзакции. Какво желаете да правя с тях? The category contains some expenses that will be removed. Do you still want to remove the category? Категорията съдържа някои разходи, които ще бъдат премахнати. Все още ли искате да премахнете категорията? Remove Category? Премахване на категорията? The category contains some incomes that will be removed. Do you still want to remove the category? Категория съдържа някои доходи, които ще бъдат премахнати. Все още ли искате да премахнете категорията? The account contains some transactions that will be removed. Do you still want to remove the account? Сметката съдържа някои транзакции, които ще бъдат премахнати. Все още ли искате да премахнете сметката? Remove Account? Премахване на сметката? %2 of %1 %1: budget; %2: remaining budget %2 от %1 %1 (with no budget) %1 (извън бюджета) %1 (with budget %2) %1 (с никакъв бюджет %2) Import CSV file Въведи CSV файла Transaction Type Selection Избор на тип на транзакцията Expenses and incomes (negative cost) Разходи и приходи (отрицателен разход) Expenses and incomes (separate columns) Разходи и приходи (отделни колони) All types Всички типове File Selection Избор на файл File: Файл: First data row: Първият ред данни: Auto Автоматично Column delimiter: Колона разделител: Comma Запетая Tabulator Табулатор Semicolon Точка и запетая Space Интервал Columns Specification Колони спецификации Column Колона Category: Категория: From account: От сметката: Create missing categories and accounts Създай липсващи категории и сметки Imports data as expenses. Costs have positive value. Value is the only required column. Въведи данните като разходи. Разходите трябва да са положителна стойност. Стойността е единственото, за което трябва колона. Imports data as incomes. Value is the only required column. Въведи данните като доходи.Стойността е единственото, за което трябва колона. To account: В сметката: Imports data as transfers. Value is the only required column. Въведи данните като трансфери.Стойността е единственото, за което трябва колона. Amount: Сума: Imports data as expenses and incomes. Costs have negative value. Value and category are both required columns. Въведи данните като доходи и разходи. Разходите трябва да са отрицателна стойност. Стойността и категориите, изискват колона. Imports data as expenses and incomes. Costs and incomes have separate columns. Income, cost, and category are all required columns. Въведи данните като доходи и разходи.Разходи и приходи са с отделни колони. Доходи, разходи и категории са с всички необходими колони. Imports data as expenses, incomes, and transfers. Costs have negative or positive value. Value, to, and from are all required columns. Accounts and categories must be existing. Въведи данните като разходи, приходи и трансфери.Разходите трябва да са с отрицателна или положителна стойност.Стойността, до,и от,са необходими колони. Сметки и категории трябва да съществуват. From: От: To: До: A file must be selected. Файлът трябва да бъде избран. Selected file is a directory. Избраният файл е директория. Selected file does not exist. Избраният файл не съществува. Empty delimiter. Празен разделител. The same column number is selected multiple times. Един и същ номер на колона е избран няколко пъти. Selected from account is the same as the to account. Избраното от сметката е същото като осчетоводеното. Couldn't open %1 for reading. Не мога да отворя %1 за четене. Error reading %1. Грешка при четенето на %1. Successfully imported 1 transaction. Успешно въведени 1 транзакция. Успешно въведени %n транзакции. Unable to import any transactions imported. Не може да се въвеждат никакви, внесени транзакции. Failed to import 1 data row. Неуспешно въвеждане на 1 ред с данни. Неуспешно въвеждане на %n редове с данни. Required columns missing. Задължителните колони липсват. Invalid value. Невалидна стойност. Empty category name. Празно име на категорията. Empty account name. Празно име на сметката. Unknown category found. Неизвестна категория намерена. Unknown account found. Неизвестна сметка намерена. Cannot import security transactions (to/from security accounts). Не могат да бъдат внесени сделки с ценни книжа (до / от сметките за сигурност). Balancing account wrongly used. Балансирането на сметката е използвано погрешно. Same to and from account/category. Същото към и от сметката / категория. No data found. Няма намерени данни. Unrecognized date format. Неразпознат формат за дата. Specify Format Определете Format The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. Форматът на дати и / или цифри в CSV файла е двусмислен. Моля, изберете правилния формат. Date format: Формат на датата: Value format: Стойност на формата: tomorrow the day after today утре today this day днес yesterday the day before today вчера &Today @option today &Днес To&morrow @option tomorrow У&тре Next &Week @option next week Следващата &седмица Next M&onth @option next month Следващия &месец No Date @option do not specify a date Липсва дата Export… Изнасяне… Print… Отпечатай… Withdrawal Изтегляне Join… Присъединете се към… Split Up Разделяне на Empty transaction list. Празен списък транзакции. Are you sure you want to delete all (%1) selected transactions? Сигурен ли сте, че искате да изтриете всички (%1), избрани транзакции? Cannot set the value of security transactions using the dialog for modifying multiple transactions. Не може да се зададе стойност на сделки с ценни книжа, използвайки диалогов прозорец за промяна на много транзакции. Cannot change description of dividends and security transactions. Не може да се промени описанието на дивидентите и сделките с ценни книжа. Cannot change payer of dividends and security transactions. Не може да се промени платецът на дивидентите и сделки с ценни книжа. Cannot change date of transactions that are part of a split transaction. Не може да се промени датата на сделките, които са част от разделянето на транзакцията. Eqonomize! Eqonomize! A personal accounting program Лична счетоводна програма Start with expenses list displayed Започнете със списъка на разходите показан на екрана Start with incomes list displayed Започнете със списъка на доходите показан на екрана Start with transfers list displayed Започнете със списъка на трансферите показан на екрана Document to open Отваряне на документ Incomes and Expenses Доходи и Разходи Profits Печалби All Categories Combined Всички категории комбинирани All Descriptions Combined Всички описания комбинирани All Payees/Payers Combined Всички получатели/платци комбинирано Start date: Начална дата: End date: Крайна дата: Monthly total Месечно общо Daily average Средно дневно All Payers Combined Всички платци комбинирано All Payees Combined Всички получатели комбинирано All Descriptions Split Разделяне на всички описания All Payers Split Разделяне на всички платци All Payees Split Разделяне на всички получатели All Categories Split Разделяне на всички категории Value (%1) Стойност (%1) Profit (%1) Печалба (%1) Income (%1) Доходи (%1) Cost (%1) Разход (%1) Time Време no payer никакъв платец %1/%2 %1: Description; %2: Payer %1/%2 no payee няма получател %1/%2 %1: Description; %2: Payee %1/%2 Error after saving file; data may not have been saved. Грешка след записване на файла; като данните не може да бъдат спасени. Average Profit Средна печалба Year Година Month Месец Includes scheduled transactions Включва планираните транзакции Adjusted for the average month / year (%1 / %2 days) Коригирано за средно месечно / годишно (%1 / %2 дни) Subtotal Междинна сума Unnamed Без име Uncategorized Некатегоризиран Import QIF file Въведи QIF файла Select a QIF file to import. When you click next, the file be analysed and you might need to answer some questions about the format of the file. Изберете QIF файла, за въвеждане. Когато натиснете Напред, файлът ще бъде анализиран и може да се наложи да отговорите на няколко въпроса за формата на файла. Local Definitions Местни определения Unknown elements where found in the QIF file. It is possible that this is because of localized type names. Please map them to the correct standard names. Неизвестни елементи, които са установени в QIF файла. Възможно е, че това е така, защото са локализирани типови имена. Моля, да ги съпоставите с правилните стандартни имена. Local Text Локален текст Standard Text Стандартен текст Select standard text: Избери стандартен техт: Date Format Формат на датата The date format in the QIF file is ambiguous. Please select the correct format. Форматът на датата във файла QIF е двусмислен. Моля, изберете правилния формат. Default Account Сметка по подразбиране Could not find any account definitions in the QIF file. Please select a default account. It is also possible that this is caused by a localized opening balance text. Не можаха да бъдат намерени определения за сметката в QIF файла. Моля, изберете акаунта по подразбиране. Възможно е също така, това да е причинено от локален текст за началното салдо. Default account: Сметка по подразбиране: Opening balance text: Начален баланс: Descriptions Описание Transactions in QIF files does not have any specific description property. You are therefore given the option to choose how the description of imported transactions will be set. Транзакциите във файловете QIF не разполагат с конкретни описание на собствеността. Ето защо това ви дава възможност да изберете как ще бъде създадено описанието на въведените транзакции. Subcategories as: Подкатегории като: Ignore игнорирай Payee as: Получателя на плащането като: Payee Получател Memo as: Отбележи като: Priority: Приоритет: Subcategory/Payee/Comments Подкатегория /Бенефициент/Коментари Payee/Subcategory/Comments Бенефициент/Подкатегория /Коментари Subcategory/Comments/Payee Подкатегория/Коментари /Бенефициент Payee/Comments/Subcategory Бенефициент/Коментари /Подкатегория Comments/Subcategory/Payee Коментари /Подкатегория/Бенефициент Comments/Payee/Subcategory Коментари /Бенефициент/Подкатегория Unknown Неизвестен Bank Банка Cat (Category) Cat (Категория) CCard (Credit Card) CCard (кредитна карта) Invst (Investment) Invst (Инвестиции) Oth A (Other Assets) Oth A (Други активи) Oth L (Other Liabilities) Oth L (Други активи) Security Сигурност Successfully imported 1 account. Успешно внесена 1 сметка. Успешно внесени %n сметки. Successfully imported 1 category. Успешно внесена 1 категория. Успешно внесени %n категории. 1 duplicate transaction was ignored. 1 дубликат на транзакцията беше игнориран. %n дубликати на транзакцията бяха игнорирани. Failed to import 1 transaction. Неуспех за внос на 1 транзакция. Неуспех за внос на %n транзакции. 1 security was not imported. 1 обезпечение не е бил внесено. %n обезпечения не са били внесени. 1 security transaction was not imported. 1 обезпечение на транзакцията не е било внесено. %n обезпечения на транзакциите не са били внесени. Export QIF File Износ на QIF файла All All accounts Всички Export transaction description as: Износ описанието на сделката като: Memo Бележка Subcategory Подкатегория &Import i18n: tag text i18n: file ./eqonomizeui.rc line 5 &Внасяне &Accounts i18n: tag text i18n: file ./eqonomizeui.rc line 12 &Сметки &Transactions i18n: tag text i18n: file ./eqonomizeui.rc line 24 &Транзакции &Securities i18n: tag text i18n: file ./eqonomizeui.rc line 41 &Обезпечения Stat&istics i18n: tag text i18n: file ./eqonomizeui.rc line 56 Стат&истика Your names NAME OF TRANSLATORS ,Launchpad Contributions:,slavov Your emails EMAIL OF TRANSLATORS ,,sslavov64@gmail.com Edit Exceptions Редактиране на изключенията Edit Recurrence Range Редактиране периода на повторение Begins on: %1 Начало на: %1 No ending date Няма крайна дата End after Край след occurrence(s) възникване (щи) End on Край на End date before start date. Крайната дата е преди началната дата. Enable recurrence Разрешаване на повторение Recurrence Rule Правило за повторение Weekly Седмично Recur every Повтаряй всеки day(s) ден/дни week(s) on: седмица(и) в: month(s), after the start month месец (и),след началото на месеца Recur on the Повтаряй на 1st 1-ви 2nd 2-ри 3rd 3-ти 4th 4-ти 5th 5-ти 6th 6-ти 7th 7-ми 8th 8-ми 9th 9-ти 10th 10-ти 11th 11-ти 12th 12-ти 13th 13-ти 14th 14-ти 15th 15-ти 16th 16-ти 17th 17-ти 18th 18-ти 19th 19-ти 20th 20-ти 21st 21-ви 22nd 22-ри 23rd 23-ти 24th 24-ти 25th 25-ти 26th 26-ти 27th 27-ми 28th 28-ми 29th 29-ти 30th 30-ти 31st 31-ви Last Последен 2nd Last 2-ия последен 3rd Last 3-ия последен 4th Last 4-ия последен 5th Last 5-ия последен day ден possibly on weekend по възможност през уикенда but before weekend но преди уикенда but after weekend но след уикенда year(s), after the start year година (и), след началната година Recur on day part before XXX of 'Recur on day XXX of month YYY' Повторение на ден of part between XXX and YYY of 'Recur on day XXX of month YYY' от On the Part before NNN in 'Recur on the NNN. WEEKDAY of MONTH' На of part between WEEKDAY and MONTH in 'Recur on NNN. WEEKDAY of MONTH' от Recur on day # Повторение на ден # of the year part after NNN of 'Recur on day #NNN of the year' от годината Range… Диапазон… Exceptions… Изключения… No day of week selected for weekly recurrence. Няма ден от седмицата избран за седмичното повторение. Selected day will never occur with selected frequency and start date. Избраният ден никога няма да настъпи с избраната честота и начална дата. Selected day does not exist in selected month. Избраният ден не съществува в избрания месец. Dividend: %1 Дивидент: %1 Account balancing Балансиране на сметката Security: %1 (bought) Ценна книга: %1 (закупена) Security: %1 (sold) Ценна книга: %1 (продадена) Shares bought: Изкупени акции: Shares sold: Продадени акции: Payer: Платец: Payee: Получател: No income category available. Няма свободна категория доходи No expense category available. Няма свободна категория разходи Cannot create a regular transfer to/from a securities account. Не може да се създаде редовен трансфер до / от сметката за ценни книжа. Cannot create a regular income to a securities account. Не може да се създаде редовен трансфер до сметка за ценни книжа. Zero price per share not allowed. Нулева цена на акция не е разрешена. Cannot create a regular expense from a securities account. Не може да се създаде редовен разход от сметката за ценни книжа. Modify Transactions Промяна на транзакции Min amount: Мин сума: Max amount: Макс сума: Min income: Мин доход: Max income: Макс доход: Min cost: Мин цена: Max cost: Макс цена: Include Включително Exclude Изключване From Account От сметката To Account В сметката Payer Платец New/Edit Expense Нови/Редактиране разходи Filter Филтър Total: Общо: Average: Средно: Monthly: Месечно: Total cost: Обща цена: Total income: Общо доходи: Total amount: Обща сума: Monthly average: Средно на месец: Are you sure you want to delete all (%1) transactions in the selected split transaction? Сигурен ли сте, че искате да изтриете всички (%1) сделки в избраната разделена транзакция? * Part of split transaction * Част от разделянето на транзакцията * Part of split (%1) * Част от разделянето (%1) ** Recurring (editing occurrence) ** Повторение (редактирени на събитието) Modify… Променяне… AccountComboBox New account… Нова сметка… Paid with loan… Платено с кредит… Multiple accounts/payments… Множество сметки/плащания… New income category… Нова категория доходи … New expense category… Нова категория разходи… New Account Нова сметка New Income Category Нова категория доходи New Expense Category Нова категория разходи AccountsMenu All Accounts Всички сметки All Categories Combined Всички категории комбинирани %n accounts %n categories Balancing Account balancing Балансиране на сметката Account balancing Balancing of an account Балансиране на сметката Account Balance Adjustment Нагласяне баланса на сметката Budget Balancing балансиране Balancing Name of account for transactions that adjust account balances Балансиране Couldn't open %1 for reading Не може да се отвори %1 за четене No exchange rates found in the downloaded ECB data. Не са намерени валутни курсове в свалените данни. Not a valid Eqonomize! file (XML parse error: "%1" at line %2, col %3) Невалиден Eqonomize! файл (XML синтактична грешка: "%1" ред %2, колона %3) Invalid root element %1 in XML document Невалиден основен елемент %1 в XML документ Unknown XML element: "%1" at line %2, col %3 Непознат XML елемент: "%1" на ред %2, колона %3 XML parse error: "%1" at line %2, col %3 Грешка при четенето на XML: "%1" на ред %2, колона %3 European Euro Евро Unable to load %n currency/currencies. Не мога да заредя %n валута. Не мога да заредя %n валути. No exchange rates found. Няма намерени валутни курсове. USD currency missing. Липсва валута USD. imported импортирана. Unable to load %n account(s). Не може да се зареди 1 сметка. Не може да се заредят %n сметки. Unable to load %n category/categories. Не може да се зареди %n група. Не може да се заредят %n групи. Unable to load %n security/securities. Financial security (e.g. stock, mutual fund) Не може да се зареди %n ценна книга. Не може да се заредят %n ценни книжа. Download command (%1) failed: %2. командата за сваляне (%1) пропадна: %2 Failed to download file from %1: %2. Файла не можа да бъде свален от %1: %2. Upload command (%1) failed: %2. Командата (%1) за качване на файл пропадна: %2 yyyy-yy Financial year when first month is not January (e.g. 2018-19). Transaction Accounts Текущи сметки Savings Accounts Спестовни сметки Credit Cards Кредитни карти Debts Дългове Securities Financial security (e.g. stock, mutual fund) Ценни книжа Cash Пари в брой Transaction Account Текуща сметка Savings Account Спестовна сметка Credit Card Кредитна карта Debt Дълг (заем) Other Друго Unable to load %n security/securities. Не може да се зареди %n ценна книга. Не може да се заредят %n ценни книжа. Unable to load %n transaction(s). Не може да се зареди %n транзакция. Не може да се заредят %n транзакции. File is a directory Файлът е папка Couldn't open file for writing Не мога да отворя файл за писане Error while writing file; file was not saved Грешка при запис на файл; файлът не е бил запазен Unnamed Без име Uncategorized Некатегоризиран CategoriesComparisonChart Save As… Запис като… Print… Печат… From От To До Source: Източник: All Expenses Всички разходи All Incomes Всички приходи Theme: Тема: Chart type: Вид графика: Pie Chart Графика Пай Vertical Bar Chart Вертикални барчета Horizontal Bar Chart Хоризонтални барчета Bar Chart Барчета Графика Default По подразбиране All Expenses, without subcategories Всички разходи, без подкатегории All Expenses, with subcategories Всички разходи, с подкатегории All Incomes, without subcategories Всички проходи, без подкатегории All Incomes, with subcategories Всички приходи, с подкатегории All Accounts Всички сметки Expenses: %1 Разходи: %1 Incomes: %1 Приходи: %1 Error Грешка Invalid date. Грешна дата. To date is before from date. Към настоящия момент е преди считано от датата. From date is after to date. Към настоящия момент е след датата. Couldn't open file for writing. Не мога да отворя файла за писане. Error while writing file; file was not saved. Грешка при запис на файл; файлът не е запазен. Expenses Разходи Expenses, %1 Разходи, %1 Incomes, %1 Приходи, %1 Incomes Приходи Accounts Сметки Expenses, %2: %1 Разходи, %2: %1 Incomes, %2: %1 Приходи, %2: %1 Other descriptions Referring to the transaction description property (transaction title/generic article name) Други описания No description Referring to the transaction description property (transaction title/generic article name) Няма описание Other accounts Други сметки Other categories Други категории %1 Value: %2 %1 Стойност: %2 No description Referring to the Transaction description property (transaction title/generic article name) Няма описание No description Referring to the generic description property Няма описание Value Стойност Income Приход Cost Цена Value (%1) Стойност (%1) Income (%1) Доходи (%1) Cost (%1) Разход (%1) No description Няма описание CategoriesComparisonChartDialog Chart Диаграма CategoriesComparisonReport Save As… Запис като… Print… Печат… Source: Източник: All Categories, excluding subcategories Всички категории без подкатегориите All Categories, including subcategories Всички категории включително и подкатегориите All Tags Всички Етикети Subcategories Подкатегории Descriptions for Referring to the Transaction description property (transaction title/generic article name) Описания за All descriptions Referring to the Transaction description property (transaction title/generic article name) Всички описания No description Referring to the Transaction description property (transaction title/generic article name) Няма описание All Categories Всички категории Expenses: %1 Разходи: %1 Incomes: %1 Приходи: %1 Descriptions for Описания за Payees/payers for Получатели на плащане / платци за Descriptions Referring to the Transaction description property (transaction title/generic article name) Описание Period: Период: From От To До Columns: Колони: Value Стойност Daily ежедневно Monthly Месечно Yearly Годишно Quantity Количество Average value Средна стойност All descriptions Всички описания All payees Всички получатели на пари All payers Всички платци No description Няма описание Descriptions for Referring to the generic description property Описания за Descriptions Referring to the generic description property Описание All descriptions Referring to the generic description property Всички описания No description Referring to the generic description property Няма описание All Payees and Payers Всички получатели и платци Tag: %1 Етикет: %1 All Accounts Всички сметки Descriptions for Referring to the transaction description property (transaction title/generic article name) Описания за Descriptions Referring to the transaction description property (transaction title/generic article name) Описание Months Месеци Years Години Tags Етикети Total: Общо: All descriptions Referring to the transaction description property (transaction title/generic article name) Всички описания All payees/payers Всички получатели/платци No description Referring to the transaction description property (transaction title/generic article name) Няма описание No payee Няма получател на пари No payer Няма платец Error Грешка Invalid date. Грешна дата. To date is before from date. Към настоящия момент е преди считано от датата. From date is after to date. Към настоящия момент е след датата. Couldn't open file for writing. Не мога да отворя файла за писане. Error while writing file; file was not saved. Грешка при запис на файл; файлът не е запазен. Expenses, %2: %1 Разходи, %2: %1 Expenses, %3: %2, %1 Разходи, %3: %2, %1 Incomes, %2: %1 Приходи, %2: %1 Incomes, %3: %2, %1 Приходи, %3: %2, %1 %3: %2, %1 %2: %1 Tags, %1 Етикети, %1 Incomes & Expenses, %1 Приходи и Разходи, %1 Expenses: %2, %1 Разходи: %2, %1 Incomes: %2, %1 Приходи: %2, %1 %2, %1 %1 %1 Incomes & Expenses Приходи & Разходи %1 (%2&ndash;%3) html format; %1: title; %2: from date; %3: to date %1 (%2&ndash;%3) %1 (to %2) html format; %1: title; %2: to date %1 (до %2) Category Категория Payee Получател Description Referring to the transaction description property (transaction title/generic article name) Отнася се за описанието на транзакцията (име на транзакция) Описание Cost Цена Payer Платец Income Приход Payee/Payer Получатели/платци Tag Етикет Daily Average Средно Дневно Monthly Average Средно на месец Yearly Average Средно годишно Average Cost Средна цена Average Income Среден доход Average Value Средна стойност No payee/payer Няма получател/платец Total Общо Total incomes Общо приходи Total expenses Общо разходи Total (Profits) Общо (печалбите) CategoriesComparisonReportDialog Report Отчет ConfirmScheduleDialog The following transactions was scheduled to occur today or before today. Confirm that they have indeed occurred (or will occur today). Следните транзакции бе насрочено да се състоят днес или вчера. Уверете се, че те наистина са се случили (или ще се появят днес). Date Дата Type Вид Description Описание Name Име Description Generic Description Описание Description Transaction description property (transaction title/generic article name) Описание Amount Сума Edit… Редактиране… Postpone… Отлагане… Delete Изтриване Error Грешка Can only postpone to future dates. Може само да се отложи за бъдещи дати. ConfirmScheduleListViewItem Transfer Прехвърляне Dividend Дивиденти Income Приход Expense Разход Securities Purchase Financial security (e.g. stock, mutual fund) Покупка ценни книги Securities Sale Financial security (e.g. stock, mutual fund) Продажба ценни книги Security Buy Покупка споръчител Security Sell Продажба с поръчител Debt Payment Плащане дълг CurrencyConversionDialog Currency Converter Валутен калкулатор DebtFee Debt payment: %1 (fee) Плащане дълг: %1 (главница) DebtInterest Debt payment: %1 (interest) Плащане дълг: %1 (лихва) DebtPayment Debt payment: %1 Плащане дълг: %1 DebtReduction Debt payment: %1 (reduction) Плащане дълг: %1 (намаляване) DescriptionsMenu All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Всички описания комбинирани All Tags Combined All Payees Combined Всички получатели комбинирано All Payers Combined Всички платци комбинирано All Payees/Payers Combined Всички получатели/платци комбинирано No description Referring to the transaction description property (transaction title/generic article name) Няма описание No payee Няма получател на пари No payer Няма платец No payee/payer Няма получател/платец %n descriptions Referring to the transaction description property (transaction title/generic article name) %n tags %n етикет %n етикети %n payees %n payers %n payees/payers EditAssetsAccountDialog Type: Вид: Cash Пари в брой Current Account Текуща сметка Savings Account Спестовна сметка Credit Card Кредитна карта Liabilities Задължения Transactional Account Чекова сметка Debt Дълг (заем) Securities Ценни книжа Other Друго Currency: Валута: Edit Редактиране Name: Име: Bank: Банка: Initial balance: Начален баланс: Debt: Дълг: Initial balance Начален баланс Group: Група: no group без група Transferred to: Прехвърлен към: Date: Дата: Lender: Кредитор: Default account for budgeted transactions Основна сметка за бюджетни транзакции Description: Описание: Account is closed Сметката е закрита Warning Внимание Type cannot be changed to securities for accounts with transactions. Типа не може да бъде променен от сметка с ценни книжа към сметка с транзакции. Issuer: Издател: Zero value not allowed. Нулева стойност, не се допуска. Error Грешка Transaction Account Текуща сметка Opening balance: Account balance Начално салдо: Opening balance Account balance Начално салдо New currency… Нова валута… If you change the currency of an account, the currency of all associated transactions will also change, without any conversion. Do do wish to continue anyway? Ако смените валутата на сметка, валутата на всички нейни транзакции също ще бъде сменена без конвертирания на стойносите. Искате ли да продължите? Empty name. Празно име. The entered name is used by another account. Въведеното име се използва от друга сметка. EditCurrencyDialog Edit Currency Редактирай валута New Currency Нова валута Code: Код: Symbol: Символ: Prefix Префикс Suffix Суфикс Default По подразбиране Name: Име: Decimals: Десетични символи: Date: Дата: Main currency Основна валута Error Грешка Error saving currencies: %1. Грешка при запис на валута: %1. Empty code. Празен код. Code already exists. Кода вече съществува. EditDebtPaymentDialog Debt Payment Погасяване на дълг EditDebtPaymentWidget Debt: Дълг: Date: Дата: Debt reduction: Намаляване на дълга: Reduction payment: Плащане: Interest: Лихва: Paid Платен Added to debt Добавено към дълга Fee: Такса: Account: Сметка: Expense category: Категория разход: Associated file: Асоцииран файл: Select a file Изберете файл Open the file Отвори файлът Comments: Коментари: Related to: Label for linked transactions Връзки: Total value: Обща стойност: Error Грешка No suitable account available. Няма подходяща сметка на разположение. Invalid date. Грешна дата. Interest must not be zero. Лихвате не може да е нула. At least one value must non-zero. Поне една стойност трябва да е различна от нула. EditExceptionsDialog Edit Exceptions Редактиране на изключенията Occurrences: Възникващи: Add Exception Добави изключение Remove Exception Премахни изключение Exceptions: Изключения: Only the first fifty occurrences are shown. Само първите петдесе съвпадения са показани. Add Добавяне Apply Прилагане Delete Изтриване Error Грешка Invalid date. Грешна дата. EditExpensesAccountDialog Name: Име: Parent category: Родителкса категория: None Няма Monthly budget: Месечен бюджет: Description: Описание: Error Грешка Empty name. Празно име. The entered name is used by another expense category. Въведеното име се използва от друга категория сметки. EditIncomesAccountDialog Name: Име: Parent category: Родителска категория: None Няма Monthly budget: Месечен бюджет: Description: Описание: Error Грешка Empty name. Празно име. The entered name is used by another income category. Въведеното име се използва от друга категория доходи. EditLoanTransactionWidget Date: Дата: Account: Сметка: Comments: Коментари: Total value: Обща стойност: Error Грешка No suitable account available. Няма подходяща сметка на разположение. Invalid date. Грешна дата. EditMultiAccountDialog Expense with Multiple Payments Разход с множество плащания Income with Multiple Payments Приход с множество плащания EditMultiAccountWidget Description: Описание: Description: Generic Description Описание: Description: Transaction description property (transaction title/generic article name) Описание: Quantity: Количество: Category: Категория: Tags: Етикети: Associated file: Асоцииран файл: Select a file Избери файл Open the file Отвори файлът Comments: Коментари: Related to: Label for linked transactions Връзки: Transactions: Транзакции: Date Дата Account Сметка Payee Получател Payer Платец Cost Цена Income Приход Total cost: Обща цена: New Tag Нов Етикет Tag: Етикет: Value Стойност New Нов Edit… Редактиране… Delete Изтриване Total value: Обща стойност: Error Грешка No suitable expense categories available. Няма налична подходяща категория за разход. A split must contain at least two transactions. Разделянето трябва да съдържа най-малко две транзакции. EditMultiItemDialog Split Transaction Разделяне на транзакциите EditMultiItemWidget Description: Описание: Description: Generic Description Описание: Date: Дата: Account: Сметка: Payee/Payer: Получатели/платци: Transactions: Транзакции: Type Вид Description Generic Description Описание Description: Transaction description property (transaction title/generic article name) Описание: Tags: Етикети: Associated file: Асоцииран файл: Select a file Избери файл Open the file Отвори файл Comments: Коментари: Related to: Label for linked transactions Връзки: Description Transaction description property (transaction title/generic article name) Описание Payment Плащане Deposit Депозит/внос New Нов New Expense… Нов разход … New Income… Нов приход… New Deposit… Нова вноска… New Withdrawal… Ново теглене … New Securities Purchase… Financial security (e.g. stock, mutual fund) Нова покупка на ценни книжа… New Securities Sale… Financial security (e.g. stock, mutual fund) Нова продажба на ценни книжа… Shares Bought… Изкупени акции… Shares Sold… Продадени акции … Account/Category Сметка/Категория Value Стойност Income Приход Expense Разход New Dividend… Нов дивидент… Edit… Редактиране… Delete Изтриване Total value: Обща стойност: Error Грешка No suitable account available. Няма подходяща сметка на разположение. Invalid date. Грешна дата. A split must contain at least two transactions. Разделянето трябва да съдържа най-малко две транзакции. Cannot transfer money to and from the same account. Не можете да прехвърляте пари от една и съща сметка. EditQuotationsDialog Quotations Оферти Date Дата Price per Share Цена на акция Quotations Financial quotation Оферти Quotes Financial quote Котировки Price per Share Financial Shares Цена на акция Add Добавяне Modify Променяне Delete Изтриване Import… Внасяне… Export… Експортиране… Quotes for %1 Financial quote Котировки на %1 Quotations for %1 Financial quotation Котировки на %1 Quotations for %1 Котировки на %1 Error Грешка Couldn't open %1 for reading. Не мога да отворя %1 за четене. Error reading %1. Грешка при четенето на %1. Successfully imported %n quote(s). Unable to import any quotes. Failed to import %n data row(s). Неуспешно въвеждане на %n ред с данни. Неуспешно въвеждане на %n редове с данни. Required columns missing. Задължителните колони липсват. Invalid value. Невалидна стойност. Invalid date. Грешна дата. No data found. Няма намерени данни. Information Информация Unrecognized date format. Неразпознат формат за дата. Specify Format Определете Format The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. Форматът на дати и / или цифри в CSV файла е двусмислен. Моля, изберете правилния формат. Date format: Формат на датата: Value format: Стойност на формата: Couldn't open file for writing. Не мога да отворя файла за писане. Quotes: %1 Котировки: %1 Error while writing file; file was not saved. Грешка при запис на файл; файлът не е запазен. EditRangeDialog Edit Recurrence Range Редактиране периода на повторение Begins on: %1 Начало на: %1 No ending date Няма крайна дата End after Край след occurrence(s) възникване (щи) End on Край на Error Грешка Invalid date. Грешна дата. End date before start date. Крайната дата е преди началната дата. EditReinvestedDividendDialog Reinvested Dividend Реинвестирани дивиденти Security: Ценна книга: Shares added: Добавяне на акции: Security: Financial security (e.g. stock, mutual fund) Ценна книга: Shares added: Financial shares Добавени акции: Date: Дата: Error Грешка Invalid date. Грешна дата. EditScheduledDebtPaymentDialog Transaction Транзакция Recurrence Повторение Edit Debt Payment Редакция на погасителна вноска New Debt Payment Ново плащане по дълг EditScheduledLoanTransactionDialog Recurrence Повторение EditScheduledMultiAccountDialog Transactions Транзакции Recurrence Повторение New Expense with Multiple Payments Нов разход с множество плащания New Income with Multiple Payments Нов приход с множество плащания Edit Expense with Multiple Payments Редакция на разход с множество плащания Edit Income with Multiple Payments Редакция на приход с множество плащания EditScheduledMultiItemDialog Transactions Транзакции Recurrence Повторение New Split Transaction Нова разделена транзакция Edit Split Transaction Редакция на разделена транзакция EditScheduledTransactionDialog Expense Разход Dividend Дивиденти Income Приход Reinvested Dividend Реинвестирани дивиденти Transfer Прехвърляне Security Buy Покупка споръчител Security Sell Продажба с поръчител Securities Purchase Financial security (e.g. stock, mutual fund) Покупка на ценни книжа Securities Sale Financial security (e.g. stock, mutual fund) Продажба на ценни книжа Recurrence Повторение New Expense Нов разход New Expense Paid with Loan Нов разход платен с дълг New Dividend Нов дивидент New Income Нов приход New Transfer Нов трансфер New Securities Purchase Financial security (e.g. stock, mutual fund) Нова покупка на ценни книжа New Reinvested Dividend Нов реинвестиран дивиден New Securities Sale Financial security (e.g. stock, mutual fund) Нова продажба на ценни книжа Edit Reinvested Dividend Редакция на реинвестиран дивидент Edit Securities Purchase Financial security (e.g. stock, mutual fund) Редактиране на покупка на ценни книжа Edit Securities Sale Financial security (e.g. stock, mutual fund) Редактиране на продажба на ценни книжа New Security Buy Нова покупка с поръчител New Security Sell Нова продажба с поръчител Edit Expense Редактиране на разходи Edit Dividend Редактиране на дивиденти Edit Income Редактиране на приходи Edit Transfer Редактиране на трансфери Edit Securities Bought Редактиране на покупка на ценни книжа Edit Securities Sold Редактиране на продажба на ценни книжа EditSecurityDialog Type: Вид: Mutual Fund Взаимен фонд Bond Облигация Stock Акция Stock Financial stock Акция Other Друг Name: Име: Account: Сметка: Decimals in shares: Financial shares Десетични знаци в акциите: Initial shares: Financial shares Първоначални акции: Decimals in quotes: Financial quote Десетични знаци в котировките: Initial quote: Financial quote Първоначален котировка: Empty name. Празно име. No suitable account available. Няма подходяща сметка на разположение. Initial quotation: Financial quotation Първоначален оферта: Decimals in shares: Десетични в акции: Initial shares: Първоначални акции: Decimals in Shares: Десетични в акции: Initial Shares: Първоначални акции: Initial quotation: Първоначален оферта: Date: Дата: Description: Описание: Error Грешка No suitable account or income category available. Няма свободна подходяща сметка или категория доходи. EditSecurityTradeDialog Security Trade Сигурност на търговията From security: От ценна книга: Shares moved: Преместни акции: All Всички To security: На ценна книга: Shares received: Получени акции: Securities Exchange Shares of one security directly exchanged for shares of another; Financial security (e.g. stock, mutual fund) Размяна на ценни книжа From security: Financial security (e.g. stock, mutual fund) От ценна книга: Shares moved: Financial shares Преместни акции: To security: Financial security (e.g. stock, mutual fund) На ценна книга: Shares received: Financial shares Получени акции: Value: Стойност: Date: Дата: Error Грешка No other security available for exchange in the account. Shares of one security directly exchanged for shares of another; Financial security (e.g. stock, mutual fund) Няма други ценни книжа за размяна по сметката. No other security available for trade in the account. Няма друга защита за търговия по сметката. Selected to and from securities are the same. Financial security (e.g. stock, mutual fund) Избраните и тези ценни книжа са едни и същи. Zero shares not allowed. Financial shares Нулеви акции не са разрешени. Selected to and from securities are the same. Избраните и тези ценни книжа са едни и същи. Invalid date. Грешна дата. Zero shares not allowed. Нулеви акции не са разрешени. Zero value not allowed. Нулева стойност, не се допуска. EditSplitDialog Split Transaction Разделяне на транзакциите Description: Описание: Date: Дата: Account: Сметка: Transactions: Транзакции: Type Вид Description Описание Name: Име: Name Име Description Generic Description Описание Account/Category Сметка/Категория Payment Плащане Deposit Депозит/внос New Нов New Expense… Нов разход … New Income… Нов приход… New Deposit… Нова вноска… New Withdrawal… Ново теглене … Shares Bought… Изкупени акции… Shares Sold… Продадени акции … New Dividend… Нов дивидент… Edit… Редактиране… Delete Изтриване Total value: Обща стойност: Error Грешка No suitable account available. Няма подходяща сметка на разположение. Invalid date. Грешна дата. Future dates is not allowed. Бъдещи дати не са позволени. A split must contain at least two transactions. Разделянето трябва да съдържа най-малко две транзакции. Cannot transfer money to and from the same account. Не можете да прехвърляте пари от една и съща сметка. Eqonomize Accounts && Categories Сметки и категории Expenses Разходи Incomes Приходи Transfers Трансфери Transaction Accounts Текущи сметки Savings Accounts Спестовни сметки Credit Cards Кредитни карти Debts Дългове Securities Ценни книжа Schedule График Account / Category Сметка / Категория Remaining Budget (%1) Оставащ бюджет (%1) Change (%1) Смени (%1) Total (%1) Общо (%1) %2 of %1 %2 remains of %1 budget %2 от %1 Accounts Сметки Includes budgeted transactions Включва бюджетни транзакции Tags Етикети Period Период From От To До Select Period Избор на период Current Month Текущ месец Current Year Текуща година Current Whole Month Целият текущ месец Current Whole Year Цялата текуща година Whole Past Month Целият изминал месец Whole Past Year Цялата изминала година Previous Month Предходния месец Previous Year Предходната година Show partial budget Покажи частично бюджета Edit Budget Редактиране на бюджета Budget: Бюджет: Month: Месец: Result previous month: Резултат за предходния месец: New Security… Нов поръчител… New Transaction Нова транзакция Set Quotation… Задаване оферта … Name Име Value Стойност Shares Акции Quotation Оферта Cost Цена Profit Печалба Yearly Rate Годишен темп Type Вид Account Сметка Statistics Period Статистически период New Schedule Нов график Edit Редактиране Remove Премахване Next Occurrence Следващо появяване Description Описание Description Generic Description Описание Amount Сума Payee/Payer Получатели/платци Comments Коментари Set Schedule Confirmation Time Нагласяне на време за потвърждение Schedule confirmation time: Нагласявне на време за потвърждение: Set Budget Period Период за бюджета First day in budget month: Първи ден на бюджетния месец: 1st 1-ви 2nd 2-ри 3rd 3-ти 4th 4-ти 5th 5-ти 6th 6-ти 7th 7-ми 8th 8-ми 9th 9-ти 10th 10-ти 11th 11-ти 12th 12-ти 13th 13-ти 14th 14-ти 15th 15-ти 16th 16-ти 17th 17-ти 18th 18-ти 19th 19-ти 20th 20-ти 21st 21-ви 22nd 22-ри 23rd 23-ти 24th 24-ти 25th 25-ти 26th 26-ти 27th 27-ми 28th 28-ми Last Последен 2nd Last 2-ия последен 3rd Last 3-ия последен 4th Last 4-ия последен 5th Last 5-ия последен Timestamp Време Links Връзки Remove Link Link to "%1" create link to transaction (link used as verb) Information Информация All Import Options Опции за импорт Ignore duplicate transactions Игнориране на дублиращи се транзакции Rename duplicate accounts Преименуване на дублиращи се транзакции Rename duplicate categories Преименуване на дублиращи се категории Rename duplicate securities Преименуване на дублиращи се ценни книжа Synchronization Settings Настройки за синхронизация Web address: WEB адрес: Download command: Команда за сваляне: Duplicate Transaction… duplicate as verb Дублирай транзакция... Create Link create link to or between transaction(s) Създаване на връзка New Tag… Нов Етикет... Rename Tag… Преименувай Етикет... Remove Tag Премахване на Етикет New Tag Нив Етикет Tag name: Имет на етикета: Remove tag? Премахване на етикета? Do you wish to remove the tag "%1" from %n transaction(s)? Желаете ли да премахнете етикет "%1" от %n транзакция? Желаете ли да премахнете етикет "%1" от %n транзакции? Rename Tag Преименуване на Етикет optional незадължително Right align Подравнете вдясно Upload command: Команда за качване: mandatory задължително Automatic synchronization Автоматична синхронизация Upload Качване Uploading… Качване... Error uploading file Грешка при качване на файла Error uploading %1: %2. Грешка при кчаване %1: %2. Synchronizing… Синхронизиране... Error synchronizing file Грешка при синхронизиране на файл Error synchronizing %1: %2. Грешка при синхронизиране %1: %2. Synchronization error Грешка при синхронизация Synchronize file? Синхронизиране на файла? The file has been modified by a different user or program. Do you wish to merge changes? Файлът е бил променен от друг потребител или приложение. Желаете ли да обединя промените? New version available Има нова версия A new version of %1 is available.<br><br>You can get version %2 at %3. Нова версия %1 е налична.<br><br> може да получите версия %2 на %3. Abort Откажи First month in budget year: Първи месец на фискалната година: %f = local file (temporary), %u = url %f = локален файл (временен), %u = url Failed to download exchange rates from %1: %2. Не може да се свалят валутните курсове от %1 : %2. Error reading data from %1: %2. Грешка при четене на данни от %1: %2. Unrecognized Currency Непозната Валута No exchange rate is available for the default currency (%1). If you wish to use multiple currencies you should set the exchange rate manually. Няма валутен курс за валутата по подразбиране (%1). Ако иксате да ползвате валутните възможности трябва да въведете валутния курс на ръка. Set Main Currency Настройка на основна валута Currency: Валута: Replace all occurrences of the former main currency Замени старата основна валута навсякъде където се е използвала Transaction Account Текуща сметка Import %1 File… Импортирай %1 файл... Update Exchange Rates Обнови валутните курсове Reconcile Account… Adjust balance… Referring to account balance Нагласяне на баланс… Close Account Mark account as closed Маркира сметката като закрита Закриване на сметка Show payee and quantity Покажи количество и бенефициенти Show quantity and payer/payee properties for incomes and expenses. Покажи количество и бенефициенти за приходи и разходи. Set Schedule Confirmation Time… Нагласяне на време за потвърждение... Select Font… Изберете шрифт... Language Език Default По подразбиране Restart required Нужен е рестарт Only use this when unable to find the cause of the incorrect recorded account balance. Използвайте това само когато не може да намерите причина за некоректен баланс в сметката. Reopen Account Mark account as not closed Отваряне на затворена сметка Set Main Currency… Настройка на Основна Валута… Use Exchange Rate for Transaction Date Използвай валутния курс за датата на транзакцията Use the exchange rate nearest the transaction date, instead of the latest available rate, when converting the value of transactions. Използвай валутния курс за най-бликата дата до датата на транзацията, instead of the latest available rate, when converting the value of transactions. Adjust Account Balance Нагласяне на баланс на сметка New Security Нов поръчител Edit Security Редактирай поръчителя Total value: Обща стойност: Cost: Разходи: Profit: Печалба: Rate: Оценка: Are you sure you want to delete the security "%1" and all associated transactions? Сигурен ли сте, че искате да изтриете поръчител "%1" и всички свързани сделки? Error Грешка No security available. Няма свободен поръчител. Set Quotation (%1) Направи оферта (%1) Price per share: Цена за една акция: Date: Дата: Invalid date. Грешна дата. Future dates are not allowed. Бъдещи дати не са позволени. Security Transactions Сделки с ценни книжа Bond Облигация Stock Акция Mutual Fund Взаимен фонд Other Друг Add Loan Добави заем Add Category Добави категория Ledger Главна счетоводна книга To date is before from date. Към настоящия момент е преди считано от датата. From date is after to date. Към настоящия момент е след датата. Cash Пари в брой Check Account Проверка на сметка Savings Account Спестовна сметка Salary Заплата Bills Сметки Clothing Облекло Groceries Хранителни Leisure Свободно време Couldn't open file Не мога да отворя файл Error loading %1: %2. Грешка при зареждане на %1: %2. Couldn't save file Файлът не може да се запази Error saving %1: %2. грешка при запазване %1: %2. Updating exchange rates… Обнявяване на валутните курсова… Error saving currencies: %1. Грешка при запис на валутуте: %1 New currency… Нова валута… Transaction Schedule График на транзакциите Total Общо Accounts &amp; Categories html format Сметки &amp; Категории Accounts &amp; Categories (%1&ndash;%2) html format Сметки &amp; Категории (%1&ndash;%2) Accounts &amp; Categories (to %1) html format Сметки &amp; Категории (to %1) Change Noun, how much the account balance has changed Промяна Balance Баланс Current Account Текуща сметка Credit Card Кредитна карта Liabilities Задължения Set Quote… Financial quote Задаване котировкa… Quote Financial quote Котировка Set Quote (%1) Financial quote Задаване котировка (%1) Stock Financial stock Акция Balance Noun. Balance of an account Cалдо Category Категория Budget Бюджет Remaining Budget Оставащ бюджет Total Incomes Общо приходи Costs Разходи Total Expenses Общо разходи Account/Category Noun, how much the account balance has changed Сметка/Категория Empty expenses list. Празен списък с разходи. Empty incomes list. Празен списък с приходи. Empty transfers list. Празен списък с трансфери. Empty securities list. Празен списък с поръчители. Empty schedule list. Празен списък с графици. Couldn't open file for writing. Не мога да отворя файла за писане. Error while writing file; file was not saved. Грешка при запис на файл; файлът не е запазен. &File &Файл &Accounts &Сметки &Transactions &Транзакции &Securities &Обезпечения Stat&istics Стат&истика S&ettings &Настройки &Help &Помощ File Файл Transactions Транзакции Statistics Статистика &New &Нов &Open… &Отваряне… Open Recent Последно използвани Clear List Изчистване на списъка &Save &Запис Save As… Запис като… &Revert &Връщане &Print View… &Покажи страницата за печат… &Print… &Отпечатай… Print Preview… Предпечат преглед… Import Внасяне Import CSV File… Импортиране CSV файла … Import QIF File… Импортиране QIF файла … Export View… Преглед на износа … Export As QIF File… Износ като файл QIF … Currency Converter Валутен калкулатор &Quit &Изход Add Account… Добави сметка… New Account… Нова сметка… New Income Category… Нова категория доходи … New Expense Category… Нова категория разходи… Add Account Добави сметка Assets Активи Description Transaction description property (transaction title/generic article name) Описание Security Transactions Financial security (e.g. stock, bond) Сделки с ценни книжа &Loans &Заеми New Loan… Нов Заем… Edit… Редактиране… Balance… Баланс… Show Transactions Покажи транзакцията Show Ledger Покажи главната счетоводна книга New Expense… Нов разход … New Income… Нов приход… New Transfer… Нов трансфер… New Split Transaction… Ново разделяне на на транзакция … New Expense with Multiple Payments… Нов разгод с множество плащания… Refund… Възстановяване… Repayment… Изплащане… New Refund/Repayment… Ново Възстановяване/Изплащане… Edit Transaction(s) (Occurrence)… Редактиране на транзакцията(ите) (в действителност) … Edit Occurrence… Редактирай събитието… Edit Schedule (Recurrence)… Редактирай графика (повторяемост) … Edit Schedule… Редактирай графика… Edit Split Transaction… Редактиране на разделянето на транзакциите… Join Transactions… join transactions together Събери транзакциите… Split Up Transaction split up joined transactions Разделяне на транзакциите Edit Timestamp… Редакция на време... Select Associated File Избор на асоцииран файл Open Associated File Отвори асоцииран файл Remove Transaction(s) (Occurrence) Премахване на транзакцията (е) (събитие) Remove Occurrence Премахни събитието Delete Schedule (Recurrence) Изтриване на график (Повторение) Delete Schedule Изтриване на график Remove Split Transaction Премахни разделянето на транзакциите New Debt Payment… Нова вноска по кредит… New Unpaid Interest… Нова неплатена лихва… New Expense Paid with Loan… Нов разход платен с кредит… Edit Security… Редактиране на поръчител… Remove Security Премахни поръчител Shares Bought… Изкупени акции… Shares Sold… Продадени акции … Shares Moved… Преместени акции… Dividend… Дивиденти… Reinvested Dividend… Реинвестирани дивиденти… Transactions… Транзакции… Edit Quotations… Редактиране на офертите… Development Over Time Report… Разработка през време на доклада… Categories Comparison Report… Доклад за сравнение на категориите… Development Over Time Chart… Развитие на графиката с времето… Categories Comparison Chart… Диаграма за сравнение на категориите… Use Additional Transaction Properties Използвайте допълнителни свойства по сделката Show quantity and payer/payee for incomes and expenses. Покажи количество и бенефициенти за приходи и разходи. Set Budget Period… Настройка на бюджетен период… Initial Period Първоначален период Remember Last Dates Запомни последните дати Backup Frequency Честота на архивирането Daily Ежедневно Weekly Седмично Fortnightly На две сеедмици Monthly Месечно Never Никога Cloud Synchronization (experimental)… Синхронизация в облака (експериментално)... Dark Mode Help Помощ Report Bug Съобщаване за грешка About %1 Относно %1 About Qt Относно Qt Please restart the application for the language change to take effect. Моля рестартирайте приложението за да влязат в сила промените на езика. A personal accounting program Лична счетоводна програма License: GNU General Public License Version 2 Лиценз: GNU General Public License 2 Crash Recovery Възстановяване след срив %1 exited unexpectedly before the file was saved and data was lost. Do you want to load the last auto-saved version of the file? %1 завърши неочаквано преди файлът е бъде запазен и данните бяха изгубени. Искате ли да заредите последната автоматично записана версия на файла? Untitled Неозаглавен Securities Financial security (e.g. stock, mutual fund) Ценни книжа New Security… Financial security (e.g. stock, mutual fund) Нови ценни книги… Set Quotation… Financial quotation Задаване оферта … Shares Financial shares Акции Quotation Financial quotation Оферта New Security Financial security (e.g. stock, mutual fund) Нови ценни книги Edit Security Financial security (e.g. stock, mutual fund) Редактирай ценни книги Delete security? Financial security (e.g. stock, mutual fund) Изтриване на ценни книжа? Are you sure you want to delete the security "%1" and all associated transactions? Financial security (e.g. stock, mutual fund) Сигурен ли сте, че искате да изтриете ценна книга "%1" и всички свързани сделки? No security available. Financial security (e.g. stock, mutual fund) Няма налични ценни книги. Set Quotation (%1) Financial quotation Направи оферта (%1) Price per share: Financial shares Цена за една акция: Security Transactions Financial security (e.g. stock, mutual fund) Сделки с ценни книжа Checking Account Transactional account Текуща сметка Balance Account balance Cалдо Empty securities list. Financial security (e.g. stock, mutual fund) Празен списък с ценни книжа. &Securities Financial security (e.g. stock, mutual fund) &Ценни книжа Balance… Balance account Баланс… Edit Security… Financial security (e.g. stock, mutual fund) Редактиране на ценни книжа… Remove Security Financial security (e.g. stock, mutual fund) Премахни ценна книга Shares Bought… Financial shares Купени акции… Shares Sold… Financial shares Продадени акции… Edit Quotations… Financial quotation Редактиране на офертите… License: GNU General Public License Version 3 Лиценз: GNU General Public License 3 Eqonomize! Accounting File Eqonomize! Счетоводен Файл S&ynchronize С&инхронизация Save file? Запис на файл? The current file has been modified. Do you want to save it? Текущия файл е бил променен. Искате ли да го запазите? Confirm Schedule Потвърдете списъка New Account Нова сметка New Loan Нов заем New Income Category Нова категория доходи New Expense Category Нова категория разходи Balance Account Баланс на сметката Book value: Счетоводна стойност: of which %1 is balance adjustment Referring to account balance от които %1 е нагласен баланс Real value: Реална стойност: Edit Account Редактиране на сметка Edit Income Category Редактиране на категория доходи Edit Expense Category Редактиране на категория разходи Remove subcategories? Премахване на подкатегория? Do you wish to remove the category including all subcategories? Искате ли да премахнете категорията включително всички нейни подкатегории? Move transactions? Преместване на транзакцията? Move to: Преместване в: Remove irreversibly from all accounts (do not do this if account has been closed!) Премахване от всички акаунти (тази операция не може да се отмени) (не правете това ако акаунта е затворен!) The category contains some expenses. What do you want to do with them? Категорията съдържа някои разходи. Какво желаете да правя с тях? The category contains some incomes. What do you want to do with them? Категорията съдържа някои доходи. Какво желаете да правя с тях? The account contains some transactions. What do you want to do with them? Сметката съдържа някои транзакции. Какво желаете да правя с тях? Remove Category? Премахване на категорията? The category contains some expenses that will be removed. Do you still want to remove the category? Категорията съдържа някои разходи, които ще бъдат премахнати. Все още ли искате да премахнете категорията? The category contains some incomes that will be removed. Do you still want to remove the category? Категория съдържа някои доходи, които ще бъдат премахнати. Все още ли искате да премахнете категорията? Remove Account? Премахване на сметката? The account contains some transactions that will be removed. Do you still want to remove the account? Сметката съдържа някои транзакции, които ще бъдат премахнати. Все още ли искате да премахнете сметката? %2 of %1 %1: budget; %2: remaining budget %2 от %1 Balance… Verb. Balance an account Баланс… Shares Exchanged… Shares of one security directly exchanged for shares of another; Financial shares Разменени акции… Shares of one security directly exchanged for shares of another Financial shares Дял от една акция дирекнто разменен за дял от друга Edit Quotes… Financial quote Редактиране на котировки… Balance Account Verb Баланс на сметката %1 (with no budget) %1 (извън бюджета) %1 (with budget %2) %1 (с никакъв бюджет %2) EqonomizeCalendarWidget Today Днес EqonomizeDateEdit Today Днес EqonomizeTranslator OK Only used when Qt translation is missing Cancel Only used when Qt translation is missing Close Only used when Qt translation is missing &Yes Only used when Qt translation is missing &No Only used when Qt translation is missing &Open Only used when Qt translation is missing &Save Only used when Qt translation is missing &Select All Only used when Qt translation is missing Look in: Only used when Qt translation is missing File &name: Only used when Qt translation is missing Files of type: Only used when Qt translation is missing EqonomizeValueEdit Error Грешка Empty denominator. Empty factor. Division by zero. Деление на нула. Unknown or ambiguous currency, or unrecognized characters, in expression: %1. Непозната или двусмислена валута, или неразпознати знаци в разход: %1. Empty base. Празна база. Empty exponent. Празна дробна част. Unrecognized characters in expression. Непознати симвили в израза. ExportQIFDialog Export QIF File Износ на QIF файла Account: Сметка: All All accounts Всички Export transaction description as: Износ описанието на сделката като: Export transaction description as: Referring to generic description Износ описанието на сделката като: Payee Получател Memo Бележка Subcategory Подкатегория Date format: Формат на датата: Value format: Стойност на формата: File: Файл: Error Грешка Selected file is a directory. Избраният файл е директория. Overwrite Презаписване The selected file already exists. Would you like to overwrite the old copy? Избраният файл вече съществува. Бихте ли искали да го замените с по-стар? You selected a directory! Избрали сте директория! Couldn't open file for writing. Не мога да отворя файла за писане. Error while writing file; file was not saved. Грешка при запис на файл; файлът не е запазен. ImportCSVDialog Import CSV file Въведи CSV файла Transaction Type Selection Избор на тип на транзакцията Expenses Разходи Incomes Приходи Transfers Трансфери Expenses and incomes (negative cost) Разходи и приходи (отрицателен разход) Expenses and incomes (separate columns) Разходи и приходи (отделни колони) All types Всички типове Presets: File Selection Избор на файл File: Файл: First data row: Първият ред данни: Auto Автоматично Column delimiter: Колона разделител: Comma Запетая Tabulator Табулатор Semicolon Точка и запетая Space Интервал Other Друг Columns Specification Колони спецификации Save as preset… Imports data as expenses and incomes. Costs have negative value. Value is the only required column. Въведи данните като доходи и разходи. Разходите трябва да са отрицателна стойност. Стойността е единственото, за което трябва колона. Imports data as expenses and incomes. Costs and incomes have separate columns. Income and cost both all required columns. Въведи данните като доходи и разходи.Разходи и приходи са с отделни колони. Доходи и разходи, изискват колона. Warning Внимание The same column number is selected multiple times. Do you wish to proceed anyway? Description: Описание: Description: Transaction description property (transaction title/generic article name) Описание: Column Колона Value Стойност Cost: Разходи: Date: Дата: Category: Категория: From account: От сметката: Quantity: Количество: Payee: Получател: Tags: Етикети: Comments: Коментари: Create missing categories and accounts Създай липсващи категории и сметки Save Preset Imports data as expenses. Costs have positive value. Value is the only required column. Въведи данните като разходи. Разходите трябва да са положителна стойност. Стойността е единственото, за което трябва колона. Imports data as incomes. Value is the only required column. Въведи данните като доходи.Стойността е единственото, за което трябва колона. Income: Приход: To account: В сметката: Payer: Платец: Imports data as transfers. Value is the only required column. Въведи данните като трансфери.Стойността е единственото, за което трябва колона. Amount: Сума: Imports data as expenses and incomes. Costs have negative value. Value and category are both required columns. Въведи данните като доходи и разходи. Разходите трябва да са отрицателна стойност. Стойността и категориите, изискват колона. Value: Стойност: Account: Сметка: Payee/payer: Получатели/платци: Imports data as expenses and incomes. Costs and incomes have separate columns. Income, cost, and category are all required columns. Въведи данните като доходи и разходи.Разходи и приходи са с отделни колони. Доходи, разходи и категории са с всички необходими колони. Imports data as expenses, incomes, and transfers. Costs have negative or positive value. Value, to, and from are all required columns. Accounts and categories must be existing. Въведи данните като разходи, приходи и трансфери.Разходите трябва да са с отрицателна или положителна стойност.Стойността, до,и от,са необходими колони. Сметки и категории трябва да съществуват. From: От: To: До: Error Грешка A file must be selected. Файлът трябва да бъде избран. Selected file is a directory. Избраният файл е директория. Selected file does not exist. Избраният файл не съществува. Empty delimiter. Празен разделител. The same column number is selected multiple times. Един и същ номер на колона е избран няколко пъти. Selected from account is the same as the to account. Избраното от сметката е същото като осчетоводеното. Invalid date. Грешна дата. Couldn't open %1 for reading. Не мога да отворя %1 за четене. Error reading %1. Грешка при четенето на %1. Uncategorized Некатегоризиран Successfully imported %n transaction(s). Успешно въведени %n транзакция. Успешно въведени %n транзакции. Unable to import any transactions. Не може да се въвеждат никакви, внесени транзакции. Failed to import %n data row(s). Неуспешно въвеждане на %n ред с данни. Неуспешно въвеждане на %n редове с данни. Required columns missing. Задължителните колони липсват. Invalid value. Невалидна стойност. Empty category name. Празно име на категорията. Empty account name. Празно име на сметката. Unknown category found. Неизвестна категория намерена. Unknown account found. Неизвестна сметка намерена. Cannot import security transactions (to/from security accounts). Не могат да бъдат внесени сделки с ценни книжа (до / от сметките за сигурност). Balancing account wrongly used. Referring to the account used for adjustments of account balances. Балансирането на сметката е използвано погрешно. Balancing account wrongly used. Балансирането на сметката е използвано погрешно. Same to and from account/category. Същото към и от сметката / категория. No data found. Няма намерени данни. Information Информация Unrecognized date format. Неразпознат формат за дата. Specify Format Определете Format The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. Форматът на дати и / или цифри в CSV файла е двусмислен. Моля, изберете правилния формат. Date format: Формат на датата: Value format: Стойност на формата: ImportQIFDialog Import QIF file Въведи QIF файла File Selection Избор на файл Select a QIF file to import. When you click next, the file be analysed and you might need to answer some questions about the format of the file. Изберете QIF файла, за въвеждане. Когато натиснете Напред, файлът ще бъде анализиран и може да се наложи да отговорите на няколко въпроса за формата на файла. File: Файл: Local Definitions Местни определения Unknown elements where found in the QIF file. It is possible that this is because of localized type names. Please map them to the correct standard names. Неизвестни елементи, които са установени в QIF файла. Възможно е, че това е така, защото са локализирани типови имена. Моля, да ги съпоставите с правилните стандартни имена. Local Text Локален текст Standard Text Стандартен текст Select standard text: Избери стандартен техт: Date Format Формат на датата The date format in the QIF file is ambiguous. Please select the correct format. Форматът на датата във файла QIF е двусмислен. Моля, изберете правилния формат. Date format: Формат на датата: Default Account Сметка по подразбиране Could not find any account definitions in the QIF file. Please select a default account. It is also possible that this is caused by a localized opening balance text. Не можаха да бъдат намерени определения за сметката в QIF файла. Моля, изберете акаунта по подразбиране. Възможно е също така, това да е причинено от локален текст за началното салдо. Default account: Сметка по подразбиране: Opening balance text: Начален баланс: Descriptions Описание Transactions in QIF files does not have any specific description property. You are therefore given the option to choose how the description of imported transactions will be set. Транзакциите във файловете QIF не разполагат с конкретни описание на собствеността. Ето защо това ви дава възможност да изберете как ще бъде създадено описанието на въведените транзакции. Subcategories as: Подкатегории като: Description Описание Transactions in QIF files does not have any specific description property. You are therefore given the option to choose how the description of imported transactions will be set. Referring to generic description Транзакциите във файловете QIF не разполагат с конкретни описание на собствеността. Ето защо това ви дава възможност да изберете как ще бъде създадено описанието на въведените транзакции. Category Категория Ignore игнорирай Payee as: Получателя на плащането като: Payee Получател Memo as: Отбележи като: Comments Коментари Priority: Приоритет: Subcategory/Payee/Comments Подкатегория /Бенефициент/Коментари Payee/Subcategory/Comments Бенефициент/Подкатегория /Коментари Subcategory/Comments/Payee Подкатегория/Коментари /Бенефициент Payee/Comments/Subcategory Бенефициент/Коментари /Подкатегория Comments/Subcategory/Payee Коментари /Подкатегория/Бенефициент Comments/Payee/Subcategory Коментари /Бенефициент/Подкатегория Import File Импортиране на файл No (further) issues were found. Press finish to import the selected QIF file. Няма повече проблеми. Изберете край за да импортирате избрания QIF файл. Ignore duplicate transactions Игнорира дублирани транзакции Error Грешка A file must be selected. Файлът трябва да бъде избран. Selected file is a directory. Избраният файл е директория. Selected file does not exist. Избраният файл не съществува. Couldn't open %1 for reading. Не мога да отворя %1 за четене. Error reading %1. Грешка при четенето на %1. Unknown Неизвестен Account Сметка Bank Банка Cash Пари в брой Cat (Category) Cat (Категория) CCard (Credit Card) CCard (кредитна карта) Invst (Investment) Invst (Инвестиции) Oth A (Other Assets) Oth A (Други активи) Oth L (Other Liabilities) Oth L (Други активи) Security Сигурност Other Друг Unrecognized date format. Неразпознат формат за дата. Successfully imported %n transaction(s). Успешно въведени %n транзакция. Успешно въведени %n транзакции. Successfully imported %n account(s). Успешно внесена %n сметка. Успешно внесени %n сметки. Successfully imported %n category/categories. Успешно внесена %n категория. Успешно внесени %n категории. %n duplicate transaction(s) was ignored. %n дубликат на транзакцията беше игнориран. %n дубликати на транзакцията бяха игнорирани. Failed to import %n transaction(s). Неуспех за внос на %n транзакция. Неуспех за внос на %n транзакции. %n security/securities were not imported. Financial security (e.g. stock, mutual fund) %n ценни книжа не са били импортирани. %n ценни книжа не са били импортирани. %n security transaction(s) were not imported. Financial security (e.g. stock, mutual fund) %n транзакция с ценни книжа не е била импортирана. %n транзакции с ценни книжа не са били импортирани. %n security/securities were not imported. %n обезпечение не е бил внесено. %n обезпечения не са били внесени. %n security transaction(s) were not imported. %n обезпечение на транзакцията не е било внесено. %n обезпечения на транзакциите не са били внесени. Information Информация Income Dividend: %1 Дивидент: %1 Reinvested dividend: %1 Реинвестирани дивиденти: %1 LedgerDialog Account: Сметка: Edit Account… Редактиране на сметка… Export… Експортиране… Print… Отпечатай… Reconcile Accounting context Контекст сметки Съгласуване Mark all as reconciled Accounting context Счетоводен контекст Маркирай всички като съгласувани Change: Accounting context Счетоводен контекст Промяна: R Header for account reconciled checkbox column Date Дата Type Вид Description Описание Name Име Description Generic Description Описание Account/Category Сметка/Категория Deposit Депозит/внос Withdrawal Изтегляне Balance Баланс Balance Account balance Cалдо Payee/Payer Получатели/платци Tags Етикети Comments Коментари Deposit Money put into account Депозит/вноска Withdrawal Money taken out from account Теглене Balance Noun. Balance of an account Cалдо New Нов Edit… Редактиране… Delete Изтриване Join… join transactions together Присъединете се към… Split Up split up joined transactions Разделяне на Edit Transaction(s)… Редактиране на транзакцията(ите)… Join Transactions… Присъединете се към транзакциите… Split Up Transaction Разделяне на транзакциите Remove Transaction(s) Премахване на транзакцията (ите) Mark as reconciled Маркиране като съгласувана Reconciled: %1 (%2) Accounting context Счетоводен контекст Съгласуване: %1 (%2) Book value: %1 (%2) Accounting context Счетоводен контекст Счетоводна стойност: %1 (%2) Error Грешка Invalid date. Невалидна дата. Opening date is after closing date. Началната дата е след крайната дата. Closing date is before opening date. Крайната дата е преди началната дата. Empty transaction list. Празен списък транзакции. Couldn't open file for writing. Не мога да отворя файла за писане. Error while writing file; file was not saved. Грешка при запис на файл; файлът не е запазен. Ledger Главна счетоводна книга Transactions for %1 Транзакции за %1 Select Time Period Изберете времеви период From: От: To: До: To date is before from date. Крайната дата е преди началната дата. Balance change: Account balance Счетоводен контекст Балансова промяна Delete transactions? Изтриване на транзакциите? Are you sure you want to delete all (%1) selected transactions? Сигурен ли сте, че искате да изтриете всички (%1), избрани транзакции? Cannot set the value of security transactions using the dialog for modifying multiple transactions. Financial security (e.g. stock, mutual fund) Не може да се зададе стойност на сделки с ценни книжа, използвайки диалогов прозорец за промяна на много транзакции. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name); Financial security (e.g. stock, mutual fund) Не може да се промени описанието на дивидентите и сделките с ценни книжа. Cannot change payer of dividends and security transactions. Financial security (e.g. stock, mutual fund) Не може да се промени платецът на дивидентите и сделки с ценни книжа. Opening balance Account balance Начално салдо Account Balance Adjustment Нагласяне на салдо Current balance: Account balance Салдо на сметка: Average balance: Account balance Средно салдо: Account Balancing Balancing of an account Балансиране на сметката Balancing Balancing of an account балансиране Balancing Account balancing балансиране Cannot set the value of security transactions using the dialog for modifying multiple transactions. Не може да се зададе стойност на сделки с ценни книжа, използвайки диалогов прозорец за промяна на много транзакции. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name) Не може да се промени описанието на дивидентите и сделките с ценни книжа. Cannot change description of dividends and security transactions. Referring to the generic description property Не може да се промени описанието на дивидентите и сделките с ценни книжа. Current debt: Текущ дълг: Total debt reduction: Общо намаляване на дълга: Total interest and fees: Тотал лихва и такса: Number of transactions: Брой транзакции: Cannot change description of dividends and security transactions. Не може да се промени описанието на дивидентите и сделките с ценни книжа. Cannot change payer of dividends and security transactions. Не може да се промени платецът на дивидентите и сделки с ценни книжа. Cannot change date of transactions that are part of a split transaction. Не може да се промени датата на сделките, които са част от разделянето на транзакцията. Initial balance Начален баланс Split Transaction Разделяне на транзакциите Debt Payment Плащане по дълг Ascending order Нарастващ ред Reduction Намаляване Fee Такса Interest Лихва Income Приход Repayment Върната сума Expense Разход Opening balance: Accounting context Счетоводен контекст Начално салдо: Closing balance: Accounting context Счетоводен контекст Крайно салдо: Description Transaction description property (transaction title/generic article name) Описание Cannot change description of dividends and security transactions. Referring to the Transaction description property (transaction title/generic article name) Не може да се промени описанието на дивидентите и сделките с ценни книжа. Refund Обезщетение Balancing балансиране Transfer Прехвърляне LinksWidget Remove Link All Remove Премахване MultiItemListViewItem Dividend Дивиденти Income Приход Repayment Върната сума Expense Разход Refund Обезщетение Securities Purchase Financial security (e.g. stock, mutual fund) Покупка ценни книжа Securities Sale Financial security (e.g. stock, mutual fund) Продажба ценни книжа Account Balance Adjustment Нагласяне на салдо Account Balancing Balancing of an account Балансиране на сметката Balancing Balancing of an account балансиране Security Buy Покупка споръчител Security Sell Продажба с поръчител Balancing балансиране Transfer Прехвърляне MultipleTransactionsEditDialog Modify Transactions Промяна на транзакции Description: Описание: Name: Име: Description: Transaction description property (transaction title/generic article name) Описание: Amount: Сума: Income: Приход: Cost: Разходи: Date: Дата: Category: Категория: Payer: Платец: Payee: Получател: New Income Category Нова категория доходи New Expense Category Нова категория разходи New Income Category… Нова категория доходи … New Expense Category… Нова категория разходи… Error Грешка No income category available. Няма свободна категория доходи. No expense category available. Няма свободна категория разходи. Invalid date. Грешна дата. OverTimeChart Save As… Запис като… Print… Печат… Source: Източник: Incomes and Expenses Доходи и Разходи Profits Печалби Expenses Разходи Incomes Приходи All Categories Combined Всички категории комбинирани All Descriptions Combined Всички описания комбинирани Theme: Тема: Chart type: Вид графика: Line Chart Графика линии Vertical Bar Chart Вертикални барове Horizontal Bar Chart Хоризонтални барове Stacked Bar Chart Default По подразбиране Tags Етикети All Accounts Combined Всички сметки комбинирано All Accounts Split Всички сметки разделени All Subcategories and Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Комбинирани всички подкатегории и описания All Descriptions Split Referring to the transaction description property (transaction title/generic article name) Всички описания разделени No description Referring to the transaction description property (transaction title/generic article name) Няма описание All Payees/Payers Split Разделяне на всички получатели/платци No payee/payer Няма получател/платец All Tags Split Всички етикети разделени Other tags Други етикети Other payees/payers Дриги получатели/платци Other descriptions Referring to the transaction description property (transaction title/generic article name) Дриги описания Profits, %1 Печалби, %1 Assets Активи All Descriptions Combined Referring to the generic description property Всички описания комбинирани Assets and Liabilities Активи и Пасиви All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Всички описания комбинирани All Payees/Payers Combined Всички получатели/платци комбинирано All Accounts Всички сметки Start date: Начална дата: End date: Крайна дата: Value: Стойност: Annual total Годишен тотал Monthly total Месечно общо Daily average Средно дневно Quantity Количество Average value Средна стойност All Payers Combined Всички платци комбинирано All Payees Combined Всички получатели комбинирано All Subcategories Split Всички подкатегория - разделени All Descriptions Split Referring to the generic description property Разделяне на всички описания No description Referring to the generic description property Няма описание Value Стойност Includes budgeted transactions Включва бюджетни транзакции Incomes − Expenses, %1 Приходи − Разходи, %1 Incomes − Expenses Приходи − Разходи Incomes & Expenses Приходи & Разходи Incomes: %1 Приходи: %1 Expenses: %1 Разходи: %1 %2: %1 Incomes: %2, %1 Приходи: %2, %1 Expenses: %2, %1 Разходи: %2, %1 %3: %2, %1 %2, %1 Incomes: %3, %2, %1 Приходи: %3, %2, %1 Expenses: %3, %2, %1 Разходи: %3, %2, %1 %4: %3, %2, %1 no payee/payer няма получател/платец %3, %2, %1 Other accounts Други сметки %1 Value: %2 Date: %3 %1 Стойност: %2 Дата: %3 MMMM yyyy Month and year All Descriptions Split Разделяне на всички описания All Payers Split Разделяне на всички платци All Payees Split Разделяне на всички получатели No description Няма описание No payer Няма платец No payee Няма получател на пари All Categories Split Разделяне на всички категории Error Грешка Invalid date. Грешна дата. Couldn't open file for writing. Не мога да отворя файла за писане. Error while writing file; file was not saved. Грешка при запис на файл; файлът не е запазен. Other payees Дриги получатели Other payers Дриги платци Value (%1) Стойност (%1) Profit (%1) Печалба (%1) Income (%1) Доходи (%1) Cost (%1) Разход (%1) Time Време %1/%2 %1: Category; %2: Payee/Payer All Descriptions Combined Referring to the Transaction description property (transaction title/generic article name) Всички описания комбинирани All Descriptions Split Referring to the Transaction description property (transaction title/generic article name) Разделяне на всички описания No description Referring to the Transaction description property (transaction title/generic article name) Няма описание Daily average value Средно дневна стойност Daily average profit Средно дневна печалба Daily average income Средно дневен приход Daily average cost Средно дневен разход Average income Сренен приход Average cost Среден разход Annual value Годишна стойност Annual profit Годишна печалба Annual income Годишен приход Annual cost Годишен разход Monthly value Месечна стойност Monthly profit Месечна печалба Monthly income Месечен приход Monthly cost Месечен разход Includes scheduled and budgeted transactions Включва планираните и бюджетни транзакции Includes scheduled transactions Включва планираните транзакции Incomes, %2: 1 Приходи, %2: 1 Tags, %1 Етикети, %1 Value: %1 Стойност: %1 Assets & Liabilities Активи & Пасиви Change: %1 Смени: %1 Excluding any profits or losses in trading of security shares Financial security (e.g. stock, mutual fund) Изключване на печалби и загуби от тъгвоцията с ценни книжа Incomes & Expenses, %1 Приходи & Разходи, %1 Incomes, %1 Приходи, %1 Expenses, %1 Разходи, %1 Incomes, %2: %1 Приходи, %2: %1 Expenses, %2: %1 Разходи, %2: %1 Incomes, %3: %2, %1 Приходи, %3: %2, %1 Expenses, %3: %2, %1 Разходи, %3: %2, %1 Incomes, %4: %3, %2, %1 Приходи, %4: %3, %2, %1 Expenses, %4: %3, %2, %1 Разходи, %4: %3, %2, %1 Liabilities Задължения no payer никакъв платец %1/%2 %1: Description; %2: Payee/Payer %1/%2 %1: Description; %2: Payer %1/%2 no payee няма получател %1/%2 %1: Description; %2: Payee %1/%2 OverTimeChartDialog Chart Диаграма OverTimeReport Save As… Запис като… Print… Печат… Source: Източник: Profits Печалби Expenses Разходи Incomes Приходи Assets & Liabilities Активи & Пасиви Tags Етикети All Categories Combined Всички категории комбинирани All Descriptions Combined Всички описания комбинирани Columns: Колони: Categories Категории Total: Общо: Value Стойност Daily ежедневно Monthly Месечно Yearly Годишно Quantity Количество Average value Средна стойност No description Няма описание All Descriptions Combined Referring to the generic description property Всички описания комбинирани No description Referring to the generic description property Няма описание All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Всички описания комбинирани All Accounts Всички сметки No description Referring to the transaction description property (transaction title/generic article name) Няма описание Error Грешка Couldn't open file for writing. Не мога да отворя файла за писане. Error while writing file; file was not saved. Грешка при запис на файл; файлът не е запазен. Average Profit Средна печалба Incomes, %1 Приходи, %1 Average Income Среден доход Expenses, %1 Разходи, %1 Average Cost Средна цена Incomes, %2: %1 Приходи, %2: %1 Incomes: %1 Приходи: %1 Expenses, %2: %1 Разходи, %2: %1 Expenses: %1 Разходи: %1 Incomes, %3: %2, %1 Приходи, %3: %2, %1 Incomes: %2, %1 Приходи: %2, %1 Expenses, %3: %2, %1 Разходи, %3: %2, %1 Expenses: %2, %1 Разходи: %2, %1 Change: %1 Noun, how much the account balance has changed Промяна: %1 Deposit Money put into account Депозит Withdrawal Money taken out from account Теглене Change Noun, how much the account balance has changed Промяна Value: %1 Стойност: %1 %2: %1 %1 %1 Average Value Средна стойност %3: %2, %1 %2, %1 Year Година Month Месец Assets Активи Deposit Депозит Withdrawal Теглене Liabilities Задължения Daily Average Средно Дневно Monthly Average Средно на месец Yearly Average Средно годишно Subtotal Междинна сума Total Общо Includes scheduled transactions Включва планираните транзакции Adjusted for the average month / year (%1 / %2 days) Коригирано за средно месечно / годишно (%1 / %2 дни) All Categories Combined Referring to the generic description property Всички категории комбинирани OverTimeReportDialog Report Отчет QApplication Start with expenses list displayed Започнете със списъка на разходите показан на екрана Start with incomes list displayed Започнете със списъка на доходите показан на екрана Start with transfers list displayed Започнете със списъка на трансферите показан на екрана Synchronize file Синхронизационен файл Document to open Отваряне на документ %1 is already running. %1 вече работи. QObject Transfer Прехвърляне Dividend Дивиденти Income Приход Expense Разход Securities Purchase Financial security (e.g. stock, mutual fund) Покупка на ценни книжа Securities Sale Financial security (e.g. stock, mutual fund) Продажба на ценни книжа Security Buy Покупка споръчител Security Sell Продажба с поръчител Debt Payment Плащане по дълг Split Transaction Разделяне на транзакция RecurrenceEditWidget Enable recurrence Разрешаване на повторение Recurrence Rule Правило за повторение Daily ежедневно Weekly Седмично Monthly Месечно Yearly Годишно Recur every Повтаряй всеки day(s) ден/дни week(s) on: седмица(и) в: month(s), after the start month месец (и),след началото на месеца Recur on the Повтаряй на 1st 1-ви 2nd 2-ри 3rd 3-ти 4th 4-ти 5th 5-ти 6th 6-ти 7th 7-ми 8th 8-ми 9th 9-ти 10th 10-ти 11th 11-ти 12th 12-ти 13th 13-ти 14th 14-ти 15th 15-ти 16th 16-ти 17th 17-ти 18th 18-ти 19th 19-ти 20th 20-ти 21st 21-ви 22nd 22-ри 23rd 23-ти 24th 24-ти 25th 25-ти 26th 26-ти 27th 27-ми 28th 28-ми 29th 29-ти 30th 30-ти 31st 31-ви Last Последен 2nd Last 2-ия последен 3rd Last 3-ия последен 4th Last 4-ия последен 5th Last 5-ия последен day ден possibly on weekend по възможност през уикенда but before weekend но преди уикенда but after weekend но след уикенда nearest weekend day Най-близкия дей от уикенда year(s), after the start year година (и), след началната година on nearest weekday Най-близкия ден от седмицата Recur on day part before XXX of 'Recur on day XXX of month YYY' Повторение на ден of part between XXX and YYY of 'Recur on day XXX of month YYY' от On the Part before NNN in 'Recur on the NNN. WEEKDAY of MONTH' На of part between WEEKDAY and MONTH in 'Recur on NNN. WEEKDAY of MONTH' от Recur on day # Повторение на ден # of the year part after NNN of 'Recur on day #NNN of the year' от годината Range… Диапазон… Occurrences/Exceptions… Изключения/възникващи… Exceptions… Изключения… Error Грешка No day of week selected for weekly recurrence. Няма ден от седмицата избран за седмичното повторение. Selected day will never occur with selected frequency and start date. Избраният ден никога няма да настъпи с избраната честота и начална дата. Selected day does not exist in selected month. Избраният ден не съществува в избрания месец. RefundDialog Repayment Върната сума Refund Обезщетение Date: Дата: Cost: Разходи: Income: Приход: Quantity returned: Върнато количество: Account: Сметка: Quantity: Количество: Payee: Получател: Payer: Платец: Comments: Коментари: Link Link the transactions together Join Join the transactions together Събери Error Грешка Zero value not allowed. Нулева стойност, не се допуска. Invalid date. Грешна дата. SecurityBuy Security: %1 (bought) Ценна книга: %1 (закупена) Security: %1 (bought) Financial security (e.g. stock, mutual fund) Ценна книга: %1 (закупена) SecuritySell Security: %1 (sold) Ценна книга: %1 (продадена) Security: %1 (sold) Financial security (e.g. stock, mutual fund) Ценна книга: %1 (продадена) SecurityTransactionsDialog Transactions for %1 Транзакции за %1 Date Дата Type Вид Value Стойност Shares Financial shares Акции Shares Bought Financial shares Купени акции Shares Bought (Recurring) Financial shares Купени акции (повтарящи се) Dividend (Recurring) Дивиденти (повтарящи се) Dividend (Scheduled) Дивиденти (по график) Reinvested Dividend (Recurring) Реинвестирани дивиденти (повтарящи се) Reinvested Dividend (Scheduled) Реинвестирани дивиденти (по график) Shares Bought Fincancial shares Изкупени акции Shares Sold Financial shares Продадени акции Shares Sold (Exchanged) Shares of one security directly exchanged for shares of another; Financial shares Акции Продадени (търгувани) Shares Bought (Exchanged) Shares of one security directly exchanged for shares of another; Financial shares Купени акции (търгувани) Shares Bought (Recurring) Fincancial shares Изкупени акции (повтарящи се) Shares Sold (Recurring) Financial shares Акции Продадени (повтарящи се) Shares Bought (Scheduled) Financial shares Изкупени акции (по график) Shares Sold (Scheduled) Financial shares Акции Продадени (по график) Shares Акции Edit… Редактиране… Delete Изтриване Shares Bought Изкупени акции Shares Sold Изкупени акции Dividend Дивиденти Reinvested Dividend Реинвестирани дивиденти Shares Sold (Traded) Акции Продадени (търгувани) Shares Bought (Traded) Изкупени акции (търгувани) Shares Bought (Recurring) Изкупени акции (повтарящи се) Shares Sold (Recurring) Акции Продадени (повтарящи се) Shares Bought (Scheduled) Изкупени акции (по график) Shares Sold (Scheduled) Акции Продадени (по график) Recurring Dividend Повтарящи се дивиденти Scheduled Dividend Планирани дивиденти SplitListViewItem Dividend Дивиденти Income Приход Repayment Върната сума Expense Разход Refund Обезщетение Security Buy Покупка споръчител Security Sell Продажба с поръчител Balancing балансиране Transfer Прехвърляне TagButton no tags няма етикети TagMenu New tag… Нов етикет... New Tag Нов етикет Tag: Етикет: TransactionEditDialog Edit Expense Редактиране на разходи Edit Dividend Редактиране на дивиденти Edit Income Редактиране на приходи Edit Transfer Редактиране на трансфери Edit Securities Purchase Financial security (e.g. stock, mutual fund) Редактиране на покупка на ценни книжа Edit Securities Sale Financial security (e.g. stock, mutual fund) Редактиране на продажба на ценни книжа Edit Reinvested Dividend Редакция Реинвестиран Дивидент Edit Securities Bought Редактиране на покупка на ценни книжа Edit Securities Sold Редактиране на продажба на ценни книжа TransactionEditWidget Security: Ценна книга: Cost: Разходи: Income: Приход: Shares bought: Изкупени акции: Shares sold: Продадени акции: All Всички Price per share: Цена за една акция: Date: Дата: Description: Описание: Name: Име: Amount: Сума: Withdrawal: Money taken out from account Теглене: New Security… Financial security (e.g. stock, mutual fund) Ценни книжа (бонове, акции) Нова ценна книга... Shares added: Financial shares Добавени дялове: Set security share value Стойност на дяла Total value: Обща стойност: Deposit: Money put into account Внасяне: Downpayment: Първоначална вноска: Quantity: Количество: From: От: To: До: Category: Категория: To account: В сметката: Payer: Платец: Payer of parent split transaction From account: От сметката: Downpayment account: Сметка за първоначална вноска: Payee: Получател: Payee of parent split transaction Lender: Заемодател: Tags: Етикети: Associated file: Асоцииран файл: Select a file Избери файл Open the file Отвори файл Comments: Коментари: Related to: Label for linked transactions Връзки: New Security Financial security (e.g. stock, mutual fund) Нови ценни книги No security available. Financial security (e.g. stock, mutual fund) Няма налична ценна книга. New Tag Нов етикет Tag: Етикет: New Account Нова сметка New Income Category Нова категория доходи New Expense Category Нова категория разходи New Income Category… Нова категория доходи … New Expense Category… Нова категория разходи… Security: Financial security (e.g. stock, mutual fund) Ценна книга: Shares bought: Financial shares Купени акции: Shares sold: Financial shares Продадени акции: Price per share: Financial shares Цена за една акция: Description: Transaction description property (transaction title/generic article name) Описание: Transaction title/generic article name Заглавие на транзакцията Number of items included in the transaction. Entered cost is total cost for all items. Брой артикули включени в транзакцията. Въведената стойност е цялата стойност на всичко. Error Грешка No suitable account available. Няма подходяща сметка на разположение. No income category available. Няма свободна категория доходи. No suitable account or income category available. Няма свободна подходяща сметка или категория доходи. No expense category available. Няма свободна категория разходи. No security available. Няма свободен поръчител. Invalid date. Грешна дата. Cannot transfer money to and from the same account. Не можете да прехвърляте пари от една и съща сметка. Downpayment must be less than total cost. Първоначалната вноска трябва да е по-малка от цялата сума. Cannot create a regular transfer to/from a securities account. Не може да се създаде редовен трансфер до / от сметката за ценни книжа. Cannot create a regular income to a securities account. Не може да се създаде редовен трансфер до сметка за ценни книжа. Zero shares not allowed. Нулеви акции не са разрешени. Zero value not allowed. Нулева стойност, не се допуска. Zero price per share not allowed. Нулева цена на акция не е разрешена. Cannot create a regular expense from a securities account. Не може да се създаде редовен разход от сметката за ценни книжа. Loan for %1 Заем за %1 TransactionFilterWidget From: От: To: До: Min amount: Мин сума: Max amount: Макс сума: Category: Категория: To account: В сметката: Min income: Мин доход: Max income: Макс доход: From account: От сметката: Min cost: Мин цена: Max cost: Макс цена: Tag: Етикет: Description: Описание: Description: Transaction description property (transaction title/generic article name) Описание: Payer: Платец: Payee: Получател: Include Включително Exclude Изключване Exact match Точно съвпадение Exclude subcategories Изключи подкатегориите Clear Изчистване All Всички Error Грешка Invalid date. Грешна дата. To date is before from date. Към настоящия момент е преди считано от датата. From date is after to date. Към настоящия момент е след датата. TransactionListWidget Date Дата Description Описание Cost Цена Category Категория From Account От сметката Payee Получател Tags Етикети Income Приход To Account В сметката Payer Платец Amount Сума From От To До Comments Коментари Add Добавяне Apply Прилагане Delete Изтриване * Part of <a href="%1">split transaction</a> * Част от < href="%1">разделянето на транзакцията</a> Expense Разход Transfer Прехвърляне New/Edit %1 Нови/Редактиране %1 Name Име Description Generic Description Описание Description Transaction description property (transaction title/generic article name) Описание New/Edit Expense Нови/Редактиране разходи New/Edit Income Нови/Редактиране приход New/Edit Transfer Нови/Редактиране трансфер Filter Филтър Quantity: Количество: Total: Общо: Average: Средно: Clear Изчистване Cost: Разходи: Monthly: Месечно: Sort by creation time Сортирай по времен на създаване Expenses Разходи Incomes Приходи Transfers Трансфери Quantity Количество Right align Подравнете вдясно Total cost: Обща цена: Total income: Общо доходи: Total amount: Обща сума: Monthly average: Средно на месец: Error Грешка Cannot set the value of security transactions using the dialog for modifying multiple transactions. Financial security (e.g. stock, mutual fund) Не може да се зададе стойност на сделки с ценни книжа, използвайки диалогов прозорец за промяна на много транзакции. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name); Financial security (e.g. stock, mutual fund) Не може да се промени описанието на дивидентите и сделките с ценни книжа. Cannot change payer of dividends and security transactions. Financial security (e.g. stock, mutual fund) Не може да се промени платецът на дивидентите и сделки с ценни книжа. Cannot change date of transactions that are part of a split transaction, unless all individual transactions are selected. Не може да се промени датата на транзакциите които са част от разделена транзакция, освен ако не се изберат всички прилежащи транзакции. Cannot set the value of security transactions using the dialog for modifying multiple transactions. Не може да се зададе стойност на сделки с ценни книжа, използвайки диалогов прозорец за промяна на много транзакции. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name) Не може да се промени описанието на дивидентите и сделките с ценни книжа. Cannot change date, description, expense category or payee of transactions that are part of a debt payment using the dialog for modifying multiple transactions. Referring to the transaction description property (transaction title/generic article name) Не може да се променя дата, описание, категория или платец на транзакции които са част от дългово плащане чрез диалога за модификация на множество транзакции. Cannot change description of dividends and security transactions. Referring to the Transaction description property (transaction title/generic article name) Не може да се промени описанието на дивидентите и сделките с ценни книжа. Cannot change description of dividends and security transactions. Referring to the generic description property Не може да се промени описанието на дивидентите и сделките с ценни книжа. Cannot change date or payee/payer of transactions that are part of a split transaction. Не може да се сменя датата или бенефициентите на транзакции които са част от разделена транзакция. Cannot change description of dividends and security transactions. Не може да се промени описанието на дивидентите и сделките с ценни книжа. Cannot change payer of dividends and security transactions. Не може да се промени платецът на дивидентите и сделки с ценни книжа. Cannot change date of transactions that are part of a split transaction. Не може да се промени датата на сделките, които са част от разделянето на транзакцията. Delete transactions? Изтриване на транзакциите? Are you sure you want to delete all (%1) transactions in the selected split transaction? Сигурен ли сте, че искате да изтриете всички (%1) сделки в избраната разделена транзакция? Join as multiple accounts/payments? Do you wish join the selected expenses as an expense with multiple accounts/payments? Do you wish join the selected incomes as an income with multiple accounts/payments? Are you sure you want to delete all (%1) selected transactions? Сигурен ли сте, че искате да изтриете всички (%1), избрани транзакции? * Part of split transaction * Част от разделянето на транзакцията * Part of split (%1) * Част от разделянето (%1) ** Recurring (editing occurrence) ** Повторение (редактирени на събитието) Modify… Променяне… Edit… Редактиране… currencies.xml U.S. Dollar Щатски долар Japansese Yen Японска йена Bulgarian Lev Български лев Czech Koruna Чешка крона Danish Krone Датска крона British Pound Британска лира Hungarian Forint Унгарски флоринт Polish Zloty Полска злота Romanian New Leu Нова румънска лея Swedish Krona Шведска крона Swiss Franc Швейцарски франк Norwegian Krone Норвежка крона Croatian Kuna Хърватска куна Russian Ruble Руска рубла Turkish New Lira Нова турска лира Australian Dollar Австралийски долар Brazilian Real Бразилски реал Canadian Dollar Канадски долар Chinese Yuan Renminbi Китайски ренминби юан Hong Kong Dollar Хонконгски долар Indonesian Rupiah Индонезийска рупия Israeli New Sheqel Израелски шекел Indian Rupee Индийска рупия South Korean Won Южнокорейски вон Mexican Peso Мексиканско песо Malaysian Ringgit Малайзийски рингит New Zeeland Dollar Новозеландски долар Philippine Peso Филиписнко песо Singapore Dollar Сингапурски долар Thai Baht Тайландски Бат South African Rand Южноафрикански ранд Eqonomize-1.5.3/translations/eqonomize_cs.ts000066400000000000000000017376521416454732000213050ustar00rootroot00000000000000 Balancing Rozvaha Couldn't open %1 for reading %1 nelze přečíst Not a valid Eqonomize! file (XML parse error: "%2" at line %3, col %4) Neplatný Eqonomize! soubor (chyba XML: "%2" na řádku %3, sloupec %4) Invalid root element %1 in XML document Neplatný kořenový prvek %1 v dokumentu XML File is a directory Soubor je adresář Couldn't open file for writing Soubor nelze otevřít pro zápis Error while writing file; file was not saved Během zápisu došlo k chybě; soubor nebyl uložen From Od To Do Source: Zdroj: All Expenses Všechny výdaje All Incomes Všechny příjmy All Accounts Všechny účty Expenses: %1 Výdaje: %1 Incomes: %1 Příjmy: %1 Invalid date. Neplatné datum. To date is before from date. Datum do je před datumem od. From date is after to date. Datum od je před datumem do. The selected file already exists. Would you like to overwrite the old copy? Vybraný soubor již existuje. Chcete ho přepsat? You selected a directory! Vybrali jste adresář! Couldn't open file for writing. Soubor nelze otevřít pro zápis. Error while writing file; file was not saved. Chyba během zápisu souboru; soubor nebyl uložen. No description Bez popisu All Categories Všechny kategorie Descriptions for Popis pro Payees/payers for Příjemci/plátci pro Period: Období: Columns: Sloupce: Value Hodnota Daily Denně Monthly Měsíčně Yearly Ročně Quantity Počet Average value Průměrná hodnota All descriptions Všechny popisy All payees Všichni příjemci All payers Všichni plátci No payee Žádný příjemce No payer Žádný plátce Expenses: %2, %1 Výdaje: %2, %1 Incomes: %2, %1 Příjmy: %2, %1 Incomes & Expenses Příjmy & výdaje %1 (%2&ndash;%3) html format; %1: title; %2: from date; %3: to date %1 (%2&ndash;%3) %1 (to %2) html format; %1: title; %2: to date %1 (do %2) Category Kategorie Cost Cena Income Příjem Daily Average Denní průměr Monthly Average Měsíční průměr Yearly Average Roční průměr Average Cost Průměrná cena Average Income Průměrný příjem Average Value Průměrná hodnota Total Celkem Total incomes Příjmy celkem Total expenses Výdaje celkem Total (Profits) Celkem (zisky) Expense Výdaj Transfer Převod Security Buy Nákup cenných papírů Security Sell Prodej cenných papírů Recurrence Opakování New Expense Nový výdaj New Dividend Nová dividenda New Income Nový příjem New Transfer Nový převod New Security Buy Nový nákup cenných papírů New Security Sell Nový prodej cenných papírů Edit Expense Upravit výdaj Edit Dividend Upravit dividendu Edit Income Upravit příjem Edit Transfer Upravit převod Edit Securities Bought Upravit nákup cenných papírů Edit Securities Sold Upravit prodej cenných papírů Dividend Dividenda Repayment Splátka Refund Úhrada Split Transaction Rozdělená transakce Description: Popis: Date: Datum: Account: Účet: Transactions: Transakce: Type Typ Description Popis Account/Category Účet/Kategorie Payment Platba Deposit Vklad New Nový New Expense… Nový výdaj… New Income… Nový příjem… New Deposit… Nový vklad… New Withdrawal… Nový výběr… Security Shares Sold… Cenné papíry prodané.. New Dividend… Nová dividenda… Edit… Upravit… Total value: Celková hodnota: No suitable account available. Vhodný účet není k dispozici. Future dates is not allowed. Budoucí datumy nejsou povoleny. A split must contain at least two transactions. Pro rozdělení potřebujete nejméně dvě transakce. Cannot transfer money to and from the same account. Peníze nelze převést na stejný účet. Cost: Cena: Income: Příjem: Quantity: Počet: Comments: Poznámky: Reinvested Dividend Reinvestované dividendy Security: Cenný papír: Shares added: Podíly přidané: Security Trade Obchod cenným papírem From security: Z cenného papíru: Shares moved: Přesunuté podíly: All Vše To security: K cennému papíru: Shares received: Podíly přijaté: Value: Hodnota: No other security available for trade in the account. Na účtu už není žádný cenný papír pro obchodování. Selected to and from securities are the same. Pro a od jsou stejné. Zero shares not allowed. Nulové podíly nejsou povoleny. Zero value not allowed. Nulová hodnota není povolena. Quotations Kurzy Date Datum Price per Share Cena za podíl Quotations for %1 Kurz pro %1 The following transactions was scheduled to occur today or before today. Confirm that they have indeed occurred (or will occur today). Následující transakce byly naplánovány na dnešní nebo dřívější datum. Potvrďte, že opravdu proběhly (nebo dnes proběhnou). Amount Množství Postpone… Odložit… Can only postpone to future dates. Odložit lze pouze na budoucí datum. Transactions for %1 Transakce pro %1 Shares Podíly Shares Bought Podíly koupené Shares Sold Podíly prodané Shares Sold (Traded) Prodej podílů (obchodní) Shares Bought (Traded) Koupené podíly (obchodované) Shares Bought (Recurring) Koupené podíly (opakované) Shares Sold (Recurring) Prodané podíly (opakované) Shares Bought (Scheduled) Koupené podíly (plánované) Shares Sold (Scheduled) Prodané podíly (plánované) Recurring Dividend Opakované dividendy Scheduled Dividend Plánované dividendy Type: Typ: Mutual Fund Vzájemný fond Bond Dluhopis Stock Akcie Other Jiný Name: Název: Decimals in Shares: Desetiny v podílech: Initial Shares: Počáteční podíly: Initial quotation: Počáteční kurz: No suitable account or income category available. Neexistuje vhodná kategorie účtů nebo příjmů. Cash Hotovost Current Account Běžný účet Savings Account Spořící účet Credit Card Platební karta Liabilities Dluhy Securities Cenné papíry Initial balance: Počáteční bilance: Default account for budgeted transactions Výchozí účet pro rozpočtové transakce Empty name. Prázdný název. The entered name is used by another account. Tento název už používá jiný účet. Monthly budget: Měsíční rozpočet: The entered name is used by another income category. Tento název už používá jiná kategorie příjmů. The entered name is used by another expense category. Tento název už používá jiná kategorie výdajů. Accounts Účty Accounts & Categories Účty & Kategorie Expenses Výdaje Incomes Příjmy Transfers Převody Schedule Plán Scheduled Transactions Plánované transakce Account / Category Účet / Skupina Remaining Budget (%1) Zbývající rozpočet (%1) Change (%1) Změna (%1) Total (%1) Celkem (%1) %2 of %1 %2 remains of %1 budget %1 ze %2 Includes budgeted transactions Zahrnuje rozpočtové transakce Period Období Select Period Vybrat období Current Month Tento měsíc Current Year Tento rok Current Whole Month Celý tento měsíc Current Whole Year Celý tento rok Whole Past Month Celý minulý měsíc Whole Past Year Celý minulý rok Previous Month Minulý měsíc Previous Year Minulý rok Show partial budget Ukázat částečný rozpočet Edit Budget Upravit rozpočet Budget: Rozpočet: Month: Měsíc: Result previous month: Výsledek minulého měsíce: New Security… Nový cenný papír… New Transaction Nová transakce Set Quotation… Nastavit kurz… Name Název Quotation Kurz Profit Zisk Yearly Rate Roční sazba Account Účet Statistics Period Doba statistiky New Schedule Nový plán Edit Upravit Next Occurrence Další výskyt Comments Komentáře New Security Nový cenný papír Edit Security Upravit cenný papír Profit: Zisk: Rate: Sazba: Are you sure you want to delete the security "%1" and all associated transactions? Opravdu chcete smazat cenný papír "%1" a všechny související transakce? No security available. Žádný cenný papír k dispozici. Set Quotation (%1) Stanovit plán rozpočtu (%1) Price per share: Cena za akcii: Future dates are not allowed. Budoucí datumy nejsou povoleny. Security Transactions Transakce s cennými papíry Ledger Účetní kniha Check Account Ověřit účet Salary Plat Bills Účty Clothing Oblečení Groceries Potraviny Leisure Volný čas Couldn't fetch %1. Nelze přinést %1. Error loading %1: %2. Chyba při spouštění %1: %2. Couldn't open file Soubor nelze otevřít Error saving %1: %2. Chyba při ukládání %1: %2. Couldn't save file Soubor nelze uložit Failed to upload file to %1. Nepodařilo se nahrát soubor do %1. Report Sestava Chart Graf Transaction Schedule Plán transakce Accounts &amp; Categories html format Účty &amp; Kategorie Accounts &amp; Categories (%1&ndash;%2) html format Účty &amp; Kategorie (%1&ndash;%2) Accounts &amp; Categories (to %1) html format Účty &amp; Kategorie (do %1) Change Změna Balance Bilance Budget Rozpočet Remaining Budget Zbývající rozpočet Total Incomes Celkové příjmy Costs Ceny Total Expenses Celkové výdaje Empty expenses list. Prázdný seznam výdajů. Empty incomes list. Prázdný seznam příjmů. Empty transfers list. Prázdný seznam převodů. Empty securities list. Prázdný seznam cenných papírů. Empty schedule list. Prázdný seznam plánů. Export View… Exportovat… Print View… Tisk… Initial Period Počáteční období Remember Last Dates Zapamatovat poslední datumy Import CSV File… Importovat soubor CSV… Import QIF File… Importovat soubor QIF… Export As QIF File… Exportovat jako soubor QIF… Add Account… Přidat účet… New Account… Nový účet… New Income Category… Nová kategorie příjmů… New Expense Category… Nová kategorie výdajů… Balance… Bilance… Show Transactions Ukázat transakce New Transfer… Nový převod… New Split Transaction… Nová rozdělená transakce… Edit Transaction(s) (Occurrence)… Upravit transakce (výskyt)… Edit Occurrence… Upravit výskyt… Edit Schedule (Recurrence)… Upravit plán (opakování)… Edit Schedule… Upravit plán… Remove Transaction(s) (Occurrence) Odstranit transakce (výskyt) Remove Occurrence Odstranit výskyt Delete Schedule (Recurrence) Odstranit plán (opakování) Delete Schedule Smazat plán Edit Split Transaction… Upravit rozdělenou transakci… Remove Split Transaction Odstranit rozdělenou transakci Join Transactions… Spojit transakce… Split Up Transaction Rozdělit transakci Refund… Úhrada… Repayment… Splátka… New Refund/Repayment… Nová úhrada/splátka… Edit Security… Upravit cenný papír… Remove Security Smazat cenný papír Shares Sold… Prodané podíly… Shares Bought… Nakoupené podíly… Dividend… Dividenda… Reinvested Dividend… Reinvestovaná dividenda… Shares Moved… Přesunuté podíly… Edit Quotations… Upravit kurz… Transactions… Transakce… Development Over Time Report… Výkaz časového vývoje… Categories Comparison Report… Výkaz porovnání kategorií… Categories Comparison Chart… Schéma vývoje kategorií… Development Over Time Chart… Schéma časového vývoje… Use Additional Transaction Properties Použít další vlastnosti transakcí Eqonomize! exited unexpectedly before the file was saved and data was lost. Do you want to load the last auto-saved version of the file? Eqonomize! byl nečekaně zavřen bez uložení a data byla ztracena. Přejete si spustit poslední automaticky uloženou verzi souboru? Crash Recovery Obnovení po pádu The current file has been modified. Do you want to save it? Soubor byl změněn. Přejete si ho uložit? Confirm Schedule Potvrdit plán New Account Nový účet New Income Category Nová skupina příjmů New Expense Category Nová kategorie výdajů Balance Account Bilanční účet Book value: Účetní hodnota: Real value: Skutečná hodnota: Edit Account Upravit účet Edit Income Category Upravit kategorii příjmů Edit Expense Category Upravit kategorii výdajů Move transactions? Přesunout transakce? Move to: Přesunout do: The category contains some expenses. What do you want to do with them? Kategorie obsahuje výdaje. Co s nimi chcete udělat? The category contains some incomes. What do you want to do with them? Kategorie obsahuje příjmy. Co s nimi chcete udělat? The account contains some transactions. What do you want to do with them? Účet obsahuje transakce. Co s nimi chcete udělat? The category contains some expenses that will be removed. Do you still want to remove the category? Kategorie obsahuje výdaje, které budou odstraněny. Opravdu chcete kategorii odstranit? Remove Category? Odstranit kategorii? The category contains some incomes that will be removed. Do you still want to remove the category? Kategorie obsahuje příjmy, které budou odstraněny. Opravdu chcete kategorii odstranit? The account contains some transactions that will be removed. Do you still want to remove the account? Účet obsahuje transakce, které budou odstraněny. Opravdu chcete účet odstranit? Remove Account? Odstranit účet? %2 of %1 %1: budget; %2: remaining budget %2 ze %1 %1 (with no budget) %1 (se žádným rozpočtem) %1 (with budget %2) %1 (s rozpočtem %2) Import CSV file Imporovat soubor CSV Transaction Type Selection Výběr typu transakce Expenses and incomes (negative cost) Výdaje a příjmy (záporná cena) Expenses and incomes (separate columns) Výdaje a příjmy (oddělené sloupce) All types Všechny typy File Selection Výběr souboru File: Soubor: First data row: První řádek údajů: Auto Auto Column delimiter: Oddělovač sloupců: Comma Čárka Tabulator Tabulátor Semicolon Středník Space Mezera Columns Specification Popis sloupce Column Sloupec Category: Kategorie: From account: Z účtu: Create missing categories and accounts Vytvořit chybějící kategorie a účty Imports data as expenses. Costs have positive value. Value is the only required column. Importovat údaje jako výdaje. Ceny jsou kladné. Vyžadován pouze sloupec hodnota. Imports data as incomes. Value is the only required column. Importovat údaje jako příjmy. Vyžadován pouze sloupec hodnota. To account: Na účet: Imports data as transfers. Value is the only required column. Importovat údaje jako převody. Vyžadován pouze sloupec hodnota. Amount: Množství: Imports data as expenses and incomes. Costs have negative value. Value and category are both required columns. Importovat údaje jako výdaje a příjmy. Ceny jsou kladné. Vyžadován sloupec hodnota i kategorie. Imports data as expenses and incomes. Costs and incomes have separate columns. Income, cost, and category are all required columns. Importovat údaje jako výdaje a příjmy. Ceny a příjmy jsou v oddělených sloupcích. Vyžadovány sloupce příjem, cena a kategorie. Imports data as expenses, incomes, and transfers. Costs have negative or positive value. Value, to, and from are all required columns. Accounts and categories must be existing. Importovat údaje jako výdaje, příjmy a převody. Ceny jsou kladné nebo záporné. Vyžadovány sloupce pro a od. Účty a kategorie musí existovat. From: Od: To: Do: A file must be selected. Vyberte soubor. Selected file is a directory. Vybraný soubor je adresář. Selected file does not exist. Vybraný soubor neexistuje. Empty delimiter. Prázdný oddělovač. The same column number is selected multiple times. Stejné číslo sloupce je vybráno vícekrát. Selected from account is the same as the to account. Vybrané z účtu je stejné jako na účet. Couldn't open %1 for reading. Nelze otevřít %1 ke čtení. Error reading %1. Chyba při čtení %1. Unable to import any transactions imported. Nelze importovat. Required columns missing. Požadované sloupce chybí. Invalid value. Neplatná hodnota. Empty category name. Prázdný název kategorie. Empty account name. Prázdný název účtu. Unknown category found. Nalezena neznámá kategorie. Unknown account found. Nalezen neznámý účet. Cannot import security transactions (to/from security accounts). Nelze imporotvat transakci s cennými papíry (z/na účet cenných papírů). Balancing account wrongly used. Bilanční účet použit špatně. Same to and from account/category. Stejné do a z účet/kategorie. No data found. Žádná data nenalezena. Unrecognized date format. Neznámý formát datumu. Specify Format Upřesněte formát The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. Formát datumů a/nebo čísel v souboru CSV je nejednoznačný. Prosím vyberte správný formát. Date format: Formát data: Value format: Formát hodnoty: Export… Exportovat… Print… Tisk… Withdrawal Výběr Join… Připojit… Split Up Rozdělit Empty transaction list. Vyprázdnit seznam transakcí. Are you sure you want to delete all (%1) selected transactions? Opravdu chcete smazat všechny (%1) vybrané transakce? Cannot set the value of security transactions using the dialog for modifying multiple transactions. Nelze zadat hodnotu transakce s cenným papírem použitím dialogu pro změnu více transakcí. Cannot change description of dividends and security transactions. Nelze změnit popis dividend a transakcí s cennými papíry. Cannot change payer of dividends and security transactions. Nelze změnit plátce dividend a transakce s cennými papíry. Cannot change date of transactions that are part of a split transaction. Nelze změnit datum transakcí, které jsou součástí rozdělené transakce. Eqonomize! Eqonomize! A personal accounting program Osobní účetní program Start with expenses list displayed Začněte se zobrazeným seznamem výdajů Start with incomes list displayed Začněte se zobrazeným seznamem příjmů Start with transfers list displayed Začněte se zobrazeným seznamem převodů Document to open Dokument k otevření Incomes and Expenses Příjmy a výdaje Profits Zisky All Categories Combined Všechny kategorie kombinované All Descriptions Combined Všechny popisy kombinované All Payees/Payers Combined Všichni plátci/příjemci kombinovaní Start date: Datum zahájení: End date: Datum ukončení: Monthly total Celkem měsíčne Daily average Denní průměr All Payers Combined Všichni plátce kombinovaní All Payees Combined Všichni příjemci kombinovaní All Descriptions Split Rozdělení všech popisů All Payers Split Rozdělení všech plátců All Payees Split Rozdělení všech příjemců All Categories Split Rozdělení všech kategorií Value (%1) Hodnota (%1) Profit (%1) Zisk (%1) Income (%1) Příjem (%1) Cost (%1) Cena (%1) Time Čas no payer Žádný plátce %1/%2 %1: Description; %2: Payer %1/%2 no payee Žádný příjemce %1/%2 %1: Description; %2: Payee %1/%2 Error after saving file; data may not have been saved. Chyba po uložení souboru; údaje možná nebyly uloženy. Average Profit Průměrný zisk Year Rok Month Měsíc Includes scheduled transactions Včetně plánovaných transakcí Adjusted for the average month / year (%1 / %2 days) Nastaveno na průměrný měsíc / rok (%1 / %2 dnů) Subtotal Mezisoučet Unnamed Bez názvu Uncategorized Neroztříděno Import QIF file Importovat soubor QIF Select a QIF file to import. When you click next, the file be analysed and you might need to answer some questions about the format of the file. Vyberte soubor QIF. Po kliknutí na další, bude soubor analyzován a pravděpodobně budete muset odpovědět na otázky týkající se formátu souboru. Local Definitions Místní definice Unknown elements where found in the QIF file. It is possible that this is because of localized type names. Please map them to the correct standard names. Byly nalezeny neznámé prvky v souboru QIF. Možná je to způsobeno místními názvy. Prosím opravte je na běžné názvy. Local Text Místní text Standard Text Běžný text Select standard text: Vyberte běžný název: Date Format Formát datumu The date format in the QIF file is ambiguous. Please select the correct format. Formát datumu v souboru QIF není správný. Prosím vyberte správný formát. Default Account Výchozí účet Could not find any account definitions in the QIF file. Please select a default account. It is also possible that this is caused by a localized opening balance text. V souboru QIF nelze najít žádný účet. Prosím vyberte výchozí účet. Problém může také spočívat v lokalizaci textu otevírané bilance. Default account: Výchozí účet: Opening balance text: Text otevírané bilance: Descriptions Popisy Transactions in QIF files does not have any specific description property. You are therefore given the option to choose how the description of imported transactions will be set. Popis transakcí v souboru QIF nemá typické vlastnosti. Proto máte možnost vybrat, jak bude popis importovaných transakcí nastaven. Subcategories as: Podkategorie jako: Ignore Ignorovat Payee as: Příjemce jako: Payee Příjemce Memo as: Poznámka jako: Priority: Priorita: Subcategory/Payee/Comments Podkategorie/Příjemce/Komentáře Payee/Subcategory/Comments Příjemce/Podkategorie/Komentáře Subcategory/Comments/Payee Podkategorie/Komentáře/Příjemce Payee/Comments/Subcategory Příjemce/Komentáře/Podkategorie Comments/Subcategory/Payee Komentáře/Podkategorie/Příjemce Comments/Payee/Subcategory Komentáře/Příjemce/Podkategorie Unknown Neznámý Bank Banka Cat (Category) Kat (Kategorie) CCard (Credit Card) PKarta (Platební karta) Invst (Investment) Invst (Investice) Oth A (Other Assets) Ost A (Ostatní aktiva) Oth L (Other Liabilities) Ost P (Ostatní pasiva) Security Akcie Export QIF File Exportovat soubor QIF All All accounts Vše Export transaction description as: Exportovat popis transakce jako: Memo Poznámka Subcategory Podkategorie &Import i18n: tag text i18n: file ./eqonomizeui.rc line 5 &Importovat &Accounts i18n: tag text i18n: file ./eqonomizeui.rc line 12 &Účty &Transactions i18n: tag text i18n: file ./eqonomizeui.rc line 24 &Transakce &Securities i18n: tag text i18n: file ./eqonomizeui.rc line 41 &Cenné papíry Stat&istics i18n: tag text i18n: file ./eqonomizeui.rc line 56 Stat&istiky Your names NAME OF TRANSLATORS ,Launchpad Contributions:,Jan Štemberk Your emails EMAIL OF TRANSLATORS ,,stemberkj@seznam.cz Edit Exceptions Upravit výjimky Edit Recurrence Range Upravit rozsah opakování Begins on: %1 Začíná: %1 No ending date Chybí datum ukončení End after Ukončit po occurrence(s) výskyt(y) End on Ukončit End date before start date. Datum ukončení předchází datumu zahájení. Enable recurrence Zapnout opakování Recurrence Rule Pravidlo opakování Weekly Týdně Recur every Opakovat každých day(s) den (dní) week(s) on: týden v: month(s), after the start month měsíc(e) po zahajovacím měsíci Recur on the Opakovat v 1st 1. 2nd 2. 3rd 3. 4th 4. 5th 5. 6th 6. 7th 7. 8th 8. 9th 9. 10th 10. 11th 11. 12th 12. 13th 13. 14th 14. 15th 15. 16th 16. 17th 17. 18th 18. 19th 19. 20th 20. 21st 21. 22nd 22. 23rd 23. 24th 24. 25th 25. 26th 26. 27th 27. 28th 28. 29th 29. 30th 30. 31st 31. Last Poslední 2nd Last 2. poslední 3rd Last 3. poslední 4th Last 4. poslední 5th Last 5. poslední day den possibly on weekend pravděpodobně o víkendu but before weekend ale před víkendem but after weekend ale po víkendu year(s), after the start year rok(ů) po zahajovacím roce Recur on day part before XXX of 'Recur on day XXX of month YYY' Opakovat dne of part between XXX and YYY of 'Recur on day XXX of month YYY' z On the Part before NNN in 'Recur on the NNN. WEEKDAY of MONTH' v Recur on day # Opakovat dne # of the year part after NNN of 'Recur on day #NNN of the year' roku Range… Rozsah… Exceptions… Výjimky… No day of week selected for weekly recurrence. Není vybrán den pro týdenní opakovaní. Selected day will never occur with selected frequency and start date. Vybraný den se nikdy nevyskytne s vybranou frekvencí a datumem zahájení. Selected day does not exist in selected month. Vybraný den není součástí tohoto měsíce Dividend: %1 Dividenda: %1 Account balancing Zůstatek účtu Security: %1 (bought) Akcie: %1 (nakoupená) Security: %1 (sold) Akcie: %1 (prodaná) Shares bought: Nakoupené cenné papíry: Shares sold: Prodané cenné papíry: Payer: Plátce: Payee: Příjemce: No income category available. Žádná kategorie příjmů není k dispozici. No expense category available. Žádná kategorie výdajů není k dispozici. Cannot create a regular transfer to/from a securities account. Nelze uskutečnit pravidelný převod na/z účtu cenných papírů. Cannot create a regular income to a securities account. Nelze uskutečnit pravidelný příjem na účet cenných papírů. Zero price per share not allowed. Nulová cena není povolena Cannot create a regular expense from a securities account. Nelze uskutečnit pravidelný výdaj z účtu cenných papírů. Modify Transactions Změnit transakce Min amount: Min množství: Max amount: Max množství: Min income: Min příjem: Max income: Max příjem: Min cost: Min cena: Max cost: Max cena: Include Včetně Exclude Kromě From Account Z účtu To Account Na účet Payer Plátce New/Edit %1 Nový/Upravit %1 Filter Filtr Total: Celkem: Average: Průměr: Monthly: Měsíčně: Total cost: Celková cena: Total income: Celkový příjem: Total amount: Celkové množství Monthly average: Měsíční průměr: Are you sure you want to delete all (%1) transactions in the selected split transaction? Opravdu chcete vymazat všech (%1) transakcí ve vybrané rozdělené transakci? * Part of split transaction * Část rozdělené transakce * Part of split (%1) Část rozdělení (%1) ** Recurring (editing occurrence) **Opakování (upravující výskyt) Modify… Změnit… AccountComboBox New account… Nový účet… Multiple accounts/payments… New income category… Nová kategorie příjmů… New expense category… Nová kategorie výdajů… Paid with loan… New Account Nový účet New Income Category Nová skupina příjmů New Expense Category Nová kategorie výdajů AccountsMenu All Accounts Všechny účty All Categories Combined Všechny kategorie kombinované %n accounts %n categories Balancing Account balancing Zůstatek účtu Account balancing Balancing of an account Zůstatek účtu Account Balance Adjustment Budget Balancing Rozvaha Balancing Name of account for transactions that adjust account balances Rozvaha Couldn't open %1 for reading %1 nelze přečíst Not a valid Eqonomize! file (XML parse error: "%1" at line %2, col %3) Neplatný Eqonomize! soubor (chyba XML: "%1" na řádku %2, sloupec %3) Invalid root element %1 in XML document Neplatný kořenový prvek %1 v dokumentu XML Unknown XML element: "%1" at line %2, col %3 XML parse error: "%1" at line %2, col %3 European Euro Unable to load %n currency/currencies. No exchange rates found. USD currency missing. imported Unable to load %n account(s). Nelze načíst účet. Nelze načíst %n účty. Nelze načíst %n účtů. Unable to load %n category/categories. Nelze načíst kategorii. Nelze načíst %n kategorie. Nelze načíst %n kategorií. Unable to load %n security/securities. Financial security (e.g. stock, mutual fund) Unable to load %n transaction(s). Nelze načíst transakci. Nelze načíst %n transakce. Nelze načíst %n transakcí. Download command (%1) failed: %2. Failed to download file from %1: %2. Upload command (%1) failed: %2. yyyy-yy Financial year when first month is not January (e.g. 2018-19). Transaction Accounts Běžné účty Savings Accounts Spořící účty Credit Cards Kreditní karty Debts Dluhy Securities Financial security (e.g. stock, mutual fund) Cenné papíry Cash Hotovost Transaction Account Běžný účet Savings Account Spořící účet Credit Card Platební karta Debt Dluh Other Ostatní File is a directory Soubor je adresář Couldn't open file for writing Soubor nelze otevřít pro zápis Error while writing file; file was not saved Během zápisu došlo k chybě; soubor nebyl uložen Unnamed Bez názvu Uncategorized Neroztříděno CategoriesComparisonChart Save As… Uloẑit jako… Print… Tisk… Options Alternativ From Od To Do Source: Zdroj: All Expenses Všechny výdaje All Incomes Všechny příjmy Theme: Chart type: Pie Chart Bar Chart Default All Expenses, without subcategories All Expenses, with subcategories All Incomes, without subcategories All Incomes, with subcategories All Accounts Všechny účty Expenses: %1 Výdaje: %1 Incomes: %1 Příjmy: %1 Error Chyba Invalid date. Neplatné datum. To date is before from date. Datum do je před datumem od. From date is after to date. Datum od je před datumem do. Couldn't open file for writing. Soubor nelze otevřít pro zápis. Error while writing file; file was not saved. Chyba během zápisu souboru; soubor nebyl uložen. Expenses Výdaje Expenses, %1 Výdaje, %1 Incomes, %1 Příjmy, %1 Incomes Příjmy Accounts Účty Expenses, %2: %1 Výdaje, %2: %1 Incomes, %2: %1 Příjmy, %2: %1 Other descriptions Referring to the transaction description property (transaction title/generic article name) No description Referring to the transaction description property (transaction title/generic article name) Bez popisu Other accounts Other categories %1 Value: %2 No description Referring to the Transaction description property (transaction title/generic article name) Bez popisu No description Referring to the generic description property Bez popisu Value Hodnota Income Příjem Cost Cena Value (%1) Hodnota (%1) Income (%1) Příjem (%1) Cost (%1) Cena (%1) No description Bez popisu CategoriesComparisonChartDialog Chart Graf CategoriesComparisonReport Save As… Uloẑit jako… Print… Tisk… Options Alternativ Source: Zdroj: All Categories, excluding subcategories All Categories, including subcategories All Payees/Payers Všichni příjemci/plátci Subcategories Descriptions for Referring to the Transaction description property (transaction title/generic article name) Popis pro All descriptions Referring to the Transaction description property (transaction title/generic article name) Všechny popisy No description Referring to the Transaction description property (transaction title/generic article name) Bez popisu All Categories Všechny kategorie Expenses: %1 Výdaje: %1 Incomes: %1 Příjmy: %1 Descriptions for Popis pro Payees/payers for Příjemci/plátci pro Descriptions Referring to the Transaction description property (transaction title/generic article name) Popisy Period: Období: From Od To Do Columns: Sloupce: Value Hodnota Daily Denně Monthly Měsíčně Yearly Ročně Quantity Počet Average value Průměrná hodnota All descriptions Všechny popisy All payees Všichni příjemci All payers Všichni plátci No description Bez popisu Descriptions for Referring to the generic description property Popis pro Descriptions Referring to the generic description property Popisy All descriptions Referring to the generic description property Všechny popisy No description Referring to the generic description property Bez popisu All Payees and Payers Všichni příjemci a plátci Tag: %1 All Accounts Všechny účty Descriptions for Referring to the transaction description property (transaction title/generic article name) Popis pro Descriptions Referring to the transaction description property (transaction title/generic article name) Popisy Months Měsíců Years Roky Tags Total: Celkem: All descriptions Referring to the transaction description property (transaction title/generic article name) Všechny popisy All payees/payers Všichni příjemci/plátci No description Referring to the transaction description property (transaction title/generic article name) Bez popisu No payee Žádný příjemce No payer Žádný plátce Error Chyba Invalid date. Neplatné datum. To date is before from date. Datum do je před datumem od. From date is after to date. Datum od je před datumem do. Couldn't open file for writing. Soubor nelze otevřít pro zápis. Error while writing file; file was not saved. Chyba během zápisu souboru; soubor nebyl uložen. Expenses, %2: %1 Výdaje, %2: %1 Expenses, %3: %2, %1 Výdaje, %3: %2, %1 Incomes, %2: %1 Příjmy, %2: %1 Incomes, %3: %2, %1 Příjmy, %3: %2, %1 %3: %2, %1 %2: %1 Tags, %1 Incomes & Expenses, %1 Příjmy & výdaje, %1 Expenses: %2, %1 Výdaje: %2, %1 Incomes: %2, %1 Příjmy: %2, %1 %2, %1 %1 %1 Incomes & Expenses Příjmy & výdaje %1 (%2&ndash;%3) html format; %1: title; %2: from date; %3: to date %1 (%2&ndash;%3) %1 (to %2) html format; %1: title; %2: to date %1 (do %2) Category Kategorie Payee Příjemce Description Referring to the transaction description property (transaction title/generic article name) Popis Cost Cena Payer Plátce Income Příjem Payee/Payer Příjemce/plátce Tag Daily Average Denní průměr Monthly Average Měsíční průměr Yearly Average Roční průměr Average Cost Průměrná cena Average Income Průměrný příjem Average Value Průměrná hodnota No payee/payer Žádný příjemce/plátce Total Celkem All Tags Total incomes Příjmy celkem Total expenses Výdaje celkem Total (Profits) Celkem (zisky) CategoriesComparisonReportDialog Report Sestava ConfirmScheduleDialog The following transactions was scheduled to occur today or before today. Confirm that they have indeed occurred (or will occur today). Následující transakce byly naplánovány na dnešní nebo dřívější datum. Potvrďte, že opravdu proběhly (nebo dnes proběhnou). Date Datum Type Typ Description Popis Name Název Description Generic Description Popis Description Transaction description property (transaction title/generic article name) Popis Amount Množství Edit… Upravit… Postpone… Odložit… Delete Smazat Error Chyba Can only postpone to future dates. Odložit lze pouze na budoucí datum. ConfirmScheduleListViewItem Transfer Převod Dividend Dividenda Income Příjem Expense Výdaj Securities Purchase Financial security (e.g. stock, mutual fund) Nákup cenných papírů Securities Sale Financial security (e.g. stock, mutual fund) Prodej cenných papírů Security Buy Nákup cenných papírů Security Sell Prodej cenných papírů Debt Payment CurrencyConversionDialog Currency Converter DebtFee Debt payment: %1 (fee) DebtInterest Debt payment: %1 (interest) DebtPayment Debt payment: %1 DebtReduction Debt payment: %1 (reduction) DescriptionsMenu All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Všechny popisy kombinované All Tags Combined All Payees Combined Všichni příjemci kombinovaní All Payers Combined Všichni plátce kombinovaní All Payees/Payers Combined Všichni plátci/příjemci kombinovaní No description Referring to the transaction description property (transaction title/generic article name) Bez popisu No payee Žádný příjemce No payer Žádný plátce No payee/payer Žádný příjemce/plátce %n descriptions Referring to the transaction description property (transaction title/generic article name) %n tags %n payees %n payers %n payees/payers EditAssetsAccountDialog Type: Typ: Cash Hotovost Current Account Běžný účet Savings Account Spořící účet Credit Card Platební karta Liabilities Dluhy Transactional Account Šekové konto Debt Dluh Securities Cenné papíry Other Ostatní Currency: Edit Upravit Name: Název: Bank: Banka: Initial balance: Počáteční bilance: Debt: Initial balance Počáteční bilance Group: no group Transferred to: Date: Datum: Lender: Default account for budgeted transactions Výchozí účet pro rozpočtové transakce Description: Popis: Account is closed Warning Type cannot be changed to securities for accounts with transactions. Issuer: Zero value not allowed. Nulová hodnota není povolena. Error Chyba Transaction Account Běžný účet Opening balance: Account balance Počáteční zůstatek: Opening balance Account balance Počáteční zůstatek New currency… If you change the currency of an account, the currency of all associated transactions will also change, without any conversion. Do do wish to continue anyway? Empty name. Prázdný název. The entered name is used by another account. Tento název už používá jiný účet. EditCurrencyDialog Edit Currency New Currency Code: Symbol: Prefix Suffix Default Name: Název: Decimals: Date: Datum: Main currency Error Chyba Error saving currencies: %1. Empty code. Code already exists. EditDebtPaymentDialog Debt Payment EditDebtPaymentWidget Debt: Date: Datum: Debt reduction: Reduction payment: Interest: Paid Added to debt Fee: Account: Účet: Expense category: Associated file: Select a file Open the file Comments: Poznámky: Related to: Label for linked transactions Odkazy: Total value: Celková hodnota: Error Chyba No suitable account available. Vhodný účet není k dispozici. Invalid date. Neplatné datum. Interest must not be zero. At least one value must non-zero. EditExceptionsDialog Edit Exceptions Upravit výjimky Occurrences: Výskyty: Add Exception Remove Exception Exceptions: Výjimky: Only the first fifty occurrences are shown. Add Přidat Apply Použít Delete Smazat Error Chyba Invalid date. Neplatné datum. EditExpensesAccountDialog Name: Název: Parent category: None Monthly budget: Měsíční rozpočet: Description: Popis: Error Chyba Empty name. Prázdný název. The entered name is used by another expense category. Tento název už používá jiná kategorie výdajů. EditIncomesAccountDialog Name: Název: Parent category: None Monthly budget: Měsíční rozpočet: Description: Popis: Error Chyba Empty name. Prázdný název. The entered name is used by another income category. Tento název už používá jiná kategorie příjmů. EditLoanTransactionWidget Date: Datum: Account: Účet: Comments: Poznámky: Total value: Celková hodnota: Error Chyba No suitable account available. Vhodný účet není k dispozici. Invalid date. Neplatné datum. EditMultiAccountDialog Expense with Multiple Payments Income with Multiple Payments EditMultiAccountWidget Description: Popis: Description: Generic Description Popis: Description: Transaction description property (transaction title/generic article name) Popis: Quantity: Počet: Category: Kategorie: Tags: Associated file: Select a file Open the file Comments: Poznámky: Related to: Label for linked transactions Odkazy: Transactions: Transakce: Date Datum Account Účet Payee Příjemce Payer Plátce Cost Cena Income Příjem Total cost: Celková cena: Value Hodnota New Nový Edit… Upravit… Delete Smazat Total value: Celková hodnota: Error Chyba No suitable expense categories available. A split must contain at least two transactions. Pro rozdělení potřebujete nejméně dvě transakce. EditMultiItemDialog Split Transaction Rozdělená transakce EditMultiItemWidget Description: Popis: Description: Generic Description Popis: Date: Datum: Account: Účet: Payee/Payer: Příjemce/plátce: Transactions: Transakce: Type Typ Description Generic Description Popis Description: Transaction description property (transaction title/generic article name) Popis: Tags: Associated file: Select a file Open the file Comments: Poznámky: Related to: Label for linked transactions Odkazy: Description Transaction description property (transaction title/generic article name) Popis Payment Platba Deposit Vklad New Nový New Expense… Nový výdaj… New Income… Nový příjem… New Deposit… Nový vklad… New Withdrawal… Nový výběr… New Securities Purchase… Financial security (e.g. stock, mutual fund) Nový nákup cenných papírů… New Securities Sale… Financial security (e.g. stock, mutual fund) Nový prodej cenných papírů… Shares Bought… Nakoupené podíly… Shares Sold… Prodané podíly… Account/Category Účet/Kategorie Value Hodnota Income Příjem Expense Výdaj New Dividend… Nová dividenda… Edit… Upravit… Delete Smazat Total value: Celková hodnota: Error Chyba No suitable account available. Vhodný účet není k dispozici. Invalid date. Neplatné datum. A split must contain at least two transactions. Pro rozdělení potřebujete nejméně dvě transakce. Cannot transfer money to and from the same account. Peníze nelze převést na stejný účet. EditQuotationsDialog Quotations Kurzy Date Datum Price per Share Cena za podíl Quotations Financial quotation Kurzy Quotes Financial quote Kurzy Price per Share Financial Shares Cena za podíl Add Přidat Modify Změnit Delete Smazat Import… Importovat… Export… Exportovat… Quotes for %1 Financial quote Kurz pro %1 Quotations for %1 Financial quotation Kurz pro %1 Quotations for %1 Kurz pro %1 Error Chyba Couldn't open %1 for reading. Nelze otevřít %1 ke čtení. Error reading %1. Chyba při čtení %1. Successfully imported %n quote(s). Unable to import any quotes. Failed to import %n data row(s). Chyba při importu datové řady. Chyba při importu %n datových řad. Chyba při importu %n datových řad. Required columns missing. Požadované sloupce chybí. Invalid value. Neplatná hodnota. Invalid date. Neplatné datum. No data found. Žádná data nenalezena. Information Unrecognized date format. Neznámý formát datumu. Specify Format Upřesněte formát The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. Formát datumů a/nebo čísel v souboru CSV je nejednoznačný. Prosím vyberte správný formát. Date format: Formát data: Value format: Formát hodnoty: Couldn't open file for writing. Soubor nelze otevřít pro zápis. Quotes: %1 Kurz: %1 Error while writing file; file was not saved. Chyba během zápisu souboru; soubor nebyl uložen. EditRangeDialog Edit Recurrence Range Upravit rozsah opakování Begins on: %1 Začíná: %1 No ending date Chybí datum ukončení End after Ukončit po occurrence(s) výskyt(y) End on Ukončit Error Chyba Invalid date. Neplatné datum. End date before start date. Datum ukončení předchází datumu zahájení. EditReinvestedDividendDialog Reinvested Dividend Reinvestované dividendy Security: Cenný papír: Shares added: Podíly přidané: Security: Financial security (e.g. stock, mutual fund) Cenný papír: Shares added: Financial shares Podíly přidané: Date: Datum: Error Chyba Invalid date. Neplatné datum. EditScheduledDebtPaymentDialog Transaction Transakce Recurrence Opakování Edit Debt Payment New Debt Payment EditScheduledLoanTransactionDialog Recurrence Opakování EditScheduledMultiAccountDialog Transactions Transakce Recurrence Opakování New Expense with Multiple Payments New Income with Multiple Payments Edit Expense with Multiple Payments Edit Income with Multiple Payments EditScheduledMultiItemDialog Transactions Transakce Recurrence Opakování New Split Transaction Nová rozdělená transakce Edit Split Transaction Upravit rozdělenou transakci EditScheduledTransactionDialog Expense Výdaj Dividend Dividenda Income Příjem Reinvested Dividend Reinvestované dividendy Transfer Převod Security Buy Nákup cenných papírů Security Sell Prodej cenných papírů Securities Purchase Financial security (e.g. stock, mutual fund) Nákup cenných papírů Securities Sale Financial security (e.g. stock, mutual fund) Prodej cenných papírů Recurrence Opakování New Expense Nový výdaj New Expense Paid with Loan New Dividend Nová dividenda New Income Nový příjem New Transfer Nový převod New Securities Purchase Financial security (e.g. stock, mutual fund) Nový nákup cenných papírů New Reinvested Dividend New Securities Sale Financial security (e.g. stock, mutual fund) Nový prodej cenných papírů Edit Reinvested Dividend Edit Securities Purchase Financial security (e.g. stock, mutual fund) Upravit nákup cenných papírů Edit Securities Sale Financial security (e.g. stock, mutual fund) Upravit prodej cenných papírů New Security Buy Nový nákup cenných papírů New Security Sell Nový prodej cenných papírů Edit Expense Upravit výdaj Edit Dividend Upravit dividendu Edit Income Upravit příjem Edit Transfer Upravit převod Edit Securities Bought Upravit nákup cenných papírů Edit Securities Sold Upravit prodej cenných papírů EditSecurityDialog Type: Typ: Mutual Fund Vzájemný fond Bond Dluhopis Stock Akcie Stock Financial stock Akcie Other Ostatní Name: Název: Account: Účet: Decimals in shares: Financial shares Desetiny v podílech: Initial shares: Financial shares Počáteční podíly: Decimals in quotes: Financial quote Initial quote: Financial quote Počáteční kurz: Empty name. Prázdný název. No suitable account available. Vhodný účet není k dispozici. Initial quotation: Financial quotation Počáteční kurz: Decimals in shares: Desetiny v podílech: Initial shares: Počáteční podíly: Decimals in Shares: Desetiny v podílech: Initial Shares: Počáteční podíly: Initial quotation: Počáteční kurz: Date: Datum: Description: Popis: Error Chyba No suitable account or income category available. Neexistuje vhodná kategorie účtů nebo příjmů. EditSecurityTradeDialog Security Trade Obchod cenným papírem From security: Z cenného papíru: Shares moved: Přesunuté podíly: All Vše To security: K cennému papíru: Shares received: Podíly přijaté: Securities Exchange Financial security (e.g. stock, mutual fund) Obchod cenným papírem Securities Exchange Shares of one security directly exchanged for shares of another; Financial security (e.g. stock, mutual fund) Obchod cenným papírem From security: Financial security (e.g. stock, mutual fund) Z cenného papíru: Shares moved: Financial shares Přesunuté podíly: To security: Financial security (e.g. stock, mutual fund) K cennému papíru: Shares received: Financial shares Podíly přijaté: Value: Hodnota: Date: Datum: Error Chyba No other security available for exchange in the account. Shares of one security directly exchanged for shares of another; Financial security (e.g. stock, mutual fund) Na účtu už není žádný cenný papír pro obchodování. No other security available for exchange in the account. Financial security (e.g. stock, mutual fund) Na účtu už není žádný cenný papír pro obchodování. No other security available for trade in the account. Na účtu už není žádný cenný papír pro obchodování. Selected to and from securities are the same. Financial security (e.g. stock, mutual fund) Pro a od jsou stejné. Zero shares not allowed. Financial shares Nulové podíly nejsou povoleny. Selected to and from securities are the same. Pro a od jsou stejné. Invalid date. Neplatné datum. Zero shares not allowed. Nulové podíly nejsou povoleny. Zero value not allowed. Nulová hodnota není povolena. EditSplitDialog Split Transaction Rozdělená transakce Description: Popis: Date: Datum: Account: Účet: Transactions: Transakce: Type Typ Description Popis Name: Název: Name Název Generic Description: Druhový popis: Description Generic Description Popis Account/Category Účet/Kategorie Payment Platba Deposit Vklad New Nový New Expense… Nový výdaj… New Income… Nový příjem… New Deposit… Nový vklad… New Withdrawal… Nový výběr… Shares Bought… Nakoupené podíly… Shares Sold… Prodané podíly… Security Shares Sold… Cenné papíry prodané… New Dividend… Nová dividenda… Edit… Upravit… Delete Smazat Total value: Celková hodnota: Error Chyba No suitable account available. Vhodný účet není k dispozici. Invalid date. Neplatné datum. Future dates is not allowed. Budoucí datumy nejsou povoleny. A split must contain at least two transactions. Pro rozdělení potřebujete nejméně dvě transakce. Cannot transfer money to and from the same account. Peníze nelze převést na stejný účet. Eqonomize Accounts && Categories Účty && Kategorie Expenses Výdaje Incomes Příjmy Transfers Převody Transaction Accounts Běžné účty Savings Accounts Spořící účty Credit Cards Kreditní karty Debts Dluhy Securities Cenné papíry Schedule Plán Account / Category Účet / Skupina Remaining Budget (%1) Zbývající rozpočet (%1) Change (%1) Změna (%1) Total (%1) Celkem (%1) %2 of %1 %2 remains of %1 budget %2 ze %1 Accounts Účty Includes budgeted transactions Zahrnuje rozpočtové transakce Securities Financial security (e.g. stock, mutual fund) Cenné papíry Tags Period Období From Od To Do Select Period Vybrat období Current Month Tento měsíc Current Year Tento rok Current Whole Month Celý tento měsíc Current Whole Year Celý tento rok Whole Past Month Celý minulý měsíc Whole Past Year Celý minulý rok Previous Month Minulý měsíc Previous Year Minulý rok Show partial budget Ukázat částečný rozpočet Edit Budget Upravit rozpočet Budget: Rozpočet: Month: Měsíc: Result previous month: Výsledek minulého měsíce: New Security… Nový cenný papír… New Transaction Nová transakce Set Quotation… Nastavit kurz… Name Název Value Hodnota Shares Podíly Quotation Kurz Cost Cena Profit Zisk Yearly Rate Roční sazba Type Typ Account Účet Statistics Period Doba statistiky New Schedule Nový plán Edit Upravit Remove Odstranit Next Occurrence Další výskyt Description Popis Description Generic Description Popis Amount Množství Payee/Payer Příjemce/plátce Comments Poznámky Set Schedule Confirmation Time Schedule confirmation time: Set Budget Period First day in budget month: 1st 1. 2nd 2. 3rd 3. 4th 4. 5th 5. 6th 6. 7th 7. 8th 8. 9th 9. 10th 10. 11th 11. 12th 12. 13th 13. 14th 14. 15th 15. 16th 16. 17th 17. 18th 18. 19th 19. 20th 20. 21st 21. 22nd 22. 23rd 23. 24th 24. 25th 25. 26th 26. 27th 27. 28th 28. Last Poslední 2nd Last 2. poslední 3rd Last 3. poslední 4th Last 4. poslední 5th Last 5. poslední Timestamp Links Odkazy Remove Link Link to "%1" create link to transaction (link used as verb) All Vše Import Options Ignore duplicate transactions Rename duplicate accounts Rename duplicate categories Rename duplicate securities Synchronization Settings Web address: Download command: Duplicate Transaction… duplicate as verb Create Link create link to or between transaction(s) New Tag… Rename Tag… Remove Tag New Tag Tag name: Remove tag? Do you wish to remove the tag "%1" from %n transaction(s)? Rename Tag optional Right align Zarovnat vpravo Upload command: mandatory Automatic synchronization Upload Uploading… Error uploading file Error uploading %1: %2. Synchronizing… Error synchronizing file Error synchronizing %1: %2. Synchronization error Synchronize file? The file has been modified by a different user or program. Do you wish to merge changes? New version available A new version of %1 is available.<br><br>You can get version %2 at %3. Abort First month in budget year: %f = local file (temporary), %u = url Failed to download exchange rates from %1: %2. Error reading data from %1: %2. Unrecognized Currency No exchange rate is available for the default currency (%1). If you wish to use multiple currencies you should set the exchange rate manually. Set Main Currency Currency: Replace all occurrences of the former main currency Transaction Account Běžný účet S&ynchronize Import %1 File… Reconcile Account… Adjust balance… Referring to account balance Close Account Mark account as closed New Expense Paid with Loan… Show payee and quantity Show quantity and payer/payee properties for incomes and expenses. Set Schedule Confirmation Time… Select Font… Language Jazyk Default Restart required Only use this when unable to find the cause of the incorrect recorded account balance. Reopen Account Mark account as not closed New Debt Payment… New Unpaid Interest… Eqonomize! Accounting File Adjust Account Balance New Security Nový cenný papír Edit Security Upravit cenný papír Total value: Celková hodnota: Cost: Cena: Profit: Zisk: Rate: Sazba: Are you sure you want to delete the security "%1" and all associated transactions? Opravdu chcete smazat cenný papír "%1" a všechny související transakce? Error Chyba No security available. Žádný cenný papír k dispozici. Set Quotation (%1) Stanovit plán rozpočtu (%1) Price per share: Cena za akcii: Date: Datum: Invalid date. Neplatné datum. Future dates are not allowed. Budoucí datumy nejsou povoleny. Security Transactions Transakce s cennými papíry Bond Dluhopis Stock Akcie Mutual Fund Vzájemný fond Other Ostatní Add Loan Add Category Ledger Účetní kniha To date is before from date. Datum do je před datumem od. From date is after to date. Datum od je před datumem do. Cash Hotovost Check Account Šekový účet Savings Account Spořící účet Salary Plat Bills Účty Clothing Oblečení Groceries Potraviny Leisure Volný čas Couldn't open file Soubor nelze otevřít Error loading %1: %2. Chyba při spouštění %1: %2. Couldn't save file Soubor nelze uložit Error saving %1: %2. Chyba při ukládání %1: %2. Updating exchange rates… Error saving currencies: %1. New currency… Transaction Schedule Plán transakce Total Celkem Accounts &amp; Categories html format Účty &amp; Kategorie Accounts &amp; Categories (%1&ndash;%2) html format Účty &amp; Kategorie (%1&ndash;%2) Accounts &amp; Categories (to %1) html format Účty &amp; Kategorie (do %1) Change Noun, how much the account balance has changed Změna Balance Bilance Current Account Běžný účet Credit Card Kreditní karta Liabilities Dluhy New Security… Financial security (e.g. stock, mutual fund) Nový cenný papír… Set Quotation… Financial quotation Nastavit kurz… Shares Financial shares Podíly Quotation Financial quotation Kurz New Security Financial security (e.g. stock, mutual fund) Nový cenný papír Edit Security Financial security (e.g. stock, mutual fund) Upravit cenný papír Delete security? Financial security (e.g. stock, mutual fund) Are you sure you want to delete the security "%1" and all associated transactions? Financial security (e.g. stock, mutual fund) Opravdu chcete smazat cenný papír "%1" a všechny související transakce? No security available. Financial security (e.g. stock, mutual fund) Žádný cenný papír k dispozici. Set Quotation (%1) Financial quotation Stanovit plán rozpočtu (%1) Price per share: Financial shares Cena za akcii: Security Transactions Financial security (e.g. stock, mutual fund) Transakce s cennými papíry Stock Financial stock Akcie Checking Account Transactional account Běžný účet Balance Account balance Zůstatek Category Kategorie Budget Rozpočet Remaining Budget Zbývající rozpočet Total Incomes Celkové příjmy Costs Ceny Total Expenses Celkové výdaje Account/Category Noun, how much the account balance has changed Účet/Kategorie Empty expenses list. Prázdný seznam výdajů. Empty incomes list. Prázdný seznam příjmů. Empty transfers list. Prázdný seznam převodů. Empty securities list. Prázdný seznam cenných papírů. Empty schedule list. Prázdný seznam plánů. Couldn't open file for writing. Soubor nelze otevřít pro zápis. Error while writing file; file was not saved. Chyba během zápisu souboru; soubor nebyl uložen. &File &Soubor &Accounts &Účty &Transactions &Transakce &Securities &Cenné papíry Stat&istics Stat&istiky S&ettings N&astavení &Help &Nápověda File Soubor Transactions Transakce Statistics Statistiky &New &Nový &Open… &Otevřít… Open Recent Otevřít nedávný Clear List Smazat seznam &Save &Uloẑit Save As… Uloẑit jako… &Revert &Vrátit &Print… &Tisk… Print Preview… Náhled tisku… &Print View… &Tisk… Import Importovat Import CSV File… Importovat soubor CSV… Import QIF File… Importovat soubor QIF… Export View… Exportovat… Export As QIF File… Exportovat jako soubor QIF… Update Exchange Rates Currency Converter &Quit U&končit Add Account… Přidat účet… New Account… Nový účet… New Loan… New Income Category… Nová kategorie příjmů… New Expense Category… Nová kategorie výdajů… Add Account Přidat účet Assets Aktiva Description Transaction description property (transaction title/generic article name) Popis Security Transactions Financial security (e.g. stock, bond) Transakce s cennými papíry &Loans &Půjčky &Securities Financial security (e.g. stock, mutual fund) &Cenné papíry Edit… Upravit… Balance… Bilance… Show Transactions Ukázat transakce Show Ledger New Expense… Nový výdaj… New Income… Nový příjem… New Transfer… Nový převod… New Split Transaction… Nová rozdělená transakce… New Expense with Multiple Payments… Refund… Úhrada… Repayment… Splátka… New Refund/Repayment… Nová úhrada/splátka… Edit Transaction(s) (Occurrence)… Upravit transakce (výskyt)… Edit Occurrence… Upravit výskyt… Edit Schedule (Recurrence)… Upravit plán (opakování)… Edit Schedule… Upravit plán… Edit Split Transaction… Upravit rozdělenou transakci… Join Transactions… join transactions together Spojit transakce… Split Up Transaction split up joined transactions Rozdělit transakci Edit Timestamp… Select Associated File Open Associated File Remove Transaction(s) (Occurrence) Odstranit transakce (výskyt) Remove Occurrence Odstranit výskyt Delete Schedule (Recurrence) Odstranit plán (opakování) Delete Schedule Smazat plán Remove Split Transaction Odstranit rozdělenou transakci Edit Security… Upravit cenný papír… Remove Security Smazat cenný papír Shares Bought… Nakoupené podíly… Shares Sold… Prodané podíly… Shares Moved… Přesunuté podíly… Dividend… Dividenda… Reinvested Dividend… Reinvestovaná dividenda… Transactions… Transakce… Edit Quotations… Upravit kurz… Development Over Time Report… Výkaz časového vývoje… Categories Comparison Report… Výkaz porovnání kategorií… Development Over Time Chart… Schéma časového vývoje… Categories Comparison Chart… Schéma vývoje kategorií… Use Additional Transaction Properties Použít další vlastnosti transakcí Set Main Currency… Use Exchange Rate for Transaction Date Use the exchange rate nearest the transaction date, instead of the latest available rate, when converting the value of transactions. Set Budget Period… Initial Period Počáteční období Remember Last Dates Zapamatovat poslední datumy Backup Frequency Daily Denně Weekly Týdně Fortnightly Monthly Měsíčně Never Cloud Synchronization (experimental)… Dark Mode Help Nápověda Report Bug Nahlásit chybu About %1 O aplikaci %1 Please restart the application for the language change to take effect. A personal accounting program Osobní účetní program License: GNU General Public License Version 3 Licens: GNU General Public License Version 3 %1 exited unexpectedly before the file was saved and data was lost. Do you want to load the last auto-saved version of the file? %1 byl nečekaně zavřen bez uložení a data byla ztracena. Přejete si spustit poslední automaticky uloženou verzi souboru? About Eqonomize! O aplikaci Eqonomize! About Qt O Qt About Eqonomize O Eqonomize <font size=+2><b>Eqonomize! v0.6</b></font><br><font size=+1>A personal accounting program</font><br><<font size=+1><i><a href="http://eqonomize.github.io/">http://eqonomize.github.io/</a></i></font><br><br>© 2006-2008, 2014, 2016 Hanna Knutsson<br>License: GNU General Public License Version 2 <font size=+2><b>Eqonomize! v0.6</b></font><br><font size=+1>Osobní účetní program</font><br><<font size=+1><i><a href="http://eqonomize.github.io/">http://eqonomize.github.io/</a></i></font><br><br>© 2006-2008, 2014, 2016 Hanna Knutsson<br>Licens: GNU General Public License Version 2 Crash Recovery Obnovení po pádu Eqonomize! exited unexpectedly before the file was saved and data was lost. Do you want to load the last auto-saved version of the file? Eqonomize! byl nečekaně zavřen bez uložení a data byla ztracena. Přejete si spustit poslední automaticky uloženou verzi souboru? Untitled Bez názvu Empty securities list. Financial security (e.g. stock, mutual fund) Prázdný seznam cenných papírů. Balance… Balance account Bilance… Edit Security… Financial security (e.g. stock, mutual fund) Upravit cenný papír… Remove Security Financial security (e.g. stock, mutual fund) Smazat cenný papír Shares Bought… Financial shares Nakoupené podíly… Shares Sold… Financial shares Prodané podíly… Shares Exchanged… Financial shares Přesunuté podíly… Edit Quotations… Financial quotation Upravit kurz… The current file has been modified. Do you want to save it? Soubor byl změněn. Přejete si ho uložit? Save file? Confirm Schedule Potvrdit plán New Account Nový účet New Loan New Income Category Nová skupina příjmů New Expense Category Nová kategorie výdajů Balance Account Bilanční účet Book value: Účetní hodnota: of which %1 is balance adjustment Referring to account balance Real value: Skutečná hodnota: Edit Account Upravit účet Edit Income Category Upravit kategorii příjmů Edit Expense Category Upravit kategorii výdajů Remove subcategories? Do you wish to remove the category including all subcategories? Move transactions? Přesunout transakce? Move to: Přesunout do: Remove irreversibly from all accounts (do not do this if account has been closed!) The category contains some expenses. What do you want to do with them? Kategorie obsahuje výdaje. Co s nimi chcete udělat? The category contains some incomes. What do you want to do with them? Kategorie obsahuje příjmy. Co s nimi chcete udělat? The account contains some transactions. What do you want to do with them? Účet obsahuje transakce. Co s nimi chcete udělat? Remove Category? Odstranit kategorii? The category contains some expenses that will be removed. Do you still want to remove the category? Kategorie obsahuje výdaje, které budou odstraněny. Opravdu chcete kategorii odstranit? The category contains some incomes that will be removed. Do you still want to remove the category? Kategorie obsahuje příjmy, které budou odstraněny. Opravdu chcete kategorii odstranit? Remove Account? Odstranit účet? The account contains some transactions that will be removed. Do you still want to remove the account? Účet obsahuje transakce, které budou odstraněny. Opravdu chcete účet odstranit? %2 of %1 %1: budget; %2: remaining budget %2 ze %1 Set Quote… Financial quote Nastavit kurz… Quote Financial quote Kurz Set Quote (%1) Financial quote Nastavit kurz (%1) Balance Noun. Balance of an account Zůstatek Balance… Verb. Balance an account Bilance… Shares Exchanged… Shares of one security directly exchanged for shares of another; Financial shares Přesunuté podíly… Shares of one security directly exchanged for shares of another Financial shares Edit Quotes… Financial quote Upravit kurz… Balance Account Verb Bilanční účet %1 (with no budget) %1 (se žádným rozpočtem) %1 (with budget %2) %1 (s rozpočtem %2) EqonomizeCalendarWidget Today Dnes EqonomizeDateEdit Today Dnes EqonomizeTranslator OK Only used when Qt translation is missing Cancel Only used when Qt translation is missing Close Only used when Qt translation is missing &Yes Only used when Qt translation is missing &No Only used when Qt translation is missing &Open Only used when Qt translation is missing &Save Only used when Qt translation is missing &Select All Only used when Qt translation is missing Look in: Only used when Qt translation is missing File &name: Only used when Qt translation is missing Files of type: Only used when Qt translation is missing EqonomizeValueEdit Error Chyba Empty denominator. Empty factor. Division by zero. Unknown or ambiguous currency, or unrecognized characters, in expression: %1. Empty base. Empty exponent. Unrecognized characters in expression. ExportQIFDialog Export QIF File Exportovat soubor QIF Account: Účet: All All accounts Vše Export transaction description as: Exportovat popis transakce jako: Export transaction description as: Referring to generic description Exportovat popis transakce jako: Payee Příjemce Memo Poznámka Subcategory Podkategorie Date format: Formát data: Value format: Formát hodnoty: File: Soubor: Error Chyba Selected file is a directory. Vybraný soubor je adresář. Overwrite The selected file already exists. Would you like to overwrite the old copy? Vybraný soubor již existuje. Chcete ho přepsat? You selected a directory! Vybrali jste adresář! Couldn't open file for writing. Soubor nelze otevřít pro zápis. Error while writing file; file was not saved. Chyba během zápisu souboru; soubor nebyl uložen. ImportCSVDialog Import CSV file Imporovat soubor CSV Transaction Type Selection Výběr typu transakce Expenses Výdaje Incomes Příjmy Transfers Převody Expenses and incomes (negative cost) Výdaje a příjmy (záporná cena) Expenses and incomes (separate columns) Výdaje a příjmy (oddělené sloupce) All types Všechny typy Presets: File Selection Výběr souboru File: Soubor: First data row: První řádek údajů: Auto Auto Column delimiter: Oddělovač sloupců: Comma Čárka Tabulator Tabulátor Semicolon Středník Space Mezera Other Ostatní Columns Specification Popis sloupce Save as preset… Imports data as expenses and incomes. Costs have negative value. Value is the only required column. Importovat údaje jako výdaje a příjmy. Ceny jsou záporné. Vyžadován pouze sloupec hodnota. Imports data as expenses and incomes. Costs and incomes have separate columns. Income and cost both all required columns. Importovat údaje jako výdaje a příjmy. Ceny a příjmy jsou v oddělených sloupcích. Vyžadovány sloupce příjem i cena. Warning The same column number is selected multiple times. Do you wish to proceed anyway? Description: Popis: Generic description: Druhový popis: Description: Transaction description property (transaction title/generic article name) Popis: Column Sloupec Value Hodnota Cost: Cena: Date: Datum: Category: Kategorie: From account: Z účtu: Quantity: Počet: Payee: Příjemce: Tags: Comments: Poznámky: Create missing categories and accounts Vytvořit chybějící kategorie a účty Save Preset Imports data as expenses. Costs have positive value. Value is the only required column. Importovat údaje jako výdaje. Ceny jsou kladné. Vyžadován pouze sloupec hodnota. Imports data as incomes. Value is the only required column. Importovat údaje jako příjmy. Vyžadován pouze sloupec hodnota. Income: Příjem: To account: Na účet: Payer: Plátce: Imports data as transfers. Value is the only required column. Importovat údaje jako převody. Vyžadován pouze sloupec hodnota. Amount: Množství: Imports data as expenses and incomes. Costs have negative value. Value and category are both required columns. Importovat údaje jako výdaje a příjmy. Ceny jsou kladné. Vyžadován sloupec hodnota i kategorie. Value: Hodnota: Account: Účet: Payee/payer: Příjemce/plátce: Imports data as expenses and incomes. Costs and incomes have separate columns. Income, cost, and category are all required columns. Importovat údaje jako výdaje a příjmy. Ceny a příjmy jsou v oddělených sloupcích. Vyžadovány sloupce příjem, cena a kategorie. Imports data as expenses, incomes, and transfers. Costs have negative or positive value. Value, to, and from are all required columns. Accounts and categories must be existing. Importovat údaje jako výdaje, příjmy a převody. Ceny jsou kladné nebo záporné. Vyžadovány sloupce pro a od. Účty a kategorie musí existovat. From: Od: To: Do: Error Chyba A file must be selected. Vyberte soubor. Selected file is a directory. Vybraný soubor je adresář. Selected file does not exist. Vybraný soubor neexistuje. Empty delimiter. Prázdný oddělovač. The same column number is selected multiple times. Stejné číslo sloupce je vybráno vícekrát. Selected from account is the same as the to account. Vybrané z účtu je stejné jako na účet. Invalid date. Neplatné datum. Couldn't open %1 for reading. Nelze otevřít %1 ke čtení. Error reading %1. Chyba při čtení %1. Uncategorized Neroztříděno Successfully imported %n transaction(s). Transakce byla úspěšně importována. %n transakce byly úspěšně importovány. %n transakcí bylo úspěšně importováno. Unable to import any transactions. Nelze importovat. Failed to import %n data row(s). Chyba při importu datové řady. Chyba při importu %n datových řad. Chyba při importu %n datových řad. Required columns missing. Požadované sloupce chybí. Invalid value. Neplatná hodnota. Empty category name. Prázdný název kategorie. Empty account name. Prázdný název účtu. Unknown category found. Nalezena neznámá kategorie. Unknown account found. Nalezen neznámý účet. Cannot import security transactions (to/from security accounts). Nelze imporotvat transakci s cennými papíry (z/na účet cenných papírů). Balancing account wrongly used. Referring to the account used for adjustments of account balances. Bilanční účet použit špatně. Balancing account wrongly used. Bilanční účet použit špatně. Same to and from account/category. Stejné do a z účet/kategorie. No data found. Žádná data nenalezena. Information Unrecognized date format. Neznámý formát datumu. Specify Format Upřesněte formát The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. Formát datumů a/nebo čísel v souboru CSV je nejednoznačný. Prosím vyberte správný formát. Date format: Formát data: Value format: Formát hodnoty: ImportQIFDialog Import QIF file Importovat soubor QIF File Selection Výběr souboru Select a QIF file to import. When you click next, the file be analysed and you might need to answer some questions about the format of the file. Vyberte soubor QIF. Po kliknutí na další, bude soubor analyzován a pravděpodobně budete muset odpovědět na otázky týkající se formátu souboru. File: Soubor: Local Definitions Místní definice Unknown elements where found in the QIF file. It is possible that this is because of localized type names. Please map them to the correct standard names. Byly nalezeny neznámé prvky v souboru QIF. Možná je to způsobeno místními názvy. Prosím opravte je na běžné názvy. Local Text Místní text Standard Text Běžný text Select standard text: Vyberte běžný název: Date Format Formát datumu The date format in the QIF file is ambiguous. Please select the correct format. Formát datumu v souboru QIF není správný. Prosím vyberte správný formát. Date format: Formát data: Default Account Výchozí účet Could not find any account definitions in the QIF file. Please select a default account. It is also possible that this is caused by a localized opening balance text. V souboru QIF nelze najít žádný účet. Prosím vyberte výchozí účet. Problém může také spočívat v lokalizaci textu otevírané bilance. Default account: Výchozí účet: Opening balance text: Text otevírané bilance: Descriptions Popisy Transactions in QIF files does not have any specific description property. You are therefore given the option to choose how the description of imported transactions will be set. Popis transakcí v souboru QIF nemá typické vlastnosti. Proto máte možnost vybrat, jak bude popis importovaných transakcí nastaven. Subcategories as: Podkategorie jako: Description Popis Generic Descriptions Druhové popisy Transactions in QIF files does not have any specific description property. You are therefore given the option to choose how the description of imported transactions will be set. Referring to generic description Popis transakcí v souboru QIF nemá typické vlastnosti. Proto máte možnost vybrat, jak bude popis importovaných transakcí nastaven. Generic description Druhový popis Category Kategorie Ignore Ignorovat Payee as: Příjemce jako: Payee Příjemce Memo as: Poznámka jako: Comments Poznámky Priority: Priorita: Subcategory/Payee/Comments Podkategorie/Příjemce/Poznámky Payee/Subcategory/Comments Příjemce/Podkategorie/Poznámky Subcategory/Comments/Payee Podkategorie/Poznámky/Příjemce Payee/Comments/Subcategory Příjemce/Poznámky/Podkategorie Comments/Subcategory/Payee Poznámky/Podkategorie/Příjemce Comments/Payee/Subcategory Poznámky/Příjemce/Podkategorie Import File No (further) issues were found. Press finish to import the selected QIF file. Ignore duplicate transactions Error Chyba A file must be selected. Vyberte soubor. Selected file is a directory. Vybraný soubor je adresář. Selected file does not exist. Vybraný soubor neexistuje. Couldn't open %1 for reading. Nelze otevřít %1 ke čtení. Error reading %1. Chyba při čtení %1. Unknown Neznámý Account Účet Bank Banka Cash Hotovost Cat (Category) Kat (Kategorie) CCard (Credit Card) PKarta (Platební karta) Invst (Investment) Invst (Investice) Oth A (Other Assets) Ost A (Ostatní aktiva) Oth L (Other Liabilities) Oth L (Ostatní pasiva) Security Akcie Other Ostatní Unrecognized date format. Neznámý formát datumu. Successfully imported %n transaction(s). Transakce byla úspěšně importována. %n transakce byly úspěšně importovány. %n transakcí bylo úspěšně importováno. Successfully imported %n account(s). Účet úspěšně importován. %n účty úspěšně importovány. %n účtů úspěšně importováno. Successfully imported %n category/categories. Kategorie byla úspěšně importována. %n kategorií bylo úspěšně importováno. %n kategorií bylo úspěšně importováno. %n duplicate transaction(s) was ignored. Kopie transakce byla ignorována. %n kopie transakcí bylo ignorováno. %n kopií transakcí bylo ignorováno. Failed to import %n transaction(s). Chyba při importování transakce. Chyba při importu %n transakcí. Chyba při importu %n transakcí. %n security/securities were not imported. Financial security (e.g. stock, mutual fund) %n security transaction(s) were not imported. Financial security (e.g. stock, mutual fund) Information Income Dividend: %1 Dividenda: %1 Reinvested dividend: %1 Reinvestované dividendy: %1 LedgerDialog Account: Účet: Edit Account… Upravit účet… Export… Exportovat… Print… Tisk… Reconcile Accounting context Mark all as reconciled Accounting context Change: Accounting context Změna: R Header for account reconciled checkbox column Date Datum Type Typ Description Popis Name Název Description Generic Description Popis Account/Category Účet/Kategorie Deposit Vklad Withdrawal Výběr Balance Bilance Balance Account balance Zůstatek Payee/Payer Příjemce/plátce Tags Comments Deposit Money put into account Vklad Withdrawal Money taken out from account Výběr Balance Noun. Balance of an account Zůstatek New Nový Edit… Upravit… Delete Smazat Join… join transactions together Připojit… Split Up split up joined transactions Rozdělit Edit Transaction(s)… Upravit transakce… Join Transactions… Spojit transakce… Split Up Transaction Rozdělit transakci Remove Transaction(s) Odstranit transakce Mark as reconciled Reconciled: %1 (%2) Accounting context Book value: %1 (%2) Accounting context Účetní hodnota: %1 (%2) Error Chyba Invalid date. Neplatné datum. Opening date is after closing date. Closing date is before opening date. Empty transaction list. Vyprázdnit seznam transakcí. Couldn't open file for writing. Soubor nelze otevřít pro zápis. Error while writing file; file was not saved. Chyba během zápisu souboru; soubor nebyl uložen. Ledger Účetní kniha Transactions for %1 Transakce pro %1 Select Time Period From: Od: To: Do: To date is before from date. Datum do je před datumem od. Balance change: Account balance Delete transactions? Are you sure you want to delete all (%1) selected transactions? Opravdu chcete smazat všechny (%1) vybrané transakce? Cannot set the value of security transactions using the dialog for modifying multiple transactions. Financial security (e.g. stock, mutual fund) Nelze zadat hodnotu transakce s cenným papírem použitím dialogu pro změnu více transakcí. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name); Financial security (e.g. stock, mutual fund) Nelze změnit popis dividend a transakcí s cennými papíry. Cannot change payer of dividends and security transactions. Financial security (e.g. stock, mutual fund) Nelze změnit plátce dividend a transakce s cennými papíry. Opening balance Account balance Počáteční zůstatek Account Balance Adjustment Current balance: Account balance Average balance: Account balance Account Balancing Balancing of an account Zůstatek účtu Balancing Balancing of an account Rozvaha Balancing Account balancing Rozvaha Cannot set the value of security transactions using the dialog for modifying multiple transactions. Nelze zadat hodnotu transakce s cenným papírem použitím dialogu pro změnu více transakcí. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name) Nelze změnit popis dividend a transakcí s cennými papíry. Cannot change description of dividends and security transactions. Referring to the generic description property Nelze změnit popis dividend a transakcí s cennými papíry. Current debt: Total debt reduction: Total interest and fees: Number of transactions: Cannot change description of dividends and security transactions. Nelze změnit popis dividend a transakcí s cennými papíry. Cannot change payer of dividends and security transactions. Nelze změnit plátce dividend a transakce s cennými papíry. Cannot change date of transactions that are part of a split transaction. Nelze změnit datum transakcí, které jsou součástí rozdělené transakce. Initial balance Počáteční bilance Split Transaction Rozdělená transakce Debt Payment Ascending order Reduction Fee Interest Income Příjem Repayment Splátka Expense Výdaj Opening balance: Accounting context Počáteční zůstatek: Closing balance: Accounting context Description Transaction description property (transaction title/generic article name) Popis Cannot change description of dividends and security transactions. Referring to the Transaction description property (transaction title/generic article name) Nelze změnit popis dividend a transakcí s cennými papíry. Refund Úhrada Balancing Rozvaha Transfer Převod LinksWidget Remove Link All Vše Remove Odstranit MultiItemListViewItem Dividend Dividenda Income Příjem Repayment Splátka Expense Výdaj Refund Úhrada Securities Purchase Financial security (e.g. stock, mutual fund) Nákup cenných papírů Securities Sale Financial security (e.g. stock, mutual fund) Prodej cenných papírů Account Balance Adjustment Account Balancing Balancing of an account Zůstatek účtu Balancing Balancing of an account Rozvaha Security Buy Nákup cenných papírů Security Sell Prodej cenných papírů Balancing Rozvaha Transfer Převod MultipleTransactionsEditDialog Modify Transactions Změnit transakce Description: Popis: Name: Název: Generic Description: Druhový popis: Description: Transaction description property (transaction title/generic article name) Popis: Amount: Množství: Income: Příjem: Cost: Cena: Date: Datum: Category: Kategorie: Payer: Plátce: Payee: Příjemce: New Income Category Nová skupina příjmů New Expense Category Nová kategorie výdajů New Income Category… Nová kategorie příjmů… New Expense Category… Nová kategorie výdajů… Error Chyba No income category available. Žádná kategorie příjmů není k dispozici. No expense category available. Žádná kategorie výdajů není k dispozici. Invalid date. Neplatné datum. OverTimeChart Save As… Print… Tisk… Options Alternativ Source: Zdroj: Incomes and Expenses Příjmy a výdaje Profits Zisky Expenses Výdaje Incomes Příjmy All Categories Combined Všechny kategorie kombinované All Descriptions Combined Všechny popisy kombinované Theme: Chart type: Line Chart Vertical Bar Chart Horizontal Bar Chart Stacked Bar Chart Default Tags All Accounts Combined Všichni účty kombinovan All Accounts Split Rozdělení všech účty All Subcategories and Descriptions Combined Referring to the transaction description property (transaction title/generic article name) All Descriptions Split Referring to the transaction description property (transaction title/generic article name) Rozdělení všech popisů No description Referring to the transaction description property (transaction title/generic article name) Bez popisu All Payees/Payers Split Rozdělení všech příjemců/plátců No payee/payer Žádný příjemce/plátce All Tags Split Other tags Other payees/payers Other descriptions Referring to the transaction description property (transaction title/generic article name) Profits, %1 Zisky, %1 Assets Aktiva All Descriptions Combined Referring to the generic description property Všechny popisy kombinované Assets and Liabilities All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Všechny popisy kombinované All Payees/Payers Combined Všichni plátci/příjemci kombinovaní All Accounts Všechny účty Start date: Datum zahájení: End date: Datum ukončení: Value: Hodnota: Annual total Monthly total Celkem měsíčne Daily average Denní průměr Quantity Počet Average value Průměrná hodnota All Payers Combined Všichni plátce kombinovaní All Payees Combined Všichni příjemci kombinovaní All Subcategories Split All Descriptions Split Referring to the generic description property Rozdělení všech popisů No description Referring to the generic description property Bez popisu Value Hodnota Includes budgeted transactions Zahrnuje rozpočtové transakce Incomes − Expenses, %1 Příjmy − výdaje, %1 Incomes − Expenses Příjmy − výdaje Incomes & Expenses Příjmy & výdaje Incomes: %1 Příjmy: %1 Expenses: %1 Výdaje: %1 %2: %1 Incomes: %2, %1 Příjmy: %2, %1 Expenses: %2, %1 Výdaje: %2, %1 %3: %2, %1 %2, %1 Incomes: %3, %2, %1 Příjmy: %3, %2, %1 Expenses: %3, %2, %1 Výdaje: %3, %2, %1 %4: %3, %2, %1 no payee/payer žádný příjemce/plátce %3, %2, %1 Other accounts %1 Value: %2 Date: %3 MMMM yyyy Month and year All Descriptions Split Rozdělení všech popisů All Payers Split Rozdělení všech plátců All Payees Split Rozdělení všech příjemců No description Bez popisu No payer Žádný plátce No payee Žádný příjemce All Categories Split Rozdělení všech kategorií Error Chyba Invalid date. Neplatné datum. Couldn't open file for writing. Soubor nelze otevřít pro zápis. Error while writing file; file was not saved. Chyba během zápisu souboru; soubor nebyl uložen. Other payees Other payers Value (%1) Hodnota (%1) Profit (%1) Zisk (%1) Income (%1) Příjem (%1) Cost (%1) Cena (%1) Time Čas %1/%2 %1: Category; %2: Payee/Payer %1/%2 All Descriptions Combined Referring to the Transaction description property (transaction title/generic article name) Všechny popisy kombinované All Descriptions Split Referring to the Transaction description property (transaction title/generic article name) Rozdělení všech popisů No description Referring to the Transaction description property (transaction title/generic article name) Bez popisu Daily average value Daily average profit Daily average income Daily average cost Average income Average cost Annual value Annual profit Annual income Annual cost Monthly value Monthly profit Monthly income Monthly cost Includes scheduled and budgeted transactions Includes scheduled transactions Včetně plánovaných transakcí Tags, %1 Value: %1 Hodnota: %1 Assets & Liabilities Change: %1 Změna: %1 Excluding any profits or losses in trading of security shares Financial security (e.g. stock, mutual fund) Incomes & Expenses, %1 Příjmy & výdaje, %1 Incomes, %1 Příjmy, %1 Expenses, %1 Výdaje, %1 Incomes, %2: %1 Příjmy, %2: %1 Expenses, %2: %1 Výdaje, %2: %1 Incomes, %3: %2, %1 Příjmy, %3: %2, %1 Expenses, %3: %2, %1 Výdaje, %3: %2, %1 Incomes, %4: %3, %2, %1 Příjmy, %4: %3, %2, %1 Expenses, %4: %3, %2, %1 Výdaje, %4: %3, %2, %1 Liabilities Dluhy no payer žádný plátce %1/%2 %1: Description; %2: Payer/Payer %1/%2 %1/%2 %1: Description; %2: Payee/Payer %1/%2 %1/%2 %1: Generic Description; %2: Payer %1/%2 %1/%2 %1: Generic Description; %2: Payee %1/%2 %1/%2 %1: Description; %2: Payer %1/%2 no payee žádný příjemce %1/%2 %1: Description; %2: Payee %1/%2 OverTimeChartDialog Chart Graf OverTimeReport Save As… Uloẑit jako… Print… Tisk… Options Alternativ Source: Zdroj: Profits Zisky Expenses Výdaje Incomes Příjmy Assets & Liabilities All Categories Combined Všechny kategorie kombinované All Descriptions Combined Všechny popisy kombinované Columns: Sloupce: Value Hodnota Daily Denně Monthly Měsíčně Yearly Ročně Quantity Počet Average value Průměrná hodnota No description Bez popisu All Descriptions Combined Referring to the generic description property Všechny popisy kombinované No description Referring to the generic description property Bez popisu All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Všechny popisy kombinované All Accounts Všechny účty No description Referring to the transaction description property (transaction title/generic article name) Bez popisu Error Chyba Couldn't open file for writing. Soubor nelze otevřít pro zápis. Error while writing file; file was not saved. Chyba během zápisu souboru; soubor nebyl uložen. Average Profit Průměrný zisk Incomes, %1 Příjmy, %1 Average Income Průměrný příjem Expenses, %1 Výdaje, %1 Average Cost Průměrná cena Incomes, %2: %1 Příjmy, %2: %1 Incomes: %1 Příjmy: %1 Expenses, %2: %1 Výdaje, %2: %1 Expenses: %1 Výdaje: %1 Incomes, %3: %2, %1 Příjmy, %3: %2, %1 Incomes: %2, %1 Příjmy: %2, %1 Expenses, %3: %2, %1 Výdaje, %3: %2, %1 Expenses: %2, %1 Výdaje: %2, %1 Change: %1 Noun, how much the account balance has changed Změna: %1 Tags Categories Total: Celkem: Deposit Money put into account Vklad Withdrawal Money taken out from account Výběr Change Noun, how much the account balance has changed Změna Value: %1 Hodnota: %1 %2: %1 %1 %1 Average Value Průměrná hodnota %3: %2, %1 %2, %1 Year Rok Month Měsíc Assets Aktiva Deposit Vklad Withdrawal Výběr Liabilities Dluhy Daily Average Denní průměr Monthly Average Měsíční průměr Yearly Average Roční průměr Subtotal Mezisoučet Total Celkem Includes scheduled transactions Včetně plánovaných transakcí Adjusted for the average month / year (%1 / %2 days) Nastaveno na průměrný měsíc / rok (%1 / %2 dnů) All Categories Combined Referring to the generic description property Všechny kategorie kombinované OverTimeReportDialog Report Sestava QApplication Start with expenses list displayed Začněte se zobrazeným seznamem výdajů Start with incomes list displayed Začněte se zobrazeným seznamem příjmů Start with transfers list displayed Začněte se zobrazeným seznamem převodů Synchronize file Document to open Dokument k otevření %1 is already running. QObject Transfer Převod Dividend Dividenda Income Příjem Expense Výdaj Securities Purchase Financial security (e.g. stock, mutual fund) Nákup cenných papírů Securities Sale Financial security (e.g. stock, mutual fund) Prodej cenných papírů Security Buy Nákup cenných papírů Security Sell Prodej cenných papírů Debt Payment Split Transaction Rozdělená transakce RecurrenceEditWidget Enable recurrence Zapnout opakování Recurrence Rule Pravidlo opakování Daily Denně Weekly Týdně Monthly Měsíčně Yearly Ročně Recur every Opakovat každých day(s) den (dní) week(s) on: týden v: month(s), after the start month měsíc(e) po zahajovacím měsíci Recur on the Opakovat v 1st 1. 2nd 2. 3rd 3. 4th 4. 5th 5. 6th 6. 7th 7. 8th 8. 9th 9. 10th 10. 11th 11. 12th 12. 13th 13. 14th 14. 15th 15. 16th 16. 17th 17. 18th 18. 19th 19. 20th 20. 21st 21. 22nd 22. 23rd 23. 24th 24. 25th 25. 26th 26. 27th 27. 28th 28. 29th 29. 30th 30. 31st 31. Last Poslední 2nd Last 2. poslední 3rd Last 3. poslední 4th Last 4. poslední 5th Last 5. poslední day den possibly on weekend pravděpodobně o víkendu but before weekend ale před víkendem but after weekend ale po víkendu nearest weekend day year(s), after the start year rok(ů) po zahajovacím roce on nearest weekday Recur on day part before XXX of 'Recur on day XXX of month YYY' Opakovat dne of part between XXX and YYY of 'Recur on day XXX of month YYY' z On the Part before NNN in 'Recur on the NNN. WEEKDAY of MONTH' v of part between WEEKDAY and MONTH in 'Recur on NNN. WEEKDAY of MONTH' z Recur on day # Opakovat dne # of the year part after NNN of 'Recur on day #NNN of the year' roku Range… Rozsah… Occurrences/Exceptions… Výskyty/výjimky… Exceptions… Výjimky… Error Chyba No day of week selected for weekly recurrence. Není vybrán den pro týdenní opakovaní. Selected day will never occur with selected frequency and start date. Vybraný den se nikdy nevyskytne s vybranou frekvencí a datumem zahájení. Selected day does not exist in selected month. Vybraný den není součástí tohoto měsíce. RefundDialog Repayment Splátka Refund Úhrada Date: Datum: Cost: Cena: Income: Příjem: Quantity returned: Počet: Account: Účet: Quantity: Počet: Payee: Příjemce: Payer: Plátce: Comments: Poznámky: Link Link the transactions together Join Join the transactions together Spojit Error Chyba Zero value not allowed. Nulová hodnota není povolena. Invalid date. Neplatné datum. SecurityBuy Security: %1 (bought) Akcie: %1 (nakoupená) Security: %1 (bought) Financial security (e.g. stock, mutual fund) Akcie: %1 (nakoupená) SecuritySell Security: %1 (sold) Akcie: %1 (prodaná) Security: %1 (sold) Financial security (e.g. stock, mutual fund) Akcie: %1 (prodaná) SecurityTransactionsDialog Transactions for %1 Transakce pro %1 Date Datum Type Typ Value Hodnota Shares Financial shares Podíly Shares Bought Financial shares Podíly koupené Shares Bought (Recurring) Financial shares Koupené podíly (opakované) Dividend (Recurring) Dividenda (opakované) Dividend (Scheduled) Dividenda (plánované) Reinvested Dividend (Recurring) Reinvestované dividendy (opakované) Reinvested Dividend (Scheduled) Reinvestované dividendy (plánované) Shares Bought Fincancial shares Podíly koupené Shares Sold Financial shares Podíly prodané Shares Sold (Exchanged) Shares of one security directly exchanged for shares of another; Financial shares Prodej podílů (obchodovaný) Shares Bought (Exchanged) Shares of one security directly exchanged for shares of another; Financial shares Koupené podíly (obchodované) Shares Sold (Exchanged) Financial shares Prodej podílů (obchodovaný) Shares Bought (Exchanged) Financial shares Koupené podíly (obchodované) Shares Bought (Recurring) Fincancial shares Koupené podíly (opakované) Shares Sold (Recurring) Financial shares Prodané podíly (opakované) Shares Bought (Scheduled) Financial shares Koupené podíly (plánované) Shares Sold (Scheduled) Financial shares Prodané podíly (plánované) Shares Podíly Edit… Upravit… Delete Smazat Shares Bought Podíly koupené Shares Sold Podíly prodané Dividend Dividenda Reinvested Dividend Reinvestované dividendy Shares Sold (Traded) Prodej podílů (obchodovaný) Shares Bought (Traded) Koupené podíly (obchodované) Shares Bought (Recurring) Koupené podíly (opakované) Shares Sold (Recurring) Prodané podíly (opakované) Shares Bought (Scheduled) Koupené podíly (plánované) Shares Sold (Scheduled) Prodané podíly (plánované) Recurring Dividend Opakované dividendy Scheduled Dividend Plánované dividendy SplitListViewItem Dividend Dividenda Income Příjem Repayment Splátka Expense Výdaj Refund Úhrada Security Buy Nákup cenných papírů Security Sell Prodej cenných papírů Balancing Rozvaha Transfer Převod TagButton no tags TagMenu New tag… New Tag Tag: TransactionEditDialog Edit Expense Upravit výdaj Edit Dividend Upravit dividendu Edit Income Upravit příjem Edit Transfer Upravit převod Edit Securities Purchase Financial security (e.g. stock, mutual fund) Upravit nákup cenných papírů Edit Securities Sale Financial security (e.g. stock, mutual fund) Upravit prodej cenných papírů Edit Reinvested Dividend Edit Securities Bought Upravit nákup cenných papírů Edit Securities Sold Upravit prodej cenných papírů TransactionEditWidget Security: Cenný papír: Cost: Cena: Income: Příjem: Shares bought: Nakoupené cenné papíry: Shares sold: Prodané cenné papíry: All Vše Price per share: Cena za akcii: Date: Datum: Description: Popis: Name: Název: Generic Description: Druhový popis: Amount: Množství: Withdrawal: Money taken out from account Výběr: New Security… Financial security (e.g. stock, mutual fund) Nový cenný papír… Shares added: Financial shares Podíly přidané: Set security share value Total value: Celková hodnota: Deposit: Money put into account Vklad: Downpayment: Quantity: Počet: From: Od: To: Do: Category: Kategorie: To account: Na účet: Payer: Plátce: Payer of parent split transaction From account: Z účtu: Downpayment account: Payee: Příjemce: Payee of parent split transaction Lender: Tags: Associated file: Select a file Open the file Comments: Poznámky: Related to: Label for linked transactions Odkazy: New Security Financial security (e.g. stock, mutual fund) Nový cenný papír No security available. Financial security (e.g. stock, mutual fund) Žádný cenný papír k dispozici. New Account Nový účet New Income Category Nová skupina příjmů New Expense Category Nová kategorie výdajů New Account… Nový účet… New Income Category… Nová kategorie příjmů… New Expense Category… Nová kategorie výdajů… Security: Financial security (e.g. stock, mutual fund) Cenný papír: Shares bought: Financial shares Nakoupené cenné papíry: Shares sold: Financial shares Prodané cenné papíry: Price per share: Financial shares Cena za akcii: Description: Transaction description property (transaction title/generic article name) Popis: Transaction title/generic article name Number of items included in the transaction. Entered cost is total cost for all items. Error Chyba No suitable account available. Vhodný účet není k dispozici. No income category available. Žádná kategorie příjmů není k dispozici. No suitable account or income category available. Neexistuje vhodná kategorie účtů nebo příjmů. No expense category available. Žádná kategorie výdajů není k dispozici. No security available. Žádný cenný papír k dispozici. Invalid date. Neplatné datum. Cannot transfer money to and from the same account. Peníze nelze převést na stejný účet. Downpayment must be less than total cost. Cannot create a regular transfer to/from a securities account. Nelze uskutečnit pravidelný převod na/z účtu cenných papírů. Cannot create a regular income to a securities account. Nelze uskutečnit pravidelný příjem na účet cenných papírů. Zero shares not allowed. Nulové podíly nejsou povoleny. Zero value not allowed. Nulová hodnota není povolena. Zero price per share not allowed. Nulová cena není povolena. Cannot create a regular expense from a securities account. Nelze uskutečnit pravidelný výdaj z účtu cenných papírů. Loan for %1 TransactionFilterWidget From: Od: To: Do: Min amount: Min množství: Max amount: Max množství: Category: Kategorie: To account: Na účet: Min income: Min příjem: Max income: Max příjem: From account: Z účtu: Min cost: Min cena: Max cost: Max cena: Tag: Generic Description: Druhový popis: Description: Popis: Description: Transaction description property (transaction title/generic article name) Popis: Payer: Plátce: Payee: Příjemce: Include Včetně Exclude Kromě Exact match Exclude subcategories Clear Vyprázdnit All Vše Error Chyba Invalid date. Neplatné datum. To date is before from date. Datum do je před datumem od. From date is after to date. Datum od je před datumem do. TransactionListWidget Date Datum Description Popis Cost Cena Category Kategorie From Account Z účtu Payee Příjemce Tags Income Příjem To Account Na účet Payer Plátce Amount Množství From Od To Do Comments Poznámky Add Přidat Apply Použít Delete Smazat * Part of <a href="%1">split transaction</a> * Část <a href="%1">rozdělené transakce</a> Expense Výdaj Transfer Převod New/Edit %1 Nový/Upravit %1 Name Název Description Generic Description Popis Description Transaction description property (transaction title/generic article name) Popis New/Edit Expense Nový/upravit výdaj New/Edit Income Nový/upravit příjem New/Edit Transfer Nový/upravit převod Filter Filtr Quantity: Počet: Total: Celkem: Average: Průměr: Clear Vyprázdnit Cost: Cena: Monthly: Měsíčně: Sort by creation time Expenses Výdaje Incomes Příjmy Transfers Převody Quantity Počet Right align Zarovnat vpravo Total cost: Celková cena: Total income: Celkový příjem: Total amount: Celkové množství: Monthly average: Měsíční průměr: Error Chyba Cannot set the value of security transactions using the dialog for modifying multiple transactions. Financial security (e.g. stock, mutual fund) Nelze zadat hodnotu transakce s cenným papírem použitím dialogu pro změnu více transakcí. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name); Financial security (e.g. stock, mutual fund) Nelze změnit popis dividend a transakcí s cennými papíry. Cannot change payer of dividends and security transactions. Financial security (e.g. stock, mutual fund) Nelze změnit plátce dividend a transakce s cennými papíry. Cannot change date of transactions that are part of a split transaction, unless all individual transactions are selected. Cannot set the value of security transactions using the dialog for modifying multiple transactions. Nelze zadat hodnotu transakce s cenným papírem použitím dialogu pro změnu více transakcí. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name) Nelze změnit popis dividend a transakcí s cennými papíry. Cannot change date, description, expense category or payee of transactions that are part of a debt payment using the dialog for modifying multiple transactions. Referring to the transaction description property (transaction title/generic article name) Cannot change description of dividends and security transactions. Referring to the Transaction description property (transaction title/generic article name) Nelze změnit popis dividend a transakcí s cennými papíry. Cannot change description of dividends and security transactions. Referring to the generic description property Nelze změnit popis dividend a transakcí s cennými papíry. Cannot change description of dividends and security transactions. Nelze změnit popis dividend a transakcí s cennými papíry. Cannot change payer of dividends and security transactions. Nelze změnit plátce dividend a transakce s cennými papíry. Cannot change date of transactions that are part of a split transaction. Nelze změnit datum transakcí, které jsou součástí rozdělené transakce. Delete transactions? Are you sure you want to delete all (%1) transactions in the selected split transaction? Opravdu chcete vymazat všech (%1) transakcí ve vybrané rozdělené transakci? Join as multiple accounts/payments? Do you wish join the selected expenses as an expense with multiple accounts/payments? Do you wish join the selected incomes as an income with multiple accounts/payments? Are you sure you want to delete all (%1) selected transactions? Opravdu chcete smazat všechny (%1) vybrané transakce? * Part of split transaction * Část rozdělené transakce * Part of split (%1) * Část rozdělení (%1) ** Recurring (editing occurrence) **Opakování (upravující výskyt) Modify… Změnit… Edit… Upravit… Eqonomize-1.5.3/translations/eqonomize_da.ts000066400000000000000000013546511416454732000212560ustar00rootroot00000000000000 AccountComboBox New account… Ny konto… Paid with loan… Betalt med lån… Multiple accounts/payments… Flere konti / betalinger ... New income category… Ny indkomstkategori… New expense category… Ny udgiftskategori… New Account Ny konto New Income Category Ny indkomstkategori New Expense Category Ny udgiftskategori AccountsMenu All Accounts Alle konti All Categories Combined Alle kategorier kombineret %n accounts %n konto %n konti %n categories %n kategori %n kategorier Balancing Account Balance Adjustment Justering af kontosaldo Budget Balancing Name of account for transactions that adjust account balances Balancekonto Couldn't open %1 for reading Kunne ikke åbne og læse %1 No exchange rates found in the downloaded ECB data. Ingen valutakurser blev fundet i den downloadede ECB-data. Not a valid Eqonomize! file (XML parse error: "%1" at line %2, col %3) Ikke en korrekt Eqonomize!-fil (XML-parsefejl: "%1" på linje %2, kolonne %3) imported importeret Invalid root element %1 in XML document Ugyldigt rodelement %1 i XML-dokumentet Unknown XML element: "%1" at line %2, col %3 Ukendt XML-element: "%1" på række %2, kolone %3 XML parse error: "%1" at line %2, col %3 XML-tolkningsfejl: "%1" på række %2, kolone %3 Unable to load %n currency/currencies. Kan ikke indlæses %n valutaen. Kan ikke indlæses %n valutaerne. No exchange rates found in downloaded ECB data Ingen valutakurser fundet i downloadede ECB-data Unable to load %n account(s). Kan ikke indlæse %n konto. Kan ikke indlæse %n konti. Unable to load %n category/categories. Kan ikke indlæse %n kategorien. Kan ikke indlæse %n kategorierne. Unable to load %n security/securities. Financial security (e.g. stock, mutual fund) Kan ikke indlæse %n værdipapirerne. Kan ikke indlæse %n værdipapirerne. Unable to load %n transaction(s). Kan ikke indlæse %n transaktionen. Kan ikke indlæse %n transaktionerne. File is a directory Filen er en mappe European Euro Europæisk euro No exchange rates found. Ingen valutakurser fundet. USD currency missing. USD-valuta mangler. Couldn't open file for writing Kunne ikke åbne filen til skrivning Error while writing file; file was not saved Fejl under skrivning af fil, filen blev ikke gemt Download command (%1) failed: %2. Downloadkommandoen (%1) mislykkedes: %2. Failed to download file from %1: %2. Det lykkedes ikke at hente filen fra %1: %2. Upload command (%1) failed: %2. Uploadkommandoen (%1) mislykkedes: %2. yyyy-yy Financial year when first month is not January (e.g. 2018-19). yyyy/yyyy Transaction Accounts Transaktionskonti Savings Accounts Opsparingskonti Credit Cards Kreditkort Debts Gæld Securities Financial security (e.g. stock, mutual fund) Værdipapirer Cash Kontanter Transaction Account Transaktionskonto Savings Account Opsparingskonto Credit Card Kreditkort Debt Gæld Other Andet Unnamed Unavngivet Uncategorized Ikke kategoriseret CategoriesComparisonChart Save As… Gem som… Print… Udskriv… From Fra To Til Source: Kilde: Theme: Tema: Chart type: Diagramtype: Pie Chart Cirkeldiagram Vertical Bar Chart Lodret søjlediagram Horizontal Bar Chart Horisontellt søjlediagram Bar Chart søjlediagram Default Standard All Expenses, without subcategories Alle udgifter uden underkategorier All Expenses, with subcategories Alle udgifter med underkategorier All Incomes, without subcategories Alle indkomster, uden underkategorier All Incomes, with subcategories Alle indkomster, med underkategorier All Accounts Alle konti Expenses: %1 Udgifter: %1 Incomes: %1 Indkomster: %1 Error Fejl Invalid date. Forkert dato. To date is before from date. Slutdato er før startdato. From date is after to date. Startdato er efter slutdato. Couldn't open file for writing. Kunne ikke åbne og skrive til filen. Error while writing file; file was not saved. Fejl ved skrivning af fil; filen blev ikke gemt. Expenses Udgifter Expenses, %1 Udgifter, %1 Incomes, %1 Indkomster, %1 Incomes Indkomster Accounts Konti Expenses, %2: %1 Udgifter, %2: %1 Incomes, %2: %1 Indkomster, %2: %1 Other descriptions Referring to the transaction description property (transaction title/generic article name) Andre beskrivelser No description Referring to the transaction description property (transaction title/generic article name) Ingen beskrivelse Other accounts Andre konti Other categories Andre kategorier Value Værdi Income Indkomst Cost Omkostninger %1 Value: %2 %1Value: %2 %1Værdi: %2 CategoriesComparisonChartDialog Chart Diagram CategoriesComparisonReport Save As… Gem som… Print… Udskriv… Source: Kilde: All Categories, excluding subcategories Alle kategorier, exklusive underkategorier All Categories, including subcategories Alle kategorier, inclusive underkategorier All Tags Alle etiketter All Payees and Payers Alle betalingsmodtagere og betalere Subcategories Underkategorier All Categories Alle kategorier Expenses: %1 Udgifter: %1 Incomes: %1 Indkomster: %1 Tag: %1 Etikette: %1 All Accounts Alle konti Payees/payers for Betalingsmodtagere / betalere for Period: Periode: From Fra To Til Columns: Kolonner: Value Værdi Daily Dagligt Monthly Månadsligt Yearly Årligt Quantity Kvantitet Average value Gennemsnitlig værdi All payees Alle betalingsmodtagere All payers Alle betalere Descriptions for Referring to the transaction description property (transaction title/generic article name) Beskrivelser for All Payees/Payers Alle betalingsmodtagere / betalere Descriptions Referring to the transaction description property (transaction title/generic article name) Beskrivelser Months Måneder Years År Tags Etiketter Total: Totalt: All descriptions Referring to the transaction description property (transaction title/generic article name) Alle Beskrivelser All payees/payers Alle betalingsmodtagere / betalere No description Referring to the transaction description property (transaction title/generic article name) Ingen beskrivelse No payee Ingen betalingsmodtager No payer Ingen betaler Error Fejl Invalid date. Ugyldig dato. To date is before from date. Slutdato er før startdato. From date is after to date. Startdato er efter slutdato. Couldn't open file for writing. Kunne ikke åbne filen til skrivning. Error while writing file; file was not saved. Fejl under skrivning af fil filen blev ikke gemt. Expenses, %2: %1 Udgifter, %2: %1 Expenses, %3: %2, %1 Udgifter, %3: %2, %1 Incomes, %2: %1 Indkomster, %2: %1 Incomes, %3: %2, %1 Indkomster, %3: %2, %1 %3: %2, %1 %3: %2, %1 %2: %1 %2: %1 Tags, %1 Etiketter, %1 Incomes & Expenses, %1 Indkomster og udgifter, %1 Expenses: %2, %1 Udgifter: %2, %1 Incomes: %2, %1 Indkomster: %2, %1 %2, %1 %2, %1 %1 %1 Incomes & Expenses Indkomster og udgifter %1 (%2&ndash;%3) html format; %1: title; %2: from date; %3: to date %1 (%2 &ndash; %3) %1 (to %2) html format; %1: title; %2: to date %1 (till %2) Category Kategori Payee Modtagare Description Referring to the transaction description property (transaction title/generic article name) Beskrivelse Cost Omkostninger Payer Betalere Income Indkomst Payee/Payer Betalingsmodtager / Betaler Tag Etikett Daily Average Dagligt gennemsnit Monthly Average Månedligt gennemsnit Yearly Average Årligt gennemsnit Average Cost Gennemsnitlige Omkostninger Average Income Gennemsnitlig indkomst Average Value Gennemsnitlig værdi No payee/payer Ingen betalingsmodtager / betaler Total Ialt Total incomes Total indkomster Total expenses Totale udgifter Total (Profits) Totalte(Fortjenester) CategoriesComparisonReportDialog Report Rapport ConfirmScheduleDialog The following transactions was scheduled to occur today or before today. Confirm that they have indeed occurred (or will occur today). Følgende transaktioner var planlagt til at forekomme i dag eller før i dag. Bekræft, at de faktisk er sket (eller vil forekomme i dag). Date Dato Type Type Description Transaction description property (transaction title/generic article name) Beskrivelse Amount Værdi Edit… Rediger… Postpone… Udskyde… Delete Slet Error Fejlj Can only postpone to future dates. Kan kun udsættes til fremtidige datoer. ConfirmScheduleListViewItem Transfer Overførsel Dividend Udbytte Income Indkomst Expense Udgift Securities Purchase Financial security (e.g. stock, mutual fund) Værdipapirkøb Securities Sale Financial security (e.g. stock, mutual fund) Værdipapirsalg Debt Payment Gældsbetaling CurrencyConversionDialog Currency Converter Valutaomregner DebtFee Debt payment: %1 (fee) Gældsbetaling: %1 (gebyr) DebtInterest Debt payment: %1 (interest) Gældsbetaling: %1 (rente) DebtPayment Debt payment: %1 Gældsbetaling: %1 DebtReduction Debt payment: %1 (reduction) Gældsbetaling: %1 (gældsnedbringelse) DescriptionsMenu All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Alle beskrivelser kombineret All Tags Combined Alle etiketter kombineret All Payees Combined Alle betalingsmodtagere kombineret All Payers Combined Alle betalere kombineret All Payees/Payers Combined Alle betalingsmodtagere / betalere kombineret No description Referring to the transaction description property (transaction title/generic article name) Ingen beskrivelse No payee Ingen betalingsmodtager No payer Ingen betaler No payee/payer Ingen betalingsmodtager / betaler %n descriptions Referring to the transaction description property (transaction title/generic article name) %n beskrivelse %n beskrivelser %n tags %n etiket %n etiketter %n payees %n betalingsmodtagere %n betalingsmodtagere %n payers %n betalere %n betalere %n payees/payers %n betalingsmodtagere / betalere %n betalingsmodtagere / betalere EditAssetsAccountDialog Type: Type: Cash Kontanter Savings Account Opsparingskonto Credit Card Kreditkort Transactional Account Transaktionskonto Debt Gæld Securities Værdipapirer Other Andet Group: Gruppe: no group ingen gruppe Currency: Valuta: Edit Rediger Name: Navn: Bank: Bank: Debt: Gæld: Transferred to: Overført til: Date: Dato: Lender: Långiver: Default account for budgeted transactions Standardkonto for budgetterede transaktioner Description: Beskrivelse: Account is closed Kontoen er lukket Zero value not allowed. Nul værdi er ikke tilladt. New currency... Ny valuta... Warning Advarsel If you change the currency of an account, the currency of all associated transactions will also change, without any conversion. Do do wish to continue anyway. Hvis du ændrer en kontos valuta, ændres også valutaen for alle tilknyttede transaktioner uden nogen konvertering. Vil du stadig fortsætte. Type cannot be changed to securities for accounts with transactions. Type kan ikke ændres til værdipapirer for konti med transaktioner. Issuer: Udsteder: Error Fejl Transaction Account Transaktionskonto Opening balance: Account balance Åbnings balance: Opening balance Account balance Åbnings balance New currency… Ny valuta… If you change the currency of an account, the currency of all associated transactions will also change, without any conversion. Do do wish to continue anyway? Hvis du ændrer en kontos valuta, ændres også valutaen for alle tilknyttede transaktioner uden nogen konvertering. Vil du stadig fortsætte? Empty name. Tomt navn. The entered name is used by another account. Navnet bruges af en anden konto. EditCurrencyDialog Edit Currency Rediger valuta New Currency Ny valuta Code: Kode: Symbol: Symbol: Prefix Prefix Suffix Suffix Default Standard Name: Navn: Decimals: Decimaler: Date: Dato: Main currency Hovedvaluta Error Fejl Error saving currencies: %1. Fejl ved gemning af valutaer: %1. Failed to save currencies. Kunne ikke gemme valutaer. Empty code. Tom kode. Code already exists. Koden findes allerede. EditDebtPaymentDialog Debt Payment Gældsbetaling EditDebtPaymentWidget Debt: Gæld: Date: Dato: Debt reduction: Gældsreduktion: Reduction payment: Gældsreduktion betaling: Interest: Renter: Paid Betalt Added to debt Lagt til gælden Fee: Afgift: Account: Konto: Expense category: Udgiftskategori: Associated file: Tilknyttet fil: Select a file Vælg en fil Open the file Åbn filen Comments: Kommentarer: Related to: Label for linked transactions Relateret til: Total value: Total værdi: Error Fejl No suitable account available. Ingen passende konto tilgængelig. Invalid date. Forkert dato. Interest must not be zero. Renten må ikke være nul. At least one value must non-zero. Mindst en værdi skal være andet end nul. EditExceptionsDialog Edit Exceptions Rediger undtagelser Occurrences: Forekomster: Add Exception Tilføj undtagelser Remove Exception Fjern undtagelser Exceptions: Undtagelser: Only the first fifty occurrences are shown. Kun de første halvtreds forekomster vises. EditExpensesAccountDialog Name: Navn: Parent category: Overordnet kategori: None Ingen Monthly budget: Månedligt budget: Description: Beskrivelse: Error Fejl Empty name. Tomt navn. The entered name is used by another expense category. Navnet bruges af en anden udgiftskategori. EditIncomesAccountDialog Name: Navn: Parent category: Overordnet kategori: None Ingen Monthly budget: Månedligt budget: Description: Beskrivelse: Error Fejl Empty name. Tomt navn. The entered name is used by another income category. Navnet bruges af en anden indkomstkategori. EditMultiAccountDialog Expense with Multiple Payments Omkostninger med flere betalinger Income with Multiple Payments Indkomst med flere betalinger EditMultiAccountWidget Quantity: Kvantitet: Category: Kategori: Comments: Kommentarer: Transactions: Transaktioner: Date Dato Account Konto Description: Transaction description property (transaction title/generic article name) Beskrivelse: Tags: Etiketter: Associated file: Tilknyttet fil: Select a file Vælg en fil Open the file Åbn filen Related to: Label for linked transactions Relateret til: Payee Betalingsmodtager Payer Betaler Cost Omkostning Income Indkomst New Ny Edit… Rediger… Delete Slet Total cost: Totale omkostninger: New Tag Ny etikette Tag: Etikette: Total value: Total værdi: Error Fejl No suitable expense categories available. Ingen passende udgiftskategori er tilgængelig. A split must contain at least two transactions. En delt transaktion skal indeholde mindst to transaktioner. EditMultiItemDialog Split Transaction Delt transaktion EditMultiItemWidget Date: Dato: Account: Konto: Payee/Payer: Betalingsmodtager / betaler: Transactions: Transaktioner: Type Type Description: Transaction description property (transaction title/generic article name) Beskrivelse: Tags: Etiketter: Associated file: Tilknyttet fil: Select a file Vælg en fil Open the file Åben filen Comments: Kommentarer: Related to: Label for linked transactions Relateret til: Description Transaction description property (transaction title/generic article name) Beskrivelse Payment Betaling Deposit Indsættelse Account/Category Konto/kategori Value Værdi Income Indkomst Expense Udgift New Ny New Expense… Ny udgift… New Income… Ny indkomst… New Deposit… Ny indsættning… New Withdrawal… Ny hævning… New Securities Purchase… Financial security (e.g. stock, mutual fund) Nyt værdipapir køb… New Securities Sale… Financial security (e.g. stock, mutual fund) Nyt værdipapirsalg… New Dividend… Nyt udbytte… Edit… Rediger… Delete Slet Total value: Total værdi: Error Fejl No suitable account available. Ingen egnet konto tilgængelig. Invalid date. Forkert dato. A split must contain at least two transactions. En delt transaktion skal indeholde mindst to transaktioner. Cannot transfer money to and from the same account. Kan ikke overføre penge til og fra den samme konto. EditQuotationsDialog Date Dato Quotes Financial quote Kurser Price per Share Financial Shares Pris per andel Add Tilføje Modify Ændre Delete Slet Import… Importer… Export… Exporter… Quotes for %1 Financial quote Kurser for %1 Error Fejl Couldn't open %1 for reading. Kunne ikke åbne og læse %1. Error reading %1. Fejl ved læsning af %1. Successfully imported %n quote(s). Succesfuld importeret kurser til %n dato. Succesfuld importeret kurser til %n dato. Unable to import any quotes. Kunne ikke importere kurser. Failed to import %n data row(s). Det lykkedes ikke at importere %n datarække. Det lykkedes ikke at importere %n datarækker. Required columns missing. Den nødvendige kolonne mangler. Invalid value. Ugyldig værdi. Invalid date. Forkert dato. No data found. Ingen data fundet. Information Information Unrecognized date format. Ukendt datoformat. Specify Format Angiv format The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. Formatet på dato og / eller nummer i CSV-filen er tvetydigt. Vælg det korrekte format. Date format: Datoformat: Value format: Værdiformat: Couldn't open file for writing. Kunne ikke åbne og skrive til fil. Quotes: %1 Kurser: %1 Error while writing file; file was not saved. Fejl ved skrivning til fil; filen blev ikke gemt. EditRangeDialog Edit Recurrence Range Rediger gentagelsesområde Begins on: %1 Starter ved: %1 No ending date Ingen slutdato End after Slut efter occurrence(s) förekomst(er) End on Slut på Error Fejl Invalid date. Forkert dato. End date before start date. Slutdato er efter startdato. EditReinvestedDividendDialog Reinvested Dividend Geninvesteret udbytte Security: Financial security (e.g. stock, mutual fund) Værdipapirer: Shares added: Financial shares Aktier tilføjet: Date: Dato: Error Fejl Invalid date. Forkert dato. EditScheduledDebtPaymentDialog Transaction Transaktion Recurrence Retur Edit Debt Payment Rediger gældsbetaling New Debt Payment Ny gældsbetalning EditScheduledMultiAccountDialog Transactions Transaktioner Recurrence Retur New Expense with Multiple Payments Ny udgift med flere betalinger New Income with Multiple Payments Ny indkomst med flere betalinger Edit Expense with Multiple Payments Rediger udgift med flere betalinger Edit Income with Multiple Payments Rediger indkomst med flere betalinger EditScheduledMultiItemDialog Transactions Transaktioner Recurrence Retur New Split Transaction Ny delt transaktion Edit Split Transaction Rediger delt transaktion EditScheduledTransactionDialog Expense Udgift Dividend Udbytte Income Indkomst Reinvested Dividend Geninvesteret udbytte Transfer Overførsel Securities Purchase Financial security (e.g. stock, mutual fund) Værdipapirkøb Securities Sale Financial security (e.g. stock, mutual fund) Værdipapirsalg Recurrence Vende tilbage New Expense Ny udgift New Expense Paid with Loan Ny udgift betalt med lån New Dividend Nyt udbytte New Income Ny indkomst New Transfer Ny overførsel New Securities Purchase Financial security (e.g. stock, mutual fund) Nyt værdipapir køb New Reinvested Dividend Nyt geninvesteret udbytte New Securities Sale Financial security (e.g. stock, mutual fund) Nyt værdipapirsalg Edit Reinvested Dividend Redigera återinvesterad utdelning Edit Securities Purchase Financial security (e.g. stock, mutual fund) Rediger værdipapirkøb Edit Securities Sale Financial security (e.g. stock, mutual fund) Rediger værdipapirsalg Edit Expense Rediger udgift Edit Dividend Rediger udbytte Edit Income Rediger indkomst Edit Transfer Rediger overførsel EditSecurityDialog Type: Type: Mutual Fund Gensidig Fond Stock Financial stock Aktie Other Andet Name: Navn: Account: Konto: Decimals in shares: Financial shares Decimaler i aktier: Initial shares: Financial shares Indledende aktier: Decimals in quotes: Financial quote Decimaler i kursangivelser: Initial quote: Financial quote Indledende kursus: Date: Dato: Description: Beskrivelse: Error Fejl Empty name. Tomt navn. No suitable account available. Ingen egnet konto tilgængelig. No suitable account or income category available. Ingen egnede konti eller indkomst kategorier er tilgængelige. EditSecurityTradeDialog All Alle Securities Exchange Shares of one security directly exchanged for shares of another; Financial security (e.g. stock, mutual fund) Værdipapirudveksling From security: Financial security (e.g. stock, mutual fund) Fra værdipapirer: Shares moved: Financial shares Aktier flyttet: To security: Financial security (e.g. stock, mutual fund) Til værdipapirer: Shares received: Financial shares Aktier tilføjet: Value: Værdi: Date: Dato: Error Fejl No other security available for exchange in the account. Shares of one security directly exchanged for shares of another; Financial security (e.g. stock, mutual fund) Der er ingen andre værdipapirer, der kan udveksles på kontoen. Selected to and from securities are the same. Financial security (e.g. stock, mutual fund) Valgte værdipapirer skal være forskellige. Zero shares not allowed. Financial shares Nul aktier er ikke tilladt. Invalid date. forkert dato. Zero value not allowed. Nul værdi er ikke tilladt. Eqonomize Accounts && Categories Konti og kategorier Expenses Udgifter Incomes Indkomster Transfers Overførsler Schedule Planlægning Account / Category Konto / kategori Remaining Budget (%1) Resterende budget (%1) Change (%1) Ændring (%1) Total (%1) Total (%1) Accounts Konton Includes budgeted transactions Inkluderer budgetterede transaktioner Assets Aktiver Tags Etiketter Period Periode From Fra To Til Select Period Vælg periode Current Month Indeværende måned Current Year Indeværende år Current Whole Month Nuværende hel måned Current Whole Year Nuværende helår Whole Past Month Hele sidste måned Whole Past Year Hele sidste år Previous Month Forrige måned Previous Year Forrige år Show partial budget Vis delbudget Edit Budget Rediger budget Budget: Budget: Month: Måned: Result previous month: Resultater sidste måned: New Transaction Ny transaktion Name Navn Value Værdi Cost Omkostninger Profit Overskud Yearly Rate Årlig rente Type Type Account Konto Statistics Period Statistikperiod Ny tidsplan Edit Rediger Remove Fjern Next Occurrence Næste forekomst Amount Værdi Payee/Payer Betalingsmodtager / betaler Comments Kommentarer Set Schedule Confirmation Time Sæt tid for bekræftelse af planlægning Schedule confirmation time: Tid til planlægningsbekræftelse: Set Budget Period Angiv budgetperiode First day in budget month: Første dag i budgetmåneden: 1st 1. 2nd 2. 3rd 3. 4th 4. 5th 5. 6th 6. 7th 7. 8th 8. 9th 9. 10th 10. 11th 11. 12th 12. 13th 13. 14th 14. 15th 15. 16th 16. 17th 17. 18th 18. 19th 19. 20th 20. 21st 21. 22nd 22. 23rd 23. 24th 24. 25th 25. 26th 26. 27th 27. 28th 28. Last Sidste 2nd Last 2. sidste 3rd Last 3. sidste 4th Last 4. sidste 5th Last 5. sidste Timestamp Tidsstempel Links Links Remove Link Fjern link Link to "%1" create link to transaction (link used as verb) Link til "%1" Information Information Select a transaction and choose %1 in the menu, to create a link between the transactions. To cancel, right-click the menu item. Vælg en transaktion, og vælg %1 i menuen for at oprette et link mellem transaktionerne. For at annullere skal du højreklikke på menupunktet. Do not show this message again Vis ikke denne besked igen Link Transaction(s) create link to transaction (link used as verb) Link transaktion (er) All Alle Cash Kontanter Synchronization Settings Synkroniseringsindstillninger Web address: web adresse: Download command: Downloads kommando: Duplicate Transaction… duplicate as verb Duplicer transaktion… New Tag… Ny etikette… Rename Tag… Omdøb etikette… Remove Tag Fjern etiketten New Tag Ny etikette Tag name: Navn på etiketten: Remove tag? Fjern etiketten? Do you wish to remove the tag "%1" from %n transaction(s)? Vil du slette etiketten "%1" fra %n transaktionen? Vil du slette etiketten "%1" fra %n transaktionerne? Do you wish to remove the tag "%1" from %2 transaction(s)? Vil du slette etiketten "%1" fra %2 transaktion(er)? Rename Tag Omdøb etiketten Transaction Account Transaktionskonto Select Font… Vælg skrifttype… Transaction Accounts Transaktionskonti Savings Accounts Opsparingskonti Credit Cards Kreditkort Debts Gæld Securities Værdipapirer optional valgfri Upload command: Upload kommando: mandatory nødvendig %f = local file, %u = url %f = lokal fil, %u = url Automatic synchronization Automatisk synkronisering Upload Upload Uploading… Uploader… Error uploading file Fejl ved uploadning af fil Error uploading %1: %2. Fejl ved uploadning af %1: %2. Synchronizing… Synkroniserer… Error synchronizing file Fejl ved synkronisering af fil Error synchronizing %1: %2. Fejl ved synkronisering af %1: %2. Synchronization error Synkroniseringsfejl Synchronize file? Synkroniser fil? The file has been modified by a different user or program. Do you wish to merge changes? Filen er blevet ændret af en bruger eller et andet program. Vil du flette ændringerne? &Synchronize &Synkroniser Reconcile Account… Afstem konto… Cloud Synchronization (experimental)… Cloud Sync (eksperimentel)… Only use this when unable to find the cause of the incorrect recorded account balance. Brug kun dette, når årsagen til den forkert bogførte kontosaldo ikke kan findes. Reopen Account Mark account as not closed Genåbn kontoen Reopen Account Genåbn kontoen Updating exchange rates... Opdater valutakurser... Abort Afbryd Failed to download exchange rates from %1: %2. Det lykkedes ikke at hente valutakurser fra %1: %2. Error reading data from %1: %2. Fejl ved læsning af data fra %1: %2. Unrecognized Currency Ukendt valuta No exchange rate is available for the default currency (%1). If you wish to use multiple currencies you should set the exchange rate manually. Ingen valutakurser er tilgængelige for den forvalgte valuta (%1). Hvis du vil bruge flere valutaer, skal du indtaste valutakursen manuelt. Set Main Currency Indtast hovedvalutaen Currency: Valuta: New currency... Ny valuta... Replace all occurrences of the former main currency Erstat alle forekomster af tidligere hovedvaluta Update Exchange Rates Opdater valutakurser Adjust balance… Referring to account balance Juster saldo… Show payee and quantity Vis betalningsmodtagare og antal Show quantity and payer/payee properties for incomes and expenses. Vis mængde og betaler / kvittering for indtægter og udgifter. Set Main Currency… Angiv hovedvaluta… Adjust Account Balance Juster kontosaldo of which %1 is balance adjustment Referring to account balance hvoraf %1 er en balancejustering Total value: Total værdi: Cost: Omkostninger: Profit: Indtjening: Rate: Rente: Error Fejl Date: Dato: New Schedule First month in budget year: Første måned i budgetåret: Invalid date. Forkert dato. Future dates are not allowed. Fremtidige datoer er ikke tilladt. Bond Obligation Mutual Fund Gensidig Fond Other Andet Right align Højrejuster Add Loan Tilføj lån Add Category Tilføj kategori Ledger Finanskonto To date is before from date. Slutdato er før startdato. From date is after to date. Startdato er efter slutdato. Savings Account Opsparingskonto Salary Løn Bills Regninger Clothing Beklædning Groceries Dagligvarer Leisure Fritid Import Options Importmuligheder Ignore duplicate transactions Spring over transaktionsdubletter Rename duplicate accounts Omdøb kontodubletter Rename duplicate categories Omdøb kategoridubletter Rename duplicate securities Omdøb værdipapirer dubletter Couldn't open file Kunne ikke åbne filen Error loading %1: %2. Fejl ved læsning af %1: %2. %f = local file (temporary), %u = url %f = lokal fil (midlertidig), %u = url Couldn't save file Kunne ikke gemme filen Error saving %1: %2. Fejl ved lagring af %1: %2. New version available Ny version tillgænglig A new version of %1 is available.<br><br>You can get version %2 at %3. En ny version af %1 er tilgængelig. <br><br> Du kan få version %2 på %3. Transaction Schedule Planlagte transaktioner Total Total Accounts &amp; Categories html format Konti og kategorier Accounts &amp; Categories (%1&ndash;%2) html format Konti og kategorier (%1 &ndash; %2) Accounts &amp; Categories (to %1) html format Konti og kategorier (til %1) Change Noun, how much the account balance has changed Ændre Current Account Transaktionskonto Credit Card Kreditkort Liabilities Forpligtelser Description Transaction description property (transaction title/generic article name) Beskrivelse Category Kategori Budget Budget Remaining Budget Resterende budget Error saving currencies: %1. Fejl ved gemning af valutaer: %1. Total Incomes Samlede indtægter Costs Omkostninger Total Expenses Totale udgifter Account/Category Noun, how much the account balance has changed Konto/kategori Empty expenses list. Tom udgiftsliste. Empty incomes list. Tom indkomstliste. Empty transfers list. Tom overførselsliste. Empty schedule list. Ingen planlagte transaktioner på listen. Couldn't open file for writing. Kunne ikke åbne og skrive til fil. Error while writing file; file was not saved. Fejl ved skrivning af fil; filen blev ikke gemt. &File &Fil &Accounts &Konti &Transactions &Transaktioner &Loans &Lån Stat&istics Stat&istik S&ettings I&nställningar &Help &Hjælp File Fil Transactions Transaktioner Statistics Statistik &New &Ny &Open… &Åben… Open Recent Åbn senest Clear List Ryd liste &Save &Gemme Save As… Gemme som… &Revert &Nulstil S&ynchronize S&ynkroniser &Print… &Udskriv… Print Preview… Forhåndsvisning… Import Importer Import CSV File… Importer CSV-fil… Import QIF File… Importer QIF-fil… Export View… Eksporter visning… Export As QIF File… Eksporter QIF-fil… &Quit &Afslut Add Account… Tilføj konto… New Account… Nyt konto… New Income Category… Ny indkomstkategori… New Expense Category… Ny udgiftskategori… Add Account Tilføj konto Securities Financial security (e.g. stock, mutual fund) Værdipapirer New Security… Financial security (e.g. stock, mutual fund) Nyt værdipapir… Shares Financial shares Aktier New Security Financial security (e.g. stock, mutual fund) Nyt værdipapir Edit Security Financial security (e.g. stock, mutual fund) Rediger værdipapirer Delete security? Financial security (e.g. stock, mutual fund) Fjern værdipapireret? Are you sure you want to delete the security "%1" and all associated transactions? Financial security (e.g. stock, mutual fund) Er du sikker på, at du vil slette værdipapiret "%1" og alle relaterede transaktioner? No security available. Financial security (e.g. stock, mutual fund) Ingen værdipapir er tilgængelig. Price per share: Financial shares Pris pr. Aktie: Security Transactions Financial security (e.g. stock, mutual fund) Værdipapierstransaktioner Stock Financial stock Aktie Updating exchange rates… Opdater valutakurser… Failed to save currencies. Kunne ikke gemme valutaer. New currency… Ny valuta… Balance Noun. Balance of an account Saldo Empty securities list. Financial security (e.g. stock, mutual fund) Tom værdipapirslist. &Securities Financial security (e.g. stock, mutual fund) &værdipapirer Import %1 File… Importer %1 fil… Currency Converter Valutaomregner New Loan… Nyt lån… Edit… Rediger… Close Luk Show Transactions Vis transaktioner Show Ledger Vis finanskonto New Expense… Ny udgift… New Income… Ny indkomst… New Transfer… Ny overførsel… New Split Transaction… Ny delt transaktion… New Expense with Multiple Payments… Ny udgift med flere betalinger… Refund… Tilbagebetaling… Repayment… Tilbagebetaling… New Refund/Repayment… Ny Tilbagebetaling… Edit Transaction(s) (Occurrence)… Rediger transaktion(er) (tillfälle)… Edit Occurrence… Rediger forekomst… Edit Schedule (Recurrence)… Rediger tidsplan (gentagelser)… Edit Schedule… Rediger planlægning… Edit Split Transaction… Rediger delt transaktion… Duplicate Transaction… Kopi af transaktion… Join Transactions… join transactions together Slå transaktioner sammen… Edit Timestamp… Rediger tidsstempel… New Debt Payment… Ny gældsbetaling… New Unpaid Interest… Ny ubetalt rente… New Expense Paid with Loan… Ny udgift betalt med lån… Edit Security… Financial security (e.g. stock, mutual fund) Rediger værdipapir… Remove Security Financial security (e.g. stock, mutual fund) Fjern værdipapiret Shares Bought… Financial shares Aktier købt… Shares Sold… Financial shares Aktier solgt… Show quantity and payer/payee for incomes and expenses. Vis antal og betaler / betalingsmodtager for indkomster og udgifter. Use Exchange Rate for Transaction Date Brug valutakurs for transaktionsdato Use the exchange rate nearest the transaction date, instead of the latest available rate, when converting the value of transactions. Brug valutakursen for den dato, der er tættest på transaktionsdatoen, i stedet for den senest tilgængelige valutakurs, når du konverterer transaktionsværdier. Set Budget Period… Indstil budgetperiode… Set Schedule Confirmation Time… Indstil tidsplan for bekræftelse af plan… Backup Frequency Hyppighed for sikerhedskopiering Daily Dagligt Weekly Ugentligt Fortnightly Hver fjortende dag Monthly Månedligt Never Aldrig Dark Mode Mørk tilstand Language Sprog Default Forvalgt About %1 Om %1 New tag… Ny etikette… Rename tag… Omdøb etiket… Remove tag Fjern etiket Restart required Genstart nødvendig Please restart the application for the language change to take effect. Genstart venligst programmet, så sprogskiftet træder i kraft. A personal accounting program Et personligt regnskabsprogram License: GNU General Public License Version 3 Licens: GNU General Public License Version 3 %1 exited unexpectedly before the file was saved and data was lost. Do you want to load the last auto-saved version of the file? %1 afsluttedes uventet, før filen blev gemt, og data gik tabt. Vil du indlæse den sidste automatisk gemte version af filen? Split Up Transaction split up joined transactions Opdel transaktionen Link Transactions create link between selected transactions (link used as verb) Link transaktioner Create Link to Transaction Opret link til transaktion Close Account Mark account as closed Luk konto Create Link create link to or between transaction(s) Opret link Remove Transaction(s) (Occurrence) Fjern transaktion (er) (forekomst) Remove Occurrence Fjern forekomst Delete Schedule (Recurrence) Slet tidsplan (gentagelse) Delete Schedule Slet tidsplan Remove Split Transaction Fjern delt transaktion Dividend… Udbytte… Reinvested Dividend… Geninvesteret udbytte… Transactions… Transaktioner… Development Over Time Report… Rapport om udvikling over tid… Categories Comparison Report… Rapport til sammenligning af kategorier… Development Over Time Chart… Diagram med utveckling över tid… Categories Comparison Chart… Diagram til sammenligning af kategorier… Use Additional Transaction Properties Anvend yderligere egenskaper for transaktioner Initial Period Oprindeligt valgt periode Remember Last Dates Husk de seneste datoer Help Hjælp Report Bug Rapporter fejl About Qt Om Qt Crash Recovery Genopretning efter nedbrud Untitled Unavngivet Checking Account Transactional account Kontrol af Transaktionskonto Select Associated File Vælg tilknyttet fil Open Associated File Åbn tilknyttet fil Shares Exchanged… Shares of one security directly exchanged for shares of another; Financial shares Aktier flyttet… Shares of one security directly exchanged for shares of another Financial shares Aktier i et vædipapir, der direkte udveksles med aktier i et andet Edit Quotes… Financial quote Rediger kursangivelser… Eqonomize! Accounting File Eqonomize! Regnskabsfil Close Account Luk kontoen Save file? Gem filen? The current file has been modified. Do you want to save it? Den aktuelle fil er blevet ændret. Vil du gemme den? Confirm Schedule Bekræft planlagte transaktioner New Account Ny konto New Loan Nyt lån New Income Category Ny indkomstkategori New Expense Category Ny udgiftskategori Book value: Bogførte værdi: Real value: Reelle værdi: Edit Account Rediger konto Edit Income Category Rediger indkomstkategori Edit Expense Category Rediger udgiftskategori Remove subcategories? Fjern underkategorier? Do you wish to remove the category including all subcategories? Vil du slette kategorien, inklusive alle underkategorier? Move transactions? Flyt transaktioner? Move to: Flyt til: Remove irreversibly from all accounts (do not do this if account has been closed!) Fjern uigenkaldeligt fra alle konti (Gør ikke dette, hvis kontoen er lukket!) The category contains some expenses. What do you want to do with them? Kategorien indeholder nogle udgifter. Hvad vil du gøre med dem? The category contains some incomes. What do you want to do with them? Kategorien indeholder nogle indtægter. Hvad vil du gøre med dem? The account contains some transactions. What do you want to do with them? Kontoen indeholder nogle transaktioner. Hvad vil du gøre med dem? Remove Category? Slet kategorien? The category contains some expenses that will be removed. Do you still want to remove the category? Kategorien indeholder nogle udgifter, der fjernes. Vil du stadig slette kategorien? The category contains some incomes that will be removed. Do you still want to remove the category? Kategorien indeholder nogle udgifter, der fjernes. Vil du stadig slette kategorien? Remove Account? Slet kontoen? The account contains some transactions that will be removed. Do you still want to remove the account? Kontoen indeholder nogle transaktioner, der fjernes. Vil du stadig slette kontoen? %2 of %1 %1: budget; %2: remaining budget %2 av %1 Set Quote… Financial quote Indtast kurs… Quote Financial quote Kurs Set Quote (%1) Financial quote Indtast kurs (%1) Reopen Genåben %1 (with no budget) %1 (uden budget) %1 (with budget %2) %1 (med budget %2) EqonomizeCalendarWidget Today Idag EqonomizeDateEdit Today Idag EqonomizeTranslator OK Only used when Qt translation is missing OK Cancel Only used when Qt translation is missing Annuller Close Only used when Qt translation is missing Luk Yes Only used when Qt translation is missing Ja No Only used when Qt translation is missing Nej &Yes Only used when Qt translation is missing &Ja &No Only used when Qt translation is missing &Nej &Open Only used when Qt translation is missing &Åben &Save Only used when Qt translation is missing &Gem &Select All Only used when Qt translation is missing &Vælg alt Select All Only used when Qt translation is missing Vælg alt Look in: Only used when Qt translation is missing Se i: File &name: Only used when Qt translation is missing Fil&navn: Files of type: Only used when Qt translation is missing Filer af typen: EqonomizeValueEdit Error Fejl Empty denominator. Tom tæller. Empty factor. Tom faktor. Division by zero. Division med nul. Unknown or ambiguous currency, or unrecognized characters, in expression: %1. Ukendt eller tvetydig valuta eller ukendte tegn i udtryk: %1. Empty base. Tom base. Empty exponent. Tom exponent. Unrecognized characters in expression. Ukendte tegn i udtryk. ExportQIFDialog Export QIF File Exporter QIF-fil Account: Konto: All All accounts Alle Date format: Datoformat: Value format: Værdiformat: File: Fil: Error Fejl Selected file is a directory. Valgte fil er en mappe. Overwrite Overskriv The selected file already exists. Would you like to overwrite the old copy? Filen findes allerede. Vil du overskrive den gamle kopi? Couldn't open file for writing. Kunne ikke åbne og skrive til fil. Error while writing file; file was not saved. Fejl ved skrivning til fil; filen blev ikke gemt. ImportCSVDialog Import CSV file Importer CSV-fil Transaction Type Selection Valg af transaktionstype Expenses Udgifter Incomes Indkomster Transfers Overførsler Expenses and incomes (negative cost) Udgifter og indtægter (negative omkostninger) Expenses and incomes (separate columns) Udgifter og indtægter (separate kolonner) All types Alle typer Presets: Forudindstillinger: File Selection Valg af fil File: Fil: First data row: Første datarække: Auto Auto Column delimiter: Kolonne afgrænsere: Comma Komma Tabulator Tabulator Semicolon Semikolon Space Mellemrum Other Andet Columns Specification Kolonne specifikation Description: Transaction description property (transaction title/generic article name) Beskrivelse: The same column number is selected multiple times. Do you wish to proceed anyway? Det samme kolonnenummer er valgt flere gange. Vil du fortsætte? Column Kolonne Value Værdi Cost: Omkostninger: Date: Dato: Category: Kategori: From account: Fra konto: Quantity: Mængde: Payee: Modtager: Tags: Etiketter: Comments: Kommentarer: Create missing categories and accounts Opret manglende kategorier og konti Save Preset Gem forudindstilling Imports data as expenses. Costs have positive value. Value is the only required column. Importerer data som udgifter. Omkostninger har en positiv værdi. Værdi er den eneste nødvendige kolonne. Imports data as incomes. Value is the only required column. Importerer data som indkomst. Omkostninger har positiv værdi. Værdi er den eneste nødvendige kolonne. Income: Indkomst: To account: Til konto: Payer: Betaler: Imports data as transfers. Value is the only required column. Importerer data som overførsler. Værdi er den eneste nødvendige kolonne. Amount: Værdi: Imports data as expenses and incomes. Costs have negative value. Value and category are both required columns. Importerer data såsom udgifter og indtægter. Omkostninger har en negativ værdi. Værdi og kategori er begge nødvendige kolonner. Value: Værdi: Account: Konto: Payee/payer: Betalingsmodtager / betaler: Imports data as expenses and incomes. Costs and incomes have separate columns. Income, cost, and category are all required columns. Importerer data som udgifter og indkomster. Omkostninger og indkomster har separate kolonner. Indtægter, omkostninger og kategori er alle nødvendige kolonner. Imports data as expenses, incomes, and transfers. Costs have negative or positive value. Value, to, and from are all required columns. Accounts and categories must be existing. Importerer data såsom udgifter, indtægter og overførsler. Omkostninger har en negativ eller positiv værdi. Værdi, til og fra er alle nødvendige kolonner. Konti og kategorier skal eksistere. From: Fra: To: Til: Error Fejl A file must be selected. En fil skal vælges. Selected file is a directory. Den valgte fil er en mappe. Selected file does not exist. Den valgte fil findes ikke. Empty delimiter. Tom afgrænser. The same column number is selected multiple times. Det samme kolonnenummer valgt flere gange. Selected from account is the same as the to account. Valgte fra konto er den samme som til konto. Invalid date. Ugyldig Dato. Couldn't open %1 for reading. Kunne ikke åbne og læse %1. Error reading %1. Fejl ved læsning af %1. Uncategorized Ikke kategoriseret Successfully imported %n transaction(s). Succesfuld importeret %n transaktion. Succesfuld importeret %n transaktioner. Unable to import any transactions. Kunne ikke importere transaktioner. Failed to import %n data row(s). Kunne ikke importere %n datarække. Kunne ikke importere %n datarækker. Balancing account wrongly used. Referring to the account used for adjustments of account balances. Balance konto brugt forkert . Required columns missing. Nødvendig kolonne mangler. Save as preset… Gem som forudindstillet… Imports data as expenses and incomes. Costs have negative value. Value is the only required column. Importer data som udgifter og indkomster. Omkostninger har en negativ værdi. Værdi er den eneste nødvendige kolonne. Imports data as expenses and incomes. Costs and incomes have separate columns. Income and cost both all required columns. Importer data som udgifter og indkomster. Omkostninger og indkomster har separate kolonner. Indtægter og omkostninger begge alle krævede kolonner. Warning Advarsel The same column number is selected multiple times. Proceed? Det samme kolonne nummer er valgt flere gange. Vil du fortsætte? Invalid value. Ugyldig værdi. Empty category name. Tomt kategorinavn. Empty account name. Tomt kontonavn. Unknown category found. Ukendt kategori fundet. Unknown account found. Ukendt konto fundet. Cannot import security transactions (to/from security accounts). Kan ikke importere værdipapirtransaktioner (til / fra værdipapirkonto). Same to and from account/category. Samme til og fra konto / kategori. No data found. Ingen data fundet. Information Information Unrecognized date format. Ukendt datoformat. Specify Format Angiv format The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. Formatet på dato og / eller nummer i CSV-filen er tvetydigt. Vælg det korrekte format. Date format: Datoformat: Value format: Værdiformat: ImportQIFDialog Import QIF file Importer QIF-fil File Selection Valg af fil Select a QIF file to import. When you click next, the file be analysed and you might need to answer some questions about the format of the file. Vælg en QIF-fil, til import. Når du klikker på næste, analyseres filen, og det kan være nødvendigt at du besvarer nogle spørgsmål om filens format. File: Fil: Local Definitions Lokala definitioner Unknown elements where found in the QIF file. It is possible that this is because of localized type names. Please map them to the correct standard names. Programmet fandt ukendte elementer i QIF-filen. Det er muligt, at dette skyldes brugen af ​​oversatte typenavne. Match disse med de korrekte standardnavne. Local Text Lokal tekst Standard Text Standard tekst Select standard text: Vælg standardtekst: Date Format Datoformat The date format in the QIF file is ambiguous. Please select the correct format. Datoformatet i QIF-filen er tvetydigt. Vælg det korrekte format. Date format: Datoformat: Default Account Standard konto Could not find any account definitions in the QIF file. Please select a default account. It is also possible that this is caused by a localized opening balance text. Programmet fandt ingen kontodefinitioner i QIF-filen. Vælg en standardkonto. Det er muligt, at dette skyldes en oversat åbningsbalancetekst. Default account: Standard konto: Opening balance text: Tekst til åbningsbalance: Import File Importer fil No (further) issues were found. Press finish to import the selected QIF file. Ingen (yderligere) problemer blev fundet. Tryk på Udfør for at importere den valgte QIF-fil. Ignore duplicate transactions Spring over transaktionsdubletter Error Fejl A file must be selected. En fil skal vælges. Selected file is a directory. Den valgte fil er en mappe. Selected file does not exist. Den valgte fil findes ikke. Couldn't open %1 for reading. Kunne ikke åbne og læse %1. Error reading %1. Fejl ved læsning af %1. Unknown Ukendt Account Konto Bank Bank Cash Kontanter Cat (Category) Cat (Kategori) CCard (Credit Card) CCard (Kreditkort) Invst (Investment) Invest (Investering) Oth A (Other Assets) Oth A (Andre aktiver) Oth L (Other Liabilities) Oth L (Anden gæld) Security Security (Værdipapirer) Other Andet Unrecognized date format. Ukendt Dato format. Successfully imported %n transaction(s). Succesfuld importeret %n transaktion. Succesfuld importeret %n transaktioner. Successfully imported %n account(s). Succesfuld importeret %n konto. Succesfuld importeret %n konti. Successfully imported %n category/categories. Succesfuld importeret %n kategori. Succesfuld importeret %n kategorier. %n duplicate transaction(s) was ignored. %n transaktionskopi blev ignoreret. %n transaktionskopier blev ignoreret. Failed to import %n transaction(s). Det lykkedes ikke at importere %n transaktion. Det lykkedes ikke at importere %n transaktioner. %n security/securities were not imported. Financial security (e.g. stock, mutual fund) %n værdipapirer blev ikke importeret. %n værdipapirer blev ikke importeret. %n security transaction(s) were not imported. Financial security (e.g. stock, mutual fund) %n værdipapirtransaktion blev ikke importeret. %n værdipapirtransaktion blev ikke importeret. Information Information Income Dividend: %1 Udbytte: %1 Reinvested dividend: %1 Geninvesteret udbytte: %1 LedgerDialog Account: Konto: Edit Account… Rediger konto… Export… Exporter… Print… Udkriv… Mark all as reconciled Accounting context Marker alle som afstemte Opening balance: Accounting context Åbningssaldo: Closing balance: Accounting context Afslutningssaldo: R Header for account reconciled checkbox column A Date Dato Type Type Account/Category Konto/kategori Deposit Indskyde Withdrawal Hævning Balance Noun. Balance of an account Saldo Yes Ja No Nej New Ny Edit… Rediger… Delete Slet Join… join transactions together Flet… Split Up split up joined transactions Opdel Reconciled value: <b>%1</b> (%2) Accounting context Afstemt værdi: <b>%1</b> (%2) Book value: <b>%1</b> (%2) Accounting context Bogført værdi: <b>%1</b> (%2) Mark as reconciled Accounting context Markere som afstemte Error Fejl Invalid date. Forkert Dato. Opening date is after closing date. Startdato er efter slutdato. Closing date is before opening date. Slutdato er efter startdato. Ascending sort Stigende sortering Empty transaction list. Tom transaktionsliste. Couldn't open file for writing. Kunne ikke åbne og skrive til fil. Error while writing file; file was not saved. Fejl ved skrivning af fil; filen blev ikke gemt. Ledger Regnskab Transactions for %1 Transaktioner for %1 Select Time Period Vælg tidsperiode From: Fra: To: Til: To date is before from date. Slutdato er før startdato. Balance change: Account balance Saldoændringer: Delete transactions? Slet transaktioner? Are you sure you want to delete all (%1) selected transactions? Er du sikker på, at du vil slette alle (%1) valgte transaktioner? Cannot set the value of security transactions using the dialog for modifying multiple transactions. Financial security (e.g. stock, mutual fund) Kan ikke angive værdien af værdipapirtransaktioner ned dialogen til ændring af flere transaktioner. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name); Financial security (e.g. stock, mutual fund) Kan ikke ændre beskrivelsen for udbytte og værdipapirtransaktioner. Cannot change payer of dividends and security transactions. Financial security (e.g. stock, mutual fund) Kan ikke ændre betalere af udbytte og værdipapirtransaktioner. Opening balance Account balance Åbnings saldo Account Balance Adjustment Justering af kontosaldo Current balance: Account balance Nuværende saldo: Average balance: Account balance Genemsnitlig saldo: Current debt: Nuværende gæld: Edit Transaction(s)… Rediger transaktion(er)… Join Transactions… Flet transaktioner… Split Up Transaction Opdel transaktionen Open Associated File Åbn den tilhørende fil Remove Transaction(s) Slet transaktion(er) Mark as reconciled Marker som afstemt Reconciled: %1 (%2) Accounting context Afstemt: %1 (%2) Ascending order Stigende orden Total debt reduction: Totale gældsreduction: Total interest and fees: Samlede renter og gebyrer: Number of transactions: Antal transaktioner: Split Transaction Delt transaktion Reconcile Accounting context Kontoafstemning Change: Accounting context Ændring: Reconciled Accounting context Afstemt Payee/Payer Betalingsmodtager / betaler Comments Kommentarer Deposit Money put into account Indskud Withdrawal Money taken out from account Hævet Reconciled value: %1 (%2) Accounting context Afstemt værdi: %1 (%2) Book value: %1 (%2) Accounting context Bogført værdi: %1 (%2) Debt Payment Betaling af gæld Tags Etiketter Reduction Nedsættelse Fee Afgift Interest Rente Income Indkomst Repayment Tilbagebetaling Expense Udgift Description Transaction description property (transaction title/generic article name) Beskrivelse Refund Tilbagebetaling Transfer Overførsel LedgerListViewItem Yes Ja No Nej LinksWidget Remove Link Fjern link All Alle Remove Fjern MultiItemListViewItem Dividend Udbytte Income Indkomst Repayment Tilbagebetaling Expense Udgift Refund Tilbagebetaling Securities Purchase Financial security (e.g. stock, mutual fund) Værdipapirkøb Securities Sale Financial security (e.g. stock, mutual fund) Værdipapirsalg Account Balance Adjustment Justering af saldo Transfer Overførsel MultipleTransactionsEditDialog Modify Transactions Ændre transaktioner Description: Transaction description property (transaction title/generic article name) Beskrivelse: Amount: Værdi: Income: Indkomst: Cost: Omkostninger: Date: Dato: Category: Kategori: Payer: Betaler: Payee: Modtager: Error Fejl No income category available. Ingen indkomstkategori er tilgængelig. No expense category available. Ingen udgiftskategori er tilgængelig. Invalid date. forkert dato. OverTimeChart Save As… Gem som… Print… Udskriv… Source: Kilde: Incomes and Expenses Indkomster og udgifter Profits Fortjenste Expenses Udgifter Incomes Indkomster All Categories Combined Alle kategorier kombineret Theme: Tema: Chart type: Diagramtype: Line Chart Linjediagram Vertical Bar Chart Lodret søjlediagram Horizontal Bar Chart Vandret søjlediagram Stacked Bar Chart Stablet søjlediagram All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Alle beskrivelser kombineret All Subcategories and Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Alle underkategorier og beskrivelser kombineret All Descriptions Split Referring to the transaction description property (transaction title/generic article name) Alle beskrivelser opdelt No description Referring to the transaction description property (transaction title/generic article name) Ingen beskrivelse Other descriptions Referring to the transaction description property (transaction title/generic article name) Andre beskrivelser Profits, %1 Fortjenste, %1 Assets Aktiver Assets and Liabilities Aktiver og passiver All Payees/Payers Combined Alle betalingsmodtagere / betalere kombineret All Accounts Alle konti Start date: Startdato: End date: Slutdato: Value: Værdi: Annual total Årligt total Monthly total Månedligt total Daily average Dagligt gennemsnit Quantity Mængde Average value Gennemsnitlig værdi All Payers Combined Alle betalere kombineret All Payees Combined Alle betalingsmodtagere kombineret All Subcategories Split Alle underkategorier opdelte Annual value Årlig værdi Annual profit Årligt overskud Annual income Årlig indkomst Annual cost Årlige omkostninger Includes budgeted transactions Inkluder budgeterede transaktioner Value: %1 Værdi: %1 Assets & Liabilities Aktiver & passiver Change: %1 Ændring: %1 Incomes & Expenses, %1 Indkomster og udgifter, %1 Incomes & Expenses Indkomster og udgifter Incomes, %1 Indkomster, %1 Expenses, %1 Udgifter, %1 Incomes, %2: %1 Indkomster, %2: %1 Incomes: %1 Indkomster: %1 Expenses, %2: %1 Udgifter, %2: %1 Expenses: %1 Udgifter: %1 Incomes, %3: %2, %1 Indkomster, %3: %2, %1 Incomes: %2, %1 Indkomster: %2, %1 Expenses, %3: %2, %1 Udgifter, %3: %2, %1 Expenses: %2, %1 Udgifter: %2, %1 Incomes, %4: %3, %2, %1 Indkomster, %4: %3, %2, %1 Incomes: %3, %2, %1 Indkomster: %3, %2, %1 Expenses, %4: %3, %2, %1 Udgifter, %4: %3, %2, %1 Expenses: %3, %2, %1 Udgifter: %3, %2, %1 no payee/payer ingen betalingsmodtager / betaler Liabilities Forpligtelser Other accounts Andre konti %1 Value: %2 Date: %3 %1 Værdi: %2 Dato: %3 MMMM yyyy Month and year MMMM, yyyy All Payers Split Alle betalere opdelt All Payees Split Alle betalingsmodtagere opdelt No payer ingen betaler No payee Ingen betalingsmodtager All Categories Split Alle kategorier opdelt Error Fejl Invalid date. forkert dato. Couldn't open file for writing. Kunne ikke åbne og skrive til fil. Error while writing file; file was not saved. Fejl ved skrivning af fil; filen blev ikke gemt. Other payees Andre betalingsmodtagere Other payers Andre betalere Time Tid %1/%2 %1: Category; %2: Payee/Payer %1/%2 Default Standard Tags Etiketter All Accounts Combined Alle konti kombineret All Accounts Split Alle konti opdelt All Payees/Payers Split Alle betalingsmodtagere / betalere opdelt No payee/payer Ingen betalingsmodtagere / betalere All Tags Split Alle etiketter opdelt Other tags Andre etiketter Other payees/payers Andre betalingsmodtagere / betalere Value Værdi Daily average value Daglig gennemsnitsværdi Daily average profit Daglig gennemsnitlig fortjeneste Daily average income Daglig gennemsnitlig indkomst Daily average cost Daglige gennemsnitlige omkostninger Average income Gennemsnitlig indkomst Average cost Gennemsnitlige omkostninger Monthly value Månedlig værdi Monthly profit Månedlig overskud Monthly income Månedlig indkomst Monthly cost Månedlige omkostninger Includes scheduled and budgeted transactions Inkluderer planlagte og budgetterede transaktioner Includes scheduled transactions Inkluderer planlagte transaktioner Incomes, %2: 1 Indkomster, %2: 1 Tags, %1 Etiketter, %1 Incomes − Expenses, %1 Indkomster − udgifter, %1 Incomes − Expenses Indkomster − udgifter Excluding any profits or losses in trading of security shares Financial security (e.g. stock, mutual fund) Eksklusive overskud eller tab ved værdipapirhandel %2: %1 %2: %1 %3: %2, %1 %3: %2, %1 %2, %1 %2, %1 %4: %3, %2, %1 %4: %3, %2, %1 %3, %2, %1 %3: %2, %1 %1/%2 %1: Description; %2: Payer/Payer %1/%2 %1/%2 %1: Description; %2: Payee/Payer %1/%2 no payer ingen utbetalare no payee ingen betalingsmodtager OverTimeChartDialog Chart Diagram OverTimeReport Save As… Gem som… Print… Udskriv… Source: Kilde: Profits Fortjeneste Expenses Udgifter Incomes Indkomster Tags Etiketter All Categories Combined Alle kategorier kombineret Columns: Kolonner: Categories Kategorier Total: Totalt: Value Værdi Daily Dagligt Monthly Månedligt Yearly Årligt Quantity Mængde Average value Gennemsnitlig værdi All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Alle beskrivelser kombineret Assets & Liabilities Aktiver og passiver All Accounts Alle konti No description Referring to the transaction description property (transaction title/generic article name) Ingen beskrivelse Error Fejl Couldn't open file for writing. Kunne ikke åbne og skrive til fil. Error while writing file; file was not saved. Fejl ved skrivning af fil; filen blev ikke gemt. Average Profit Gennemsnitlig fortjeneste Incomes, %1 Indkomster, %1 Average Income Gennemsnitlig indkomst Expenses, %1 Udgifter, %1 Average Cost Gennemsnitlige omkostninger Incomes, %2: %1 Indkomster, %2: %1 Incomes: %1 Indkomster: %1 Expenses, %2: %1 Udgifter, %2: %1 Expenses: %1 Udgifter: %1 Incomes, %3: %2, %1 Indkomster, %3: %2, %1 Incomes: %2, %1 Indkomster: %2, %1 Expenses, %3: %2, %1 Udgifter, %3: %2, %1 Expenses: %2, %1 Udgifter: %2, %1 Change: %1 Noun, how much the account balance has changed Ændring: %1 Average Change Gennemsnitlig ændring Change Noun, how much the account balance has changed Ændring Value: %1 Værdi: %1 Year År Month Måned Assets Aktiver Deposit Indskud Withdrawal Hævning Liabilities Forpligtelser %2: %1 %2: %1 %1 %1 Average Value Gennemsnitlig værdi %3: %2, %1 %3: %2, %1 %2, %1 %2, %1 Daily Average Dagligt genomsnitt Monthly Average Månatligt gennemsnit Yearly Average Årligt gennemsnit Subtotal Subtotal Total Total Deposit Money put into account Indskud Withdrawal Money taken out from account Hævning Includes scheduled transactions Inkluderer planlagte transaktioner Adjusted for the average month / year (%1 / %2 days) Justeret for den gennemsnitlige måned / år(%1 / %2 dagar) OverTimeReportDialog Report Rapport QApplication Start with expenses list displayed Start med udgiftslisten vist Start with incomes list displayed Start med indkomstlisten vist Start with transfers list displayed Start med overførselslisten vist Synchronize file Synkroniser fil Document to open Dokument til åbening %1 is already running. %1 kører allerede. QObject Transfer Overførsel Dividend Udbytte Income Indkomst Expense Udgift Securities Purchase Financial security (e.g. stock, mutual fund) Værdipapirkøb Securities Sale Financial security (e.g. stock, mutual fund) Værdipapirsalg Debt Payment Gældsbetalning Split Transaction Delt transaktion RecurrenceEditWidget Enable recurrence Aktivér gentagelse Recurrence Rule Regler for gentagelse Daily Dagligt Weekly Ugentligt Monthly Månedligt Yearly Årligt Recur every Gentag efter day(s) dag(e) week(s) on: uge(r) på: month(s), after the start month måned(er), efter startdo Recur on the Gentag den 1st 1. 2nd 2. 3rd 3. 4th 4. 5th 5. 6th 6. 7th 7. 8th 8. 9th 9. 10th 10. 11th 11. 12th 12. 13th 13. 14th 14. 15th 15. 16th 16. 17th 17. 18th 18. 19th 19. 20th 20. 21st 21. 22nd 22. 23rd 23. 24th 24. 25th 25. 26th 26. 27th 27. 28th 28. 29th 29. 30th 30. 31st 31. Last Sidste 2nd Last Næst sidste 3rd Last 3.sidste 4th Last 4.sidste 5th Last 5.sidste day dagen possibly on weekend muligt i weekenden but before weekend men før weekenden but after weekend men efter weekenden nearest weekend day næste weekend dag year(s), after the start year år, efter startåret on nearest weekday på næste hverdag Recur on day part before XXX of 'Recur on day XXX of month YYY' Gentag på dag of part between XXX and YYY of 'Recur on day XXX of month YYY' i On the Part before NNN in 'Recur on the NNN. WEEKDAY of MONTH' På den of part between WEEKDAY and MONTH in 'Recur on NNN. WEEKDAY of MONTH' i Recur on day # Gentag på dag # of the year part after NNN of 'Recur on day #NNN of the year' af året Range… Omfang… Occurrences/Exceptions… Forekomster / undtagelser… Error Fejl No day of week selected for weekly recurrence. Ingen hverdag valgt til ugentlig gentagelse. Selected day will never occur with selected frequency and start date. Den valgte dag vil aldrig forekomme med den valgte frekvens og startdato. Selected day does not exist in selected month. Den valgte dag findes ikke i den valgte måned. RefundDialog Repayment Tilbagebetaling Refund Tilbagebetaling Date: Dato: Cost: Omkostninger: Income: Indkomst: Quantity returned: Mængde returneret: Account: Konto: Quantity: Mængde: Payee: Betalingsmodtager: Payer: Betaler: Comments: Kommentarer: Link Link the transactions together Sammenføj Join Join the transactions together Sammenføj Error Fejl Zero value not allowed. Nul værdi er ikke tilladt. Invalid date. forkert dato. SecurityBuy Security: %1 (bought) Financial security (e.g. stock, mutual fund) Værdipapirer: %1 (købt) SecuritySell Security: %1 (sold) Financial security (e.g. stock, mutual fund) Værdipapirer: %1 (solgt) SecurityTransactionsDialog Transactions for %1 Transaktioner for %1 Date Dato Type Type Value Værdi Shares Financial shares Aktier Shares Bought Financial shares Aktier købt Shares Bought (Recurring) Financial shares Købte aktier (tilbagevendende) Dividend (Recurring) Udbytte (tilbagevendende) Dividend (Scheduled) Utdelning (planerad) Reinvested Dividend (Recurring) Återinvesterad utdelning (återkommande) Reinvested Dividend (Scheduled) Återinvesterad utdelning (planerad) Recurring Reinvested Dividend Återkommande återinvesterad utdelning Scheduled Reinvested Dividend Planerad återinvesterad utdelning Shares Sold Financial shares Andelar sålda Shares Sold (Exchanged) Shares of one security directly exchanged for shares of another; Financial shares Andelar sålda (flyttade) Shares Bought (Exchanged) Shares of one security directly exchanged for shares of another; Financial shares Andelar köpta (flyttade) Shares Sold (Recurring) Financial shares Andelar sålda (återkommande) Shares Bought (Scheduled) Financial shares Andelar köpta (planerad) Shares Sold (Scheduled) Financial shares Andelar sålda (planerad) Edit… Redigera… Delete Ta bort Dividend Utdelning Reinvested Dividend Återinvesterad utdelning Recurring Dividend Återkommande utdelning Scheduled Dividend Planerad utdelning TagButton no tags inga etiketter TagMenu New tag… Ny etikett… New Tag Ny etikett Tag: Etikett: TransactionEditDialog Edit Expense Redigera utgift Edit Dividend Redigera utdelning Edit Income Redigera inkomst Edit Transfer Redigera överföring Edit Securities Purchase Financial security (e.g. stock, mutual fund) Redigera värdepappersköp Edit Securities Sale Financial security (e.g. stock, mutual fund) Redigera värdepappersförsäljning Edit Reinvested Dividend Redigera återinvesterad utdelning TransactionEditWidget Cost: Omkostninger: Income: Inkomst: All Alla Date: Dato: Amount: Værdi: Downpayment: Handpenning: Shares added: Financial shares Andelar tillkomna: Value per share: Financial shares Värde per andel: Set security share value Uppdatera kurs för värdepapper Total value: Totalt värde: Quantity: Kvantitet: From: Från: To: Till: Category: Kategori: To account: Till konto: Payer: Betaler: From account: Från konto: Downpayment account: Konto för handpenning: Payee: Mottagare: Lender: Långivare: Comments: Kommentarer: No security available. Financial security (e.g. stock, mutual fund) Inget värdepapper finns tillgängligt. Security: Financial security (e.g. stock, mutual fund) Værdipapirer: New Security… Financial security (e.g. stock, mutual fund) Nytt värdepapper… Shares bought: Financial shares Köpta andelar: Shares sold: Financial shares Sålda andelar: Price per share: Financial shares Pris per andel: Description: Transaction description property (transaction title/generic article name) Beskrivelse: Transaction title/generic article name Transaktionstitel/allmänt artikelnamn Withdrawal: Uttag: Deposit: Insättning: Withdrawal: Money taken out from account Uttag: Deposit: Money put into account Insättning: Number of items included in the transaction. Entered cost is total cost for all items. Antal enheter inkluderade i transaktionen. Angiven kostnad är total kostnad för alla enheter. Payer of parent split transaction Betaler for overordnet delte transaktion Payee of parent split transaction Mottagare för överordnad delad transaktion Tags: Etiketter: Associated file: Tilknyttet fil: Select a file Vælg en fil Open the file Åben filen Related to: Label for linked transactions Relateret til: New Security Financial security (e.g. stock, mutual fund) Nyt værdipapirer Error Fejl No suitable account available. Ingen egnet konto tilgængelig. No income category available. Ingen indkomstkategori er tilgængelig. No suitable account or income category available. Ingen egnede konti eller indkomstkategorier er tilgængelige. No expense category available. Ingen udgiftskategori er tilgængelig. Invalid date. forkert dato. Cannot transfer money to and from the same account. Kan ikke overføre penge til og fra den samme konto. Downpayment must be less than total cost. Udbetalingen skal være lavere end de samlede omkostninger. Cannot create a regular transfer to/from a securities account. Kan ikke oprette en standardoverførsel til / fra en værdipapirkonto. Cannot create a regular income to a securities account. Kan ikke generere en regelmæssig indkomst til en værdipapirkonto. Zero shares not allowed. Nul aktier er ikke tilladt. Zero value not allowed. Nul værdi er ikke tilladt. Zero price per share not allowed. Nulpris pr. Aktie er ikke tilladt. Cannot create a regular expense from a securities account. Kan ikke oprette en normal udgift fra en værdipapirkonto. Loan for %1 Lån til %1 New Tag Ny etikette Tag: Etikette: TransactionFilterWidget From: Fra: To: Til: Min amount: Laveste værdi: Max amount: Maksimal værdi: Category: Kategori: To account: Till konto: Min income: Minimumsindkomst: Max income: Højeste indkomst: From account: Fra konto: Min cost: Laveste omkostninger: Max cost: Højeste omkostning: Description: Transaction description property (transaction title/generic article name) Beskrivelse: Tag: Etikette: Payer: Betaler: Payee: Betalingsmodtager: Include Inkludera Exclude Ekskluder Exact match Præcis match Exclude subcategories Udeluk underkategorier Clear Tøm All Alle Error .Fejl Invalid date. forkert dato. To date is before from date. Slutdato er før startdato. From date is after to date. Startdato er efter slutdato. TransactionListWidget Date Dato Cost Omkostninger Category Kategori From Account Fra konto Payee Betalingsmodtager Tags Etiketter Income Indkomst To Account Til konto Payer Betaler Amount Værdi From Fra To Til Comments Kommentarer Add Tilføj Apply Ansøg Delete Slet * Part of <a href="%1">split transaction</a> * Del af <a href="%1">delt transaktion</a> Description Transaction description property (transaction title/generic article name) Beskrivelse New/Edit Expense Ny/Ændre udgift New/Edit Income Ny/Ændre indkomst New/Edit Transfer Ny/Ændre overførsel Filter Filter Quantity: Mængde: Total: Total: Average: Genemsnit: Clear Tøm Cost: Omkostninger: Monthly: Månedligt: Sort by creation time Sorter efter bogføringstidspunkt Expenses Udgifter Incomes Indkomster Transfers Overførsler Quantity Mængde Right align Højrejuster Total cost: Samlede omkostninger:: Total income: Samlede indtægter: Total amount: Samlet værdi: Monthly average: Månedligt gennemsnit: Error .Fejl Cannot set the value of security transactions using the dialog for modifying multiple transactions. Financial security (e.g. stock, mutual fund) Kan ikke angive værdi for værdipapirtransaktioner med dialogen for at ændre flere transaktioner. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name); Financial security (e.g. stock, mutual fund) Kan ikke ændre beskrivelsen af ​​udbytte og værdipapirtransaktioner. Cannot change payer of dividends and security transactions. Financial security (e.g. stock, mutual fund) Kan ikke ændre betaler af udbytte og værdipapirtransaktioner. Cannot change date, description, expense category or payee of transactions that are part of a debt payment using the dialog for modifying multiple transactions. Referring to the transaction description property (transaction title/generic article name) Dato, benämning, utgiftskategori och mottagare kan inte ändras för skuldbetalningar i dialogen för att ändra flera transaktioner. Cannot change date of transactions that are part of a split transaction, unless all individual transactions are selected. Kan inte ändra datum på transaktioner som ingår i en delad transaktion, såvida inte alla enskilda transaktioner är valda. Cannot change date of transactions that are part of a split transaction, unless all transactions are selected. Kan ikke ændre datoen for transaktioner, der er inkluderet i en delt transaktion, medmindre alle transaktioner er valgt. Cannot change date or payee/payer of transactions that are part of a split transaction or debt payment, unless all transactions are selected. Kan ikke ændre dato eller betalingsmodtager / betaler for transaktioner, der er en del af en delt transaktion eller gældsbetaling, medmindre alle transaktioner er valgt. Cannot change date or payee/payer of transactions that are part of a split transaction. Kan ikke ændre dato eller betalingsmodtager / betaler på transaktioner, der er en del af en delt transaktion. Delete transactions? Slet transaktioner? Are you sure you want to delete all (%1) transactions in the selected split transaction? Vil du virkelig slette alle (%1) transaktioner i den valgte splittransaktion?? Join as multiple accounts/payments? Flet som flere konti / betaling? Do you wish join the selected expenses as an expense with multiple accounts/payments? Vil du kombinere de valgte udgifter som en udgift med flere konti / betalinger? Do you wish join the selected incomes as an income with multiple accounts/payments? Vil du kombinere den valgte indkomst som en indkomst med flere konti / betalinger? Are you sure you want to delete all (%1) selected transactions? Vil du virkelig slette alle (%1) valgte transaktioner?? * Part of split transaction * Del af delt transaktion * Part of split (%1) * Del af delt (%1) ** Recurring (editing occurrence) ** Tilbagevendende (redigering forekomst) * Part of <a href="split transaction">split transaction</a> * Del af <a href="Delt transaction">delt transaktion</a> Modify… Ændre… Edit… Rediger… currencies.xml U.S. Dollar U.S. dollar Japansese Yen Japanske yen Bulgarian Lev Bulgariske lev Czech Koruna Tjeckiske koruna Danish Krone Danske kroner British Pound Brittiske pund Hungarian Forint Ungerske forint Polish Zloty Polske zloty Romanian New Leu Rumänske ny leu Swedish Krona Svenske kroner Swiss Franc Schweiziske franc Norwegian Krone Norske kroner Croatian Kuna Kroatiske kuna Russian Ruble Rusiske rubler Turkish New Lira Turkiske ny lira Australian Dollar Australiensiske dollar Brazilian Real Brazilianske real Canadian Dollar Kanadensiske dollar Chinese Yuan Renminbi Kinesiske yuan renminbi Hong Kong Dollar Hong Kong-dollar Indonesian Rupiah Indonesisk rupe Israeli New Sheqel Israeliske sheqel Indian Rupee Indiske rupie South Korean Won Sydkoreanske won Mexican Peso Mexikanske peso Malaysian Ringgit Malaysiske ringgit New Zeeland Dollar Nya Zeeländske dollar Philippine Peso Filippinske peso Singapore Dollar Singapor dollar Thai Baht Thailändske baht South African Rand Sydafrikanske rand Eqonomize-1.5.3/translations/eqonomize_de.ts000066400000000000000000017651341416454732000212640ustar00rootroot00000000000000 Your names NAME OF TRANSLATORS Martin F. Hohenberg, Elias Probst, Frank S. Thomas, Martin F. Hohenberg,,Launchpad Contributions:,Elias Probst,Frank S. Thomas,Martin F. Hohenberg Your emails EMAIL OF TRANSLATORS martin.hohenberg@gmail.com, mail@eliasprobst.eu, fst@debian.org, martin.hohenberg@gmail.com,,,mail@eliasprobst.eu,fst@debian.org,martin.hohenberg@gmail.com Balancing Bilanzieren Couldn't open %1 for reading Konnte %1 nicht zum Lesen öffnen Not a valid Eqonomize! file (XML parse error: "%2" at line %3, col %4) Keine gültige Eqonomize!-Datei (XML-Analysefehler: "%2" in der Zeile %3, Spalte %4) Invalid root element %1 in XML document Ungültiges Wurzelelement %1 im XML-Dokument Unable to load 1 account. Konnte 1 Konto nicht laden. Konnte %1 Konten nicht laden. Unable to load 1 category. Konnte 1 Kategorie nicht laden. Konnte %1 Kategorien nicht laden. Unable to load 1 security. Konnte 1 Wertpapier nicht laden. Konnte %1 Wertpapiere nicht laden. Unable to load 1 transaction. Konnte 1 Transaktion nicht laden. Konnte %1 Transaktionen nicht laden. File is a directory Datei ist ein Verzeichnis Couldn't open file for writing Konnte Datei nicht zum Schreiben öffnen Error while writing file; file was not saved Fehler beim Schreiben der Datei; Datei wurde nicht gespeichert From Von To Nach Source: Quelle: All Expenses Alle Ausgaben All Incomes Alle Einnahmen All Accounts Alle Konten Expenses: %1 Ausgaben: %1 Incomes: %1 Einnahmen: %1 Invalid date. Ungültiges Datum. To date is before from date. "Bis"-Datum liegt vor dem "Von"-Datum From date is after to date. "Von"-Datum liegt hinter dem "Bis"-Datum No description Keine Beschreibung All Categories Alle Kategorien Descriptions for Beschreibungen für Payees/payers for Zahlungsempfänger/Zahlungspflichtiger für Period: Dauer: Columns: Spalten: Value Wert Daily Täglich Monthly Monatlich Yearly Jährlich Quantity Anzahl Average value Durchschnittlicher Wert All descriptions Alle Beschreibungen All payees Alle Zahlungsempfänger All payers Alle Zahlungspflichtigen No payee Keine Zahlungsempfänger No payer Keine Zahlungspflichtigen The selected file already exists. Would you like to overwrite the old copy? Diese Datei existiert bereits. Soll die alte Kopie überschrieben werden? You selected a directory! Es wurde ein Verzeichnis ausgewählt! Couldn't open file for writing. Konnte Datei nicht zum Schreiben öffnen. Error while writing file; file was not saved. Fehler beim Schreiben der Datei; Datei wurde nicht gespeichert Expenses: %2, %1 Ausgaben: %2, %1 Incomes: %2, %1 Einnahmen: %2, %1 Incomes & Expenses Einnahmen & Ausgaben %1 (%2&ndash;%3) html format; %1: title; %2: from date; %3: to date %1 (%2&ndash;%3) %1 (to %2) html format; %1: title; %2: to date %1 (bis %2) Category Kategorie Cost Kosten Income Einnahmen Daily Average Täglicher Durchschnitt Monthly Average Monatlicher Durchschnitt Yearly Average Jährlicher Durchschnitt Average Cost Durchschnittliche Kosten Average Income Durchschnittliche Einnahmen Average Value Durchschnittlicher Wert Total Gesamt Total incomes Gesamte Einnahmen Total expenses Gesamte Ausgaben Total (Profits) Gesamt (Ertrag) Expense Ausgabe Transfer Überweisung Security Buy Wertpapierkauf Security Sell Wertpapierverkauf Recurrence Wiederholung New Expense Neue Ausgabe New Dividend Neue Dividende New Income Neue Einnahme New Transfer Neue Überweisung New Security Buy Neuer Wertpapierkauf New Security Sell Neuer Wertpapierverkauf Edit Expense Ausgabe bearbeiten Edit Dividend Dividende bearbeiten Edit Income Einnahme bearbeiten Edit Transfer Überweisung bearbeiten Edit Securities Bought Gekaufte Wertpapiere bearbeiten Edit Securities Sold Verkaufte Wertpapiere bearbeiten Dividend Dividende Repayment Rückzahlung Refund Rückerstattung Split Transaction Teiltransaktion Description: Beschreibung: Date: Datum: Account: Konto: Transactions: Transaktionen: Type Typ Description Beschreibung Account/Category Konto/Kategorie Payment Zahlung Deposit Einlage New Neu New Expense… Neue Ausgabe… New Income… Neue Einnahme… New Deposit… Neue Einlage… New Withdrawal… Neue Abhebung… Security Shares Sold… Verkaufte Wertpapieranteile… New Dividend… Neue Dividende… Edit… Bearbeiten… Total value: Gesamtwert: No suitable account available. Kein geeignetes Konto verfügbar Future dates is not allowed. Ein Datum in der Zukunft ist nicht erlaubt. A split must contain at least two transactions. Eine geteilte Transaktion besteht aus mindestens zwei Transaktionen. Cannot transfer money to and from the same account. Transfer zum selben Konto können nicht durchgeführt werden. Cost: Kosten: Income: Einnahmen: Quantity: Menge: Comments: Kommentare: Reinvested Dividend Reinvestierte Dividende Security: Wertpapier: Shares added: Hinzugefügte Anteile: Security Trade Wertpapierhandel From security: Von Wertpapier: Shares moved: Anteile verschoben: All Alle To security: Zu Wertpapier Shares received: Anteile erhalten: Value: Wert: No other security available for trade in the account. Keine weiteren Wertpapiere zum Handeln in diesem Account vorhanden: Selected to and from securities are the same. Ausgewählte "von" und "nach" Wertpapiere sind die selben Zero shares not allowed. Keine Anteile sind nicht erlaubt Zero value not allowed. Kein Wert ist nicht erlaubt. Quotations Kurse Date Datum Price per Share Preis pro Anteil Quotations for %1 Kurse für %1 Report Bericht The following transactions was scheduled to occur today or before today. Confirm that they have indeed occurred (or will occur today). Die folgenden Transaktionen sollen heute oder in der Vergangenheit durchgeführt werden. Bestätigen Sie, daß diese Transaktionen tatsächlich durchgeführt wurden (oder heute durchgeführt werden). Amount Wert Postpone… Verschieben… Can only postpone to future dates. Man kann nur auf zukünftige Termine verschieben. Transactions for %1 Transaktionen für %1 Shares Anteile Shares Bought Anteile gekauft Shares Sold Anteile verkauft Shares Sold (Traded) Anteile verkauft (gehandelt) Shares Bought (Traded) Anteile gekauft (gehandelt) Shares Bought (Recurring) Anteile gekauft (wiederkehrend) Shares Sold (Recurring) Anteile verkauft (wiederkehrend) Shares Bought (Scheduled) Anteile gekauft (geplant) Shares Sold (Scheduled) Anteile verkauft (geplant) Recurring Dividend Wiederkehrende Dividende Scheduled Dividend Geplante Dividende Type: Typ: Mutual Fund Investmentfonds Bond Anleihe Stock Aktie Other Anderes Name: Name: Decimals in Shares: Dezimal in Anteilen: Initial Shares: Anteile zu Beginn: Initial quotation: Startkurs: No suitable account or income category available. Kein passendes Konto oder Einkommenskategorie vorhanden. Cash Bargeld Current Account Girokonto Savings Account Rücklagekonto Credit Card Kreditkarte Liabilities Verbindlichkeiten Securities Wertpapiere Initial balance: Wert zu Beginn Default account for budgeted transactions Standardkonto für geplante Transaktionen Empty name. Leerer Name. The entered name is used by another account. Dieser Name wird bereits von einem anderen Konto verwendet. Monthly budget: Monatliches Budget The entered name is used by another income category. Dieser Name wird bereits von einer anderen Einkommenskategorie verwendet. The entered name is used by another expense category. Dieser Name wird bereits von einer anderen Ausgabenkategorie verwendet. Accounts Konten Accounts & Categories Konten & Kategorien Expenses Ausgaben Incomes Einnahmen Transfers Überweisungen Schedule Planer Scheduled Transactions Geplante Transaktionen Account / Category Konto / Kategorie Remaining Budget (%1) Verbleibendes Budget (%1) Change (%1) Änderung (%1) Total (%1) Gesamt (%1) %2 of %1 %2 remains of %1 budget %2 von %1 Includes budgeted transactions beinhaltet geplante Transaktionen Period Zeitraum Select Period Zeitraum wählen Current Month Dieser Monat Current Year Dieses Jahr Current Whole Month Dieser Kalendermonat Current Whole Year Dieses Kalenderjahr Whole Past Month Der letzte Kalendermonat Whole Past Year Das letzte Kalenderjahr Previous Month Vorheriger Monat Previous Year Vorheriges Jahr Show partial budget Zeige Teilbudget Edit Budget Budget bearbeiten Budget: Budget: Month: Monat: Result previous month: Ergebnis des Vormonats New Security… Neues Wertpapier… New Transaction Neue Transaktion Set Quotation… Kurs setzen… Name Name Quotation Kurs Profit Ertrag Yearly Rate Jährliche Gebühr Account Konto Statistics Period Zeitraum der Statistik New Schedule Neuer Terminplan Edit Bearbeiten Next Occurrence Nächstes Vorkommnisse Comments Kommentare New Security Neues Wertpapier Edit Security Wertpapier bearbeiten Profit: Ertrag: Rate: Gebühren: Are you sure you want to delete the security "%1" and all associated transactions? Sind Sie sicher, daß Sie die Sicherheit "%1" und alle zugehörigen Transaktionen löschen wollen? No security available. Kein Wertpapier verfügbar Set Quotation (%1) Rate setzen (%1) Price per share: Preis pro Anteil: Future dates are not allowed. Termine in der Zukunft ist nicht erlaubt. Security Transactions Sicherheitstransaktion Ledger Hauptbuch Check Account Konto überprüfen Salary Gehalt Bills Rechnungen Clothing Kleidung Groceries Lebensmittel Leisure Vergnügen Error loading %1: %2. Fehler beim Laden von %1: %2 Couldn't open file Konnte Datei nicht öffnen Error saving %1: %2. Fehler beim Speichern von %1: %2 Couldn't save file Konnte Datei nicht speichern Transaction Schedule Transaktions-Terminplan Accounts &amp; Categories html format Konten &amp; Kategorien Accounts &amp; Categories (%1&ndash;%2) html format Konten &amp Kategorien (%1&ndash;%2) Accounts &amp; Categories (to %1) html format Konten &amp; Kategorien (bis %1) Change Änderung Balance Bilanz Budget Budget Remaining Budget Verbleibendes Budget Total Incomes Gesamte Einnahmen Costs Kosten Total Expenses Gesamte Ausgaben Empty expenses list. Leere Ausgabenliste Empty incomes list. Leere Einnahmenliste Empty transfers list. Leere Transferliste Empty securities list. Leere Wertpapierliste Empty schedule list. Leerer Terminplan Export View… Exportiere Ansicht… Print View… Drucke Ansicht… Initial Period Zeitraum beim Start Remember Last Dates Definierten Zeitraum merken Import CSV File… CSV-Datei importieren… Import QIF File… QIF-Datei importieren… Export As QIF File… QIF-Datei exportieren… Add Account… Konto hinzufügen New Account… Neues Konto… New Income Category… Neue Einkommenkategorie New Expense Category… Neue Ausgabenkategorie Balance… Bilanzieren… Show Transactions Transaktionen zeigen New Transfer… Neuer Überweisung… New Split Transaction… Neue geteilte Transaktion… Edit Transaction(s) (Occurrence)… Bearbeite Transaktion(en) (Vorkommnis)… Edit Occurrence… Vorkommnis bearbeiten… Edit Schedule (Recurrence)… Bearbeite Terminplan (Wiederholung)… Edit Schedule… Terminplan bearbeiten… Remove Transaction(s) (Occurrence) Transaktion(en) entfernen (Vorkommnis) Remove Occurrence Vorkommnis entfernen Delete Schedule (Recurrence) Terminplan löschen (Wiederholung) Delete Schedule Terminplan löschen Edit Split Transaction… Bearbeite geteilte Transaktionen Remove Split Transaction Entferne geteilte Transaktionen Join Transactions… Transaktionen zusammenfassen Split Up Transaction Transaktion teilen Refund… Erstattung… Repayment… Rückzahlung… New Refund/Repayment… Neue Erstattung/Rückzahlung… Edit Security… Wertpapier bearbeiten… Remove Security Wertpapier entfernen Shares Sold… Anteile verkauft… Shares Bought… Anteile gekauft… Dividend… Dividende… Reinvested Dividend… Reinvestierte Dividende… Shares Moved… Verschobene Anteile… Edit Quotations… Kurse bearbeiten… Transactions… Transaktionen… Development Over Time Report… Bericht "Entwicklung über Zeit" Categories Comparison Report… Bericht "Kategorienvergleich" Categories Comparison Chart… Diagramm "Kategorienvergleich" Development Over Time Chart… Diagramm "Entwicklung über Zeit" Use Additional Transaction Properties Zusätzliche Transaktionseinstellungen verwenden Eqonomize! exited unexpectedly before the file was saved and data was lost. Do you want to load the last auto-saved version of the file? Eqonomize! wurde unerwartet beendet, bevor die Datei gespeichert werden konnte. Es kann zu Datenverlust gekommen sein. Wollen Sie die letzte automatisch gespeicherte Version dieser Datei laden? Crash Recovery Absturz-Wiederherstellung The current file has been modified. Do you want to save it? Die Datei wurde verändert. Möchten Sie sie speichern? Confirm Schedule Terminplan bestätigen New Account Neues Konto New Income Category Neue Einnahmenkategorie New Expense Category Neue Ausgabenkategorie Balance Account Konto bilanzieren Book value: Buchwert: Real value: Realwert: Edit Account Konto bearbeiten Edit Income Category Einnahmenkategorie bearbeiten Edit Expense Category Ausgabenkategorie bearbeiten Move transactions? Transaktionen verschieben? Move to: Verschieben nach: The category contains some expenses. What do you want to do with them? Die Kategorie enthält einige Ausgaben. Was wollen Sie mit diesen tun? The category contains some incomes. What do you want to do with them? Die Kategorie enthält einige Einnahmen. Was wollen Sie mit diesen tun? The account contains some transactions. What do you want to do with them? Dieses Konto enthält einige Tranaktionen. Was wollen Sie mit diesen tun? The category contains some expenses that will be removed. Do you still want to remove the category? Die Kategorie enthält einige Ausgaben, die entfernt werden würden. Wollen Sie die Kategorie tatsächlich entfernen? Remove Category? Kategorie entfernen? The category contains some incomes that will be removed. Do you still want to remove the category? Die Kategorie enthält einige Einnahmen, die entfernt werden würden. Wollen Sie die Kategorie wirklich entfernen? The account contains some transactions that will be removed. Do you still want to remove the account? Das Konte enthält einige Transaktionen, die entfernt werden würden. Wollen Sie das Konto wirklich entfernen? Remove Account? Konto entfernen? %2 of %1 %1: budget; %2: remaining budget %2 von %1 %1 (with no budget) %1 (ohne Budget) %1 (with budget %2) %1 (mit Budget %2) &Import i18n: ectx: Menu (import) Importieren &Accounts i18n: ectx: Menu (accounts) &Konten &Transactions i18n: ectx: Menu (transactions) &Transaktionen &Securities i18n: ectx: Menu (securities) &Wertpapiere Stat&istics i18n: ectx: Menu (statistics) Stat&istiken Import CSV file CSV-Datei importieren Transaction Type Selection Auswahl des Transaktionstyps Expenses and incomes (negative cost) Ausgaben und Einnahmen (negative Kosten) Expenses and incomes (separate columns) Ausgaben und Einnahmen (getrennte Spalten) All types Alle Typen File Selection Dateiauswahl File: Datei: First data row: Erste Zeile mit Daten: Auto Auto Column delimiter: Trennzeichen: Comma Komma Tabulator Tabulator Semicolon Semikolon Space Leerzeichen Columns Specification Spaltenbeschreibung Column Spalte Category: Kategorie From account: Von Konto: Create missing categories and accounts Lege fehlende Kategorien und Konten an Imports data as expenses. Costs have positive value. Value is the only required column. Importiere Daten als Ausgaben. Kosten haben einen positiven Wert. "Wert" ist die einzig benötigte Spalte. Imports data as incomes. Value is the only required column. Importiert Daten als Einnahmen. Die einzig benötigte Spalte ist "Wert". To account: Zu Konto: Imports data as transfers. Value is the only required column. Importiert Daten als Transaktionen. Die einzige benötigte Spalte ist "Wert" Amount: Menge: Imports data as expenses and incomes. Costs have negative value. Value and category are both required columns. Importiert Daten als Ausgaben und Einnahmen. Kosten haben einen negativen Wert. Spalten für "Wert" und "Kategorie" werden benötigt. Imports data as expenses and incomes. Costs and incomes have separate columns. Income, cost, and category are all required columns. Importiert Daten als Ausgaben und Einnahmen. Kosten haben einen negativen Wert. Spalten für "Wert" und "Kategorie" werden benötigt. Imports data as expenses, incomes, and transfers. Costs have negative or positive value. Value, to, and from are all required columns. Accounts and categories must be existing. Importiert Daten als Ausgaben, Einnahmen und Transaktionen. Kosten müssen negative oder positive Werte haben. Benötigte Spalten sind "Wert", "Von" und "Nach". Alle Konten und Kategorien müssen bereits existieren. From: Von: To: Nach: A file must be selected. Es muss eine Datei ausgewählt werden. Selected file is a directory. Die ausgewählte Datei ist ein Verzeichnis. Selected file does not exist. Die ausgewählte Datei existiert nicht. Empty delimiter. Leeres Trennzeichen. The same column number is selected multiple times. Die selbe Spaltennummer ist mehrfach ausgewählt. Selected from account is the same as the to account. Das gewählte Ausgangskonto ist identisch mit dem Eingangskonto. Couldn't open %1 for reading. Konnte %1 nicht zum lesen öffnen. Error reading %1. Fehler beim Lesen von %1. Successfully imported 1 transaction. Eine Transaktion erfolgreich eingelesen. %1 Transaktionen erfolgreich eingelesen. Unable to import any transactions imported. Es konnten keine Transaktionen importiert werden. Failed to import 1 data row. Ein Datensatz konnte nicht eingelesen werden. %1 Datensätze konnten nicht importiert werden. Required columns missing. Notwendige Spalten fehlen. Invalid value. Ungültiger Wert. Empty category name. Leerer Kategorienname. Empty account name. Leerer Kontenname. Unknown category found. Unbekannte Kategorie gefunden. Unknown account found. Unbekanntes Konto gefunden. Cannot import security transactions (to/from security accounts). Kann Wertpapiertransaktionen nicht importieren (von/nach Wertpapierkonten). Balancing account wrongly used. Bilanzierungskonto falsch verwendet. Same to and from account/category. Konto/Kategorie sind identisch. No data found. Keine Daten gefunden. Unrecognized date format. Unbekanntes Datumsformat. Specify Format Format bestimmen The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. Das Format von Terminen und/oder Zahlen in der CSV-Datei ist zweideutig. Bitte wählen Sie das korrekte Format. Date format: Datumsformat: Value format: Zahlenformat: tomorrow the day after today morgen today this day heute yesterday the day before today gestern &Today @option today Heute To&morrow @option tomorrow Morgen Export… Exportieren… Print… Drucken… Withdrawal Abhebung Join… Zusammenfassen… Split Up Aufteilen Empty transaction list. Leere Transaktionsliste Are you sure you want to delete all (%1) selected transactions? Sind Sie sicher, daß Sie alle (%1) ausgewählten Transaktionen löschen wollen? Cannot set the value of security transactions using the dialog for modifying multiple transactions. Der Wert von Wertpapiertransaktionen kann nicht über den Dialog zum Ändern mehrerer Transaktionen geändert werden. Cannot change description of dividends and security transactions. Die Beschreibung für Dividenden und Wertpapiertransaktionen kann nicht geändert werden. Cannot change payer of dividends and security transactions. Der Zahlungspflichtige von Dividenden und Wertpapiere kann nicht verändert werden. Cannot change date of transactions that are part of a split transaction. Das Datum von Teilen einer geteilten Transaktion kann nicht verändert werden. Eqonomize! Eqonomize! A personal accounting program Ein Programm für die private Buchhaltung Start with expenses list displayed Mit Ausgabenansicht beginnen Start with incomes list displayed Mit Einnahmenansicht beginenn Start with transfers list displayed Mit Transaktionenansicht beginnen Document to open Zu öffnendes Dokument Incomes and Expenses Einnahmen und Ausgaben Profits Einkünfte All Categories Combined Alle Kategorien zusammen All Descriptions Combined Alle Beschreibungen zusammen All Payees/Payers Combined Alle Zahlungsempfänger/Zahlungspflichtigen zusammengefasst Start date: Startdatum: End date: Enddatum: Monthly total Monatlich gesamt Daily average Täglicher Durchschnitt All Payers Combined Alle Zahlungspflichtigen zusammengefasst All Payees Combined Alle Zahlungsempfänger zusammengefasst All Descriptions Split Alle Beschreibungen geteilt All Payers Split Alle Zahlungspflichtigen geteilt All Payees Split Alle Zahlungsempfänger geteilt All Categories Split Alle Kategorien geteilt Value (%1) Wert (%1) Profit (%1) Ertrag (%1) Income (%1) Einnahmen (%1) Cost (%1) Kosten (%1) Time Zeit no payer Kein Zahlungspflichtiger %1/%2 %1: Description; %2: Payer %1: Beschreibung; %2: Zahlungspflichtiger no payee Kein Zahlungsempfänger %1/%2 %1: Description; %2: Payee %1: Beschreibung; %2: Zahlungsempfänger Average Profit Durchschnittliche Einkünfte Year Jahr Month Monat Includes scheduled transactions Beinhaltet geplante Transaktionen Adjusted for the average month / year (%1 / %2 days) An den durchschnittlichen Monat / das durchschnittliche Jahr angepasst (%1 / %2 Tage) Subtotal Zwischensumme Import QIF file QIF-Datei importieren Select a QIF file to import. When you click next, the file be analysed and you might need to answer some questions about the format of the file. Wählen Sie eine QIF-Datei zum Import. Wenn Sie "Weiter" klicken, wird die Datei analysiert, und Sie könnten einige weitere Fragen über das Dateiformat beantworten müssen. Local Definitions Lokale Definitionen Unknown elements where found in the QIF file. It is possible that this is because of localized type names. Please map them to the correct standard names. Es wurden unbekannte Elemente in dieser QIF-Datei gefunden. Dies kann durch lokal angepasste Typnamen verursacht worden sein. Bitte entschlüssln Sie diese zu den korrekten Standardnamen. Local Text Lokaler Text Standard Text Standardtext Select standard text: Standardtext auswählen: Date Format Datumsformat The date format in the QIF file is ambiguous. Please select the correct format. Das Datumsformat in diser QIF-Datei ist zweideutig. Bitte wählen Sie das korrekte Datumsformat. Default Account Standardkonto Could not find any account definitions in the QIF file. Please select a default account. It is also possible that this is caused by a localized opening balance text. Konnte keine Kontendefinitionen in der QIF-Datei finden. Bitte wählen Sie ein Standardkonto. Dies kann durch lokal veränderte Starteinlagen-Texte entstenen. Default account: Standardkonto: Opening balance text: Starteinlagen-Text: Descriptions Beschreibungen Transactions in QIF files does not have any specific description property. You are therefore given the option to choose how the description of imported transactions will be set. Transaktionen in QIF-Dateien haben keine eigene Beschreibungsfelder. Daher erhalten Sie die Möglichkeit zu wählen, wie die Beschreibungen der importierten Transaktionen gefüllt werden. Subcategories as: Unterkategorien als: Ignore Ignorieren Payee as: Zahlungsempfänger als: Payee Zahlungsempfänger Memo as: Notiz als: Priority: Priorität: Subcategory/Payee/Comments Unterkategorie/Zahlungsempfänger/Kommentare Payee/Subcategory/Comments Zahlungsempfänger/Unterkategorie/Kommentare Subcategory/Comments/Payee Unterkategorie/Kommentare/Zahlungsempfänger Payee/Comments/Subcategory Zahlungsempfänger/Kommentare/Unterkategorie Comments/Subcategory/Payee Kommentare/Unterkategorie/Zahlungsempfänger Comments/Payee/Subcategory Kommentare/Zahlungsempfänger/Unterkategorie Unknown Unbekannt Bank Bank Cat (Category) Kat. (Kategorie) CCard (Credit Card) Kreditkarte Invst (Investment) Invst. (Investitionen) Oth A (Other Assets) Andere Akt. (Andere Aktiva) Oth L (Other Liabilities) Andere Verpf. (Verpflichtungen) Security Wertpapier Successfully imported 1 account. Ein Konto wurde erfolgreich importiert. %1 Konten wurden erfolgreich importiert. Successfully imported 1 category. Eine Kategorie wurde erfolgreich importiert. %1 Kategorien wurden erfolgreich importiert. 1 duplicate transaction was ignored. Eine doppelte Transaktion wurde ignoriert. %1 doppelte Transaktionen wurden ignoriert. Failed to import 1 transaction. Fehler beim impotrieren von 1 Transaktion. Fehler beim Importieren von %1 Transaktionen. 1 security was not imported. Eine Wertpapier wurde nicht importiert. %1 Wertpapier wurden nicht importiert. 1 security transaction was not imported. Eine Wertpapiertransaktion wurde nicht importiert. %1 Wertpapiertransaktionen wurden nicht importiert. Export QIF File QIF-Datei exportieren All All accounts Alle Export transaction description as: Beschreibung dieser Transaktion exportieren als: Memo Notiz Subcategory Unterkategorie Unnamed Unbenannt Uncategorized Nicht kategorisiert Edit Exceptions Ausnahmen bearbeiten Edit Recurrence Range Zeitraum für Wiederholungen bearbeiten. Begins on: %1 Beginnt am: %1 No ending date Kein Enddatum End after Ende nach occurrence(s) Vorkommnis(se) End on Endet am End date before start date. Endzeitpunkt vor Startzeitpunkt. Enable recurrence Wiederholung aktivieren Recurrence Rule Regel für Wiederholungen Weekly Wöchentlich Recur every Wiederhole alle day(s) Tag(e) week(s) on: Woche(n) am: month(s), after the start month Monat(e), nach dem Startmonat Recur on the Wiederholen am 1st 1. 2nd 2. 3rd 3. 4th 4. 5th 5. 6th 6. 7th 7. 8th 8. 9th 9. 10th 10. 11th 11. 12th 12. 13th 13. 14th 14. 15th 15. 16th 16. 17th 17. 18th 18. 19th 19. 20th 20. 21st 21. 22nd 22. 23rd 23. 24th 24. 25th 25. 26th 26. 27th 27. 28th 28. 29th 29. 30th 30. 31st 31. Last Letzten 2nd Last Vorletzten 3rd Last Drittletzten 4th Last Viertletzten 5th Last Fünftletzten day Tag possibly on weekend auch am Wochenende but before weekend aber vor einem Wochenende but after weekend aber nach einem Wochenende year(s), after the start year Jahr(e) nach dem Startjahr Recur on day part before XXX of 'Recur on day XXX of month YYY' Wiederhole am Tag of part between XXX and YYY of 'Recur on day XXX of month YYY' im On the Part before NNN in 'Recur on the NNN. WEEKDAY of MONTH' Am of part between WEEKDAY and MONTH in 'Recur on NNN. WEEKDAY of MONTH' im Recur on day # Wiederhole am of the year part after NNN of 'Recur on day #NNN of the year' Tag des Jahres Range… Bereich… Exceptions… Ausnahmen… No day of week selected for weekly recurrence. Kein Wochentag für wöchentliche Wiederholung ausgewählt Selected day will never occur with selected frequency and start date. Der gewählte Tag liegt nicht innerhalb des gewählten Zeitraumes. Selected day does not exist in selected month. Der gewählte Tag kommt im gewählten Monat nicht vor. Dividend: %1 Dividende: %1 Account balancing Kontenbilanzierung Security: %1 (bought) Wertpapier: %1 (gekauft) Security: %1 (sold) Wertpapier: %1 (verkauft) Shares bought: Anteile gekauft: Shares sold: Anteile verkauft: Payer: Zahlungspflichtiger: Payee: Zahlungsempfänger: No income category available. Keine Einkommenkategorie verfügbar No expense category available. Keine Ausgabenkategorie verfügbar Cannot create a regular transfer to/from a securities account. Normale Transfers von/zu einem Wertpapierkonto können nicht durchgeführt werden. Cannot create a regular income to a securities account. Normale Einkünfte können nicht zu einem Wertpapierkonto zugefügt werden. Zero price per share not allowed. Anteile ohne Wert sind nicht erlaubt. Cannot create a regular expense from a securities account. Normale Ausgaben aus einem Wertpapierkonto sind nicht möglich. Modify Transactions Transaktionen bearbeiten. Min amount: Mindestmenge Max amount: Höchstmenge Min income: Mindesteinnahmen Max income: Höchsteinnahmen Min cost: Mindestkosten Max cost: Höchstkosten Include Inklusive Exclude Exklusive From Account Von Konto To Account Zu Konto Payer Absender New/Edit %1 %1 anlegen/bearbeiten Filter Filter Total: Gesamt: Average: Durchschnittlich: Monthly: Monatlich: Total cost: Gesamtkosten: Total income: Gesamte Einnahmen: Total amount: Gesamtwert: Monthly average: Monatlicher Durchschnitt: Are you sure you want to delete all (%1) transactions in the selected split transaction? Sind Sie sicher, daß Sie alle (%1) ausgewählten geteilten Transaktionen löschen wollen? * Part of split transaction * Teil einer geteilten Transaktion * Part of split (%1) * Teil (%1) ** Recurring (editing occurrence) ** Wiederkehrend (bearbeite Vorkommnisse) Modify… Verändere… Couldn't fetch %1. Konnte %1 nicht abholen Failed to upload file to %1. Konnte Datei nicht nach %1 hochladen Chart Diagramm Error after saving file; data may not have been saved. Fehler nach dem Speichern der Datei; Daten wurden möglicherweise nicht gespeichert. AccountComboBox New account… Neues Konto… Paid with loan… Mit Darlehen bezahlt… Multiple accounts/payments… Mehrere Konten/Zahlungen… New income category… Neue Einkommenkategorie… New expense category… Neue Ausgabenkategorie… New Account Neues Konto New Income Category Neue Einnahmenkategorie New Expense Category Neue Ausgabenkategorie AccountsMenu All Accounts Alle Konten All Categories Combined Alle Kategorien zusammen %n accounts %n Konto %n Konten %n categories %n Kategori %n Kategorien Balancing Account balancing Kontenbilanzierung Account balancing Balancing of an account Kontenbilanzierung Account Balance Adjustment Kontostand korrigieren Budget Balancing Bilanzieren Balancing Name of account for transactions that adjust account balances Bilanzieren Balancing Account Name of account for transactions that adjust account balances Bilanzkonto Couldn't open %1 for reading Konnte %1 nicht zum Lesen öffnen Not a valid Eqonomize! file (XML parse error: "%1" at line %2, col %3) Keine gültige Eqonomize!-Datei (XML-Analysefehler: "%1" in der Zeile %2, Spalte %3) Invalid root element %1 in XML document Ungültiges Wurzelelement %1 im XML-Dokument Unknown XML element: "%1" at line %2, col %3 Unbekanntes XML Element: "%1" in der Zeile %2, Spalte %3 XML parse error: "%1" at line %2, col %3 XML-Parserfehler: "%1" in der Zeile %2, Spalte %3 European Euro Euro Unable to load %n currency/currencies. Konnte %n Währung nicht laden. Konnte %n Währungen nicht laden. No exchange rates found. Keine Wechselkurse gefunden. USD currency missing. Währung USD fehlt. imported Importiert Unable to load %n account(s). Konnte %n Konto nicht laden. Konnte %n Konten nicht laden. Unable to load %n category/categories. Konnte %n Kategorie nicht laden. Konnte %n Kategorien nicht laden. Unable to load %n security/securities. Financial security (e.g. stock, mutual fund) Konnte %n Wertpapier nicht laden. Konnte %n Wertpapiere nicht laden. Download command (%1) failed: %2. Befehl zum Herunterladen (%1) schlug fehl: %2. Failed to download file from %1: %2. Fehler beim Herunterladen der Datei von %1: %2. Upload command (%1) failed: %2. Befehl zum Hochladen (%1) schlug fehl: %2. yyyy-yy Financial year when first month is not January (e.g. 2018-19). yyyy/yy Transaction Accounts Girokonten Savings Accounts Sparkonten Credit Cards Kreditkarten Debts Schulden Securities Financial security (e.g. stock, mutual fund) Wertpapiere Cash Bargeld Transaction Account Girokonto Savings Account Rücklagekonto Credit Card Kreditkarte Debt Schulden Other Anderes Unable to load %n security/securities. Konnte %n Wertpapier nicht laden. Konnte %n Wertpapiere nicht laden. Unable to load %n transaction(s). Konnte %n Transaktion nicht laden. Konnte %n Transaktionen nicht laden. File is a directory Datei ist ein Verzeichnis Couldn't open file for writing Konnte Datei nicht zum Schreiben öffnen Error while writing file; file was not saved Fehler beim Schreiben der Datei; Datei wurde nicht gespeichert Unnamed Unbenannt Uncategorized Nicht kategorisiert CategoriesComparisonChart Save As… Speichern unter… Print… Drucken… From Von To Nach Source: Quelle: All Expenses Alle Ausgaben All Incomes Alle Einnahmen Theme: Thema: Chart type: Diagramm Typ: Pie Chart Tortendiagramm Bar Chart Balkendiagramm Default Standard All Expenses, without subcategories Alle Ausgaben, ohne Unterkategorien All Expenses, with subcategories Alle Ausgaben, mit Unterkategorien All Incomes, without subcategories Alle Einnahmen, ohne Unterkategorien All Incomes, with subcategories Alle Einnahmen, mit Unterkategorien All Accounts Alle Konten Expenses: %1 Ausgaben: %1 Incomes: %1 Einnahmen: %1 Error Fehler Invalid date. Ungültiges Datum. To date is before from date. "Bis"-Datum liegt vor dem "Von"-Datum. From date is after to date. "Von"-Datum liegt hinter dem "Bis"-Datum. Couldn't open file for writing. Konnte Datei nicht zum Schreiben öffnen. Error while writing file; file was not saved. Fehler beim Schreiben der Datei; Datei wurde nicht gespeichert. Expenses Ausgaben Expenses, %1 Ausgaben, %1 Incomes, %1 Einnahmen, %1 Incomes Einnahmen Accounts Konten Expenses, %2: %1 Ausgaben, %2: %1 Incomes, %2: %1 Einnahmen, %2: %1 Other descriptions Referring to the transaction description property (transaction title/generic article name) Andere Beschreibungen No description Referring to the transaction description property (transaction title/generic article name) Keine Beschreibung Other accounts Andere Konten Other categories Andere Kategorien %1 Value: %2 %1 Wert: %2 No description Referring to the Transaction description property (transaction title/generic article name) Keine Beschreibung No description Referring to the generic description property Keine Beschreibung Value Wert Income Einnahmen Cost Kosten Value (%1) Wert (%1) Income (%1) Einnahmen (%1) Cost (%1) Kosten (%1) No description Keine Beschreibung CategoriesComparisonChartDialog Chart Diagramm CategoriesComparisonReport Save As… Speichern unter… Print… Drucken… Source: Quelle: All Categories, excluding subcategories Alle Kategorien, ohne Unterkategorien All Categories, including subcategories Alle Kategorien, mit Unterkategorien All Payees/Payers Alle Zahlungsempfänger/Zahlungspflichtigen Subcategories Unterkategorien Descriptions for Referring to the Transaction description property (transaction title/generic article name) Beschreibungen für All descriptions Referring to the Transaction description property (transaction title/generic article name) Alle Beschreibungen No description Referring to the Transaction description property (transaction title/generic article name) Keine Beschreibung All Categories Alle Kategorien Expenses: %1 Ausgaben: %1 Incomes: %1 Einnahmen: %1 Descriptions for Beschreibungen für Payees/payers for Zahlungsempfänger/-flichtigen für Descriptions Referring to the Transaction description property (transaction title/generic article name) Beschreibungen Period: Zeitraum: From Von To Nach Columns: Spalten: Value Wert Daily Täglich Monthly Monatlich Yearly Jährlich Quantity Anzahl Average value Durchschnittlicher Wert All descriptions Alle Beschreibungen All payees Alle Zahlungsempfänger All payers Alle Zahlungspflichtigen No description Keine Beschreibung Descriptions for Referring to the generic description property Beschreibungen für Descriptions Referring to the generic description property Beschreibungen All descriptions Referring to the generic description property Alle Beschreibungen No description Referring to the generic description property Keine Beschreibung All Payees and Payers Alle Zahlungsempfänger und Pflichtigen Tag: %1 Etikett: %1 All Accounts Alle Konten Descriptions for Referring to the transaction description property (transaction title/generic article name) Beschreibungen für Descriptions Referring to the transaction description property (transaction title/generic article name) Beschreibungen Months Monate Years Jahre Tags Etikette Total: Gesamt: All descriptions Referring to the transaction description property (transaction title/generic article name) Alle Beschreibungen All payees/payers Alle Zahlungsempfänger/-pflichtigen No description Referring to the transaction description property (transaction title/generic article name) Keine Beschreibung No payee Keine Zahlungsempfänger No payer Keine Zahlungspflichtigen Error Fehler Invalid date. Ungültiges Datum. To date is before from date. "Bis"-Datum liegt vor dem "Von"-Datum. From date is after to date. "Von"-Datum liegt hinter dem "Bis"-Datum. Couldn't open file for writing. Konnte Datei nicht zum Schreiben öffnen. Error while writing file; file was not saved. Fehler beim Schreiben der Datei; Datei wurde nicht gespeichert. Expenses, %2: %1 Ausgaben, %2: %1 Expenses, %3: %2, %1 Ausgaben, %3: %2, %1 Incomes, %2: %1 Einnahmen, %2: %1 Incomes, %3: %2, %1 Einnahmen, %3: %2, %1 %3: %2, %1 %3: %2, %1 %2: %1 %2: %1 Tags, %1 Etikette, %1 Incomes & Expenses, %1 Einnahmen & Ausgaben, %1 Expenses: %2, %1 Ausgaben: %2, %1 Incomes: %2, %1 Einnahmen: %2, %1 %2, %1 %2, %1 %1 %1 Incomes & Expenses Einnahmen & Ausgaben %1 (%2&ndash;%3) html format; %1: title; %2: from date; %3: to date %1 (%2&ndash;%3) %1 (to %2) html format; %1: title; %2: to date %1 (bis %2) Category Kategorie Payee Zahlungsempfänger Description Referring to the transaction description property (transaction title/generic article name) Beschreibung Cost Kosten Payer Zahlungspflichtiger Income Einnahmen Payee/Payer Zahlungsempfänger/-pflichtiger Tag Etikett Daily Average Täglicher Durchschnitt Monthly Average Monatlicher Durchschnitt Yearly Average Jährlicher Durchschnitt Average Cost Durchschnittliche Kosten Average Income Durchschnittliche Einnahmen Average Value Durchschnittlicher Wert No payee/payer Keine Zahlungsempfänger/-pflichtigen Total Gesamt All Tags Alle Etiketten Total incomes Gesamte Einnahmen Total expenses Gesamte Ausgaben Total (Profits) Gesamt (Ertrag) CategoriesComparisonReportDialog Report Bericht ConfirmScheduleDialog The following transactions was scheduled to occur today or before today. Confirm that they have indeed occurred (or will occur today). Die folgenden Transaktionen sollen heute oder in der Vergangenheit durchgeführt werden. Bestätigen Sie, daß diese Transaktionen tatsächlich durchgeführt wurden (oder heute durchgeführt werden). Date Datum Type Typ Description Beschreibung Name Name Description Generic Description Allgemeine Beschreibung Description Transaction description property (transaction title/generic article name) Beschreibung Amount Wert Edit… Bearbeiten… Postpone… Verschieben… Delete Löschen Error Fehler Can only postpone to future dates. Man kann nur auf zukünftige Termine verschieben. ConfirmScheduleListViewItem Transfer Überweisung Dividend Dividende Income Einnahme Expense Ausgabe Securities Purchase Financial security (e.g. stock, mutual fund) Wertpapierkauf Securities Sale Financial security (e.g. stock, mutual fund) Wertpapierverkauf Security Buy Wertpapierkauf Security Sell Wertpapierverkauf Debt Payment Schuldentilgung CurrencyConversionDialog Currency Converter Währungsrechner DebtFee Debt payment: %1 (fee) Schuldentilgung: %1 (Gebühr) DebtInterest Debt payment: %1 (interest) Schuldentilgung: %1 (Zinsen) DebtPayment Debt payment: %1 Schuldentilgung: %1 DebtReduction Debt payment: %1 (reduction) Schuldentilgung: %1 (Reduzierung) DescriptionsMenu All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Alle Beschreibungen zusammen All Tags Combined All Payees Combined Alle Zahlungsempfänger zusammengefasst All Payers Combined Alle Zahlungspflichtigen zusammengefasst All Payees/Payers Combined No description Referring to the transaction description property (transaction title/generic article name) Keine Beschreibung No payee Keine Zahlungsempfänger No payer Keine Zahlungspflichtigen No payee/payer Keine Zahlungsempfänger/-pflichtigen %n descriptions Referring to the transaction description property (transaction title/generic article name) %n Beschreibung %n Beschreibungen %n tags %n Etikett %n Etiketten %n payees %n Zahlungsempfänger %n Zahlungsempfänger %n payers %n Zahlungspflichtigen %n Zahlungspflichtigen %n payees/payers %n Zahlungsempfänger/-pflichtigen %n Zahlungsempfänger/-pflichtigen EditAssetsAccountDialog Type: Typ: Cash Bargeld Current Account Girokonto Savings Account Rücklagekonto Credit Card Kreditkarte Liabilities Verbindlichkeiten Transactional Account Girokonto Debt Schulden Securities Wertpapiere Other Anderes Currency: Währung: Edit Bearbeiten Name: Name: Bank: Bank: Initial balance: Wert zu Beginn: Debt: Schulden: Initial balance Wert zu Beginn Group: Gruppe: no group keine Gruppe Transferred to: Überwiesen an: Date: Datum: Lender: Darlehensgeber: Default account for budgeted transactions Standardkonto für geplante Transaktionen Description: Beschreibung: Account is closed Das Konto ist geschlossen Warning Warnung Type cannot be changed to securities for accounts with transactions. Der Typ kann nicht in Wertpapiere für Konten mit Transaktionen geändert werden. Issuer: Emittent: Zero value not allowed. Null-Wert ist nicht erlaubt. Error Fehler Transaction Account Girokonto Opening balance: Account balance Anfangsbestand: Opening balance Account balance Anfangsbestand New currency… Neue Währung… If you change the currency of an account, the currency of all associated transactions will also change, without any conversion. Do do wish to continue anyway? Wenn Sie die Währung eines Kontos ändern, ändert sich auch die Währung aller zugehörigen Transaktionen ohne Konvertierung. Möchten Sie trotzdem fortfahren? Empty name. Leerer Name. The entered name is used by another account. Dieser Name wird bereits von einem anderen Konto verwendet. EditCurrencyDialog Edit Currency Währung bearbeiten New Currency Neue Währung Code: Code: Symbol: Symbol: Prefix Präfix Suffix Suffix Default Standard Name: Name: Decimals: Dezimalstellen: Date: Datum: Main currency Hauptwährung Error Fehler Error saving currencies: %1. Fehler beim Speichern der Währungen: %1. Empty code. Leerer Code. Code already exists. Code schon vergeben. EditDebtPaymentDialog Debt Payment Schuldentilgung EditDebtPaymentWidget Debt: Schulden: Date: Datum: Debt reduction: Schuldenreduzierung: Reduction payment: Abschlagszahlung: Interest: Zinsen: Paid Bezahlt Added to debt Schulden hinzugefügt Fee: Gebühr: Account: Konto: Expense category: Ausgabenkategorie: Associated file: Zugehörige Datei: Select a file Datei auswählen Open the file Datei öffnen Comments: Kommentare: Related to: Label for linked transactions Links: Total value: Gesamtwert: Error Fehler No suitable account available. Kein geeignetes Konto verfügbar. Invalid date. Ungültiges Datum. Interest must not be zero. Zinsen müssen ungleich Null sein At least one value must non-zero. Mindestens ein Wert muss ungleich Null sein. EditExceptionsDialog Edit Exceptions Ausnahmen bearbeiten Occurrences: Vorkommnisse: Add Exception Ausnahme hinzufügen Remove Exception Ausnahme entfernen Exceptions: Ausnahmen: Only the first fifty occurrences are shown. Nur die ersten 50 Einträge werden angezeigt. Add Hinzufügen Apply Anwenden Delete Löschen Error Fehler Invalid date. Ungültiges Datum. EditExpensesAccountDialog Name: Name: Parent category: Übergeordnete Kategorie: None Keine Monthly budget: Monatliches Budget: Description: Beschreibung: Error Fehler Empty name. Leerer Name. The entered name is used by another expense category. Dieser Name wird bereits von einer anderen Ausgabenkategorie verwendet. EditIncomesAccountDialog Name: Name: Parent category: Übergeordnete Kategorie: None Keine Monthly budget: Monatliches Budget: Description: Beschreibung: Error Fehler Empty name. Leerer Name. The entered name is used by another income category. Dieser Name wird bereits von einer anderen Einkommenskategorie verwendet. EditLoanTransactionWidget Date: Datum: Account: Konto: Comments: Kommentare: Total value: Gesamtwert: Error Fehler Invalid date. Ungültiges Datum. EditMultiAccountDialog Expense with Multiple Payments Ausgaben mit mehreren Zahlungen Income with Multiple Payments Einnahmen mit mehreren Zahlungen EditMultiAccountWidget Description: Beschreibung: Description: Generic Description Beschreibung: Description: Transaction description property (transaction title/generic article name) Beschreibung: Quantity: Menge: Category: Kategorie: Tags: Etikette: Associated file: Zugeordnete Datei: Select a file Datei auswählen Open the file Datei öffnen Comments: Kommentare: Related to: Label for linked transactions Links: Transactions: Transaktionen: Date Datum Account Konto Payee Zahlungsempfänger Payer Cost Kosten Income Einnahmen Total cost: Gesamtkosten: New Tag Neues Etikett Tag: Etikett: Value Wert New Neu Edit… Bearbeiten… Delete Löschen Total value: Gesamtwert: Error Fehler No suitable expense categories available. Keine passende Ausgabenkategorie verfügbar. A split must contain at least two transactions. Eine geteilte Transaktion besteht aus mindestens zwei Transaktionen. EditMultiItemDialog Split Transaction Geteilte Transaktion EditMultiItemWidget Description: Beschreibung: Description: Generic Description Beschreibung: Date: Datum: Account: Konto: Payee/Payer: Zahlungsempfänger/-pflichtiger: Transactions: Transaktionen: Type Typ Description Generic Description Beschreibung Description: Transaction description property (transaction title/generic article name) Beschreibung: Tags: Etikette: Associated file: Zugeordnete Datei: Select a file Datei auswählen Open the file Datei öffnen Comments: Kommentare: Related to: Label for linked transactions Links: Description Transaction description property (transaction title/generic article name) Beschreibung Payment Zahlung Deposit Einlage New Neu New Expense… Neue Ausgabe… New Income… Neue Einnahme… New Deposit… Neue Einlage… New Withdrawal… Neue Abhebung… New Securities Purchase… Financial security (e.g. stock, mutual fund) Neuer Wertpapierkauf… New Securities Sale… Financial security (e.g. stock, mutual fund) Neuer Wertpapierverkauf… Shares Bought… Anteile gekauft… Shares Sold… Anteile verkauft… Account/Category Konto/Kategorie Value Wert Income Einnahmen Expense Ausgabe New Dividend… Neue Dividende… Edit… Bearbeiten… Delete Löschen Total value: Gesamtwert: Error Fehler No suitable account available. Kein geeignetes Konto verfügbar. Invalid date. Ungültiges Datum. A split must contain at least two transactions. Eine geteilte Transaktion besteht aus mindestens zwei Transaktionen. Cannot transfer money to and from the same account. Transfer zum selben Konto können nicht durchgeführt werden. EditQuotationsDialog Quotations Kurse Date Datum Price per Share Preis pro Anteil Quotations Financial quotation Kurse Quotes Financial quote Kurse Price per Share Financial Shares Preis pro Anteil Add Hinzufügen Modify Verändern Delete Löschen Import… Importieren… Export… Exportieren… Quotes for %1 Financial quote Kurse für %1 Quotations for %1 Financial quotation Kurse für %1 Quotations for %1 Kurse für %1 Error Fehler Couldn't open %1 for reading. Error reading %1. Fehler beim Lesen von %1. Successfully imported %n quote(s). %n Kurs wurde erfolgreich importiert. %n Kurse wurde erfolgreich importiert. Unable to import any quotes. Es konnten keine Kurse importiert werden. Failed to import %n data row(s). %n Datensatz konnte nicht eingelesen werden. %n Datensätze konnten nicht eingelesen werden. Required columns missing. Notwendige Spalten fehlen. Invalid value. Ungültiger Wert. Invalid date. Ungültiges Datum. No data found. Keine Daten gefunden. Information Information Unrecognized date format. Unbekanntes Datumsformat. Specify Format Format bestimmen The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. Das Format von Terminen und/oder Zahlen in der CSV-Datei ist zweideutig. Bitte wählen Sie das korrekte Format. Date format: Datumsformat: Value format: Zahlenformat: Couldn't open file for writing. Quotes: %1 Kurse: %1 Error while writing file; file was not saved. EditRangeDialog Edit Recurrence Range Zeitraum für Wiederholungen bearbeiten Begins on: %1 Beginnt am: %1 No ending date Kein Enddatum End after Endet nach occurrence(s) Vorkommnis(se) End on Endet am Error Fehler Invalid date. Ungültiges Datum. End date before start date. Endzeitpunkt vor dem Startzeitpunkt. EditReinvestedDividendDialog Reinvested Dividend Reinvestierte Dividende Security: Wertpapier: Shares added: Hinzugefügte Anteile: Security: Financial security (e.g. stock, mutual fund) Wertpapier: Shares added: Financial shares Hinzugefügte Anteile: Date: Datum: Error Fehler Invalid date. Ungültiges Datum. EditScheduledDebtPaymentDialog Transaction Transaktion Recurrence Wiederholung Edit Debt Payment Schuldenzahlung bearbeiten New Debt Payment Neue Schuldzahlung EditScheduledLoanTransactionDialog Recurrence Wiederholung EditScheduledMultiAccountDialog Transactions Transaktionen Recurrence Wiederholung New Expense with Multiple Payments Neue Ausgabe mit mehreren Zahlungen New Income with Multiple Payments Neue Einnahme mit mehreren Zahlungen Edit Expense with Multiple Payments Ausgabe mit mehreren Zahlungen bearbeiten Edit Income with Multiple Payments Einnahme mit mehreren Zahlungen bearbeiten EditScheduledMultiItemDialog Transactions Transaktionen Recurrence Wiederholung New Split Transaction Neue geteilte Transaktion Edit Split Transaction Bearbeite geteilte Transaktionen EditScheduledTransactionDialog Expense Ausgabe Dividend Dividende Income Einnahmen Reinvested Dividend Reinvestierte Dividende Transfer Überweisung Security Buy Wertpapierkauf Security Sell Wertpapierverkauf Securities Purchase Financial security (e.g. stock, mutual fund) Wertpapierkauf Securities Sale Financial security (e.g. stock, mutual fund) Wertpapierverkauf Recurrence Wiederholung New Expense Neue Ausgabe New Expense Paid with Loan Neue Ausgaben mit Darlehen bezahlt New Dividend Neue Dividende New Income Neue Einnahme New Transfer Neue Überweisung New Securities Purchase Financial security (e.g. stock, mutual fund) Neuer Wertpapierkauf New Reinvested Dividend Neue Reinvestierte Dividende New Securities Sale Financial security (e.g. stock, mutual fund) Neuer Wertpapierverkauf Edit Reinvested Dividend Reinvestierte Dividende bearbeiten Edit Securities Purchase Financial security (e.g. stock, mutual fund) Gekaufte Wertpapiere bearbeiten Edit Securities Sale Financial security (e.g. stock, mutual fund) Verkaufte Wertpapiere bearbeiten New Security Buy Neuer Wertpapierkauf New Security Sell Neuer Wertpapierverkauf Edit Expense Ausgabe bearbeiten Edit Dividend Dividende bearbeiten Edit Income Einnahme bearbeiten Edit Transfer Überweisung bearbeiten Edit Securities Bought Gekaufte Wertpapiere bearbeiten Edit Securities Sold Verkaufte Wertpapiere bearbeiten EditSecurityDialog Type: Typ: Mutual Fund Investmentfonds Bond Anleihe Stock Aktie Stock Financial stock Aktie Other Anderes Name: Name: Account: Konto: Decimals in shares: Financial shares Dezimalstellen der Anteile: Initial shares: Financial shares Anteile zu Beginn: Decimals in quotes: Financial quote Dezimalstellen des Kurses: Initial quote: Financial quote Startkurs: Empty name. Leerer Name. No suitable account available. Kein geeignetes Konto verfügbar. Decimals in quotations: Financial quotation Dezimal in Kurs: Initial quotation: Financial quotation Startkurs: Decimals in shares: Dezimal in Anteilen: Initial shares: Anteile zu Beginn: Decimals in Shares: Dezimal in Anteilen: Initial Shares: Anteile zu Beginn: Initial quotation: Startkurs: Date: Datum: Description: Beschreibung: Error Fehler No suitable account or income category available. Kein passendes Konto oder Einkommenskategorie vorhanden. EditSecurityTradeDialog Security Trade Wertpapierhandel From security: Vom Wertpapier: Shares moved: Anteile verschoben: All Alle To security: Zum Wertpapier: Shares received: Anteile erhalten: Securities Exchange Shares of one security directly exchanged for shares of another; Financial security (e.g. stock, mutual fund) Wertpapierhandel From security: Financial security (e.g. stock, mutual fund) Vom Wertpapier: Shares moved: Financial shares Anteile verschoben: To security: Financial security (e.g. stock, mutual fund) Zum Wertpapier: Shares received: Financial shares Anteile erhalten: Value: Wert: Date: Datum: Error Fehler No other security available for exchange in the account. Shares of one security directly exchanged for shares of another; Financial security (e.g. stock, mutual fund) Keine weiteren Wertpapiere zum Handeln in diesem Account vorhanden. No other security available for trade in the account. Keine weiteren Wertpapiere zum Handeln in diesem Account vorhanden. Selected to and from securities are the same. Financial security (e.g. stock, mutual fund) Ausgewählte "von" und "nach" Wertpapiere sind die selben. Zero shares not allowed. Financial shares Leere Anteile sind nicht erlaubt. Selected to and from securities are the same. Ausgewählte "von" und "nach" Wertpapiere sind die selben. Invalid date. Ungültiges Datum. Zero shares not allowed. Leere Anteile sind nicht erlaubt. Zero value not allowed. Null-Wert ist nicht erlaubt. EditSplitDialog Split Transaction Teiltransaktion Description: Beschreibung: Date: Datum: Account: Konto: Transactions: Transaktionen: Type Typ Description Beschreibung Name: Name: Name Name Generic Description: Allgemeine Bezeichnung: Description Generic Description Beschreibung Account/Category Konto/Kategorie Payment Zahlung Deposit Einlage New Neu New Expense… Neue Ausgabe… New Income… Neue Einnahme… New Deposit… Neue Einlage… New Withdrawal… Neue Abhebung… Shares Bought… Anteile gekauft… Shares Sold… Anteile verkauft… New Security Shares Bought… Anteile gekaufter Wertpapiere… Security Shares Sold… Anteile verkaufter Wertpapiere… New Dividend… Neue Dividende… Edit… Bearbeiten… Delete Löschen Total value: Gesamtwert: Error Fehler No suitable account available. Kein geeignetes Konto verfügbar. Invalid date. Ungültiges Datum. Future dates is not allowed. Ein Datum in der Zukunft ist nicht erlaubt. A split must contain at least two transactions. Eine geteilte Transaktion besteht aus mindestens zwei Transaktionen. Cannot transfer money to and from the same account. Transfer zum selben Konto können nicht durchgeführt werden. Eqonomize Accounts && Categories Konten && Kategorien Expenses Ausgaben Incomes Einnahmen Transfers Überweisungen Transaction Accounts Girokonten Savings Accounts Sparkonten Credit Cards Kreditkarten Debts Schulden Securities Wertpapiere Schedule Terminplan Account / Category Konto / Kategorie Remaining Budget (%1) Verbleibendes Budget (%1) Change (%1) Änderung (%1) Total (%1) Gesamt (%1) %2 of %1 %2 remains of %1 budget %2 von %1 Accounts Konten Includes budgeted transactions beinhaltet geplante Transaktionen Securities Financial security (e.g. stock, mutual fund) Wertpapiere Tags Etikette Period Zeitraum From Von To Nach Select Period Zeitraum wählen Current Month Dieser Monat Current Year Dieses Jahr Current Whole Month Dieser Kalendermonat Current Whole Year Dieses Kalenderjahr Whole Past Month Der letzte Kalendermonat Whole Past Year Das letzte Kalenderjahr Previous Month Vorheriger Monat Previous Year Vorheriges Jahr Show partial budget Zeige Teilbudget Edit Budget Budget bearbeiten Budget: Budget: Month: Monat: Result previous month: Ergebnis des Vormonats: New Security… Neues Wertpapier… New Transaction Neue Transaktion Set Quotation… Kurs setzen… Name Name Value Wert Shares Anteile Quotation Kurs Cost Kosten Profit Gewinn Yearly Rate Jährliche Gebühr Type Typ Account Konto Statistics Period Zeitraum der Statistik New Schedule Neuer Terminplan Edit Bearbeiten Remove Entfernen Next Occurrence Nächstes Vorkommnis Description Beschreibung Description Generic Description Beschreibung Amount Menge Payee/Payer Zahlungsempfänger/-pflichtiger Comments Kommentare Set Schedule Confirmation Time Zeit für die Bestätigung des Terminplans setzen Schedule confirmation time: Zeit für die Bestätigung des Terminplans: Set Budget Period Budgetperiode einstellen First day in budget month: Erster Tag im Haushaltsmonats: 1st 1. 2nd 2. 3rd 3. 4th 4. 5th 5. 6th 6. 7th 7. 8th 8. 9th 9. 10th 10. 11th 11. 12th 12. 13th 13. 14th 14. 15th 15. 16th 16. 17th 17. 18th 18. 19th 19. 20th 20. 21st 21. 22nd 22. 23rd 23. 24th 24. 25th 25. 26th 26. 27th 27. 28th 28. Last Letzten 2nd Last Vorletzten 3rd Last Drittletzten 4th Last Viertletzten 5th Last Fünftletzten Timestamp Zeitstempel Links Remove Link Link entfernen Link to "%1" create link to transaction (link used as verb) Verknüpfen mit "%1" Information Information Link Transaction(s) create link to transaction (link used as verb) Die Transaktion(en) verknüpfen All Alle Import Options Import Optionen Ignore duplicate transactions Doppelte Transaktionen ignorieren Rename duplicate accounts Doppelte Konten umbenennen Rename duplicate categories Doppelte Kategorien umbenennen Rename duplicate securities Doppelte Wertpapiere umbenennen Synchronization Settings Synchronisationseinstellungen Web address: Web Adresse: Download command: Befehl zum Herunterladen: Duplicate Transaction… duplicate as verb Transaktion duplizieren… Create Link create link to or between transaction(s) Erstellen Link New Tag… Neues Etikett… Rename Tag… Etikett umbenennen… Remove Tag Etikett entfernen New Tag Neues Etikett Tag name: Name des Etiketts: Remove tag? Etikett entfernen? Do you wish to remove the tag "%1" from %n transaction(s)? Rename Tag Etikett umbenennen optional optional Link Transactions create link between selected transactions (link used as verb) Transaktionen verknüpfen Create Link to Transaction Erstellen Link zur Transaktion Upload command: Befehl zum Hochladen: mandatory Pflichtfeld Automatic synchronization Automatische Synchronisation Upload Hochladen Uploading… Lade hoch… Error uploading file Fehler beim Hochladen der Datei Error uploading %1: %2. Fehler beim Hochladen von %1: %2. Synchronizing… Synchronisiere… Error synchronizing file Fehler beim Synchronisieren der Datei Error synchronizing %1: %2. Fehler bei der Synchronisierung: %1: %2. Synchronization error Fehler bei der Synchronisierung Synchronize file? Datei synchronisieren? The file has been modified by a different user or program. Do you wish to merge changes? Die Datei wurde von einem anderen Benutzer oder Programm geändert. Möchten Sie Änderungen zusammenführen? New version available Neue Version verfügbar A new version of %1 is available.<br><br>You can get version %2 at %3. Eine neue Version von %1 ist verfügbar.<br><br>Sie können die Version %2 hier herunterladen: %3. Abort Abbrechen Failed to download exchange rates from %1: %2. Fehler beim Herunterladen der Wechselkurse von %1: %2. Error reading data from %1: %2. Fehler beim Laden von %1: %2. Unrecognized Currency Unbekannte Währung No exchange rate is available for the default currency (%1). If you wish to use multiple currencies you should set the exchange rate manually. Für die Standardwährung (%1) ist kein Wechselkurs verfügbar. Wenn Sie mehrere Währungen verwenden möchten, müssen Sie den Wechselkurs manuell einstellen. Set Main Currency Primäre Währung setzen Currency: Währung: Replace all occurrences of the former main currency Ersetzen Sie alle Vorkommnisse der früheren Hauptwährung Transaction Account Girokonto Import %1 File… %1-Datei importieren… Reconcile Account… Konto abgleichen… Adjust balance… Referring to account balance Kontostand anpassen… Close Account Mark account as closed Konto schließen Show payee and quantity Zeige Zahlungsempfänger und Menge an Show quantity and payer/payee properties for incomes and expenses. Zeigen Sie die Menge und die Eigenschaften des Zahlungspflichtigen/Zahlungsempfängers für Einnahmen und Ausgaben an. Set Schedule Confirmation Time… Zeit für die Bestätigung des Terminplans setzen… Select Font… Schriftart auswählen… Language Sprache Default Standard Restart required Only use this when unable to find the cause of the incorrect recorded account balance. Verwenden Sie diese Option nur, wenn Sie die Ursache für den falsch erfassten Kontostand nicht finden können. Reopen Account Mark account as not closed Konto wiedereröffnen New Debt Payment… Neue Schuldzahlung… New Unpaid Interest… Neue unbezahlte Zinsen… New Expense Paid with Loan… Neue Ausgaben mit Darlehen bezahlt… Shares of one security directly exchanged for shares of another Financial shares Wertpapieranteile direkt in die Anteile eines anderen Wertpapiers umgetauscht Eqonomize! Accounting File Eqonomize! Buchhaltungsdatei Save file? Datei speichern? New Loan Neues Darlehen Adjust Account Balance Kontostand anpassen New Security Neues Wertpapier Edit Security Wertpapier bearbeiten Total value: Gesamtwert: Cost: Kosten: Profit: Gewinn: Rate: Gebühren: Delete security? Wertpapier löschen? Are you sure you want to delete the security "%1" and all associated transactions? Sind Sie sicher, daß Sie das Wertpapier "%1" und alle zugehörigen Transaktionen löschen wollen? Error Fehler No security available. Kein Wertpapier verfügbar. Set Quotation (%1) Rate setzen (%1) Price per share: Preis pro Anteil: Date: Datum: Invalid date. Ungültiges Datum. Future dates are not allowed. Termine in der Zukunft sind nicht erlaubt. Security Transactions Wertpapiertransaktionen Bond Anleihe Stock Aktie Mutual Fund Investmentfonds Other Anderes Add Loan Kredit hinzufügen Add Category Kategorie hinzufügen Ledger Hauptbuch To date is before from date. "Bis"-Datum liegt vor dem "Von"-Datum. From date is after to date. "Von"-Datum liegt hinter dem "Bis"-Datum. Cash Bargeld Check Account Kontokorrent Savings Account Rücklagekonto Salary Gehalt Bills Rechnungen Clothing Kleidung Groceries Lebensmittel Leisure Vergnügen Couldn't open file Konnte Datei nicht löschen Error loading %1: %2. Fehler beim Laden von %1: %2. Couldn't save file Konnte Datei nicht speichern Error saving %1: %2. Fehler beim Speichern von %1: %2. Transaction Schedule Transaktionen Terminplan Total Gesamt Accounts &amp; Categories html format Konten &amp; Kategorien Accounts &amp; Categories (%1&ndash;%2) html format Konten &amp; Kategorien (%1&ndash;%2) Accounts &amp; Categories (to %1) html format Konten &amp; Kategorien (bis %1) Change Noun, how much the account balance has changed Änderung Balance Bilanz Current Account Girokonto Credit Card Kreditkarte Liabilities Verbindlichkeiten New Security… Financial security (e.g. stock, mutual fund) Neues Wertpapier… Set Quotation… Financial quotation Kurs setzen… Shares Financial shares Anteile Quotation Financial quotation Kurs Delete security? Financial security (e.g. stock, mutual fund) Wertpapier löschen? Are you sure you want to delete the security "%1" and all associated transactions? Financial security (e.g. stock, mutual fund) Sind Sie sicher, daß Sie das Wertpapier "%1" und alle zugehörigen Transaktionen löschen wollen? No security available. Financial security (e.g. stock, mutual fund) Kein Wertpapier verfügbar. Set Quotation (%1) Financial quotation Rate setzen (%1) Price per share: Financial shares Preis pro Anteil: Security Transactions Financial security (e.g. stock, mutual fund) Wertpapiertransaktionen Stock Financial stock Aktie Balance Noun. Balance of an account Kontostand Category Kategorie Budget Budget Remaining Budget Verbleibendes Budget Total Incomes Gesamte Einnahmen Costs Kosten Total Expenses Gesamte Ausgaben Account/Category Noun, how much the account balance has changed Konto/Kategorie Empty expenses list. Leere Ausgabenliste. Empty incomes list. Leere Einnahmenliste. Empty transfers list. Leere Überweisungsliste. Empty securities list. Leere Wertpapierliste. Empty schedule list. Leerer Terminplan. Couldn't open file for writing. Konnte Datei nicht zum Schreiben öffnen. Error while writing file; file was not saved. Fehler beim Schreiben der Datei; Datei wurde nicht gespeichert. &File &Datei &Accounts &Konten &Transactions &Transaktionen &Securities &Wertpapiere Stat&istics Stat&istiken S&ettings &Einstellungen &Help &Hilfe File Datei Transactions Transaktionen Statistics Statistiken &New &Neu &Open… &Öffnen… Open Recent Zuletzt geöffnete Dateien Clear List Liste leeren &Save &Speichern Save As… Speichern unter… &Revert &Zuletzt gespeicherte Fassung S&ynchronize Synchronisieren &Print… &Drucken… Print Preview… Druckvorschau… &Print View… &Ansicht drucken… Import Importieren Import CSV File… CSV-Datei importieren… Import QIF File… QIF-Datei importieren… Export View… Ansicht exportieren… Export As QIF File… QIF-Datei exportieren… &Quit &Beenden Add Account… Konto hinzufügen… New Account… Neues Konto… New Income Category… Neue Einkommenkategorie… New Expense Category… Neue Ausgabenkategorie… Add Account Konto hinzufügen Assets Vermögenswerte Set Quote… Financial quote Kurs setzen… Quote Financial quote Kurs Description Transaction description property (transaction title/generic article name) Beschreibung First month in budget year: Erster Monat im Haushaltsjahrs: New Security Financial security (e.g. stock, mutual fund) Neues Wertpapier Edit Security Financial security (e.g. stock, mutual fund) Wertpapier bearbeiten Set Quote (%1) Financial quote Kurs setzen (%1) Right align Rechts ausrichten %f = local file (temporary), %u = url %f = lokale Datei (temporär), %u = URL Updating exchange rates… Aktualisiere Wechselkurse… Error saving currencies: %1. Fehler beim Speichern der Währungen: %1. New currency… Neue Währung… &Loans &Kredite &Securities Financial security (e.g. stock, mutual fund) &Wertpapiere Update Exchange Rates Wechselkurse aktualisieren Currency Converter Währungsrechner New Loan… Neues Darlehen… Edit… Bearbeiten… Balance… Bilanzieren… Show Transactions Transaktionen anzeigen Show Ledger Hauptbuch anzeigen New Expense… Neue Ausgabe… New Income… Neue Einnahme… New Transfer… Neue Überweisung… New Split Transaction… Neue geteilte Transaktion… New Expense with Multiple Payments… Neue Ausgabe mit mehreren Zahlungen… Refund… Erstattung… Repayment… Tilgung… New Refund/Repayment… Neue Erstattung/Tilgung… Edit Transaction(s) (Occurrence)… Bearbeite Transaktion(en) (Vorkommnis)… Edit Occurrence… Vorkommnis bearbeiten… Edit Schedule (Recurrence)… Bearbeite Terminplan (Wiederholung)… Edit Schedule… Terminplan bearbeiten… Edit Split Transaction… Bearbeite geteilte Transaktionen… Join Transactions… join transactions together Transaktionen zusammenfassen… Split Up Transaction split up joined transactions Transaktion aufteilen Edit Timestamp… Zeitstempel bearbeiten… Select Associated File Verknüpfte Datei auswählen Open Associated File Verknüpfte Datei öffnen Remove Transaction(s) (Occurrence) Transaktion(en) entfernen (Vorkommnis) Remove Occurrence Vorkommnis entfernen Delete Schedule (Recurrence) Terminplan löschen (Wiederholung) Delete Schedule Terminplan löschen Remove Split Transaction Entferne aufgeteilte Transaktionen Edit Security… Wertpapier bearbeiten… Remove Security Wertpapier entfernen Shares Bought… Anteile gekauft… Shares Sold… Anteile verkauft… Shares Moved… Verschobene Anteile… Dividend… Dividende… Reinvested Dividend… Reinvestierte Dividende… Transactions… Transaktionen… Edit Quotations… Kurse bearbeiten… Development Over Time Report… Bericht "Entwicklung über Zeit"… Categories Comparison Report… Bericht "Kategorienvergleich"… Development Over Time Chart… Diagramm "Entwicklung über Zeit"… Categories Comparison Chart… Diagramm "Kategorienvergleich"… Use Additional Transaction Properties Zusätzliche Transaktionseinstellungen verwenden Set Main Currency… Primäre Währung einstellen… Use Exchange Rate for Transaction Date Verwenden Sie den Wechselkurs für das Transaktionsdatum Use the exchange rate nearest the transaction date, instead of the latest available rate, when converting the value of transactions. Verwenden Sie zum Umrechnen des Transaktionswerts den Wechselkurs, der dem Transaktionsdatum am nächsten ist, und nicht den letzten verfügbaren Kurs. Set Budget Period… Budgetperiode einstellen… Initial Period Zeitraum beim Start Backup Frequency Backup Häufigkeit Daily Täglich Weekly Wöchentlich Fortnightly Vierzehntäglich Monthly Monatlich Never Nie Cloud Synchronization (experimental)… Cloud Synchronisation (Experimentel)… Dark Mode Dunkelmodus About %1 Über %1 Please restart the application for the language change to take effect. A personal accounting program Ein Programm für die private Buchhaltung License: GNU General Public License Version 3 Lizenz: GNU General Public License Version 3 %1 exited unexpectedly before the file was saved and data was lost. Do you want to load the last auto-saved version of the file? %1 wurde unerwartet beendet, bevor die Datei gespeichert werden konnte. Es kann zu Datenverlust gekommen sein. Wollen Sie die letzte automatisch gespeicherte Version dieser Datei laden? Whole Month Dieser Kalendermonat Whole Year Dieses Kalenderjahr Remember Last Dates Definierten Zeitraum merken Help Hilfe Report Bug Probleme oder Wünsche melden About Eqonomize! Über Eqonomize! About Qt Über Qt About Eqonomize Über Eqonomize <font size=+2><b>Eqonomize! v0.6</b></font><br><font size=+1>A personal accounting program</font><br><<font size=+1><i><a href="http://eqonomize.github.io/">http://eqonomize.github.io/</a></i></font><br><br>© 2006-2008, 2014, 2016 Hanna Knutsson<br>License: GNU General Public License Version 2 <font size=+2><b>Eqonomize! v0.6</b></font><br><font size=+1>Ein Programm für die private Buchhaltung</font><br><<font size=+1><i><a href="http://eqonomize.github.io/">http://eqonomize.github.io/</a></i></font><br><br>© 2006-2008, 2014, 2016 Hanna Knutsson<br>Lizenz: GNU General Public License Version 2 Crash Recovery Absturz-Wiederherstellung Eqonomize! exited unexpectedly before the file was saved and data was lost. Do you want to load the last auto-saved version of the file? Eqonomize! wurde unerwartet beendet, bevor die Datei gespeichert werden konnte. Es kann zu Datenverlust gekommen sein. Wollen Sie die letzte automatisch gespeicherte Version dieser Datei laden? Untitled Unbennant Checking Account Transactional account Girokonto Balance Account balance Kontostand Empty securities list. Financial security (e.g. stock, mutual fund) Leere Wertpapierliste. Balance… Balance account Bilanzieren… Edit Security… Financial security (e.g. stock, mutual fund) Wertpapier bearbeiten… Remove Security Financial security (e.g. stock, mutual fund) Wertpapier entfernen Shares Bought… Financial shares Anteile gekauft… Shares Sold… Financial shares Anteile verkauft… Edit Quotations… Financial quotation Kurse bearbeiten… The current file has been modified. Do you want to save it? Die Datei wurde verändert. Möchten Sie sie speichern? Confirm Schedule Terminplan bestätigen New Account Neues Konto New Income Category Neue Einnahmenkategorie New Expense Category Neue Ausgabenkategorie Balance Account Konto bilanzieren Book value: Buchwert: of which %1 is balance adjustment Referring to account balance von welchem %1 is die Bilanzanpassung Real value: Realwert: Edit Account Konto bearbeiten Edit Income Category Einnahmenkategorie bearbeiten Edit Expense Category Ausgabenkategorie bearbeiten Remove subcategories? Unterkategorien entfernen? Do you wish to remove the category including all subcategories? Möchten Sie die Kategorie mit allen Unterkategorien entfernen? Move transactions? Transaktionen verschieben? Move to: Verschieben nach: Remove irreversibly from all accounts (do not do this if account has been closed!) Von allen Konten unwiderruflich entfernen (Tun Sie dies nicht, wenn das Konto geschlossen wurde!) The category contains some expenses. What do you want to do with them? Die Kategorie enthält einige Ausgaben. Was wollen Sie mit diesen tun? The category contains some incomes. What do you want to do with them? Die Kategorie enthält einige Einnahmen. Was wollen Sie mit diesen tun? The account contains some transactions. What do you want to do with them? Dieses Konto enthält einige Tranaktionen. Was wollen Sie mit diesen tun? Remove Category? Kategorie entfernen? The category contains some expenses that will be removed. Do you still want to remove the category? Die Kategorie enthält einige Ausgaben, die entfernt werden würden. Wollen Sie die Kategorie wirklich entfernen? The category contains some incomes that will be removed. Do you still want to remove the category? Die Kategorie enthält einige Einnahmen, die entfernt werden würden. Wollen Sie die Kategorie wirklich entfernen? Remove Account? Konto entfernen? The account contains some transactions that will be removed. Do you still want to remove the account? Das Konte enthält einige Transaktionen, die entfernt werden würden. Wollen Sie das Konto wirklich entfernen? %2 of %1 %1: budget; %2: remaining budget %2 von %1 Balance… Verb. Balance an account Bilanzieren… Shares Exchanged… Shares of one security directly exchanged for shares of another; Financial shares Getauschte Anteile… Edit Quotes… Financial quote Kurse bearbeiten… Balance Account Verb Konto bilanzieren %1 (with no budget) %1 (ohne Budget) %1 (with budget %2) %1 (mit Budget %2) EqonomizeCalendarWidget Today Heute EqonomizeDateEdit Today Heute EqonomizeTranslator OK Only used when Qt translation is missing Cancel Only used when Qt translation is missing Close Only used when Qt translation is missing &Yes Only used when Qt translation is missing &No Only used when Qt translation is missing &Open Only used when Qt translation is missing &Save Only used when Qt translation is missing &Select All Only used when Qt translation is missing Look in: Only used when Qt translation is missing File &name: Only used when Qt translation is missing Files of type: Only used when Qt translation is missing EqonomizeValueEdit Error Fehler Empty denominator. Leerer Nenner. Empty factor. Leerer Faktor. Division by zero. Division durch Null. Unknown or ambiguous currency, or unrecognized characters, in expression: %1. Unbekannte oder mehrdeutige Währung oder nicht erkannte Zeichen im Ausdruck: %1. Empty base. Leere Basis. Empty exponent. Leerer Exponent. Unrecognized characters in expression. Nicht erkannte Zeichen im Ausdruck. ExportQIFDialog Export QIF File Exportiere als QIF-Datei Account: Konto: All All accounts Alle Export transaction description as: Beschreibung dieser Transaktion exportieren als: Export transaction description as: Referring to generic description Beschreibung dieser Transaktion exportieren als: Payee Zahlungsempfänger Memo Notiz Subcategory Unterkategorie Date format: Datumsformat: Value format: Zahlenformat: File: Datei: Error Fehler Selected file is a directory. Die ausgewählte Datei ist ein Verzeichnis. Overwrite Überschreiben The selected file already exists. Would you like to overwrite the old copy? Diese Datei existiert bereits. Soll die alte Kopie überschrieben werden? You selected a directory! Es wurde ein Verzeichnis ausgewählt! Couldn't open file for writing. Konnte Datei nicht zum Schreiben öffnen. Error while writing file; file was not saved. Fehler beim Schreiben der Datei; Datei wurde nicht gespeichert. ImportCSVDialog Import CSV file CSV-Datei importieren Transaction Type Selection Auswahl des Transaktionstyps Expenses Ausgaben Incomes Einnahmen Transfers Überweisungen Expenses and incomes (negative cost) Ausgaben und Einnahmen (negative Kosten) Expenses and incomes (separate columns) Ausgaben und Einnahmen (getrennte Spalten) All types Alle Typen Presets: Voreinstellungen: File Selection Dateiauswahl File: Datei: First data row: Erste Zeile mit Daten: Auto Auto Column delimiter: Spaltentrenner: Comma Komma Tabulator Tabulator Semicolon Semikolon Space Leerzeichen Other Anderes Columns Specification Spaltenbeschreibung Save as preset… Als Voreinstellung speichern… Imports data as expenses and incomes. Costs have negative value. Value is the only required column. Importiert Daten als Ausgaben und Einnahmen. Kosten haben einen negativen Wert. Die einzige benötigte Spalte ist "Wert". Imports data as expenses and incomes. Costs and incomes have separate columns. Income and cost both all required columns. Importiert Daten als Ausgaben und Einnahmen. Kosten und Einnahmen haben getrennte Spalten. Spalten für "Costen" und "Einnahmen" werden benötigt. Warning Warnung The same column number is selected multiple times. Do you wish to proceed anyway? Description: Beschreibung: Generic description: oder Allgemeine Beschreibung, oder Gattungsbezeichnung Allgemeine Bezeichnung: Description: Transaction description property (transaction title/generic article name) Beschreibung: Column Spalte Value Wert Cost: Kosten: Date: Datum: Category: Kategorie: From account: Vom Konto: Quantity: Menge: Payee: Zahlungsempfänger: Tags: Etikette: Comments: Kommentare: Create missing categories and accounts Erstelle fehlende Kategorien und Konten an Save Preset Voreinstellung speichern Imports data as expenses. Costs have positive value. Value is the only required column. Importiere Daten als Ausgaben. Kosten haben einen positiven Wert. "Wert" ist die einzig benötigte Spalte. Imports data as incomes. Value is the only required column. Importiert Daten als Einnahmen. Einzig benötigte Spalte ist "Wert". Income: Einnahmen: To account: Zum Konto: Payer: Zahlungspflichtiger: Imports data as transfers. Value is the only required column. Importiert Daten als Transaktionen. Die einzige benötigte Spalte ist "Wert". Amount: Menge: Imports data as expenses and incomes. Costs have negative value. Value and category are both required columns. Importiert Daten als Ausgaben und Einnahmen. Kosten haben einen negativen Wert. Spalten für "Wert" und "Kategorie" werden benötigt. Value: Wert: Account: Konto: Payee/payer: Zahlungsempfänger/-pflichtiger: Imports data as expenses and incomes. Costs and incomes have separate columns. Income, cost, and category are all required columns. Importiert Daten als Ausgaben und Einnahmen. Kosten haben einen negativen Wert. Spalten für "Wert" und "Kategorie" werden benötigt. Imports data as expenses, incomes, and transfers. Costs have negative or positive value. Value, to, and from are all required columns. Accounts and categories must be existing. Importiert Daten als Ausgaben, Einnahmen und Transaktionen. Kosten müssen negative oder positive Werte haben. Benötigte Spalten sind "Wert", "Von" und "Nach". Alle Konten und Kategorien müssen bereits existieren. From: Von: To: Nach: Error Fehler A file must be selected. Es muss eine Datei ausgewählt werden. Selected file is a directory. Die ausgewählte Datei ist ein Verzeichnis. Selected file does not exist. Die ausgewählte Datei existiert nicht. Empty delimiter. Leeres Trennzeichen. The same column number is selected multiple times. Die selbe Spaltennummer ist mehrfach ausgewählt. Selected from account is the same as the to account. Das gewählte Ausgangskonto ist identisch mit dem Eingangskonto. Invalid date. Ungültiges Datum. Couldn't open %1 for reading. Konnte %1 nicht zum Lesen öffnen. Error reading %1. Fehler beim Lesen von %1. Uncategorized Nicht kategorisiert Successfully imported %n transaction(s). %n Transaktion erfolgreich eingelesen. %n Transaktionen erfolgreich eingelesen. Unable to import any transactions. Es konnten keine Transaktionen importiert werden. Failed to import %n data row(s). %n Datensatz konnte nicht eingelesen werden. %n Datensätze konnten nicht eingelesen werden. Required columns missing. Notwendige Spalten fehlen. Invalid value. Ungültiger Wert. Empty category name. Leerer Kategorienname. Empty account name. Leerer Kontoname. Unknown category found. Unbekannte Kategorie gefunden. Unknown account found. Unbekanntes Konto gefunden. Cannot import security transactions (to/from security accounts). Kann Wertpapiertransaktionen nicht importieren (von/nach Wertpapierkonten). Balancing account wrongly used. Referring to the account used for adjustments of account balances. Bilanzierungskonto falsch verwendet. Balancing account wrongly used. Bilanzierungskonto falsch verwendet. Same to and from account/category. Identische von und nach Konten/Kategorien. No data found. Keine Daten gefunden. Information Information Unrecognized date format. Unbekanntes Datumsformat. Specify Format Format bestimmen The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. Das Format von Terminen und/oder Zahlen in der CSV-Datei ist zweideutig. Bitte wählen Sie das korrekte Format. Date format: Datumsformat: Value format: Zahlenformat: ImportQIFDialog Import QIF file QIF-Datei importieren File Selection Dateiauswahl Select a QIF file to import. When you click next, the file be analysed and you might need to answer some questions about the format of the file. Wählen Sie eine QIF-Datei zum Import. Wenn Sie "Weiter" klicken, wird die Datei analysiert und Sie müssen unter Umständen weitere Fragen über das Dateiformat beantworten. File: Datei: Local Definitions Lokale Definitionen Unknown elements where found in the QIF file. It is possible that this is because of localized type names. Please map them to the correct standard names. Es wurden unbekannte Elemente in dieser QIF-Datei gefunden. Dies kann durch lokal angepasste Typnamen verursacht worden sein. Bitte entschlüsseln Sie diese zu den korrekten Standardnamen. Local Text Lokaler Text Standard Text Standardtext Select standard text: Standardtext auswählen: Date Format Datumsformat The date format in the QIF file is ambiguous. Please select the correct format. Das Datumsformat in diser QIF-Datei ist zweideutig. Bitte wählen Sie das korrekte Datumsformat. Date format: Datumsformat: Default Account Standardkonto Could not find any account definitions in the QIF file. Please select a default account. It is also possible that this is caused by a localized opening balance text. Konnte keine Kontendefinitionen in der QIF-Datei finden. Bitte wählen Sie ein Standardkonto. Dies kann durch lokal veränderte Anfangsbestand Texte entstenen. Default account: Standardkonto: Opening balance text: Anfangsbestand Text: Descriptions Beschreibungen Transactions in QIF files does not have any specific description property. You are therefore given the option to choose how the description of imported transactions will be set. Transaktionen in QIF-Dateien haben keine eigene Beschreibungsfelder. Daher erhalten Sie die Möglichkeit zu wählen, wie die Beschreibungen der importierten Transaktionen gefüllt werden. Subcategories as: Unterkategorien als: Description Beschreibung Generic Descriptions Allgemeinen Bezeichnungen Transactions in QIF files does not have any specific description property. You are therefore given the option to choose how the description of imported transactions will be set. Referring to generic description Transaktionen in QIF-Dateien haben keine eigene Beschreibungsfelder. Daher erhalten Sie die Möglichkeit zu wählen, wie die Beschreibungen der importierten Transaktionen gefüllt werden. Generic description Allgemeine Bezeichnung Category Kategorie Ignore Ignorieren Payee as: Zahlungsempfänger als: Payee Zahlungsempfänger Memo as: Notiz als: Comments Kommentare Priority: Priorität: Subcategory/Payee/Comments Unterkategorie/Zahlungsempfänger/Kommentare Payee/Subcategory/Comments Zahlungsempfänger/Unterkategorie/Kommentare Subcategory/Comments/Payee Unterkategorie/Kommentare/Zahlungsempfänger Payee/Comments/Subcategory Zahlungsempfänger/Kommentare/Unterkategorie Comments/Subcategory/Payee Kommentare/Unterkategorie/Zahlungsempfänger Comments/Payee/Subcategory Kommentare/Zahlungsempfänger/Unterkategorie Import File Datei importieren No (further) issues were found. Press finish to import the selected QIF file. Keine (weiteren) Probleme wurden gefunden. Drücken Sie auf Fertigstellen, um die ausgewählte QIF-Datei zu importieren. Ignore duplicate transactions Doppelte Transaktion ignorieren Error Fehler A file must be selected. Es muss eine Datei ausgewählt werden. Selected file is a directory. Die ausgewählte Datei ist ein Verzeichnis. Selected file does not exist. Die ausgewählte Datei existiert nicht. Couldn't open %1 for reading. Konnte %1 nicht zum Lesen öffnen. Error reading %1. Fehler beim Lesen von %1. Unknown Unbekannt Account Konto Bank Bank Cash Bargeld Cat (Category) Kat. (Kategorie) CCard (Credit Card) Kreditkarte Invst (Investment) Invst. (Investitionen) Oth A (Other Assets) Oth A (Andere Vermögenswerte) Oth L (Other Liabilities) Oth L (Verbindlichkeiten) Security Wertpapier Other Anderes Unrecognized date format. Unbekanntes Datumsformat. Successfully imported %n transaction(s). %n Transaktion erfolgreich eingelesen. %n Transaktionen erfolgreich eingelesen. Successfully imported %n account(s). %n Konto wurde erfolgreich importiert. %n Konten wurden erfolgreich importiert. Successfully imported %n category/categories. %n Kategorie wurde erfolgreich importiert. %n Kategorien wurden erfolgreich importiert. %n duplicate transaction(s) was ignored. %n doppelte Transaktion wurde ignoriert. %n doppelte Transaktionen wurden ignoriert. Failed to import %n transaction(s). Fehler beim impotrieren von %n Transaktion. Fehler beim impotrieren von %n Transaktionen. %n security/securities were not imported. Financial security (e.g. stock, mutual fund) %n Wertpapier wurde nicht importiert. %n Wertpapiere wurden nicht importiert. %n security transaction(s) were not imported. Financial security (e.g. stock, mutual fund) %n Wertpapiertransaktion wurde nicht importiert. %n Wertpapiertransaktionen wurden nicht importiert. %n security/securities were not imported. %n Wertpapier wurde nicht importiert. %n Wertpapiere wurden nicht importiert. %n security transaction(s) were not imported. %n Wertpapiertransaktion wurde nicht importiert. %n Wertpapiertransaktionen wurden nicht importiert. Information Information Income Dividend: %1 Dividende: %1 Reinvested dividend: %1 Reinvestierte Dividende: %1 LedgerDialog Account: Konto: Edit Account… Konto bearbeiten… Export… Exportieren… Print… Drucken… Reconcile Accounting context Kontenabgleich Mark all as reconciled Accounting context Markiere alle als abgeglichen Change: Accounting context Änderung: R Header for account reconciled checkbox column A Date Datum Type Typ Description Beschreibung Name Name Description Generic Description Beschreibung Account/Category Konto/Kategorie Deposit Einlage Withdrawal Abhebung Balance Bilanz Balance Account balance Kontostand Payee/Payer Zahlungsempfänger/-pflichtiger Tags Etikette Comments Kommentare Deposit Money put into account Einlage Withdrawal Money taken out from account Abhebung Balance Noun. Balance of an account Kontostand New Neu Edit… Bearbeiten… Delete Löschen Join… join transactions together Zusammenfassen… Split Up split up joined transactions Aufteilen Edit Transaction(s)… Bearbeite Transaktion(en)… Join Transactions… Transaktionen zusammenfassen… Split Up Transaction Transaktion aufteilen Open Associated File Verknüpfte Datei öffnen Remove Transaction(s) Transaktion(en) entfernen Mark as reconciled Markiere als abgeglichen Reconciled: %1 (%2) Accounting context Ausgeglichen: %1 (%2) Book value: %1 (%2) Accounting context Buchwert: %1 (%2) Mark as reconciled Accounting context Markiere als abgeglichen Error Fehler Invalid date. Ungültiges Datum. Opening date is after closing date. Das Öffnungsdatum ist nach dem Schließdatum. Closing date is before opening date. Das Schließdatum liegt vor dem Öffnungsdatum. Empty transaction list. Leere Transaktionsliste. Couldn't open file for writing. Konnte Datei nicht zum Schreiben öffnen. Error while writing file; file was not saved. Fehler beim Schreiben der Datei; Datei wurde nicht gespeichert. Ledger Hauptbuch Transactions for %1 Transaktionen für %1 Select Time Period Zeitraum auswählen From: Von: To: Nach: To date is before from date. "Bis"-Datum liegt vor dem "Von"-Datum. Balance change: Account balance Kontostand: Delete transactions? Transaktionen löschen? Are you sure you want to delete all (%1) selected transactions? Sind Sie sicher, daß Sie alle (%1) ausgewählten Transaktionen löschen wollen? Cannot set the value of security transactions using the dialog for modifying multiple transactions. Financial security (e.g. stock, mutual fund) Der Wert von Wertpapiertransaktionen kann nicht über den Dialog zum Ändern mehrerer Transaktionen geändert werden. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name); Financial security (e.g. stock, mutual fund) Die Beschreibung für Dividenden- und Wertpapiertransaktionen kann nicht geändert werden. Cannot change payer of dividends and security transactions. Financial security (e.g. stock, mutual fund) Der Zahlungspflichtige von Dividenden und Wertpapieren kann nicht verändert werden. Opening balance Account balance Anfangsbestand Account Balance Adjustment Kontostand anpassen Current balance: Account balance Akuteller Kontostand: Average balance: Account balance Durchschnittlicher Kontostand: Account Balancing Balancing of an account Kontenbilanzierung Balancing Balancing of an account Kontenbilanzierung Balancing Account balancing Bilanzieren Cannot set the value of security transactions using the dialog for modifying multiple transactions. Der Wert von Wertpapiertransaktionen kann nicht über den Dialog zum Ändern mehrerer Transaktionen geändert werden. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name) Die Beschreibung für Dividenden- und Wertpapiertransaktionen kann nicht geändert werden. Cannot change description of dividends and security transactions. Referring to the generic description property Die Beschreibung für Dividenden- und Wertpapiertransaktionen kann nicht geändert werden. Current debt: Aktuelle Schulden: Total debt reduction: Gesamtschuldenabbau: Total interest and fees: Zinsen und Gebühren insgesamt: Number of transactions: Anzahl der Transaktionen: Cannot change description of dividends and security transactions. Die Beschreibung für Dividenden- und Wertpapiertransaktionen kann nicht geändert werden. Cannot change payer of dividends and security transactions. Der Zahlungspflichtige von Dividenden und Wertpapiere kann nicht verändert werden. Cannot change date of transactions that are part of a split transaction. Das Datum der Transaktionen, die Teil einer Transaktion sind, kann nicht geändert werden. Initial balance Wert zu Beginn Split Transaction Geteilte Transaktion Debt Payment Schuldenzahlung Ascending order Aufsteigende Reihenfolge Reduction Reduzierung Fee Gebühr Interest Zinsen Income Einnahmen Repayment Rückzahlung Expense Ausgabe Opening balance: Accounting context Anfangsbestand: Closing balance: Accounting context Abschlussbilanz: Description Transaction description property (transaction title/generic article name) Beschreibung Cannot change description of dividends and security transactions. Referring to the Transaction description property (transaction title/generic article name) Die Beschreibung für Dividenden- und Wertpapiertransaktionen kann nicht geändert werden. Refund Rückerstattung Balancing Bilanzieren Transfer Überweisung LinksWidget Remove Link Link entfernen All Alle Remove Entfernen MultiItemListViewItem Dividend Dividende Income Einnahmen Repayment Rückzahlung Expense Ausgabe Refund Rückerstattung Securities Purchase Financial security (e.g. stock, mutual fund) Wertpapierkauf Securities Sale Financial security (e.g. stock, mutual fund) Wertpapierverkauf Account Balance Adjustment Kontostand anpassen Account Balancing Balancing of an account Kontenbilanzierung Balancing Balancing of an account Bilanzieren Security Buy Wertpapierkauf Security Sell Wertpapierverkauf Balancing Bilanzieren Transfer Überweisung MultipleTransactionsEditDialog Modify Transactions Transaktionen bearbeiten Description: Beschreibung: Name: Name: Generic Description: Allgemeine Bezeichnung: Description: Transaction description property (transaction title/generic article name) Beschreibung: Amount: Menge: Income: Einnahmen: Cost: Kosten: Date: Datum: Category: Kategorie: Payer: Zahlungspflichtiger: Payee: Zahlungsempfänger: New Income Category Neue Einnahmenkategorie New Expense Category Neue Ausgabenkategorie Error Fehler No income category available. Einkommenkategorie nicht verfügbar. No expense category available. Ausgabenkategorie nicht verfügbar. Invalid date. Ungültiges Datum. OverTimeChart Save As… Speichern unter… Print… Drucken… Source: Quelle: Incomes and Expenses Einnahmen und Ausgaben Profits Einkünfte Expenses Ausgaben Incomes Einnahmen All Categories Combined Alle Kategorien zusammen All Descriptions Combined Alle Beschreibungen zusammen Theme: Thema: Chart type: Diagramm Typ: Line Chart Liniendiagramm Vertical Bar Chart Vertikales Balkendiagramm Horizontal Bar Chart Horizontales Balkendiagramm Stacked Bar Chart Gestapeltes Balkendiagramm Default Standard Tags Etikette All Accounts Combined Alle Konten zusammengefasst All Accounts Split Alle Konten aufgeteilt All Subcategories and Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Alle Kategorien und Unterkategorien zusammen All Descriptions Split Referring to the transaction description property (transaction title/generic article name) Alle Beschreibungen aufgeteilt No description Referring to the transaction description property (transaction title/generic article name) Keine Beschreibung All Payees/Payers Split Alle Zahlungsempfänger/-pflichtigen geteilt No payee/payer Keine Zahlungsempfänger/-pflichtigen All Tags Split Alle Etikette geteilt Other tags Andere Etikette Other payees/payers Andere Zahlungsempfänger/-pflichtigen Other descriptions Referring to the transaction description property (transaction title/generic article name) Andere Beschreibungen Profits, %1 Einkünfte, %1 Assets Vermögenswerte All Descriptions Combined Referring to the generic description property Alle Beschreibungen zusammen Assets and Liabilities Vermögenswerte und Verbindlichkeiten All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Alle Beschreibungen zusammen All Payees/Payers Combined Alle Zahlungsempfänger/-pflichtigen zusammengefasst All Accounts Alle Konten Start date: Startdatum: End date: Enddatum: Value: Wert: Annual total Jährlich gesamt Monthly total Monatlich gesamt Daily average Täglicher Durchschnitt Quantity Anzahl Average value Durchschnittlicher Wert All Payers Combined Alle Zahlungspflichtigen zusammengefasst All Payees Combined Alle Zahlungsempfänger zusammengefasst All Subcategories Split Alle Unterkategorien aufgeteilt All Descriptions Split Referring to the generic description property Alle Beschreibungen aufgeteilt No description Referring to the generic description property Keine Beschreibung Value Wert Includes budgeted transactions Beinhaltet budgetierte Transaktionen Incomes − Expenses, %1 Einnahmen − Ausgaben, %1 Incomes − Expenses Einnahmen − Ausgaben Incomes & Expenses Einnahmen & Ausgaben Incomes: %1 Einnahmen: %1 Expenses: %1 Ausgaben: %1 %2: %1 %2: %1 Incomes: %2, %1 Einnahmen: %2, %1 Expenses: %2, %1 Ausgaben: %2, %1 %3: %2, %1 %3: %2, %1 %2, %1 %2, %1 Incomes: %3, %2, %1 Einnahmen: %3, %2, %1 Expenses: %3, %2, %1 Ausgaben: %3, %2, %1 %4: %3, %2, %1 %4: %3, %2, %1 no payee/payer keine Zahlungsempfänger/-pflichtigen %3, %2, %1 %3: %2, %1 Other accounts Andere Konten %1 Value: %2 Date: %3 %1 Wert: %2 Datum: %3 MMMM yyyy Month and year MMMM yyyy All Descriptions Split Alle Beschreibungen geteilt All Payers Split Alle Zahlungspflichtigen geteilt All Payees Split Alle Zahlungsmpfänger geteilt No description Keine Beschreibung No payer Keine Zahlungspflichtigen No payee Keine Zahlungsempfänger All Categories Split Alle Kategorien aufgeteilt Error Fehler Invalid date. Ungültiges Datum. Couldn't open file for writing. Konnte Datei zum Schreiben nicht öffnen. Error while writing file; file was not saved. Fehler beim Schreiben der Datei; Datei wurde nicht gespeichert. Other payees Andere Zahlungsempfänger Other payers Andere Zahlungspflichtige Value (%1) Wert (%1) Profit (%1) Gewinn (%1) Income (%1) Einnahmen (%1) Cost (%1) Kosten (%1) Time Zeit %1/%2 %1: Category; %2: Payee/Payer %1/%2 All Descriptions Combined Referring to the Transaction description property (transaction title/generic article name) Alle Beschreibungen zusammen All Descriptions Split Referring to the Transaction description property (transaction title/generic article name) Alle Beschreibungen geteilt No description Referring to the Transaction description property (transaction title/generic article name) Keine Beschreibung Daily average value Täglicher Durchschnittswert Daily average profit Täglicher durchschnittlicher Gewinn Daily average income Tägliche durchschnittliche Einnahmen Daily average cost Tägliche Durchschnittskosten Average income Durchschnittliche Einnahmen Average cost Durchschnittliche Kosten Annual value Jahreswert Annual profit Jährlicher Gewinn Annual income Jährliche Einnahmen Annual cost Jährliche Kosten Monthly value Monatswert Monthly profit Monatlicher Gewinn Monthly income Monatliche Einnahmen Monthly cost Monatliche Kosten Includes scheduled and budgeted transactions Beinhaltet geplante und budgetierte Transaktionen Includes scheduled transactions Beinhaltet geplante Transaktionen Incomes, %2: 1 Einnahmen, %2: 1 Tags, %1 Etikette, %1 Value: %1 Wert: %1 Assets & Liabilities Vermögenswerte & Verbindlichkeiten Change: %1 Änderung: %1 Excluding any profits or losses in trading of security shares Financial security (e.g. stock, mutual fund) Ausgenommen Gewinne oder Verluste beim Handel mit Wertpapieranteilen Incomes & Expenses, %1 Einnahmen & Ausgaben, %1 Incomes, %1 Einnahmen, %1 Expenses, %1 Ausgaben, %1 Incomes, %2: %1 Einnahmen, %2: %1 Expenses, %2: %1 Ausgaben, %2: %1 Incomes, %3: %2, %1 Einnahmen, %3: %2, %1 Expenses, %3: %2, %1 Ausgaben, %3: %2, %1 Incomes, %4: %3, %2, %1 Einnahmen, %4: %3, %2, %1 Expenses, %4: %3, %2, %1 Ausgaben, %4: %3, %2, %1 Liabilities Verbindlichkeiten no payer kein Zahler %1/%2 %1: Description; %2: Payer/Payer %1/%2 %1/%2 %1: Description; %2: Payee/Payer %1/%2 %1/%2 %1: Description; %2: Payer %1/%2 no payee kein Zahlungsempfänger %1/%2 %1: Description; %2: Payee %1/%2 OverTimeChartDialog Chart Diagramm OverTimeReport Save As… Speichern unter… Print… Drucken… Source: Quelle: Profits Einkünfte Expenses Ausgaben Incomes Einnahmen Assets & Liabilities Vermögenswerte & Verbindlichkeiten Tags Etikette All Categories Combined Alle Kategorien zusammen All Descriptions Combined Alle Beschreibungen zusammen Columns: Spalten: Categories Kategorien Total: Gesamt: Value Wert Daily Täglich Monthly Monatlich Yearly Jährlich Quantity Menge Average value Durchschnittlicher Wert No description Keine Beschreibung All Descriptions Combined Referring to the generic description property Alle Beschreibungen zusammen No description Referring to the generic description property Keine Beschreibung All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Alle Beschreibungen zusammen All Accounts Alle Konten No description Referring to the transaction description property (transaction title/generic article name) Keine Beschreibung Error Fehler Couldn't open file for writing. Konnte Datei nicht zum Schreiben öffnen. Error while writing file; file was not saved. Fehler beim Schreiben der Datei; Datei wurde nicht gesichert. Average Profit Durchschnittliche Einkünfte Incomes, %1 Einnahmen, %1 Average Income Durchschnittliche Einnahmen Expenses, %1 Ausgaben: %1 Average Cost Durchschnittliche Kosten Incomes, %2: %1 Einnahmen, %2: %1 Incomes: %1 Einnahmen: %1 Expenses, %2: %1 Ausgaben, %2: %1 Expenses: %1 Ausgaben: %1 Incomes, %3: %2, %1 Einnahmen, %3: %2, %1 Incomes: %2, %1 Einnahmen: %2, %1 Expenses, %3: %2, %1 Ausgaben, %3: %2, %1 Expenses: %2, %1 Ausgaben: %2, %1 Change: %1 Noun, how much the account balance has changed Veränderung: %1 Average Change Durchschnittliche Veränderung Change Noun, how much the account balance has changed Veränderung Value: %1 Wert: %1 Year Jahr Month Monat Assets Vermögenswerte Deposit Einlage Withdrawal Abhebung Liabilities Verbindlichkeiten %2: %1 %2: %1 %1 %1 Average Value Durchschnittlicher Wert %3: %2, %1 %3: %2, %1 %2, %1 %2, %1 Daily Average Täglicher Durchschnitt Monthly Average Monatlicher Durchschnitt Yearly Average Jährlicher Durchschnitt Subtotal Zwischensumme Total Gesamt Deposit Money put into account Einlage Withdrawal Money taken out from account Abhebung Includes scheduled transactions Beinhaltet geplante Transaktionen Adjusted for the average month / year (%1 / %2 days) An den durchschnittlichen Monat / das durchschnittliche Jahr angepasst (%1 / %2 Tage) All Categories Combined Referring to the generic description property Alle Kategorien zusammen OverTimeReportDialog Report Bericht QApplication Start with expenses list displayed Mit Ausgabenansicht beginnen Start with incomes list displayed Mit Einnahmenansicht beginnen Start with transfers list displayed Mit Transaktionenansicht beginnen Synchronize file Synchronisiere Datei Document to open Zu öffnendes Dokument %1 is already running. %1 läuft bereits. QObject Transfer Überweisung Dividend Dividende Income Einnahme Expense Ausgabe Securities Purchase Financial security (e.g. stock, mutual fund) Wertpapierkauf Securities Sale Financial security (e.g. stock, mutual fund) Wertpapierverkauf Security Buy Wertpapierkauf Security Sell Wertpapierverkauf Debt Payment Schuldenzahlung Split Transaction Teiltransaktion RecurrenceEditWidget Enable recurrence Wiederholung aktivieren Recurrence Rule Regel für Wiederholungen Daily Täglich Weekly Wöchentlich Monthly Monatlich Yearly Jährlich Recur every Wiederhole alle day(s) Tag(e) week(s) on: Woche(n) am: month(s), after the start month Monat(e), nach dem Startmonat Recur on the Wiederholen am 1st 1. 2nd 2. 3rd 3. 4th 4. 5th 5. 6th 6. 7th 7. 8th 8. 9th 9. 10th 10. 11th 11. 12th 12. 13th 13. 14th 14. 15th 15. 16th 16. 17th 17. 18th 18. 19th 19. 20th 20. 21st 21. 22nd 22. 23rd 23. 24th 24. 25th 25. 26th 26. 27th 27. 28th 28. 29th 29. 30th 30. 31st 31. Last Letzten 2nd Last Vorletzten 3rd Last Drittletzten 4th Last Viertletzten 5th Last Fünftletzten day Tag possibly on weekend auch am Wochenende but before weekend aber vor einem Wochenende but after weekend aber nach einem Wochenende nearest weekend day nächster Wochenendtag year(s), after the start year Jahr(e) nach dem Startjahr on nearest weekday am nächsten Werktag Recur on day part before XXX of 'Recur on day XXX of month YYY' Wiederhole am of part between XXX and YYY of 'Recur on day XXX of month YYY' im On the Part before NNN in 'Recur on the NNN. WEEKDAY of MONTH' Am of part between WEEKDAY and MONTH in 'Recur on NNN. WEEKDAY of MONTH' im Recur on day # Wiederhole am of the year part after NNN of 'Recur on day #NNN of the year' Tag des Jahres Range… Bereich… Occurrences/Exceptions… Vorkommnisse/Ausnahmen… Exceptions… Ausnahmen… Error Fehler No day of week selected for weekly recurrence. Kein Wochentag für wöchentliche Wiederholung ausgewählt. Selected day will never occur with selected frequency and start date. Der gewählte Tag liegt nicht innerhalb des gewählten Zeitraumes. Selected day does not exist in selected month. Der gewählte Tag kommt im gewählten Monat nicht vor. RefundDialog Repayment Rückzahlung Refund Rückerstattung Date: Datum: Cost: Kosten: Income: Einnahmen: Quantity returned: Menge zurückgegeben: Account: Konto: Quantity: Menge: Payee: Zahlungsempfänger: Payer: Zahlungspflichtiger: Comments: Kommentare: Link Link the transactions together Verknüpfen Join Join the transactions together Zusammenfassen Error Fehler Zero value not allowed. Null-Wert ist nicht erlaubt. Invalid date. Ungültiges Datum. SecurityBuy Security: %1 (bought) Wertpapier: %1 (gekauft) Security: %1 (bought) Financial security (e.g. stock, mutual fund) Wertpapier: %1 (gekauft) SecuritySell Security: %1 (sold) Wertpapier: %1 (verkauft) Security: %1 (sold) Financial security (e.g. stock, mutual fund) Wertpapier: %1 (verkauft) SecurityTransactionsDialog Transactions for %1 Transaktionen für %1 Date Datum Type Typ Value Wert Shares Financial shares Anteile Shares Bought Financial shares Anteile gekauft Shares Bought (Recurring) Financial shares Anteile gekauft (wiederkehrend) Dividend (Recurring) Dividende (wiederkehrend) Dividend (Scheduled) Dividende (geplant) Reinvested Dividend (Recurring) Reinvestierte Dividende (wiederkehrend) Reinvested Dividend (Scheduled) Reinvestierte Dividende (geplant) Shares Bought Fincancial shares Anteile gekauft Shares Sold Financial shares Anteile verkauft Shares Sold (Exchanged) Shares of one security directly exchanged for shares of another; Financial shares Anteile verkauft (gehandelt) Shares Bought (Exchanged) Shares of one security directly exchanged for shares of another; Financial shares Anteile gekauft (gehandelt) Shares Bought (Recurring) Fincancial shares Anteile gekauft (wiederkehrend) Shares Sold (Recurring) Financial shares Anteile verkauft (wiederkehrend) Shares Bought (Scheduled) Financial shares Anteile gekauft (geplant) Shares Sold (Scheduled) Financial shares Anteile verkauft (geplant) Shares Anteile Edit… Bearbeiten… Delete Löschen Shares Bought Anteile gekauft Shares Sold Anteile verkauft Dividend Dividende Reinvested Dividend Reinvestierte Dividende Shares Sold (Traded) Anteile verkauft (gehandelt) Shares Bought (Traded) Anteile gekauft (gehandelt) Shares Bought (Recurring) Anteile gekauft (wiederkehrend) Shares Sold (Recurring) Anteile verkauft (wiederkehrend) Shares Bought (Scheduled) Anteile gekauft (geplant) Shares Sold (Scheduled) Anteile verkauft (geplant) Recurring Dividend Wiederkehrende Dividende Scheduled Dividend Geplante Dividende SplitListViewItem Dividend Dividende Income Einnahmen Repayment Rückzahlung Expense Ausgabe Refund Rückerstattung Security Buy Wertpapierkauf Security Sell Wertpapierverkauf Balancing Bilanzieren Transfer Überweisung TagButton no tags keine Etikette TagMenu New tag… Neues Etikett… New Tag Neues Etikett Tag: Etikett: TransactionEditDialog Edit Expense Ausgabe bearbeiten Edit Dividend Dividende bearbeiten Edit Income Einnahme bearbeiten Edit Transfer Überweisung bearbeiten Edit Securities Purchase Financial security (e.g. stock, mutual fund) Gekaufte Wertpapiere bearbeiten Edit Securities Sale Financial security (e.g. stock, mutual fund) Verkaufte Wertpapiere bearbeiten Edit Reinvested Dividend Reinvestierte Dividende bearbeiten Edit Securities Bought Gekaufte Wertpapiere bearbeiten Edit Securities Sold Verkaufte Wertpapiere bearbeiten TransactionEditWidget Security: Wertpapier: Cost: Kosten: Income: Einnahmen: Shares bought: Anteile gekauft: Shares sold: Anteile verkauft: All Alle Price per share: Preis pro Anteil: Date: Datum: Description: Beschreibung: Name: Name: Generic Description: Allgemeine Bezeichnung: Amount: Menge: Withdrawal: Money taken out from account Abhebung: New Security… Financial security (e.g. stock, mutual fund) Neues Wertpapier… Shares added: Financial shares Hinzugefügte Anteile: Set security share value Legen Sie den Wert der Wertpapieranteile fest Total value: Gesamtwert: Deposit: Money put into account Einlage: Downpayment: Anzahlung: Quantity: Menge: From: Von: To: Nach: Category: Kategorie: To account: Zum Konto: Payer: Zahlungspflichtiger: Payer of parent split transaction Zahlungspflichtiger der übergeordneten geteilten Transaktion From account: Vom Konto: Downpayment account: Anzahlungskonto: Payee: Zahlungsempfänger: Payee of parent split transaction Zahlungsempfänger der übergeordneten geteilten Transaktion Lender: Darlehensgeber: Tags: Etikette: Associated file: Zugehörige Datei: Select a file Datei auswählen Open the file Datei öffnen Comments: Kommentare: Related to: Label for linked transactions Links: New Security Financial security (e.g. stock, mutual fund) Neues Wertpapier No security available. Financial security (e.g. stock, mutual fund) Wertpapiere nicht verfügbar. New Tag Neues Etikett Tag: Etikett: New Account Neues Konto New Income Category Neue Einnahmenkategorie New Expense Category Neue Ausgabenkategorie New Account… Neues Konto… Security: Financial security (e.g. stock, mutual fund) Wertpapier: Shares bought: Financial shares Anteile gekauft: Shares sold: Financial shares Anteile verkauft: Price per share: Financial shares Preis pro Anteil: Description: Transaction description property (transaction title/generic article name) Beschreibung: Transaction title/generic article name Titel der Transaktion/Allgemeiner Artikelname Number of items included in the transaction. Entered cost is total cost for all items. Anzahl der in der Transaktion enthaltenen Artikel. Die eingegebenen Kosten sind Gesamtkosten für alle Artikel. Error Fehler No suitable account available. Kein geeignetes Konto verfügbar. No income category available. Keine Einkommenkategorie verfügbar. No suitable account or income category available. Kein passendes Konto oder Einkommenskategorie vorhanden. No expense category available. Keine Ausgabenkategorie verfügbar. No security available. Kein Wertpapier verfügbar. Invalid date. Ungültiges Datum. Cannot transfer money to and from the same account. Überweisung zum selben Konto kann nicht durchgeführt werden. Downpayment must be less than total cost. Die Anzahlung muss unter den Gesamtkosten liegen. Cannot create a regular transfer to/from a securities account. Normale Überweisungen von/zu einem Wertpapierkonto können nicht gebucht werden. Cannot create a regular income to a securities account. Normale Einnahmen können nicht zu einem Wertpapierkonto hinzugebucht werden. Zero shares not allowed. Anteile ohne Wert sind nicht erlaubt. Zero value not allowed. Null-Wert ist nicht erlaubt. Zero price per share not allowed. Anteile ohne Wert sind nicht erlaubt. Cannot create a regular expense from a securities account. Normale Ausgaben können nicht von einem Wertpapierkonto abgebucht werden. Loan for %1 Darlehen für %1 TransactionFilterWidget From: Von: To: Nach: Min amount: Mindestmenge: Max amount: Höchstmenge: Category: Kategorie: To account: Zum Konto: Min income: Mindesteinnahmen: Max income: Höchsteinnahmen: From account: Vom Konto: Min cost: Mindestkosten: Max cost: Höchstkosten: Tag: Etikett: Generic Description: Allgemeine Beschreibung: Description: Beschreibung: Description: Transaction description property (transaction title/generic article name) Beschreibung: Payer: Zahlungspflichtiger: Payee: Zahlungsempfänger: Include Inklusive Exclude Exklusive Exact match Genaue Übereinstimmung Exclude subcategories Ohne Unterkategorien Clear Alles löschen All Alle Error Fehler Invalid date. Ungültiges Datum. To date is before from date. "Bis"-Datum liegt vor dem "Von"-Datum. From date is after to date. "Von"-Datum liegt hinter dem "Bis"-Datum. TransactionListWidget Date Datum Description Beschreibung Cost Kosten Category Kategorie From Account Vom Konto Payee Zahlungsempfänger Tags Etikette Income Einnahmen To Account Zum Konto Payer Zahlungspflichtiger Amount Menge From Von To Nach Comments Kommentare Add Hinzufügen Apply Anwenden Delete Löschen * Part of <a href="%1">split transaction</a> * Teil einer < href="%1">geteilten Transaktion</a> Expense Ausgabe Transfer Überweisung New/Edit %1 %1 anlegen/bearbeiten Name Name Description Generic Description Beschreibung Description Transaction description property (transaction title/generic article name) Beschreibung New/Edit Expense Ausgabe anlegen/bearbeiten New/Edit Income Einnahme anlegen/bearbeiten New/Edit Transfer Überweisung anlegen/bearbeiten Filter Filter Quantity: Menge: Total: Gesamt: Average: Durchschnittlich: Clear Alles löschen Cost: Kosten: Monthly: Monatlich: Sort by creation time Nach Erstellungszeitpunkt sortieren Expenses Ausgaben Incomes Einnahmen Transfers Überweisungen Quantity Menge Right align Rechts ausrichten Total cost: Gesamtkosten: Total income: Gesamte Einnahmen: Total amount: Gesamtwert: Monthly average: Monatlicher Durchschnitt: Error Fehler Cannot set the value of security transactions using the dialog for modifying multiple transactions. Financial security (e.g. stock, mutual fund) Der Wert von Wertpapiertransaktionen kann nicht über den Dialog zum Ändern mehrerer Transaktionen geändert werden. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name); Financial security (e.g. stock, mutual fund) Die Beschreibung für Dividenden- und Wertpapiertransaktionen kann nicht geändert werden. Cannot change payer of dividends and security transactions. Financial security (e.g. stock, mutual fund) Der Zahlungspflichtige von Dividenden- und Wertpapiertransaktionen kann nicht verändert werden. Cannot change date of transactions that are part of a split transaction, unless all individual transactions are selected. Das Datum der Transaktionen, die Teil einer geteilten Transaktion sind, kann nicht geändert werden, es sei denn, alle einzelnen Transaktionen sind ausgewählt. Cannot set the value of security transactions using the dialog for modifying multiple transactions. Der Wert von Wertpapiertransaktionen kann nicht über den Dialog zum Ändern mehrerer Transaktionen geändert werden. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name) Die Beschreibung für Dividenden- und Wertpapiertransaktionen kann nicht geändert werden. Cannot change date, description, expense category or payee of transactions that are part of a debt payment using the dialog for modifying multiple transactions. Referring to the transaction description property (transaction title/generic article name) Datum, Beschreibung, Kostenkategorie oder Zahlungsempfänger von Transaktionen, die Teil einer Schuldzahlung sind, können nicht über das Dialogfeld zum Ändern mehrerer Transaktionen geändert werden. Cannot change description of dividends and security transactions. Referring to the Transaction description property (transaction title/generic article name) Die Beschreibung für Dividenden- und Wertpapiertransaktionen kann nicht geändert werden. Cannot change description of dividends and security transactions. Referring to the generic description property Die Beschreibung für Dividenden- und Wertpapiertransaktionen kann nicht geändert werden. Cannot change description of dividends and security transactions. Die Beschreibung für Dividenden- und Wertpapiertransaktionen kann nicht geändert werden. Cannot change payer of dividends and security transactions. Der Zahlungspflichtige von Dividenden und Wertpapiere kann nicht verändert werden. Cannot change date of transactions that are part of a split transaction. Das Datum einer Transaktion, die Teil einer geteilten Transaktion ist, kann nicht verändert werden. Delete transactions? Transaktionen löschen? Are you sure you want to delete all (%1) transactions in the selected split transaction? Sind Sie sicher, daß Sie alle (%1) ausgewählten geteilten Transaktionen löschen wollen? Join as multiple accounts/payments? Do you wish join the selected expenses as an expense with multiple accounts/payments? Do you wish join the selected incomes as an income with multiple accounts/payments? Are you sure you want to delete all (%1) selected transactions? Sind Sie sicher, daß Sie alle (%1) ausgewählten Transaktionen löschen wollen? * Part of split transaction * Teil einer geteilten Transaktion * Part of split (%1) * Teil (%1) ** Recurring (editing occurrence) ** Wiederkehrend (bearbeite Vorkommnisse) Modify… Verändern… Edit… Bearbeiten… Eqonomize-1.5.3/translations/eqonomize_es.ts000066400000000000000000020417501416454732000212730ustar00rootroot00000000000000 Balancing Balance kde-format Couldn't open %1 for reading No se pudo abrir %1 para la lectura kde-format Not a valid Eqonomize! file (XML parse error: "%2" at line %3, col %4) No es un archivo Eqonomize válido ! (Error de análisis XML: "%2" at line %3, col %4) kde-format Invalid root element %1 in XML document Elemento raiz inválido %1 en el documento XML kde-format Unable to load 1 account. Incapaz de cargar una cuenta. Incapaz de cargar %n cuentas. kde-format Unable to load %n accounts. Unable to load 1 category. Incapaz de cargar una categoría. Incapaz de cargar %n categorías. kde-format Unable to load %n categories. Unable to load 1 security. Incapaz de cargar 1 acción. Incapaz de cargar %n acciones. kde-format Unable to load %n securities. Unable to load 1 transaction. Incapaz de cargar 1 transacción. Incapaz de cargar %n transacciones. kde-format Unable to load %n transactions. File is a directory El archivo es un directorio kde-format Couldn't open file for writing No se pudo abrir fichero para escritura kde-format Error while writing file; file was not saved Error mientras se escribía en el archivo; el archivo no fue guardado kde-format From De kde-format To Para kde-format Source: Fuente: kde-format All Expenses Todos los Gastos kde-format All Incomes Todos los ingresos kde-format All Accounts Todas las cuentas kde-format Expenses: %1 Gastos: %1 kde-format Incomes: %1 Ingresos: %1 kde-format Invalid date. Fecha no válida. kde-format To date is before from date. La fecha final esta antes de la fecha de inicio kde-format From date is after to date. La fecha de inicio esta despues de la fecha final kde-format The selected file already exists. Would you like to overwrite the old copy? El archivo existe, ¿Quiere sobreescribirlo? kde-format You selected a directory! Usted selecciono un directorio. kde-format Couldn't open file for writing. No se pudo abrir el archivo para editarlo. kde-format Error while writing file; file was not saved. Error mientras se escribía en el archivo; el archivo no fue guardado. kde-format No description Sin descripción kde-format All Categories Todas las categorías kde-format Descriptions for Descripción para kde-format Payees/payers for Acreedores/deudores para kde-format Period: Periodo: kde-format Columns: Columnas: kde-format Value Valor kde-format Daily Diario kde-format Monthly Mensualmente kde-format Yearly Anualmente kde-format Quantity Cantidad kde-format Average value Valor promedio kde-format All descriptions Todas las descripciones kde-format All payees Todos los acreedores kde-format All payers Todos los deudores kde-format No payee Sin acreedor kde-format No payer Sin deudor kde-format Expenses: %2, %1 Gastos: %2, %1 kde-format Incomes: %2, %1 Ingresos: %2, %1 kde-format Incomes & Expenses Ingresos & Gastos kde-format %1 (%2&ndash;%3) html format; %1: title; %2: from date; %3: to date %1 (%2&ndash;%3) kde-format %1 (to %2) html format; %1: title; %2: to date %1 (a %2) kde-format Category Categoria kde-format Cost Gasto kde-format Income Ingreso kde-format Daily Average Promedio Diario kde-format Monthly Average Promedio Mensual kde-format Yearly Average Promedio Anual kde-format Average Cost Gasto Promedio kde-format Average Income Ingreso Promedio kde-format Average Value Valor Promedio kde-format Total Total kde-format Total incomes Ingreso Total kde-format Total expenses Gasto Total kde-format Total (Profits) Total (Ganancias) kde-format Expense Gastos kde-format Transfer Transferencias kde-format Security Buy Compra Segura kde-format Security Sell Venta segura kde-format Recurrence Repetición kde-format New Expense Nuevo Gasto kde-format New Dividend Nuevo Dividendo kde-format New Income Nuevo Ingreso kde-format New Transfer Nueva Transferencia kde-format New Security Buy Nueva Compra Segura kde-format New Security Sell Nueva Venta Segura kde-format Edit Expense Editar Gastos kde-format Edit Dividend Editar Divididendos kde-format Edit Income Editar Ingresos kde-format Edit Transfer Editar Transferencias kde-format Edit Securities Bought Editar kde-format Edit Securities Sold Editar Acciones Vendidas kde-format Dividend Dividendo kde-format Repayment Refinanciamiento kde-format Refund Reembolso kde-format Split Transaction Dividir Transacciones kde-format Description: Descripción kde-format Date: Fecha: kde-format Account: Cuenta: kde-format Transactions: Transacción kde-format Type Tipo kde-format Description Descripción kde-format Account/Category Cuenta/Categoría kde-format Payment Pago kde-format Deposit Depósito kde-format New Nuevo kde-format New Expense… Nuevo Gasto… kde-format New Income… Nuevo Ingreso… kde-format New Deposit… Nuevo Deposito… kde-format New Withdrawal… Nuevo Retiro… kde-format Security Shares Sold… Acciones de Seguridad Vendidas.. kde-format New Dividend… Nuevo Dividendo… kde-format Edit… Editar… kde-format Total value: Valor total: kde-format No suitable account available. No se encuentra una cuenta adecuada disponible. kde-format Future dates is not allowed. Fechas posteriores no son permitidas. kde-format A split must contain at least two transactions. Una división debe al menos contener dos transacciones. kde-format Cannot transfer money to and from the same account. No se puede transferir dinero de y hacia la misma cuenta. kde-format Cost: Gasto: kde-format Income: Ingreso: kde-format Quantity: Cantidad: kde-format Comments: Comentarios: kde-format Reinvested Dividend Dividendos Reinvertidos kde-format Security: Seguridad: kde-format Shares added: Unidades añadidas: kde-format Security Trade Transacción de Acciones kde-format From security: De la acción: kde-format Shares moved: Unidades movidas: kde-format All Todo kde-format To security: Para la acción: kde-format Shares received: Dividendos recibidos: kde-format Value: Valor kde-format No other security available for trade in the account. No hay otra acción disponible para comerciar en esta cuenta. kde-format Selected to and from securities are the same. El origen y el destino de las acciones es el mismo. kde-format Zero shares not allowed. Cero unidades no está permitido kde-format Zero value not allowed. Valor Cero no esta permitido kde-format Quotations Cita kde-format Date Fecha kde-format Price per Share Precio por unidad kde-format Quotations for %1 Citas para %1 kde-format The following transactions was scheduled to occur today or before today. Confirm that they have indeed occurred (or will occur today). La siguiente transacción fue planificada para ocurrir el día de hoy o después. Confirme que esta efectivamente ocurrió, (o lo hará el día de hoy). kde-format Amount Monto kde-format Postpone… Postponer… kde-format Can only postpone to future dates. Solo puede posponer a fechas posteriores. kde-format Transactions for %1 Transacciones para %1 kde-format Shares Unidades kde-format Shares Bought Unidades Compradas kde-format Shares Sold Unidades Vendidas kde-format Shares Sold (Traded) Unidades Vendidas (Transacción) kde-format Shares Bought (Traded) Unidades Compradas (Transacción) kde-format Shares Bought (Recurring) Acciones Compradas (Recurrentes) kde-format Shares Sold (Recurring) Acciones Vendidas (Recurrentes) kde-format Shares Bought (Scheduled) Acciones Compradas (Programada) kde-format Shares Sold (Scheduled) Acciones Vendidas (Programado) kde-format Recurring Dividend Dividendos Recurrentes kde-format Scheduled Dividend Dividendos Programados kde-format Type: Tipo: kde-format Mutual Fund Fondos Mutuos kde-format Bond Enlace kde-format Stock Stock kde-format Other Otro kde-format Name: Nombre: kde-format Decimals in Shares: Cuantos decimales utiliza kde-format Initial Shares: Unidades Iniciales kde-format Initial quotation: Citas Iniciales kde-format No suitable account or income category available. No se encuentra una cuenta o una categoría de renta adecuada disponible kde-format Cash Efectivo kde-format Current Account Cuenta actual kde-format Savings Account Cuenta de Ahorros kde-format Credit Card Tarjeta de Cŕedito kde-format Liabilities Pasivos kde-format Securities Acciones kde-format Initial balance: Balance inicial kde-format Default account for budgeted transactions Cuenta predeterminada para las transacciones presupuestadas kde-format Empty name. Nombre vació kde-format The entered name is used by another account. El nombre que ingreso esta siendo utilizado por otra cuenta. kde-format Monthly budget: Presupuesto Mensual kde-format The entered name is used by another income category. El nombre elegido ya está siendo usado en otra categoría de ingresos. kde-format The entered name is used by another expense category. El nombre elegido ya está siendo usado en otra categoría de gastos. kde-format Accounts Cuentas kde-format Accounts & Categories Cuentas & Categorías kde-format Expenses Gastos kde-format Incomes Ingresos kde-format Transfers Transferencias kde-format Schedule Calendario kde-format Scheduled Transactions Transacciones programadas kde-format Account / Category Cuenta / Categoría kde-format Remaining Budget (%1) Presupuesto Restante (%1) kde-format Change (%1) Cambio (%1) kde-format Total (%1) Total (%1) kde-format %2 of %1 %2 remains of %1 budget %2 de %1 kde-format Includes budgeted transactions Incluye transacciones presupuestadas kde-format Period Periodo kde-format Select Period Elija un Periodo kde-format Current Month Mes Actual kde-format Current Year Año Actual kde-format Current Whole Month Todo el mes actual kde-format Current Whole Year Todo el presente año kde-format Whole Past Month Todo el mes pasado kde-format Whole Past Year Todo el año pasado kde-format Previous Month Mes anterior kde-format Previous Year Año anterior kde-format Show partial budget Mostrar el presupuesto parcial kde-format Edit Budget Editar Presupuesto kde-format Budget: Presupuesto: kde-format Month: Mes: kde-format Result previous month: Resultado del mes anterior: kde-format New Security… Nueva Acción… kde-format New Transaction Nueva Transacción kde-format Set Quotation… Escribir Cita kde-format Name Nombre kde-format Quotation Cita kde-format Profit Beneficio kde-format Yearly Rate Índice Anual kde-format Account Cuenta kde-format Statistics Period Estadísticas del Periodo kde-format New Schedule Nuevo Calendario kde-format Edit Editar kde-format Next Occurrence Siguiente Ocurrencia kde-format Comments Comentarios kde-format New Security Nueva Acción kde-format Edit Security Editar Acción kde-format Profit: Ganancia: kde-format Rate: Tasa: kde-format Are you sure you want to delete the security "%1" and all associated transactions? ¿Está seguro de que quiere eliminar la acción «%1» y todas las transacciones asociadas? kde-format No security available. Seguridad no Disponible kde-format Set Quotation (%1) Establecer presupuesto (%1) kde-format Price per share: Precio por Unidad: kde-format Future dates are not allowed. Fechas posteriores no están permitidas. kde-format Security Transactions Transacciones Seguras kde-format Ledger Libro de Compras kde-format Untitled Sin título kde-format Check Account Comprobar Cuenta kde-format Salary Salario kde-format Bills Cuentas kde-format Clothing Ropa kde-format Groceries Comestibles kde-format Leisure Ocio kde-format Couldn't fetch %1. No se puedo obtener %1 kde-format Error loading %1: %2. Error al cargar %1: %2. kde-format Couldn't open file No se pudo abrir el archivo kde-format Error saving %1: %2. Error grabando %1: %2. kde-format Couldn't save file No se pudo grabar el archivo kde-format Failed to upload file to %1. Fallo al cargar el archivo %1. kde-format Report Reporte kde-format Chart Gráfico kde-format Transaction Schedule Transacción Programada kde-format Accounts &amp; Categories html format Cuentas &amp; Categorías kde-format Accounts &amp; Categories (%1&ndash;%2) html format Cuentas &amp; Categorías (%1&ndash;%2) kde-format Accounts &amp; Categories (to %1) html format Cuentas y categorías (a %1) kde-format Change Cambio kde-format Balance Balance kde-format Budget Presupuesto kde-format Remaining Budget Presupuesto Restante kde-format Total Incomes Ingresos Totales kde-format Costs Costos kde-format Total Expenses Gastos Totales kde-format Empty expenses list. Lista de gastos vacía. kde-format Empty incomes list. Lista de Ingresos vacia. kde-format Empty transfers list. Lista de transferencias vacia. kde-format Empty securities list. Lista de acciones vacia. kde-format Empty schedule list. Lista de programación vacía. kde-format Export View… Exportar Vista… kde-format Print View… Vista de Impresión kde-format Initial Period Periodo Inicial kde-format Remember Last Dates Recordar últimas fechas kde-format Import CSV File… Importar Archivo CSV… kde-format Import QIF File… Importar Archivo QIF… kde-format Export As QIF File… Exportar como Archivo QIF… kde-format Add Account… Añádir Cuenta… kde-format New Account… Nueva Cuenta… kde-format New Income Category… Nueva Categoría de Ingresos… kde-format New Expense Category… Nueva Categoría de Gastos… kde-format Balance… Balance… kde-format Show Transactions Mostrar Transacciones kde-format New Transfer… Nueva Transacción… kde-format New Split Transaction… Nueva Transacción dividida kde-format Edit Transaction(s) (Occurrence)… Editar Transacción(es) (Frecuencia)… kde-format Edit Occurrence… Editar Ocurrencia… kde-format Edit Schedule (Recurrence)… Editar Programación (Repetición)… kde-format Edit Schedule… Editar Calendario… kde-format Remove Transaction(s) (Occurrence) Remover Las trasacciones programadas kde-format Remove Occurrence Remover Ocurrencia kde-format Delete Schedule (Recurrence) Borrar Programación (Recurrente) kde-format Delete Schedule Eliminar Calendario kde-format Edit Split Transaction… Editar Transacción Dividida… kde-format Remove Split Transaction Eliminar Transacción Dividida kde-format Join Transactions… Unir Transacciones… kde-format Split Up Transaction Dividir Transacción kde-format Refund… Resembolso… kde-format Repayment… Repago kde-format New Refund/Repayment… Reintegro/Repago kde-format Shares Sold… Acciones Vendidas… kde-format Shares Bought… Acciones Compradas… kde-format Dividend… Dividendos… kde-format Reinvested Dividend… Dividendos reinvertidos… kde-format Shares Moved… Unidades movidas… kde-format Edit Quotations… Editar Citas… kde-format Transactions… Transacciones… kde-format Development Over Time Report… Reporte Detallado por Tiempo kde-format Categories Comparison Report… Reporte Comparativo de Categorías… kde-format Categories Comparison Chart… Tabla comparativa de categorías… kde-format Development Over Time Chart… Tabla Detallada por Tiempo kde-format Use Additional Transaction Properties Use Propiedades Adicionales de las Trensacciones kde-format Eqonomize! exited unexpectedly before the file was saved and data was lost. Do you want to load the last auto-saved version of the file? Eqonomize terminó de forma inesperada antes de que el archivo fuera guardado. Los datos se han perdido. ¿Quiere cargar la última versión del archivo auto-guardado? kde-format Crash Recovery Recuperación del cuelgue kde-format The current file has been modified. Do you want to save it? El Archivo actual ha sido modificado. ¿Desea guardar los cambios? kde-format Confirm Schedule Confirmar la Programación kde-format New Account Nueva Cuenta kde-format New Income Category Nueva Categoría de Ingresos kde-format New Expense Category Nueva Categoría de Gastos kde-format Balance Account Balance de Cuenta kde-format Book value: Valor del libro: kde-format Real value: Valor Real: kde-format Edit Account Editar Cuenta kde-format Edit Income Category Editar Categoría de Ingresos kde-format Edit Expense Category Editar Categoría de Gastos kde-format Move transactions? ¿Mover transacción? kde-format Move to: Mover a: kde-format The category contains some expenses. What do you want to do with them? La categoría contiene algunos gastos. ¿Qué desea hacer con ellos? kde-format The category contains some incomes. What do you want to do with them? La categoría contiene algunos ingresos. ¿Qué desea hacer con ellos? kde-format The account contains some transactions. What do you want to do with them? La categoría contiene algunas transacciones. ¿Qué desea hacer con ellas? kde-format The category contains some expenses that will be removed. Do you still want to remove the category? La Categoría contiene algunos gastos que serán eliminados. ¿Desea eliminarla? kde-format Remove Category? ¿Eliminar Categoría? kde-format The category contains some incomes that will be removed. Do you still want to remove the category? La Categoría contiene algunos ingresos que serán eliminados. ¿Desea eliminarla? kde-format The account contains some transactions that will be removed. Do you still want to remove the account? La cuenta contiene algunas transacciones que serán eliminadas. ¿Desea eliminarla? kde-format Remove Account? ¿Eliminar Cuenta? kde-format %2 of %1 %1: budget; %2: remaining budget %2 de %1 kde-format %1 (with no budget) %1 (sin presupuesto) kde-format %1 (with budget %2) %1 (con presupuesto %2) kde-format Import CSV file Importar archivo CVS kde-format Transaction Type Selection Selecciona el Tipo de Transacción kde-format Expenses and incomes (negative cost) Gastos e ingresos (Gastos negativos) kde-format Expenses and incomes (separate columns) Gastos e ingresos (Columnas separadas) kde-format All types Todos los tipos kde-format File Selection Selección de archivo kde-format File: Archivo kde-format First data row: Primera fila de datos: kde-format Auto Automático kde-format Column delimiter: Delimitador de Columna: kde-format Comma Coma kde-format Tabulator Tabulador kde-format Semicolon Punto y coma kde-format Space Espacio kde-format Columns Specification Espicificación de Columnas kde-format Column Columna kde-format Category: Categoría: kde-format From account: Desde la cuenta: kde-format Create missing categories and accounts Cree las categorías y las cuentas que faltan kde-format Imports data as incomes. Value is the only required column. Importar datos como ingresos. El valor es la única columna requerida. kde-format To account: Para la cuenta: kde-format Imports data as transfers. Value is the only required column. Importar datos como trasacciones. El valor es la única columna requerida. kde-format Amount: Cuenta: kde-format Imports data as expenses and incomes. Costs have negative value. Value and category are both required columns. Importar datos como gastos e ingresos. Los gastos tienen valor negativo. El valor y la categoría son las columnas requeridas. kde-format Imports data as expenses and incomes. Costs and incomes have separate columns. Income, cost, and category are all required columns. Importar datos como gastos e ingresos. Gastos e ingresos estan en columnas separadas. Ingresos, gastos y categoría son columnas requeridas. kde-format Imports data as expenses, incomes, and transfers. Costs have negative or positive value. Value, to, and from are all required columns. Accounts and categories must be existing. Importar datos como gastos, ingresos y transacciones. Gastos tiene valor positivo o negativo. El valor, el destino y el origen son las columnas requeridas. kde-format From: De: kde-format To: Para: kde-format A file must be selected. Un archivo debe ser seleccionado kde-format Selected file is a directory. El archivo seleccionado es un directorio. kde-format Selected file does not exist. El archivo seleccionado no existe. kde-format Empty delimiter. Delimitador vacio. kde-format The same column number is selected multiple times. El mismo número de columna ha sido seleccionado varias veces. kde-format Selected from account is the same as the to account. La cuenta seleccionada desde es la misma que la en. kde-format Couldn't open %1 for reading. No se pudo abrir %1 para lectura. kde-format Error reading %1. Ocurrió un error cuando se leía %1. kde-format Successfully imported 1 transaction. Importada 1 transacción satisfactoriamente. Importada %n transacciónes satisfactoriamente. kde-format Successfully imported %n transactions. Unable to import any transactions imported. No se pudo importar ninguna transacción. kde-format Failed to import 1 data row. Fallo al importar 1 fila de datos. Fallo al importar %n filas de datos. kde-format Failed to import %n data rows. Required columns missing. No se encuentra una columna requerida kde-format Invalid value. Valor no válido. kde-format Empty category name. Nombre de categoría vacío kde-format Empty account name. Nombre de cuenta vacío kde-format Unknown category found. Categoría desconocida kde-format Unknown account found. Cuenta desconocida kde-format Cannot import security transactions (to/from security accounts). No se pudo importar las transacciones de seguridad (desde/a cuentas seguras). kde-format Balancing account wrongly used. Cuenta de Balance mal utilizada kde-format Same to and from account/category. El origen y el destino de la cuenta/categoría es el mismo. kde-format No data found. No se encontraron datos. kde-format Unrecognized date format. Formato de fecha desconocido. kde-format Specify Format Formato específico kde-format The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. El formato de las fechas y/o números en el archivo CVS es ambiguo. Por favor selecciona un formato correcto. kde-format Date format: Formato de fecha: kde-format Value format: Formato de Valor kde-format tomorrow the day after today mañana kde-format today this day hoy kde-format yesterday the day before today ayer kde-format &Today @option today &Hoy kde-format To&morrow @option tomorrow Ma&ñana kde-format Next &Week @option next week Próxima &Semana kde-format Next M&onth @option next month Próximo M&es kde-format No Date @option do not specify a date Sin Fecha kde-format Export… Exportar… kde-format Print… Imprimir… kde-format Withdrawal Retirada kde-format Join… Unir… kde-format Split Up Separar kde-format Empty transaction list. Lista de la transacción vacia kde-format Are you sure you want to delete all (%1) selected transactions? ¿Esta seguro de que quiere eliminar todas (%1) las transacciones seleccionadas? kde-format Eqonomize! Eqonomize! A personal accounting program Un programa de contabilidad personal Start with expenses list displayed Comenzar con la lista de los gastos mostrada Start with incomes list displayed Comenzar con la lista de los ingresos mostrada Start with transfers list displayed Comenzar con la lista de las transferencias mostrada Document to open Abrir documento: Incomes and Expenses Ingresos y Gastos kde-format Profits Beneficios kde-format All Categories Combined Todas las Categorías combinadas kde-format All Descriptions Combined Todas las Descripciones combinadas kde-format All Payees/Payers Combined Todos los Acreedores/Deudores Combinados kde-format Start date: Fecha de inicio: kde-format End date: Fecha de finalización: kde-format Monthly total Total Mensual kde-format Daily average Media diaria kde-format All Payers Combined Todos los Deudores Combinados kde-format All Payees Combined Todos los Acreedores Combinados kde-format All Descriptions Split Todas las descripciones separadas kde-format All Payers Split Todos los deudores separados kde-format All Payees Split Todos los acreedores separados kde-format All Categories Split Todas las categorías separadas kde-format Value (%1) Valor (%1) kde-format Profit (%1) Beneficios (%1) kde-format Income (%1) Ingresos (%1) kde-format Cost (%1) Gastos (%1) kde-format Time Tiempo kde-format no payer no deudor kde-format %1/%2 %1: Description; %2: Payer %1/%2 kde-format no payee no acreedor kde-format %1/%2 %1: Description; %2: Payee %1/%2 kde-format Error after saving file; data may not have been saved. Error después de guardar el archivo; los datos pueden no haber sido guardados. kde-format Average Profit Promedio de Beneficios kde-format Year Año kde-format Month Mes kde-format Includes scheduled transactions Incluir las transacciones progamadas kde-format Adjusted for the average month / year (%1 / %2 days) Ajustado para el mes / año promedio (%1 / %2 días) kde-format Subtotal Subtotal kde-format Unnamed Sin Nombre kde-format Uncategorized Sin Categoría kde-format Import QIF file Importar Archivo QIF kde-format Select a QIF file to import. When you click next, the file be analysed and you might need to answer some questions about the format of the file. Seleccione un archivo QIF para importar. Cuando usted haga click en "Next", se analizará el archivo y es posible que tenga que responder a algunas preguntas sobre el formato del archivo. kde-format Local Definitions Definiciones Locales kde-format Local Text Texto Local kde-format Standard Text Texto estándar kde-format Select standard text: Seleccionar texto estándar: kde-format Date Format Formato de Fecha kde-format The date format in the QIF file is ambiguous. Please select the correct format. El formato de la fecha del archivo QIF es ambiguo. Por favor, elige un formato correcto. kde-format Default Account Cuenta por Defecto kde-format Could not find any account definitions in the QIF file. Please select a default account. It is also possible that this is caused by a localized opening balance text. No se pudo encontrar ninguna definicion de cuentas en el archivo QIF. Por favor, seleccione una cuenta por defecto. Es posible que esto sea causado por utilizar una localizacion del texto del balance. kde-format Default account: Cuenta por Defecto: kde-format Descriptions Descripciones kde-format Subcategories as: Subcategorías como: kde-format Ignore Omitir kde-format Payee as: Acreedor como: kde-format Payee Acreedor kde-format Priority: Prioridad: kde-format Subcategory/Payee/Comments Subcategoría/Acreedor/comentarios kde-format Payee/Subcategory/Comments Acreedor/Subcategoría/Comentarios kde-format Subcategory/Comments/Payee Subcategoría/Comentarios/Acreedor kde-format Payee/Comments/Subcategory Acreedor/Comentarios/Subcategoría kde-format Comments/Subcategory/Payee Comentarios/Subcategoría/Acreedor kde-format Comments/Payee/Subcategory Comentarios/Acreedor/Subcategoría kde-format Unknown Desconocido kde-format Bank Banco kde-format Cat (Category) Cat (Categoría) kde-format CCard (Credit Card) CCard (Tarjeta de Crédito) kde-format Invst (Investment) Invst (Inversión) kde-format Oth A (Other Assets) Oth A (Otros Activos) kde-format Oth L (Other Liabilities) Oth L (Otras Responsabilidades) kde-format Security Seguridad kde-format Successfully imported 1 account. Importada 1 cuenta satisfactoriamente Importadas %n cuentas satisfactoriamente kde-format Successfully imported %n accounts. Successfully imported 1 category. Importada 1 categoría satisfactoriamente. Importadas %n categorías satisfactoriamente. kde-format Successfully imported %n categories. 1 duplicate transaction was ignored. 1 transacción duplicada ha sido ignorada. %n transacciones duplicadas han sido ignoradas. kde-format %n duplicate transactions was ignored. Failed to import 1 transaction. Fallo al importar 1 transacción. Fallo al importar %n transacciones. kde-format Failed to import %n transactions. Export QIF File Exportar archivo QIF kde-format All All accounts Todo kde-format Export transaction description as: Exportar la descripción de la transacción como: kde-format Memo Nota kde-format Subcategory Subcategoría kde-format &Import i18n: tag text i18n: file ./eqonomizeui.rc line 5 &Importar kde-format &Accounts i18n: tag text i18n: file ./eqonomizeui.rc line 12 &Cuentas kde-format &Transactions i18n: tag text i18n: file ./eqonomizeui.rc line 24 &Transacciones kde-format Stat&istics i18n: tag text i18n: file ./eqonomizeui.rc line 56 Estad&ísticas kde-format Your names NAME OF TRANSLATORS ,Launchpad Contributions:,Alejandro Mas Chiotakis,Dagor Olwe,Ernesto Ramirez G,Mario César Señoranis,MiltonInostrozaAguilera,Paco Molinero,Steven De Winter,eternal1,Ángel Eduardo, ,Launchpad Contributions:,Adolfo Jayme,Alejandro Mas Chiotakis,AlexMorphine,Dagor Olwe,Eduardo Alberto Calvo,Ernesto Ramirez G,Feder Sáiz,Fido,Hanna K.,J,Mario César Señoranis,MiltonInostrozaAguilera,Paco Molinero,Sergio Cuellar Valdes,Steven De Winter,eternal1,simon,Ángel Eduardo kde-format Your emails EMAIL OF TRANSLATORS ,,alejandro.maschiotakis@gmail.com,soron.registro@gmail.com,,mariocesar.c50@gmail.com,minoztro@gmail.com,paco@byasl.com,,,arcnor@arcnor.com,,,fitoschido@gmail.com,alejandro.maschiotakis@gmail.com,,soron.registro@gmail.com,,,,,,,mariocesar.c50@gmail.com,minoztro@gmail.com,paco@byasl.com,herrsergio@gmail.com,,,,arcnor@arcnor.com kde-format Edit Exceptions Editar Excepciones kde-format Edit Recurrence Range Editar Rango de Repetición kde-format Begins on: %1 Inicia en: %1 kde-format No ending date Sin fecha de finalización kde-format End after Termina después kde-format occurrence(s) ocurrencia(s) kde-format End on Termina en kde-format End date before start date. La fecha de finalización es anterior a la fecha de inicio kde-format Enable recurrence Repetición permitida kde-format Recurrence Rule Regla de repetición kde-format Weekly Semanalmente kde-format Recur every Repetir cada kde-format day(s) día(s) kde-format week(s) on: semana(s) en: kde-format month(s), after the start month mes(es), después del mes de comienzo kde-format Recur on the Repetir el kde-format 1st kde-format 2nd kde-format 3rd kde-format 4th kde-format 5th kde-format 6th kde-format 7th kde-format 8th kde-format 9th kde-format 10th 10º kde-format 11th 11º kde-format 12th 12º kde-format 13th 13º kde-format 14th 14º kde-format 15th 15º kde-format 16th 16º kde-format 17th 17º kde-format 18th 18º kde-format 19th 19º kde-format 20th 20º kde-format 21st 21 kde-format 22nd 22º kde-format 23rd 23º kde-format 24th 24º kde-format 25th 25º kde-format 26th 26º kde-format 27th 27º kde-format 28th 28º kde-format 29th 29º kde-format 30th 30º kde-format 31st 31º kde-format Last Último kde-format 2nd Last Penúltimo kde-format 3rd Last Antepenúltimo kde-format 4th Last 4 Último kde-format 5th Last 5 Último kde-format day día kde-format possibly on weekend posiblemente en el fin de semana kde-format but after weekend pero después del fin de semana kde-format Recur on day part before XXX of 'Recur on day XXX of month YYY' Repetir el día kde-format of part between XXX and YYY of 'Recur on day XXX of month YYY' de kde-format On the Part before NNN in 'Recur on the NNN. WEEKDAY of MONTH' En el/la kde-format of part between WEEKDAY and MONTH in 'Recur on NNN. WEEKDAY of MONTH' de kde-format of the year part after NNN of 'Recur on day #NNN of the year' del año kde-format Range… Rango… kde-format Exceptions… Excepciones… kde-format No day of week selected for weekly recurrence. Ningún día de la semana seleccionado para la repetición semanal kde-format Selected day does not exist in selected month. Este día no existe en el mes seleccionado kde-format Dividend: %1 Dividendo %1 kde-format Security: %1 (bought) Seguridad: %1 (comprado) kde-format Security: %1 (sold) Seguridad: %1 (vendido) kde-format Payer: Deudor: kde-format Payee: Acreedor: kde-format No expense category available. Ninguna categoría de gastos disponible kde-format Modify Transactions Modificar transacciones kde-format Min amount: Cantidad mínima kde-format Max amount: Cantidad máxima kde-format Min income: Ingresos mínimos kde-format Max income: Ingresos máximos kde-format Min cost: Coste mínimo kde-format Max cost: Coste máximo kde-format Include Incluir kde-format Exclude Excluir kde-format To Account A la cuenta kde-format Payer Deudor kde-format New/Edit Expense Nuevo/Editar Gasto kde-format Filter Filtro kde-format Total: Total: kde-format Average: Promedio: kde-format Monthly: Mensual kde-format Total cost: Costo Total: kde-format Total income: Ingreso Total kde-format Total amount: Monto total kde-format Monthly average: Promedio Mensual kde-format Are you sure you want to delete all (%1) transactions in the selected split transaction? ¿Está seguro de que desea eliminar todas (%1) las transacciones pertenecientes a la transacción dividida? kde-format * Part of split transaction * Parte de la transacción dividida kde-format * Part of split (%1) * Parte (%1) del corte kde-format Modify… Modificar… kde-format AccountComboBox New account… Nueva cuenta… Multiple accounts/payments… New income category… Nueva categoría de ingresos… New expense category… Nueva categoría de gastos… Paid with loan… New Account Nueva cuenta New Income Category Nueva categoría de ingresos New Expense Category Nueva categoría de gastos AccountsMenu All Accounts Todas las cuentas All Categories Combined Todas las categorías combinadas %n accounts %n cuenta %n cuentas %n categories %n categoría %n categorías Balancing Account balancing Balancing of an account Balanceo de cuenta Account Balance Adjustment Ajuste del saldo de la cuenta Budget Balancing Balance Balancing Name of account for transactions that adjust account balances Balanceo Couldn't open %1 for reading No se pudo abrir %1 para la lectura Not a valid Eqonomize! file (XML parse error: "%1" at line %2, col %3) No es un archivo Eqonomize válido ! (Error de análisis XML: "%1" at line %2, col %3) Invalid root element %1 in XML document Elemento raiz inválido %1 en el documento XML Unknown XML element: "%1" at line %2, col %3 XML parse error: "%1" at line %2, col %3 European Euro Unable to load %n currency/currencies. No exchange rates found. USD currency missing. imported Unable to load %n account(s). Incapaz de cargar %n cuenta. Incapaz de cargar %n cuentas. Unable to load %n category/categories. Incapaz de cargar %n categoría. Incapaz de cargar %n categorías. Unable to load %n security/securities. Financial security (e.g. stock, mutual fund) Incapaz de cargar %n título. Incapaz de cargar %n títulos. Download command (%1) failed: %2. Failed to download file from %1: %2. Upload command (%1) failed: %2. yyyy-yy Financial year when first month is not January (e.g. 2018-19). Transaction Accounts Cuentas corrientes Savings Accounts Cuentas de ahorro Credit Cards Tarjetas de cŕedito Debts Deudas Securities Financial security (e.g. stock, mutual fund) Títulos financiero Cash Efectivo Transaction Account Cuenta corriente Savings Account Cuenta de ahorros Credit Card Tarjeta de cŕedito Debt Dueda Other Otro Unable to load %n security/securities. Incapaz de cargar 1 acción. Unable to load %n transaction(s). Incapaz de cargar %n transacción. Incapaz de cargar %n transacciones. File is a directory El archivo es un directorio Couldn't open file for writing No se pudo abrir fichero para escritura Error while writing file; file was not saved Error mientras se escribía en el archivo; el archivo no fue guardado Unnamed Sin Nombre Uncategorized Sin Categoría CategoriesComparisonChart Save As… Guardar como… Print… Imprimir… From De To Para Source: Fuente: All Expenses Todos los Gastos All Incomes Todos los ingresos Theme: Chart type: Pie Chart Bar Chart Default Defecto All Expenses, without subcategories Todos los gastos, sin subcategorías All Expenses, with subcategories Todos los gastos, con subcategorías All Incomes, without subcategories Todos los ingresos, sin subcategorías All Incomes, with subcategories Todos los ingresos, con subcategorías All Accounts Todas las cuentas Expenses: %1 Gastos: %1 Incomes: %1 Ingresos: %1 Error Invalid date. Fecha no válida. To date is before from date. La fecha final esta antes de la fecha de inicio. From date is after to date. La fecha de inicio esta despues de la fecha final. Couldn't open file for writing. No se pudo abrir el archivo para editarlo. Error while writing file; file was not saved. Error mientras se escribía en el archivo; el archivo no fue guardado. Expenses Gastos Expenses, %1 Gastos, %1 Incomes, %1 Ingresos, %1 Incomes Ingresos Accounts Cuentas Expenses, %2: %1 Gastos, %2: %1 Incomes, %2: %1 Ingresos, %2: %1 Other descriptions Referring to the transaction description property (transaction title/generic article name) Otras descripciones No description Referring to the transaction description property (transaction title/generic article name) Sin descripción Other accounts Otras cuentas Other categories Otras categorías %1 Value: %2 %1 Valor: %2 No description Referring to the Transaction description property (transaction title/generic article name) Sin descripción No description Referring to the generic description property Sin descripción Value Valor Income Ingreso Cost Gasto Value (%1) Valor (%1) Income (%1) Ingresos (%1) Cost (%1) Gastos (%1) No description Sin descripción CategoriesComparisonChartDialog Chart Gráfico CategoriesComparisonReport Save As… Guardar como… Print… Imprimir… Source: Fuente: All Categories, excluding subcategories Todas las categorías, sin subcategorías All Categories, including subcategories Todas las categorías, con subcategorías All Payees/Payers Todos los acreedores/deudores Subcategories Subcategorías Descriptions for Referring to the Transaction description property (transaction title/generic article name) Descripción para All descriptions Referring to the Transaction description property (transaction title/generic article name) Todas las descripciones No description Referring to the Transaction description property (transaction title/generic article name) Sin descripción All Categories Todas las categorías Expenses: %1 Gastos: %1 Incomes: %1 Ingresos: %1 Descriptions for Descripción para Payees/payers for Acreedores/deudores para Descriptions Referring to the Transaction description property (transaction title/generic article name) Descripciones Period: Periodo: From De To Para Columns: Columnas: Value Valor Daily Diario Monthly Mensualmente Yearly Anualmente Quantity Cantidad Average value Valor promedio All descriptions Todas las descripciones All payees Todos los acreedores All payers Todos los deudores No description Sin descripción Descriptions for Referring to the generic description property Descripción para Descriptions Referring to the generic description property Descripciones All descriptions Referring to the generic description property Todas las descripciones No description Referring to the generic description property Sin descripción All Payees and Payers Todos los acreedores y deudores Tag: %1 Etiqueta: %1 All Accounts Todas las cuentas Descriptions for Referring to the transaction description property (transaction title/generic article name) Descripciones para Descriptions Referring to the transaction description property (transaction title/generic article name) Descripciones Months Meses Years Años Tags Etiquetas Total: Total: All descriptions Referring to the transaction description property (transaction title/generic article name) Todas las descripciones All payees/payers Todos los acreedores/deudores No description Referring to the transaction description property (transaction title/generic article name) Sin descripción No payee Sin acreedor No payer Sin deudor Error Invalid date. Fecha no válida. To date is before from date. La fecha final esta antes de la fecha de inicio. From date is after to date. La fecha de inicio esta despues de la fecha final. Couldn't open file for writing. No se pudo abrir el archivo para editarlo. Error while writing file; file was not saved. Error mientras se escribía en el archivo; el archivo no fue guardado. Expenses, %2: %1 Gastos, %2: %1 Expenses, %3: %2, %1 Gastos, %3: %2, %1 Incomes, %2: %1 Ingresos, %2: %1 Incomes, %3: %2, %1 Ingresos, %3: %2, %1 %3: %2, %1 %3: %2, %1 %2: %1 %2: %1 Tags, %1 Etiquetas, %1 Incomes & Expenses, %1 Ingresos y gastos, %1 Expenses: %2, %1 Gastos: %2, %1 Incomes: %2, %1 Ingresos: %2, %1 %2, %1 %2, %1 %1 %1 Incomes & Expenses Ingresos y gastos %1 (%2&ndash;%3) html format; %1: title; %2: from date; %3: to date %1 (%2&ndash;%3) %1 (to %2) html format; %1: title; %2: to date %1 (a %2) Category Categoria Payee Acreedor Description Referring to the transaction description property (transaction title/generic article name) Descripción Cost Gasto Payer Deudor Income Ingreso Payee/Payer Acreedor/deudor Tag Etiqueta Daily Average Promedio diario Monthly Average Promedio mensual Yearly Average Promedio anual Average Cost Gasto promedio Average Income Ingreso promedio Average Value Valor promedio No payee/payer Sin acreedor/deudor Total Total All Tags Todas las etiquetas Total incomes Ingreso total Total expenses Gasto total Total (Profits) Total (ganancias) CategoriesComparisonReportDialog Report Reporte ConfirmScheduleDialog The following transactions was scheduled to occur today or before today. Confirm that they have indeed occurred (or will occur today). La siguiente transacción fue planificada para ocurrir el día de hoy o después. Confirme que esta efectivamente ocurrió, (o lo hará el día de hoy). Date Fecha Type Tipo Description Descripción Name Nombre Description Generic Description Descripción Description Transaction description property (transaction title/generic article name) Descripción Amount Monto Edit… Editar… Postpone… Postponer… Delete Eliminar Error Can only postpone to future dates. Solo puede posponer a fechas posteriores. ConfirmScheduleListViewItem Transfer Transferencias Dividend Dividendo Income Ingreso Expense Gastos Securities Purchase Financial security (e.g. stock, mutual fund) Compra de títulos Securities Sale Financial security (e.g. stock, mutual fund) Venta de títulos Security Buy Compra de valores Security Sell Venta de valores Debt Payment CurrencyConversionDialog Currency Converter DebtFee Debt payment: %1 (fee) DebtInterest Debt payment: %1 (interest) DebtPayment Debt payment: %1 DebtReduction Debt payment: %1 (reduction) DescriptionsMenu All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) All Tags Combined All Payees Combined All Payers Combined All Payees/Payers Combined No description Referring to the transaction description property (transaction title/generic article name) Sin descripción No payee Sin acreedor No payer Sin deudor No payee/payer Sin acreedor/deudor %n descriptions Referring to the transaction description property (transaction title/generic article name) %n descripción %n descripciones %n tags %n etiqueta %n etiquetas %n payees %n acreedor %n acreedores %n payers %n deudores %n deudor %n payees/payers %n acreedor/deudor %n acreedores/deudores EditAssetsAccountDialog Type: Tipo: Cash Efectivo Current Account Cuenta actual Savings Account Cuenta de ahorros Credit Card Tarjeta de cŕedito Liabilities Pasivos Transactional Account Cuenta corriente Debt Dueda Securities Títulos financiero Other Otro Currency: Edit Editar Name: Nombre: Bank: Banca: Initial balance: Balance inicial: Debt: Initial balance Balance inicial Group: Grupo: no group ningún grupo Transferred to: Date: Fecha: Lender: Default account for budgeted transactions Cuenta predeterminada para las transacciones presupuestadas Description: Descripción: Account is closed Warning Type cannot be changed to securities for accounts with transactions. Issuer: Zero value not allowed. Error Transaction Account Cuenta corriente Opening balance: Account balance Saldo inicial: Opening balance Account balance Saldo inicial New currency… If you change the currency of an account, the currency of all associated transactions will also change, without any conversion. Do do wish to continue anyway? Empty name. Nombre vació. The entered name is used by another account. El nombre que ingreso esta siendo utilizado por otra cuenta. EditCurrencyDialog Edit Currency New Currency Code: Symbol: Prefix Suffix Default Defecto Name: Nombre: Decimals: Date: Fecha: Main currency Error Error saving currencies: %1. Empty code. Code already exists. EditDebtPaymentDialog Debt Payment EditDebtPaymentWidget Debt: Date: Fecha: Debt reduction: Reduction payment: Interest: Paid Added to debt Fee: Account: Cuenta: Expense category: Categoría de gastos: Associated file: Archivo asociado: Select a file Open the file Comments: Comentarios: Related to: Label for linked transactions Enlaces: Total value: Valor total: Error No suitable account available. No se encuentra una cuenta adecuada disponible. Invalid date. Fecha no válida. Interest must not be zero. At least one value must non-zero. EditExceptionsDialog Edit Exceptions Editar excepciones Occurrences: Ocurrencias: Add Exception Remove Exception Exceptions: Excepciones: Only the first fifty occurrences are shown. Invalid date. Fecha no válida. EditExpensesAccountDialog Name: Nombre: Parent category: None Monthly budget: Presupuesto mensual: Description: Descripción: Error Empty name. Nombre vació. The entered name is used by another expense category. El nombre elegido ya está siendo usado en otra categoría de gastos. EditIncomesAccountDialog Name: Nombre: Parent category: None Monthly budget: Presupuesto mensual: Description: Descripción: Error Empty name. Nombre vació. The entered name is used by another income category. El nombre elegido ya está siendo usado en otra categoría de ingresos. EditLoanTransactionWidget Date: Fecha: Account: Cuenta: Comments: Comentarios: Total value: Valor total: No suitable account available. No se encuentra una cuenta adecuada disponible. Invalid date. Fecha no válida. EditMultiAccountDialog Expense with Multiple Payments Income with Multiple Payments EditMultiAccountWidget Description: Descripción Description: Generic Description Descripción Description: Transaction description property (transaction title/generic article name) Descripción: Quantity: Cantidad: Category: Categoría: Tags: Etiquetas: Associated file: Archivo asociado: Select a file Open the file Comments: Comentarios: Related to: Label for linked transactions Enlaces: Transactions: Transacciónes: Date Fecha Account Cuenta Payee Acreedor Payer Deudor Cost Gasto Income Ingreso Total cost: Costo Total: New Tag Nueva etiqueta Tag: Etiqueta: Value Valor New Nuevo Edit… Editar… Delete Eliminar Total value: Valor total: Error No suitable expense categories available. A split must contain at least two transactions. Una división debe al menos contener dos transacciones. EditMultiItemDialog Split Transaction Dividir transacciones EditMultiItemWidget Description: Descripción Description: Generic Description Descripción Date: Fecha: Account: Cuenta: Payee/Payer: Acreedor/duedor: Transactions: Transacciónes: Type Tipo Description Generic Description Descripción Description: Transaction description property (transaction title/generic article name) Descripción: Tags: Etiquetas: Associated file: Archivo asociado: Select a file Open the file Comments: Comentarios: Related to: Label for linked transactions Enlaces: Description Transaction description property (transaction title/generic article name) Descripción Payment Pago Deposit Depósito New Nuevo New Expense… Nuevo gasto… New Income… Nuevo ingreso… New Deposit… Nuevo deposito… New Withdrawal… Nuevo retiro… New Securities Purchase… Financial security (e.g. stock, mutual fund) Nueva compra de títulos… New Securities Sale… Financial security (e.g. stock, mutual fund) Nueva venta de títulos… Shares Bought… Acciones Compradas… Shares Sold… Acciones Vendidas… Account/Category Cuenta/Categoría Value Valor Income Ingreso Expense Gastos New Dividend… Nuevo dividendo… Edit… Editar… Delete Eliminar Total value: Valor total: Error No suitable account available. No se encuentra una cuenta adecuada disponible. Invalid date. Fecha no válida. A split must contain at least two transactions. Una división debe al menos contener dos transacciones. Cannot transfer money to and from the same account. No se puede transferir dinero de y hacia la misma cuenta. EditQuotationsDialog Quotations Cita Date Fecha Price per Share Precio por unidad Quotations Financial quotation Cita Quotes Financial quote Cotizaciones Price per Share Financial Shares Precio por unidad Add Añadir Modify Modificar Delete Eiliminar Import… Importar… Export… Exportar… Quotes for %1 Financial quote Cotizaciones para %1 Quotations for %1 Financial quotation Citas para %1 Quotations for %1 Citas para %1 Error Couldn't open %1 for reading. No se pudo abrir %1 para lectura. Error reading %1. Ocurrió un error cuando se leía %1. Successfully imported %n quote(s). Importada %n cotizacién satisfactoriamente. Importada %n cotizaciones satisfactoriamente. Unable to import any quotes. No se pudo importar ninguna cotización. Failed to import %n data row(s). Fallo al importar %n fila de datos. Fallo al importar %n filas de datos. Required columns missing. Invalid value. Valor no válido. Invalid date. Fecha no válida. No data found. No se encontraron datos. Information Unrecognized date format. Formato de fecha desconocido. Specify Format Formato específico The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. El formato de las fechas y/o números en el archivo CVS es ambiguo. Por favor selecciona un formato correcto. Date format: Formato de fecha: Value format: Couldn't open file for writing. No se pudo abrir el archivo para editarlo. Quotes: %1 Cotizaciones: %1 Error while writing file; file was not saved. Error mientras se escribía en el archivo; el archivo no fue guardado. EditRangeDialog Edit Recurrence Range Editar rango de repetición Begins on: %1 Inicia en: %1 No ending date Sin fecha de finalización End after Termina después occurrence(s) ocurrencia(s) End on Termina en Error Invalid date. Fecha no válida. End date before start date. La fecha de finalización es anterior a la fecha de inicio. EditReinvestedDividendDialog Reinvested Dividend Dividendos reinvertidos Security: Valores: Shares added: Acciones añadidas: Security: Financial security (e.g. stock, mutual fund) Título: Shares added: Financial shares Unidades añadidas: Date: Fecha: Invalid date. Fecha no válida. EditScheduledDebtPaymentDialog Transaction Transacción Recurrence Repetición Edit Debt Payment New Debt Payment EditScheduledLoanTransactionDialog Recurrence Repetición EditScheduledMultiAccountDialog Transactions Transacciones Recurrence Repetición New Expense with Multiple Payments New Income with Multiple Payments Edit Expense with Multiple Payments Edit Income with Multiple Payments EditScheduledMultiItemDialog Transactions Transacciones Recurrence Repetición New Split Transaction Nueva transacción dividida Edit Split Transaction Editar transacción dividida EditScheduledTransactionDialog Expense Gastos Dividend Dividendo Income Ingreso Reinvested Dividend Dividendos reinvertidos Transfer Transferencias Security Buy Compra de valores Security Sell Venta de valores Securities Purchase Financial security (e.g. stock, mutual fund) Compra de títulos Securities Sale Financial security (e.g. stock, mutual fund) Venta de títulos Recurrence Repetición New Expense Nuevo gasto New Expense Paid with Loan New Dividend Nuevo dividendo New Income Nuevo ingreso New Transfer Nueva transferencia New Securities Purchase Financial security (e.g. stock, mutual fund) Nueva compra de títulos New Reinvested Dividend New Securities Sale Financial security (e.g. stock, mutual fund) Nueva venta de títulos Edit Reinvested Dividend Edit Securities Purchase Financial security (e.g. stock, mutual fund) Editar compra de títulos Edit Securities Sale Financial security (e.g. stock, mutual fund) Editar venta de títulos New Security Buy Nueva compra de valores New Security Sell Nueva venta de valores Edit Expense Editar gastos Edit Dividend Editar divididendos Edit Income Editar ingreso Edit Transfer Editar transferencias Edit Securities Bought Editar Edit Securities Sold Editar Acciones Vendidas EditSecurityDialog Type: Tipo: Mutual Fund Fondos mutuos Bond Enlace Stock Stock Stock Financial stock Acciones Other Otro Name: Nombre: Account: Cuenta: Decimals in shares: Financial shares Unidades decimales utiliza: Initial shares: Financial shares Unidades iniciales: Decimals in quotes: Financial quote Initial quote: Financial quote Cotización iniciales: Empty name. Nombre vació. No suitable account available. No se encuentra una cuenta adecuada disponible. Decimals in shares: Cuantos decimales utiliza: Initial shares: Unidades iniciales: Decimals in Shares: Cuantos decimales utiliza Initial Shares: Unidades Iniciales Initial quotation: Citas Iniciales: Date: Fecha: Description: Descripción: Error No suitable account or income category available. No se encuentra una cuenta o una categoría de ingresos adecuada disponible. EditSecurityTradeDialog Security Trade Transacción de valores From security: De los valores: Shares moved: Unidades movidas: All Todo To security: Para los valores: Shares received: Dividendos recibidos: Securities Exchange Shares of one security directly exchanged for shares of another; Financial security (e.g. stock, mutual fund) Transacción de títulos From security: Financial security (e.g. stock, mutual fund) De la título: Shares moved: Financial shares Unidades movidas: To security: Financial security (e.g. stock, mutual fund) Para la título: Shares received: Financial shares Unidades recibidos: Value: Valor: Date: Fecha: Error No other security available for exchange in the account. Shares of one security directly exchanged for shares of another; Financial security (e.g. stock, mutual fund) No hay otra título disponible para comerciar en esta cuenta. No other security available for trade in the account. No hay otra valores disponible para comerciar en esta cuenta. Selected to and from securities are the same. Financial security (e.g. stock, mutual fund) El origen y el destino de las títulos es el mismo. Zero shares not allowed. Financial shares Cero unidades no está permitido. Selected to and from securities are the same. El origen y el destino de las acciones es el mismo. Invalid date. Fecha no válida. Zero shares not allowed. Cero unidades no está permitido. Zero value not allowed. Valor Cero no esta permitido. EditSplitDialog Split Transaction Dividir Transacciones Description: Descripción Date: Fecha: Account: Cuenta: Transactions: Transacción Type Tipo Description Descripción Name: Nombre: Name Nombre Description Generic Description Descripción Account/Category Cuenta/Categoría Payment Pago Deposit Depósito New Nuevo New Expense… Nuevo Gasto… New Income… Nuevo Ingreso… New Deposit… Nuevo Deposito… New Withdrawal… Nuevo Retiro… Shares Bought… Acciones Compradas… Shares Sold… Acciones Vendidas… New Dividend… Nuevo Dividendo… Edit… Editar… Total value: Valor total: No suitable account available. No se encuentra una cuenta adecuada disponible. Invalid date. Fecha no válida. Future dates is not allowed. Fechas posteriores no son permitidas. A split must contain at least two transactions. Una división debe al menos contener dos transacciones. Cannot transfer money to and from the same account. No se puede transferir dinero de y hacia la misma cuenta. Eqonomize Accounts && Categories Cuentas y categorías Expenses Gastos Incomes Ingresos Transfers Transferencias Transaction Accounts Cuentas corrientes Savings Accounts Cuentas de ahorro Credit Cards Tarjetas de cŕedito Debts Deudas Securities Acciones Schedule Calendario Account / Category Cuenta / categoría Remaining Budget (%1) Presupuesto restante (%1) Change (%1) Cambio (%1) Total (%1) Total (%1) %2 of %1 %2 remains of %1 budget %2 de %1 Accounts Cuentas Includes budgeted transactions Incluye transacciones presupuestadas Tags Etiquetas Period Periodo From De To Para Select Period Elija un periodo Current Month Mes actual Current Year Año actual Current Whole Month Todo el mes actual Current Whole Year Todo el presente año Whole Past Month Todo el mes pasado Whole Past Year Todo el año pasado Previous Month Mes anterior Previous Year Año anterior Show partial budget Mostrar el presupuesto parcial Edit Budget Editar presupuesto Budget: Presupuesto: Month: Mes: Result previous month: Resultado del mes anterior: New Security… Nueva valores… New Transaction Nueva transacción Set Quotation… Escribir Cita Name Nombre Value Valor Shares Unidades Quotation Cita Cost Gasto Profit Beneficio Yearly Rate Índice anual Type Tipo Account Cuenta Statistics Period Estadísticas del periodo New Schedule Nuevo calendario Edit Editar Remove Eliminar Next Occurrence Siguiente ocurrencia Description Descripción Description Generic Description Descripción Amount Monto Payee/Payer Acreedor/deudor Comments Comentarios Set Schedule Confirmation Time Schedule confirmation time: Set Budget Period First day in budget month: 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 10º 11th 11º 12th 12º 13th 13º 14th 14º 15th 15º 16th 16º 17th 17º 18th 18º 19th 19º 20th 20º 21st 21 22nd 22º 23rd 23º 24th 24º 25th 25º 26th 26º 27th 27º 28th 28º Last Último 2nd Last Penúltimo 3rd Last Antepenúltimo 4th Last 4 Último 5th Last 5 Último Timestamp Marca temporal Links Enlaces Remove Link Remover enlace Link to "%1" create link to transaction (link used as verb) Enlace a "%1" Link Transaction(s) create link to transaction (link used as verb) Enlace transacción(es) All Todo Import Options Ignore duplicate transactions Rename duplicate accounts Rename duplicate categories Rename duplicate securities Synchronization Settings Web address: Download command: Duplicate Transaction… duplicate as verb Duplicar transacción… Create Link create link to or between transaction(s) Crear enlace New Tag… Nueva etiqueta… Rename Tag… Remove Tag New Tag Nueva etiqueta Tag name: Nombre de etiqueta: Remove tag? Do you wish to remove the tag "%1" from %n transaction(s)? Rename Tag optional Link Transactions create link between selected transactions (link used as verb) Enlace transacciones Create Link to Transaction Crear enlace a transacción Upload command: mandatory Automatic synchronization Upload Uploading… Error uploading file Error uploading %1: %2. Synchronizing… Error synchronizing file Error synchronizing %1: %2. Synchronization error Synchronize file? The file has been modified by a different user or program. Do you wish to merge changes? New version available A new version of %1 is available.<br><br>You can get version %2 at %3. Abort First month in budget year: Right align Alinear a la derecha %f = local file (temporary), %u = url Failed to download exchange rates from %1: %2. Error reading data from %1: %2. Unrecognized Currency No exchange rate is available for the default currency (%1). If you wish to use multiple currencies you should set the exchange rate manually. Set Main Currency Currency: Replace all occurrences of the former main currency Transaction Account Cuenta corriente S&ynchronize Import %1 File… Reconcile Account… Conciliar cuenta… Adjust balance… Referring to account balance Ajustar el saldo… Close Account Mark account as closed Cerrar cuenta New Expense Paid with Loan… Show payee and quantity Mostrar acreedor y cantidad Show quantity and payer/payee properties for incomes and expenses. Set Schedule Confirmation Time… Select Font… Seleccionar fuente… Language Idioma Default Defecto Restart required Only use this when unable to find the cause of the incorrect recorded account balance. Reopen Account Mark account as not closed New Debt Payment… New Unpaid Interest… Shares of one security directly exchanged for shares of another Financial shares Use Exchange Rate for Transaction Date Use the exchange rate nearest the transaction date, instead of the latest available rate, when converting the value of transactions. %1 exited unexpectedly before the file was saved and data was lost. Do you want to load the last auto-saved version of the file? Eqonomize! Accounting File Save file? New Loan Adjust Account Balance Ajustar el saldo de la cuenta New Security Nueva valores Edit Security Editar valores Total value: Valor total: Cost: Gasto: Profit: Ganancia: Rate: Tasa: Are you sure you want to delete the security "%1" and all associated transactions? ¿Está seguro de que quiere eliminar los valores «%1» y todas las transacciones asociadas? Error No security available. Valores no disponible. Set Quotation (%1) Establecer presupuesto (%1) Price per share: Precio por Unidad: Date: Fecha: Invalid date. Fecha no válida. Future dates are not allowed. Fechas posteriores no están permitidas. Security Transactions Transacciones de valores Bond Bono Stock Stock Mutual Fund Fondo mutuo Other Otro Add Loan Añadir préstamo Add Category Añadir categoría Ledger Libro de Compras To date is before from date. La fecha final esta antes de la fecha de inicio. From date is after to date. La fecha de inicio esta despues de la fecha final. Cash Efectivo Check Account Comprobar Cuenta Savings Account Cuenta de ahorros Salary Salario Bills Cuentas Clothing Ropa Groceries Comestibles Leisure Ocio Couldn't open file No se pudo abrir el archivo Error loading %1: %2. Error al cargar %1: %2. Couldn't save file No se pudo grabar el archivo Error saving %1: %2. Error grabando %1: %2. Updating exchange rates… Error saving currencies: %1. New currency… Transaction Schedule Transacción Programada Total Total Accounts &amp; Categories html format Cuentas y categorías Accounts &amp; Categories (%1&ndash;%2) html format Cuentas y categorías (%1&ndash;%2) Accounts &amp; Categories (to %1) html format Cuentas y categorías (a %1) Change Noun, how much the account balance has changed Cambio Balance Balance Current Account Cuenta actual Credit Card Tarjeta de cŕedito Liabilities Pasivos Set Quote… Financial quote Escribir cotización… Quote Financial quote Cotización Set Quote (%1) Financial quote Escribir cotización (%1) Stock Financial stock Acciones Balance Noun. Balance of an account Saldo Category Categoria Budget Presupuesto Remaining Budget Presupuesto restante Total Incomes Ingresos totales Costs Costos Total Expenses Gastos totales Account/Category Noun, how much the account balance has changed Cuenta/categoría Empty expenses list. Lista de gastos vacía. Empty incomes list. Lista de Ingresos vacia. Empty transfers list. Lista de transferencias vacia. Empty securities list. Lista de acciones vacia. Empty schedule list. Lista de programación vacía. Couldn't open file for writing. No se pudo abrir el archivo para editarlo. Error while writing file; file was not saved. Error mientras se escribía en el archivo; el archivo no fue guardado. &File &Archivo &Accounts &Cuentas &Transactions &Transacciones Stat&istics Estad&ísticas S&ettings &Preferencias &Help A&yuda File Archivo Transactions Transacciones Statistics Estadísticas &New &Nuevo &Open… &Abrir… Open Recent Abrir reciente Clear List Borrar lista &Save &Guardar Save As… Guardar como… &Revert &Volver a cargar &Print… &Imprimir… Print Preview… Vista previa… Import Importar Import CSV File… Importar archivo CSV… Import QIF File… Importar archivo QIF… Export View… Exportar vista… Export As QIF File… Exportar como archivo QIF… Update Exchange Rates Currency Converter &Quit &Salir Add Account… Añádir cuenta… New Account… Nueva cuenta… New Income Category… Nueva categoría de ingresos… New Expense Category… Nueva categoría de gastos… Add Account Añádir cuenta Assets Activos Description Transaction description property (transaction title/generic article name) Descripción &Loans &Préstamos New Loan… Nueva préstamo… Edit… Editar… Balance… Balance… Show Transactions Mostrar transacciones Show Ledger Mostrar libro de compras New Expense… Nuevo gasto… New Income… Nuevo ingreso… New Transfer… Nueva transacción… New Split Transaction… Nueva transacción dividida… New Expense with Multiple Payments… Refund… Resembolso… Repayment… Repago… New Refund/Repayment… Nueva reintegro/repago… Edit Transaction(s) (Occurrence)… Editar transacción(es) (occurencia)… Edit Occurrence… Editar ocurrencia… Edit Schedule (Recurrence)… Editar calendario (repetición)… Edit Schedule… Editar calendario… Edit Split Transaction… Editar transacción dividida… Join Transactions… join transactions together Unir transacciones… Split Up Transaction split up joined transactions Dividir transacción Edit Timestamp… Editar marca temporal… Select Associated File Open Associated File Remove Transaction(s) (Occurrence) Remover trasacción(es) (ocurrencia) Remove Occurrence Remover ocurrencia Delete Schedule (Recurrence) Eliminar calendario (recurrente) Delete Schedule Eliminar calendario Remove Split Transaction Eliminar transacción dividida Edit Security… Editar valores… Shares Bought… Acciones compradas… Shares Sold… Acciones Vendidas… Shares Moved… Unidades movidas… Dividend… Dividendos… Reinvested Dividend… Dividendos reinvertidos… Transactions… Transacciones… Edit Quotations… Editar Citas… Development Over Time Report… Reporte detallado por tiempo… Categories Comparison Report… Reporte comparativo de categorías… Development Over Time Chart… Tabla detallada por tiempo… Categories Comparison Chart… Tabla comparativa de categorías… Use Additional Transaction Properties Use propiedades adicionales de las trensacciones Set Main Currency… Set Budget Period… Initial Period Periodo inicial Remember Last Dates Recordar últimas fechas Backup Frequency Daily Diario Weekly Semanalmente Fortnightly Monthly Mensualmente Never Cloud Synchronization (experimental)… Dark Mode Modo oscuro Help Report Bug About %1 About Qt Please restart the application for the language change to take effect. A personal accounting program Un programa de contabilidad personal License: GNU General Public License Version 3 Crash Recovery Recuperación del cuelgue Untitled Sin título Securities Financial security (e.g. stock, mutual fund) Títulos financiero New Security… Financial security (e.g. stock, mutual fund) Nueva título… Set Quotation… Financial quotation Escribir Cita Shares Financial shares Unidades Quotation Financial quotation Cita New Security Financial security (e.g. stock, mutual fund) Nueva título Edit Security Financial security (e.g. stock, mutual fund) Editar título Delete security? Financial security (e.g. stock, mutual fund) Are you sure you want to delete the security "%1" and all associated transactions? Financial security (e.g. stock, mutual fund) No security available. Financial security (e.g. stock, mutual fund) Título no disponible. Set Quotation (%1) Financial quotation Establecer presupuesto (%1) Price per share: Financial shares Precio por unidad: Security Transactions Financial security (e.g. stock, mutual fund) Transacciones de títulos Checking Account Transactional account Cuenta corriente Balance Account balance Saldo Empty securities list. Financial security (e.g. stock, mutual fund) Lista de acciones vacia. &Securities Financial security (e.g. stock, mutual fund) &Títulos Balance… Balance account Balance… Edit Security… Financial security (e.g. stock, mutual fund) Editar título… Remove Security Financial security (e.g. stock, mutual fund) Eleminar título Shares Bought… Financial shares Unidades compradas… Shares Sold… Financial shares Unidades vendidas… Edit Quotations… Financial quotation Editar Citas… The current file has been modified. Do you want to save it? El Archivo actual ha sido modificado. ¿Desea guardar los cambios? Confirm Schedule Confirmar la programación New Account Nueva cuenta New Income Category Nueva categoría de ingresos New Expense Category Nueva categoría de gastos Balance Account Cuenta de balance Book value: Valor del libro: of which %1 is balance adjustment Referring to account balance Real value: Valor teal: Edit Account Editar cuenta Edit Income Category Editar categoría de ingresos Edit Expense Category Editar categoría de gastos Remove subcategories? ¿Eliminar subcategorías? Do you wish to remove the category including all subcategories? Move transactions? ¿Mover transacción? Move to: Mover a: Remove irreversibly from all accounts (do not do this if account has been closed!) The category contains some expenses. What do you want to do with them? La categoría contiene algunos gastos. ¿Qué desea hacer con ellos? The category contains some incomes. What do you want to do with them? La categoría contiene algunos ingresos. ¿Qué desea hacer con ellos? The account contains some transactions. What do you want to do with them? La categoría contiene algunas transacciones. ¿Qué desea hacer con ellas? Remove Category? ¿Eliminar categoría? The category contains some expenses that will be removed. Do you still want to remove the category? La Categoría contiene algunos gastos que serán eliminados. ¿Desea eliminarla? The category contains some incomes that will be removed. Do you still want to remove the category? La categoría contiene algunos ingresos que serán eliminados. ¿Desea eliminarla? Remove Account? ¿Eliminar cuenta? The account contains some transactions that will be removed. Do you still want to remove the account? La cuenta contiene algunas transacciones que serán eliminadas. ¿Desea eliminarla? %2 of %1 %1: budget; %2: remaining budget %2 de %1 Balance… Verb. Balance an account Balance… Shares Exchanged… Shares of one security directly exchanged for shares of another; Financial shares Unidades movidas… Edit Quotes… Financial quote Editar cotizaciones… Balance Account Verb Cuenta de balance %1 (with no budget) %1 (sin presupuesto) %1 (with budget %2) %1 (con presupuesto %2) EqonomizeCalendarWidget Today Hoy EqonomizeDateEdit Today Hoy EqonomizeTranslator OK Only used when Qt translation is missing Cancel Only used when Qt translation is missing Close Only used when Qt translation is missing &Yes Only used when Qt translation is missing &No Only used when Qt translation is missing &Open Only used when Qt translation is missing &Save Only used when Qt translation is missing &Select All Only used when Qt translation is missing Look in: Only used when Qt translation is missing File &name: Only used when Qt translation is missing Files of type: Only used when Qt translation is missing EqonomizeValueEdit Error Empty denominator. Empty factor. Division by zero. Unknown or ambiguous currency, or unrecognized characters, in expression: %1. Empty base. Empty exponent. Unrecognized characters in expression. ExportQIFDialog Export QIF File Exportar archivo QIF Account: Cuenta: All All accounts Todo Export transaction description as: Exportar la descripción de la transacción como: Export transaction description as: Referring to generic description Exportar la descripción de la transacción como: Payee Acreedor Memo Nota Subcategory Subcategoría Date format: Formato de fecha: Value format: Formato de valor: File: Archivo: Error Selected file is a directory. El archivo seleccionado es un directorio. Overwrite The selected file already exists. Would you like to overwrite the old copy? El archivo existe, ¿Quiere sobreescribirlo? You selected a directory! Usted selecciono un directorio. Couldn't open file for writing. No se pudo abrir el archivo para editarlo. Error while writing file; file was not saved. Error mientras se escribía en el archivo; el archivo no fue guardado. ImportCSVDialog Import CSV file Importar archivo CVS Transaction Type Selection Selecciona el tipo de transacción Expenses Gastos Incomes Ingresos Transfers Transferencias Expenses and incomes (negative cost) Gastos e ingresos (gastos negativos) Expenses and incomes (separate columns) Gastos e ingresos (columnas separadas) All types Todos los tipos Presets: File Selection Selección de archivo File: Archivo: First data row: Primera fila de datos: Auto Automático Column delimiter: Delimitador de Columna: Comma Coma Tabulator Tabulador Semicolon Punto y coma Space Espacio Other Otro Columns Specification Espicificación de columnas Save as preset… Imports data as expenses and incomes. Costs have negative value. Value is the only required column. Importar datos como gastos e ingresos. Los gastos tienen valor negativo. El valor es la única columna requerida. Imports data as expenses and incomes. Costs and incomes have separate columns. Income and cost both all required columns. Importar datos como gastos e ingresos. Gastos e ingresos estan en columnas separadas. Ingresos y gastos son columnas requeridas. Warning The same column number is selected multiple times. Do you wish to proceed anyway? Description: Descripción Description: Transaction description property (transaction title/generic article name) Descripción: Column Columna Value Valor Cost: Gasto: Date: Fecha: Category: Categoría: From account: Desde la cuenta: Quantity: Cantidad: Payee: Acreedor: Tags: Etiquetas: Comments: Comentarios: Create missing categories and accounts Cree las categorías y las cuentas que faltan Save Preset Imports data as expenses. Costs have positive value. Value is the only required column. Imports data as incomes. Value is the only required column. Importar datos como ingresos. El valor es la única columna requerida. Income: Ingreso: To account: Para la cuenta: Payer: Deudor: Imports data as transfers. Value is the only required column. Importar datos como trasacciones. El valor es la única columna requerida. Amount: Cuenta: Imports data as expenses and incomes. Costs have negative value. Value and category are both required columns. Importar datos como gastos e ingresos. Los gastos tienen valor negativo. El valor y la categoría son las columnas requeridas. Value: Valor: Account: Cuenta: Payee/payer: Acreedor/deudor: Imports data as expenses and incomes. Costs and incomes have separate columns. Income, cost, and category are all required columns. Importar datos como gastos e ingresos. Gastos e ingresos estan en columnas separadas. Ingresos, gastos y categoría son columnas requeridas. Imports data as expenses, incomes, and transfers. Costs have negative or positive value. Value, to, and from are all required columns. Accounts and categories must be existing. Importar datos como gastos, ingresos y transacciones. Gastos tiene valor positivo o negativo. El valor, el destino y el origen son las columnas requeridas. From: De: To: Para: Error A file must be selected. Un archivo debe ser seleccionado. Selected file is a directory. El archivo seleccionado es un directorio. Selected file does not exist. El archivo seleccionado no existe. Empty delimiter. Delimitador vacio. The same column number is selected multiple times. El mismo número de columna ha sido seleccionado varias veces. Selected from account is the same as the to account. La cuenta seleccionada desde es la misma que la en. Invalid date. Fecha no válida. Couldn't open %1 for reading. No se pudo abrir %1 para lectura. Error reading %1. Ocurrió un error cuando se leía %1. Uncategorized Sin Categoría Successfully imported %n transaction(s). Importada %n transacción satisfactoriamente. Importada %n transacciones satisfactoriamente. Unable to import any transactions. No se pudo importar ninguna transacción. Failed to import %n data row(s). Fallo al importar %n fila de datos. Fallo al importar %n filas de datos. Required columns missing. No se encuentra una columna requerida. Invalid value. Valor no válido. Empty category name. Nombre de categoría vacío. Empty account name. Nombre de cuenta vacío. Unknown category found. Categoría desconocida. Unknown account found. Cuenta desconocida. Cannot import security transactions (to/from security accounts). No se pudo importar las transacciones de valores (desde/a cuentas valores). Balancing account wrongly used. Referring to the account used for adjustments of account balances. Cuenta de balance mal utilizada. Balancing account wrongly used. Cuenta de balance mal utilizada. Same to and from account/category. El origen y el destino de la cuenta/categoría es el mismo. No data found. No se encontraron datos. Information Unrecognized date format. Formato de fecha desconocido. Specify Format Formato específico The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. El formato de las fechas y/o números en el archivo CVS es ambiguo. Por favor selecciona un formato correcto. Date format: Formato de fecha: Value format: Formato de valor: ImportQIFDialog Import QIF file Importar archivo QIF File Selection Selección de archivo Select a QIF file to import. When you click next, the file be analysed and you might need to answer some questions about the format of the file. Seleccione un archivo QIF para importar. Cuando usted haga click en "Next", se analizará el archivo y es posible que tenga que responder a algunas preguntas sobre el formato del archivo. File: Archivo: Local Definitions Definiciones Locales Unknown elements where found in the QIF file. It is possible that this is because of localized type names. Please map them to the correct standard names. Local Text Texto local Standard Text Texto estándar Select standard text: Seleccionar texto estándar: Date Format Formato de fecha The date format in the QIF file is ambiguous. Please select the correct format. El formato de la fecha del archivo QIF es ambiguo. Por favor, elige un formato correcto. Date format: Formato de fecha: Default Account Cuenta por defecto Could not find any account definitions in the QIF file. Please select a default account. It is also possible that this is caused by a localized opening balance text. No se pudo encontrar ninguna definicion de cuentas en el archivo QIF. Por favor, seleccione una cuenta por defecto. Es posible que esto sea causado por utilizar una localizacion del texto del balance. Default account: Cuenta por defecto: Opening balance text: Descriptions Descripciones Subcategories as: Subcategorías como: Description Descripción Category Categoria Ignore Omitir Payee as: Acreedor como: Payee Acreedor Comments Comentarios Priority: Prioridad: Subcategory/Payee/Comments Subcategoría/Acreedor/comentarios Payee/Subcategory/Comments Acreedor/Subcategoría/Comentarios Subcategory/Comments/Payee Subcategoría/Comentarios/Acreedor Payee/Comments/Subcategory Acreedor/Comentarios/Subcategoría Comments/Subcategory/Payee Comentarios/Subcategoría/Acreedor Comments/Payee/Subcategory Comentarios/Acreedor/Subcategoría Import File Importar archivo No (further) issues were found. Press finish to import the selected QIF file. Ignore duplicate transactions Error A file must be selected. Un archivo debe ser seleccionado. Selected file is a directory. El archivo seleccionado es un directorio. Selected file does not exist. El archivo seleccionado no existe. Couldn't open %1 for reading. No se pudo abrir %1 para lectura. Error reading %1. Ocurrió un error cuando se leía %1. Unknown Desconocido Account Cuenta Bank Banco Cash Efectivo Cat (Category) Cat (categoría) CCard (Credit Card) CCard (tarjeta de crédito) Invst (Investment) Invst (inversión) Oth A (Other Assets) Oth A (otros activos) Oth L (Other Liabilities) Oth L (otras pasivos) Security Título Other Otro Unrecognized date format. Formato de fecha desconocido. Successfully imported %n transaction(s). Importada %n transacción satisfactoriamente. Importada %n transacciones satisfactoriamente. Successfully imported %n account(s). Importada %n cuenta satisfactoriamente. Importadas %n cuentas satisfactoriamente. Successfully imported %n category/categories. Importada %n categoría satisfactoriamente. Importadas %n categorías satisfactoriamente. %n duplicate transaction(s) was ignored. %n transacción duplicada ha sido ignorada. %n transacciones duplicadas ha sido ignoradas. Failed to import %n transaction(s). Fallo al importar %n transacción. Fallo al importar %n transacciones. %n security/securities were not imported. Financial security (e.g. stock, mutual fund) %n security transaction(s) were not imported. Financial security (e.g. stock, mutual fund) Information Income Dividend: %1 Dividendo %1 Reinvested dividend: %1 Dividendos reinvertidos: %1 LedgerDialog Account: Cuenta: Export… Exportar… Print… Imprimir… Reconcile Accounting context Conciliar Change: Accounting context Cambio: Date Fecha Type Tipo Description Descripción Name Nombre Description Generic Description Descripción Account/Category Cuenta/categoría Deposit Depósito Withdrawal Retirada Balance Balance New Nuevo Edit… Editar… Delete Eleminar Join… join transactions together Unir… Split Up split up joined transactions Separar Reconciled: %1 (%2) Accounting context Conciliado: %1 (%2) Error Invalid date. Fecha no válida. Opening date is after closing date. Closing date is before opening date. Empty transaction list. Lista de la transacción vacia. Couldn't open file for writing. No se pudo abrir el archivo para editarlo. Error while writing file; file was not saved. Error mientras se escribía en el archivo; el archivo no fue guardado. Ledger Libro de Compras Transactions for %1 Transacciones para %1 Select Time Period From: De: To: Para: To date is before from date. Balance change: Account balance Delete transactions? ¿Eliminar transacciones? Are you sure you want to delete all (%1) selected transactions? ¿Esta seguro de que quiere eliminar todas (%1) las transacciones seleccionadas? Opening balance Account balance Saldo inicial Account Balance Adjustment Ajuste del saldo de la cuenta Current balance: Account balance Average balance: Account balance Account Balancing Balancing of an account Balanceo de cuenta Balancing Balancing of an account Balance Balancing Account balancing Balance Current debt: Total debt reduction: Total interest and fees: Number of transactions: Initial balance Balance inicial Description Transaction description property (transaction title/generic article name) Descripción Balance Account balance Saldo Cannot set the value of security transactions using the dialog for modifying multiple transactions. Financial security (e.g. stock, mutual fund) Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name); Financial security (e.g. stock, mutual fund) Cannot change payer of dividends and security transactions. Financial security (e.g. stock, mutual fund) Split Transaction Dividir transacciones Debt Payment Reduction Fee Interest Income Ingreso Repayment Refinanciamiento Expense Gastos Edit Account… Editar cuenta… Mark all as reconciled Accounting context Opening balance: Accounting context Saldo de apertura: Closing balance: Accounting context Balance de cierre: R Header for account reconciled checkbox column C Payee/Payer Acreedor/deudor Tags Etiquetas Comments Comentarios Deposit Money put into account Depósito Withdrawal Money taken out from account Retirada Balance Noun. Balance of an account Saldo Edit Transaction(s)… Editar transacción(es)… Join Transactions… Unir transacciones… Split Up Transaction Dividir transacción Remove Transaction(s) Remover trasacción(es) Mark as reconciled Book value: %1 (%2) Accounting context Valor del libro: %1 (%2) Ascending order Refund Reembolso Balancing Balance Transfer Transferencias LinksWidget Remove Link Remover enlace All Todo Remove Eliminar MultiItemListViewItem Dividend Dividendo Income Ingreso Repayment Refinanciamiento Expense Gastos Refund Reembolso Securities Purchase Financial security (e.g. stock, mutual fund) Compra de títulos Securities Sale Financial security (e.g. stock, mutual fund) Venta de títulos Account Balance Adjustment Ajuste del saldo de la cuenta Account Balancing Balancing of an account Balanceo de cuenta Balancing Balancing of an account Balance Security Buy Compra de valores Security Sell Venta de valores Balancing Balance Transfer Transferencias MultipleTransactionsEditDialog Modify Transactions Modificar transacciones Description: Descripción Name: Nombre: Description: Transaction description property (transaction title/generic article name) Descripción: Amount: Cuenta: Income: Ingreso: Cost: Gasto: Date: Fecha: Category: Categoría: Payer: Deudor: Payee: Acreedor: New Income Category Nueva Categoría de Ingresos New Expense Category Nueva Categoría de Gastos New Income Category… Nueva Categoría de Ingresos… New Expense Category… Nueva Categoría de Gastos… Error No income category available. Ninguna categoría de ingresos disponible. No expense category available. Ninguna categoría de gastos disponible. Invalid date. Fecha no válida. OverTimeChart Save As… Guardar como… Print… Imprimir… Source: Fuente: Incomes and Expenses Ingresos y gastos Profits Beneficios Expenses Gastos Incomes Ingresos All Categories Combined Todas las categorías combinadas All Descriptions Combined Todas las Descripciones combinadas Theme: Chart type: Line Chart Vertical Bar Chart Horizontal Bar Chart Stacked Bar Chart Default Defecto Tags Etiquetas All Accounts Combined Todos las cuentas combinados All Accounts Split Todas las cuentas separados All Subcategories and Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Todas las subcategorías y descripciones combinadas All Descriptions Split Referring to the transaction description property (transaction title/generic article name) Todas las descripciones separadas No description Referring to the transaction description property (transaction title/generic article name) Sin descripción All Payees/Payers Split Todos los acreedores/deudores separados No payee/payer Sin acreedor/deudor All Tags Split Todas las etiquetas separadas Other tags Otras etiquetas Other payees/payers Otros acreedores/deudores Other descriptions Referring to the transaction description property (transaction title/generic article name) Otras descripciones Profits, %1 Beneficios, %1 Assets Activos All Descriptions Combined Referring to the generic description property Todas las Descripciones combinadas Assets and Liabilities Activos y pasivos All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Todas las descripciones combinadas All Payees/Payers Combined Todos los acreedores/deudores combinados All Accounts Todas las cuentas Start date: Fecha de inicio: End date: Fecha de finalización: Value: Valor: Annual total Total anual Monthly total Total mensual Daily average Media diaria Quantity Cantidad Average value Valor promedio All Payers Combined Todos los deudores combinados All Payees Combined Todos los acreedores combinados All Subcategories Split Todas las subcategorías separadas All Descriptions Split Referring to the generic description property Todas las descripciones separadas No description Referring to the generic description property Sin descripción Value Valor Includes budgeted transactions Incluye transacciones presupuestadas Incomes − Expenses, %1 Ingresos − gastos, %1 Incomes − Expenses Ingresos − gastos Incomes & Expenses Ingresos y gastos Incomes: %1 Ingresos: %1 Expenses: %1 Gastos: %1 %2: %1 %2: %1 Incomes: %2, %1 Ingresos: %2, %1 Expenses: %2, %1 Gastos: %2, %1 %3: %2, %1 %3: %2, %1 %2, %1 %2, %1 Incomes: %3, %2, %1 Ingresos: %3, %2, %1 Expenses: %3, %2, %1 Gastos: %3, %2, %1 %4: %3, %2, %1 %4: %3, %2, %1 no payee/payer sin acreedor/deudor %3, %2, %1 %3, %2, %1 Other accounts Otras cuentas %1 Value: %2 Date: %3 %1 Valor: %2 Fecha: %3 MMMM yyyy Month and year All Descriptions Split Todas las descripciones separadas All Payers Split Todos los deudores separados All Payees Split Todos los acreedores separados No description Sin descripción No payer Sin deudor No payee Sin acreedor All Categories Split Todas las categorías separadas Error Invalid date. Fecha no válida. Couldn't open file for writing. No se pudo abrir el archivo para editarlo. Error while writing file; file was not saved. Error mientras se escribía en el archivo; el archivo no fue guardado. Other payees Otros acreedores Other payers Otros deudores Value (%1) Valor (%1) Profit (%1) Beneficios (%1) Income (%1) Ingresos (%1) Cost (%1) Gastos (%1) Time Tiempo %1/%2 %1: Category; %2: Payee/Payer %1/%2 All Descriptions Combined Referring to the Transaction description property (transaction title/generic article name) Todas las Descripciones combinadas All Descriptions Split Referring to the Transaction description property (transaction title/generic article name) Todas las descripciones separadas No description Referring to the Transaction description property (transaction title/generic article name) Sin descripción Daily average value Valor promedio diario Daily average profit Promedio de beneficio diario Daily average income Ingreso promedio diario Daily average cost Gasto promedio diario Average income Ingreso promedio Average cost Gasto promedio Annual value Valor anual Annual profit Beneficio anual Annual income Ingreso anual Annual cost Gasto anual Monthly value Valor mensual Monthly profit Beneficio mensual Monthly income Ingreso mensual Monthly cost Gasto mensual Includes scheduled and budgeted transactions Incluir transacciones progamadas y presupuestadas Includes scheduled transactions Incluir las transacciones progamadas Tags, %1 Etiquetas, %1 Value: %1 Valor: %1 Assets & Liabilities Activos y pasivos Change: %1 Cambio: %1 Excluding any profits or losses in trading of security shares Financial security (e.g. stock, mutual fund) Incomes & Expenses, %1 Ingresos y gastos, %1 Incomes, %1 Ingresos, %1 Expenses, %1 Gastos, %1 Incomes, %2: %1 Ingresos, %2: %1 Expenses, %2: %1 Gastos, %2: %1 Incomes, %3: %2, %1 Ingresos, %3: %2, %1 Expenses, %3: %2, %1 Gastos, %3: %2, %1 Incomes, %4: %3, %2, %1 Ingresos, %4: %3, %2, %1 Expenses, %4: %3, %2, %1 Gastos, %4: %3, %2, %1 Liabilities Pasivos no payer no deudor %1/%2 %1: Description; %2: Payer/Payer %1/%2 %1/%2 %1: Description; %2: Payee/Payer %1/%2 %1/%2 %1: Description; %2: Payer %1/%2 no payee no acreedor %1/%2 %1: Description; %2: Payee %1/%2 OverTimeChartDialog Chart Gráfico OverTimeReport Save As… Guardar como… Print… Imprimir… Source: Fuente: Profits Beneficios Expenses Gastos Incomes Ingresos Assets & Liabilities Activos y pasivos Tags Etiquetas All Categories Combined Todas las categorías combinadas All Descriptions Combined Todas las Descripciones combinadas Columns: Columnas: Categories Categorías Total: Total: Value Valor Daily Diario Monthly Mensualmente Yearly Anualmente Quantity Cantidad Average value Valor promedio No description Sin descripción All Descriptions Combined Referring to the generic description property Todas las Descripciones combinadas No description Referring to the generic description property Sin descripción All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Todas las descripciones combinadas All Accounts Todas las cuentas No description Referring to the transaction description property (transaction title/generic article name) Sin descripción Error Couldn't open file for writing. No se pudo abrir el archivo para editarlo. Error while writing file; file was not saved. Error mientras se escribía en el archivo; el archivo no fue guardado. Average Profit Promedio de beneficios Incomes, %1 Ingresos, %1 Average Income Ingreso promedio Expenses, %1 Gastos, %1 Average Cost Gasto promedio Incomes, %2: %1 Ingresos, %2: %1 Incomes: %1 Ingresos: %1 Expenses, %2: %1 Gastos, %2: %1 Expenses: %1 Gastos: %1 Incomes, %3: %2, %1 Ingresos, %3: %2, %1 Incomes: %2, %1 Ingresos: %2, %1 Expenses, %3: %2, %1 Gastos, %3: %2, %1 Expenses: %2, %1 Gastos: %2, %1 Change: %1 Noun, how much the account balance has changed Cambio: %1 Average Change Cambio promedio Change Noun, how much the account balance has changed Cambio Value: %1 Valor: %1 Year Año Month Mes Assets Activos Deposit Depósito Withdrawal Retirada Liabilities Pasivos %2: %1 %2: %1 %1 %1 Average Value Valor promedio %3: %2, %1 %3: %2, %1 %2, %1 %2, %1 Daily Average Promedio diario Monthly Average Promedio mensual Yearly Average Promedio anual Subtotal Subtotal Total Total Deposit Money put into account Depósito Withdrawal Money taken out from account Retirada Includes scheduled transactions Incluir las transacciones progamadas Adjusted for the average month / year (%1 / %2 days) Ajustado para el mes / año promedio (%1 / %2 días) All Categories Combined Referring to the generic description property Todas las Categorías combinadas OverTimeReportDialog Report Reporte QApplication Start with expenses list displayed Comenzar con la lista de los gastos mostrada Start with incomes list displayed Comenzar con la lista de los ingresos mostrada Start with transfers list displayed Comenzar con la lista de las transferencias mostrada Synchronize file Document to open Abrir documento %1 is already running. QObject Transfer Transferencias Dividend Dividendo Income Ingreso Expense Gastos Securities Purchase Financial security (e.g. stock, mutual fund) Compra de títulos Securities Sale Financial security (e.g. stock, mutual fund) Venta de títulos Security Buy Compra de valores Security Sell Venta de valores Debt Payment Split Transaction Dividir transacciones RecurrenceEditWidget Enable recurrence Repetición permitida Recurrence Rule Regla de repetición Daily Diario Weekly Semanalmente Monthly Mensualmente Yearly Anualmente Recur every Repetir cada day(s) día(s) week(s) on: semana(s) en: month(s), after the start month mes(es), después del mes de comienzo Recur on the Repetir el 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 10º 11th 11º 12th 12º 13th 13º 14th 14º 15th 15º 16th 16º 17th 17º 18th 18º 19th 19º 20th 20º 21st 21 22nd 22º 23rd 23º 24th 24º 25th 25º 26th 26º 27th 27º 28th 28º 29th 29º 30th 30º 31st 31º Last Último 2nd Last Penúltimo 3rd Last Antepenúltimo 4th Last 4 Último 5th Last 5 Último day día possibly on weekend posiblemente en el fin de semana but before weekend but after weekend pero después del fin de semana nearest weekend day year(s), after the start year on nearest weekday Recur on day part before XXX of 'Recur on day XXX of month YYY' Repetir el día of part between XXX and YYY of 'Recur on day XXX of month YYY' de On the Part before NNN in 'Recur on the NNN. WEEKDAY of MONTH' En el/la of part between WEEKDAY and MONTH in 'Recur on NNN. WEEKDAY of MONTH' de Recur on day # of the year part after NNN of 'Recur on day #NNN of the year' del año Range… Rango… Occurrences/Exceptions… Ocurrencias/excepciones… Exceptions… Excepciones… Error No day of week selected for weekly recurrence. Ningún día de la semana seleccionado para la repetición semanal. Selected day will never occur with selected frequency and start date. Selected day does not exist in selected month. Este día no existe en el mes seleccionado. RefundDialog Repayment Refinanciamiento Refund Reembolso Date: Fecha: Cost: Gasto: Income: Ingreso: Quantity returned: Cantidad devuelta: Account: Cuenta: Quantity: Cantidad: Payee: Acreedor: Payer: Deudor: Comments: Comentarios: Link Link the transactions together Link Join Join the transactions together Unir Error Zero value not allowed. Valor Cero no esta permitido. Invalid date. Fecha no válida. SecurityBuy Security: %1 (bought) Valores: %1 (comprado) Security: %1 (bought) Financial security (e.g. stock, mutual fund) Título: %1 (comprado) SecuritySell Security: %1 (sold) Valores: %1 (vendido) Security: %1 (sold) Financial security (e.g. stock, mutual fund) Título: %1 (vendido) SecurityTransactionsDialog Transactions for %1 Transacciones para %1 Date Fecha Type Tipo Value Valor Shares Financial shares Unidades Shares Bought Financial shares Unidades compradas Shares Bought (Recurring) Financial shares Unidades compradas (recurrentes) Dividend (Recurring) Dividendo (recurrentes) Dividend (Scheduled) Dividendo (programada) Reinvested Dividend (Recurring) Dividendos reinvertidos (recurrentes) Reinvested Dividend (Scheduled) Dividendos reinvertidos (programada) Shares Bought Fincancial shares Unidades Compradas Shares Sold Financial shares Unidades vendidas Shares Sold (Exchanged) Shares of one security directly exchanged for shares of another; Financial shares Unidades vendidas (transacción) Shares Bought (Exchanged) Shares of one security directly exchanged for shares of another; Financial shares Unidades compradas (transacción) Shares Bought (Recurring) Fincancial shares Acciones Compradas (Recurrentes) Shares Sold (Recurring) Financial shares Unidades vendidas (recurrentes) Shares Bought (Scheduled) Financial shares Unidades compradas (programada) Shares Sold (Scheduled) Financial shares Unidades vendidas (programado) Shares Unidades Edit… Editar… Delete Eliminar Shares Bought Unidades Compradas Shares Sold Unidades Vendidas Dividend Dividendo Reinvested Dividend Dividendos reinvertidos Shares Sold (Traded) Unidades Vendidas (Transacción) Shares Bought (Traded) Unidades Compradas (Transacción) Shares Bought (Recurring) Acciones Compradas (Recurrentes) Shares Sold (Recurring) Acciones Vendidas (Recurrentes) Shares Bought (Scheduled) Acciones Compradas (Programada) Shares Sold (Scheduled) Acciones Vendidas (Programado) Recurring Dividend Dividendos recurrentes Scheduled Dividend Dividendos programados SplitListViewItem Dividend Dividendo Income Ingreso Repayment Refinanciamiento Expense Gastos Refund Reembolso Security Buy Compra Segura Security Sell Venta segura Balancing Balance Transfer Transferencias TagButton no tags no etiquetas TagMenu New tag… Nueva etiqueta… New Tag Nueva etiqueta Tag: Etiqueta: TransactionEditDialog Edit Expense Editar gastos Edit Dividend Editar divididendos Edit Income Editar ingreso Edit Transfer Editar transferencias Edit Securities Purchase Financial security (e.g. stock, mutual fund) Editar compra de títulos Edit Securities Sale Financial security (e.g. stock, mutual fund) Editar venta de títulos Edit Reinvested Dividend Edit Securities Bought Editar Edit Securities Sold Editar Acciones Vendidas TransactionEditWidget Security: Valores: Cost: Gasto: Income: Ingreso: All Todo Price per share: Precio por Unidad: Date: Fecha: Description: Descripción Name: Nombre: Amount: Cuenta: Withdrawal: Money taken out from account Retirada: New Security… Financial security (e.g. stock, mutual fund) Shares added: Financial shares Set security share value Total value: Valor total: Deposit: Money put into account Depósito: Downpayment: Quantity: Cantidad: From: De: To: Para: Category: Categoría: To account: Para la cuenta: Payer: Deudor: Payer of parent split transaction From account: Desde la cuenta: Downpayment account: Payee: Acreedor: Payee of parent split transaction Lender: Tags: Etiquetas: Associated file: Archivo asociado: Select a file Open the file Comments: Comentarios: Related to: Label for linked transactions Enlaces: New Security Financial security (e.g. stock, mutual fund) Nueva valores No security available. Financial security (e.g. stock, mutual fund) Título no disponible. New Tag Nueva etiqueta Tag: Etiqueta: New Account Nueva Cuenta New Income Category Nueva Categoría de Ingresos New Expense Category Nueva Categoría de Gastos New Account… Nueva Cuenta… New Income Category… Nueva Categoría de Ingresos… New Expense Category… Nueva Categoría de Gastos… Security: Financial security (e.g. stock, mutual fund) Título: Shares bought: Financial shares Unidades compradas: Shares sold: Financial shares Unidades vendidas: Price per share: Financial shares Precio por unidad: Description: Transaction description property (transaction title/generic article name) Descripción: Transaction title/generic article name Number of items included in the transaction. Entered cost is total cost for all items. Error No suitable account available. No se encuentra una cuenta adecuada disponible. No income category available. Ninguna categoría de ingresos disponible. No suitable account or income category available. No se encuentra una cuenta o una categoría de ingresos adecuada disponible. No expense category available. Ninguna categoría de gastos disponible. No security available. Valores no disponible. Invalid date. Fecha no válida. Cannot transfer money to and from the same account. No se puede transferir dinero de y hacia la misma cuenta. Downpayment must be less than total cost. Cannot create a regular transfer to/from a securities account. Cannot create a regular income to a securities account. Zero shares not allowed. Cero unidades no está permitido. Zero value not allowed. Valor cero no esta permitido. Zero price per share not allowed. Cannot create a regular expense from a securities account. Loan for %1 TransactionFilterWidget From: De: To: Para: Min amount: Cantidad mínima: Max amount: Cantidad máxima: Category: Categoría: To account: Para la cuenta: Min income: Ingresos mínimos: Max income: Ingresos máximos: From account: Desde la cuenta: Min cost: Coste mínimo: Max cost: Coste máximo: Tag: Etiqueta: Description: Descripción Description: Transaction description property (transaction title/generic article name) Descripción: Payer: Deudor: Payee: Acreedor: Include Incluir Exclude Excluir Exact match Exclude subcategories Clear Borrar All Todo Error Invalid date. Fecha no válida. To date is before from date. La fecha final esta antes de la fecha de inicio. From date is after to date. La fecha de inicio esta despues de la fecha final. TransactionListWidget Date Fecha Description Descripción Cost Gasto Category Categoria From Account Desde la cuenta Payee Acreedor Income Ingreso To Account A la cuenta Payer Deudor Amount Monto From De To Para Comments Comentarios Add Añadir Apply Applicar Delete Eliminar Expense Gastos Transfer Transferencias Name Nombre Description Generic Description Descripción Description Transaction description property (transaction title/generic article name) Descripción New/Edit Expense Nuevo/editar gasto New/Edit Income Nuevo/editar ingreso New/Edit Transfer Nuevo/editar transferencia Filter Filtro Quantity: Cantidad: Total: Total: Average: Promedio: Clear Borrar Cost: Gasto: Monthly: Mensual: Sort by creation time Right align Alinear a la derecha Expenses Gastos Incomes Ingresos Transfers Transferencias Quantity Cantidad Tags Etiquetas Total cost: Costo Total: Total income: Ingreso total: Total amount: Monto total: Monthly average: Promedio mensual: Error Cannot set the value of security transactions using the dialog for modifying multiple transactions. Financial security (e.g. stock, mutual fund) Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name); Financial security (e.g. stock, mutual fund) Cannot change payer of dividends and security transactions. Financial security (e.g. stock, mutual fund) Cannot change date, description, expense category or payee of transactions that are part of a debt payment using the dialog for modifying multiple transactions. Referring to the transaction description property (transaction title/generic article name) Cannot change date of transactions that are part of a split transaction, unless all individual transactions are selected. Delete transactions? ¿Eliminar transacciones? Are you sure you want to delete all (%1) transactions in the selected split transaction? ¿Está seguro de que desea eliminar todas (%1) las transacciones pertenecientes a la transacción dividida? Join as multiple accounts/payments? Do you wish join the selected expenses as an expense with multiple accounts/payments? Do you wish join the selected incomes as an income with multiple accounts/payments? Are you sure you want to delete all (%1) selected transactions? ¿Esta seguro de que quiere eliminar todas (%1) las transacciones seleccionadas? * Part of <a href="%1">split transaction</a> * Parte de la <a href="%1">transacción dividida</a> * Part of split transaction * Parte de la transacción dividida * Part of split (%1) * Parte (%1) del corte ** Recurring (editing occurrence) Modify… Modificar… Edit… Editar… Eqonomize-1.5.3/translations/eqonomize_fr.ts000066400000000000000000020510671416454732000212750ustar00rootroot00000000000000 Balancing solde kde-format Couldn't open %1 for reading Impossible d'ouvrir %1 en lecture kde-format Not a valid Eqonomize! file (XML parse error: "%2" at line %3, col %4) Fichier Eqonomize! non valide (Erreur d'analyse XML: "%2" à la ligne %3, col %4) kde-format Invalid root element %1 in XML document L'élément racine %1 du document XML est invalide kde-format Unable to load 1 account. Impossible de charger 1 compte. Impossible de charger %n comptes. kde-format Unable to load %n accounts. Unable to load 1 category. Impossible de charger 1 catégorie. Impossible de charger %n catégories. kde-format Unable to load %n categories. Unable to load 1 security. Impossible de charger 1 sécurité. Impossible de charger %n sécurités. kde-format Unable to load %n securities. Unable to load 1 transaction. Impossible de charger 1 transaction. Impossible de charger %n transactions. kde-format Unable to load %n transactions. File is a directory Le fichier est un répertoire kde-format Couldn't open file for writing Impossible d'ouvrir le fichier en écriture kde-format Error while writing file; file was not saved Erreur lors de l'enregistrement ; fichier non sauvegardé kde-format From De kde-format To A kde-format Source: Source: kde-format All Expenses Toutes les dépenses kde-format All Incomes Tous les revenus kde-format All Accounts Tous les comptes kde-format Expenses: %1 Dépenses: %1 kde-format Incomes: %1 Revenus: %1 kde-format Invalid date. Date invalide. kde-format To date is before from date. La date est antérieure à la date visée kde-format From date is after to date. La date est postérieure à la date visée kde-format The selected file already exists. Would you like to overwrite the old copy? Le fichier existe déjà. Voulez-vous réécrire par dessus l'ancien fichier? kde-format You selected a directory! Vous avez sélectionné un répertoire! kde-format Couldn't open file for writing. Impossible d' ouvrir le fichier en écriture. kde-format Error while writing file; file was not saved. Erreur lors de l' écriture du fichier ; fichier non sauvegardé. kde-format No description Pas de description kde-format All Categories Toutes les catégories kde-format Descriptions for Descriptions pour kde-format Payees/payers for Bénéficiaires/Débiteurs pour kde-format Period: Période: kde-format Columns: Colonnes: kde-format Value Valeur kde-format Daily Journalier kde-format Monthly Mensuel kde-format Yearly Annuel kde-format Quantity Quantité kde-format Average value Valeur moyenne kde-format All descriptions Toutes les descriptions kde-format All payees Tous les bénéficiaires kde-format All payers Tous les débiteurs kde-format No payee Pas de bénéficiaire kde-format No payer Pas de débiteur kde-format Expenses: %2, %1 Dépenses: %2, %1 kde-format Incomes: %2, %1 Revenus: %2, %1 kde-format Incomes & Expenses Revenus & Dépenses kde-format %1 (%2&ndash;%3) html format; %1: title; %2: from date; %3: to date %1 (%2&ndash;%3) kde-format %1 (to %2) html format; %1: title; %2: to date %1 (to %2) kde-format Category Catégorie kde-format Cost Coût kde-format Income Revenu kde-format Daily Average Moyenne journalière kde-format Monthly Average Moyenne mensuelle kde-format Yearly Average Moyenne annuelle kde-format Average Cost Coût moyen kde-format Average Income Revenu moyen kde-format Average Value Valeur moyenne kde-format Total Total kde-format Total incomes Revenus totaux kde-format Total expenses Dépenses totales kde-format Total (Profits) Total (Profits) kde-format Expense Dépense kde-format Transfer Transfère kde-format Security Buy Achat de titres kde-format Security Sell Vente de titres kde-format Recurrence Récurrence kde-format New Expense Nouvelle dépense kde-format New Dividend Nouveau dividende kde-format New Income Nouveau revenu kde-format New Transfer Nouveau transfert kde-format New Security Buy Nouvel achat de titres kde-format New Security Sell Nouvelle vente de titres kde-format Edit Expense Éditer la dépense kde-format Edit Dividend Éditer le dividende kde-format Edit Income Éditer le revenu kde-format Edit Transfer Éditer le transfert kde-format Edit Securities Bought Éditer les titres achetés kde-format Edit Securities Sold Éditer les titres vendus kde-format Dividend Dividende kde-format Repayment Remboursement kde-format Refund Rembourser kde-format Split Transaction Transaction séparée kde-format Description: Description: kde-format Date: Date: kde-format Account: Compte: kde-format Transactions: Transactions: kde-format Type Type kde-format Description Description kde-format Account/Category Compte/Catégorie kde-format Payment Paiement kde-format Deposit Dépôt kde-format New Nouveau kde-format New Expense… Nouvelle dépense… kde-format New Income… Nouveau revenu… kde-format New Deposit… Nouveau dépôt… kde-format New Withdrawal… Nouveau retrait kde-format New Security Shares Bought… Parts achetées… kde-format New Dividend… Nouveau dividende kde-format Edit… Éditer… kde-format Total value: Valeur totale: kde-format No suitable account available. Pas de compte approprié disponible kde-format Future dates is not allowed. Les dates futures ne sont pas permises. kde-format A split must contain at least two transactions. Une séparation doit contenir au moins deux transactions. kde-format Cannot transfer money to and from the same account. Impossible de transférer de l'argent de et vers le même compte. kde-format Cost: Coût: kde-format Income: Revenu: kde-format Quantity: Quantité: kde-format Comments: Commentaires: kde-format Reinvested Dividend Réinvestir le dividende kde-format Security: Titre: kde-format Shares added: Parts ajoutées: kde-format Security Trade Vente de titres kde-format From security: Titre de: kde-format Shares moved: Parts transférées: kde-format All Tout kde-format To security: Vers le titre: kde-format Shares received: Parts reçues: kde-format Value: Valeur: kde-format No other security available for trade in the account. Pas d'autre titre disponible pour la vente dans ce compte. kde-format Zero shares not allowed. Zéro partages non autorisé. kde-format Zero value not allowed. Valeur nulle non autorisée. kde-format Quotations Devis kde-format Date Date kde-format Price per Share Prix par part kde-format Quotations for %1 Quotations pour %1 kde-format The following transactions was scheduled to occur today or before today. Confirm that they have indeed occurred (or will occur today). Les transactions suivantes étaient prévues pour se dérouler aujourd'hui ou avant aujourd'hui. Veuillez confirmer qu'elles se sont déroulées (ou vont se dérouler aujourd'hui). kde-format Amount Montant kde-format Postpone… Ajourner… kde-format Can only postpone to future dates. Opération remise à plus tard. kde-format Transactions for %1 Transactions pour %1 kde-format Shares Parts kde-format Shares Bought Parts achetées kde-format Shares Sold Parts vendues kde-format Shares Sold (Traded) Parts vendues (Ventes) kde-format Shares Bought (Traded) Parts achetées (Ventes= kde-format Shares Bought (Recurring) Parts achetées (Récurrentes) kde-format Shares Sold (Recurring) Parts vendues (Récurrentes) kde-format Shares Bought (Scheduled) Parts achetées (planifiées) kde-format Shares Sold (Scheduled) Parts vendues (planifiées) kde-format Recurring Dividend Dividende récurrent kde-format Scheduled Dividend Dividende planifié kde-format Type: Type: kde-format Mutual Fund Fond mutuel kde-format Bond Obligation kde-format Stock Stock kde-format Other Autre kde-format Name: Nom: kde-format Decimals in Shares: Décimales des parts: kde-format Initial Shares: Parts initiales: kde-format Initial quotation: Citation initiale: kde-format No suitable account or income category available. Aucune catégorie de compte ou de revenu appropriée. kde-format Cash Liquide kde-format Current Account Compte courant kde-format Savings Account Compte d'épargne kde-format Credit Card Carte de crédit kde-format Liabilities Dettes kde-format Securities Titres kde-format Initial balance: Équilibre initial: kde-format Default account for budgeted transactions Compte par défaut pour les transactions planifiées kde-format Empty name. Nom vide. kde-format The entered name is used by another account. Le nom saisi est déjà utilisé par un autre compte. kde-format Monthly budget: Budget mensuel: kde-format The entered name is used by another income category. Le nom saisi est utilisé par une autre catégorie de revenus. kde-format The entered name is used by another expense category. Le nom saisi est utilisé par une autre catégorie de dépenses. kde-format Accounts Comptes kde-format Accounts & Categories Comptes et Catégories kde-format Expenses Dépenses kde-format Incomes Revenus kde-format Transfers Transferts kde-format Schedule Planning kde-format Scheduled Transactions Transactions planifiées kde-format Account / Category Compte / Catégorie kde-format Remaining Budget (%1) Budget prévisionnel (%1) kde-format Change (%1) Change (%1) kde-format Total (%1) Total (%1) kde-format %2 of %1 %2 remains of %1 budget %2 de %1 kde-format Includes budgeted transactions Inclut les transactions planifiées kde-format Period Période kde-format Select Period Période sélectionnée kde-format Current Month Mois actuel kde-format Current Year Année actuelle kde-format Current Whole Month Mois entier actuel kde-format Current Whole Year Année entière actuelle kde-format Whole Past Month Mois passé entier kde-format Whole Past Year Année passée entière kde-format Previous Month Mois précédent kde-format Previous Year Années précédente kde-format Show partial budget Afficher le budget partiel kde-format Edit Budget Éditer le budget kde-format Budget: Budget: kde-format Month: Mois: kde-format Result previous month: Résultat du mois précédent: kde-format New Security… Nouveau titre… kde-format New Transaction Nouvelle transaction kde-format Set Quotation… Mettre une quotation… kde-format Name Nom kde-format Quotation Quotation kde-format Profit Profit kde-format Yearly Rate Taux annuel kde-format Account Compte kde-format Statistics Period Statistiques de la période kde-format New Schedule Nouvelle plannification kde-format Edit Éditer kde-format Next Occurrence Occurrence suivante kde-format Comments Commentaires kde-format New Security Nouveau titre kde-format Edit Security Éditer le titre kde-format Profit: Profit: kde-format Rate: Taux: kde-format Are you sure you want to delete the security "%1" and all associated transactions? Êtes-vous certain de vouloir supprimer le titre "%1" et toutes les transactions associées? kde-format No security available. Aucune garantie disponible kde-format Set Quotation (%1) Mettre la Quotation (%1) kde-format Price per share: Prix par part: kde-format Future dates are not allowed. Les dates futures ne sont pas permises. kde-format Security Transactions Transactions de titres kde-format Ledger Registre kde-format Check Account Vérifier le compte kde-format Salary Salaire kde-format Bills Factures kde-format Clothing Habillement kde-format Groceries Alimentation kde-format Leisure Loisir kde-format Couldn't fetch %1. Ne peut pas retrouver %1. kde-format Error loading %1: %2. Erreur lors du chargement de %1: %2. kde-format Couldn't open file Impossible d' ouvrir le fichier kde-format Error saving %1: %2. Erreur lors de l'enregistrement de %1: %2. kde-format Couldn't save file Impossible d'enregistrer le fichier kde-format Failed to upload file to %1. Impossible de charger le fichier sur %1. kde-format Report Rapport kde-format Chart Diagramme kde-format Transaction Schedule Planning de la transaction kde-format Accounts &amp; Categories html format Comptes &amp; Catégories kde-format Accounts &amp; Categories (%1&ndash;%2) html format Comptes &amp; Catégories (%1&ndash;%2) kde-format Accounts &amp; Categories (to %1) html format Comptes &amp; Catégories (to %1) kde-format Change Change kde-format Balance Équilibre kde-format Budget Budget kde-format Remaining Budget Budget prévisionnel kde-format Total Incomes Revenus totaux kde-format Costs Coûts kde-format Total Expenses Dépenses totales kde-format Empty expenses list. Liste des dépenses vide. kde-format Empty incomes list. Liste des revenus vide. kde-format Empty transfers list. Liste des transferts vide. kde-format Empty securities list. Liste des titres vides. kde-format Empty schedule list. Liste des plannings vide. kde-format Export View… Exporter la vue… kde-format Print View… Imprimer la vue… kde-format Remember Last Dates Se souvenir des dernières dates kde-format Import CSV File… Importe un fichier CSV… kde-format Import QIF File… Importer un fichier QIF… kde-format Export As QIF File… Exporter un fichier QIF… kde-format Add Account… Ajouter un compte… kde-format New Account… Nouveau compte… kde-format New Income Category… Nouvelle catégorie de revenu… kde-format New Expense Category… Nouvelle catégorie de dépense… kde-format Balance… Équilibre… kde-format Show Transactions Montrer les transactions kde-format New Transfer… Nouveau transfert… kde-format New Split Transaction… Nouveau transaction séparée… kde-format Edit Transaction(s) (Occurrence)… Éditer la/les transaction(s) (Occurrence)… kde-format Edit Occurrence… Éditer l'occurrence… kde-format Edit Schedule (Recurrence)… Éditer le(s) planning(s) (Occurrence)… kde-format Edit Schedule… Éditer le planning… kde-format Remove Transaction(s) (Occurrence) Enlever la/les transaction(s) (Occurrence) kde-format Remove Occurrence Enlever l' occurrence kde-format Delete Schedule (Recurrence) Supprimer le(s) plannings (Récurrence) kde-format Delete Schedule Supprimer le planning kde-format Edit Split Transaction… Editer une transaction séparée… kde-format Remove Split Transaction Déplacer la transaction séparée kde-format Join Transactions… Lier les transactions… kde-format Split Up Transaction Transaction décomposée kde-format Refund… Rembourser… kde-format Repayment… Remboursement… kde-format New Refund/Repayment… Nouveau remboursement… kde-format Edit Security… Éditer le titre… kde-format Remove Security Enlever le titre kde-format Shares Sold… Parts vendues… kde-format Shares Bought… Parts achetées… kde-format Dividend… Dividende… kde-format Reinvested Dividend… Dividende réinvesti… kde-format Shares Moved… Parts bougées… kde-format Edit Quotations… Éditer les quotations kde-format Transactions… Transactions… kde-format Development Over Time Report… Rapport de développement temporel… kde-format Categories Comparison Report… Rapport de comparaison de catégories… kde-format Categories Comparison Chart… Diagramme de comparaison de catégories… kde-format Development Over Time Chart… Diagramme de développement temporel… kde-format Use Additional Transaction Properties Utiliser les paramètres de transaction additionnel kde-format Eqonomize! exited unexpectedly before the file was saved and data was lost. Do you want to load the last auto-saved version of the file? Eqonomize! est quitté sans consentement avant que le fichier ne soit sauvé et les données ont été perdues. Voulez vous charger la dernière version sauvée automatiquement du fichier? kde-format Crash Recovery Récupération de l'accident kde-format The current file has been modified. Do you want to save it? Le fichier courant a été modifié. Voulez-vous l'enregistrer? kde-format Confirm Schedule Confirmer le planning kde-format New Account Nouveau compte kde-format New Income Category Nouvelle catégorie de revenus kde-format New Expense Category Nouvelle catégorie de dépenses kde-format Balance Account Équilibre du compte kde-format Book value: Valeur comptable: kde-format Real value: Valeur réelle: kde-format Edit Account Editer le compte kde-format Edit Income Category Éditer les catégories de revenus kde-format Edit Expense Category Éditer les catégories de dépenses kde-format Move transactions? Bouger les transactions? kde-format Move to: Bouger vers: kde-format The category contains some expenses. What do you want to do with them? La catégorie contient quelques dépenses. Que voulez-vous faire d'elles? kde-format The category contains some incomes. What do you want to do with them? La catégorie contient quelques revenus. Que voulez-vous faire d'eux? kde-format The account contains some transactions. What do you want to do with them? Ce compte contient plusieurs transactions. Que voulez vous en faire ? kde-format The category contains some expenses that will be removed. Do you still want to remove the category? La catégorie contient quelques dépenses qui seront enlevées. Voulez-vous toujours enlever cette catégorie? kde-format Remove Category? Enlever la catégorie? kde-format The category contains some incomes that will be removed. Do you still want to remove the category? La catégorie contient quelques revenus qui seront supprimés. Voulez-vous toujours enlever cette catégorie? kde-format The account contains some transactions that will be removed. Do you still want to remove the account? Ce compte contient plusieurs transactions qui seront enlevées. Voulez vous toujours enlever ce compte ? kde-format Remove Account? Enlever le compte? kde-format %2 of %1 %1: budget; %2: remaining budget %2 de %1 kde-format %1 (with no budget) %1 (sans budget) kde-format %1 (with budget %2) %1 (avec le budget %2) kde-format Import CSV file Importer le fichier CSV kde-format Transaction Type Selection Choix du type de transaction kde-format Expenses and incomes (negative cost) Dépenses et revenus (coût négatif) kde-format Expenses and incomes (separate columns) Dépenses et revenus (colonnes séparées) kde-format All types Tous types kde-format File Selection Sélection de fichier kde-format File: Fichier: kde-format First data row: Première colonne de données: kde-format Auto Voiture kde-format Column delimiter: Délimiteur de colonne: kde-format Comma Virgule kde-format Tabulator Tabulation kde-format Semicolon Point virgule kde-format Space Espace kde-format Columns Specification Spécification de la colonne kde-format Column Colonne kde-format Category: Catégorie: kde-format From account: Compte de: kde-format Create missing categories and accounts Crée les comptes et catégories manquante kde-format Imports data as expenses. Costs have positive value. Value is the only required column. Importe les données comme des dépenses. Les coûts ont une valeur positive. Le valeur est la seule colonne requise. kde-format Imports data as incomes. Value is the only required column. Importe les données comme des revenus. Value est la seule colonne requise. kde-format To account: Vers le compte: kde-format Imports data as transfers. Value is the only required column. Importer les données comme des transferts. Value est la seule colonne requise. kde-format Amount: Quantité: kde-format Imports data as expenses and incomes. Costs have negative value. Value and category are both required columns. Importe les données comme des dépenses et des revenus. Les coûts ont une valeur négative. La valeur et la catégorie sont les seules colonnes requises. kde-format Imports data as expenses and incomes. Costs and incomes have separate columns. Income, cost, and category are all required columns. Importe les données comme des dépenses et des revenus. Les coûts ont des colonnes séparées. Revenus, coût, et la catégorie sont les seules colonnes requises. kde-format Imports data as expenses, incomes, and transfers. Costs have negative or positive value. Value, to, and from are all required columns. Accounts and categories must be existing. Importe les données comme dépenses, revenus et transferts. Les coûts ont une valeur négative ou positive. Toutes les valeurs sont requises. Comptes et catégories doivent exister. kde-format From: De: kde-format To: A: kde-format A file must be selected. Vous devez sélectionner un fichier. kde-format Selected file is a directory. Le fichier sélectionné est un dossier. kde-format Selected file does not exist. Le fichier sélectionné n'existe pas. kde-format Empty delimiter. Délimiteur vide. kde-format The same column number is selected multiple times. Le même numéro de colonne est sélectionné plusieurs fois. kde-format Selected from account is the same as the to account. Le compte de destination est le même que le compte source. kde-format Couldn't open %1 for reading. Impossible d' ouvrir le fichier %1 en lecture. kde-format Error reading %1. Erreur lors de la lecture de %1. kde-format Successfully imported 1 transaction. 1 transaction importée avec succès. %n transactions importées avec succès. kde-format Successfully imported %n transactions. Unable to import any transactions imported. Impossible d'enregistrer les transactions importées. kde-format Failed to import 1 data row. Echec à l'importation de une donnée. Echec à l'importation de %n données. kde-format Failed to import %n data rows. Required columns missing. Les colonnes nécessaires sont manquantes. kde-format Invalid value. Valeur invalide. kde-format Empty category name. Nom de catégorie vide. kde-format Empty account name. Nom de compte vide. kde-format Unknown category found. Catégorie inconnue trouvée. kde-format Unknown account found. Compte inconnu trouvé. kde-format Cannot import security transactions (to/from security accounts). Impossible d'importer les transaction de titre (comptes A/De) kde-format Balancing account wrongly used. Equilibrage des comptes mal utilisé. kde-format Same to and from account/category. Même De et A compte/catégorie kde-format No data found. Pas de donnée trouvée. kde-format Unrecognized date format. Format de date non reconnu. kde-format Specify Format Format spécifié kde-format The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. Le format des dates et/ou nombres dans le fichier CSV est ambigu. S'il vous plaît sélectionner le format correct. kde-format Date format: Format de date: kde-format Value format: Format de valeur: kde-format tomorrow the day after today demain kde-format today this day aujorud'hui kde-format yesterday the day before today hier kde-format &Today @option today Aujorud'hui kde-format To&morrow @option tomorrow Demain kde-format Export… Exporter… kde-format Print… Imprimer… kde-format Withdrawal Retrait kde-format Join… Lier… kde-format Split Up Décomposer kde-format Are you sure you want to delete all (%1) selected transactions? Êtes-vous certain de vouloir supprimer toutes (%1) les transactions sélectionnées? kde-format Cannot set the value of security transactions using the dialog for modifying multiple transactions. Impossible de fixer la valeur des transactions de titre en utilisant la fenêtre de modification multiple des transactions. kde-format Cannot change description of dividends and security transactions. Impossible de changer la description des dividendes et transactions de titre. kde-format Cannot change payer of dividends and security transactions. Impossible de changer le débiteur des dividendes et transactions de titres. kde-format Cannot change date of transactions that are part of a split transaction. Impossible de dater les transactions qui font parti d'une transaction séparée. kde-format Eqonomize! Eqonomize! A personal accounting program Un programme personnel de finance Start with expenses list displayed Commencer avec la liste des dépenses montrée Start with incomes list displayed Commencer avec la liste des revenus montrée Start with transfers list displayed Commencer avec la liste des transferts montrée Document to open Document à ouvrir Incomes and Expenses Revenus et Dépenses kde-format Profits Profits kde-format All Categories Combined Toutes les catégories combinées kde-format All Descriptions Combined Toutes les descriptions combinées kde-format All Payees/Payers Combined Tous les bénéficiaires/débiteurs combinés kde-format Start date: Date de départ: kde-format Monthly total Total mensuel kde-format Daily average Moyenne journalière kde-format All Payers Combined Tous les débiteurs combinés kde-format All Payees Combined Tous les bénéficiaires combinés kde-format All Descriptions Split Toutes les descriptions séparées kde-format All Payers Split Tous les débiteurs séparés kde-format All Payees Split Tous les bénéficiaires séparés kde-format All Categories Split Toutes les catégories séparées kde-format Value (%1) Valeur (%1) kde-format Profit (%1) Profit (%1) kde-format Income (%1) Revenu (%1) kde-format Cost (%1) Coût (%1) kde-format Time Temps kde-format no payer aucun débiteur kde-format %1/%2 %1: Description; %2: Payer %1/%2 kde-format no payee aucun bénéficiaire kde-format %1/%2 %1: Description; %2: Payee %1/%2 kde-format Error after saving file; data may not have been saved. Erreur après l'enregistrement du fichier ; des données peuvent avoir été perdues. kde-format Average Profit Profit moyen kde-format Year Année kde-format Month Mois kde-format Includes scheduled transactions Inclut les transactions planifiées kde-format Adjusted for the average month / year (%1 / %2 days) Ajusté pour le mois/annér moyen (%1 / %2 jours) kde-format Subtotal Sous-total kde-format Unnamed Anonyme kde-format Uncategorized N'est pas catégorisé kde-format Import QIF file Importer le fichier QIF kde-format Select a QIF file to import. When you click next, the file be analysed and you might need to answer some questions about the format of the file. Sélectionner un fichier QIF pour l'importation. Quand vous cliquez sur prochain, le fichier sera analysé et vous pourrez devoir répondre à des questions sur le format du fichier. kde-format Local Definitions Définitions locales kde-format Unknown elements where found in the QIF file. It is possible that this is because of localized type names. Please map them to the correct standard names. Le fichier QIF présente des éléments inconnus. Cela est certainement du à l'utilisation de caractères locaux. Veuillez les remplacer par des caractères standards. kde-format Local Text Texte local kde-format Standard Text Texte standard kde-format Select standard text: Sélectionner un texte standard: kde-format Date Format Format de date kde-format The date format in the QIF file is ambiguous. Please select the correct format. Le format de date dans le fichier QIF est ambigu. S'il vous plaît sélectionner le format correct. kde-format Default Account Compte par défaut kde-format Could not find any account definitions in the QIF file. Please select a default account. It is also possible that this is caused by a localized opening balance text. Impossible de trouver les définitions de compte dans le fichier QIF. S'il vous plaît sélectionner un compte par défaut. Il est également possible que cela soit du au solde ouvert traduit en français. kde-format Default account: Compte par défaut: kde-format Opening balance text: Texte du solde ouvert: kde-format Descriptions Descriptions kde-format Transactions in QIF files does not have any specific description property. You are therefore given the option to choose how the description of imported transactions will be set. Les transactions dans les fichiers QIF n'ont pas de propriétés de description spécifique. C'est pourquoi vous allez donner l'option pour définir comment la description des transactions importées sera établie. kde-format Subcategories as: Sous-catégories de: kde-format Ignore Ignorer kde-format Payee as: Bénéficiaire de: kde-format Payee Bénéficiaire kde-format Memo as: Note de: kde-format Priority: Priorité: kde-format Subcategory/Payee/Comments Sous-catégorie/Bénéficiaire/Commentaires kde-format Payee/Subcategory/Comments Bénéficiaire/Sous-Catégorie/Commentaires kde-format Subcategory/Comments/Payee Sous-Catégorie/Commentaires/Bénéficiaire kde-format Payee/Comments/Subcategory Bénéficiaire/Commentaires/Sous-Catégorie kde-format Comments/Subcategory/Payee Commentaires/Sous-Catégorie/Bénéficiaire kde-format Comments/Payee/Subcategory Commentaires/Bénéficiaire/Sous-Catégorie kde-format Unknown Inconnu kde-format Bank Banque kde-format Cat (Category) Cat (Catégorie) kde-format CCard (Credit Card) CCard (Carte de crédit) kde-format Invst (Investment) Invest (Investissement) kde-format Oth A (Other Assets) Oth A (Other Assets = autres actifs) kde-format Security Titre kde-format Successfully imported 1 account. 1 compte importé avec succès. %n comptes importés avec succès. kde-format Successfully imported %n accounts. Successfully imported 1 category. 1 catégorie importée avec succès. %n catégories importées avec succès. kde-format Successfully imported %n categories. 1 duplicate transaction was ignored. 1 transaction dupliquée a été ignorée. %n transactions dupliquées ont été ignorées. kde-format %n duplicate transactions was ignored. Failed to import 1 transaction. Echec à l'importation d'1 transaction. Echec à l'importation de %n transactions. kde-format Failed to import %n transactions. Export QIF File Exporter le fichier QIF kde-format All All accounts Tout kde-format Export transaction description as: Exporter la description de la transaction comme: kde-format Memo Mémo kde-format Subcategory Sous-catégorie kde-format &Import i18n: tag text i18n: file ./eqonomizeui.rc line 5 &Importer kde-format &Accounts i18n: tag text i18n: file ./eqonomizeui.rc line 12 &Comptes kde-format &Transactions i18n: tag text i18n: file ./eqonomizeui.rc line 24 &Transactions kde-format &Securities i18n: tag text i18n: file ./eqonomizeui.rc line 41 &Titres kde-format Stat&istics i18n: tag text i18n: file ./eqonomizeui.rc line 56 Stat&istiques kde-format Your names NAME OF TRANSLATORS Jérôme Rapinat, Antoine Rodriguez,,Launchpad Contributions:,Marie-Lise Issoire, Nicolas Velin, Perrine, romjerome kde-format Your emails EMAIL OF TRANSLATORS gnupower@hotmail.fr, antoiner@gmail.com,,,,nicolas@velin.fr,,gnupower@hotmail.fr kde-format Edit Exceptions Éditer les exceptions kde-format Edit Recurrence Range Éditer les marges de récurrence kde-format Begins on: %1 Commence sur : %1 kde-format No ending date Pas de date de fin kde-format End after Fin après kde-format occurrence(s) occurrence(s) kde-format End on Fin le kde-format End date before start date. Date de fin avant la date de départ kde-format Enable recurrence Autoriser les récurrences kde-format Recurrence Rule Règle de récurrence kde-format Weekly hebdomadaire kde-format Recur every Se produit tous les kde-format day(s) jour(s) kde-format week(s) on: semaine(s) sur: kde-format month(s), after the start month mois(s), après le mois de départ kde-format Recur on the Se produit le kde-format 1st 1er kde-format 2nd 2ème kde-format 3rd 3ème kde-format 4th 4ème kde-format 5th 5ème kde-format 6th 6ème kde-format 7th 7ème kde-format 8th 8ème kde-format 9th 9ème kde-format 10th 10ème kde-format 11th 11ème kde-format 12th 12ème kde-format 13th 13ème kde-format 14th 14ème kde-format 15th 15ème kde-format 16th 16ème kde-format 17th 17ème kde-format 18th 18ème kde-format 19th 19ème kde-format 20th 20ème kde-format 21st 21ème kde-format 22nd 22ème kde-format 23rd 23ème kde-format 24th 24ème kde-format 25th 25ème kde-format 26th 26ème kde-format 27th 27ème kde-format 28th 28ème kde-format 29th 29ème kde-format 30th 30ème kde-format 31st 31ème kde-format Last Dernier(e) kde-format 2nd Last Avant dernier(e) kde-format 3rd Last 3ème dernier(e) kde-format 4th Last 4ème dernier(e) kde-format 5th Last 5ème dernier(e) kde-format day jour kde-format possibly on weekend si possible le weekend kde-format but before weekend mais avant le weekend kde-format but after weekend mais après le weekend kde-format year(s), after the start year année(s), après l'année de départ kde-format Recur on day part before XXX of 'Recur on day XXX of month YYY' Reste sur le jour kde-format of part between XXX and YYY of 'Recur on day XXX of month YYY' de kde-format On the Part before NNN in 'Recur on the NNN. WEEKDAY of MONTH' Le kde-format of part between WEEKDAY and MONTH in 'Recur on NNN. WEEKDAY of MONTH' de kde-format Recur on day # Se produit le jour # kde-format of the year part after NNN of 'Recur on day #NNN of the year' de l'année kde-format Range… Intersection… kde-format Exceptions… Exceptions… kde-format No day of week selected for weekly recurrence. Pas de jour de semaine sélectionné pour la récurrence hebdomadaire. kde-format Selected day will never occur with selected frequency and start date. Le jour sélectionné ne se produira jamais avec la fréquence et la date de départ sélectionnées. kde-format Selected day does not exist in selected month. Le jour sélectionné n'existe pas dans le mois sélectionné. kde-format Dividend: %1 Dividende: %1 kde-format Account balancing Equilibrage du compte kde-format Security: %1 (bought) Titre: %1 (acheté) kde-format Security: %1 (sold) Titre: %1 (vendu) kde-format Shares bought: Parts achetées: kde-format Shares sold: Parts vendues: kde-format Payer: Débiteur: kde-format Payee: Bénéficiaire: kde-format No income category available. Pas de catégorie de revenu disponible kde-format No expense category available. Pas de catégorie de dépense disponible kde-format Cannot create a regular transfer to/from a securities account. Impossible de créer un transfert régulier de/vers un compte de titres. kde-format Cannot create a regular income to a securities account. Impossible de créer un revenu régulier vers un compte de titres. kde-format Zero price per share not allowed. Prix zéro par part non autorisé. kde-format Cannot create a regular expense from a securities account. Impossible de créer une dépense régulière à partir d' un compte de titres. kde-format Modify Transactions Modifier les transactions kde-format Min amount: Montant min: kde-format Max amount: Montant max: kde-format Min income: Revenu min: kde-format Max income: Revenu max: kde-format Min cost: Coût min: kde-format Max cost: Coût max: kde-format Include Inclut kde-format Exclude Exclut kde-format From Account Du compte kde-format To Account Vers le compte kde-format Payer Créditeur kde-format New/Edit %1 Crée/modifie %1 kde-format Filter Filtre kde-format Total: Total: kde-format Average: Moyenne: kde-format Monthly: Mensuel: kde-format Total cost: Coût total: kde-format Total income: Revenu total: kde-format Total amount: Quantité totale: kde-format Monthly average: Moyenne mensuelle: kde-format Are you sure you want to delete all (%1) transactions in the selected split transaction? Êtes-vous certain de vouloir supprimer toutes les (%1) transactions sélectionnées comme transaction séparée? kde-format * Part of split transaction * partie de la transaction séparée kde-format * Part of split (%1) * Partie de la séparation (%1) kde-format ** Recurring (editing occurrence) ** Se reproduit (éditer l' occurrence) kde-format Modify… Modifier… kde-format AccountComboBox New account… Nouveau compte… Multiple accounts/payments… Comptes/payements multiples... New income category… Nouvelle catégorie de revenu… New expense category… Nouvelle catégorie de dépense… Paid with loan… New Account Nouveau compte New Income Category Nouvelle catégorie de revenus New Expense Category Nouvelle catégorie de dépenses AccountsMenu All Accounts Tous les comptes All Categories Combined Toutes les catégories combinées %n accounts %n compte %n comptes %n categories %n catégorie %n catégories Balancing Account balancing Equilibrage du compte Account balancing Balancing of an account Equilibrage du compte Account Balance Adjustment Ajustement du solde du compte Budget Balancing Solde Balancing Name of account for transactions that adjust account balances Équilibrage Balancing Account Name of account for transactions that adjust account balances Compte d'équilibrage Couldn't open %1 for reading Impossible d'ouvrir %1 en lecture Not a valid Eqonomize! file (XML parse error: "%1" at line %2, col %3) Fichier Eqonomize! non valide (Erreur d'analyse XML: "%1" à la ligne %2, col %3) Invalid root element %1 in XML document L'élément racine %1 du document XML est invalide Unknown XML element: "%1" at line %2, col %3 XML parse error: "%1" at line %2, col %3 European Euro Euro Unable to load %n currency/currencies. Impossible de charger %n monnaie‧s. No exchange rates found. USD currency missing. Monnaie USD manquante. imported importé Unable to load %n account(s). Impossible de charger %n compte. Impossible de charger %n comptes. Unable to load %n category/categories. Impossible de charger %n catégorie. Impossible de charger %n catégories. Unable to load %n security/securities. Financial security (e.g. stock, mutual fund) Impossible de charger %n titre. Impossible de charger %n titres. Download command (%1) failed: %2. Failed to download file from %1: %2. Upload command (%1) failed: %2. yyyy-yy Financial year when first month is not January (e.g. 2018-19). Transaction Accounts Comptes courants Savings Accounts Comptes d'épargne Credit Cards Cartes de crédit Debts Dettes Securities Financial security (e.g. stock, mutual fund) Titres Cash Liquide Transaction Account Compte courant Savings Account Compte d'épargne Credit Card Carte de crédit Debt Dette Other Autre Unable to load %n security/securities. Impossible de charger %n titre. Impossible de charger %n titres. Unable to load %n transaction(s). Impossible de charger %n transaction. Impossible de charger %n transactions. File is a directory Le fichier est un répertoire Couldn't open file for writing Impossible d'ouvrir le fichier en écriture Error while writing file; file was not saved Erreur lors de l'enregistrement ; fichier non sauvegardé Unnamed Anonyme Uncategorized N'est pas catégorisé CategoriesComparisonChart Save As… Enregistrer sous… Print… Imprimer… From De To A Source: Source: All Expenses Toutes les dépenses All Incomes Tous les revenus Theme: Thème : Chart type: Type de diagramme : Pie Chart Diagramme en secteurs Bar Chart Diagramme bâtons Default Par défaut All Expenses, without subcategories Toutes les dépenses, sans sous-catégories All Expenses, with subcategories Toutes les dépenses, avec les sous-catégories All Incomes, without subcategories Tous les revenus, sans sous-catégories All Incomes, with subcategories Tous les revenus, avec les sous-catégories All Accounts Tous les comptes Expenses: %1 Dépenses: %1 Incomes: %1 Revenus: %1 Error Erreur Invalid date. Date invalide. To date is before from date. La date est antérieure à la date visée. From date is after to date. La date est postérieure à la date visée. Couldn't open file for writing. Impossible d' ouvrir le fichier en écriture. Error while writing file; file was not saved. Erreur lors de l' écriture du fichier ; fichier non sauvegardé. Expenses Dépenses Expenses, %1 Dépenses, %1 Incomes, %1 Revenus, %1 Incomes Revenus Accounts Comptes Expenses, %2: %1 Dépenses, %2: %1 Incomes, %2: %1 Revenus, %2: %1 Other descriptions Referring to the transaction description property (transaction title/generic article name) Autres descriptions No description Referring to the transaction description property (transaction title/generic article name) Pas de description Other accounts Autres comptes Other categories Autres catégories %1 Value: %2 %1 Valeur : %2 No description Referring to the generic description property Pas de nom Value Valeur Income Revenu Cost Coût Value (%1) Valeur (%1) Income (%1) Revenu (%1) Cost (%1) Coût (%1) No description Pas de nom CategoriesComparisonChartDialog Chart Diagramme CategoriesComparisonReport Save As… Enregistrer sous… Print… Imprimer… Source: Source: All Categories, excluding subcategories Toutes les catégories, à l'exclusion sous-catégories All Categories, including subcategories Toutes les catégories, y compris les sous-catégories All Payees/Payers Tous les bénéficiaires/débiteurs Subcategories Sous-catégories All Categories Toutes les catégories Expenses: %1 Dépenses: %1 Incomes: %1 Revenus: %1 Descriptions for Noms pour Payees/payers for Bénéficiaires/Débiteurs pour Descriptions Referring to the Transaction description property (transaction title/generic article name) Descriptions Period: Période: From De To A Columns: Colonnes: Value Valeur Daily Journalier Monthly Mensuel Yearly Annuel Quantity Quantité Average value Valeur moyenne All descriptions Toutes les noms All payees Tous les bénéficiaires All payers Tous les débiteurs No description Pas de nom Descriptions for Referring to the generic description property Noms pour Descriptions Referring to the generic description property Descriptions All descriptions Referring to the generic description property Toutes les noms No description Referring to the generic description property Pas de nom All Payees and Payers Tous les bénéficiaires et débiteurs Tag: %1 Étiquette: %1 All Accounts Tous les comptes Descriptions for Referring to the transaction description property (transaction title/generic article name) Descriptions pour Descriptions Referring to the transaction description property (transaction title/generic article name) Descriptions Months Mois Years Années Tags Étiquettes Total: Total: All descriptions Referring to the transaction description property (transaction title/generic article name) Toutes les descriptions All payees/payers Tous les bénéficiaires/débiteurs No description Referring to the transaction description property (transaction title/generic article name) Pas de description No payee Pas de bénéficiaire No payer Pas de débiteur Error Erreur Invalid date. Date invalide. To date is before from date. La date est antérieure à la date visée. From date is after to date. La date est postérieure à la date visée. Couldn't open file for writing. Impossible d' ouvrir le fichier en écriture. Error while writing file; file was not saved. Erreur lors de l' écriture du fichier ; fichier non sauvegardé. Expenses, %2: %1 Dépenses, %2: %1 Expenses, %3: %2, %1 Dépenses, %3: %2, %1 Incomes, %2: %1 Revenus, %2: %1 Incomes, %3: %2, %1 Revenus, %3: %2, %1 %3: %2, %1 %3: %2, %1 %2: %1 %2: %1 Tags, %1 Étiquettes, %1 Incomes & Expenses, %1 Revenus & Dépenses, %1 Expenses: %2, %1 Dépenses: %2, %1 Incomes: %2, %1 Revenus: %2, %1 %2, %1 %2, %1 %1 %1 Incomes & Expenses Revenus & Dépenses %1 (%2&ndash;%3) html format; %1: title; %2: from date; %3: to date %1 (%2&ndash;%3) %1 (to %2) html format; %1: title; %2: to date %1 (to %2) Category Catégorie Payee Bénéficiaire Description Referring to the transaction description property (transaction title/generic article name) Description Cost Coût Payer Créditeur Income Revenu Payee/Payer Bénéficiaire/créditeur Tag Étiquette Daily Average Moyenne journalière Monthly Average Moyenne mensuelle Yearly Average Moyenne annuelle Average Cost Coût moyen Average Income Revenu moyen Average Value Valeur moyenne No payee/payer Pas de bénéficiaire/créditeur Total Total All Tags Toutes les étiquettes Total incomes Revenus totaux Total expenses Dépenses totales Total (Profits) Total (Profits) CategoriesComparisonReportDialog Report Rapport ConfirmScheduleDialog The following transactions was scheduled to occur today or before today. Confirm that they have indeed occurred (or will occur today). Les transactions suivantes étaient prévues pour se dérouler aujourd'hui ou avant aujourd'hui. Veuillez confirmer qu'elles se sont déroulées (ou vont se dérouler aujourd'hui). Date Date Type Type Description Nom Name Nom Description Generic Description Nom Description Transaction description property (transaction title/generic article name) Description Amount Montant Edit… Éditer… Postpone… Ajourner… Delete Supprimer Error Erreur Can only postpone to future dates. Opération remise à plus tard. ConfirmScheduleListViewItem Transfer Transfère Dividend Dividende Income Revenu Expense Dépense Securities Purchase Financial security (e.g. stock, mutual fund) Achat de titres Securities Sale Financial security (e.g. stock, mutual fund) Vente de titres Security Buy Achat de titres Security Sell Vente de titres Debt Payment Payement de dette CurrencyConversionDialog Currency Converter Convertisseur de monnaie DebtFee Debt payment: %1 (fee) Payement de dette : %1 (frais) DebtInterest Debt payment: %1 (interest) Payement de dette : %1 (intérets) DebtPayment Debt payment: %1 Payement de dette : %1 DebtReduction Debt payment: %1 (reduction) Payement de dette : %1 (réduction) DescriptionsMenu All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) All Tags Combined All Payees Combined Tous les bénéficiaires combinés All Payers Combined Tous les débiteurs combinés All Payees/Payers Combined Tous les bénéficiaires/débiteurs combinés No description Referring to the transaction description property (transaction title/generic article name) No payee Pas de bénéficiaire No payer Pas de débiteur No payee/payer Pas de bénéficiaire/créditeur %n descriptions Referring to the transaction description property (transaction title/generic article name) %n descriptions %n description %n tags %n étiquette %n étiquettes %n payees %n bénéficiaire %n bénéficiaires %n payers %n débiteur %n débiteurs %n payees/payers %n bénéficiaire/débiteur %n bénéficiaires/débiteurs EditAssetsAccountDialog Type: Type: Cash Liquide Current Account Compte courant Savings Account Compte d'épargne Credit Card Carte de crédit Liabilities Dettes Transactional Account Compte courant Debt Dette Securities Titres Other Autre Currency: Monnaie : Edit Éditer Name: Nom: Bank: Banque : Initial balance: Équilibre initial: Debt: Dette : Initial balance Équilibre initial Group: Groupe: no group pas de groupe Transferred to: Transférré vers : Date: Date: Lender: Prêteur : Default account for budgeted transactions Compte par défaut pour les transactions planifiées Description: Description: Account is closed Le compte est fermé Warning Attention Type cannot be changed to securities for accounts with transactions. Issuer: Zero value not allowed. Valeur nulle non autorisée. Error Erreur Transaction Account Compte courant Opening balance: Account balance Solde d'ouverture : Opening balance Account balance Solde d'ouverture New currency… If you change the currency of an account, the currency of all associated transactions will also change, without any conversion. Do do wish to continue anyway? Empty name. Nom vide. The entered name is used by another account. Le nom saisi est déjà utilisé par un autre compte. EditCurrencyDialog Edit Currency New Currency Code: Code : Symbol: Symbole : Prefix Préfixe Suffix Suffixe Default Par défaut Name: Nom : Decimals: Date: Date : Main currency Error Erreur Error saving currencies: %1. Empty code. Code vide. Code already exists. Le code existe déjà. EditDebtPaymentDialog Debt Payment Payement de dette EditDebtPaymentWidget Debt: Dette : Date: Date: Debt reduction: Réduction de dette : Reduction payment: Réduction de payement : Interest: Intérêt : Paid Payé Added to debt Ajouté à la dette Fee: Account: Compte: Expense category: Catégorie de dépenses : Associated file: Fichier associé : Select a file Sélectionnez un fichier Open the file Ouvrir le fichier Comments: Commentaires: Related to: Label for linked transactions Liens: Total value: Valeur totale: Error Erreur No suitable account available. Pas de compte approprié disponible. Invalid date. Date invalide. Interest must not be zero. At least one value must non-zero. EditExceptionsDialog Edit Exceptions Éditer les exceptions Occurrences: Occurrences : Add Exception Ajouter une exception Remove Exception Enlever l'exception Exceptions: Exceptions : Only the first fifty occurrences are shown. Seules les premières cinquante occurences sont visibles. Add Ajouter Apply Appliquer Delete Supprimer Error Erreur Invalid date. Date invalide. EditExpensesAccountDialog Name: Nom: Parent category: Catégorie parente : None Aucun Monthly budget: Budget mensuel: Description: Description: Error Erreur Empty name. Nom vide. The entered name is used by another expense category. Le nom saisi est utilisé par une autre catégorie de dépenses. EditIncomesAccountDialog Name: Nom: Parent category: Catégorie parente : None Aucun Monthly budget: Budget mensuel: Description: Description: Error Erreur Empty name. Nom vide. The entered name is used by another income category. Le nom saisi est utilisé par une autre catégorie de revenus. EditLoanTransactionWidget Date: Date: Account: Compte: Comments: Commentaires: Total value: Valeur totale: Error Erreur Invalid date. Date invalide. EditMultiAccountDialog Expense with Multiple Payments Dépense avec payements multiples Income with Multiple Payments Revenu avec payements multiples EditMultiAccountWidget Description: Description: Description: Generic Description Description: Description: Transaction description property (transaction title/generic article name) Description : Quantity: Quantité: Category: Catégorie: Tags: Étiquettes: Associated file: Fichier associé : Select a file Sélectionnez un fichier Open the file Ouvrir le fichier Comments: Commentaires: Related to: Label for linked transactions Liens: Transactions: Transactions: Date Date Account Compte Payee Bénéficiaire Payer Créditeur Cost Coût Income Revenu Total cost: Coût total: New Tag Nouvelle étiquette Tag: Étiquette: Value Valeur New Nouveau Edit… Éditer… Delete Supprimer Total value: Valeur totale: Error Erreur No suitable expense categories available. A split must contain at least two transactions. Une séparation doit contenir au moins deux transactions. EditMultiItemDialog Split Transaction Transaction séparée EditMultiItemWidget Description: Description: Description: Generic Description Description: Date: Date: Account: Compte: Payee/Payer: Bénéficiaire/créditeur: Transactions: Transactions: Type Type Description: Transaction description property (transaction title/generic article name) Description : Tags: Étiquettes: Associated file: Fichier associé : Select a file Sélectionnez un fichier Open the file Ouvrir le fichier Comments: Commentaires: Related to: Label for linked transactions Liens: Description Transaction description property (transaction title/generic article name) Description Payment Paiement Deposit Dépôt New Nouveau New Expense… Nouvelle dépense… New Income… Nouveau revenu… New Deposit… Nouveau dépôt… New Withdrawal… Nouveau retrait… New Securities Purchase… Financial security (e.g. stock, mutual fund) Nouvel achat de titres… New Securities Sale… Financial security (e.g. stock, mutual fund) Nouvelle vente de titres… Shares Bought… Parts achetées… Shares Sold… Parts vendues… Account/Category Compte/Catégorie Value Valeur Income Revenu Expense Dépense New Dividend… Nouveau dividende… Edit… Éditer… Delete Supprimer Total value: Valeur totale: Error Erreur No suitable account available. Pas de compte approprié disponible. Invalid date. Date invalide. A split must contain at least two transactions. Une séparation doit contenir au moins deux transactions. Cannot transfer money to and from the same account. Impossible de transférer de l'argent de et vers le même compte. EditQuotationsDialog Quotations Devis Date Date Price per Share Prix par part Quotations Financial quotation Devis Quotes Financial quote Cotations Price per Share Financial Shares Prix par part Add Ajouter Modify Modifier Delete Supprimer Import… Importer… Export… Exporter… Quotes for %1 Financial quote Cotations pour %1 Quotations for %1 Financial quotation Quotations pour %1 Quotations for %1 Quotations pour %1 Error Erreur Couldn't open %1 for reading. Impossible d' ouvrir le fichier %1 en lecture. Error reading %1. Erreur lors de la lecture de %1. Successfully imported %n quote(s). %n cotation importé avec succès. %n cotations importé avec succès. Unable to import any quotes. Failed to import %n data row(s). Echec à l'importation de %n donnée. Echec à l'importation de %n données. Required columns missing. Les colonnes nécessaires sont manquantes. Invalid value. Valeur invalide. Invalid date. Date invalide. No data found. Pas de donnée trouvée. Information Information Unrecognized date format. Format de date non reconnu. Specify Format Format spécifié The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. Le format des dates et/ou nombres dans le fichier CSV est ambigu. S'il vous plaît sélectionner le format correct. Date format: Format de date: Value format: Format de valeur: Couldn't open file for writing. Impossible d' ouvrir le fichier en écriture. Quotes: %1 Cotations: %1 Error while writing file; file was not saved. Erreur lors de l' écriture du fichier ; fichier non sauvegardé. EditRangeDialog Edit Recurrence Range Éditer les marges de récurrence Begins on: %1 Commence sur : %1 No ending date Pas de date de fin End after Fin après occurrence(s) occurrence(s) End on Fin le Error Erreur Invalid date. Date invalide. End date before start date. Date de fin avant la date de départ. EditReinvestedDividendDialog Reinvested Dividend Réinvestir le dividende Security: Titre: Shares added: Parts ajoutées: Security: Financial security (e.g. stock, mutual fund) Titre: Shares added: Financial shares Parts ajoutées: Date: Date: Error Erreur Invalid date. Date invalide. EditScheduledDebtPaymentDialog Transaction Transaction Recurrence Récurrence Edit Debt Payment Éditer le payement de dette New Debt Payment Nouveau payement de dette EditScheduledLoanTransactionDialog Recurrence Récurrence EditScheduledMultiAccountDialog Transactions Transactions Recurrence Récurrence New Expense with Multiple Payments Nouvelle dépense avec payements multiples New Income with Multiple Payments Nouveau revenu avec payements multiples Edit Expense with Multiple Payments Éditer la dépense avec payements multiples Edit Income with Multiple Payments Éditer le revenu avec payements multiples EditScheduledMultiItemDialog Transactions Transactions Recurrence Récurrence New Split Transaction Nouveau transaction séparée Edit Split Transaction Editer une transaction séparée EditScheduledTransactionDialog Expense Dépense Dividend Dividende Income Revenu Reinvested Dividend Dividende réinvesti Transfer Transfère Security Buy Achat de titres Security Sell Vente de titres Securities Purchase Financial security (e.g. stock, mutual fund) Achat de titres Securities Sale Financial security (e.g. stock, mutual fund) Vente de titres Recurrence Récurrence New Expense Nouvelle dépense New Expense Paid with Loan New Dividend Nouveau dividende New Income Nouveau revenu New Transfer Nouveau transfert New Securities Purchase Financial security (e.g. stock, mutual fund) Nouvel achat de titres New Reinvested Dividend New Securities Sale Financial security (e.g. stock, mutual fund) Nouvelle vente de titres Edit Reinvested Dividend Edit Securities Purchase Financial security (e.g. stock, mutual fund) Éditer les titres achetés Edit Securities Sale Financial security (e.g. stock, mutual fund) Éditer les titres vendus New Security Buy Nouvel achat de titres New Security Sell Nouvelle vente de titres Edit Expense Éditer la dépense Edit Dividend Éditer le dividende Edit Income Éditer le revenu Edit Transfer Éditer le transfert Edit Securities Bought Éditer les titres achetés Edit Securities Sold Éditer les titres vendus EditSecurityDialog Type: Type: Mutual Fund Fond mutuel Bond Obligation Stock Action Stock Financial stock Action Other Autre Name: Nom: Account: Compte: Decimals in shares: Financial shares Décimales des parts: Initial shares: Financial shares Parts initiales: Decimals in quotes: Financial quote Initial quote: Financial quote Quotation initiale: Empty name. Nom vide. No suitable account available. Pas de compte approprié disponible. Decimals in quotations: Financial quotation Décimales des quotations: Initial quotation: Financial quotation Citation initiale: Decimals in shares: Décimales des parts: Initial shares: Parts initiales: Decimals in quotations: Décimales des quotations: Decimals in Shares: Décimales des parts: Initial Shares: Parts initiales: Initial quotation: Citation initiale: Date: Date: Description: Description: Error Erreur No suitable account or income category available. Aucune catégorie de compte ou de revenu appropriée. EditSecurityTradeDialog Security Trade Vente de titres From security: Titre de: Shares moved: Parts transférées: All Tout To security: Vers le titre: Shares received: Parts reçues: Securities Exchange Financial security (e.g. stock, mutual fund) Vente de titres Securities Exchange Shares of one security directly exchanged for shares of another; Financial security (e.g. stock, mutual fund) Vente de titres From security: Financial security (e.g. stock, mutual fund) Titre de: Shares moved: Financial shares Parts transférées: To security: Financial security (e.g. stock, mutual fund) Vers le titre: Shares received: Financial shares Parts reçues: Value: Valeur: Date: Date: Error Erreur No other security available for exchange in the account. Shares of one security directly exchanged for shares of another; Financial security (e.g. stock, mutual fund) Pas d'autre titre disponible pour la vente dans ce compte. No other security available for exchange in the account. Financial security (e.g. stock, mutual fund) Pas d'autre titre disponible pour la vente dans ce compte. No other security available for trade in the account. Pas d'autre titre disponible pour la vente dans ce compte. Selected to and from securities are the same. Financial security (e.g. stock, mutual fund) Les choix à partir des ou vers les titres sont les mêmes. Zero shares not allowed. Financial shares Zéro partages non autorisé. Selected to and from securities are the same. Les choix à partir des ou vers les titres sont les mêmes. Invalid date. Date invalide. Zero shares not allowed. Zéro partages non autorisé. Zero value not allowed. Valeur nulle non autorisée. EditSplitDialog Split Transaction Transaction séparée Description: Description: Date: Date: Account: Compte: Transactions: Transactions: Type Type Description Description Name: Nom: Name Nom Generic Description: Nom générique: Generic Description Nom générique Description Generic Description Nom Account/Category Compte/Catégorie Payment Paiement Deposit Dépôt New Nouveau New Expense… Nouvelle dépense… New Income… Nouveau revenu… New Deposit… Nouveau dépôt… New Withdrawal… Nouveau retrait… Shares Bought… Parts achetées… Shares Sold… Parts vendues… New Dividend… Nouveau dividende… Edit… Éditer… Delete Supprimer Total value: Valeur totale: Error Erreur No suitable account available. Pas de compte approprié disponible. Invalid date. Date invalide. Future dates is not allowed. Les dates futures ne sont pas permises. A split must contain at least two transactions. Une séparation doit contenir au moins deux transactions. Cannot transfer money to and from the same account. Impossible de transférer de l'argent de et vers le même compte. Eqonomize Accounts && Categories Comptes et Catégories Expenses Dépenses Incomes Revenus Transfers Transferts Transaction Accounts Comptes courants Savings Accounts Comptes d'épargne Credit Cards Cartes de crédit Debts Dettes Securities Titres Schedule Planning Account / Category Compte / Catégorie Remaining Budget (%1) Budget prévisionnel (%1) Change (%1) Change (%1) Total (%1) Total (%1) %2 of %1 %2 remains of %1 budget %2 de %1 Accounts Comptes Includes budgeted transactions Inclut les transactions planifiées Securities Financial security (e.g. stock, mutual fund) Titres Tags Étiquettes Period Période From De To A Select Period Période sélectionnée Current Month Mois actuel Current Year Année actuelle Current Whole Month Mois entier actuel Current Whole Year Année entière actuelle Whole Past Month Mois passé entier Whole Past Year Année passée entière Previous Month Mois précédent Previous Year Années précédente Show partial budget Afficher le budget partiel Edit Budget Éditer le budget Budget: Budget: Month: Mois: Result previous month: Résultat du mois précédent: New Security… Nouveau titre… New Transaction Nouvelle transaction Set Quotation… Mettre une quotation… Name Nom Value Valeur Shares Parts Quotation Cote? Quotation Cost Coût Profit Profit Yearly Rate Taux annuel Type Type Account Compte Statistics Period Statistiques de la période New Schedule Nouvelle plannification Edit Éditer Remove Supprimer Next Occurrence Occurrence suivante Description Description Description Generic Description Nom Amount Montant Payee/Payer Bénéficiaire/créditeur Comments Commentaires Set Schedule Confirmation Time Schedule confirmation time: Set Budget Period First day in budget month: 1st 1er 2nd 2ème 3rd 3ème 4th 4ème 5th 5ème 6th 6ème 7th 7ème 8th 8ème 9th 9ème 10th 10ème 11th 11ème 12th 12ème 13th 13ème 14th 14ème 15th 15ème 16th 16ème 17th 17ème 18th 18ème 19th 19ème 20th 20ème 21st 21ème 22nd 22ème 23rd 23ème 24th 24ème 25th 25ème 26th 26ème 27th 27ème 28th 28ème Last Dernier(e) 2nd Last Avant dernier(e) 3rd Last 3ème dernier(e) 4th Last 4ème dernier(e) 5th Last 5ème dernier(e) Set Quote (%1) Financial quote Mettre la quotation (%1) Stock Financial stock Action Timestamp Horodatage Links Liens Remove Link Supprimer le lien Link to "%1" create link to transaction (link used as verb) Liez à "%1" Link Transaction(s) create link to transaction (link used as verb) Lier la/les transaction(es) All Tout Checking Account Transactional account Compte courant Import Options Ignore duplicate transactions Ignorer les transactions dupliquées Rename duplicate accounts Renommer les comptes dupliqués Rename duplicate categories Renommer les catégories dupliquées Rename duplicate securities Synchronization Settings Paramètres de synchronisation Web address: Adresse web : Download command: Duplicate Transaction… duplicate as verb Dupliquer transaction… Create Link create link to or between transaction(s) Créer lien New Tag… Nouvelle étiquette… Rename Tag… Eenommer l'étiquette… Remove Tag Enlever l'étiquette New Tag Nouvelle étiquette Tag name: Nom de l'étiquette: Remove tag? Enlever l'étiquette? Do you wish to remove the tag "%1" from %n transaction(s)? Rename Tag Eenommer l'étiquette optional optionnel Link Transactions create link between selected transactions (link used as verb) Liez les transactions Create Link to Transaction Créer lien vers la transaction Upload command: mandatory requis Automatic synchronization Synchronisation automatique Upload Téléversement Uploading… Téléversement... Error uploading file Erreur lors du téléversement du fichier Error uploading %1: %2. Erreur lors du téléversement de %1: %2. Synchronizing… Synchronisation... Error synchronizing file Erreur lors de la synchronisation du fichier Error synchronizing %1: %2. Erreur lors de la synchronisation de %1 : %2. Synchronization error Erreur de synchronisation Synchronize file? Synchroniser le fichier ? The file has been modified by a different user or program. Do you wish to merge changes? Le fichier a été modifié par un autre utilisateur ou programme. Voulez vous fusionner les changements ? New version available Nouvelle version disponible A new version of %1 is available.<br><br>You can get version %2 at %3. Une nouvelle version de %1 est disponible.<br><br>Vous pouvez obtenir la version %2 à %3. Abort Avorter First month in budget year: Right align Aligner à droite %f = local file (temporary), %u = url Failed to download exchange rates from %1: %2. Error reading data from %1: %2. Unrecognized Currency No exchange rate is available for the default currency (%1). If you wish to use multiple currencies you should set the exchange rate manually. Set Main Currency Currency: Monnaie : Replace all occurrences of the former main currency Transaction Account Compte courant Import %1 File… Importer %1 fichier... Reconcile Account… Réconcilier compte… Adjust balance… Referring to account balance Régler le solde… Close Account Mark account as closed Fermer le compte New Expense Paid with Loan… Show payee and quantity Montrer bénéficiaire et quantité Show quantity and payer/payee properties for incomes and expenses. Set Schedule Confirmation Time… Select Font… Sélectionner la police… Language Langue Default Par défaut Restart required Only use this when unable to find the cause of the incorrect recorded account balance. Reopen Account Mark account as not closed Réouvrir le compte New Debt Payment… S&ynchronize S&yncroniser New Unpaid Interest… Shares of one security directly exchanged for shares of another Financial shares Use Exchange Rate for Transaction Date Use the exchange rate nearest the transaction date, instead of the latest available rate, when converting the value of transactions. %1 exited unexpectedly before the file was saved and data was lost. Do you want to load the last auto-saved version of the file? Eqonomize! Accounting File Save file? Enregistrer le fichier ? New Loan Adjust Account Balance Régler le solde du compte Balance Account Verb Équilibre du compte Balance Account balance Solde Balance… Balance account Équilibre… Shares Exchanged… Shares of one security directly exchanged for shares of another; Financial shares Parts transférées… Edit Quotes… Financial quote Éditer les cotations… New Security Nouveau titre Edit Security Éditer le titre Total value: Valeur totale: Cost: Coût: Profit: Profit: Rate: Taux: Delete security? Supprimer le titre? Are you sure you want to delete the security "%1" and all associated transactions? Êtes-vous certain de vouloir supprimer le titre "%1" et toutes les transactions associées? Error Erreur No security available. Aucune titre disponible. Set Quotation (%1) Mettre la Quotation (%1) Price per share: Prix par part: Date: Date: Invalid date. Date invalide. Future dates are not allowed. Les dates futures ne sont pas permises. Security Transactions Transactions de titres Bond Obligation Stock Action Mutual Fund Fond mutuel Other Autre Add Loan Add Category Ajouter une catégorie Ledger Registre To date is before from date. La date est antérieure à la date visée. From date is after to date. La date est postérieure à la date visée. Cash Liquide Check Account Vérifier le compte Savings Account Compte d'épargne Salary Salaire Bills Factures Clothing Habillement Groceries Alimentation Leisure Loisir Couldn't open file Impossible d' ouvrir le fichier Error loading %1: %2. Erreur lors du chargement de %1: %2. Couldn't save file Impossible d'enregistrer le fichier Error saving %1: %2. Erreur lors de l'enregistrement de %1: %2. Updating exchange rates… Error saving currencies: %1. New currency… Transaction Schedule Planning de la transaction Total Total Accounts &amp; Categories html format Comptes &amp; Catégories Accounts &amp; Categories (%1&ndash;%2) html format Comptes &amp; Catégories (%1&ndash;%2) Accounts &amp; Categories (to %1) html format Comptes &amp; Catégories (to %1) Change Noun, how much the account balance has changed Change Balance Équilibre Current Account Compte courant Credit Card Carte de crédit Liabilities Dettes New Security… Financial security (e.g. stock, mutual fund) Nouveau titre… Set Quotation… Financial quotation Mettre une quotation… Shares Financial shares Parts Quotation Financial quotation Quotation New Security Financial security (e.g. stock, mutual fund) Nouveau titre Edit Security Financial security (e.g. stock, mutual fund) Éditer le titre Delete security? Financial security (e.g. stock, mutual fund) Supprimer le titre? Are you sure you want to delete the security "%1" and all associated transactions? Financial security (e.g. stock, mutual fund) Êtes-vous certain de vouloir supprimer le titre "%1" et toutes les transactions associées? No security available. Financial security (e.g. stock, mutual fund) Aucune titre disponible. Set Quotation (%1) Financial quotation Mettre la Quotation (%1) Price per share: Financial shares Prix par part: Security Transactions Financial security (e.g. stock, mutual fund) Transactions de titres Balance Noun. Balance of an account Solde Category Catégorie Budget Budget Remaining Budget Budget prévisionnel Total Incomes Revenus totaux Costs Coûts Total Expenses Dépenses totales Account/Category Noun, how much the account balance has changed Compte/Catégorie Empty expenses list. Liste des dépenses vide. Empty incomes list. Liste des revenus vide. Empty transfers list. Liste des transferts vide. Empty securities list. Liste des titres vides. Empty schedule list. Liste des plannings vide. Couldn't open file for writing. Impossible d' ouvrir le fichier en écriture. Error while writing file; file was not saved. Erreur lors de l' écriture du fichier ; fichier non sauvegardé. &File &Fichier &Accounts &Comptes &Transactions &Transactions &Securities &Titres Stat&istics Stat&istiques S&ettings &Configuration &Help &Aide File Fichier Transactions Transactions Statistics Statistiques &New &Nouveau &Open… &Ouvrir… Open Recent Récemment ouvert(s) Clear List Effacer la liste &Save &Enregistrer Save As… Enregistrer sous… &Revert &Annuler &Print View… &Imprimer la vue… &Print… &Imprimer… Print Preview… Aperçu avant impression… Import Importer Import CSV File… Importe un fichier CSV… Import QIF File… Importer un fichier QIF… Export View… Exporter la vue… Export As QIF File… Exporter un fichier QIF… Update Exchange Rates Currency Converter Convertisseur de monnaie &Quit &Quitter Add Account… Ajouter un compte… New Account… Nouveau compte… New Loan… New Income Category… Nouvelle catégorie de revenu… New Expense Category… Nouvelle catégorie de dépense… Add Account Ajouter un compte Assets Actifs Description Transaction description property (transaction title/generic article name) Description Security Transactions Financial security (e.g. stock, bond) Transactions de titres &Loans &Crédits &Securities Financial security (e.g. stock, mutual fund) &Titres Edit… Éditer… Balance… Équilibre… Show Transactions Montrer les transactions Show Ledger Montrer le registre New Expense… Nouvelle dépense… New Income… Nouveau revenu… New Transfer… Nouveau transfert… New Split Transaction… Nouveau transaction séparée… New Expense with Multiple Payments… Refund… Rembourser… Repayment… Remboursement… New Refund/Repayment… Nouveau remboursement… Edit Transaction(s) (Occurrence)… Éditer la/les transaction(s) (Occurrence)… Edit Occurrence… Éditer l'occurrence… Edit Schedule (Recurrence)… Éditer le(s) planning(s) (Occurrence)… Edit Schedule… Éditer le planning… Edit Split Transaction… Editer une transaction séparée… Join Transactions… join transactions together Lier les transactions… Split Up Transaction split up joined transactions Transaction décomposée Edit Timestamp… Éditer l'horodatage… Select Associated File Sélectionner le fichier associé Open Associated File Ouvrir le fichier associé Remove Transaction(s) (Occurrence) Enlever la/les transaction(s) (Occurrence) Remove Occurrence Enlever l' occurrence Delete Schedule (Recurrence) Supprimer le(s) plannings (Récurrence) Delete Schedule Supprimer le planning Remove Split Transaction Déplacer la transaction séparée Edit Security… Éditer le titre… Remove Security Enlever le titre Shares Bought… Parts achetées… Shares Sold… Parts vendues… Shares Moved… Parts bougées… Dividend… Dividende… Reinvested Dividend… Dividende réinvesti… Transactions… Transactions… Edit Quotations… Éditer les quotations… Development Over Time Report… Rapport de développement temporel… Categories Comparison Report… Rapport de comparaison de catégories… Development Over Time Chart… Diagramme de développement temporel… Categories Comparison Chart… Diagramme de comparaison de catégories… Use Additional Transaction Properties Utiliser les paramètres de transaction additionnel Set Main Currency… Set Budget Period… Initial Period Période initiale Remember Last Dates Se souvenir des dernières dates Backup Frequency Daily Journalier Weekly hebdomadaire Fortnightly Monthly Mensuel Never Jamais Cloud Synchronization (experimental)… Dark Mode Thème sombre Help Aide Report Bug Rapport de bogue About %1 À propos de %1 About Qt À propos de Qt Please restart the application for the language change to take effect. A personal accounting program Un programme personnel de finance License: GNU General Public License Version 3 Licence: Version 3 de la Licence Générale Publique GNU Crash Recovery Récupération de l'accident Untitled Sans-titre Generic Description Nom générique The current file has been modified. Do you want to save it? Le fichier courant a été modifié. Voulez-vous l'enregistrer? Confirm Schedule Confirmer le planning New Account Nouveau compte New Income Category Nouvelle catégorie de revenus New Expense Category Nouvelle catégorie de dépenses Balance Account Équilibre du compte Book value: Valeur comptable: of which %1 is balance adjustment Referring to account balance Real value: Valeur réelle: Edit Account Editer le compte Edit Income Category Éditer les catégories de revenus Edit Expense Category Éditer les catégories de dépenses Remove subcategories? Enlever les sous-catégories? Do you wish to remove the category including all subcategories? Move transactions? Bouger les transactions? Move to: Bouger vers: Remove irreversibly from all accounts (do not do this if account has been closed!) The category contains some expenses. What do you want to do with them? La catégorie contient quelques dépenses. Que voulez-vous faire d'elles? The category contains some incomes. What do you want to do with them? La catégorie contient quelques revenus. Que voulez-vous faire d'eux? The account contains some transactions. What do you want to do with them? Ce compte contient plusieurs transactions. Que voulez vous en faire ? Remove Category? Enlever la catégorie? The category contains some expenses that will be removed. Do you still want to remove the category? La catégorie contient quelques dépenses qui seront enlevées. Voulez-vous toujours enlever cette catégorie? The category contains some incomes that will be removed. Do you still want to remove the category? La catégorie contient quelques revenus qui seront supprimés. Voulez-vous toujours enlever cette catégorie? Remove Account? Enlever le compte? The account contains some transactions that will be removed. Do you still want to remove the account? Ce compte contient plusieurs transactions qui seront enlevées. Voulez vous toujours enlever ce compte ? %2 of %1 %1: budget; %2: remaining budget %2 de %1 Set Quote… Financial quote Mettre une quotation… Quote Financial quote Quotation Empty securities list. Financial security (e.g. stock, mutual fund) Liste des titres vides. Balance… Verb. Balance an account Équilibre… Edit Security… Financial security (e.g. stock, mutual fund) Éditer le titre… Remove Security Financial security (e.g. stock, mutual fund) Enlever le titre Shares Bought… Financial shares Parts achetées… Shares Sold… Financial shares Parts vendues… Shares Exchanged… Financial shares Parts transférées… Edit Quotations… Financial quotation Éditer les quotations… %1 (with no budget) %1 (sans budget) %1 (with budget %2) %1 (avec le budget %2) EqonomizeCalendarWidget Today Aujorud'hui EqonomizeDateEdit Today Aujorud'hui EqonomizeTranslator OK Only used when Qt translation is missing Cancel Only used when Qt translation is missing Close Only used when Qt translation is missing &Yes Only used when Qt translation is missing &No Only used when Qt translation is missing &Open Only used when Qt translation is missing &Save Only used when Qt translation is missing &Select All Only used when Qt translation is missing Look in: Only used when Qt translation is missing File &name: Only used when Qt translation is missing Files of type: Only used when Qt translation is missing EqonomizeValueEdit Error Erreur Empty denominator. Empty factor. Division by zero. Division par zéro. Unknown or ambiguous currency, or unrecognized characters, in expression: %1. Empty base. Base vide. Empty exponent. Unrecognized characters in expression. ExportQIFDialog Export QIF File Exporter le fichier QIF Account: Compte: All All accounts Tout Export transaction description as: Exporter le nom de la transaction comme: Export transaction description as: Referring to generic description Exporter le nom de la transaction comme: Payee Bénéficiaire Memo Mémo Subcategory Sous-catégorie Date format: Format de date: Value format: Format de valeur: File: Fichier: Error Erreur Selected file is a directory. Le fichier sélectionné est un dossier. Overwrite The selected file already exists. Would you like to overwrite the old copy? Le fichier existe déjà. Voulez-vous réécrire par dessus l'ancien fichier? You selected a directory! Vous avez sélectionné un répertoire! Couldn't open file for writing. Impossible d' ouvrir le fichier en écriture. Error while writing file; file was not saved. Erreur lors de l' écriture du fichier ; fichier non sauvegardé. ImportCSVDialog Import CSV file Importer le fichier CSV Transaction Type Selection Choix du type de transaction Expenses Dépenses Incomes Revenus Transfers Transferts Expenses and incomes (negative cost) Dépenses et revenus (coût négatif) Expenses and incomes (separate columns) Dépenses et revenus (colonnes séparées) All types Tous types Presets: File Selection Sélection de fichier File: Fichier: First data row: Première colonne de données: Auto Voiture Column delimiter: Délimiteur de colonne: Comma Virgule Tabulator Tabulation Semicolon Point virgule Space Espace Other Autre Columns Specification Spécification de la colonne Save as preset… Imports data as expenses and incomes. Costs have negative value. Value is the only required column. Importe les données comme des dépenses et des revenus. Les coûts ont une valeur négative. Value est la seule colonne requise. Imports data as expenses and incomes. Costs and incomes have separate columns. Income and cost both all required columns. Importe les données comme des dépenses et des revenus. Les coûts ont des colonnes séparées.Les revenus et les coût sont les seules colonnes requises. Warning Attention The same column number is selected multiple times. Do you wish to proceed anyway? Description: Description: Generic description: Nom générique: Description: Transaction description property (transaction title/generic article name) Description : Column Colonne Value Valeur Cost: Coût: Date: Date: Category: Catégorie: From account: Compte de: Quantity: Quantité: Payee: Bénéficiaire: Tags: Étiquettes: Comments: Commentaires: Create missing categories and accounts Crée les comptes et catégories manquante Save Preset Imports data as expenses. Costs have positive value. Value is the only required column. Importe les données comme des dépenses. Les coûts ont une valeur positive. Le valeur est la seule colonne requise. Imports data as incomes. Value is the only required column. Importe les données comme des revenus. Value est la seule colonne requise. Income: Revenu: To account: Vers le compte: Payer: Débiteur: Imports data as transfers. Value is the only required column. Importer les données comme des transferts. Value est la seule colonne requise. Amount: Quantité: Imports data as expenses and incomes. Costs have negative value. Value and category are both required columns. Importe les données comme des dépenses et des revenus. Les coûts ont une valeur négative. La valeur et la catégorie sont les seules colonnes requises. Value: Valeur: Account: Compte: Payee/payer: Bénéficiaire/créditeur : Imports data as expenses and incomes. Costs and incomes have separate columns. Income, cost, and category are all required columns. Importe les données comme des dépenses et des revenus. Les coûts ont des colonnes séparées. Revenus, coût, et la catégorie sont les seules colonnes requises. Imports data as expenses, incomes, and transfers. Costs have negative or positive value. Value, to, and from are all required columns. Accounts and categories must be existing. Importe les données comme dépenses, revenus et transferts. Les coûts ont une valeur négative ou positive. Toutes les valeurs sont requises. Comptes et catégories doivent exister. From: De: To: A: Error Erreur A file must be selected. Vous devez sélectionner un fichier. Selected file is a directory. Le fichier sélectionné est un dossier. Selected file does not exist. Le fichier sélectionné n'existe pas. Empty delimiter. Délimiteur vide. The same column number is selected multiple times. Le même numéro de colonne est sélectionné plusieurs fois. Selected from account is the same as the to account. Le compte de destination est le même que le compte source. Invalid date. Date invalide. Couldn't open %1 for reading. Impossible d' ouvrir le fichier %1 en lecture. Error reading %1. Erreur lors de la lecture de %1. Uncategorized N'est pas catégorisé Successfully imported %n transaction(s). %n transaction importée avec succès. %n transactions importées avec succès. Unable to import any transactions. Impossible d'enregistrer les transactions importées. Failed to import %n data row(s). Echec à l'importation de %n donnée. Echec à l'importation de %n données. Required columns missing. Les colonnes nécessaires sont manquantes. Invalid value. Valeur invalide. Empty category name. Nom de catégorie vide. Empty account name. Nom de compte vide. Unknown category found. Catégorie inconnue trouvée. Unknown account found. Compte inconnu trouvé. Cannot import security transactions (to/from security accounts). Impossible d'importer les transaction de titre (comptes A/De). Balancing account wrongly used. Referring to the account used for adjustments of account balances. Equilibrage des comptes mal utilisé. Balancing account wrongly used. Equilibrage des comptes mal utilisé. Same to and from account/category. Même De et A compte/catégorie. No data found. Pas de donnée trouvée. Information information Unrecognized date format. Format de date non reconnu. Specify Format Format spécifié The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. Le format des dates et/ou nombres dans le fichier CSV est ambigu. S'il vous plaît sélectionner le format correct. Date format: Format de date: Value format: Format de valeur: ImportQIFDialog Import QIF file Importer le fichier QIF File Selection Sélection de fichier Select a QIF file to import. When you click next, the file be analysed and you might need to answer some questions about the format of the file. Sélectionner un fichier QIF pour l'importation. Quand vous cliquez sur prochain, le fichier sera analysé et vous pourrez devoir répondre à des questions sur le format du fichier. File: Fichier: Local Definitions Définitions locales Unknown elements where found in the QIF file. It is possible that this is because of localized type names. Please map them to the correct standard names. Le fichier QIF présente des éléments inconnus. Cela est certainement du à l'utilisation de caractères locaux. Veuillez les remplacer par des caractères standards. Local Text Texte local Standard Text Texte standard Select standard text: Sélectionner un texte standard: Date Format Format de date The date format in the QIF file is ambiguous. Please select the correct format. Le format de date dans le fichier QIF est ambigu. S'il vous plaît sélectionner le format correct. Date format: Format de date: Default Account Compte par défaut Could not find any account definitions in the QIF file. Please select a default account. It is also possible that this is caused by a localized opening balance text. Impossible de trouver les définitions de compte dans le fichier QIF. S'il vous plaît sélectionner un compte par défaut. Il est également possible que cela soit du au solde ouvert traduit en français. Default account: Compte par défaut: Opening balance text: Texte du solde ouvert: Descriptions Descriptions Transactions in QIF files does not have any specific description property. You are therefore given the option to choose how the description of imported transactions will be set. Les transactions dans les fichiers QIF n'ont pas de propriétés de description spécifique. C'est pourquoi vous allez donner l'option pour définir comment la description des transactions importées sera établie. Subcategories as: Sous-catégories de: Description Description Generic Descriptions Noms génériques Transactions in QIF files does not have any specific description property. You are therefore given the option to choose how the description of imported transactions will be set. Referring to generic description Les transactions dans les fichiers QIF n'ont pas de propriétés de nom spécifique. C'est pourquoi vous allez donner l'option pour définir comment le nom des transactions importées sera établie. Generic description Nom générique Category Catégorie Ignore Ignorer Payee as: Bénéficiaire de: Payee Bénéficiaire Memo as: Note de: Comments Commentaires Priority: Priorité: Subcategory/Payee/Comments Sous-catégorie/Bénéficiaire/Commentaires Payee/Subcategory/Comments Bénéficiaire/Sous-Catégorie/Commentaires Subcategory/Comments/Payee Sous-Catégorie/Commentaires/Bénéficiaire Payee/Comments/Subcategory Bénéficiaire/Commentaires/Sous-Catégorie Comments/Subcategory/Payee Commentaires/Sous-Catégorie/Bénéficiaire Comments/Payee/Subcategory Commentaires/Bénéficiaire/Sous-Catégorie Import File Importer un fichier No (further) issues were found. Press finish to import the selected QIF file. Ignore duplicate transactions Ignorer les transactions dupliquées Error Erreur A file must be selected. Vous devez sélectionner un fichier. Selected file is a directory. Le fichier sélectionné est un dossier. Selected file does not exist. Le fichier sélectionné n'existe pas. Couldn't open %1 for reading. Impossible d' ouvrir le fichier %1 en lecture. Error reading %1. Erreur lors de la lecture de %1. Unknown Inconnu Account Compte Bank Banque Cash Liquide Cat (Category) Cat (Catégorie) CCard (Credit Card) CCard (Carte de crédit) Invst (Investment) Invest (Investissement) Oth A (Other Assets) Oth A (Autres actifs) Oth L (Other Liabilities) Oth L (Des otres dettes) Security Titre Other Autre Unrecognized date format. Format de date non reconnu. Successfully imported %n transaction(s). %n transaction importée avec succès. %n transactions importées avec succès. Successfully imported %n account(s). %n compte importé avec succès. %n comptes importés avec succès. Successfully imported %n category/categories. %n catégorie importée avec succès. %n catégories importées avec succès. %n duplicate transaction(s) was ignored. %n transaction dupliquée a été ignorée. %n transactions dupliquées a été ignorée. Failed to import %n transaction(s). Echec à l'importation d'%n transaction. Echec à l'importation de %n transactions. %n security/securities were not imported. Financial security (e.g. stock, mutual fund) %n titre n'a pas été importé. %n titres n'ont pas été importées. %n security transaction(s) were not imported. Financial security (e.g. stock, mutual fund) %n opération de titre n'a pas été importée. %n opérations de titre n'ont pas été importées. %n security/securities were not imported. %n titre n'a pas été importée. %n titres n'ont pas été importées. %n security transaction(s) were not imported. %n opération de titre n'a pas été importée. %n opérations de titre n'ont pas été importées. Information Information Income Dividend: %1 Dividende: %1 Reinvested dividend: %1 Dividende réinvesti : %1 LedgerDialog Account: Compte: Edit Account… Editer le compte… Export… Exporter… Print… Imprimer… Reconcile Accounting context Réconcilier Mark all as reconciled Accounting context Marquer tout comme réconcilié Change: Accounting context Change: R Header for account reconciled checkbox column R Date Date Type Type Description Description Name Nom Generic Description Nom générique Description Generic Description Nom Account/Category Compte/Catégorie Deposit Dépôt Withdrawal Retrait Balance Équilibre Payee/Payer Bénéficiaire/créditeur Tags Étiquettes Comments Commentaires Deposit Money put into account Dépôt Withdrawal Money taken out from account Retrait Balance Noun. Balance of an account Solde New Nouveau Edit… Éditer… Delete Supprimer Join… join transactions together Lier… Split Up split up joined transactions Décomposer Edit Transaction(s)… Éditer la/les transaction(s)… Join Transactions… Lier les transactions… Split Up Transaction Transaction décomposée Open Associated File Ouvrir le fichier associé Remove Transaction(s) Enlever la/les transaction(s) Mark as reconciled Marquer comme réconcilié Reconciled: %1 (%2) Accounting context Réconcilié: %1 (%2) Book value: %1 (%2) Accounting context Valeur comptable: %1 (%2) Mark as reconciled Accounting context Marquer comme réconcilié Error Erreur Invalid date. Date invalide. Opening date is after closing date. La date d'ouverture est après la date de fermeture. Closing date is before opening date. La date de fermeture est après la date d'ouverture. Empty transaction list. Liste des transactions vide. Couldn't open file for writing. Impossible d' ouvrir le fichier en écriture. Error while writing file; file was not saved. Erreur lors de l' écriture du fichier ; fichier non sauvegardé. Ledger Registre Transactions for %1 Transactions pour %1 Select Time Period From: De : To: À : To date is before from date. Balance change: Account balance Delete transactions? Supprimer les transactions ? Are you sure you want to delete all (%1) selected transactions? Êtes-vous certain de vouloir supprimer toutes (%1) les transactions sélectionnées? Account Balance Adjustment Ajustement du solde du compte Current balance: Account balance Average balance: Account balance Account Balancing Balancing of an account Équilibrage du compte Balancing Balancing of an account L'équilibrage de compte Cannot set the value of security transactions using the dialog for modifying multiple transactions. Impossible de fixer la valeur des transactions de titre en utilisant la fenêtre de modification multiple des transactions. Cannot change description of dividends and security transactions. Referring to the generic description property Impossible de changer le nom des dividendes et transactions de titre. Current debt: Total debt reduction: Total interest and fees: Number of transactions: Cannot change description of dividends and security transactions. Impossible de changer le nom des dividendes et transactions de titre. Cannot change payer of dividends and security transactions. Impossible de changer le débiteur des dividendes et transactions de titres. Cannot change date of transactions that are part of a split transaction. Impossible de dater les transactions qui font parti d'une transaction séparée. Initial balance Équilibre initial Split Transaction Transaction séparée Debt Payment Payement de dette Ascending order Reduction Fee Interest Income Revenu Repayment Remboursement Expense Dépense Opening balance: Accounting context Solde d'ouverture: Closing balance: Accounting context Solde de clôture: Description Transaction description property (transaction title/generic article name) Description Balance Account balance Solde Cannot set the value of security transactions using the dialog for modifying multiple transactions. Financial security (e.g. stock, mutual fund) Impossible de fixer la valeur des transactions de titre en utilisant la fenêtre de modification multiple des transactions. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name); Financial security (e.g. stock, mutual fund) Impossible de changer la description des dividendes et transactions de titre. Cannot change payer of dividends and security transactions. Financial security (e.g. stock, mutual fund) Impossible de changer le débiteur des dividendes et transactions de titres. Opening balance Account balance Solde d'ouverture Refund Rembourser Balancing solde Transfer Transfère LinksWidget Remove Link Supprimer le lien All Tout Remove Supprimer MultiItemListViewItem Dividend Dividende Income Revenu Repayment Remboursement Expense Dépense Refund Rembourser Securities Purchase Financial security (e.g. stock, mutual fund) Achat de titres Securities Sale Financial security (e.g. stock, mutual fund) Vente de titres Account Balance Adjustment Ajustement du solde du compte Account Balancing Balancing of an account Équilibrage du compte Balancing Balancing of an account L'équilibrage de compte Security Buy Achat de titres Security Sell Vente de titres Balancing Solde Transfer Transfère MultipleTransactionsEditDialog Modify Transactions Modifier les transactions Description: Description: Name: Nom: Generic Description: Nom générique: Description: Transaction description property (transaction title/generic article name) Description : Amount: Quantité: Income: Revenu: Cost: Coût: Date: Date: Category: Catégorie: Payer: Débiteur: Payee: Bénéficiaire: New Income Category Nouvelle catégorie de revenus New Expense Category Nouvelle catégorie de dépenses New Income Category… Nouvelle catégorie de revenu… New Expense Category… Nouvelle catégorie de dépense… Error Erreur No income category available. Pas de catégorie de revenu disponible. No expense category available. Pas de catégorie de dépense disponible. Invalid date. Date invalide. OverTimeChart Save As… Enregistrer sous… Print… Imprimer… Source: Source: Incomes and Expenses Revenus et Dépenses Profits Profits Expenses Dépenses Incomes Revenus All Categories Combined Toutes les catégories combinées All Descriptions Combined Toutes les descriptions combinées Theme: Thème : Chart type: Type de diagramme : Line Chart Diagramme ligne Vertical Bar Chart Diagramme bâtons verticaux Horizontal Bar Chart Diagramme bâtons horizontaux Stacked Bar Chart Diagramme bâtons Default Par défaut All Subcategories and Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Toutes les sous-catégories et descriptions combinées All Descriptions Split Referring to the transaction description property (transaction title/generic article name) Toutes les descriptions séparées No description Referring to the transaction description property (transaction title/generic article name) Pas de description Other descriptions Referring to the transaction description property (transaction title/generic article name) Autres descriptions Profits, %1 Profits, %1 Assets Actifs All Descriptions Combined Referring to the generic description property Toutes les noms combinées Assets and Liabilities Actifs et dettes Tags Étiquettes All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Toutes les descriptions combinées All Payees/Payers Combined Tous les bénéficiaires/débiteurs combinés All Accounts Combined Tous les comptes combinés All Accounts Split Tous les comptes séparés Start date: Date de départ: End date: Date de fin : Value: Valeur: Monthly total Total mensuel Daily average Moyenne journalière Quantity Quantité Average value Valeur moyenne All Payers Combined Tous les débiteurs combinés All Payees Combined Tous les bénéficiaires combinés All Subcategories Split Toutes les sous-catégories séparées All Descriptions Split Referring to the generic description property Toutes les noms séparées No description Referring to the generic description property Pas de nom Value Valeur Includes budgeted transactions Inclut les transactions budgétées Incomes − Expenses, %1 Revenus − dépenses, %1 Incomes − Expenses Revenus − dépenses Incomes & Expenses Revenus & Dépenses Incomes: %1 Revenus: %1 Expenses: %1 Dépenses: %1 %2: %1 %2: %1 Incomes: %2, %1 Revenus: %2, %1 Expenses: %2, %1 Dépenses: %2, %1 %3: %2, %1 %3: %2, %1 %2, %1 %2, %1 Incomes: %3, %2, %1 Revenus: %3, %2, %1 Expenses: %3, %2, %1 Dépenses: %3, %2, %1 %4: %3, %2, %1 %4: %3, %2, %1 no payee/payer pas de bénéficiaire/créditeur %3, %2, %1 %3, %2, %1 Other accounts Autres comptes %1 Value: %2 Date: %3 %1 Valeur : %2 Date : %3 MMMM yyyy Month and year MMMM AAAA All Descriptions Split Toutes les descriptions séparées All Payers Split Tous les débiteurs séparés All Payees Split Tous les bénéficiaires séparés No description Pas de description No payer Pas de débiteur No payee Pas de bénéficiaire All Categories Split Toutes les catégories séparées Error Erreur Invalid date. Date invalide. Couldn't open file for writing. Impossible d' ouvrir le fichier en écriture. Error while writing file; file was not saved. Erreur lors de l' écriture du fichier ; fichier non sauvegardé. Other payees Autres bénéficiaires Other payers Autres créditeurs Value (%1) Valeur (%1) Profit (%1) Profit (%1) Income (%1) Revenu (%1) Cost (%1) Coût (%1) Time Temps %1/%2 %1: Category; %2: Payee/Payer All Accounts Tous les comptes Annual total Total annuel All Payees/Payers Split Tous les bénéficiaires/débiteurs séparés No payee/payer Pas de bénéficiaire/créditeur All Tags Split Toutes les étiquettes séparés Other tags Autres étiquettes Other payees/payers Autres bénéficiaires/débiteurs Daily average value Valeur moyenne journalière Daily average profit Profit moyen journalier Daily average income Revenu moyen journalier Daily average cost Coût moyen journalier Average income Revenu moyen Average cost Coût moyen Annual value Valeur annuelle Annual profit Profit annuel Annual income Revenu annuel Annual cost Coût annuel Monthly value Valeur mensuelle Monthly profit Profit mensuel Monthly income Revenu mensuel Monthly cost Coût mensuel Includes scheduled and budgeted transactions Inclut les transactions planifiées et budgétées Includes scheduled transactions Inclut les transactions planifiées Incomes, %2: 1 Revenus, %2: 1 Tags, %1 Étiquettes, %1 Value: %1 Valeur : %1 Assets & Liabilities Actifs & dettes Change: %1 Change: %1 Excluding any profits or losses in trading of security shares Financial security (e.g. stock, mutual fund) Incomes & Expenses, %1 Revenus & Dépenses, %1 Incomes, %1 Revenus, %1 Expenses, %1 Dépenses, %1 Incomes, %2: %1 Revenus, %2 : %1 Expenses, %2: %1 Dépenses, %2 : %1 Incomes, %3: %2, %1 Revenus, %3 : %2, %1 Expenses, %3: %2, %1 Dépenses, %3 : %2, %1 Incomes, %4: %3, %2, %1 Revenus, %4 : %3, %2, %1 Expenses, %4: %3, %2, %1 Dépenses, %4 : %3, %2, %1 Liabilities Dettes no payer aucun débiteur %1/%2 %1: Description; %2: Payee/Payer %1/%2 %1: Generic Description; %2: Payer %1/%2 %1/%2 %1: Generic Description; %2: Payee %1/%2 %1/%2 %1: Description; %2: Payer %1/%2 no payee aucun bénéficiaire %1/%2 %1: Description; %2: Payee %1/%2 OverTimeChartDialog Chart Diagramme OverTimeReport Save As… Enregistrer sous… Print… Imprimer… Source: Source: Profits Profits Expenses Dépenses Incomes Revenus Assets & Liabilities Actifs & dettes Tags Étiquettes All Categories Combined Toutes les catégories combinées All Descriptions Combined Toutes les descriptions combinées Columns: Colonnes: Categories Catégories Total: Total: Value Valeur Daily Journalier Monthly Mensuel Yearly Annuel Quantity Quantité Average value Valeur moyenne No description Pas de description All Descriptions Combined Referring to the generic description property Toutes les noms combinées No description Referring to the generic description property Pas de nom All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Toutes les descriptions combinées All Accounts Tous les comptes No description Referring to the transaction description property (transaction title/generic article name) Pas de description Error Erreur Couldn't open file for writing. Impossible d' ouvrir le fichier en écriture. Error while writing file; file was not saved. Erreur lors de l' écriture du fichier ; fichier non sauvegardé. Average Profit Profit moyen Incomes, %1 Revenus, %1 Average Income Revenu moyen Expenses, %1 Dépenses, %1 Average Cost Coût moyen Incomes, %2: %1 Revenus, %2 : %1 Incomes: %1 Revenus: %1 Expenses, %2: %1 Dépenses, %2 : %1 Expenses: %1 Dépenses: %1 Incomes, %3: %2, %1 Revenus, %3 : %2, %1 Incomes: %2, %1 Revenus: %2, %1 Expenses, %3: %2, %1 Dépenses, %3 : %2, %1 Expenses: %2, %1 Dépenses: %2, %1 Change: %1 Noun, how much the account balance has changed Change : %1 Average Change Change moyen Change Noun, how much the account balance has changed Change Value: %1 Valeur : %1 Year Année Month Mois Assets Actifs Deposit Dépôt Withdrawal Retrait Liabilities Dettes %2: %1 %2: %1 %1 %1 Average Value Valeur moyenne %3: %2, %1 %3: %2, %1 %2, %1 %2, %1 Daily Average Moyenne journalière Monthly Average Moyenne mensuelle Yearly Average Moyenne annuelle Subtotal Sous-total Total Total Deposit Money put into account Dépôt Withdrawal Money taken out from account Retrait Includes scheduled transactions Inclut les transactions planifiées Adjusted for the average month / year (%1 / %2 days) Ajusté pour le mois/annér moyen (%1 / %2 jours) All Categories Combined Referring to the generic description property Toutes les catégories combinées OverTimeReportDialog Report Rapport QApplication Start with expenses list displayed Commencer avec la liste des dépenses montrée Start with incomes list displayed Commencer avec la liste des revenus montrée Start with transfers list displayed Commencer avec la liste des transferts montrée Synchronize file Document to open Document à ouvrir %1 is already running. QObject Transfer Transfère Dividend Dividende Income Revenu Expense Dépense Securities Purchase Financial security (e.g. stock, mutual fund) Achat de titres Securities Sale Financial security (e.g. stock, mutual fund) Vente de titres Security Buy Achat de titres Security Sell Vente de titres Debt Payment Payement de dette Split Transaction Transaction séparée RecurrenceEditWidget Enable recurrence Autoriser les récurrences Recurrence Rule Règle de récurrence Daily Journalier Weekly hebdomadaire Monthly Mensuel Yearly Annuel Recur every Se produit tous les day(s) jour(s) week(s) on: semaine(s) sur: month(s), after the start month mois(s), après le mois de départ Recur on the Se produit le 1st 1er 2nd 2ème 3rd 3ème 4th 4ème 5th 5ème 6th 6ème 7th 7ème 8th 8ème 9th 9ème 10th 10ème 11th 11ème 12th 12ème 13th 13ème 14th 14ème 15th 15ème 16th 16ème 17th 17ème 18th 18ème 19th 19ème 20th 20ème 21st 21ème 22nd 22ème 23rd 23ème 24th 24ème 25th 25ème 26th 26ème 27th 27ème 28th 28ème 29th 29ème 30th 30ème 31st 31ème Last Dernier(e) 2nd Last Avant dernier(e) 3rd Last 3ème dernier(e) 4th Last 4ème dernier(e) 5th Last 5ème dernier(e) day jour possibly on weekend si possible le weekend but before weekend mais avant le weekend but after weekend mais après le weekend nearest weekend day year(s), after the start year année(s), après l'année de départ on nearest weekday Recur on day part before XXX of 'Recur on day XXX of month YYY' Reste sur le jour of part between XXX and YYY of 'Recur on day XXX of month YYY' de On the Part before NNN in 'Recur on the NNN. WEEKDAY of MONTH' Le of part between WEEKDAY and MONTH in 'Recur on NNN. WEEKDAY of MONTH' de Recur on day # Se produit le jour # of the year part after NNN of 'Recur on day #NNN of the year' de l'année Range… Intersection… Occurrences/Exceptions… Exceptions… Exceptions… Error Erreur No day of week selected for weekly recurrence. Pas de jour de semaine sélectionné pour la récurrence hebdomadaire. Selected day will never occur with selected frequency and start date. Le jour sélectionné ne se produira jamais avec la fréquence et la date de départ sélectionnées. Selected day does not exist in selected month. Le jour sélectionné n'existe pas dans le mois sélectionné. RefundDialog Repayment Remboursement Refund Rembourser Date: Date: Cost: Coût: Income: Revenu: Quantity returned: Quantité retournée: Account: Compte: Quantity: Quantité: Payee: Bénéficiaire: Payer: Débiteur: Comments: Commentaires: Link Link the transactions together Lier Join Join the transactions together Rejoignez Error Erreur Zero value not allowed. Valeur nulle non autorisée. Invalid date. Date invalide. SecurityBuy Security: %1 (bought) Titre: %1 (acheté) Security: %1 (bought) Financial security (e.g. stock, mutual fund) Titre : %1 (acheté) SecuritySell Security: %1 (sold) Titre: %1 (vendu) Security: %1 (sold) Financial security (e.g. stock, mutual fund) Titre : %1 (vendu) SecurityTransactionsDialog Transactions for %1 Transactions pour %1 Date Date Type Type Value Valeur Shares Financial shares Parts Shares Bought Financial shares Parts achetées Shares Bought (Recurring) Financial shares Parts achetées (récurrentes) Dividend (Recurring) Dividende (récurrents) Dividend (Scheduled) Dividende (planifiés) Reinvested Dividend (Recurring) Réinvestir le dividende (récurrent) Reinvested Dividend (Scheduled) Réinvestir le dividende (planifié) Shares Bought Fincancial shares Parts achetées Shares Sold Financial shares Parts vendues Shares Sold (Exchanged) Shares of one security directly exchanged for shares of another; Financial shares Parts vendues (Ventes) Shares Bought (Exchanged) Shares of one security directly exchanged for shares of another; Financial shares Parts achetées (Ventes) Shares Sold (Exchanged) Financial shares Parts vendues (Ventes) Shares Bought (Exchanged) Financial shares Parts achetées (Ventes) Shares Bought (Recurring) Fincancial shares Parts achetées (Récurrentes) Shares Sold (Recurring) Financial shares Parts vendues (récurrentes) Shares Bought (Scheduled) Financial shares Parts achetées (planifiées) Shares Sold (Scheduled) Financial shares Parts vendues (planifiées) Shares Parts Edit… Éditer… Delete Supprimer Shares Bought Parts achetées Shares Sold Parts vendues Dividend Dividende Reinvested Dividend Réinvestir le dividende Shares Sold (Traded) Parts vendues (Ventes) Shares Bought (Traded) Parts achetées (Ventes= Shares Bought (Recurring) Parts achetées (Récurrentes) Shares Sold (Recurring) Parts vendues (Récurrentes) Shares Bought (Scheduled) Parts achetées (planifiées) Shares Sold (Scheduled) Parts vendues (planifiées) Recurring Dividend Dividende récurrent Scheduled Dividend Dividende planifié SplitListViewItem Dividend Dividende Income Revenu Repayment Remboursement Expense Dépense Refund Rembourser Security Buy Achat de titres Security Sell Vente de titres Balancing solde Transfer Transfère TagButton no tags Pas d'étiquette TagMenu New tag… Nouvelle étiquette… New Tag Nouvelle étiquette Tag: Étiquette: TransactionEditDialog Edit Expense Éditer la dépense Edit Dividend Éditer le dividende Edit Income Éditer le revenu Edit Transfer Éditer le transfert Edit Securities Purchase Financial security (e.g. stock, mutual fund) Éditer les titres achetés Edit Securities Sale Financial security (e.g. stock, mutual fund) Éditer les titres vendus Edit Reinvested Dividend Edit Securities Bought Éditer les titres achetés Edit Securities Sold Éditer les titres vendus TransactionEditWidget Security: Titre: Cost: Coût: Income: Revenu: Shares bought: Parts achetées: Shares sold: Parts vendues: All Tout Price per share: Prix par part: Date: Date: Description: Description: Name: Nom: Generic Description: Nom générique: Amount: Quantité: Withdrawal: Money taken out from account Retrait : New Security… Financial security (e.g. stock, mutual fund) Nouveau titre… Shares added: Financial shares Parts ajoutées: Set security share value Total value: Valeur totale : Deposit: Money put into account Dépôt : Downpayment: Quantity: Quantité: From: De: To: A: Category: Catégorie: To account: Vers le compte: Payer: Débiteur: Payer of parent split transaction From account: Compte de: Downpayment account: Payee: Bénéficiaire: Payee of parent split transaction Lender: Prêteur : Tags: Étiquettes: Associated file: Fichier associé : Select a file Sélectionnez un fichier Open the file Ouvrir le fichier Comments: Commentaires: Related to: Label for linked transactions Liens: New Security Financial security (e.g. stock, mutual fund) Nouveau titre No security available. Financial security (e.g. stock, mutual fund) Aucune titre disponible. New Tag Nouvelle étiquette Tag: Étiquette: New Account Nouveau compte New Income Category Nouvelle catégorie de revenus New Expense Category Nouvelle catégorie de dépenses New Account… Nouveau compte… New Income Category… Nouvelle catégorie de revenu… New Expense Category… Nouvelle catégorie de dépense… Security: Financial security (e.g. stock, mutual fund) Titre: Shares bought: Financial shares Parts achetées: Shares sold: Financial shares Parts vendues: Price per share: Financial shares Prix par part: Description: Transaction description property (transaction title/generic article name) Description : Transaction title/generic article name Number of items included in the transaction. Entered cost is total cost for all items. Error Erreur No suitable account available. Pas de compte approprié disponible. No income category available. Pas de catégorie de revenu disponible. No suitable account or income category available. Aucune catégorie de compte ou de revenu appropriée. No expense category available. Pas de catégorie de dépense disponible. No security available. Aucune titre disponible. Invalid date. Date invalide. Cannot transfer money to and from the same account. Impossible de transférer de l'argent de et vers le même compte. Downpayment must be less than total cost. Cannot create a regular transfer to/from a securities account. Impossible de créer un transfert régulier de/vers un compte de titres. Cannot create a regular income to a securities account. Impossible de créer un revenu régulier vers un compte de titres. Zero shares not allowed. Zéro partages non autorisé. Zero value not allowed. Valeur nulle non autorisée. Zero price per share not allowed. Prix zéro par part non autorisé. Cannot create a regular expense from a securities account. Impossible de créer une dépense régulière à partir d' un compte de titres. Loan for %1 TransactionFilterWidget From: De: To: A: Min amount: Montant min: Max amount: Montant max: Category: Catégorie: To account: Vers le compte: Min income: Revenu min: Max income: Revenu max: From account: Compte de: Min cost: Coût min: Max cost: Coût max: Tag: Étiquette: Generic Description: Nom générique: Description: Description: Description: Transaction description property (transaction title/generic article name) Description : Payer: Débiteur: Payee: Bénéficiaire: Include Inclut Exclude Exclut Exact match Exclude subcategories Clear Effacer All Tout Error Erreur Invalid date. Date invalide. To date is before from date. La date est antérieure à la date visée. From date is after to date. La date est postérieure à la date visée. TransactionListWidget Date Date Description Description Cost Coût Category Catégorie From Account Du compte Payee Bénéficiaire Tags Étiquettes Income Revenu To Account Vers le compte Payer Créditeur Amount Montant From De To A Comments Commentaires Add Ajouter Apply Appliquer Delete Supprimer * Part of <a href="%1">split transaction</a> * partie de la <a href="%1">transaction séparée</a> Expense Dépense Transfer Transfère New/Edit %1 Crée/modifie %1 Name Nom Generic Description Nom générique Description Generic Description Nom Description Transaction description property (transaction title/generic article name) Description New/Edit Expense Crée/modifie dépense New/Edit Income Crée/modifie revenue New/Edit Transfer Crée/modifie transfert Filter Filtre Quantity: Quantité: Total: Total: Average: Moyenne: Clear Effacer Cost: Coût : Monthly: Mensuel: Sort by creation time Expenses Dépenses Incomes Revenus Transfers Transferts Quantity Quantité Right align Aligner à droite Total cost: Coût total: Total income: Revenu total: Total amount: Quantité totale: Monthly average: Moyenne mensuelle: Error Erreur Cannot set the value of security transactions using the dialog for modifying multiple transactions. Financial security (e.g. stock, mutual fund) Impossible de fixer la valeur des transactions de titre en utilisant la fenêtre de modification multiple des transactions. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name); Financial security (e.g. stock, mutual fund) Impossible de changer la description des dividendes et transactions de titre. Cannot change payer of dividends and security transactions. Financial security (e.g. stock, mutual fund) Impossible de changer le débiteur des dividendes et transactions de titres. Cannot change date of transactions that are part of a split transaction, unless all individual transactions are selected. Cannot set the value of security transactions using the dialog for modifying multiple transactions. Impossible de fixer la valeur des transactions de titre en utilisant la fenêtre de modification multiple des transactions. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name) Impossible de changer la description des dividendes et transactions de titre. Cannot change date, description, expense category or payee of transactions that are part of a debt payment using the dialog for modifying multiple transactions. Referring to the transaction description property (transaction title/generic article name) Cannot change description of dividends and security transactions. Referring to the generic description property Impossible de changer le nom des dividendes et transactions de titre. Cannot change description of dividends and security transactions. Impossible de changer le nom des dividendes et transactions de titre. Cannot change payer of dividends and security transactions. Impossible de changer le débiteur des dividendes et transactions de titres. Cannot change date of transactions that are part of a split transaction. Impossible de dater les transactions qui font parti d'une transaction séparée. Delete transactions? Supprimer les transactions ? Are you sure you want to delete all (%1) transactions in the selected split transaction? Êtes-vous certain de vouloir supprimer toutes les (%1) transactions sélectionnées comme transaction séparée? Join as multiple accounts/payments? Do you wish join the selected expenses as an expense with multiple accounts/payments? Do you wish join the selected incomes as an income with multiple accounts/payments? Are you sure you want to delete all (%1) selected transactions? Êtes-vous certain de vouloir supprimer toutes (%1) les transactions sélectionnées? * Part of split transaction * partie de la transaction séparée * Part of split (%1) * Partie de la séparation (%1) ** Recurring (editing occurrence) ** Se reproduit (éditer l' occurrence) Modify… Modifier… Edit… Éditer… Eqonomize-1.5.3/translations/eqonomize_hu.ts000066400000000000000000020440721416454732000213000ustar00rootroot00000000000000 Balancing Kiegyenlítés kde-format Couldn't open %1 for reading %1 nem nyitható meg olvasásra kde-format Not a valid Eqonomize! file (XML parse error: "%2" at line %3, col %4) Nem érvényes Eqonomize!-fájl (XML parse error: "%2" a(z) %3. sorban, a(z) %4. oszlopban) kde-format Invalid root element %1 in XML document Érvénytelen %1 elem az XML dokumentumban. kde-format Unable to load 1 account. Nem lehet betölteni 1 számlát. kde-format Unable to load %n accounts. Unable to load 1 category. Nem lehet betölteni 1 kategóriát. kde-format Unable to load %n categories. Unable to load 1 security. Nem lehet betölteni 1 értékpapírt. kde-format Unable to load %n securities. Unable to load 1 transaction. Nem lehet betölteni 1 tranzakciót. kde-format Unable to load %n transactions. File is a directory A fájl egy könyvtár kde-format Couldn't open file for writing Nem írható fájl kde-format Error while writing file; file was not saved Hiba írás közben; a fájl nem lett elmentve. kde-format From Eredet kde-format To Cél kde-format Source: Forrás: kde-format All Expenses Összes kiadás kde-format All Incomes Összes bevétel kde-format All Accounts összes számla kde-format Expenses: %1 Kiadások: %1 kde-format Incomes: %1 Bevételek: %1 kde-format Invalid date. Érvénytelen dátum kde-format To date is before from date. A záródátum korábbi, mint a kezdődátum. kde-format From date is after to date. A kezdődátum későbbi, mint a záródátum. kde-format The selected file already exists. Would you like to overwrite the old copy? A kiválasztott fájl már létezik. Felülírod a régebbi változatot? kde-format You selected a directory! Könyvtárt választottál! kde-format Couldn't open file for writing. Nem írható fájl. kde-format Error while writing file; file was not saved. Hiba írás közben; a fájl nincs elmentve. kde-format No description Nincs leírás kde-format All Categories Összes kategória kde-format Descriptions for Típusok kde-format Payees/payers for Kedvezményezettek/kifizetők kde-format Period: Periódus: kde-format Columns: Oszlopok: kde-format Value Érték kde-format Daily Naponta kde-format Monthly Havonta kde-format Yearly Évente kde-format Quantity Mennyiség kde-format Average value Átlagérték kde-format All descriptions Összes típus kde-format All payees Összes kedvezményezett kde-format All payers Összes kifizető kde-format No payee Nincs kedvezményezett kde-format No payer Nincs kifizető kde-format Expenses: %2, %1 Kiadások: %2, %1 kde-format Incomes: %2, %1 Bevételek: %2, %1 kde-format Incomes & Expenses Bevételek és kiadások kde-format %1 (%2&ndash;%3) html format; %1: title; %2: from date; %3: to date %1 (%2&ndash;%3) kde-format %1 (to %2) html format; %1: title; %2: to date %1 (%2-ig) kde-format Category Kategória kde-format Cost Költség kde-format Income Bevétel kde-format Daily Average Napi átlag kde-format Monthly Average Havi átlag kde-format Yearly Average Éves átlag kde-format Average Cost Átlagos költség kde-format Average Income Átlagos bevétel kde-format Average Value Átlagos érték kde-format Total Összesen kde-format Total incomes Bevétel összesen kde-format Total expenses Kiadás összesen kde-format Total (Profits) Összes (nyereség) kde-format Expense Kiadás kde-format Transfer Átutalás kde-format Security Buy Értékpapír vétel kde-format Security Sell Értékpapír eladás kde-format Recurrence Ismétlődés kde-format New Expense Új kiadás kde-format New Dividend Új osztalék kde-format New Income Új bevétel kde-format New Transfer Új átutalás kde-format New Security Buy Új értékpapír vétel kde-format New Security Sell Új értékpapír eladás kde-format Edit Expense Kiadás szerkesztése kde-format Edit Dividend Osztalék szerkesztése kde-format Edit Income Bevétel szerkesztése kde-format Edit Transfer Átutalás szerkesztése kde-format Edit Securities Bought Értékpapír vétel szerkesztése kde-format Edit Securities Sold Értékpapír eladás szerkesztése kde-format Dividend Osztalék kde-format Repayment Visszafizetés kde-format Refund Visszatérítés kde-format Split Transaction Osztott tranzakció kde-format Description: Leírás: kde-format Date: Dátum: kde-format Account: Számla: kde-format Transactions: Tranzakciók: kde-format Type Típus kde-format Description Leírás kde-format Account/Category Számla/Kategória kde-format Payment Fizetés kde-format Deposit Letét kde-format New Új kde-format New Expense… Új kiadás… kde-format New Income… Új bevétel… kde-format New Deposit… Új letét… kde-format New Withdrawal… Új kivét… kde-format New Security Shares Bought… Új részvényvásárlás… kde-format Security Shares Sold… Részvény eladás… kde-format New Dividend… Új osztalék… kde-format Edit… Szerkesztés… kde-format Total value: Összes érték: kde-format No suitable account available. Nincs megfelelő számla. kde-format Future dates is not allowed. Jövőbeli dátum nem megengedett. kde-format A split must contain at least two transactions. Egy osztott tranzakció legalább két tranzakcióból áll. kde-format Cannot transfer money to and from the same account. Nem lehet átutalni ugyanarról ugyanarra a számlára. kde-format Cost: Költség: kde-format Income: Bevétel: kde-format Quantity: Mennyiség: kde-format Comments: Megjegyzések: kde-format Reinvested Dividend Újra befektetett osztalék kde-format Security: Értékpapír: kde-format Shares added: Hozzáadott részvények: kde-format Security Trade Értékpapír-forgalom kde-format From security: Forrás értékpapír: kde-format Shares moved: Áthelyezett részvények: kde-format All Összes kde-format To security: Cél értékpapír: kde-format Shares received: Kapott részvények: kde-format Value: Érték: kde-format No other security available for trade in the account. Nincs más értékesíthető értékpapír a számlán. kde-format Selected to and from securities are the same. A kiválasztott cél és forrás értékpapírok ugyanazok. kde-format Zero shares not allowed. Nulla részvény nem megengedett. kde-format Zero value not allowed. Nulla érték nem megengedett. kde-format Quotations Árfolyamok kde-format Date Dátum kde-format Price per Share Részvényenkénti ár kde-format Quotations for %1 %1 árfolyamai kde-format The following transactions was scheduled to occur today or before today. Confirm that they have indeed occurred (or will occur today). A következő tranzakciók teljesítése volt tervezve a mai napra vagy korábbra. Erősítsd meg, hogy ezek valóban teljesültek (vagy teljesülnek a mai napon). kde-format Amount Mennyiség kde-format Postpone… Halasztás… kde-format Can only postpone to future dates. Csak jövőbeli dátumra halasztható. kde-format Transactions for %1 %1 tranzakciói kde-format Shares Részvények kde-format Shares Bought Részvényvásárlás kde-format Shares Sold Részvényeladás kde-format Shares Sold (Traded) Részvényeladás (megkötött) kde-format Shares Bought (Traded) Részvényvásárlás (megkötött) kde-format Shares Bought (Recurring) Részvényvásárlás (ismétlődő) kde-format Shares Sold (Recurring) Részvényeladás (ismétlődő) kde-format Shares Bought (Scheduled) Részvényvásárlás (tervezett) kde-format Shares Sold (Scheduled) Részvényeladás (tervezett) kde-format Recurring Dividend Ismétlődő osztalék kde-format Scheduled Dividend Tervezett osztalék kde-format Type: Típus: kde-format Mutual Fund Befektetési alap kde-format Bond Kötvény kde-format Stock Részvény kde-format Other Egyéb kde-format Name: Név: kde-format Decimals in Shares: Törtek a részvényekben: kde-format Initial Shares: Kezdeti részvények: kde-format Initial quotation: Kezdő árfolyam: kde-format No suitable account or income category available. Nincs megfelelő számla vagy bevétel kategória. kde-format Cash Készpénz kde-format Current Account Folyószámla kde-format Savings Account Takarékbetét-számla kde-format Credit Card Hitelkártya kde-format Liabilities Tartozások kde-format Securities Értékpapírok kde-format Initial balance: Nyitóegyenleg: kde-format Default account for budgeted transactions Alapértelmezett számla a költségvetési tranzakciókhoz kde-format Empty name. Üres név. kde-format The entered name is used by another account. A megadott név másik számláé. kde-format Monthly budget: Havi költségvetés: kde-format The entered name is used by another income category. A megadott név másik bevételi kategóriáé. kde-format The entered name is used by another expense category. A megadott név másik kiadási kategóriáé. kde-format Accounts Számlák kde-format Accounts & Categories Számlák és kategóriák kde-format Expenses Kiadások kde-format Incomes Bevételek kde-format Transfers Átutalások kde-format Schedule Ütemterv kde-format Scheduled Transactions Tervezett tranzakciók kde-format Account / Category Számla / Kategória kde-format Remaining Budget (%1) Hátralévő költségvetés (%1) kde-format Change (%1) Változás (%1) kde-format Total (%1) Összesen (%1) kde-format %2 of %1 %2 remains of %1 budget %2 maradt (terv: %1) kde-format Includes budgeted transactions Költségvetési tranzakciókat tartalmaz kde-format Period Időszak kde-format Select Period Válassz időszakot kde-format Current Month Aktuális hónap kde-format Current Year Aktuális év kde-format Current Whole Month Aktuális teljes hónap kde-format Current Whole Year Aktuális teljes év kde-format Whole Past Month Teljes múlt hónap kde-format Whole Past Year Teljes múlt év kde-format Previous Month Előző hónap kde-format Previous Year Előző év kde-format Show partial budget Mutasd a részleges költségvetést kde-format Edit Budget Költségvetés szerkesztése kde-format Budget: Költségvetés: kde-format Month: Hónap: kde-format Result previous month: Előző havi eredmény: kde-format New Security… Új értékpapír… kde-format New Transaction Új tranzakció kde-format Set Quotation… Árfolyam beállítása… kde-format Name Név kde-format Quotation Árfolyam kde-format Profit Nyereség kde-format Yearly Rate Éves kamatláb kde-format Account Számla kde-format Statistics Period Statisztikai időszak kde-format New Schedule Új ütemterv kde-format Edit Szerkesztés kde-format Next Occurrence Következő esemény kde-format Comments Megjegyzések kde-format New Security Új értékpapír kde-format Edit Security Értékpapír szerkesztése kde-format Profit: Nyereség: kde-format Rate: Kamat: kde-format Are you sure you want to delete the security "%1" and all associated transactions? Valóban törölni akarod a "%1" értékpapírt és minden kapcsolódó tranzakciót? kde-format No security available. Nincs lehetséges értékpapír. kde-format Set Quotation (%1) Árfolyam beállítása (%1) kde-format Price per share: Részvényenkénti ár: kde-format Future dates are not allowed. Jövőbeli dátumok nem megengedettek. kde-format Security Transactions Értékpapír tranzakciók kde-format Ledger Főkönyv kde-format Untitled Névtelen kde-format Check Account Számlaellenőrzés kde-format Salary Fizetés kde-format Bills Számlák kde-format Clothing Ruházat kde-format Groceries Élelmiszer kde-format Leisure Szabadidő kde-format Couldn't fetch %1. %1 nem behozható. kde-format Error loading %1: %2. Hiba %1 betöltése közben: %2. kde-format Couldn't open file Nem lehetett megnyitni a fájlt. kde-format Error saving %1: %2. Hiba %1 mentése közben: %2. kde-format Couldn't save file Nem lehetett menteni a fájlt. kde-format Failed to upload file to %1. Hiba történt %1 fájlba való feltöltéskor. kde-format Report Jelentés kde-format Chart Grafikon kde-format Transaction Schedule Tranzakciós ütemterv kde-format Accounts &amp; Categories html format Számlák &amp; Kategóriák kde-format Accounts &amp; Categories (%1&ndash;%2) html format Számlák &amp; Kategóriák (%1&ndash;%2) kde-format Accounts &amp; Categories (to %1) html format Számlák &amp; Kategóriák (%1-hoz/hez) kde-format Change Változás kde-format Balance Egyenleg kde-format Budget Költségvetés kde-format Remaining Budget Hátralevő költségvetés kde-format Total Incomes Összes bevétel kde-format Costs Költségek kde-format Total Expenses Összes kiadás kde-format Empty expenses list. Üres kiadási lista. kde-format Empty incomes list. Üres bevételi lista. kde-format Empty transfers list. Üres átutalási lista. kde-format Empty securities list. Üres értékpapírlista. kde-format Empty schedule list. Üres ütemterv lista. kde-format Export View… Exportálási nézet… kde-format Print View… Nyomtatási nézet… kde-format Initial Period Kezdő periódus kde-format Remember Last Dates Utolsó dátumok megjegyzése kde-format Import CSV File… CSV fájl importálása… kde-format Import QIF File… QIF fájl importálása kde-format Export As QIF File… Exportálás QIF fájlként kde-format Add Account… Számla hozzáadása… kde-format New Account… Új számla… kde-format New Income Category… Új bevételi kategória… kde-format New Expense Category… Új kiadási kategória… kde-format Balance… Egyenleg… kde-format Show Transactions Tranzakciók megmutatása kde-format New Transfer… Új átutalás… kde-format New Split Transaction… Új osztott tranzakció… kde-format Edit Transaction(s) (Occurrence)… Tranzakció(k) szerkesztése (Eseti)… kde-format Edit Occurrence… Esemény szerkesztése… kde-format Edit Schedule (Recurrence)… Ütemterv szerkesztése (ismétlődő)… kde-format Edit Schedule… Ütemterv szerkesztése kde-format Remove Transaction(s) (Occurrence) Tranzakció(k) visszavonása (Eseti) kde-format Remove Occurrence Visszavont esemény kde-format Delete Schedule (Recurrence) Ütemterv törlése (ismétlődő) kde-format Delete Schedule Törölt ütemterv kde-format Edit Split Transaction… Osztott tranzakció szerkesztése… kde-format Remove Split Transaction Osztott tranzakció visszavonása… kde-format Join Transactions… Tranzakciók egyesítése… kde-format Split Up Transaction Tranzakciók felosztása… kde-format Refund… Visszatérítés… kde-format Repayment… Visszafizetés… kde-format New Refund/Repayment… Új visszatérítés/visszafizetés… kde-format Edit Security… Értékpapír szerkesztése… kde-format Remove Security Értékpapír visszavonása kde-format Shares Sold… Részvények eladása… kde-format Shares Bought… Részvények vásárlása… kde-format Dividend… Osztalék… kde-format Reinvested Dividend… Osztalék újrabefektetése… kde-format Shares Moved… Részvények mozgatása… kde-format Edit Quotations… Árfolyamok szerkesztése… kde-format Transactions… Tranzakciók… kde-format Development Over Time Report… Időbeli fejlődés jelentés… kde-format Categories Comparison Report… Kategória-összehasonlító jelentés… kde-format Categories Comparison Chart… Kategória-összehasonlító grafikon… kde-format Development Over Time Chart… Időbeli fejlődés grafikon… kde-format Use Additional Transaction Properties Kiegészítő tranzakció tulajdonságok használata kde-format Eqonomize! exited unexpectedly before the file was saved and data was lost. Do you want to load the last auto-saved version of the file? Az Eqonomize! váratlanul kilépett, mielőtt a fájlt mentették volna és az adat elveszett. Betöltöd a fájl utolsó automatikusan mentett verzióját? kde-format Crash Recovery Helyreállítás kde-format The current file has been modified. Do you want to save it? Az aktuális fájl módosult. Akarod menteni? kde-format Confirm Schedule Ütemterv megerősítése kde-format New Account Új számla kde-format New Income Category Új bevételi kategória kde-format New Expense Category Új kiadási kategória kde-format Balance Account Mérlegszámla kde-format Book value: Könyvérték: kde-format Real value: Valódi érték: kde-format Edit Account Számla szerkesztése kde-format Edit Income Category Bevétel kategória szerkesztése kde-format Edit Expense Category Kiadás kategória szerkesztése kde-format Move transactions? Tranzakciók mozgatása? kde-format Move to: Mozgatás ide: kde-format The category contains some expenses. What do you want to do with them? A kategória kiadásokat tartalmaz. Mit akarsz velük tenni? kde-format The category contains some incomes. What do you want to do with them? A kategória bevételeket tartalmaz. Mit akarsz velük tenni? kde-format The account contains some transactions. What do you want to do with them? A számla tranzakciókat tartalmaz. Mit akarsz velük tenni? kde-format The category contains some expenses that will be removed. Do you still want to remove the category? A kategória kiadásokat tartalmaz, amik törlődni fognak. Biztosan el akarod távolítani a kategóriát? kde-format Remove Category? Kategória eltávolítása? kde-format The category contains some incomes that will be removed. Do you still want to remove the category? A kategória bevételeket tartalmaz, amik törlődni fognak. Biztosan el akarod távolítani a kategóriát? kde-format The account contains some transactions that will be removed. Do you still want to remove the account? A számla tranzakciókat tartalmaz, amik törlődni fognak. Biztosan el akarod távolítani a számlát? kde-format Remove Account? Számla eltávolítása? kde-format %2 of %1 %1: budget; %2: remaining budget %2 maradt (terv: %1) kde-format %1 (with no budget) %1 (költségvetés nélkül) kde-format %1 (with budget %2) %1 (%2 költségvetéssel) kde-format Import CSV file CSV fájl importálása kde-format Transaction Type Selection Tranzakciótípus kiválasztása kde-format Expenses and incomes (negative cost) Kiadások és bevételek (negatív költség) kde-format Expenses and incomes (separate columns) Kiadások és bevételek (külön oszlopok) kde-format All types Összes típus kde-format File Selection Fájl kiválasztása kde-format File: Fájl: kde-format First data row: Első adatsor kde-format Auto Automatikus kde-format Column delimiter: oszlop elválasztó: kde-format Comma Vessző kde-format Tabulator Tabulátor kde-format Semicolon Pontosvessző kde-format Space Space kde-format Columns Specification Oszlopok leírása kde-format Column Oszlop kde-format Category: Kategória: kde-format From account: Erről a számláról: kde-format Create missing categories and accounts Hiányzó kategóriák és számlák készítése kde-format Imports data as expenses. Costs have positive value. Value is the only required column. Adatok importálása kiadásként. A költségek pozitív értékek. Az érték az egyetlen szükséges oszlop. kde-format Imports data as incomes. Value is the only required column. Adatok importálása bevételként. Az érték az egyetlen szükséges oszlop. kde-format To account: Erre a számlára: kde-format Imports data as transfers. Value is the only required column. Adatok importálása átutalásként. Az érték az egyetlen szükséges oszlop. kde-format Amount: Összeg: kde-format Imports data as expenses and incomes. Costs have negative value. Value and category are both required columns. Adatok importálása kiadásként és bevételként. A költségek negatív értékek. Az érték és a kategória egyaránt szükséges oszlop. kde-format Imports data as expenses and incomes. Costs and incomes have separate columns. Income, cost, and category are all required columns. Adatok importálása kiadásként és bevételként. A költségek és bevételek külön oszlopok. A bevétel, a költség és a kategória mind szükséges oszlopok. kde-format Imports data as expenses, incomes, and transfers. Costs have negative or positive value. Value, to, and from are all required columns. Accounts and categories must be existing. Adatok importálása kiadásként, bevételként és átutalásként. A költségek negatív vagy pozitív értékek. Az érték, a forrás és a cél mind szükséges oszlopok. A számláknak és kategóriáknak létezniük kell. kde-format From: Forrás: kde-format To: Cél: kde-format A file must be selected. Ki kell választani egy fájlt. kde-format Selected file is a directory. Könyvtárt választottál. kde-format Selected file does not exist. A kiválasztott fájl nem létezik. kde-format Empty delimiter. Üres elválasztó. kde-format The same column number is selected multiple times. Ugyanaz az oszlopszám többször kiválasztva. kde-format Selected from account is the same as the to account. A kiválasztott forrásszámla megegyezik a célszámlával. kde-format Couldn't open %1 for reading. %1 nem nyitható meg olvasásra. kde-format Error reading %1. Hiba %1 olvasása közben. kde-format Successfully imported 1 transaction. 1 tranzakciót sikerült importálni. kde-format Successfully imported %n transactions. Unable to import any transactions imported. Nem lehet importálni importált tranzakciókat. kde-format Failed to import 1 data row. Nem lehetett importálni 1 adatsort. kde-format Failed to import %n data rows. Required columns missing. A szükséges oszlopok hiányoznak. kde-format Invalid value. Érvénytelen érték. kde-format Empty category name. Üres kategórianév. kde-format Empty account name. Üres számlanév kde-format Unknown category found. Ismeretlen kategóriát találtam. kde-format Unknown account found. Ismeretlen számlát találtam. kde-format Cannot import security transactions (to/from security accounts). Nem lehet importálni értékpapír-tranzakciókat (cél/forrás értékpapírszámlákat). kde-format Balancing account wrongly used. Rosszult használt mérlegszámla. kde-format Same to and from account/category. Megegyezik a cél- és a forrásszámla/kategória. kde-format No data found. Nem találtam adatot. kde-format Unrecognized date format. Ismeretlen dátumformátum. kde-format Specify Format Formátum meghatározása kde-format The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. A dátumok és/vagy a számok formátuma a CSV fájlban félreérthető. Kérlek, válaszd ki a helyes formátumot. kde-format Date format: Dátumformátum: kde-format Value format: Értékformátum: kde-format tomorrow the day after today holnap kde-format today this day ma kde-format yesterday the day before today tegnap kde-format &Today @option today &Ma kde-format To&morrow @option tomorrow Ho&lnap kde-format Next &Week @option next week Következő &hét kde-format Next M&onth @option next month Következő H&ónap kde-format No Date @option do not specify a date nincs dátum kde-format Export… Exportálás… kde-format Print… Nyomtatás… kde-format Withdrawal Kivét kde-format Join… Belépés… kde-format Split Up Felosztás kde-format Empty transaction list. Üres tranzakciós lista. kde-format Are you sure you want to delete all (%1) selected transactions? Biztosan törölni akarsz minden (%1) kiválasztott tranzakciót? kde-format Cannot set the value of security transactions using the dialog for modifying multiple transactions. Az értékpapír-tranzakciók értékét nem lehet beállítani a többszörös tranzakciók módosítása párbeszédablakban. kde-format Cannot change description of dividends and security transactions. Az értékpapír-tranzakciók és az osztalékok fajtája nem változtatható meg. kde-format Cannot change payer of dividends and security transactions. Az osztalékok és értékpapír-tranzakciók kifizetője nem változtatható meg. kde-format Cannot change date of transactions that are part of a split transaction. Osztott tranzakcióban szereplő tranzakciók dátuma nem változtatható meg. kde-format Eqonomize! Eqonomize! A personal accounting program Személyi könyvelőprogram Start with expenses list displayed Indítás a kiadások listájával Start with incomes list displayed Indítás a bevételek listájával Start with transfers list displayed Indítás az átutalások listájával Document to open Megnyitandó dokumentum Incomes and Expenses Bevételek és kiadások kde-format Profits Nyereségek kde-format All Categories Combined Összes kategória együtt kde-format All Descriptions Combined Összes típus együtt kde-format All Payees/Payers Combined Összes kedvezményezett/kifizető együtt kde-format Start date: Kezdődátum: kde-format End date: Záródátum: kde-format Monthly total Havonta összesen kde-format Daily average Napi átlag kde-format All Payers Combined Összes kifizető együtt kde-format All Payees Combined Összes kedvezményezett együtt kde-format All Descriptions Split Összes típus külön kde-format All Payers Split Összes kifizető külön kde-format All Payees Split Összes kedvezményezett külön kde-format All Categories Split Összes kategória külön kde-format Value (%1) Érték (%1) kde-format Profit (%1) Nyereség (%1) kde-format Income (%1) Bevétel (%1) kde-format Cost (%1) Költség (%1) kde-format Time Idő kde-format no payer nincs kifizető kde-format %1/%2 %1: Description; %2: Payer %1/%2 kde-format no payee nincs kedvezményezett kde-format %1/%2 %1: Description; %2: Payee %1/%2 kde-format Error after saving file; data may not have been saved. Hiba a fájl mentése után; lehet, hogy az adat nincs mentve. kde-format Average Profit Átlagnyereség kde-format Year Év kde-format Month Hónap kde-format Includes scheduled transactions Ütemezett tranzakciókat tartalmaz kde-format Adjusted for the average month / year (%1 / %2 days) Beállítva átlag hónapra / évre (%1 / %2 nap) kde-format Subtotal Részösszeg kde-format Unnamed Névtelen kde-format Uncategorized Kategorizálatlan kde-format Import QIF file QIF fájl importálása kde-format Select a QIF file to import. When you click next, the file be analysed and you might need to answer some questions about the format of the file. Válassz ki egy QIF fájlt importáláshoz. Kattintáskor a fájl elemzése után lehet, hogy válaszolnod kell néhány kérdésre a fájl formátumáról. kde-format Local Definitions Helyi definíciók kde-format Unknown elements where found in the QIF file. It is possible that this is because of localized type names. Please map them to the correct standard names. Ismeretlen elem található a QIF fájlban. Lehet, hogy ez a korlátozott típusnevek miatt van. Térképezd fel ezeket a helyes standard nevekhez. kde-format Local Text Helyi szöveg kde-format Standard Text Standard szöveg kde-format Select standard text: Standard szöveg kiválasztása kde-format Date Format Dátumformátum kde-format The date format in the QIF file is ambiguous. Please select the correct format. A QIF fájl dátumformátuma félreérthető. Válaszd a helyes formátumot. kde-format Default Account Alapértelmezett számla kde-format Could not find any account definitions in the QIF file. Please select a default account. It is also possible that this is caused by a localized opening balance text. Nem található számladefiníció a QIF fájlban. Válassz egy alapértelmezett számlát. kde-format Default account: Alapértelmezett számla: kde-format Opening balance text: Nyitóegyenleg szöveg: kde-format Descriptions Típusok kde-format Transactions in QIF files does not have any specific description property. You are therefore given the option to choose how the description of imported transactions will be set. A QIF fájlban lévő tranzakcióknak nincs specifikus tulajdonsága. Ezért beállíthatod az importált tranzakciók típusát. kde-format Subcategories as: Alkategóriák mint: kde-format Ignore Mellőzés kde-format Payee as: Kedvezményezett mint: kde-format Payee Kedvezményezett kde-format Memo as: Emlékeztető mint: kde-format Priority: Prioritás: kde-format Subcategory/Payee/Comments Alkategória/Kedvezményezett/Megjegyzések kde-format Payee/Subcategory/Comments Kedvezményezett/Alkategória/Megjegyzések kde-format Subcategory/Comments/Payee Alkategória/Megjegyzések/Kedvezményezett kde-format Payee/Comments/Subcategory Kedvezményezett/Megjegyzések/Alkategória kde-format Comments/Subcategory/Payee Megjegyzések/Alkategória/Kedvezményezett kde-format Comments/Payee/Subcategory Megjegyzések/Kedvezményezett/Alkategória kde-format Unknown Ismeretlen kde-format Bank Bank kde-format Cat (Category) Kat. (Kategória) kde-format CCard (Credit Card) H.kártya (Hitelkártya) kde-format Invst (Investment) Befekt. (Befektetés) kde-format Oth A (Other Assets) Egyéb vagyon kde-format Oth L (Other Liabilities) Egyéb köt. (Egyéb kötelezettségek) kde-format Security Értékpapír kde-format Successfully imported 1 account. 1 számla sikeresen importálva. kde-format Successfully imported %n accounts. Successfully imported 1 category. 1 kategória sikeresen importálva. kde-format Successfully imported %n categories. 1 duplicate transaction was ignored. 1 megismételt tranzakció mellőzve. kde-format %n duplicate transactions was ignored. Failed to import 1 transaction. 1 tranzakció sikertelen importálása. kde-format Failed to import %n transactions. 1 security was not imported. 1 értékpapír nem lett importálva. kde-format %n securities were not imported. 1 security transaction was not imported. 1 értékpapír-tranzakció nem lett importálva. kde-format %n security transactions were not imported. Export QIF File QIF fájl exportálása kde-format All All accounts Összes kde-format Export transaction description as: Alábbi tranzakció-típusok exportálása: kde-format Memo Emlékeztető kde-format Subcategory Alkategória kde-format &Import i18n: tag text i18n: file ./eqonomizeui.rc line 5 &Importálás kde-format &Accounts i18n: tag text i18n: file ./eqonomizeui.rc line 12 &Számlák kde-format &Transactions i18n: tag text i18n: file ./eqonomizeui.rc line 24 &Tranzakciók kde-format &Securities i18n: tag text i18n: file ./eqonomizeui.rc line 41 &Értékpapírok kde-format Stat&istics i18n: tag text i18n: file ./eqonomizeui.rc line 56 Stat&isztikák kde-format Your names NAME OF TRANSLATORS ,Launchpad Contributions:,Gergely Szarka,Nandor Novak kde-format Your emails EMAIL OF TRANSLATORS ,,szarka.honved@gmail.com,nannov@gmail.com kde-format Edit Exceptions Kivételek szerkesztése kde-format Edit Recurrence Range Ismétlődési tartomány szerkesztése kde-format Begins on: %1 Kezdés: %1 kde-format No ending date Nincs záródátum kde-format End after Zárás kde-format occurrence(s) előfordulás után kde-format End on Záródátum kde-format End date before start date. A záródátum a kezdődátum előtt van. kde-format Enable recurrence Ismétlés megengedése kde-format Recurrence Rule Ismétlési szabály kde-format Weekly Hetente kde-format Recur every Ismétlődik minden kde-format day(s) . napon kde-format week(s) on: . héten: kde-format month(s), after the start month . hónapban, a kezdőhónap után kde-format Recur on the Ismétlődik minden kde-format 1st 1. kde-format 2nd 2. kde-format 3rd 3. kde-format 4th 4. kde-format 5th 5. kde-format 6th 6. kde-format 7th 7. kde-format 8th 8. kde-format 9th 9. kde-format 10th 10. kde-format 11th 11. kde-format 12th 12. kde-format 13th 13. kde-format 14th 14. kde-format 15th 15. kde-format 16th 16. kde-format 17th 17. kde-format 18th 18. kde-format 19th 19. kde-format 20th 20. kde-format 21st 21. kde-format 22nd 22. kde-format 23rd 23. kde-format 24th 24. kde-format 25th 25. kde-format 26th 26. kde-format 27th 27. kde-format 28th 28. kde-format 29th 29. kde-format 30th 30. kde-format 31st 31. kde-format Last Utolsó kde-format 2nd Last Utolsó előtti kde-format 3rd Last Hátulról 3. kde-format 4th Last Hátulról 4. kde-format 5th Last Hátulról 5. kde-format day nap kde-format possibly on weekend Esetleg hétvégén kde-format but before weekend de hétvége előtt kde-format but after weekend de hétvége után kde-format year(s), after the start year . évben, a kezdőév után kde-format Recur on day part before XXX of 'Recur on day XXX of month YYY' Ismétlés e napon: kde-format of part between XXX and YYY of 'Recur on day XXX of month YYY' e hónapban: kde-format On the Part before NNN in 'Recur on the NNN. WEEKDAY of MONTH' e napon: kde-format of part between WEEKDAY and MONTH in 'Recur on NNN. WEEKDAY of MONTH' e hónapban: kde-format Recur on day # Ismétlés e napon: kde-format of the year part after NNN of 'Recur on day #NNN of the year' . napján az évnek kde-format Range… Terjedelem… kde-format Exceptions… Kivételek… kde-format No day of week selected for weekly recurrence. A hét egy napját sem választottad ki heti ismétlődéshez. kde-format Selected day will never occur with selected frequency and start date. A kiválasztott nap soha nem következik be a választott gyakorisággal és kezdődátummal. kde-format Selected day does not exist in selected month. A kiválasztott nap nem létezik a választott hónapban. kde-format Dividend: %1 Osztalék: %1 kde-format Account balancing Számlaegyenleg kde-format Security: %1 (bought) Értékpapír: %1 (vétel) kde-format Security: %1 (sold) Értékpapír: %1 (eladás) kde-format Shares bought: Vett részvények: kde-format Shares sold: Eladott részvények: kde-format Payer: Kifizető: kde-format Payee: Kedvezményezett: kde-format No income category available. Nincs rendelkezésre álló bevételi kategória. kde-format No expense category available. Nincs rendelkezésre álló kiadási kategória. kde-format Cannot create a regular transfer to/from a securities account. Nem hozható létre állandó átutalás értékpapírszámlára/-ról. kde-format Cannot create a regular income to a securities account. Nem hozható létre állandó bevétel értékpapírszámlára. kde-format Zero price per share not allowed. Nulla részvényenkénti ár nem megengedett. kde-format Cannot create a regular expense from a securities account. Nem hozható létre állandó kiadás értékpapírszámláról. kde-format Modify Transactions Módosított tranzakciók kde-format Min amount: Min. összeg: kde-format Max amount: Max. összeg: kde-format Min income: Min. bevétel: kde-format Max income: Max. bevétel: kde-format Min cost: Min. költség: kde-format Max cost: Max. költség: kde-format Include Tartalmaz kde-format Exclude Kizár kde-format From Account Számláról kde-format To Account Számlára kde-format Payer Kifizető kde-format New/Edit Expense Új kiadás/Kiadás szerkesztése kde-format Filter Szűrő kde-format Total: Összeg: kde-format Average: Átlag: kde-format Monthly: Havonta: kde-format Total cost: Összes költség: kde-format Total income: Összes bevétel: kde-format Total amount: Teljes összeg: kde-format Monthly average: Havi átlag: kde-format Are you sure you want to delete all (%1) transactions in the selected split transaction? Biztosan törölni akarsz minden (%1) tranzakciót a kiválasztott osztott tranzakcióban? kde-format * Part of split transaction * Osztott tranzakció része kde-format * Part of split (%1) * A (%1) osztott tranzakció része kde-format ** Recurring (editing occurrence) ** Ismétlődés (események szerkesztése) kde-format Modify… Módosítás… kde-format AccountComboBox New account… Új számla… Multiple accounts/payments… New income category… Új bevételi kategória… New expense category… Új kiadási kategória… Paid with loan… New Account Új számla New Income Category Új bevételi kategória New Expense Category Új kiadási kategória AccountsMenu All Accounts Összes számla All Categories Combined Összes kategória együtt %n accounts %n számlak %n categories %n kategória Balancing Account balancing Számlaegyenleg Account balancing Balancing of an account Számlaegyenleg Account Balance Adjustment Budget Balancing Kiegyenlítés Balancing Name of account for transactions that adjust account balances Kiegyenlítés Couldn't open %1 for reading %1 nem nyitható meg olvasásra Not a valid Eqonomize! file (XML parse error: "%1" at line %2, col %3) Nem érvényes Eqonomize!-fájl (XML parse error: "%1" a(z) %2. sorban, a(z) %3. oszlopban) Invalid root element %1 in XML document Érvénytelen %1 elem az XML dokumentumban Unknown XML element: "%1" at line %2, col %3 XML parse error: "%1" at line %2, col %3 European Euro Unable to load %n currency/currencies. No exchange rates found. USD currency missing. imported Unable to load %n account(s). Nem lehet betölteni %n számlát. Unable to load %n category/categories. Nem lehet betölteni %n kategóriát. Unable to load %n security/securities. Financial security (e.g. stock, mutual fund) Nem lehet betölteni %n értékpapírt. Download command (%1) failed: %2. Failed to download file from %1: %2. Upload command (%1) failed: %2. yyyy-yy Financial year when first month is not January (e.g. 2018-19). Transaction Accounts Folyószámlák Savings Accounts Takarékszámlák Credit Cards Hitelkártyák Debts Adósságok Securities Financial security (e.g. stock, mutual fund) Értékpapírok Cash Készpénz Transaction Account Folyószámla Savings Account Takarékbetét-számla Credit Card Hitelkártya Debt Adósság Other Egyéb Unable to load %n security/securities. Nem lehet betölteni %n értékpapírt. Unable to load %n transaction(s). Nem lehet betölteni %n tranzakciót. File is a directory A fájl egy könyvtár Couldn't open file for writing Nem írható fájl Error while writing file; file was not saved Hiba írás közben; a fájl nem lett elmentve Unnamed Névtelen Uncategorized Kategorizálatlan CategoriesComparisonChart Save As… Mentés másként… Print… Nyomtatás… From Eredet To Cél Source: Forrás: All Expenses Összes kiadás All Incomes Összes bevétel Theme: Chart type: Pie Chart Bar Chart Default All Expenses, without subcategories All Expenses, with subcategories All Incomes, without subcategories All Incomes, with subcategories All Accounts Összes számla Expenses: %1 Kiadások: %1 Incomes: %1 Bevételek: %1 Error Invalid date. Érvénytelen dátum. To date is before from date. A záródátum korábbi, mint a kezdődátum. From date is after to date. A kezdődátum későbbi, mint a záródátum. Couldn't open file for writing. Nem írható fájl. Error while writing file; file was not saved. Hiba írás közben; a fájl nincs elmentve. Expenses Kiadások Expenses, %1 Kiadások, %1 Incomes, %1 Bevételek, %1 Incomes Bevételek Accounts Számlák Expenses, %2: %1 Kiadások, %2: %1 Incomes, %2: %1 Bevételek, %2: %1 Other descriptions Referring to the transaction description property (transaction title/generic article name) No description Referring to the transaction description property (transaction title/generic article name) Nincs leírás Other accounts Other categories %1 Value: %2 No description Referring to the Transaction description property (transaction title/generic article name) Nincs leírás No description Referring to the generic description property Nincs leírás Value Érték Income Bevétel Cost Költség Value (%1) Érték (%1) Income (%1) Bevétel (%1) Cost (%1) Költség (%1) No description Nincs leírás CategoriesComparisonChartDialog Chart Grafikon CategoriesComparisonReport Save As… Mentés másként… Print… Nyomtatás… Source: Forrás: All Categories, excluding subcategories All Categories, including subcategories All Payees/Payers Összes kedvezményezett/kifizető Subcategories Alkategória Descriptions for Referring to the Transaction description property (transaction title/generic article name) Típusok All descriptions Referring to the Transaction description property (transaction title/generic article name) Összes típus No description Referring to the Transaction description property (transaction title/generic article name) Nincs leírás All Categories Összes kategória Expenses: %1 Kiadások: %1 Incomes: %1 Bevételek: %1 Descriptions for Típusok Payees/payers for Kedvezményezettek/kifizetők Descriptions Referring to the Transaction description property (transaction title/generic article name) Típusok Period: Periódus: From Eredet To Cél Columns: Oszlopok: Value Érték Daily Naponta Monthly Havonta Yearly Évente Quantity Mennyiség Average value Átlagérték All descriptions Összes típus All payees Összes kedvezményezett All payers Összes kifizető No description Nincs leírás Descriptions for Referring to the generic description property Típusok Descriptions Referring to the generic description property Típusok All descriptions Referring to the generic description property Összes típus No description Referring to the generic description property Nincs leírás All Payees and Payers Összes kedvezményezett és kifizető Tag: %1 Descriptions for Referring to the transaction description property (transaction title/generic article name) Típusok Descriptions Referring to the transaction description property (transaction title/generic article name) Típusok Months Hónap Years Évek Tags Total: Összeg: All descriptions Referring to the transaction description property (transaction title/generic article name) Összes típus All payees/payers Összes kedvezményezett/kifizető No description Referring to the transaction description property (transaction title/generic article name) Nincs leírás No payee Nincs kedvezményezett No payer Nincs kifizető Error Invalid date. Érvénytelen dátum. To date is before from date. A záródátum korábbi, mint a kezdődátum. From date is after to date. A kezdődátum későbbi, mint a záródátum. Couldn't open file for writing. Nem írható fájl. Error while writing file; file was not saved. Hiba írás közben; a fájl nincs elmentve. Expenses, %2: %1 Kiadások, %2: %1 Expenses, %3: %2, %1 Kiadások, %3: %2, %1 Incomes, %2: %1 Bevételek, %2: %1 Incomes, %3: %2, %1 Bevételek, %3: %2, %1 %3: %2, %1 %2: %1 Tags, %1 Incomes & Expenses, %1 Bevételek és kiadások, %1 Expenses: %2, %1 Kiadások: %2, %1 Incomes: %2, %1 Bevételek: %2, %1 %2, %1 %1 %1 Incomes & Expenses Bevételek és kiadások %1 (%2&ndash;%3) html format; %1: title; %2: from date; %3: to date %1 (%2&ndash;%3) %1 (to %2) html format; %1: title; %2: to date %1 (%2-ig) Category Kategória Payee Kedvezményezett Description Referring to the transaction description property (transaction title/generic article name) Leírás Cost Költség Payer Kifizető Income Bevétel Payee/Payer Kedvezményezett/kifizető Tag Daily Average Napi átlag Monthly Average Havi átlag Yearly Average Éves átlag Average Cost Átlagos költség Average Income Átlagos bevétel Average Value Átlagos érték No payee/payer Nincs kedvezményezett/kifizető Total Összesen All Tags Total incomes Bevétel összesen Total expenses Kiadás összesen Total (Profits) Összes (nyereség) CategoriesComparisonReportDialog Report Jelentés ConfirmScheduleDialog The following transactions was scheduled to occur today or before today. Confirm that they have indeed occurred (or will occur today). A következő tranzakciók teljesítése volt tervezve a mai napra vagy korábbra. Erősítsd meg, hogy ezek valóban teljesültek (vagy teljesülnek a mai napon). Date Dátum Type Típus Description Leírás Name Név Description Generic Description Leírás Description Transaction description property (transaction title/generic article name) Leírás Amount Mennyiség Edit… Szerkesztés… Postpone… Halasztás… Delete Törlés Error Can only postpone to future dates. Csak jövőbeli dátumra halasztható. ConfirmScheduleListViewItem Transfer Átutalás Dividend Osztalék Income Bevétel Expense Kiadás Securities Purchase Financial security (e.g. stock, mutual fund) Értékpapír vétel Securities Sale Financial security (e.g. stock, mutual fund) Értékpapír eladás Security Buy Értékpapír vétel Security Sell Értékpapír eladás Debt Payment CurrencyConversionDialog Currency Converter DebtFee Debt payment: %1 (fee) DebtInterest Debt payment: %1 (interest) DebtPayment Debt payment: %1 DebtReduction Debt payment: %1 (reduction) DescriptionsMenu All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Összes típus együtt All Tags Combined All Payees Combined Összes kedvezményezett együtt All Payers Combined Összes kifizető együtt All Payees/Payers Combined Összes kedvezményezett/kifizető együtt No description Referring to the transaction description property (transaction title/generic article name) Nincs leírás No payee Nincs kedvezményezett No payer Nincs kifizető No payee/payer Nincs kedvezményezett/kifizető %n descriptions Referring to the transaction description property (transaction title/generic article name) %n típusok %n tags %n payees %n kedvezményezett %n payers %n kifizető %n payees/payers %n kedvezményezettek/kifizetők EditAssetsAccountDialog Type: Típus: Cash Készpénz Current Account Folyószámla Savings Account Takarékbetét-számla Credit Card Hitelkártya Liabilities Tartozások Transactional Account Folyószámla Debt Adósság Securities Értékpapírok Other Egyéb Currency: Edit Szerkesztés Name: Név: Bank: Bank: Initial balance: Nyitóegyenleg: Debt: Initial balance Nyitóegyenleg Group: no group Transferred to: Date: Dátum: Lender: Default account for budgeted transactions Alapértelmezett számla a költségvetési tranzakciókhoz Description: Leírás: Account is closed Warning Type cannot be changed to securities for accounts with transactions. Issuer: Zero value not allowed. Nulla érték nem megengedett. Error Transaction Account Folyószámla Opening balance: Account balance Nyitóegyenleg: Opening balance Account balance Nyitóegyenleg New currency… If you change the currency of an account, the currency of all associated transactions will also change, without any conversion. Do do wish to continue anyway? Empty name. Üres név. The entered name is used by another account. A megadott név másik számláé. EditCurrencyDialog Edit Currency New Currency Code: Symbol: Prefix Suffix Default Name: Név: Decimals: Date: Dátum: Main currency Error Error saving currencies: %1. Empty code. Code already exists. EditDebtPaymentDialog Debt Payment EditDebtPaymentWidget Debt: Date: Dátum: Debt reduction: Reduction payment: Interest: Paid Added to debt Fee: Account: Számla: Expense category: Kiadási kategória: Associated file: Select a file Open the file Comments: Megjegyzések: Related to: Label for linked transactions Linkek: Total value: Összes érték: Error No suitable account available. Nincs megfelelő számla. Invalid date. Érvénytelen dátum. Interest must not be zero. At least one value must non-zero. EditExceptionsDialog Edit Exceptions Kivételek szerkesztése Occurrences: Add Exception Remove Exception Exceptions: Only the first fifty occurrences are shown. Invalid date. Érvénytelen dátum EditExpensesAccountDialog Name: Név: Parent category: None Monthly budget: Havi költségvetés: Description: Leírás: Error Empty name. Üres név. The entered name is used by another expense category. A megadott név másik kiadási kategóriáé. EditIncomesAccountDialog Name: Név: Parent category: None Monthly budget: Havi költségvetés: Description: Leírás: Error Empty name. Üres név. The entered name is used by another income category. A megadott név másik bevételi kategóriáé. EditLoanTransactionWidget Date: Dátum: Account: Számla: Comments: Megjegyzések: Total value: Összes érték: No suitable account available. Nincs megfelelő számla. Invalid date. Érvénytelen dátum EditMultiAccountDialog Expense with Multiple Payments Income with Multiple Payments EditMultiAccountWidget Description: Leírás: Description: Generic Description Leírás: Description: Transaction description property (transaction title/generic article name) Leírás: Quantity: Mennyiség: Category: Kategória: Tags: Associated file: Select a file Open the file Comments: Megjegyzések: Related to: Label for linked transactions Linkek: Transactions: Tranzakciók: Date Dátum Account Számla Payee Kedvezményezett Payer Kifizető Cost Költség Income Bevétel Total cost: Összes költség: Value Érték New Új Edit… Szerkesztés… Delete Törlés Total value: Összes érték: Error No suitable expense categories available. A split must contain at least two transactions. Egy osztott tranzakció legalább két tranzakcióból áll. EditMultiItemDialog Split Transaction Osztott tranzakció EditMultiItemWidget Description: Leírás: Description: Generic Description Leírás: Date: Dátum: Account: Számla: Payee/Payer: Kedvezményezett/kifizető: Transactions: Tranzakciók: Type Típus Description Generic Description Leírás Description: Transaction description property (transaction title/generic article name) Leírás: Tags: Associated file: Select a file Open the file Comments: Megjegyzések: Related to: Label for linked transactions Linkek: Description Transaction description property (transaction title/generic article name) Leírás Payment Fizetés Deposit Letét New Új New Expense… Új kiadás… New Income… Új bevétel… New Deposit… Új letét… New Withdrawal… Új kivét… New Securities Purchase… Financial security (e.g. stock, mutual fund) Új értékpapír vétel… New Securities Sale… Financial security (e.g. stock, mutual fund) Új értékpapír eladás… Shares Bought… Részvények vásárlása… Shares Sold… Részvények eladása… Account/Category Számla/Kategória Value Érték Income Bevétel Expense Kiadás New Dividend… Új osztalék… Edit… Szerkesztés… Delete Törlés Total value: Összes érték: Error No suitable account available. Nincs megfelelő számla. Invalid date. Érvénytelen dátum. A split must contain at least two transactions. Egy osztott tranzakció legalább két tranzakcióból áll. Cannot transfer money to and from the same account. Nem lehet átutalni ugyanarról ugyanarra a számlára. EditQuotationsDialog Quotations Árfolyamok Date Dátum Price per Share Részvényenkénti ár Quotations Financial quotation Árfolyamok Quotes Financial quote Árfolyamok Price per Share Financial Shares Részvényenkénti ár Add Hozzáadás Modify Módosítás Delete Törlés Import… Importálás… Export… Exportálás… Quotes for %1 Financial quote %1 árfolyamai Quotations for %1 Financial quotation %1 árfolyamai Quotations for %1 %1 árfolyamai Error Couldn't open %1 for reading. %1 nem nyitható meg olvasásra. Error reading %1. Hiba %1 olvasása közben. Successfully imported %n quote(s). %n árfolyamok sikeresen importálva. Unable to import any quotes. Failed to import %n data row(s). Nem lehetett importálni %n adatsort. Required columns missing. A szükséges oszlopok hiányoznak. Invalid value. Érvénytelen érték. Invalid date. Érvénytelen dátum. No data found. Nem találtam adatot. Information Unrecognized date format. Ismeretlen dátumformátum. Specify Format Formátum meghatározása The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. A dátumok és/vagy a számok formátuma a CSV fájlban félreérthető. Kérlek, válaszd ki a helyes formátumot. Date format: Dátumformátum: Value format: Értékformátum: Couldn't open file for writing. Nem írható fájl. Quotes: %1 Árfolyamai: %1 Error while writing file; file was not saved. Hiba írás közben; a fájl nincs elmentve. EditRangeDialog Edit Recurrence Range Ismétlődési tartomány szerkesztése Begins on: %1 Kezdés: %1 No ending date Nincs záródátum End after Zárás occurrence(s) előfordulás után End on Záródátum Error Invalid date. Érvénytelen dátum. End date before start date. A záródátum a kezdődátum előtt van. EditReinvestedDividendDialog Reinvested Dividend Újra befektetett osztalék Security: Értékpapír: Shares added: Hozzáadott részvények: Security: Financial security (e.g. stock, mutual fund) Értékpapír: Shares added: Financial shares Hozzáadott részvények: Date: Dátum: Invalid date. Érvénytelen dátum. EditScheduledDebtPaymentDialog Transaction Tranzakciók Recurrence Ismétlődés Edit Debt Payment New Debt Payment EditScheduledLoanTransactionDialog Recurrence Ismétlődés EditScheduledMultiAccountDialog Transactions Tranzakciók Recurrence Ismétlődés New Expense with Multiple Payments New Income with Multiple Payments Edit Expense with Multiple Payments Edit Income with Multiple Payments EditScheduledMultiItemDialog Transactions Tranzakciók Recurrence Ismétlődés New Split Transaction Új osztott tranzakció Edit Split Transaction Osztott tranzakció szerkesztése EditScheduledTransactionDialog Expense Kiadás Dividend Osztalék Income Bevétel Reinvested Dividend Újra befektetett osztalék Transfer Átutalás Security Buy Értékpapír vétel Security Sell Értékpapír eladás Securities Purchase Financial security (e.g. stock, mutual fund) Értékpapír vétel Securities Sale Financial security (e.g. stock, mutual fund) Értékpapír eladás Recurrence Ismétlődés New Expense Új kiadás New Expense Paid with Loan New Dividend Új osztalék New Income Új bevétel New Transfer Új átutalás New Securities Purchase Financial security (e.g. stock, mutual fund) Új értékpapír vétel New Reinvested Dividend New Securities Sale Financial security (e.g. stock, mutual fund) Új értékpapír eladás Edit Reinvested Dividend Edit Securities Purchase Financial security (e.g. stock, mutual fund) Értékpapír vétel szerkesztése Edit Securities Sale Financial security (e.g. stock, mutual fund) Értékpapír eladás szerkesztése New Security Buy Új értékpapír vétel New Security Sell Új értékpapír eladás Edit Expense Kiadás szerkesztése Edit Dividend Osztalék szerkesztése Edit Income Bevétel szerkesztése Edit Transfer Átutalás szerkesztése Edit Securities Bought Értékpapír vétel szerkesztése Edit Securities Sold Értékpapír eladás szerkesztése EditSecurityDialog Type: Típus: Mutual Fund Befektetési alap Bond Kötvény Stock Részvény Stock Financial stock Részvény Other Egyéb Name: Név: Account: Számla: Decimals in shares: Financial shares Törtek a részvényekben: Initial shares: Financial shares Kezdeti részvények: Decimals in quotes: Financial quote Initial quote: Financial quote Kezdő árfolyam: Empty name. Üres név. No suitable account available. Nincs megfelelő számla. Initial quotation: Financial quotation Kezdő árfolyam: Decimals in shares: Törtek a részvényekben: Initial shares: Kezdeti részvények: Decimals in Shares: Törtek a részvényekben: Initial Shares: Kezdeti részvények: Initial quotation: Kezdő árfolyam: Date: Dátum: Description: Leírás: Error No suitable account or income category available. Nincs megfelelő számla vagy bevétel kategória. EditSecurityTradeDialog Security Trade Értékpapír-forgalom From security: Forrás értékpapír: Shares moved: Áthelyezett részvények: All Összes To security: Cél értékpapír: Shares received: Kapott részvények: Securities Exchange Shares of one security directly exchanged for shares of another; Financial security (e.g. stock, mutual fund) Értékpapír-forgalom From security: Financial security (e.g. stock, mutual fund) Forrás értékpapír: Shares moved: Financial shares Áthelyezett részvények: To security: Financial security (e.g. stock, mutual fund) Cél értékpapír: Shares received: Financial shares Kapott részvények: Value: Érték: Date: Dátum: Error No other security available for exchange in the account. Shares of one security directly exchanged for shares of another; Financial security (e.g. stock, mutual fund) Nincs más értékesíthető értékpapír a számlán. No other security available for trade in the account. Nincs más értékesíthető értékpapír a számlán. Selected to and from securities are the same. Financial security (e.g. stock, mutual fund) A kiválasztott cél és forrás értékpapírok ugyanazok. Zero shares not allowed. Financial shares Nulla részvény nem megengedett. Selected to and from securities are the same. A kiválasztott cél és forrás értékpapírok ugyanazok. Invalid date. Érvénytelen dátum. Zero shares not allowed. Nulla részvény nem megengedett. Zero value not allowed. Nulla érték nem megengedett. EditSplitDialog Split Transaction Osztott tranzakció Description: Leírás: Date: Dátum: Account: Számla: Transactions: Tranzakciók: Type Típus Description Leírás Name: Név: Name Név Description Generic Description Leírás Account/Category Számla/Kategória Payment Fizetés Deposit Letét New Új New Expense… Új kiadás… New Income… Új bevétel… New Deposit… Új letét… New Withdrawal… Új kivét… Shares Bought… Részvények vásárlása… Shares Sold… Részvények eladása… New Dividend… Új osztalék… Edit… Szerkesztés… Total value: Összes érték: No suitable account available. Nincs megfelelő számla. Invalid date. Érvénytelen dátum Future dates is not allowed. Jövőbeli dátum nem megengedett. A split must contain at least two transactions. Egy osztott tranzakció legalább két tranzakcióból áll. Cannot transfer money to and from the same account. Nem lehet átutalni ugyanarról ugyanarra a számlára. Eqonomize Accounts && Categories Számlák és kategóriák Expenses Kiadások Incomes Bevételek Transfers Átutalások Transaction Accounts Folyószámlák Savings Accounts Takarékszámlák Credit Cards Hitelkártyák Debts Adósságok Securities Értékpapírok Schedule Ütemterv Account / Category Számla / Kategória Remaining Budget (%1) Hátralévő költségvetés (%1) Change (%1) Változás (%1) Total (%1) Összesen (%1) %2 of %1 %2 remains of %1 budget %2 maradt (terv: %1) Accounts Számlák Includes budgeted transactions Költségvetési tranzakciókat tartalmaz Tags Period Időszak From Eredet To Cél Select Period Válassz időszakot Current Month Aktuális hónap Current Year Aktuális év Current Whole Month Aktuális teljes hónap Current Whole Year Aktuális teljes év Whole Past Month Teljes múlt hónap Whole Past Year Teljes múlt év Previous Month Előző hónap Previous Year Előző év Show partial budget Mutasd a részleges költségvetést Edit Budget Költségvetés szerkesztése Budget: Költségvetés: Month: Hónap: Result previous month: Előző havi eredmény: New Security… Új értékpapír… New Transaction Új tranzakció Set Quotation… Árfolyam beállítása… Name Név Value Érték Shares Részvények Quotation Árfolyam Cost Költség Profit Nyereség Yearly Rate Éves kamatláb Type Típus Account Számla Statistics Period Statisztikai időszak New Schedule Új ütemterv Edit Szerkesztés Remove Törlés Next Occurrence Következő esemény Description Leírás Description Generic Description Leírás Amount Mennyiség Payee/Payer Kedvezményezett/kifizető Comments Megjegyzések Set Schedule Confirmation Time Schedule confirmation time: Set Budget Period First day in budget month: 1st 1. 2nd 2. 3rd 3. 4th 4. 5th 5. 6th 6. 7th 7. 8th 8. 9th 9. 10th 10. 11th 11. 12th 12. 13th 13. 14th 14. 15th 15. 16th 16. 17th 17. 18th 18. 19th 19. 20th 20. 21st 21. 22nd 22. 23rd 23. 24th 24. 25th 25. 26th 26. 27th 27. 28th 28. Last Utolsó 2nd Last Utolsó előtti 3rd Last Hátulról 3. 4th Last Hátulról 4. 5th Last Hátulról 5. Timestamp Links Linkek Remove Link Link to "%1" create link to transaction (link used as verb) All Összes Import Options Ignore duplicate transactions Rename duplicate accounts Rename duplicate categories Rename duplicate securities Synchronization Settings Web address: Download command: Duplicate Transaction… duplicate as verb Create Link create link to or between transaction(s) Link létrehozása New Tag… Rename Tag… Remove Tag New Tag Tag name: Remove tag? Do you wish to remove the tag "%1" from %n transaction(s)? Rename Tag optional Right align Jobbra igazítás Upload command: mandatory Automatic synchronization Upload Uploading… Error uploading file Error uploading %1: %2. Synchronizing… Error synchronizing file Error synchronizing %1: %2. Synchronization error Synchronize file? The file has been modified by a different user or program. Do you wish to merge changes? New version available A new version of %1 is available.<br><br>You can get version %2 at %3. Abort First month in budget year: %f = local file (temporary), %u = url Failed to download exchange rates from %1: %2. Error reading data from %1: %2. Unrecognized Currency No exchange rate is available for the default currency (%1). If you wish to use multiple currencies you should set the exchange rate manually. Set Main Currency Currency: Replace all occurrences of the former main currency Transaction Account Folyószámla S&ynchronize Import %1 File… Reconcile Account… Adjust balance… Referring to account balance Close Account Mark account as closed New Expense Paid with Loan… Show payee and quantity Show quantity and payer/payee properties for incomes and expenses. Set Schedule Confirmation Time… Select Font… Language Nyelv Default Restart required Only use this when unable to find the cause of the incorrect recorded account balance. Reopen Account Mark account as not closed New Debt Payment… New Unpaid Interest… Use Exchange Rate for Transaction Date Use the exchange rate nearest the transaction date, instead of the latest available rate, when converting the value of transactions. %1 exited unexpectedly before the file was saved and data was lost. Do you want to load the last auto-saved version of the file? Eqonomize! Accounting File Adjust Account Balance New Security Új értékpapír Edit Security Értékpapír szerkesztése Total value: Összes érték: Cost: Költség: Profit: Nyereség: Rate: Kamat: Are you sure you want to delete the security "%1" and all associated transactions? Valóban törölni akarod a "%1" értékpapírt és minden kapcsolódó tranzakciót? Error No security available. Nincs lehetséges értékpapír. Set Quotation (%1) Árfolyam beállítása (%1) Price per share: Részvényenkénti ár: Date: Dátum: Invalid date. Érvénytelen dátum. Future dates are not allowed. Jövőbeli dátumok nem megengedettek. Security Transactions Értékpapír tranzakciók Bond Kötvény Stock Részvény Mutual Fund Befektetési alap Other Egyéb Add Loan Add Category Ledger Főkönyv To date is before from date. A záródátum korábbi, mint a kezdődátum. From date is after to date. A kezdődátum későbbi, mint a záródátum. Cash Készpénz Check Account Számlaellenőrzés Savings Account Takarékbetét-számla Salary Fizetés Bills Számlák Clothing Ruházat Groceries Élelmiszer Leisure Szabadidő Couldn't open file Nem lehetett megnyitni a fájlt Error loading %1: %2. Hiba %1 betöltése közben: %2. Couldn't save file Nem lehetett menteni a fájlt Error saving %1: %2. Hiba %1 mentése közben: %2. Updating exchange rates… Error saving currencies: %1. New currency… Transaction Schedule Tranzakciós ütemterv Total Összesen Accounts &amp; Categories html format Számlák &amp; Kategóriák Accounts &amp; Categories (%1&ndash;%2) html format Számlák &amp; Kategóriák (%1&ndash;%2) Accounts &amp; Categories (to %1) html format Számlák &amp; Kategóriák (%1-hoz/hez) Change Noun, how much the account balance has changed Változás Balance Egyenleg Current Account Folyószámla Credit Card Hitelkártya Liabilities Tartozások Set Quote… Financial quote Árfolyam beállítása… Quote Financial quote Árfolyam Set Quote (%1) Financial quote Árfolyam beállítása (%1) Stock Financial stock Részvény Balance Noun. Balance of an account Egyenleg Category Kategória Budget Költségvetés Remaining Budget Hátralevő költségvetés Total Incomes Összes bevétel Costs Költségek Total Expenses Összes kiadás Account/Category Noun, how much the account balance has changed Számla/Kategória Empty expenses list. Üres kiadási lista. Empty incomes list. Üres bevételi lista. Empty transfers list. Üres átutalási lista. Empty securities list. Üres értékpapírlista. Empty schedule list. Üres ütemterv lista. Couldn't open file for writing. Nem írható fájl. Error while writing file; file was not saved. Hiba írás közben; a fájl nincs elmentve. &File &Fájl &Accounts &Számlák &Transactions &Tranzakciók &Securities &Értékpapírok Stat&istics Stat&isztikák S&ettings &Beállítások &Help S&úgó File Fájl Transactions Tranzakciók Statistics Statisztikák &New &Új &Open… &Megnyitás… Open Recent Legutóbbi megnyitása Clear List A lista törlése &Save M&entés Save As… Mentés másként… &Revert &Újratöltés &Print… &Nyomtatás… Print Preview… Nyomtatási előnézet… Import Importálás Import CSV File… CSV fájl importálása… Import QIF File… QIF fájl importálása… Export View… Exportálási nézet… Export As QIF File… Exportálás QIF fájlként… Update Exchange Rates Currency Converter &Quit &Kilépés Add Account… Számla hozzáadása… New Account… Új számla… New Loan… New Income Category… Új bevételi kategória… New Expense Category… Új kiadási kategória… Add Account Számla hozzáadása Assets Vagyon Description Transaction description property (transaction title/generic article name) Leírás Security Transactions Financial security (e.g. stock, bond) Értékpapír tranzakciók &Loans &Hitel Edit… Szerkesztés… Balance… Egyenleg… Show Transactions Tranzakciók megmutatása Show Ledger New Expense… Új kiadás… New Income… Új bevétel… New Transfer… Új átutalás… New Split Transaction… Új osztott tranzakció… New Expense with Multiple Payments… Refund… Visszatérítés… Repayment… Visszafizetés… New Refund/Repayment… Új visszatérítés/visszafizetés… Edit Transaction(s) (Occurrence)… Tranzakció(k) szerkesztése (Eseti)… Edit Occurrence… Esemény szerkesztése… Edit Schedule (Recurrence)… Ütemterv szerkesztése (ismétlődő)… Edit Schedule… Ütemterv szerkesztése… Edit Split Transaction… Osztott tranzakció szerkesztése… Join Transactions… join transactions together Tranzakciók egyesítése… Split Up Transaction split up joined transactions Tranzakciók felosztása Edit Timestamp… Select Associated File Open Associated File Remove Transaction(s) (Occurrence) Tranzakció(k) visszavonása (Eseti) Remove Occurrence Visszavont esemény Delete Schedule (Recurrence) Ütemterv törlése (ismétlődő) Delete Schedule Törölt ütemterv Remove Split Transaction Osztott tranzakció visszavonása Edit Security… Értékpapír szerkesztése… Remove Security Értékpapír visszavonása Shares Bought… Részvények vásárlása… Shares Sold… Részvények eladása… Shares Moved… Részvények mozgatása… Dividend… Osztalék… Reinvested Dividend… Osztalék újrabefektetése… Transactions… Tranzakciók… Edit Quotations… Árfolyamok szerkesztése… Development Over Time Report… Időbeli fejlődés jelentés… Categories Comparison Report… Kategória-összehasonlító jelentés… Development Over Time Chart… Időbeli fejlődés grafikon… Categories Comparison Chart… Kategória-összehasonlító grafikon… Use Additional Transaction Properties Kiegészítő tranzakció tulajdonságok használata Set Main Currency… Set Budget Period… Initial Period Kezdő periódus Remember Last Dates Utolsó dátumok megjegyzése Backup Frequency Daily Naponta Weekly Hetente Fortnightly Monthly Havonta Never Cloud Synchronization (experimental)… Dark Mode Help Report Bug About %1 About Qt Please restart the application for the language change to take effect. A personal accounting program Személyi könyvelőprogram License: GNU General Public License Version 3 Crash Recovery Helyreállítás Untitled Névtelen Securities Financial security (e.g. stock, mutual fund) Értékpapírok New Security… Financial security (e.g. stock, mutual fund) Új értékpapír… Set Quotation… Financial quotation Árfolyam beállítása… Shares Financial shares Részvények Quotation Financial quotation Árfolyam New Security Financial security (e.g. stock, mutual fund) Új értékpapír Edit Security Financial security (e.g. stock, mutual fund) Értékpapír szerkesztése Delete security? Financial security (e.g. stock, mutual fund) Are you sure you want to delete the security "%1" and all associated transactions? Financial security (e.g. stock, mutual fund) Valóban törölni akarod a "%1" értékpapírt és minden kapcsolódó tranzakciót? No security available. Financial security (e.g. stock, mutual fund) Nincs lehetséges értékpapír. Set Quotation (%1) Financial quotation Árfolyam beállítása (%1) Price per share: Financial shares Részvényenkénti ár: Security Transactions Financial security (e.g. stock, mutual fund) Értékpapír tranzakciók Checking Account Transactional account Folyószámla Balance Account balance Egyenleg Empty securities list. Financial security (e.g. stock, mutual fund) Üres értékpapírlista. &Securities Financial security (e.g. stock, mutual fund) &Értékpapírok Balance… Balance account Egyenleg… Edit Security… Financial security (e.g. stock, mutual fund) Értékpapír szerkesztése… Remove Security Financial security (e.g. stock, mutual fund) Értékpapír visszavonása Shares Bought… Financial shares Részvények vásárlása… Shares Sold… Financial shares Részvények eladása… Edit Quotations… Financial quotation Árfolyamok szerkesztése… The current file has been modified. Do you want to save it? Az aktuális fájl módosult. Akarod menteni? Save file? Confirm Schedule Ütemterv megerősítése New Account Új számla New Loan New Income Category Új bevételi kategória New Expense Category Új kiadási kategória Balance Account Mérlegszámla Book value: Könyvérték: of which %1 is balance adjustment Referring to account balance Real value: Valódi érték: Edit Account Számla szerkesztése Edit Income Category Bevétel kategória szerkesztése Edit Expense Category Kiadás kategória szerkesztése Remove subcategories? Do you wish to remove the category including all subcategories? Move transactions? Tranzakciók mozgatása? Move to: Mozgatás ide: Remove irreversibly from all accounts (do not do this if account has been closed!) The category contains some expenses. What do you want to do with them? A kategória kiadásokat tartalmaz. Mit akarsz velük tenni? The category contains some incomes. What do you want to do with them? A kategória bevételeket tartalmaz. Mit akarsz velük tenni? The account contains some transactions. What do you want to do with them? A számla tranzakciókat tartalmaz. Mit akarsz velük tenni? Remove Category? Kategória eltávolítása? The category contains some expenses that will be removed. Do you still want to remove the category? A kategória kiadásokat tartalmaz, amik törlődni fognak. Biztosan el akarod távolítani a kategóriát? The category contains some incomes that will be removed. Do you still want to remove the category? A kategória bevételeket tartalmaz, amik törlődni fognak. Biztosan el akarod távolítani a kategóriát? Remove Account? Számla eltávolítása? The account contains some transactions that will be removed. Do you still want to remove the account? A számla tranzakciókat tartalmaz, amik törlődni fognak. Biztosan el akarod távolítani a számlát? %2 of %1 %1: budget; %2: remaining budget %2 maradt (terv: %1) Balance… Verb. Balance an account Egyenleg… Shares Exchanged… Shares of one security directly exchanged for shares of another; Financial shares Részvények mozgatása… Shares of one security directly exchanged for shares of another Financial shares Edit Quotes… Financial quote Árfolyamok szerkesztése… Balance Account Verb Mérlegszámla %1 (with no budget) %1 (költségvetés nélkül) %1 (with budget %2) %1 (%2 költségvetéssel) EqonomizeCalendarWidget Today Ma EqonomizeDateEdit Today Ma EqonomizeTranslator OK Only used when Qt translation is missing Cancel Only used when Qt translation is missing Close Only used when Qt translation is missing &Yes Only used when Qt translation is missing &No Only used when Qt translation is missing &Open Only used when Qt translation is missing &Save Only used when Qt translation is missing &Select All Only used when Qt translation is missing Look in: Only used when Qt translation is missing File &name: Only used when Qt translation is missing Files of type: Only used when Qt translation is missing EqonomizeValueEdit Error Empty denominator. Empty factor. Division by zero. Unknown or ambiguous currency, or unrecognized characters, in expression: %1. Empty base. Empty exponent. Unrecognized characters in expression. ExportQIFDialog Export QIF File QIF fájl exportálása Account: Számla: All All accounts Összes Export transaction description as: Alábbi tranzakció-típusok exportálása: Export transaction description as: Referring to generic description Alábbi tranzakció-típusok exportálása: Payee Kedvezményezett Memo Emlékeztető Subcategory Alkategória Date format: Dátumformátum: Value format: Értékformátum: File: Fájl: Error Selected file is a directory. Könyvtárt választottál. Overwrite The selected file already exists. Would you like to overwrite the old copy? A kiválasztott fájl már létezik. Felülírod a régebbi változatot? You selected a directory! Könyvtárt választottál! Couldn't open file for writing. Nem írható fájl. Error while writing file; file was not saved. Hiba írás közben; a fájl nincs elmentve. ImportCSVDialog Import CSV file CSV fájl importálása Transaction Type Selection Tranzakciótípus kiválasztása Expenses Kiadások Incomes Bevételek Transfers Átutalások Expenses and incomes (negative cost) Kiadások és bevételek (negatív költség) Expenses and incomes (separate columns) Kiadások és bevételek (külön oszlopok) All types Összes típus Presets: File Selection Fájl kiválasztása File: Fájl: First data row: Első adatsor: Auto Automatikus Column delimiter: oszlop elválasztó: Comma Vessző Tabulator Tabulátor Semicolon Pontosvessző Space Space Other Egyéb Columns Specification Oszlopok leírása Save as preset… Imports data as expenses and incomes. Costs have negative value. Value is the only required column. Adatok importálása kiadásként és bevételként. A költségek negatív értékek. Az érték az egyetlen szükséges oszlop. Imports data as expenses and incomes. Costs and incomes have separate columns. Income and cost both all required columns. Adatok importálása kiadásként és bevételként. A költségek és bevételek külön oszlopok. A bevétel és a költség és egyaránt szükséges oszlop. Warning The same column number is selected multiple times. Do you wish to proceed anyway? Description: Leírás: Description: Transaction description property (transaction title/generic article name) Leírás: Column Oszlop Value Érték Cost: Költség: Date: Dátum: Category: Kategória: From account: Erről a számláról: Quantity: Mennyiség: Payee: Kedvezményezett: Tags: Comments: Megjegyzések: Create missing categories and accounts Hiányzó kategóriák és számlák készítése Save Preset Imports data as expenses. Costs have positive value. Value is the only required column. Adatok importálása kiadásként. A költségek pozitív értékek. Az érték az egyetlen szükséges oszlop. Imports data as incomes. Value is the only required column. Adatok importálása bevételként. Az érték az egyetlen szükséges oszlop. Income: Bevétel: To account: Erre a számlára: Payer: Kifizető: Imports data as transfers. Value is the only required column. Adatok importálása átutalásként. Az érték az egyetlen szükséges oszlop. Amount: Összeg: Imports data as expenses and incomes. Costs have negative value. Value and category are both required columns. Adatok importálása kiadásként és bevételként. A költségek negatív értékek. Az érték és a kategória egyaránt szükséges oszlop. Value: Érték: Account: Számla: Payee/payer: Kedvezményezett/kifizető: Imports data as expenses and incomes. Costs and incomes have separate columns. Income, cost, and category are all required columns. Adatok importálása kiadásként és bevételként. A költségek és bevételek külön oszlopok. A bevétel, a költség és a kategória mind szükséges oszlopok. Imports data as expenses, incomes, and transfers. Costs have negative or positive value. Value, to, and from are all required columns. Accounts and categories must be existing. Adatok importálása kiadásként, bevételként és átutalásként. A költségek negatív vagy pozitív értékek. Az érték, a forrás és a cél mind szükséges oszlopok. A számláknak és kategóriáknak létezniük kell. From: Forrás: To: Cél: Error A file must be selected. Ki kell választani egy fájlt. Selected file is a directory. Könyvtárt választottál. Selected file does not exist. A kiválasztott fájl nem létezik. Empty delimiter. Üres elválasztó. The same column number is selected multiple times. Ugyanaz az oszlopszám többször kiválasztva. Selected from account is the same as the to account. A kiválasztott forrásszámla megegyezik a célszámlával. Invalid date. Érvénytelen dátum. Couldn't open %1 for reading. %1 nem nyitható meg olvasásra. Error reading %1. Hiba %1 olvasása közben. Uncategorized Kategorizálatlan Successfully imported %n transaction(s). %n tranzakciót sikerült importálni. Unable to import any transactions. Nem lehet importálni tranzakciókat. Failed to import %n data row(s). Nem lehetett importálni %n adatsort. Required columns missing. A szükséges oszlopok hiányoznak. Invalid value. Érvénytelen érték. Empty category name. Üres kategórianév. Empty account name. Üres számlanév. Unknown category found. Ismeretlen kategóriát találtam. Unknown account found. Ismeretlen számlát találtam. Cannot import security transactions (to/from security accounts). Nem lehet importálni értékpapír-tranzakciókat (cél/forrás értékpapírszámlákat). Balancing account wrongly used. Referring to the account used for adjustments of account balances. Rosszult használt mérlegszámla. Balancing account wrongly used. Rosszult használt mérlegszámla. Same to and from account/category. Megegyezik a cél- és a forrásszámla/kategória. No data found. Nem találtam adatot. Information Unrecognized date format. Ismeretlen dátumformátum. Specify Format Formátum meghatározása The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. A dátumok és/vagy a számok formátuma a CSV fájlban félreérthető. Kérlek, válaszd ki a helyes formátumot. Date format: Dátumformátum: Value format: Értékformátum: ImportQIFDialog Import QIF file QIF fájl importálása File Selection Fájl kiválasztása Select a QIF file to import. When you click next, the file be analysed and you might need to answer some questions about the format of the file. Válassz ki egy QIF fájlt importáláshoz. Kattintáskor a fájl elemzése után lehet, hogy válaszolnod kell néhány kérdésre a fájl formátumáról. File: Fájl: Local Definitions Helyi definíciók Unknown elements where found in the QIF file. It is possible that this is because of localized type names. Please map them to the correct standard names. Ismeretlen elem található a QIF fájlban. Lehet, hogy ez a korlátozott típusnevek miatt van. Térképezd fel ezeket a helyes standard nevekhez. Local Text Helyi szöveg Standard Text Standard szöveg Select standard text: Standard szöveg kiválasztása: Date Format Dátumformátum The date format in the QIF file is ambiguous. Please select the correct format. A QIF fájl dátumformátuma félreérthető. Válaszd a helyes formátumot. Date format: Dátumformátum: Default Account Alapértelmezett számla Could not find any account definitions in the QIF file. Please select a default account. It is also possible that this is caused by a localized opening balance text. Nem található számladefiníció a QIF fájlban. Válassz egy alapértelmezett számlát. Default account: Alapértelmezett számla: Opening balance text: Nyitóegyenleg szöveg: Descriptions Típusok Transactions in QIF files does not have any specific description property. You are therefore given the option to choose how the description of imported transactions will be set. A QIF fájlban lévő tranzakcióknak nincs specifikus tulajdonsága. Ezért beállíthatod az importált tranzakciók típusát. Subcategories as: Alkategóriák mint: Description Leírás Transactions in QIF files does not have any specific description property. You are therefore given the option to choose how the description of imported transactions will be set. Referring to generic description A QIF fájlban lévő tranzakcióknak nincs specifikus tulajdonsága. Ezért beállíthatod az importált tranzakciók típusát. Category Kategória Ignore Mellőzés Payee as: Kedvezményezett mint: Payee Kedvezményezett Memo as: Emlékeztető mint: Comments Megjegyzések Priority: Prioritás: Subcategory/Payee/Comments Alkategória/Kedvezményezett/Megjegyzések Payee/Subcategory/Comments Kedvezményezett/Alkategória/Megjegyzések Subcategory/Comments/Payee Alkategória/Megjegyzések/Kedvezményezett Payee/Comments/Subcategory Kedvezményezett/Megjegyzések/Alkategória Comments/Subcategory/Payee Megjegyzések/Alkategória/Kedvezményezett Comments/Payee/Subcategory Megjegyzések/Kedvezményezett/Alkategória Import File No (further) issues were found. Press finish to import the selected QIF file. Ignore duplicate transactions Error A file must be selected. Ki kell választani egy fájlt. Selected file is a directory. Könyvtárt választottál. Selected file does not exist. A kiválasztott fájl nem létezik. Couldn't open %1 for reading. %1 nem nyitható meg olvasásra. Error reading %1. Hiba %1 olvasása közben. Unknown Ismeretlen Account Számla Bank Bank Cash Készpénz Cat (Category) Kat. (Kategória) CCard (Credit Card) H.kártya (Hitelkártya) Invst (Investment) Befekt. (Befektetés) Oth A (Other Assets) Oth A (Egyéb vagyon) Oth L (Other Liabilities) Oth L (Egyéb kötelezettségek) Security Értékpapír Other Egyéb Unrecognized date format. Ismeretlen dátumformátum. Successfully imported %n transaction(s). %n tranzakciót sikerült importálni. Successfully imported %n account(s). %n számla sikeresen importálva. Successfully imported %n category/categories. %n kategória sikeresen importálva. %n duplicate transaction(s) was ignored. %n megismételt tranzakció mellőzve. Failed to import %n transaction(s). %n tranzakció sikertelen importálása. %n security/securities were not imported. Financial security (e.g. stock, mutual fund) %n értékpapír-tranzakció nem lett importálva. %n security transaction(s) were not imported. Financial security (e.g. stock, mutual fund) %n értékpapír-tranzakció nem lett importálva. %n security/securities were not imported. %n értékpapír-tranzakció nem lett importálva. %n security transaction(s) were not imported. %n értékpapír-tranzakció nem lett importálva. Information Income Dividend: %1 Osztalék: %1 Reinvested dividend: %1 Újra befektetett osztalék: %1 LedgerDialog Account: Számla: Edit Account… Számla szerkesztése… Export… Exportálás… Print… Nyomtatás… Reconcile Accounting context Mark all as reconciled Accounting context Change: Accounting context Változás: R Header for account reconciled checkbox column Date Dátum Type Típus Description Leírás Name Név Description Generic Description Leírás Account/Category Számla/Kategória Deposit Letét Withdrawal Kivét Balance Egyenleg Balance Account balance Egyenleg Payee/Payer Kedvezményezett/kifizető Tags Comments Megjegyzések Deposit Money put into account Letét Withdrawal Money taken out from account Kivét Balance Noun. Balance of an account Egyenleg New Új Edit… Szerkesztés… Delete Törlés Join… join transactions together Belépés… Split Up split up joined transactions Felosztás Edit Transaction(s)… Tranzakció(k) szerkesztése… Join Transactions… Tranzakciók egyesítése… Split Up Transaction Tranzakciók felosztása Remove Transaction(s) Tranzakció(k) visszavonása Mark as reconciled Reconciled: %1 (%2) Accounting context Book value: %1 (%2) Accounting context Könyvérték: %1 (%2) Error Invalid date. Opening date is after closing date. Closing date is before opening date. Empty transaction list. Üres tranzakciós lista. Couldn't open file for writing. Nem írható fájl. Error while writing file; file was not saved. Hiba írás közben; a fájl nincs elmentve. Ledger Főkönyv Transactions for %1 %1 tranzakciói Select Time Period From: Forrás: To: Cél: To date is before from date. A záródátum korábbi, mint a kezdődátum. Balance change: Account balance Delete transactions? Are you sure you want to delete all (%1) selected transactions? Biztosan törölni akarsz minden (%1) kiválasztott tranzakciót? Cannot set the value of security transactions using the dialog for modifying multiple transactions. Financial security (e.g. stock, mutual fund) Az értékpapír-tranzakciók értékét nem lehet beállítani a többszörös tranzakciók módosítása párbeszédablakban. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name); Financial security (e.g. stock, mutual fund) Az értékpapír-tranzakciók és az osztalékok fajtája nem változtatható meg. Cannot change payer of dividends and security transactions. Financial security (e.g. stock, mutual fund) Az osztalékok és értékpapír-tranzakciók kifizetője nem változtatható meg. Opening balance Account balance Nyitóegyenleg Account Balance Adjustment Current balance: Account balance Average balance: Account balance Account Balancing Balancing of an account Számlaegyenleg Balancing Balancing of an account Kiegyenlítés Balancing Account balancing Kiegyenlítés Cannot set the value of security transactions using the dialog for modifying multiple transactions. Az értékpapír-tranzakciók értékét nem lehet beállítani a többszörös tranzakciók módosítása párbeszédablakban. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name) Az értékpapír-tranzakciók és az osztalékok fajtája nem változtatható meg. Cannot change description of dividends and security transactions. Referring to the generic description property Az értékpapír-tranzakciók és az osztalékok fajtája nem változtatható meg. Current debt: Total debt reduction: Total interest and fees: Number of transactions: Cannot change description of dividends and security transactions. Az értékpapír-tranzakciók és az osztalékok fajtája nem változtatható meg. Cannot change payer of dividends and security transactions. Az osztalékok és értékpapír-tranzakciók kifizetője nem változtatható meg. Cannot change date of transactions that are part of a split transaction. Osztott tranzakcióban szereplő tranzakciók dátuma nem változtatható meg. Initial balance Nyitóegyenleg Split Transaction Osztott tranzakció Debt Payment Ascending order Reduction Fee Interest Income Bevétel Repayment Visszafizetés Expense Kiadás Opening balance: Accounting context Nyitóegyenleg: Closing balance: Accounting context Description Transaction description property (transaction title/generic article name) Leírás Cannot change description of dividends and security transactions. Referring to the Transaction description property (transaction title/generic article name) Az értékpapír-tranzakciók és az osztalékok fajtája nem változtatható meg. Refund Visszatérítés Balancing Kiegyenlítés Transfer Átutalás LinksWidget Remove Link All Összes Remove Törlés MultiItemListViewItem Dividend Osztalék Income Bevétel Repayment Visszafizetés Expense Kiadás Refund Visszatérítés Securities Purchase Financial security (e.g. stock, mutual fund) Értékpapír vétel Securities Sale Financial security (e.g. stock, mutual fund) Értékpapír eladás Account Balance Adjustment Account Balancing Balancing of an account Számlaegyenleg Balancing Balancing of an account Kiegyenlítés Security Buy Értékpapír vétel Security Sell Értékpapír eladás Balancing Kiegyenlítés Transfer Átutalás MultipleTransactionsEditDialog Modify Transactions Módosított tranzakciók Description: Leírás: Name: Név: Description: Transaction description property (transaction title/generic article name) Leírás: Amount: Összeg: Income: Bevétel: Cost: Költség: Date: Dátum: Category: Kategória: Payer: Kifizető: Payee: Kedvezményezett: New Income Category Új bevételi kategória New Expense Category Új kiadási kategória New Income Category… Új bevételi kategória… New Expense Category… Új kiadási kategória… Error No income category available. Nincs rendelkezésre álló bevételi kategória. No expense category available. Nincs rendelkezésre álló kiadási kategória. Invalid date. Érvénytelen dátum. OverTimeChart Save As… Mentés másként… Print… Nyomtatás… Source: Forrás: Incomes and Expenses Bevételek és kiadások Profits Nyereségek Expenses Kiadások Incomes Bevételek All Categories Combined Összes kategória együtt All Descriptions Combined Összes típus együtt Theme: Chart type: Line Chart Vertical Bar Chart Horizontal Bar Chart Stacked Bar Chart Default Tags All Accounts Combined Összes számla együtt All Accounts Split Összes számla külön All Subcategories and Descriptions Combined Referring to the transaction description property (transaction title/generic article name) All Descriptions Split Referring to the transaction description property (transaction title/generic article name) Összes típus külön No description Referring to the transaction description property (transaction title/generic article name) Nincs leírás All Payees/Payers Split Összes kedvezményezett/kifizető külön No payee/payer Nincs kedvezményezett/kifizető All Tags Split Other tags Other payees/payers Other descriptions Referring to the transaction description property (transaction title/generic article name) Incomes − Expenses, %1 Bevételek − kiadások, %1 Assets Vagyon All Descriptions Combined Referring to the generic description property Összes típus együtt Assets and Liabilities All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Összes típus együtt All Payees/Payers Combined Összes kedvezményezett/kifizető együtt Start date: Kezdődátum: End date: Záródátum: Value: Érték: Annual total Monthly total Havonta összesen Daily average Napi átlag Quantity Mennyiség Average value Átlagérték All Payers Combined Összes kifizető együtt All Payees Combined Összes kedvezményezett együtt All Subcategories Split All Descriptions Split Referring to the generic description property Összes típus külön No description Referring to the generic description property Nincs leírás Value Érték Includes budgeted transactions Költségvetési tranzakciókat tartalmaz Profits, %1 Nyereségek, %1 Incomes & Expenses Bevételek és kiadások Incomes: %1 Bevételek: %1 Expenses: %1 Kiadások: %1 Incomes: %2, %1 Bevételek: %2, %1 Expenses: %2, %1 Kiadások: %2, %1 Incomes: %3, %2, %1 Bevételek: %3, %2, %1 Expenses: %3, %2, %1 Kiadások: %3, %2, %1 %1/%2 %1: Generic Description; %2: Payer/Payer %1/%2 %1/%2 %1: Generic Description; %2: Payee/Payer %1/%2 %1 Value: %2 Date: %3 MMMM yyyy Month and year All Descriptions Split Összes típus külön All Payers Split Összes kifizető külön All Payees Split Összes kedvezményezett külön No description Nincs leírás No payer Nincs kifizető No payee Nincs kedvezményezett All Categories Split Összes kategória külön Error Invalid date. Érvénytelen dátum. Couldn't open file for writing. Nem írható fájl. Error while writing file; file was not saved. Hiba írás közben; a fájl nincs elmentve. Other payees Other payers Value (%1) Érték (%1) Profit (%1) Nyereség (%1) Income (%1) Bevétel (%1) Cost (%1) Költség (%1) Time Idő %1/%2 %1: Category; %2: Payee/Payer %1/%2 All Descriptions Combined Referring to the Transaction description property (transaction title/generic article name) Összes típus együtt All Descriptions Split Referring to the Transaction description property (transaction title/generic article name) Összes típus külön No description Referring to the Transaction description property (transaction title/generic article name) Nincs leírás Daily average value Daily average profit Daily average income Daily average cost Average income Average cost Annual value Annual profit Annual income Annual cost Monthly value Monthly profit Monthly income Monthly cost Includes scheduled and budgeted transactions Includes scheduled transactions Ütemezett tranzakciókat tartalmaz Tags, %1 Value: %1 Érték: %1 Assets & Liabilities Incomes − Expenses Bevételek − kiadások %2: %1 %3: %2, %1 %2, %1 %4: %3, %2, %1 no payee/payer nincs kedvezményezett/kifizető %3, %2, %1 Other accounts Change: %1 Változás: %1 Excluding any profits or losses in trading of security shares Financial security (e.g. stock, mutual fund) Incomes & Expenses, %1 Bevételek és kiadások, %1 Incomes, %1 Bevételek, %1 Expenses, %1 Kiadások, %1 Incomes, %2: %1 Bevételek, %2: %1 Expenses, %2: %1 Kiadások, %2: %1 Incomes, %3: %2, %1 Bevételek, %3: %2, %1 Expenses, %3: %2, %1 Kiadások, %3: %2, %1 Incomes, %4: %3, %2, %1 Bevételek, %4: %3, %2, %1 Expenses, %4: %3, %2, %1 Kiadások, %4: %3, %2, %1 Liabilities Tartozások no payer nincs kifizető %1/%2 %1: Description; %2: Payer/Payer %1/%2 %1/%2 %1: Description; %2: Payee/Payer %1/%2 %1/%2 %1: Generic Description; %2: Payer %1/%2 %1/%2 %1: Generic Description; %2: Payee %1/%2 %1/%2 %1: Description; %2: Payer %1/%2 no payee nincs kedvezményezett %1/%2 %1: Description; %2: Payee %1/%2 OverTimeChartDialog Chart Grafikon OverTimeReport Save As… Mentés másként… Print… Nyomtatás… Source: Forrás: Profits Nyereségek Expenses Kiadások Incomes Bevételek Assets & Liabilities Tags All Categories Combined Összes kategória együtt All Descriptions Combined Összes típus együtt Columns: Oszlopok: Categories Total: Összeg: Value Érték Daily Naponta Monthly Havonta Yearly Évente Quantity Mennyiség Average value Átlagérték No description Nincs leírás All Descriptions Combined Referring to the generic description property Összes típus együtt No description Referring to the generic description property Nincs leírás All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Összes típus együtt No description Referring to the transaction description property (transaction title/generic article name) Nincs leírás Error Couldn't open file for writing. Nem írható fájl. Error while writing file; file was not saved. Hiba írás közben; a fájl nincs elmentve. Average Profit Átlagnyereség Incomes, %1 Bevételek, %1 Average Income Átlagos bevétel Expenses, %1 Kiadások, %1 Average Cost Átlagos költség Incomes, %2: %1 Bevételek, %2: %1 Incomes: %1 Bevételek: %1 Expenses, %2: %1 Kiadások, %2: %1 Expenses: %1 Kiadások: %1 Incomes, %3: %2, %1 Bevételek, %3: %2, %1 Incomes: %2, %1 Bevételek: %2, %1 Expenses, %3: %2, %1 Kiadások, %3: %2, %1 Expenses: %2, %1 Kiadások: %2, %1 Change: %1 Noun, how much the account balance has changed Változás: %1 Deposit Money put into account Letét Withdrawal Money taken out from account Kivét Change Noun, how much the account balance has changed Változás Value: %1 Érték: %1 %2: %1 %1 %1 Average Value Átlagos érték %3: %2, %1 %2, %1 Year Év Month Hónap Assets Vagyon Deposit Letét Withdrawal Kivét Liabilities Tartozások Daily Average Napi átlag Monthly Average Havi átlag Yearly Average Éves átlag Subtotal Részösszeg Total Összesen Includes scheduled transactions Ütemezett tranzakciókat tartalmaz Adjusted for the average month / year (%1 / %2 days) Beállítva átlag hónapra / évre (%1 / %2 nap) All Categories Combined Referring to the generic description property Összes kategória együtt OverTimeReportDialog Report Jelentés QApplication Start with expenses list displayed Indítás a kiadások listájával Start with incomes list displayed Indítás a bevételek listájával Start with transfers list displayed Indítás az átutalások listájával Synchronize file Document to open Megnyitandó dokumentum %1 is already running. QObject Transfer Átutalás Dividend Osztalék Income Bevétel Expense Kiadás Securities Purchase Financial security (e.g. stock, mutual fund) Értékpapír vétel Securities Sale Financial security (e.g. stock, mutual fund) Értékpapír eladás Security Buy Értékpapír vétel Security Sell Értékpapír eladás Debt Payment Split Transaction Osztott tranzakció RecurrenceEditWidget Enable recurrence Ismétlés megengedése Recurrence Rule Ismétlési szabály Daily Naponta Weekly Hetente Monthly Havonta Yearly Évente Recur every Ismétlődik minden day(s) . napon week(s) on: . héten: month(s), after the start month . hónapban, a kezdőhónap után Recur on the Ismétlődik minden 1st 1. 2nd 2. 3rd 3. 4th 4. 5th 5. 6th 6. 7th 7. 8th 8. 9th 9. 10th 10. 11th 11. 12th 12. 13th 13. 14th 14. 15th 15. 16th 16. 17th 17. 18th 18. 19th 19. 20th 20. 21st 21. 22nd 22. 23rd 23. 24th 24. 25th 25. 26th 26. 27th 27. 28th 28. 29th 29. 30th 30. 31st 31. Last Utolsó 2nd Last Utolsó előtti 3rd Last Hátulról 3. 4th Last Hátulról 4. 5th Last Hátulról 5. day nap possibly on weekend Esetleg hétvégén but before weekend de hétvége előtt but after weekend de hétvége után nearest weekend day year(s), after the start year . évben, a kezdőév után on nearest weekday Recur on day part before XXX of 'Recur on day XXX of month YYY' Ismétlés e napon: of part between XXX and YYY of 'Recur on day XXX of month YYY' e hónapban: On the Part before NNN in 'Recur on the NNN. WEEKDAY of MONTH' e napon: of part between WEEKDAY and MONTH in 'Recur on NNN. WEEKDAY of MONTH' e hónapban: Recur on day # Ismétlés e napon: of the year part after NNN of 'Recur on day #NNN of the year' . napján az évnek Range… Terjedelem… Occurrences/Exceptions… Exceptions… Kivételek… Error No day of week selected for weekly recurrence. A hét egy napját sem választottad ki heti ismétlődéshez. Selected day will never occur with selected frequency and start date. A kiválasztott nap soha nem következik be a választott gyakorisággal és kezdődátummal. Selected day does not exist in selected month. A kiválasztott nap nem létezik a választott hónapban. RefundDialog Repayment Visszafizetés Refund Visszatérítés Date: Dátum: Cost: Költség: Income: Bevétel: Quantity returned: Visszaadott mennyiség: Account: Számla: Quantity: Mennyiség: Payee: Kedvezményezett: Payer: Kifizető: Comments: Megjegyzések: Link Link the transactions together Join Join the transactions together Belépés Error Zero value not allowed. Nulla érték nem megengedett. Invalid date. Érvénytelen dátum. SecurityBuy Security: %1 (bought) Értékpapír: %1 (vétel) Security: %1 (bought) Financial security (e.g. stock, mutual fund) Értékpapír: %1 (vétel) SecuritySell Security: %1 (sold) Értékpapír: %1 (eladás) Security: %1 (sold) Financial security (e.g. stock, mutual fund) Értékpapír: %1 (eladás) SecurityTransactionsDialog Transactions for %1 %1 tranzakciói Date Dátum Type Típus Value Érték Shares Financial shares Részvények Shares Bought Financial shares Részvényvásárlás Shares Bought (Recurring) Financial shares Részvényvásárlás (ismétlődő) Dividend (Recurring) Osztalék (ismétlődő) Dividend (Scheduled) Osztalék (tervezett) Reinvested Dividend (Recurring) Újra befektetett osztalék (ismétlődő) Reinvested Dividend (Scheduled) Újra befektetett osztalék (tervezett) Shares Bought Fincancial shares Részvényvásárlás Shares Sold Financial shares Részvényeladás Shares Sold (Exchanged) Shares of one security directly exchanged for shares of another; Financial shares Részvényeladás (megkötött) Shares Bought (Exchanged) Shares of one security directly exchanged for shares of another; Financial shares Részvényvásárlás (megkötött) Shares Bought (Recurring) Fincancial shares Részvényvásárlás (ismétlődő) Shares Sold (Recurring) Financial shares Részvényeladás (ismétlődő) Shares Bought (Scheduled) Financial shares Részvényvásárlás (tervezett) Shares Sold (Scheduled) Financial shares Részvényeladás (tervezett) Shares Részvények Edit… Szerkesztés… Delete Törlés Shares Bought Részvényvásárlás Shares Sold Részvényeladás Dividend Osztalék Reinvested Dividend Újra befektetett osztalék Shares Sold (Traded) Részvényeladás (megkötött) Shares Bought (Traded) Részvényvásárlás (megkötött) Shares Bought (Recurring) Részvényvásárlás (ismétlődő) Shares Sold (Recurring) Részvényeladás (ismétlődő) Shares Bought (Scheduled) Részvényvásárlás (tervezett) Shares Sold (Scheduled) Részvényeladás (tervezett) Recurring Dividend Ismétlődő osztalék Scheduled Dividend Tervezett osztalék SplitListViewItem Dividend Osztalék Income Bevétel Repayment Visszafizetés Expense Kiadás Refund Visszatérítés Security Buy Értékpapír vétel Security Sell Értékpapír eladás Balancing Kiegyenlítés Transfer Átutalás TagButton no tags TagMenu New tag… New Tag Tag: TransactionEditDialog Edit Expense Kiadás szerkesztése Edit Dividend Osztalék szerkesztése Edit Income Bevétel szerkesztése Edit Transfer Átutalás szerkesztése Edit Securities Purchase Financial security (e.g. stock, mutual fund) Értékpapír vétel szerkesztése Edit Securities Sale Financial security (e.g. stock, mutual fund) Értékpapír eladás szerkesztése Edit Reinvested Dividend Edit Securities Bought Értékpapír vétel szerkesztése Edit Securities Sold Értékpapír eladás szerkesztése TransactionEditWidget Security: Értékpapír: Cost: Költség: Income: Bevétel: Shares bought: Vett részvények: Shares sold: Eladott részvények: All Összes Price per share: Részvényenkénti ár: Date: Dátum: Description: Leírás: Name: Név: Amount: Összeg: Withdrawal: Money taken out from account Kivét: New Security… Financial security (e.g. stock, mutual fund) Új értékpapír… Shares added: Financial shares Hozzáadott részvények: Set security share value Total value: Összes érték: Deposit: Money put into account Letét: Downpayment: Quantity: Mennyiség: From: Forrás: To: Cél: Category: Kategória: To account: Erre a számlára: Payer: Kifizető: Payer of parent split transaction From account: Erről a számláról: Downpayment account: Payee: Kedvezményezett: Payee of parent split transaction Lender: Tags: Associated file: Select a file Open the file Comments: Megjegyzések: Related to: Label for linked transactions Linkek: New Security Financial security (e.g. stock, mutual fund) Új értékpapír No security available. Financial security (e.g. stock, mutual fund) Nincs lehetséges értékpapír. New Account Új számla New Income Category Új bevételi kategória New Expense Category Új kiadási kategória New Account… Új számla… New Income Category… Új bevételi kategória… New Expense Category… Új kiadási kategória… Security: Financial security (e.g. stock, mutual fund) Értékpapír: Shares bought: Financial shares Vett részvények: Shares sold: Financial shares Eladott részvények: Price per share: Financial shares Részvényenkénti ár: Description: Transaction description property (transaction title/generic article name) Leírás: Transaction title/generic article name Number of items included in the transaction. Entered cost is total cost for all items. Error No suitable account available. Nincs megfelelő számla. No income category available. Nincs rendelkezésre álló bevételi kategória. No suitable account or income category available. Nincs megfelelő számla vagy bevétel kategória. No expense category available. Nincs rendelkezésre álló kiadási kategória. No security available. Nincs lehetséges értékpapír. Invalid date. Érvénytelen dátum. Cannot transfer money to and from the same account. Nem lehet átutalni ugyanarról ugyanarra a számlára. Downpayment must be less than total cost. Cannot create a regular transfer to/from a securities account. Nem hozható létre állandó átutalás értékpapírszámlára/-ról. Cannot create a regular income to a securities account. Nem hozható létre állandó bevétel értékpapírszámlára. Zero shares not allowed. Nulla részvény nem megengedett. Zero value not allowed. Nulla érték nem megengedett. Zero price per share not allowed. Nulla részvényenkénti ár nem megengedett. Cannot create a regular expense from a securities account. Nem hozható létre állandó kiadás értékpapírszámláról. Loan for %1 TransactionFilterWidget From: Forrás: To: Cél: Min amount: Min. összeg: Max amount: Max. összeg: Category: Kategória: To account: Erre a számlára: Min income: Min. bevétel: Max income: Max. bevétel: From account: Erről a számláról: Min cost: Min. költség: Max cost: Max. költség: Tag: Description: Leírás: Description: Transaction description property (transaction title/generic article name) Leírás: Payer: Kifizető: Payee: Kedvezményezett: Include Tartalmaz Exclude Kizár Exact match Exclude subcategories Clear Törlés All Összes Error Invalid date. Érvénytelen dátum. To date is before from date. A záródátum korábbi, mint a kezdődátum. From date is after to date. A kezdődátum későbbi, mint a záródátum. TransactionListWidget Date Dátum Description Leírás Cost Költség Category Kategória From Account Számláról Payee Kedvezményezett Tags Income Bevétel To Account Számlára Payer Kifizető Amount Mennyiség From Eredet To Cél Comments Megjegyzések Add Hozzáadás Apply Alkalmazás Delete Törlés * Part of <a href="%1">split transaction</a> * Osztott <a href="%1">tranzakció része</a> Expense Kiadás Transfer Átutalás Name Név Description Generic Description Leírás Description Transaction description property (transaction title/generic article name) Leírás New/Edit Expense Új kiadás/kiadás szerkesztése New/Edit Income Új bevétel/bevétel szerkesztése New/Edit Transfer Új átutalás/átutalás szerkesztése Filter Szűrő Quantity: Mennyiség: Total: Összeg: Average: Átlag: Clear Törlés Cost: Költség: Monthly: Havonta: Sort by creation time Expenses Kiadások Incomes Bevételek Transfers Átutalások Quantity Mennyiség Right align Jobbra igazítás Total cost: Összes költség: Total income: Összes bevétel: Total amount: Teljes összeg: Monthly average: Havi átlag: Error Cannot set the value of security transactions using the dialog for modifying multiple transactions. Financial security (e.g. stock, mutual fund) Az értékpapír-tranzakciók értékét nem lehet beállítani a többszörös tranzakciók módosítása párbeszédablakban. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name); Financial security (e.g. stock, mutual fund) Az értékpapír-tranzakciók és az osztalékok fajtája nem változtatható meg. Cannot change payer of dividends and security transactions. Financial security (e.g. stock, mutual fund) Az osztalékok és értékpapír-tranzakciók kifizetője nem változtatható meg. Cannot change date of transactions that are part of a split transaction, unless all individual transactions are selected. Cannot set the value of security transactions using the dialog for modifying multiple transactions. Az értékpapír-tranzakciók értékét nem lehet beállítani a többszörös tranzakciók módosítása párbeszédablakban. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name) Az értékpapír-tranzakciók és az osztalékok fajtája nem változtatható meg. Cannot change date, description, expense category or payee of transactions that are part of a debt payment using the dialog for modifying multiple transactions. Referring to the transaction description property (transaction title/generic article name) Cannot change description of dividends and security transactions. Referring to the Transaction description property (transaction title/generic article name) Az értékpapír-tranzakciók és az osztalékok fajtája nem változtatható meg. Cannot change description of dividends and security transactions. Referring to the generic description property Az értékpapír-tranzakciók és az osztalékok fajtája nem változtatható meg. Cannot change description of dividends and security transactions. Az értékpapír-tranzakciók és az osztalékok fajtája nem változtatható meg. Cannot change payer of dividends and security transactions. Az osztalékok és értékpapír-tranzakciók kifizetője nem változtatható meg. Cannot change date of transactions that are part of a split transaction. Osztott tranzakcióban szereplő tranzakciók dátuma nem változtatható meg. Delete transactions? Are you sure you want to delete all (%1) transactions in the selected split transaction? Biztosan törölni akarsz minden (%1) tranzakciót a kiválasztott osztott tranzakcióban? Join as multiple accounts/payments? Do you wish join the selected expenses as an expense with multiple accounts/payments? Do you wish join the selected incomes as an income with multiple accounts/payments? Are you sure you want to delete all (%1) selected transactions? Biztosan törölni akarsz minden (%1) kiválasztott tranzakciót? * Part of split transaction * Osztott tranzakció része * Part of split (%1) * A (%1) osztott tranzakció része ** Recurring (editing occurrence) ** Ismétlődés (események szerkesztése) Modify… Módosítás… Edit… Szerkesztés… Eqonomize-1.5.3/translations/eqonomize_it.ts000066400000000000000000020617411416454732000213020ustar00rootroot00000000000000 Balancing Bilanciamento kde-format Couldn't open %1 for reading Impossibile aprire %1 per la lettura kde-format Not a valid Eqonomize! file (XML parse error: "%2" at line %3, col %4) Non è un file valido di Eqonomize! (Errore di analisi XML: "%2" alla linea %3, colonna %4) kde-format Invalid root element %1 in XML document L'elemento radice %1 del documento XML non è valido kde-format Unable to load 1 account. Fallito il caricamento di 1 conto. Fallito il caricamento di %n conti. kde-format Unable to load %n accounts. Unable to load 1 category. Fallito il caricamento di 1 categoria. Fallito il caricamento di %n categorie. kde-format Unable to load %n categories. Unable to load 1 security. Fallito il caricamento di 1 titolo. Fallito il caricamento di %n titoli. kde-format Unable to load %n securities. Unable to load 1 transaction. Fallito il caricamento di 1 transizione. Fallito il caricamento di %n transizioni. kde-format Unable to load %n transactions. File is a directory Il file è una directory kde-format Couldn't open file for writing Impossibile aprire il file per la scrittura kde-format Error while writing file; file was not saved Errore nella scrittura del file; il file non è stato salvato. kde-format From Da kde-format To A kde-format Source: Fonte: kde-format All Expenses Tutte le uscite kde-format All Incomes Tutte le entrate kde-format All Accounts Tutti i conti kde-format Expenses: %1 Uscite: %1 kde-format Incomes: %1 Entrate: %1 kde-format Invalid date. Data non valida. kde-format To date is before from date. La data A è precedente alla data Da. kde-format From date is after to date. La data Da è posteriore alla data A. kde-format The selected file already exists. Would you like to overwrite the old copy? Il file selezionato già esiste. Vuoi sovrascriverlo? kde-format You selected a directory! Hai selezionato una cartella! kde-format Couldn't open file for writing. Impossibile aprire il file per la scrittura. kde-format Error while writing file; file was not saved. Errore nella scrittura del file; il file non è stato salvato. kde-format No description Nessuna descrizione kde-format All Categories Tutte le categorie kde-format Descriptions for Descrizione per kde-format Payees/payers for Creditore/debitore per kde-format Period: Periodo: kde-format Columns: Colonne: kde-format Value Valore kde-format Daily Giornalmente kde-format Monthly Mensilmente kde-format Yearly Annualmente kde-format Quantity Quantità kde-format Average value Valore medio kde-format All descriptions Tutte le descrizioni kde-format All payees Tutti i creditori kde-format All payers Tutti i debitori kde-format No payee Nessun creditore kde-format No payer Nessun debitore kde-format Expenses: %2, %1 Uscite: %2, %1 kde-format Incomes: %2, %1 Entrate: %2, %1 kde-format Incomes & Expenses Entrate & Uscite kde-format %1 (%2&ndash;%3) html format; %1: title; %2: from date; %3: to date %1 (%2&ndash;%3) kde-format %1 (to %2) html format; %1: title; %2: to date %1 (a %2) kde-format Category Categoria kde-format Cost Costo kde-format Income Entrata kde-format Daily Average Media Giornaliera kde-format Monthly Average Media Mensile kde-format Yearly Average Media Annuale kde-format Average Cost Media dei Costi kde-format Average Income Media delle Entrate kde-format Average Value Valore Medio kde-format Total Totale kde-format Total incomes Totale delle entrate kde-format Total expenses Totale delle uscite kde-format Total (Profits) Totale (Profitti) kde-format Expense Uscita kde-format Transfer Trasferimento kde-format Security Buy Acquisto di titoli kde-format Security Sell Vendita di titoli kde-format Recurrence Ricorrenza kde-format New Expense Nuova Uscita kde-format New Dividend Nuovo Dividendo kde-format New Income Nuova Entrata kde-format New Transfer Nuovo Trasferimento kde-format New Security Buy Nuovo acquisto di titoli kde-format New Security Sell Nuova vendita di titoli kde-format Edit Expense Modifica Uscita kde-format Edit Dividend Modifica Dividendo kde-format Edit Income Modifica Entrata kde-format Edit Transfer Modifica Trasferimento kde-format Edit Securities Bought Modifica i titoli acquistati kde-format Edit Securities Sold Modifica i titoli venduti kde-format Dividend Dividendo kde-format Repayment Rimborso kde-format Refund Rimborso kde-format Split Transaction Dividi la Transazione kde-format Description: Descrizione: kde-format Date: Data: kde-format Account: Conto: kde-format Transactions: Transazioni: kde-format Type Tipo kde-format Description Descrizione kde-format Account/Category Conto/Categoria kde-format Payment Pagamento kde-format Deposit Deposito kde-format New Nuovo kde-format New Expense… Nuova Uscita… kde-format New Income… Nuova Entrata… kde-format New Deposit… Nuovo Deposito… kde-format New Withdrawal… Nuovo Prelievo… kde-format New Dividend… Nuovo Dividendo kde-format Edit… Modifica… kde-format Total value: Valore totale: kde-format No suitable account available. Nessun conto adeguato è disponibile. kde-format Future dates is not allowed. Date future non sono permesse kde-format A split must contain at least two transactions. Una suddivisione deve contenere almeno due transazioni. kde-format Cannot transfer money to and from the same account. Impossibile trasferire denaro a e dallo stesso conto. kde-format Cost: Costo: kde-format Income: Entrata: kde-format Quantity: Quantità: kde-format Comments: Commenti: kde-format Reinvested Dividend Dividendo Reinvestito kde-format Security: Titoli: kde-format Shares added: Azioni aggiunte: kde-format Security Trade Commercio di titoli kde-format From security: Dal titolo: kde-format Shares moved: Titoli trasferiti: kde-format All Tutti kde-format To security: Al titolo: kde-format Shares received: Azioni ricevute: kde-format Value: Valore: kde-format No other security available for trade in the account. Nessun altro titolo disponibile per commercio, nel conto. kde-format Zero shares not allowed. Zero azioni non è permesso. kde-format Zero value not allowed. Il valore zero non è permesso. kde-format Quotations Quotazione kde-format Date Data kde-format Price per Share Prezzo per Azione kde-format Quotations for %1 Quotazione per %1 kde-format The following transactions was scheduled to occur today or before today. Confirm that they have indeed occurred (or will occur today). La seguente transazione è stata pianificata per occorrere oggi o precedentemente. Conferma che è veramente occorsa (o che occorrerà oggi). kde-format Amount Quantità kde-format Postpone… Rinvia… kde-format Can only postpone to future dates. Si può rinviare solo a date future. kde-format Transactions for %1 Transazione per %1 kde-format Shares Azioni kde-format Shares Bought Azioni comprate kde-format Shares Sold Azioni vendute kde-format Shares Sold (Traded) Azioni vendute (commerciate) kde-format Shares Bought (Traded) Azioni comprate (commerciate) kde-format Shares Bought (Recurring) Azioni comprate (con ricorrenza) kde-format Shares Sold (Recurring) Azioni vendute (con ricorrenza) kde-format Shares Bought (Scheduled) Azioni comprate (pianificate) kde-format Shares Sold (Scheduled) Azioni vendute (pianificate) kde-format Recurring Dividend Dividendo ricorrente kde-format Scheduled Dividend Dividendo pianificato kde-format Type: Tipo: kde-format Mutual Fund Fondi Comuni kde-format Bond Bond kde-format Stock Azione kde-format Other Altro kde-format Name: Nome: kde-format Decimals in Shares: Decimali in Azioni: kde-format Initial Shares: Azioni Iniziali: kde-format Initial quotation: Quotazione iniziale: kde-format Cash Contante kde-format Current Account Conto Corrente kde-format Savings Account Libretto di Risparmio kde-format Credit Card Carta di Credito kde-format Liabilities Passività kde-format Securities Titoli kde-format Initial balance: Bilancio iniziale: kde-format Default account for budgeted transactions Account predefinito per transazioni finanziate kde-format Empty name. Nome vuoto. kde-format The entered name is used by another account. Il nome inserito è utilizzato da un altro conto. kde-format Monthly budget: Budget Mensile: kde-format The entered name is used by another income category. Il nome inserito è utilizzato da un'altra categoria d'entrata. kde-format The entered name is used by another expense category. Il nome inserito è utilizzato da un'altra categoria di uscita. kde-format Accounts Conti kde-format Accounts & Categories Conti & Categorie kde-format Expenses Uscite: kde-format Incomes Entrate: kde-format Transfers Trasferimenti: kde-format Schedule Pianificazione kde-format Scheduled Transactions Transazioni Pianificate kde-format Account / Category Conto / Categoria kde-format Remaining Budget (%1) Budget Restante (%1) kde-format Change (%1) Cambio (%1) kde-format Total (%1) Totale (%1) kde-format %2 of %1 %2 remains of %1 budget %2 di %1 kde-format Includes budgeted transactions Incluse le transazioni preventivate kde-format Period Periodo kde-format Select Period Seleziona Periodo kde-format Current Month Il Mese Corrente kde-format Current Year L'Anno Corrente kde-format Current Whole Month L'Intero Mese Corrente kde-format Current Whole Year L'Intero Anno Corrente kde-format Whole Past Month L'Intero Mese Trascorso kde-format Whole Past Year L'intero Anno Trascorso kde-format Previous Month Il Mese Precedente kde-format Previous Year L'Anno Precedente kde-format Show partial budget Mostra budget parziale kde-format Edit Budget Modifica il Budget kde-format Budget: Budget: kde-format Month: Mese: kde-format Result previous month: Risultato del mese precedente: kde-format New Security… Nuovo titolo… kde-format New Transaction Nuova Transazione kde-format Set Quotation… Fissa Quotazione… kde-format Name Nome kde-format Quotation Quotazione kde-format Profit Profitto kde-format Yearly Rate Tasso Annuale kde-format Account Conto kde-format Statistics Period Periodo Statistiche kde-format New Schedule Nuova Pianificazione kde-format Edit Modifica kde-format Next Occurrence Prossima Ricorrenza kde-format Comments Commenti kde-format New Security Nuovo titolo kde-format Edit Security Modifica titolo kde-format Profit: Profitto: kde-format Rate: Tasso: kde-format Are you sure you want to delete the security "%1" and all associated transactions? Sei sicuro di voler eliminare il titolo "%1" e tutte le transazioni associate? kde-format Set Quotation (%1) Fissa Quotazione (%1) kde-format Price per share: Prezzo per azione: kde-format Future dates are not allowed. Date future non sono permesse. kde-format Security Transactions Transazioni di titoli kde-format Ledger Libro Maestro kde-format Untitled Senza titolo kde-format Check Account Controlla Account kde-format Salary Stipendio kde-format Bills Ricevute kde-format Clothing Vestiario kde-format Groceries Cibario kde-format Leisure Comodità kde-format Couldn't fetch %1. Impossibile recuperare %1. kde-format Error loading %1: %2. Errore caricando %1: %2. kde-format Couldn't open file Impossibile aprire il file kde-format Error saving %1: %2. Errore salvando %1: %2. kde-format Couldn't save file Impossibile salvare il file kde-format Failed to upload file to %1. Fallito l'upload del file a %1. kde-format Report Rapporto kde-format Chart Diagramma kde-format Transaction Schedule Transazione Pianificata kde-format Accounts &amp; Categories html format Conti &amp; Categorie kde-format Accounts &amp; Categories (%1&ndash;%2) html format Conti &amp; Categorie (%1&ndash;%2) kde-format Accounts &amp; Categories (to %1) html format Conti &amp; Categorie (a %1) kde-format Change Cambio kde-format Balance Bilanciamento kde-format Budget Budget kde-format Remaining Budget Budget restante kde-format Total Incomes Totale delle Entrate kde-format Costs Costi kde-format Total Expenses Totale delle Uscite kde-format Empty expenses list. Svuota la lista delle uscite. kde-format Empty incomes list. Svuota la lista delle entrate. kde-format Empty transfers list. Svuota la lista dei trasferimenti. kde-format Empty securities list. Svuola la lista dei titoli kde-format Empty schedule list. Svuota la lista delle pianificazioni. kde-format Export View… Esporta vista… kde-format Print View… Stampa vista… kde-format Initial Period Periodo Iniziale kde-format Remember Last Dates Ricorda Ultimi Appuntamenti kde-format Import CSV File… Importa File CSV… kde-format Import QIF File… Importa File QIF… kde-format Export As QIF File… Esporta file come QIF… kde-format Add Account… Aggiungi Conto… kde-format New Account… Nuovo Conto… kde-format New Income Category… Nuova Categoria d'Entrata… kde-format New Expense Category… Nuova Categoria di Uscita… kde-format Balance… Bilanciamento… kde-format Show Transactions Mostra Transazioni kde-format New Transfer… Nuovo Trasferimento… kde-format New Split Transaction… Nuova Transazione Suddivisa kde-format Edit Transaction(s) (Occurrence)… Modifica Transazione(i) (Occorrenza)… kde-format Edit Occurrence… Modifica Ricorrenza kde-format Edit Schedule (Recurrence)… Modifica Pianificazione (Ricorrenza)… kde-format Edit Schedule… Modifca Pianificazione… kde-format Remove Transaction(s) (Occurrence) Elimina Transazione(i) (Occorrenza) kde-format Remove Occurrence Elimina Ricorrenza kde-format Delete Schedule (Recurrence) Elimina Pianficazione (Ricorrenza) kde-format Delete Schedule Elimina Pianificazione kde-format Edit Split Transaction… Modifica Transazione Suddivisa kde-format Remove Split Transaction Elimina Transazione Suddivisa kde-format Join Transactions… Unisci Transazioni… kde-format Split Up Transaction Suddividi Transazione kde-format Refund… Ricerca… kde-format Repayment… Ripagamento… kde-format Edit Security… Modifica titolo… kde-format Remove Security Elimina titolo kde-format Shares Sold… Azioni Vendute… kde-format Shares Bought… Azioni Acquistate… kde-format Dividend… Dividendo… kde-format Reinvested Dividend… Dividendo Reinvestito… kde-format Shares Moved… Azioni Spostate… kde-format Edit Quotations… Modifica Quotazioni… kde-format Transactions… Transazioni… kde-format Development Over Time Report… Rapporto di sviluppo temporale… kde-format Categories Comparison Report… Rapporto di comparazioni delle categorie… kde-format Categories Comparison Chart… Diagramma di comparazione delle categorie… kde-format Development Over Time Chart… Diagramma su sviluppo temporale… kde-format Use Additional Transaction Properties Utilizza le proprietà aggiuntive per le transazioni kde-format Eqonomize! exited unexpectedly before the file was saved and data was lost. Do you want to load the last auto-saved version of the file? Eqonomize! è uscito inaspettatamente prima che il file venisse salvato. I dati sono stati persi. Vuoi caricare l'ultima versione auto-salvata del file? kde-format Crash Recovery Recupero dal crash kde-format The current file has been modified. Do you want to save it? Il file corrente è stato modificato. Vuoi salvarlo? kde-format Confirm Schedule Conferma Pianificazione kde-format New Account Nuovo Conto kde-format New Income Category Nuova categoria d'entrata kde-format New Expense Category Nuova categoria di uscita kde-format Balance Account Bilanciamento del conto kde-format Book value: Valore contabile: kde-format Real value: Valore reale: kde-format Edit Account Modifica Conto kde-format Edit Income Category Modifica categoria di entrata kde-format Edit Expense Category Modifica categoria di uscite kde-format Move transactions? Spostare le transizioni? kde-format Move to: Sposta a: kde-format The category contains some expenses. What do you want to do with them? La categoria contiene delle uscite. Cosa vuoi farne? kde-format The category contains some incomes. What do you want to do with them? La categoria contiene delle entrate. Cosa vuoi farne? kde-format The account contains some transactions. What do you want to do with them? La categoria contiene delle transazioni. Cosa vuoi farne? kde-format The category contains some expenses that will be removed. Do you still want to remove the category? La categoria contiene delle uscite che verranno eliminate. Sei sicuro di voler eliminare la categoria? kde-format Remove Category? Rimuovere la categoria? kde-format The category contains some incomes that will be removed. Do you still want to remove the category? La categoria contiene delle entrate che verranno eliminate. Sei sicuro di voler eliminare la categoria kde-format The account contains some transactions that will be removed. Do you still want to remove the account? La categoria contiene delle transizioni che verranno eliminate. Sei sicuro di voler eliminare la categoria kde-format Remove Account? Eliminare il Conto? kde-format %2 of %1 %1: budget; %2: remaining budget %2 di %1 kde-format %1 (with no budget) %1 (senza budget) kde-format %1 (with budget %2) %1 (con budget %2) kde-format Import CSV file Importa file CSV kde-format Transaction Type Selection Selezione Tipo di Transazione kde-format Expenses and incomes (negative cost) Uscite ed entrate (costi negativi) kde-format Expenses and incomes (separate columns) Uscite ed entrate (colonne separate) kde-format All types Tutti i tipi kde-format File Selection Selezione file kde-format File: File: kde-format First data row: Prima colonna di dati: kde-format Auto Auto kde-format Column delimiter: Delimitatore delle Colonne: kde-format Comma Virgola kde-format Tabulator Tabulatore kde-format Semicolon Punto e virgola kde-format Space Spazio kde-format Columns Specification Specifica delle colonne kde-format Column Colonna kde-format Category: Categoria: kde-format From account: Dal conto: kde-format Create missing categories and accounts Creare le categorie e i conti mancanti kde-format Imports data as expenses. Costs have positive value. Value is the only required column. Importa i dati come uscite. I costi hanno un valore positivo. L'unica colonna richiesta è: valore. kde-format Imports data as incomes. Value is the only required column. Importa i dati come entrate. L'unica colonna richiesta è: valore. kde-format To account: Al conto: kde-format Imports data as transfers. Value is the only required column. Importa i dati come trasferimenti. L'unica colonna richiesta è: valore. kde-format Amount: Quantità: kde-format Imports data as expenses and incomes. Costs have negative value. Value and category are both required columns. Importa i dati come uscite ed entrate. I costi hanno un valore negativo. Sono richieste le colonne: valore, categoria. kde-format Imports data as expenses and incomes. Costs and incomes have separate columns. Income, cost, and category are all required columns. Importa i dati come uscite ed entrate. I costi e le entrate hanno colonne separate. Sono richieste le colonne: entrata, costo, categoria. kde-format Imports data as expenses, incomes, and transfers. Costs have negative or positive value. Value, to, and from are all required columns. Accounts and categories must be existing. Importa i dati come uscite, entrate e trasferimenti. I costi hanno dei valori negativi o positivi. Sono richieste le colonne: valore, a, da. Conti e categorie devono essere presenti. kde-format From: Da: kde-format To: A: kde-format A file must be selected. Deve essere selezionato un file. kde-format Selected file is a directory. Il file selezionato è una cartella. kde-format Selected file does not exist. Il file selezionato non esiste. kde-format Empty delimiter. Delimitatore vuoto. kde-format The same column number is selected multiple times. Lo stesso numero di colonna è selezionato più volte kde-format Selected from account is the same as the to account. Il conto Da selezionato è lo stesso del conto A. kde-format Couldn't open %1 for reading. Impossibile aprire %1 in lettura. kde-format Error reading %1. Errore leggendo %1. kde-format Successfully imported 1 transaction. Importo di 1 transazione riuscito. Importo di %n transazioni riuscito. kde-format Successfully imported %n transactions. Unable to import any transactions imported. Fallito l'importo delle transazioni importati. kde-format Failed to import 1 data row. Fallito l'importo di 1 linea di dati. Fallito l'importo di %n linee di dati kde-format Failed to import %n data rows. Required columns missing. Richieste delle colonne mancanti. kde-format Invalid value. Valore non valido. kde-format Empty category name. Nome categoria vuoto. kde-format Empty account name. Nome account vuoto. kde-format Unknown category found. Trovata categoria sconosciuta. kde-format Unknown account found. Trovato un conto non conosciuto. kde-format Cannot import security transactions (to/from security accounts). Impossibile importare le transazioni dei titoli (da/a conti di titoli). kde-format Balancing account wrongly used. Il bilanciamento del conto è utilizzato incorrettamente. kde-format No data found. Nessuna dato trovato. kde-format Unrecognized date format. Il formato della data non è riconosciuto. kde-format Specify Format Specificare il formato kde-format The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. Il formato delle date e/o i numeri nel file CSV è ambiguo. Per favore seleziona il formato corretto. kde-format Date format: Formato della data: kde-format Value format: Formato del valore: kde-format tomorrow the day after today domani kde-format today this day oggi kde-format yesterday the day before today ieri kde-format &Today @option today &Oggi kde-format To&morrow @option tomorrow Do&mani kde-format Next &Week @option next week &Settimana prossima kde-format Next M&onth @option next month Il mese pr&ossimo kde-format No Date @option do not specify a date Senza data kde-format Export… Esporta… kde-format Print… Stampa… kde-format Withdrawal Prelievo kde-format Join… Unisci… kde-format Split Up Dividi kde-format Empty transaction list. Svuota la lista delle transazioni. kde-format Are you sure you want to delete all (%1) selected transactions? Sei sicuro di volere eliminare tutte le (%1) transazioni? kde-format Cannot change description of dividends and security transactions. Impossibile cambiare la descrizione dei dividendi e delle transazioni dei titoli. kde-format Cannot change payer of dividends and security transactions. Impossibile cambiare il debitore dei dividenti e delle transazioni dei titoli. kde-format Cannot change date of transactions that are part of a split transaction. Impossibile cambiare la data delle transizione che fanno parte di una transizione suddivisa. kde-format Eqonomize! Eqonomize! A personal accounting program Un programma di contabilità personale Start with expenses list displayed Avvia mostrando la lista delle uscite Start with incomes list displayed Avvia mostrando la lista delle entrate Start with transfers list displayed Avvia mostrando la lista dei trasferimenti Document to open Documento da aprire Incomes and Expenses Entrate ed Uscite kde-format Profits Profitti kde-format All Categories Combined Tutte le categorie combinate kde-format All Descriptions Combined Tutte le descrizioni combinate kde-format All Payees/Payers Combined Tutti debitori/creditori combinati kde-format Start date: Data di inizio: kde-format End date: Data di conclusione: kde-format Monthly total Totale mensile kde-format Daily average Media giornaliera kde-format All Payers Combined Tutti i debitori combinati kde-format All Payees Combined Tutti i creditori combinati kde-format All Descriptions Split Tutte le descrizioni suddivise kde-format All Payers Split Tutti i debitori suddivisi kde-format All Payees Split Tutti i creditori suddivisi kde-format All Categories Split Tutte le categorie suddivise kde-format Value (%1) Valore (%1) kde-format Profit (%1) Profitto (%1) kde-format Income (%1) Entrata (%1) kde-format Cost (%1) Costo (%1) kde-format Time Tempo kde-format no payer nessun debitore kde-format %1/%2 %1: Description; %2: Payer %1/%2 kde-format no payee nessun creditore kde-format %1/%2 %1: Description; %2: Payee %1/%2 kde-format Error after saving file; data may not have been saved. Errore dopo il salvataggio del file; i dati potrebbero non essere stati salvati. kde-format Average Profit Profitto Medio kde-format Year Anno kde-format Month Mese kde-format Includes scheduled transactions Includi le transizioni pianificate kde-format Adjusted for the average month / year (%1 / %2 days) Adattati per la media mese / anno (%1 / %2 giorni) kde-format Subtotal Subtotale kde-format Unnamed Senza nome kde-format Uncategorized Non categorizzato kde-format Import QIF file Importa file QIF kde-format Select a QIF file to import. When you click next, the file be analysed and you might need to answer some questions about the format of the file. Seleziona un file QIF da importare. Quando cliccherai su prossimo, il file verrà analizzato e potresti avere il bisogno di rispondere ad alcune domande riguardo al formato del file. kde-format Local Definitions Definizioni locali kde-format Local Text Testo locale kde-format Standard Text Testo standard kde-format Select standard text: Seleziona il testo standard: kde-format Date Format Formato della data kde-format The date format in the QIF file is ambiguous. Please select the correct format. Il formato della data nel file QIF è ambigua. Per favore seleziona il formato corretto. kde-format Default Account Conto predefinito kde-format Default account: Conto predefinito: kde-format Opening balance text: Testo di apertura bilancio: kde-format Descriptions Descrizioni kde-format Subcategories as: Sottocategorizza come: kde-format Ignore Ignora kde-format Payee as: Creditore come: kde-format Payee Debitore kde-format Memo as: Memorizza come: kde-format Priority: Priorità: kde-format Subcategory/Payee/Comments Sottocategoria/Creditore/Commenti kde-format Payee/Subcategory/Comments Creditore/Sottocategoria/Commenti kde-format Subcategory/Comments/Payee Sottocategoria/Commenti/Creditore kde-format Payee/Comments/Subcategory Creditore/Commenti/Sottocategoria kde-format Comments/Subcategory/Payee Commenti/Sottocategoria/Creditore kde-format Comments/Payee/Subcategory Commenti/Creditore/Sottocategoria kde-format Unknown Sconosciuto kde-format Bank Banca kde-format Cat (Category) Cat (Categoria) kde-format CCard (Credit Card) CCredito (Carta di Credito) kde-format Invst (Investment) Invest (Investimento) kde-format Oth A (Other Assets) Altre A (Altre Attività) kde-format Oth L (Other Liabilities) Altre P (Altre Passività) kde-format Security Titolo kde-format Successfully imported 1 account. Importato correttamente 1 conto. Importati correttamente %n conti. kde-format Successfully imported %n accounts. Successfully imported 1 category. Importata correttamente 1 categoria. Importate correttamente %n categorie. kde-format Successfully imported %n categories. 1 duplicate transaction was ignored. 1 duplicato della transazione è stato ignorato %n duplicati della transazione sono stati ignorati kde-format %n duplicate transactions was ignored. Failed to import 1 transaction. Fallito l'importo di 1 transazione. Fallito l'importo di %n transazioni. kde-format Failed to import %n transactions. 1 security was not imported. 1 titolo non è stato importato. %n titoli non sono stati importati. kde-format %n securities were not imported. 1 security transaction was not imported. 1 transazione di titolo non è stata importata. %n transazioni di titoli non sono state importate. kde-format %n security transactions were not imported. Export QIF File Esporta file QIF kde-format All All accounts Tutti kde-format Export transaction description as: Esporta le descrizioni delle transizione come: kde-format Memo Memo kde-format Subcategory Sottocategoria kde-format &Import i18n: tag text i18n: file ./eqonomizeui.rc line 5 &Importa kde-format &Accounts i18n: tag text i18n: file ./eqonomizeui.rc line 12 &Conti kde-format &Transactions i18n: tag text i18n: file ./eqonomizeui.rc line 24 &Transazioni kde-format &Securities i18n: tag text i18n: file ./eqonomizeui.rc line 41 &Titoli kde-format Stat&istics i18n: tag text i18n: file ./eqonomizeui.rc line 56 Stat&istiche kde-format Your names NAME OF TRANSLATORS Giuseppe Bottiglieri,,Launchpad Contributions:,Giuseppe Bottiglieri,Guybrush88,Luca Livraghi,Marco, ,Launchpad Contributions:,Giuseppe Bottiglieri,Guybrush88,Hanna K.,Luca Livraghi,Marco,Martino Barbon,simone.sandri kde-format Your emails EMAIL OF TRANSLATORS Giuseppe.Bottiglieri@gmail.com,,,Giuseppe.Bottiglieri@gmail.com,,luca.91@hotmail.it,,,,Giuseppe.Bottiglieri@gmail.com,,,luca.91@hotmail.it,,,lexluxsox@hotmail.it kde-format Edit Exceptions Modifica eccezioni kde-format Edit Recurrence Range Modifica intervallo di ricorrenza kde-format Begins on: %1 Comincia il: %1 kde-format No ending date Nessuna data finale kde-format End after Termina dopo kde-format occurrence(s) occorrenza/e kde-format End on Verso la fine kde-format End date before start date. La data finale è prima della data di inizio. kde-format Enable recurrence Abilita ricorrenza kde-format Recurrence Rule Regola di ricorrenza kde-format Weekly Settimanalmente kde-format Recur every Occorri ogni kde-format day(s) giorno/i kde-format week(s) on: settimana/e di: kde-format month(s), after the start month mese/i, dopo il mese di avvio kde-format Recur on the Occorri il kde-format 1st kde-format 2nd kde-format 3rd kde-format 4th 4 kde-format 5th 5 kde-format 6th 6 kde-format 7th 7 kde-format 8th 8 kde-format 9th 9 kde-format 10th 10 kde-format 11th 11 kde-format 12th 12 kde-format 13th 13 kde-format 14th 14 kde-format 15th 15 kde-format 16th 16 kde-format 17th 17 kde-format 18th 18 kde-format 19th 19 kde-format 20th 20 kde-format 21st 21 kde-format 22nd 22 kde-format 23rd 23 kde-format 24th 24 kde-format 25th 25 kde-format 26th 26 kde-format 27th 27 kde-format 28th 28 kde-format 29th 29 kde-format 30th 30 kde-format 31st 31 kde-format Last Ultimo kde-format 2nd Last penultimo kde-format 3rd Last terzultimo kde-format 4th Last quartultimo kde-format 5th Last quintultimo kde-format day giorno kde-format possibly on weekend possibilmente in settimana kde-format but before weekend ma prima del fine settimana kde-format but after weekend ma dopo il fine settimana kde-format year(s), after the start year anno/i, dopo l'anno di inizio kde-format of part between XXX and YYY of 'Recur on day XXX of month YYY' di kde-format On the Part before NNN in 'Recur on the NNN. WEEKDAY of MONTH' su kde-format of part between WEEKDAY and MONTH in 'Recur on NNN. WEEKDAY of MONTH' di kde-format Recur on day # Ricorri il giorno # kde-format of the year part after NNN of 'Recur on day #NNN of the year' dell'anno kde-format Range… Intervallo… kde-format Exceptions… Eccezioni… kde-format No day of week selected for weekly recurrence. Nessun giorno della settimana è stato selezionato per la ricorrenza settimanale. kde-format Selected day does not exist in selected month. Il giorno selezionato non esiste nel mese selezionato. kde-format Dividend: %1 Dividendo: %1 kde-format Account balancing Bilanciamento del conto kde-format Security: %1 (bought) Titolo: %1 (comprato) kde-format Security: %1 (sold) Titolo: %1 (venduto) kde-format Shares bought: Azioni acquistate: kde-format Shares sold: Azioni vendute: kde-format Payer: Debitore: kde-format Payee: Creditore: kde-format No income category available. Nessuna categoria di entrata è disponibile. kde-format No expense category available. Nessuna categoria di uscita è disponibile. kde-format Cannot create a regular transfer to/from a securities account. Impossibile creare un regolare trasferimento a/da un conto di titoli. kde-format Cannot create a regular income to a securities account. Impossibile creare una regolare entrata da un conto di titoli. kde-format Zero price per share not allowed. Zero per cento delle azioni non è permesso. kde-format Cannot create a regular expense from a securities account. Impossibile creare una regolare uscita da un conto di titoli. kde-format Modify Transactions Modifica Transazioni kde-format Min amount: Min quantità: kde-format Max amount: Max quantità: kde-format Min income: Min entrata: kde-format Max income: Max entrata: kde-format Min cost: Min costo: kde-format Max cost: Max costo: kde-format Include Includi kde-format Exclude Escludi kde-format From Account Dal Conto kde-format To Account Al Conto kde-format Payer Debitore kde-format New/Edit Expense Nuova/Modifica Uscita kde-format Filter Filtro kde-format Total: Totale: kde-format Average: Media: kde-format Monthly: Mensilmente: kde-format Total cost: Totale dei costi: kde-format Total income: Totale delle entrate: kde-format Total amount: Tatale delle quantità: kde-format Monthly average: Media mensile: kde-format * Part of split transaction * Parte di una transazione suddivisa kde-format * Part of split (%1) *Parte di una suddivisione (%1) kde-format Modify… Modifica… kde-format AccountComboBox New account… Nuovo conto… Multiple accounts/payments… New income category… Nuova categoria d'entrata… New expense category… Nuova categoria di uscita… Paid with loan… New Account Nuovo conto New Income Category Nuova categoria d'entrata New Expense Category Nuova categoria di uscita AccountsMenu All Accounts Tutti i conti All Categories Combined Tutte le categorie combinate %n accounts %n conto %n conti %n categories %n categoria %n categorie Balancing Account balancing Bilanciamento del conto Account balancing Balancing of an account Bilanciamento del conto Account Balance Adjustment Regolazione del saldo del conto Budget Balancing Bilanciamento Balancing Name of account for transactions that adjust account balances Bilanciamento Couldn't open %1 for reading Impossibile aprire %1 per la lettura Not a valid Eqonomize! file (XML parse error: "%1" at line %2, col %3) Non è un file valido di Eqonomize! (Errore di analisi XML: "%1" alla linea %2, colonna %3) Invalid root element %1 in XML document L'elemento radice %1 del documento XML non è valido Unknown XML element: "%1" at line %2, col %3 XML parse error: "%1" at line %2, col %3 European Euro Unable to load %n currency/currencies. No exchange rates found. USD currency missing. imported Unable to load %n account(s). Fallito il caricamento di %n conto. Fallito il caricamento di %n conti. Unable to load %n category/categories. Fallito il caricamento di %n categoria. Fallito il caricamento di %n categorie. Unable to load %n security/securities. Financial security (e.g. stock, mutual fund) Fallito il caricamento di %n titolo. Fallito il caricamento di %n titoli. Unable to load %n transaction(s). Fallito il caricamento di %n transizione. Fallito il caricamento di %n transizioni. Download command (%1) failed: %2. Failed to download file from %1: %2. Upload command (%1) failed: %2. yyyy-yy Financial year when first month is not January (e.g. 2018-19). Transaction Accounts Conti correnti Savings Accounts Conti di risparmio Credit Cards Carte di credito Debts Debiti Securities Financial security (e.g. stock, mutual fund) Titoli Cash Contante Transaction Account Conto corrente Savings Account Libretto di risparmio Credit Card Carta di credito Debt Debito Other Altro File is a directory Il file è una directory Couldn't open file for writing Impossibile aprire il file per la scrittura Error while writing file; file was not saved Errore nella scrittura del file; il file non è stato salvato Unnamed Senza nome Uncategorized Non categorizzato CategoriesComparisonChart Save As… Salva come… Print… Stampa… From Da To A Source: Fonte: All Expenses Tutte le uscite All Incomes Tutte le entrate Theme: Chart type: Pie Chart Bar Chart Default Predefinito All Expenses, without subcategories Tutte le uscite, senza sottocategorie All Expenses, with subcategories Tutte le uscite, con sottocategorie All Incomes, without subcategories Tutte le entrate, senza sottocategorie All Incomes, with subcategories Tutte le entrate, con sottocategorie All Accounts Tutti i conti Expenses: %1 Uscite: %1 Incomes: %1 Entrate: %1 Error Invalid date. Data non valida. To date is before from date. La data A è precedente alla data Da. From date is after to date. La data Da è posteriore alla data A. Couldn't open file for writing. Impossibile aprire il file per la scrittura. Error while writing file; file was not saved. Errore nella scrittura del file; il file non è stato salvato. Expenses Uscite Expenses, %1 Uscite, %1 Incomes, %1 Entrate, %1 Incomes Entrate Accounts Conti Expenses, %2: %1 Uscite, %2: %1 Incomes, %2: %1 Entrate, %2: %1 Other descriptions Referring to the transaction description property (transaction title/generic article name) Altre descrizioni No description Referring to the transaction description property (transaction title/generic article name) Nessuna descrizione Other accounts Altri conti Other categories Altri categorie %1 Value: %2 %1 Valore: %2 No description Referring to the Transaction description property (transaction title/generic article name) Nessuna descrizione No description Referring to the generic description property Nessuna descrizione Value Valore Income Entrata Cost Costo Value (%1) Valore (%1) Income (%1) Entrata (%1) Cost (%1) Costo (%1) No description Nessuna descrizione CategoriesComparisonChartDialog Chart Diagramma CategoriesComparisonReport Save As… Salva come… Print… Stampa… Source: Fonte: All Categories, excluding subcategories Tutte le categorie, escluse le sottocategorie All Categories, including subcategories Tutte le categorie, tra le sottocategorie All Payees/Payers Tutti i creditore/debitore Subcategories Sottocategorizza Descriptions for Referring to the Transaction description property (transaction title/generic article name) Descrizione per All descriptions Referring to the Transaction description property (transaction title/generic article name) Tutte le descrizioni No description Referring to the Transaction description property (transaction title/generic article name) Nessuna descrizione All Categories Tutte le categorie Expenses: %1 Uscite: %1 Incomes: %1 Entrate: %1 Descriptions for Descrizione per Payees/payers for Creditore/debitore per Descriptions Referring to the Transaction description property (transaction title/generic article name) Descrizioni Period: Periodo: From Da To A Columns: Colonne: Value Valore Daily Giornalmente Monthly Mensilmente Yearly Annualmente Quantity Quantità Average value Valore medio All descriptions Tutte le descrizioni All payees Tutti i creditori All payers Tutti i debitori No description Nessuna descrizione Descriptions for Referring to the generic description property Descrizione per Descriptions Referring to the generic description property Descrizioni All descriptions Referring to the generic description property Tutte le descrizioni No description Referring to the generic description property Nessuna descrizione All Payees and Payers Tutti i creditori e i debitori Tag: %1 Etichetta: %1 All Accounts Tutti i conti Descriptions for Referring to the transaction description property (transaction title/generic article name) Descrizione per Descriptions Referring to the transaction description property (transaction title/generic article name) Descrizioni Months Mesi Years Anni Tags Etichette Total: Totale: All descriptions Referring to the transaction description property (transaction title/generic article name) Tutte le descrizioni All payees/payers Tutti i creditori/debitori No description Referring to the transaction description property (transaction title/generic article name) Nessuna descrizione No payee Nessun creditore No payer Nessun debitore Error Invalid date. Data non valida. To date is before from date. La data A è precedente alla data Da. From date is after to date. La data Da è posteriore alla data A. Couldn't open file for writing. Impossibile aprire il file per la scrittura. Error while writing file; file was not saved. Errore nella scrittura del file; il file non è stato salvato. Expenses, %2: %1 Uscite, %2: %1 Expenses, %3: %2, %1 Uscite, %3: %2, %1 Incomes, %2: %1 Entrate, %2: %1 Incomes, %3: %2, %1 Entrate, %3: %2, %1 %3: %2, %1 %3: %2, %1 %2: %1 %2: %1 Tags, %1 Etichette, %1 Incomes & Expenses, %1 Entrate ed uscite, %1 Expenses: %2, %1 Uscite: %2, %1 Incomes: %2, %1 Entrate: %2, %1 %2, %1 %2, %1 %1 %1 Incomes & Expenses Entrate ed uscite %1 (%2&ndash;%3) html format; %1: title; %2: from date; %3: to date %1 (%2&ndash;%3) %1 (to %2) html format; %1: title; %2: to date %1 (a %2) Category Categoria Payee Debitore Description Referring to the transaction description property (transaction title/generic article name) Descrizione Cost Costo Payer Debitore Income Entrata Payee/Payer Creditore/debitore Tag Etichetta Daily Average Media giornaliera Monthly Average Media mensile Yearly Average Media annuale Average Cost Media dei costi Average Income Media delle entrate Average Value Valore medio No payee/payer Nessun creditore/debitore Total Totale All Tags Tutte le etichette Total incomes Totale delle entrate Total expenses Totale delle uscite Total (Profits) Totale (profitti) CategoriesComparisonReportDialog Report Rapporto ConfirmScheduleDialog The following transactions was scheduled to occur today or before today. Confirm that they have indeed occurred (or will occur today). La seguente transazione è stata pianificata per occorrere oggi o precedentemente. Conferma che è veramente occorsa (o che occorrerà oggi). Date Data Type Tipo Description Descrizione Name Nome Description Generic Description Descrizione Description Transaction description property (transaction title/generic article name) Descrizione Amount Quantità Edit… Modifica… Postpone… Rinvia… Delete Elimina Error Can only postpone to future dates. Si può rinviare solo a date future. ConfirmScheduleListViewItem Transfer Trasferimento Dividend Dividendo Income Entrata Expense Uscita Securities Purchase Financial security (e.g. stock, mutual fund) Acquisto di titoli Securities Sale Financial security (e.g. stock, mutual fund) Vendita di titoli Security Buy Acquisto di titoli Security Sell Vendita di titoli Debt Payment CurrencyConversionDialog Currency Converter DebtFee Debt payment: %1 (fee) DebtInterest Debt payment: %1 (interest) DebtPayment Debt payment: %1 DebtReduction Debt payment: %1 (reduction) DescriptionsMenu All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Tutte le descrizioni combinate All Tags Combined All Payees Combined Tutti i creditori combinati All Payers Combined Tutti i debitori combinati All Payees/Payers Combined No description Referring to the transaction description property (transaction title/generic article name) Nessuna descrizione No payee Nessun creditore No payer Nessun debitore No payee/payer Nessun creditore/debitore %n descriptions Referring to the transaction description property (transaction title/generic article name) %n descrizione %n descrizioni %n tags %n etichetta %n etichette %n payees %n creditore %n creditori %n payers %n debitore %n debitori %n payees/payers %n creditore/debitore %n creditori/debitori EditAssetsAccountDialog Type: Tipo: Cash Contante Current Account Conto Corrente Savings Account Libretto di risparmio Credit Card Carta di credito Liabilities Passività Transactional Account Conto corrente Debt Debito Securities Titoli Other Altro Currency: Edit Modifica Name: Nome: Bank: Banca: Initial balance: Bilancio iniziale: Debt: Initial balance Bilancio iniziale Group: Gruppo: no group nessun gruppo Transferred to: Date: Data: Lender: Default account for budgeted transactions Account predefinito per transazioni finanziate Description: Descrizione: Account is closed Warning Type cannot be changed to securities for accounts with transactions. Issuer: Zero value not allowed. Il valore zero non è permesso. Error Transaction Account Conto corrente Opening balance: Account balance Bilancio di apertura: Opening balance Account balance Bilancio di apertura New currency… If you change the currency of an account, the currency of all associated transactions will also change, without any conversion. Do do wish to continue anyway? Empty name. Nome vuoto. The entered name is used by another account. Il nome inserito è utilizzato da un altro conto. EditCurrencyDialog Edit Currency New Currency Code: Symbol: Prefix Suffix Default Predefinito Name: Nome: Decimals: Date: Data: Main currency Error Error saving currencies: %1. Empty code. Code already exists. EditDebtPaymentDialog Debt Payment EditDebtPaymentWidget Debt: Date: Data: Debt reduction: Reduction payment: Interest: Paid Added to debt Fee: Account: Conto: Expense category: Associated file: File associato: Select a file Open the file Comments: Commenti: Related to: Label for linked transactions Collegamenti: Total value: Valore totale: Error No suitable account available. Nessun conto adeguato è disponibile. Invalid date. Data non valida. Interest must not be zero. At least one value must non-zero. EditExceptionsDialog Edit Exceptions Modifica eccezioni Occurrences: Occorrenze: Add Exception Remove Exception Exceptions: Eccezioni: Only the first fifty occurrences are shown. Invalid date. Data non valida. EditExpensesAccountDialog Name: Nome: Parent category: None Monthly budget: Budget Mensile: Description: Descrizione: Error Empty name. Nome vuoto. The entered name is used by another expense category. Il nome inserito è utilizzato da un'altra categoria di uscita. EditIncomesAccountDialog Name: Nome: Parent category: None Monthly budget: Budget Mensile: Description: Descrizione: Error Empty name. Nome vuoto. The entered name is used by another income category. Il nome inserito è utilizzato da un'altra categoria d'entrata. EditLoanTransactionWidget Date: Data: Account: Conto: Comments: Commenti: Total value: Valore totale: No suitable account available. Nessun conto adeguato è disponibile. Invalid date. Data non valida. EditMultiAccountDialog Expense with Multiple Payments Income with Multiple Payments EditMultiAccountWidget Description: Descrizione: Description: Generic Description Descrizione: Description: Transaction description property (transaction title/generic article name) Descrizione: Quantity: Quantità: Category: Categoria: Tags: Etichette: Associated file: File associato: Select a file Open the file Comments: Commenti: Related to: Label for linked transactions Collegamenti: Transactions: Transazioni: Date Data Account Conto Payee Debitore Payer Debitore Cost Costo Income Entrata Total cost: Totale dei costi: New Tag Nuova etichetta Tag: Etichetta: Value Valore New Nuovo Edit… Modifica… Delete Elimina Total value: Valore totale: Error No suitable expense categories available. A split must contain at least two transactions. Una suddivisione deve contenere almeno due transazioni. EditMultiItemDialog Split Transaction Dividi la transazione EditMultiItemWidget Description: Descrizione: Description: Generic Description Descrizione: Date: Data: Account: Conto: Payee/Payer: Creditore/debitore: Transactions: Transazioni: Type Tipo Description Generic Description Descrizione Description: Transaction description property (transaction title/generic article name) Descrizione: Tags: Etichette: Associated file: File associato: Select a file Open the file Comments: Commenti: Related to: Label for linked transactions Collegamenti: Description Transaction description property (transaction title/generic article name) Descrizione Payment Pagamento Deposit Deposito New Nuovo New Expense… Nuova uscita… New Income… Nuova entrata… New Deposit… Nuovo deposito… New Withdrawal… Nuovo prelievo… New Securities Purchase… Financial security (e.g. stock, mutual fund) Nuovo acquisto di titoli… New Securities Sale… Financial security (e.g. stock, mutual fund) Nuova vendita di titoli… Shares Bought… Azioni Acquistate… Shares Sold… Azioni Vendute… Account/Category Conto/Categoria Value Valore Income Entrata Expense Uscita New Dividend… Nuovo dividendo… Edit… Modifica… Delete Elimina Total value: Valore totale: Error No suitable account available. Nessun conto adeguato è disponibile. Invalid date. Data non valida. A split must contain at least two transactions. Una suddivisione deve contenere almeno due transazioni. Cannot transfer money to and from the same account. Impossibile trasferire denaro a e dallo stesso conto. EditQuotationsDialog Quotations Quotazione Date Data Price per Share Prezzo per Azione Quotations Financial quotation Quotazione Quotes Financial quote Quotazioni Price per Share Financial Shares Prezzo per azione Add Agguingi Modify Modifica Delete Elimina Import… Importa… Export… Esporta… Quotes for %1 Financial quote Quotazione per %1 Quotations for %1 Financial quotation Quotazione per %1 Quotations for %1 Quotazione per %1 Error Couldn't open %1 for reading. Impossibile aprire %1 in lettura. Error reading %1. Errore leggendo %1. Successfully imported %n quote(s). Importata correttamente %n quotazione. Importata correttamente %n quotazioni. Unable to import any quotes. Failed to import %n data row(s). Fallito l'importo di %n linea di dati. Fallito l'importo di %n linee di dati. Required columns missing. Richieste delle colonne mancanti. Invalid value. Valore non valido. Invalid date. Data non valida. No data found. Nessuna dato trovato. Information Unrecognized date format. Il formato della data non è riconosciuto. Specify Format Specificare il formato The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. Il formato delle date e/o i numeri nel file CSV è ambiguo. Per favore seleziona il formato corretto. Date format: Formato della data: Value format: Formato del valore: Couldn't open file for writing. Impossibile aprire il file per la scrittura. Quotes: %1 Quotazioni: %1 Error while writing file; file was not saved. Errore nella scrittura del file; il file non è stato salvato. EditRangeDialog Edit Recurrence Range Modifica intervallo di ricorrenza Begins on: %1 Comincia il: %1 No ending date Nessuna data finale End after Termina dopo occurrence(s) occorrenza/e End on Verso la fine Error Invalid date. Data non valida. End date before start date. La data finale è prima della data di inizio. EditReinvestedDividendDialog Reinvested Dividend Dividendo reinvestito Security: Titoli: Shares added: Azioni aggiunte: Security: Financial security (e.g. stock, mutual fund) Titoli: Shares added: Financial shares Azioni aggiunte: Date: Data: Invalid date. Data non valida. EditScheduledDebtPaymentDialog Transaction Transazione Recurrence Ricorrenza Edit Debt Payment New Debt Payment EditScheduledLoanTransactionDialog Recurrence Ricorrenza EditScheduledMultiAccountDialog Transactions Transazioni Recurrence Ricorrenza New Expense with Multiple Payments New Income with Multiple Payments Edit Expense with Multiple Payments Edit Income with Multiple Payments EditScheduledMultiItemDialog Transactions Transazioni Recurrence Ricorrenza New Split Transaction Nuova transazione suddivisa Edit Split Transaction Modifica transazione suddivisa EditScheduledTransactionDialog Expense Uscita Dividend Dividendo Income Entrata Reinvested Dividend Dividendo reinvestito Transfer Trasferimento Security Buy Acquisto di titoli Security Sell Vendita di titoli Securities Purchase Financial security (e.g. stock, mutual fund) Acquisto di titoli Securities Sale Financial security (e.g. stock, mutual fund) Vendita di titoli Recurrence Ricorrenza New Expense Nuova uscita New Expense Paid with Loan New Dividend Nuovo dividendo New Income Nuova entrata New Transfer Nuovo trasferimento New Securities Purchase Financial security (e.g. stock, mutual fund) Nuovo acquisto di titoli New Reinvested Dividend New Securities Sale Financial security (e.g. stock, mutual fund) Nuova vendita di titoli Edit Reinvested Dividend Edit Securities Purchase Financial security (e.g. stock, mutual fund) Modifica i titoli acquistati Edit Securities Sale Financial security (e.g. stock, mutual fund) Modifica i titoli venduti New Security Buy Nuovo acquisto di titoli New Security Sell Nuova vendita di titoli Edit Expense Modifica uscita Edit Dividend Modifica dividendo Edit Income Modifica entrata Edit Transfer Modifica trasferimento Edit Securities Bought Modifica i titoli acquistati Edit Securities Sold Modifica i titoli venduti EditSecurityDialog Type: Tipo: Mutual Fund Fondi comuni Bond Bond Stock Azione Stock Financial stock Azione Other Altro Name: Nome: Account: Conto: Decimals in shares: Financial shares Decimali in azioni: Initial shares: Financial shares Azioni iniziali: Decimals in quotes: Financial quote Initial quote: Financial quote Quotazione iniziale: Empty name. Nome vuoto. No suitable account available. Nessun conto adeguato è disponibile. Initial quotation: Financial quotation Quotazione iniziale: Decimals in Shares: Decimali in Azioni: Initial Shares: Azioni Iniziali: Initial quotation: Quotazione iniziale: Date: Data: Description: Descrizione: Error EditSecurityTradeDialog Security Trade Commercio di titoli From security: Dal titolo: Shares moved: Titoli trasferiti: All Tutti To security: Al titolo: Shares received: Azioni ricevute: Securities Exchange Shares of one security directly exchanged for shares of another; Financial security (e.g. stock, mutual fund) Commercio di titoli From security: Financial security (e.g. stock, mutual fund) Dal titolo: Shares moved: Financial shares Titoli trasferiti: To security: Financial security (e.g. stock, mutual fund) Al titolo: Shares received: Financial shares Azioni ricevute: Value: Valore: Date: Data: Error No other security available for exchange in the account. Shares of one security directly exchanged for shares of another; Financial security (e.g. stock, mutual fund) Nessun altro titolo disponibile per commercio, nel conto. No other security available for trade in the account. Nessun altro titolo disponibile per commercio, nel conto. Selected to and from securities are the same. Financial security (e.g. stock, mutual fund) Zero shares not allowed. Financial shares Zero azioni non è permesso. Invalid date. Data non valida. Zero shares not allowed. Zero azioni non è permesso. Zero value not allowed. Il valore zero non è permesso. EditSplitDialog Split Transaction Dividi la Transazione Description: Descrizione: Date: Data: Account: Conto: Transactions: Transazioni: Type Tipo Description Descrizione Name: Nome: Name Nome Description Generic Description Descrizione Account/Category Conto/Categoria Payment Pagamento Deposit Deposito New Nuovo New Expense… Nuova Uscita… New Income… Nuova Entrata… New Deposit… Nuovo Deposito… New Withdrawal… Nuovo Prelievo… Shares Bought… Azioni Acquistate… Shares Sold… Azioni Vendute… New Dividend… Nuovo Dividendo Edit… Modifica… Total value: Valore totale: No suitable account available. Nessun conto adeguato è disponibile. Invalid date. Data non valida. Future dates is not allowed. Date future non sono permesse A split must contain at least two transactions. Una suddivisione deve contenere almeno due transazioni. Cannot transfer money to and from the same account. Impossibile trasferire denaro a e dallo stesso conto. Eqonomize Accounts && Categories Conti & categorie Expenses Uscite Incomes Entrate Transfers Trasferimenti Transaction Accounts Conti correnti Savings Accounts Conti di risparmio Credit Cards Carte di credito Debts Debiti Securities Titoli Schedule Pianificazione Account / Category Conto / categoria Remaining Budget (%1) Budget restante (%1) Change (%1) Cambio (%1) Total (%1) Totale (%1) %2 of %1 %2 remains of %1 budget %2 di %1 Accounts Conti Includes budgeted transactions Incluse le transazioni preventivate Tags Etichette Period Periodo From Da To A Select Period Seleziona periodo Current Month Il mese corrente Current Year L'anno corrente Current Whole Month L'intero mese corrente Current Whole Year L'intero anno corrente Whole Past Month L'intero mese trascorso Whole Past Year L'intero anno trascorso Previous Month Il mese precedente Previous Year L'anno precedente Show partial budget Mostra budget parziale Edit Budget Modifica il budget Budget: Budget: Month: Mese: Result previous month: Risultato del mese precedente: New Security… Nuovo titolo… New Transaction Nuova transazione Set Quotation… Fissa Quotazione… Name Nome Value Valore Shares Azioni Quotation Quotazione Cost Costo Profit Profitto Yearly Rate Tasso annuale Type Tipo Account Conto Statistics Period Periodo statistiche New Schedule Nuova pianificazione Edit Modifica Remove Rimuovi Next Occurrence Prossima ricorrenza Description Descrizione Description Generic Description Descrizione Amount Quantità Payee/Payer Creditore/debitore Comments Commenti Set Schedule Confirmation Time Schedule confirmation time: Set Budget Period First day in budget month: 1st 2nd 3rd 4th 4 5th 5 6th 6 7th 7 8th 8 9th 9 10th 10 11th 11 12th 12 13th 13 14th 14 15th 15 16th 16 17th 17 18th 18 19th 19 20th 20 21st 21 22nd 22 23rd 23 24th 24 25th 25 26th 26 27th 27 28th 28 Last Ultimo 2nd Last penultimo 3rd Last terzultimo 4th Last quartultimo 5th Last quintultimo Timestamp Marca temporale Links Collegamenti Remove Link Rimuovi collegamento Link to "%1" create link to transaction (link used as verb) Collega a "%1" All Tutti Import Options Ignore duplicate transactions Rename duplicate accounts Rename duplicate categories Rename duplicate securities Synchronization Settings Web address: Download command: Duplicate Transaction… duplicate as verb Duplicare transazione… Create Link create link to or between transaction(s) Crea collegamento New Tag… Nuova etichetta… Rename Tag… Rinominare l'etichetta… Remove Tag Rimuovere l'etichetta New Tag Nuova etichetta Tag name: Nome di etichetta: Remove tag? Rimuovere l'etichetta? Do you wish to remove the tag "%1" from %n transaction(s)? Rename Tag Rinominare l'etichetta optional Link Transactions create link between selected transactions (link used as verb) Collegare le transazioni Create Link to Transaction Crea collegamento alla transazione Upload command: mandatory Automatic synchronization Upload Uploading… Error uploading file Error uploading %1: %2. Synchronizing… Error synchronizing file Error synchronizing %1: %2. Synchronization error Synchronize file? The file has been modified by a different user or program. Do you wish to merge changes? New version available A new version of %1 is available.<br><br>You can get version %2 at %3. Abort First month in budget year: Right align Allinea a destra %f = local file (temporary), %u = url Failed to download exchange rates from %1: %2. Error reading data from %1: %2. Unrecognized Currency No exchange rate is available for the default currency (%1). If you wish to use multiple currencies you should set the exchange rate manually. Set Main Currency Currency: Replace all occurrences of the former main currency Transaction Account Conto corrente S&ynchronize Import %1 File… Reconcile Account… Adjust balance… Referring to account balance Regolare il saldo… Close Account Mark account as closed Chiudere conto New Expense Paid with Loan… Show payee and quantity Mostra creditore e quantità Show quantity and payer/payee properties for incomes and expenses. Set Schedule Confirmation Time… Select Font… Seleziona carattere… Language Lingua Default Predefinito Restart required Only use this when unable to find the cause of the incorrect recorded account balance. Reopen Account Mark account as not closed New Debt Payment… New Unpaid Interest… Shares of one security directly exchanged for shares of another Financial shares Use Exchange Rate for Transaction Date Use the exchange rate nearest the transaction date, instead of the latest available rate, when converting the value of transactions. %1 exited unexpectedly before the file was saved and data was lost. Do you want to load the last auto-saved version of the file? Eqonomize! Accounting File Save file? New Loan Adjust Account Balance Regolare il saldo del conto New Security Nuovo titolo Edit Security Modifica titolo Total value: Valore totale: Cost: Costo: Profit: Profitto: Rate: Tasso: Are you sure you want to delete the security "%1" and all associated transactions? Sei sicuro di voler eliminare il titolo "%1" e tutte le transazioni associate? Error Set Quotation (%1) Fissa Quotazione (%1) Price per share: Prezzo per azione: Date: Data: Invalid date. Data non valida. Future dates are not allowed. Date future non sono permesse. Security Transactions Transazioni di titoli Bond Bond Stock Azione Mutual Fund Fondi comuni Other Altro Add Loan Add Category Ledger Libro Maestro To date is before from date. La data A è precedente alla data Da. From date is after to date. La data Da è posteriore alla data A. Cash Contante Check Account Conto corrente Savings Account Conto di risparmio Salary Stipendio Bills Ricevute Clothing Vestiario Groceries Cibario Leisure Comodità Couldn't open file Impossibile aprire il file Error loading %1: %2. Errore caricando %1: %2. Couldn't save file Impossibile salvare il file Error saving %1: %2. Errore salvando %1: %2. Updating exchange rates… Error saving currencies: %1. New currency… Transaction Schedule Transazione Pianificata Total Totale Accounts &amp; Categories html format Conti &amp; categorie Accounts &amp; Categories (%1&ndash;%2) html format Conti &amp; categorie (%1&ndash;%2) Accounts &amp; Categories (to %1) html format Conti &amp; categorie (a %1) Change Noun, how much the account balance has changed Cambio Balance Bilanciamento Current Account Conto corrente Credit Card Carta di credito Liabilities Passività Set Quote… Financial quote Fissa quotazione… Quote Financial quote Quotazione Set Quote (%1) Financial quote Fissa quotazione (%1) Stock Financial stock Azione Balance Noun. Balance of an account Saldo Category Categoria Budget Budget Remaining Budget Budget restante Total Incomes Totale delle entrate Costs Costi Total Expenses Totale delle uscite Account/Category Noun, how much the account balance has changed Conto/categoria Empty expenses list. Svuota la lista delle uscite. Empty incomes list. Svuota la lista delle entrate. Empty transfers list. Svuota la lista dei trasferimenti. Empty securities list. Svuola la lista dei titoli Empty schedule list. Svuota la lista delle pianificazioni. Couldn't open file for writing. Impossibile aprire il file per la scrittura. Error while writing file; file was not saved. Errore nella scrittura del file; il file non è stato salvato. &File &File &Accounts &Conti &Transactions &Transazioni &Securities &Titoli Stat&istics Stat&istiche S&ettings I&mpostazioni &Help &Aiuto File File Transactions Transazioni Statistics Statistiche &New &Nuovo &Open… &Apri… Open Recent Apri recente Clear List Pulisci elenco &Save &Salva Save As… Salva come… &Revert &Ricarica &Print… &Stampa… Print Preview… Anteprima di stampa… Import Importa Import CSV File… Importa file CSV… Import QIF File… Importa file QIF… Export View… Esporta vista… Export As QIF File… Esporta file come QIF… Update Exchange Rates Currency Converter &Quit &Esci Add Account… Aggiungi conto… New Account… Nuovo conto… New Loan… New Income Category… Nuova categoria d'entrata… New Expense Category… Nuova categoria di uscita… Add Account Aggiungi conto Assets Attività Description Transaction description property (transaction title/generic article name) Descrizione Security Transactions Financial security (e.g. stock, bond) Transazioni di titoli &Loans &Prestiti Edit… Modifica… Balance… Bilanciamento… Show Transactions Mostra transazioni Show Ledger Mostra libro maestro New Expense… Nuova uscita… New Income… Nuova entrata… New Transfer… Nuovo trasferimento… New Split Transaction… Nuova transazione suddivisa… New Expense with Multiple Payments… Refund… Rimborso… Repayment… Rimborso… New Refund/Repayment… Nuova rimborso… Edit Transaction(s) (Occurrence)… Modifica transazione(i) (occorrenza)… Edit Occurrence… Modifica ricorrenza… Edit Schedule (Recurrence)… Modifica pianificazione (ricorrenza)… Edit Schedule… Modifca pianificazione… Edit Split Transaction… Modifica transazione suddivisa… Join Transactions… join transactions together Unisci transazioni… Split Up Transaction split up joined transactions Suddividi transazione Edit Timestamp… Modifica marca temporale… Select Associated File Open Associated File Remove Transaction(s) (Occurrence) Elimina transazione(i) (occorrenza) Remove Occurrence Elimina ricorrenza Delete Schedule (Recurrence) Elimina pianficazione (ricorrenza) Delete Schedule Elimina pianificazione Remove Split Transaction Elimina transazione suddivisa Edit Security… Modifica titolo… Remove Security Elimina titolo Shares Bought… Azioni Acquistate… Shares Sold… Azioni Vendute… Shares Moved… Azioni Spostate… Dividend… Dividendo… Reinvested Dividend… Dividendo reinvestito… Transactions… Transazioni… Edit Quotations… Modifica Quotazioni… Development Over Time Report… Rapporto di sviluppo temporale… Categories Comparison Report… Rapporto di comparazioni delle categorie… Development Over Time Chart… Diagramma su sviluppo temporale… Categories Comparison Chart… Diagramma di comparazione delle categorie… Use Additional Transaction Properties Utilizza le proprietà aggiuntive per le transazioni Set Main Currency… Set Budget Period… Initial Period Periodo iniziale Remember Last Dates Ricorda ultimi appuntamenti Backup Frequency Daily Giornalmente Weekly Settimanalmente Fortnightly Monthly Mensilmente Never Cloud Synchronization (experimental)… Dark Mode Tema scuro Help Report Bug About %1 About Qt Please restart the application for the language change to take effect. A personal accounting program Un programma di contabilità personale License: GNU General Public License Version 3 Crash Recovery Recupero dal crash Untitled Senza titolo Securities Financial security (e.g. stock, mutual fund) Titoli New Security… Financial security (e.g. stock, mutual fund) Nuovo titolo… Set Quotation… Financial quotation Fissa Quotazione… Shares Financial shares Azioni Quotation Financial quotation Quotazione New Security Financial security (e.g. stock, mutual fund) Nuovo titolo Edit Security Financial security (e.g. stock, mutual fund) Modifica titolo Delete security? Financial security (e.g. stock, mutual fund) Are you sure you want to delete the security "%1" and all associated transactions? Financial security (e.g. stock, mutual fund) Sei sicuro di voler eliminare il titolo "%1" e tutte le transazioni associate? Set Quotation (%1) Financial quotation Fissa quotazione (%1) Price per share: Financial shares Prezzo per azione: Security Transactions Financial security (e.g. stock, mutual fund) Transazioni di titoli Checking Account Transactional account Conto corrente Balance Account balance Saldo Empty securities list. Financial security (e.g. stock, mutual fund) Svuola la lista dei titoli. &Securities Financial security (e.g. stock, mutual fund) &Titoli Balance… Balance account Bilanciamento… Edit Security… Financial security (e.g. stock, mutual fund) Modifica titolo… Remove Security Financial security (e.g. stock, mutual fund) Elimina titolo Shares Bought… Financial shares Azioni acquistate… Shares Sold… Financial shares Azioni vendute… Edit Quotations… Financial quotation Modifica quotazioni… The current file has been modified. Do you want to save it? Il file corrente è stato modificato. Vuoi salvarlo? Confirm Schedule Conferma pianificazione New Account Nuovo conto New Income Category Nuova categoria d'entrata New Expense Category Nuova categoria di uscita Balance Account Bilanciamento del conto Book value: Valore contabile: of which %1 is balance adjustment Referring to account balance Real value: Valore reale: Edit Account Modifica conto Edit Income Category Modifica categoria di entrata Edit Expense Category Modifica categoria di uscite Remove subcategories? Do you wish to remove the category including all subcategories? Move transactions? Spostare le transizioni? Move to: Sposta a: Remove irreversibly from all accounts (do not do this if account has been closed!) The category contains some expenses. What do you want to do with them? La categoria contiene delle uscite. Cosa vuoi farne? The category contains some incomes. What do you want to do with them? La categoria contiene delle entrate. Cosa vuoi farne? The account contains some transactions. What do you want to do with them? La categoria contiene delle transazioni. Cosa vuoi farne? Remove Category? Rimuovere la categoria? The category contains some expenses that will be removed. Do you still want to remove the category? La categoria contiene delle uscite che verranno eliminate. Sei sicuro di voler eliminare la categoria? The category contains some incomes that will be removed. Do you still want to remove the category? La categoria contiene delle entrate che verranno eliminate. Sei sicuro di voler eliminare la categoria? Remove Account? Eliminare il Conto? The account contains some transactions that will be removed. Do you still want to remove the account? La categoria contiene delle transizioni che verranno eliminate. Sei sicuro di voler eliminare la categoria? %2 of %1 %1: budget; %2: remaining budget %2 di %1 Balance… Verb. Balance an account Bilanciamento… Shares Exchanged… Shares of one security directly exchanged for shares of another; Financial shares Azioni spostate… Edit Quotes… Financial quote Modifica quotazioni… Balance Account Verb Bilanciamento del conto %1 (with no budget) %1 (senza budget) %1 (with budget %2) %1 (con budget %2) EqonomizeCalendarWidget Today Oggi EqonomizeDateEdit Today Oggi EqonomizeTranslator OK Only used when Qt translation is missing Cancel Only used when Qt translation is missing Close Only used when Qt translation is missing &Yes Only used when Qt translation is missing &No Only used when Qt translation is missing &Open Only used when Qt translation is missing &Save Only used when Qt translation is missing &Select All Only used when Qt translation is missing Look in: Only used when Qt translation is missing File &name: Only used when Qt translation is missing Files of type: Only used when Qt translation is missing EqonomizeValueEdit Error Empty denominator. Empty factor. Division by zero. Unknown or ambiguous currency, or unrecognized characters, in expression: %1. Empty base. Empty exponent. Unrecognized characters in expression. ExportQIFDialog Export QIF File Esporta file QIF Account: Conto: All All accounts Tutti Export transaction description as: Esporta le descrizioni delle transizione come: Export transaction description as: Referring to generic description Esporta le descrizioni delle transizione come: Payee Debitore Memo Memo Subcategory Sottocategoria Date format: Formato della data: Value format: Formato del valore: File: File: Error Selected file is a directory. Il file selezionato è una cartella. Overwrite The selected file already exists. Would you like to overwrite the old copy? Il file selezionato già esiste. Vuoi sovrascriverlo? You selected a directory! Hai selezionato una cartella! Couldn't open file for writing. Impossibile aprire il file per la scrittura. Error while writing file; file was not saved. Errore nella scrittura del file; il file non è stato salvato. ImportCSVDialog Import CSV file Importa file CSV Transaction Type Selection Selezione tipo di transazione Expenses Uscite Incomes Entrate Transfers Trasferimenti Expenses and incomes (negative cost) Uscite ed entrate (costi negativi) Expenses and incomes (separate columns) Uscite ed entrate (colonne separate) All types Tutti i tipi Presets: File Selection Selezione file File: File: First data row: Prima colonna di dati: Auto Auto Column delimiter: Delimitatore delle Colonne: Comma Virgola Tabulator Tabulatore Semicolon Punto e virgola Space Spazio Other Altro Columns Specification Specifica delle colonne Save as preset… Imports data as expenses and incomes. Costs have negative value. Value is the only required column. Importa i dati come uscite ed entrate. I costi hanno un valore negativo. L'unica colonna richiesta è: valore. Imports data as expenses and incomes. Costs and incomes have separate columns. Income and cost both all required columns. Importa i dati come uscite ed entrate. I costi e le entrate hanno colonne separate. Sono richieste le colonne: entrata, costo. Warning The same column number is selected multiple times. Do you wish to proceed anyway? Description: Descrizione: Description: Transaction description property (transaction title/generic article name) Descrizione: Column Colonna Value Valore Cost: Costo: Date: Data: Category: Categoria: From account: Dal conto: Quantity: Quantità: Payee: Creditore: Tags: Etichette: Comments: Commenti: Create missing categories and accounts Creare le categorie e i conti mancanti Save Preset Imports data as expenses. Costs have positive value. Value is the only required column. Importa i dati come uscite. I costi hanno un valore positivo. L'unica colonna richiesta è: valore. Imports data as incomes. Value is the only required column. Importa i dati come entrate. L'unica colonna richiesta è: valore. Income: Entrata: To account: Al conto: Payer: Debitore: Imports data as transfers. Value is the only required column. Importa i dati come trasferimenti. L'unica colonna richiesta è: valore. Amount: Quantità: Imports data as expenses and incomes. Costs have negative value. Value and category are both required columns. Importa i dati come uscite ed entrate. I costi hanno un valore negativo. Sono richieste le colonne: valore, categoria. Value: Valore: Account: Conto: Payee/payer: Creditore/debitore: Imports data as expenses and incomes. Costs and incomes have separate columns. Income, cost, and category are all required columns. Importa i dati come uscite ed entrate. I costi e le entrate hanno colonne separate. Sono richieste le colonne: entrata, costo, categoria. Imports data as expenses, incomes, and transfers. Costs have negative or positive value. Value, to, and from are all required columns. Accounts and categories must be existing. Importa i dati come uscite, entrate e trasferimenti. I costi hanno dei valori negativi o positivi. Sono richieste le colonne: valore, a, da. Conti e categorie devono essere presenti. From: Da: To: A: Error A file must be selected. Deve essere selezionato un file. Selected file is a directory. Il file selezionato è una cartella. Selected file does not exist. Il file selezionato non esiste. Empty delimiter. Delimitatore vuoto. The same column number is selected multiple times. Lo stesso numero di colonna è selezionato più volte. Selected from account is the same as the to account. Il conto Da selezionato è lo stesso del conto A. Invalid date. Data non valida. Couldn't open %1 for reading. Impossibile aprire %1 in lettura. Error reading %1. Errore leggendo %1. Uncategorized Non categorizzato Successfully imported %n transaction(s). Importo di %n transazione riuscito. Importo di %n transazioni riuscito. Unable to import any transactions. Fallito l'importo delle transazioni. Failed to import %n data row(s). Fallito l'importo di %n linea di dati. Fallito l'importo di %n linee di dati. Required columns missing. Richieste delle colonne mancanti. Invalid value. Valore non valido. Empty category name. Nome categoria vuoto. Empty account name. Nome account vuoto. Unknown category found. Trovata categoria sconosciuta. Unknown account found. Trovato un conto non conosciuto. Cannot import security transactions (to/from security accounts). Impossibile importare le transazioni dei titoli (da/a conti di titoli). Balancing account wrongly used. Referring to the account used for adjustments of account balances. Il bilanciamento del conto è utilizzato incorrettamente. Balancing account wrongly used. Il bilanciamento del conto è utilizzato incorrettamente. Same to and from account/category. No data found. Nessuna dato trovato. Information Unrecognized date format. Il formato della data non è riconosciuto. Specify Format Specificare il formato The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. Il formato delle date e/o i numeri nel file CSV è ambiguo. Per favore seleziona il formato corretto. Date format: Formato della data: Value format: Formato del valore: ImportQIFDialog Import QIF file Importa file QIF File Selection Selezione file Select a QIF file to import. When you click next, the file be analysed and you might need to answer some questions about the format of the file. Seleziona un file QIF da importare. Quando cliccherai su prossimo, il file verrà analizzato e potresti avere il bisogno di rispondere ad alcune domande riguardo al formato del file. File: File: Local Definitions Definizioni locali Unknown elements where found in the QIF file. It is possible that this is because of localized type names. Please map them to the correct standard names. Local Text Testo locale Standard Text Testo standard Select standard text: Seleziona il testo standard: Date Format Formato della data The date format in the QIF file is ambiguous. Please select the correct format. Il formato della data nel file QIF è ambigua. Per favore seleziona il formato corretto. Date format: Formato della data: Default Account Conto predefinito Could not find any account definitions in the QIF file. Please select a default account. It is also possible that this is caused by a localized opening balance text. Default account: Conto predefinito: Opening balance text: Testo di apertura bilancio: Descriptions Descrizioni Subcategories as: Sottocategorizza come: Description Descrizione Category Categoria Ignore Ignora Payee as: Creditore come: Payee Debitore Memo as: Memorizza come: Comments Commenti Priority: Priorità: Subcategory/Payee/Comments Sottocategoria/Creditore/Commenti Payee/Subcategory/Comments Creditore/Sottocategoria/Commenti Subcategory/Comments/Payee Sottocategoria/Commenti/Creditore Payee/Comments/Subcategory Creditore/Commenti/Sottocategoria Comments/Subcategory/Payee Commenti/Sottocategoria/Creditore Comments/Payee/Subcategory Commenti/Creditore/Sottocategoria Import File No (further) issues were found. Press finish to import the selected QIF file. Ignore duplicate transactions Error A file must be selected. Deve essere selezionato un file. Selected file is a directory. Il file selezionato è una cartella. Selected file does not exist. Il file selezionato non esiste. Couldn't open %1 for reading. Impossibile aprire %1 in lettura. Error reading %1. Errore leggendo %1. Unknown Sconosciuto Account Conto Bank Banca Cash Contante Cat (Category) Cat (categoria) CCard (Credit Card) CCard (carta di credito) Invst (Investment) Invest (investimento) Oth A (Other Assets) Oth A (altre attività) Oth L (Other Liabilities) Oth L (altre passività) Security Titolo Other Altro Unrecognized date format. Il formato della data non è riconosciuto. Successfully imported %n transaction(s). Importo di %n transazione riuscito. Importo di %n transazioni riuscito. Successfully imported %n account(s). Importato correttamente %n conto. Importati correttamente %n conti. Successfully imported %n category/categories. Importata correttamente %n categoria. Importate correttamente %n categorie. %n duplicate transaction(s) was ignored. %n duplicato della transazione è stato ignorato. %n duplicati della transazione sono stati ignorati. Failed to import %n transaction(s). Fallito l'importo di %n transazione. Fallito l'importo di %n transazioni. %n security/securities were not imported. Financial security (e.g. stock, mutual fund) %n titolo non è stato importato. %n titoli non sono stati importati. %n security transaction(s) were not imported. Financial security (e.g. stock, mutual fund) %n transazione di titolo non è stata importata. %n transazioni di titolo non sono state importate. Information Income Dividend: %1 Dividendo: %1 Reinvested dividend: %1 Dividendo reinvestito: %1 LedgerDialog Account: Conto: Edit Account… Modifica conto… Export… Esporta… Print… Stampa… Reconcile Accounting context Mark all as reconciled Accounting context Change: Accounting context Cambio: R Header for account reconciled checkbox column Date Data Type Tipo Description Descrizione Name Nome Description Generic Description Descrizione Account/Category Conto/categoria Deposit Deposito Withdrawal Prelievo Balance Bilanciamento Balance Account balance Saldo Payee/Payer Creditore/debitore Tags Etichette Comments Commenti Deposit Money put into account Deposito Withdrawal Money taken out from account Prelievo Balance Noun. Balance of an account Saldo New Nuovo Edit… Modifica… Delete Elimina Join… join transactions together Unisci… Split Up split up joined transactions Dividi Edit Transaction(s)… Modifica transazione(i)… Join Transactions… Unisci transazioni… Split Up Transaction Suddividi transazione Remove Transaction(s) Elimina transazione(i) Mark as reconciled Reconciled: %1 (%2) Accounting context Book value: %1 (%2) Accounting context Valore contabile: %1 (%2) Error Invalid date. Data non valida. Opening date is after closing date. Closing date is before opening date. Empty transaction list. Svuota la lista delle transazioni. Couldn't open file for writing. Impossibile aprire il file per la scrittura. Error while writing file; file was not saved. Errore nella scrittura del file; il file non è stato salvato. Ledger Libro Maestro Transactions for %1 Transazione per %1 Select Time Period From: Da: To: A: To date is before from date. La data A è precedente alla data Da. Balance change: Account balance Delete transactions? Are you sure you want to delete all (%1) selected transactions? Sei sicuro di volere eliminare tutte le (%1) transazioni? Cannot set the value of security transactions using the dialog for modifying multiple transactions. Financial security (e.g. stock, mutual fund) Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name); Financial security (e.g. stock, mutual fund) Impossibile cambiare la descrizione dei dividendi e delle transazioni dei titoli. Cannot change payer of dividends and security transactions. Financial security (e.g. stock, mutual fund) Impossibile cambiare il debitore dei dividenti e delle transazioni dei titoli. Opening balance Account balance Bilancio di apertura Account Balance Adjustment Regolazione del saldo del conto Current balance: Account balance Average balance: Account balance Account Balancing Balancing of an account Bilanciamento del conto Balancing Balancing of an account Bilanciamento Balancing Account balancing Bilanciamento Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name) Impossibile cambiare la descrizione dei dividendi e delle transazioni dei titoli. Cannot change description of dividends and security transactions. Referring to the generic description property Impossibile cambiare la descrizione dei dividendi e delle transazioni dei titoli. Current debt: Total debt reduction: Total interest and fees: Number of transactions: Cannot change description of dividends and security transactions. Impossibile cambiare la descrizione dei dividendi e delle transazioni dei titoli. Cannot change payer of dividends and security transactions. Impossibile cambiare il debitore dei dividenti e delle transazioni dei titoli. Cannot change date of transactions that are part of a split transaction. Impossibile cambiare la data delle transizione che fanno parte di una transizione suddivisa. Initial balance Bilancio iniziale Split Transaction Dividi la transazione Debt Payment Ascending order Reduction Fee Interest Income Entrata Repayment Rimborso Expense Uscita Opening balance: Accounting context Bilancio di apertura: Closing balance: Accounting context Description Transaction description property (transaction title/generic article name) Descrizione Cannot change description of dividends and security transactions. Referring to the Transaction description property (transaction title/generic article name) Impossibile cambiare la descrizione dei dividendi e delle transazioni dei titoli. Refund Rimborso Balancing Bilanciamento Transfer Trasferimento LinksWidget Remove Link Rimuovi collegamento All Tutti Remove Rimuovi MultiItemListViewItem Dividend Dividendo Income Entrata Repayment Rimborso Expense Uscita Refund Rimborso Securities Purchase Financial security (e.g. stock, mutual fund) Acquisto di titoli Securities Sale Financial security (e.g. stock, mutual fund) Vendita di titoli Account Balance Adjustment Regolazione del saldo del conto Account Balancing Balancing of an account Bilanciamento del conto Balancing Balancing of an account Bilanciamento Security Buy Acquisto di titoli Security Sell Vendita di titoli Balancing Bilanciamento Transfer Trasferimento MultipleTransactionsEditDialog Modify Transactions Modifica transazioni Description: Descrizione: Name: Nome: Description: Transaction description property (transaction title/generic article name) Descrizione: Amount: Quantità: Income: Entrata: Cost: Costo: Date: Data: Category: Categoria: Payer: Debitore: Payee: Creditore: New Income Category Nuova categoria d'entrata New Expense Category Nuova categoria di uscita New Income Category… Nuova Categoria d'Entrata… New Expense Category… Nuova Categoria di Uscita… Error No income category available. Nessuna categoria di entrata è disponibile. No expense category available. Nessuna categoria di uscita è disponibile. Invalid date. Data non valida. OverTimeChart Save As… Salva come… Print… Stampa… Source: Fonte: Incomes and Expenses Entrate ed uscite Profits Profitti Expenses Uscite Incomes Entrate All Categories Combined Tutte le categorie combinate All Descriptions Combined Tutte le descrizioni combinate Theme: Chart type: Line Chart Vertical Bar Chart Horizontal Bar Chart Stacked Bar Chart Default Predefinito Tags Etichette All Accounts Combined Tutti i conti combinate All Accounts Split Tutti i conti suddivisi All Subcategories and Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Tutte le sottocategorie e le descrizioni combinate All Descriptions Split Referring to the transaction description property (transaction title/generic article name) Tutte le descrizioni suddivise No description Referring to the transaction description property (transaction title/generic article name) Nessuna descrizione All Payees/Payers Split Tutti i creditori/debitori suddivisi No payee/payer Nessun creditore/debitore All Tags Split Tutte le etichette subdivise Other tags Altre etichette Other payees/payers Altre creditori/debitori Other descriptions Referring to the transaction description property (transaction title/generic article name) Altre descrizioni Profits, %1 Profitti, %1 Assets Attività All Descriptions Combined Referring to the generic description property Tutte le descrizioni combinate Assets and Liabilities Attività e passività All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Tutte le descrizioni combinate All Payees/Payers Combined Tutti i debitori/creditori combinati All Accounts Tutti i conti Start date: Data di inizio: End date: Data di conclusione: Value: Valore: Annual total Totale annuale Monthly total Totale mensile Daily average Media giornaliera Quantity Quantità Average value Valore medio All Payers Combined Tutti i debitori combinati All Payees Combined Tutti i creditori combinati All Subcategories Split Tutte le sottocategorie suddivise All Descriptions Split Referring to the generic description property Tutte le descrizioni suddivise No description Referring to the generic description property Nessuna descrizione Value Valore Includes budgeted transactions Incluse le transazioni preventivate Incomes − Expenses, %1 Entrate − uscite, %1 Incomes − Expenses Entrate − uscite Incomes & Expenses Entrate ed uscite Incomes: %1 Entrate: %1 Expenses: %1 Uscite: %1 %2: %1 %2: %1 Incomes: %2, %1 Entrate: %2, %1 Expenses: %2, %1 Uscite: %2, %1 %3: %2, %1 %3: %2, %1 %2, %1 %2, %1 Incomes: %3, %2, %1 Entrate: %3, %2, %1 Expenses: %3, %2, %1 Uscite: %3, %2, %1 %4: %3, %2, %1 %4: %3, %2, %1 no payee/payer nessun creditore/debitore %3, %2, %1 %3, %2, %1 Other accounts Altri conti %1 Value: %2 Date: %3 %1 Valore: %2 Data: %3 MMMM yyyy Month and year All Descriptions Split Tutte le descrizioni suddivise All Payers Split Tutti i debitori suddivisi All Payees Split Tutti i creditori suddivisi No description Nessuna descrizione No payer Nessun debitore No payee Nessun creditore All Categories Split Tutte le categorie suddivise Error Invalid date. Data non valida. Couldn't open file for writing. Impossibile aprire il file per la scrittura. Error while writing file; file was not saved. Errore nella scrittura del file; il file non è stato salvato. Other payees Altre creditori Other payers Altre debitori Value (%1) Valore (%1) Profit (%1) Profitto (%1) Income (%1) Entrata (%1) Cost (%1) Costo (%1) Time Tempo %1/%2 %1: Category; %2: Payee/Payer %1/%2 All Descriptions Combined Referring to the Transaction description property (transaction title/generic article name) Tutte le descrizioni combinate All Descriptions Split Referring to the Transaction description property (transaction title/generic article name) Tutte le descrizioni suddivise No description Referring to the Transaction description property (transaction title/generic article name) Nessuna descrizione Daily average value Valore medio giornaliero Daily average profit Profitto medio giornaliero Daily average income Media delle entrate giornaliere Daily average cost Media dei costi giornalieri Average income Media delle entrate Average cost Media dei costi Annual value Valore annuale Annual profit Profitto annuale Annual income Entrate annuale Annual cost Costo annuale Monthly value Valore mensile Monthly profit Profitto mensile Monthly income Entrate mensile Monthly cost Costo mensile Includes scheduled and budgeted transactions Includi le transizioni pianificate e preventivate Includes scheduled transactions Includi le transizioni pianificate Tags, %1 Etichette, %1 Value: %1 Valore: %1 Assets & Liabilities Attività e passività Change: %1 Cambio: %1 Excluding any profits or losses in trading of security shares Financial security (e.g. stock, mutual fund) Incomes & Expenses, %1 Entrate ed uscite, %1 Incomes, %1 Entrate, %1 Expenses, %1 Uscite, %1 Incomes, %2: %1 Entrate, %2: %1 Expenses, %2: %1 Uscite, %2: %1 Incomes, %3: %2, %1 Entrate, %3: %2, %1 Expenses, %3: %2, %1 Uscite, %3: %2, %1 Incomes, %4: %3, %2, %1 Entrate, %4: %3, %2, %1 Expenses, %4: %3, %2, %1 Uscite, %4: %3, %2, %1 Liabilities Passività no payer nessun debitore %1/%2 %1: Description; %2: Payer/Payer %1/%2 %1/%2 %1: Description; %2: Payee/Payer %1/%2 %1/%2 %1: Description; %2: Payer %1/%2 no payee nessun creditore %1/%2 %1: Description; %2: Payee %1/%2 OverTimeChartDialog Chart Diagramma OverTimeReport Save As… Salva come… Print… Stampa… Source: Fonte: Profits Profitti Expenses Uscite Incomes Entrate Assets & Liabilities Attività e passività Tags Etichette All Categories Combined Tutte le categorie combinate All Descriptions Combined Tutte le descrizioni combinate Columns: Colonne: Categories Categorie Total: Totale: Value Valore Daily Giornalmente Monthly Mensilmente Yearly Annualmente Quantity Quantità Average value Valore medio No description Nessuna descrizione All Descriptions Combined Referring to the generic description property Tutte le descrizioni combinate No description Referring to the generic description property Nessuna descrizione All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Tutte le descrizioni combinate All Accounts Tutti i conti No description Referring to the transaction description property (transaction title/generic article name) Nessuna descrizione Error Couldn't open file for writing. Impossibile aprire il file per la scrittura. Error while writing file; file was not saved. Errore nella scrittura del file; il file non è stato salvato. Average Profit Profitto medio Incomes, %1 Entrate, %1 Average Income Media delle entrate Expenses, %1 Uscite, %1 Average Cost Media dei costi Incomes, %2: %1 Entrate, %2: %1 Incomes: %1 Entrate: %1 Expenses, %2: %1 Uscite, %2: %1 Expenses: %1 Uscite: %1 Incomes, %3: %2, %1 Entrate, %3: %2, %1 Incomes: %2, %1 Entrate: %2, %1 Expenses, %3: %2, %1 Uscite, %3: %2, %1 Expenses: %2, %1 Uscite: %2, %1 Change: %1 Noun, how much the account balance has changed Cambio: %1 Deposit Money put into account Deposito Withdrawal Money taken out from account Prelievo Change Noun, how much the account balance has changed Cambio Value: %1 Valore: %1 %2: %1 %2: %1 %1 %1 Average Value Valore medio %3: %2, %1 %3: %2, %1 %2, %1 %2, %1 Year Anno Month Mese Assets Attività Deposit Deposito Withdrawal Prelievo Liabilities Passività Daily Average Media giornaliera Monthly Average Media mensile Yearly Average Media annuale Subtotal Subtotale Total Totale Includes scheduled transactions Includi le transizioni pianificate Adjusted for the average month / year (%1 / %2 days) Adattati per la media mese / anno (%1 / %2 giorni) All Categories Combined Referring to the generic description property Tutte le categorie combinate OverTimeReportDialog Report Rapporto QApplication Start with expenses list displayed Avvia mostrando la lista delle uscite Start with incomes list displayed Avvia mostrando la lista delle entrate Start with transfers list displayed Avvia mostrando la lista dei trasferimenti Synchronize file Document to open Documento da aprire %1 is already running. QObject Transfer Trasferimento Dividend Dividendo Income Entrata Expense Uscita Securities Purchase Financial security (e.g. stock, mutual fund) Acquisto di titoli Securities Sale Financial security (e.g. stock, mutual fund) Vendita di titoli Security Buy Acquisto di titoli Security Sell Vendita di titoli Debt Payment Split Transaction Dividi la Transazione RecurrenceEditWidget Enable recurrence Abilita ricorrenza Recurrence Rule Regola di ricorrenza Daily Giornalmente Weekly Settimanalmente Monthly Mensilmente Yearly Annualmente Recur every Occorri ogni day(s) giorno/i week(s) on: settimana/e di: month(s), after the start month mese/i, dopo il mese di avvio Recur on the Occorri il 1st 2nd 3rd 4th 4 5th 5 6th 6 7th 7 8th 8 9th 9 10th 10 11th 11 12th 12 13th 13 14th 14 15th 15 16th 16 17th 17 18th 18 19th 19 20th 20 21st 21 22nd 22 23rd 23 24th 24 25th 25 26th 26 27th 27 28th 28 29th 29 30th 30 31st 31 Last Ultimo 2nd Last penultimo 3rd Last terzultimo 4th Last quartultimo 5th Last quintultimo day giorno possibly on weekend possibilmente in settimana but before weekend ma prima del fine settimana but after weekend ma dopo il fine settimana nearest weekend day year(s), after the start year anno/i, dopo l'anno di inizio on nearest weekday Recur on day part before XXX of 'Recur on day XXX of month YYY' Ricorri il giorno of part between XXX and YYY of 'Recur on day XXX of month YYY' di On the Part before NNN in 'Recur on the NNN. WEEKDAY of MONTH' su of part between WEEKDAY and MONTH in 'Recur on NNN. WEEKDAY of MONTH' di Recur on day # Ricorri il giorno # of the year part after NNN of 'Recur on day #NNN of the year' dell'anno Range… Intervallo… Occurrences/Exceptions… Ricorrenze/eccezioni… Exceptions… Eccezioni… Error No day of week selected for weekly recurrence. Nessun giorno della settimana è stato selezionato per la ricorrenza settimanale. Selected day will never occur with selected frequency and start date. Selected day does not exist in selected month. Il giorno selezionato non esiste nel mese selezionato. RefundDialog Repayment Rimborso Refund Rimborso Date: Data: Cost: Costo: Income: Entrata: Quantity returned: Quantità restituita: Account: Conto: Quantity: Quantità: Payee: Creditore: Payer: Debitore: Comments: Commenti: Link Link the transactions together Collegare Join Join the transactions together Unisci Error Zero value not allowed. Il valore zero non è permesso. Invalid date. Data non valida. SecurityBuy Security: %1 (bought) Titolo: %1 (comprato) Security: %1 (bought) Financial security (e.g. stock, mutual fund) Titolo: %1 (comprato) SecuritySell Security: %1 (sold) Titolo: %1 (venduto) Security: %1 (sold) Financial security (e.g. stock, mutual fund) Titolo: %1 (venduto) SecurityTransactionsDialog Transactions for %1 Transazione per %1 Date Data Type Tipo Value Valore Shares Financial shares Azioni Shares Bought Financial shares Azioni comprate Shares Bought (Recurring) Financial shares Azioni comprate (con ricorrenza) Dividend (Recurring) Dividendo (con ricorrenza) Dividend (Scheduled) Dividendo (pianificate) Reinvested Dividend (Recurring) Dividendo Reinvestito (con ricorrenza) Reinvested Dividend (Scheduled) Dividendo Reinvestito (pianificate) Shares Bought Fincancial shares Azioni comprate Shares Sold Financial shares Azioni vendute Shares Sold (Exchanged) Shares of one security directly exchanged for shares of another; Financial shares Azioni vendute (commerciate) Shares Bought (Exchanged) Shares of one security directly exchanged for shares of another; Financial shares Azioni comprate (commerciate) Shares Bought (Recurring) Fincancial shares Azioni comprate (con ricorrenza) Shares Sold (Recurring) Financial shares Azioni vendute (con ricorrenza) Shares Bought (Scheduled) Financial shares Azioni comprate (pianificate) Shares Sold (Scheduled) Financial shares Azioni vendute (pianificate) Shares Azioni Edit… Modifica… Delete Elimina Shares Bought Azioni comprate Shares Sold Azioni vendute Dividend Dividendo Reinvested Dividend Dividendo reinvestito Shares Sold (Traded) Azioni vendute (commerciate) Shares Bought (Traded) Azioni comprate (commerciate) Shares Bought (Recurring) Azioni comprate (con ricorrenza) Shares Sold (Recurring) Azioni vendute (con ricorrenza) Shares Bought (Scheduled) Azioni comprate (pianificate) Shares Sold (Scheduled) Azioni vendute (pianificate) Recurring Dividend Dividendo ricorrente Scheduled Dividend Dividendo pianificato SplitListViewItem Dividend Dividendo Income Entrata Repayment Rimborso Expense Uscita Refund Rimborso Security Buy Acquisto di titoli Security Sell Vendita di titoli Balancing Bilanciamento Transfer Trasferimento TagButton no tags niente etichette TagMenu New tag… Nuova etichetta… New Tag Nuova etichetta Tag: Etichetta: TransactionEditDialog Edit Expense Modifica Uscita Edit Dividend Modifica Dividendo Edit Income Modifica Entrata Edit Transfer Modifica Trasferimento Edit Securities Purchase Financial security (e.g. stock, mutual fund) Modifica i titoli acquistati Edit Securities Sale Financial security (e.g. stock, mutual fund) Modifica i titoli venduti Edit Reinvested Dividend Edit Securities Bought Modifica i titoli acquistati Edit Securities Sold Modifica i titoli venduti TransactionEditWidget Security: Titoli: Cost: Costo: Income: Entrata: Shares bought: Azioni acquistate: Shares sold: Azioni vendute: All Tutti Price per share: Prezzo per azione: Date: Data: Description: Descrizione: Name: Nome: Amount: Quantità: Downpayment: Quantity: Quantità: From: Da: To: A: Category: Categoria: To account: Al conto: Payer: Debitore: From account: Dal conto: Downpayment account: Payee: Creditore: Lender: Comments: Commenti: No security available. Financial security (e.g. stock, mutual fund) New Account Nuovo Conto New Income Category Nuova categoria d'entrata New Expense Category Nuova categoria di uscita New Account… Nuovo Conto… New Income Category… Nuova Categoria d'Entrata… New Expense Category… Nuova Categoria di Uscita… Security: Financial security (e.g. stock, mutual fund) Titoli: New Security… Financial security (e.g. stock, mutual fund) Nuovo titolo… Shares added: Financial shares Azioni aggiunte: Shares bought: Financial shares Azioni acquistate: Shares sold: Financial shares Azioni vendute: Price per share: Financial shares Prezzo per azione: Set security share value Total value: Valore totale: Description: Transaction description property (transaction title/generic article name) Descrizione: Transaction title/generic article name Withdrawal: Money taken out from account Prelievo: Deposit: Money put into account Deposito: Number of items included in the transaction. Entered cost is total cost for all items. Payer of parent split transaction Payee of parent split transaction Tags: Etichette: Associated file: File associato: Select a file Open the file Related to: Label for linked transactions Collegamenti: New Security Financial security (e.g. stock, mutual fund) Nuovo titolo Error No suitable account available. Nessun conto adeguato è disponibile. No income category available. Nessuna categoria di entrata è disponibile. No suitable account or income category available. No expense category available. Nessuna categoria di uscita è disponibile. Invalid date. Data non valida. Cannot transfer money to and from the same account. Impossibile trasferire denaro a e dallo stesso conto. Downpayment must be less than total cost. Cannot create a regular transfer to/from a securities account. Impossibile creare un regolare trasferimento a/da un conto di titoli. Cannot create a regular income to a securities account. Impossibile creare una regolare entrata da un conto di titoli. Zero shares not allowed. Zero azioni non è permesso. Zero value not allowed. Il valore zero non è permesso. Zero price per share not allowed. Zero per cento delle azioni non è permesso. Cannot create a regular expense from a securities account. Impossibile creare una regolare uscita da un conto di titoli. Loan for %1 New Tag Nuova etichetta Tag: Etichetta: TransactionFilterWidget From: Da: To: A: Min amount: Min quantità: Max amount: Max quantità: Category: Categoria: To account: Al conto: Min income: Min entrata: Max income: Max entrata: From account: Dal conto: Min cost: Min costo: Max cost: Max costo: Tag: Etichetta: Description: Descrizione: Description: Transaction description property (transaction title/generic article name) Descrizione: Payer: Debitore: Payee: Creditore: Include Includi Exclude Escludi Exact match Corrispondenza esatta Exclude subcategories Escludere sottocategorie Clear Pulisci All Tutti Error Invalid date. Data non valida. To date is before from date. La data A è precedente alla data Da. From date is after to date. La data Da è posteriore alla data A. TransactionListWidget Date Data Description Descrizione Cost Costo Category Categoria From Account Dal conto Payee Creditore Tags Etichette Income Entrata To Account Al conto Payer Debitore Amount Quantità From Da To A Comments Commenti Add Aggiungi Apply Applica Delete Elimina * Part of <a href="%1">split transaction</a> * Parte di una <a href="%1">transazione suddivisa</a> Expense Uscita Transfer Trasferimento Name Nome Description Generic Description Descrizione Description Transaction description property (transaction title/generic article name) Descrizione New/Edit Expense Nuova/modifica uscita New/Edit Income Nuova/modifica entrata New/Edit Transfer Nuova/modifica trasferimento Filter Filtro Quantity: Quantità: Total: Totale: Average: Media: Clear Pulisci Cost: Costo: Monthly: Mensilmente: Sort by creation time Expenses Uscite Incomes Entrate Transfers Trasferimenti Quantity Quantità Right align Allinea a destra Total cost: Totale dei costi: Total income: Totale delle entrate: Total amount: Tatale delle quantità: Monthly average: Media mensile: Error Cannot set the value of security transactions using the dialog for modifying multiple transactions. Financial security (e.g. stock, mutual fund) Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name); Financial security (e.g. stock, mutual fund) Impossibile cambiare la descrizione dei dividendi e delle transazioni dei titoli. Cannot change payer of dividends and security transactions. Financial security (e.g. stock, mutual fund) Impossibile cambiare il debitore dei dividenti e delle transazioni dei titoli. Cannot change date of transactions that are part of a split transaction, unless all individual transactions are selected. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name) Impossibile cambiare la descrizione dei dividendi e delle transazioni dei titoli. Cannot change date, description, expense category or payee of transactions that are part of a debt payment using the dialog for modifying multiple transactions. Referring to the transaction description property (transaction title/generic article name) Cannot change description of dividends and security transactions. Referring to the Transaction description property (transaction title/generic article name) Impossibile cambiare la descrizione dei dividendi e delle transazioni dei titoli. Cannot change description of dividends and security transactions. Referring to the generic description property Impossibile cambiare la descrizione dei dividendi e delle transazioni dei titoli. Cannot change description of dividends and security transactions. Impossibile cambiare la descrizione dei dividendi e delle transazioni dei titoli. Cannot change payer of dividends and security transactions. Impossibile cambiare il debitore dei dividenti e delle transazioni dei titoli. Cannot change date of transactions that are part of a split transaction. Impossibile cambiare la data delle transizione che fanno parte di una transizione suddivisa. Delete transactions? Are you sure you want to delete all (%1) transactions in the selected split transaction? Join as multiple accounts/payments? Do you wish join the selected expenses as an expense with multiple accounts/payments? Do you wish join the selected incomes as an income with multiple accounts/payments? Are you sure you want to delete all (%1) selected transactions? Sei sicuro di volere eliminare tutte le (%1) transazioni? * Part of split transaction * Parte di una transazione suddivisa * Part of split (%1) * Parte di una suddivisione (%1) ** Recurring (editing occurrence) Modify… Modifica… Edit… Modifica… Eqonomize-1.5.3/translations/eqonomize_nl.ts000066400000000000000000021056311416454732000212740ustar00rootroot00000000000000 Balancing Balans kde-format Couldn't open %1 for reading Kan %1 niet openen om te lezen kde-format Not a valid Eqonomize! file (XML parse error: "%2" at line %3, col %4) Ongeldig Eqonomize! bestand (XML parserfout: "%2" in regel %3, kolom %4) kde-format Invalid root element %1 in XML document Ongeldig bronelement %1 in XML document kde-format Unable to load 1 account. Kan 1 rekening niet inlezen. Kan %n rekeningen niet inlezen. kde-format Unable to load %n accounts. Unable to load 1 category. Kan 1 categorie niet inlezen. Kan %n categorieën niet inlezen. kde-format Unable to load %n categories. Unable to load 1 security. Kan 1 effect niet inlezen. Kan %n effecten niet inlezen. kde-format Unable to load %n securities. Unable to load 1 transaction. Kan 1 transactie niet inlezen. Kan %n transacties niet inlezen. kde-format Unable to load %n transactions. File is a directory Bestand is een directory kde-format Couldn't open file for writing Kan bestand niet openen om te schrijven kde-format Error while writing file; file was not saved Fout tijdens het schrijven van het bestand; bestand is niet opgeslagen kde-format From Vanaf kde-format To Tot kde-format Source: Bron: kde-format All Expenses Alle uitgaven kde-format All Incomes Alle inkomsten kde-format All Accounts Alle rekeningen kde-format Expenses: %1 Uitgaven: %1 kde-format Incomes: %1 Inkomsten: %1 kde-format Invalid date. Ongeldige datum kde-format To date is before from date. Tot-datum ligt voor Vanaf-datum. kde-format From date is after to date. Vanaf-datum ligt na Tot-datum. kde-format The selected file already exists. Would you like to overwrite the old copy? Het geselecteerde bestand bestaat al. Wil u de oude versie overschrijven? kde-format You selected a directory! U heeft een map geselecteerd! kde-format Couldn't open file for writing. Kan bestand niet openen voor schrijven. kde-format Error while writing file; file was not saved. Fout tijdens het schrijven van het bestand; bestand is niet opgeslagen. kde-format No description Geen omschrijving kde-format All Categories Alle categorieën kde-format Descriptions for Omschrijving voor kde-format Payees/payers for Crediteuren/debiteuren voor kde-format Period: Periode: kde-format Columns: Kolommen: kde-format Value Waarde kde-format Daily Dagelijks kde-format Monthly Maandelijks kde-format Yearly Jaarlijks kde-format Quantity Hoeveelheid kde-format Average value Gemiddelde waarde kde-format All descriptions Alle omschrijvingen kde-format All payees Alle crediteuren kde-format All payers Alle debiteuren kde-format No payee Geen crediteur kde-format No payer Geen debiteur kde-format Expenses: %2, %1 Uitgaven: %2, %1 kde-format Incomes: %2, %1 Inkomsten: %2, %1 kde-format Incomes & Expenses Inkomsten & uitgaven kde-format %1 (%2&ndash;%3) html format; %1: title; %2: from date; %3: to date %1 (%2&ndash;%3) kde-format %1 (to %2) html format; %1: title; %2: to date %1 (tot %2) kde-format Category Categorie kde-format Cost Kosten kde-format Income Inkomsten kde-format Daily Average Dagelijks gemiddelde kde-format Monthly Average Maandelijks gemiddelde kde-format Yearly Average Jaarlijks gemiddelde kde-format Average Cost Gemiddelde kosten kde-format Average Income Gemiddelde inkomsten kde-format Average Value Gemiddelde waarde kde-format Total Totaal kde-format Total incomes Totaal inkomsten kde-format Total expenses Totaal uitgaven kde-format Total (Profits) Totaal (winst) kde-format Expense Uitgaven kde-format Transfer Overboeking kde-format Security Buy Effecten aankopen kde-format Security Sell Effecten verkopen kde-format Recurrence Herhaling kde-format New Expense Nieuwe kosten kde-format New Dividend Nieuw dividend kde-format New Income Nieuwe inkomsten kde-format New Transfer Nieuwe overboeking kde-format New Security Buy Nieuwe effectenaankoop kde-format New Security Sell Nieuwe effectenverkoop kde-format Edit Expense Kosten bewerken kde-format Edit Dividend Dividend bewerken kde-format Edit Income Inkomsten bewerken kde-format Edit Transfer Overboeking bewerken kde-format Edit Securities Bought Gekochte effecten bewerken kde-format Edit Securities Sold Verkochte effecten bewerken kde-format Dividend Dividend kde-format Repayment Aflossing kde-format Refund Terugstorten kde-format Split Transaction Gesplitste transactie kde-format Description: Omschrijving: kde-format Date: Datum: kde-format Account: Rekening: kde-format Transactions: Transacties: kde-format Type Type kde-format Description Omschrijving kde-format Account/Category Rekening/Categorie kde-format Payment Betaling kde-format Deposit Storting kde-format New Nieuw kde-format New Expense… Nieuwe kosten… kde-format New Income… Nieuwe inkomsten… kde-format New Deposit… Nieuwe storting… kde-format New Withdrawal… Nieuwe opname… kde-format New Security Shares Bought… Nieuw gekochte aandelen… kde-format Security Shares Sold… Aandelen verkocht… kde-format New Dividend… Nieuw dividend… kde-format Edit… Bewerk… kde-format Total value: Totale waarde: kde-format No suitable account available. Geen geschikte rekening beschikbaar. kde-format Future dates is not allowed. Datums in de toekomst zijn niet toegestaan. kde-format A split must contain at least two transactions. Een splitsing moet minstens twee transacties bevatten. kde-format Cannot transfer money to and from the same account. Kan geen geld overmaken naar en van dezelde rekening. kde-format Cost: Kosten: kde-format Income: Inkomsten: kde-format Quantity: Hoeveelheid: kde-format Comments: Opmerkingen: kde-format Reinvested Dividend Geherinvesteerd dividend kde-format Security: Effecten: kde-format Shares added: Aandelen toegevoegd: kde-format Security Trade Effectenhandel kde-format From security: Van effecten: kde-format Shares moved: Effecten verplaatst: kde-format All Alle kde-format To security: Naar effecten: kde-format Shares received: Effecten ontvangen: kde-format Value: Waarde: kde-format No other security available for trade in the account. Geen andere effecten beschikbaar om te verhandelen op deze rekening. kde-format Selected to and from securities are the same. Gekozen effecten Van en Naar zijn hetzelfde. kde-format Zero shares not allowed. Nul effecten niet toegestaan. kde-format Zero value not allowed. Geen waarde niet toegestaan. kde-format Quotations Noteringen kde-format Date Datum kde-format Price per Share Prijs per aandeel kde-format Quotations for %1 Noteringen voor %1 kde-format The following transactions was scheduled to occur today or before today. Confirm that they have indeed occurred (or will occur today). De volgende transacties waren gepland om vandaag of eerder plaats te vinden. Bevestig dat ze plaats hebben gevonden (of vandaag nog plaats zullen vinden). kde-format Amount Bedrag kde-format Postpone… Uitstellen… kde-format Can only postpone to future dates. Kan alleen uitstellen naar een datum in de toekomst. kde-format Transactions for %1 Transacties voor %1 kde-format Shares Aandelen kde-format Shares Bought Aandelen Gekocht kde-format Shares Sold Aandelen Verkocht kde-format Shares Sold (Traded) Aandelen Verkocht (Handel) kde-format Shares Bought (Traded) Aandelen Gekocht (Handel) kde-format Shares Bought (Recurring) Aandelen Gekocht (Herhalend) kde-format Shares Sold (Recurring) Aandelen Verkocht (Herhalend) kde-format Shares Bought (Scheduled) Aandelen Gekocht (Gepland) kde-format Shares Sold (Scheduled) Aandelen Verkocht (Gepland) kde-format Recurring Dividend Herhalend Dividend kde-format Scheduled Dividend Gepland Dividend kde-format Type: Soort: kde-format Mutual Fund Beleggingsfonds kde-format Bond Obligatie kde-format Stock Aandelen kde-format Other Overig kde-format Name: Naam: kde-format Decimals in Shares: Decimalen in Aandelen: kde-format Initial Shares: Aanvankelijke Aandelen: kde-format Initial quotation: Aanvankelijke Notering: kde-format No suitable account or income category available. Geen geschikte rekening of inkomsten categorie beschikbaar. kde-format Cash Contant Geld kde-format Current Account Lopende rekening kde-format Savings Account Spaarrekening kde-format Credit Card Creditcard kde-format Liabilities Passiva kde-format Securities Effecten kde-format Initial balance: Openingsbalans: kde-format Default account for budgeted transactions Standaard rekening voor gebudgetteerde transacties kde-format Empty name. Lege naam. kde-format The entered name is used by another account. De ingevoerde naam is al gebruikt voor een andere rekening. kde-format Monthly budget: Maandelijks budget: kde-format The entered name is used by another income category. De ingevoerde naam is gebruikt voor een andere inkomsten categorie. kde-format The entered name is used by another expense category. De ingevoerde naam is gebruikt voor een andere kosten categorie. kde-format Accounts Rekeningen kde-format Accounts & Categories Rekeningen & Categorieën kde-format Expenses Uitgaven kde-format Incomes Inkomsten kde-format Transfers Overboekingen kde-format Schedule Planning kde-format Scheduled Transactions Geplande Transacties kde-format Account / Category Rekening / Categorie kde-format Remaining Budget (%1) Resterend Budget (%1) kde-format Change (%1) Mutatie (%1) kde-format Total (%1) Totaal (%1) kde-format %2 of %1 %2 remains of %1 budget %2 van %1 kde-format Includes budgeted transactions Inclusief gebudgetteerde transacties kde-format Period Periode kde-format Select Period Selecteer Periode kde-format Current Month Huidige Maand kde-format Current Year Huidig Jaar kde-format Current Whole Month Huidige Hele Maand kde-format Current Whole Year Huidig Heel Jaar kde-format Whole Past Month Hele Afgelopen Maand kde-format Whole Past Year Heel Vorig Jaar kde-format Previous Month Vorige Maand kde-format Previous Year Vorig Jaar kde-format Show partial budget Toon gedeeltelijk budget kde-format Edit Budget Bewerk Budget kde-format Budget: Budget: kde-format Month: Maand: kde-format Result previous month: Resultaat vorige maand: kde-format New Security… Nieuw Effecten… kde-format New Transaction Nieuwe Transactie kde-format Set Quotation… Voer notering in… kde-format Name Naam kde-format Quotation Notering kde-format Profit Winst kde-format Yearly Rate Jaarlijkse Ontwikkeling kde-format Account Rekening kde-format Statistics Period Statistieken Periode kde-format New Schedule Nieuwe Planning kde-format Edit Bewerk kde-format Next Occurrence Volgende gebeurtenis kde-format Comments Beschrijving kde-format New Security Nieuw Waardepapier kde-format Edit Security Bewerk Waardepapier kde-format Profit: Winst: kde-format Rate: Rentabiliteit: kde-format Are you sure you want to delete the security "%1" and all associated transactions? Weet je zeker dat je het waardepapier "%1" en alle geassocieerde transacties wilt verwijderen ? kde-format No security available. Geen effecten beschikbaar, kde-format Set Quotation (%1) Voer notering in (%1) kde-format Price per share: Prijs per aandeel: kde-format Future dates are not allowed. Datum in de toekomst is niet toegestaan. kde-format Security Transactions Waardepapier transacties kde-format Ledger Grootboek kde-format Untitled Naamloos kde-format Check Account Lopende rekening kde-format Salary Salaris kde-format Bills Rekeningen kde-format Clothing Kleding kde-format Groceries Boodschappen kde-format Leisure Vrijetijd kde-format Couldn't fetch %1. Kon %1 niet ophalen. kde-format Error loading %1: %2. Fout tijdens inlezen %1: %2. kde-format Couldn't open file Kan bestand niet openen kde-format Error saving %1: %2. Fout bij opslaan %1: %2. kde-format Couldn't save file Kan bestand niet opslaan kde-format Failed to upload file to %1. Kan bestand niet uploaden naar %1. kde-format Report Rapportage kde-format Chart Grafiek kde-format Transaction Schedule Transactie Planning kde-format Accounts &amp; Categories html format Rekeningen &amp; Categorieën kde-format Accounts &amp; Categories (%1&ndash;%2) html format Rekeningen &amp; Categorieën (%1&ndash;%2) kde-format Accounts &amp; Categories (to %1) html format Rekeningen &amp; Categorieën (naar %1) kde-format Change Mutatie kde-format Balance Balans kde-format Budget Budget kde-format Remaining Budget Resterend Budget kde-format Total Incomes Totale Inkomsten kde-format Costs Kosten kde-format Total Expenses Totale Uitgaven kde-format Empty expenses list. Lege uitgaven lijst. kde-format Empty incomes list. Lege inkomsten lijst. kde-format Empty transfers list. Lege transactie lijst. kde-format Empty securities list. Lege waardepapieren lijst. kde-format Empty schedule list. Lege Planning. kde-format Export View… Exporteer Overzicht… kde-format Print View… Print Overzicht… kde-format Initial Period Start met periode kde-format Remember Last Dates Onthoud laatst gebuikte datums kde-format Import CSV File… Importeer CSV Bestand… kde-format Import QIF File… Importeer QIF Bestand… kde-format Export As QIF File… Exporteer Als QIF Bestand… kde-format Add Account… Rekening Toevoegen… kde-format New Account… Nieuwe Rekening… kde-format New Income Category… Nieuwe Inkomsten Categorie… kde-format New Expense Category… Nieuwe Uitgaven Categorie… kde-format Balance… Balans… kde-format Show Transactions Toon Transacties kde-format New Transfer… Nieuwe Overboeking: kde-format New Split Transaction… Nieuwe Gesplitste Transactie… kde-format Edit Transaction(s) (Occurrence)… Bewerk Transactie(s) (Gebeurtenis)… kde-format Edit Occurrence… Bewerk Herhaling… kde-format Edit Schedule (Recurrence)… Bewerk Planning (Herhaling)… kde-format Edit Schedule… Bewerk Planning… kde-format Remove Transaction(s) (Occurrence) Verwijder Transactie(s) (Gebeurtenis) kde-format Remove Occurrence Verwijder Herhaling kde-format Delete Schedule (Recurrence) Verwijder Planning (Herhaling) kde-format Delete Schedule Verwijder Planning kde-format Edit Split Transaction… Bewerk Gesplitste Transactie… kde-format Remove Split Transaction Verwijder Gesplitste Transactie kde-format Join Transactions… Transacties Samenvoegen… kde-format Split Up Transaction Splits Transacties kde-format Refund… Restitutie… kde-format Repayment… Terugbetaling… kde-format New Refund/Repayment… Nieuw Restitutie/Terugbetaling… kde-format Edit Security… Bewerk Waardepapier… kde-format Remove Security Verwijder Waardepapier kde-format Shares Sold… Aandelen Verkocht… kde-format Shares Bought… Aandelen Gekocht… kde-format Dividend… Dividend… kde-format Reinvested Dividend… Herinversteerd Dividend… kde-format Shares Moved… Aandelen Verplaatst… kde-format Edit Quotations… Bewerk noteringen… kde-format Transactions… Transacties… kde-format Development Over Time Report… Rapportage per periode… kde-format Categories Comparison Report… Rapportage per Categorie… kde-format Categories Comparison Chart… Grafiek per Categorie… kde-format Development Over Time Chart… Grafiek per periode… kde-format Use Additional Transaction Properties Extra transactie-eigenschappen gebruiken kde-format Eqonomize! exited unexpectedly before the file was saved and data was lost. Do you want to load the last auto-saved version of the file? Eqonomize! is onverwachts afgesloten voordat het bestand was opgelagen en gegevens zijn verloren. Wilt je de laaste automatisch opgelagen versie van het bestanden inladen? kde-format Crash Recovery Herstellen na vastlopen kde-format The current file has been modified. Do you want to save it? Het huidige bestand is gewijzigd. Wilt u het bestand opslaan? kde-format Confirm Schedule Bevestig Planning kde-format New Account Nieuwe Rekening kde-format New Income Category Nieuwe Inkomsten Categorie kde-format New Expense Category Nieuwe Uitgaven Categorie kde-format Balance Account Balansrekening kde-format Book value: Boek waarde: kde-format Real value: Echte waarde: kde-format Edit Account Bewerk Rekening kde-format Edit Income Category Bewerk Inkomsten Categorie kde-format Edit Expense Category Bewerk Uitgaven Categorie kde-format Move transactions? Verplaats transactie? kde-format Move to: Verplaatsen naar: kde-format The category contains some expenses. What do you want to do with them? De categorie bevat enkele uitgaven. Wat wil je er mee doen? kde-format The category contains some incomes. What do you want to do with them? De categorie bevat enkele inkomsten. Wat wil je er mee doen? kde-format The account contains some transactions. What do you want to do with them? Het account bevat enkele transacties. Wat wil je er mee doen? kde-format The category contains some expenses that will be removed. Do you still want to remove the category? De categorie bevat enkele uitgaven die verwijderd zullen worden. Wil je nog steeds de categorie verwijderen? kde-format Remove Category? Verwijder Categorie? kde-format The category contains some incomes that will be removed. Do you still want to remove the category? De categorie bevat enkele inkomsten die verwijderd zullen worden. Wil je nog steeds de categorie verwijderen? kde-format The account contains some transactions that will be removed. Do you still want to remove the account? De categorie bevat enkele transacties die verwijderd zullen worden. Wil je nog steeds de categorie verwijderen? kde-format Remove Account? Verwijder Account? kde-format %2 of %1 %1: budget; %2: remaining budget %2 van %1 kde-format %1 (with no budget) %1 (zonder budget) kde-format %1 (with budget %2) %1 (met budget %2) kde-format Import CSV file Importeer CSV bestand kde-format Transaction Type Selection Selectie Transactiesoort kde-format Expenses and incomes (negative cost) Uitgaven en inkomsten (negatieve kosten) kde-format Expenses and incomes (separate columns) Uitgaven en inkomsten (afgezonderde kolommen) kde-format All types Alle soorten kde-format File Selection Bestandselectie kde-format File: Bestand: kde-format First data row: Eerste gegevens rij: kde-format Auto Automatisch kde-format Column delimiter: Kolom scheiding: kde-format Comma Komma kde-format Tabulator Tabulator kde-format Semicolon Puntkomma kde-format Space Witruimte kde-format Columns Specification Kolommen Specificatie kde-format Column Kolom kde-format Category: Categorie: kde-format From account: Van rekening: kde-format Create missing categories and accounts Maak ontbrekende categorieën en rekeningen kde-format Imports data as expenses. Costs have positive value. Value is the only required column. Importeer gegevens als uitgaven. Kosten hebben positieve waarde. Waarde is de enige vereiste kolom. kde-format Imports data as incomes. Value is the only required column. Importeer gegevens als inkomsten. Waarde is de enige vereiste kolom. kde-format To account: Naar rekening: kde-format Imports data as transfers. Value is the only required column. Importeer gegevens als overboekingen. Waarde is de enige vereiste kolom. kde-format Amount: Hoeveelheid: kde-format Imports data as expenses and incomes. Costs have negative value. Value and category are both required columns. Importeer gegevens als uitgaven en inkomsten. Kosten hebben negatieve waarde. Waarde en categorie zijn beide vereiste kolommen. kde-format Imports data as expenses and incomes. Costs and incomes have separate columns. Income, cost, and category are all required columns. Importeer gegevens als uitgaven en inkomsten. Kosten en inkomsten hebben gescheiden kolommen. Inkomsten, kosten en categorie zijn alle vereiste kolommen. kde-format Imports data as expenses, incomes, and transfers. Costs have negative or positive value. Value, to, and from are all required columns. Accounts and categories must be existing. Importeer gegevens als uitgaven, inkomsten en overboekingen. Kosten hebben negatieve of positieve waarde. Waarde, naar en van zijn alle vereiste kolommen. Rekeningen en categorieën moeten bestaan. kde-format From: Van: kde-format To: Naar: kde-format A file must be selected. Er moet een bestand gelecteerd zijn. kde-format Selected file is a directory. Geselecteerd bestand is een directory. kde-format Selected file does not exist. Geselecteerd bestand bestaat niet. kde-format Empty delimiter. Leeg scheidingsteken. kde-format The same column number is selected multiple times. Hetzelfde kolomnummer is meerdere keren geselecteerd. kde-format Selected from account is the same as the to account. Geselecteerde Van Rekening is hetzelfde als de Naar Rekening. kde-format Couldn't open %1 for reading. Kan bestand %1 niet openen om te lezen. kde-format Error reading %1. Fout bij lezen %1. kde-format Successfully imported 1 transaction. Er is 1 transactie succesvol geïmporteerd. Er zijn %n transacties succesvol geïmporteerd. kde-format Successfully imported %n transactions. Unable to import any transactions imported. Het importeren van transacties is niet gelukt. kde-format Failed to import 1 data row. Het importeren van 1 rij met gegevens is niet gelukt. Het importeren van %n rijen met gegevens is niet gelukt. kde-format Failed to import %n data rows. Required columns missing. Benodigde kolommen ontbreken. kde-format Invalid value. Ongeldige waarde. kde-format Empty category name. De naam van een categorie is leeg. kde-format Empty account name. De naam van een rekening is leeg. kde-format Unknown category found. Onbekende catagorie gevonden. kde-format Unknown account found. Er is een onbekende rekening aangetroffen. kde-format Cannot import security transactions (to/from security accounts). Kan geen effectentransacties importeren (van/naar effectenrekeningen) kde-format Balancing account wrongly used. Balansrekening verkeerd gebuikt. kde-format Same to and from account/category. Rekening/Categorie van en naar zijn hetzelfde. kde-format No data found. Geen gegevens gevonden. kde-format Unrecognized date format. Onherkenbare datumnotatie. kde-format Specify Format Geef notatie aan kde-format The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. De notatie van datums en/of getallen in het CSV-bestand is niet eenduidig. Kies a.u.b. de juiste notatie. kde-format Date format: Datumnotatie: kde-format Value format: Notatie van waarde: kde-format tomorrow the day after today morgen kde-format today this day vandaag kde-format yesterday the day before today gisteren kde-format &Today @option today &Vandaag kde-format To&morrow @option tomorrow &Morgen kde-format Next &Week @option next week Volgende &week kde-format Next M&onth @option next month Volgende m&aand kde-format No Date @option do not specify a date Geen datum kde-format Export… Exporteren… kde-format Print… Afdrukken… kde-format Withdrawal Opname kde-format Join… Samenvoegen… kde-format Split Up Splitsen kde-format Empty transaction list. Lege transactielijst. kde-format Are you sure you want to delete all (%1) selected transactions? Wilt u alle (%1) geselecteerde transacties verwijderen? kde-format Cannot set the value of security transactions using the dialog for modifying multiple transactions. Met het scherm voor het wijzigen van meerdere transacties kunt u de waarde van beleggingstransacties niet instellen. kde-format Cannot change description of dividends and security transactions. Kan de omschrijving van dividenden en effectentransacties niet wijzigen. kde-format Cannot change payer of dividends and security transactions. Kan de debiteur van dividenden en effectentransacties niet wijzigen. kde-format Cannot change date of transactions that are part of a split transaction. Kan de datum van transacties die deel zijn van een gesplitste transactie niet wijzigen. kde-format Eqonomize! Eqonomize! A personal accounting program Een persoonlijk boekhoudprogramma Start with expenses list displayed Startweergave met de lijst van uitgaven Start with incomes list displayed Startweergave met de lijst van inkomsten Start with transfers list displayed Startweergave met de lijst van overboekingen Document to open Document om te openen Incomes and Expenses Inkomsten en Uitgaven kde-format Profits Winsten kde-format All Categories Combined Alle categorieën gecombineerd kde-format All Descriptions Combined Alle omschrijvingen gecombineerd kde-format All Payees/Payers Combined Alle debiteuren/crediteuren gecombineerd kde-format Start date: Begindatum: kde-format End date: Einddatum: kde-format Monthly total Totaal per maand kde-format Daily average Gemiddeld per dag kde-format All Payers Combined Alle debiteuren gecombineerd kde-format All Payees Combined Alle crediteuren gecombineerd kde-format All Descriptions Split Alle omschrijvingen apart kde-format All Payers Split Alle debiteuren apart kde-format All Payees Split Alle crediteuren apart kde-format All Categories Split Alle categorieën apart kde-format Value (%1) Waarde (%1) kde-format Profit (%1) Winst (%1) kde-format Income (%1) Inkomsten (%1) kde-format Cost (%1) Uitgaven (%1) kde-format Time Tijd kde-format no payer geen debiteur kde-format %1/%2 %1: Description; %2: Payer %1/%2 kde-format no payee geen crediteur kde-format %1/%2 %1: Description; %2: Payee %1/%2 kde-format Error after saving file; data may not have been saved. Fout na het opslaan van het bestand; gegevens zijn mogelijk niet opgeslagen. kde-format Average Profit Gemiddelde winst kde-format Year Jaar kde-format Month Maand kde-format Includes scheduled transactions Inclusief geplande transacties kde-format Adjusted for the average month / year (%1 / %2 days) Aangepast voor de gemiddelde maand / jaar (%1 / %2 dagen) kde-format Subtotal Subtotaal kde-format Unnamed Onbenoemd kde-format Uncategorized Zonder categorie kde-format Import QIF file Importeer QIF-bestand kde-format Select a QIF file to import. When you click next, the file be analysed and you might need to answer some questions about the format of the file. Kies een QIF-bestand om te importeren. Wanneer u op Volgende klikt, zal het bestand geanaliseerd worden, en zult u eventueel nog enkele vragen over de indeling van het bestand moeten beantwoorden. kde-format Local Definitions Lokale definities kde-format Unknown elements where found in the QIF file. It is possible that this is because of localized type names. Please map them to the correct standard names. Er zijn onbekende elementen aangetroffen in het QIF-bestand. Mogelijk komt dit door gelokaliseerde type-namen. Geef alstublieft de juiste vertalingen naar standaardnamen aan. kde-format Local Text Lokale tekst kde-format Standard Text Standaardtekst kde-format Select standard text: Selecteer standaardtekst kde-format Date Format Datumnotatie kde-format The date format in the QIF file is ambiguous. Please select the correct format. De datumnotatie in het QIF-bestand is niet eenduidig. Kies a.u.b. de juiste notatie. kde-format Default Account Standaard tegenrekening kde-format Could not find any account definitions in the QIF file. Please select a default account. It is also possible that this is caused by a localized opening balance text. Er zijn geen rekeningdefinities in het QIF-bestand aangetroffen. U kunt een terugval-rekening kiezen. Het is ook mogelijk dat dit probleem het gevolg is van een gelokaliseerde openingsbalanstekst. kde-format Default account: Standaard account: kde-format Opening balance text: Openingsbalanstekst: kde-format Descriptions Omschrijvingen kde-format Transactions in QIF files does not have any specific description property. You are therefore given the option to choose how the description of imported transactions will be set. Bij transacties in QIF-bestanden wordt geen omschrijving vermeld. U kunt aangeven welke omschrijving aan geïmporteerde transacties wordt toegevoegd. kde-format Subcategories as: Subcategorieën als: kde-format Ignore Negeer kde-format Payee as: Crediteur als: kde-format Payee Crediteur kde-format Memo as: Notitie als: kde-format Priority: Prioriteit: kde-format Subcategory/Payee/Comments Subcategorie/Crediteur/Opmerkingen kde-format Payee/Subcategory/Comments Crediteur/Subcategorie/Opmerkingen kde-format Subcategory/Comments/Payee Subcategorie/Opmerkingen/Crediteur kde-format Payee/Comments/Subcategory Crediteur/Opmerkingen/Subcategorie kde-format Comments/Subcategory/Payee Opmerkingen/Subcategorie/Crediteur kde-format Comments/Payee/Subcategory Opmerkingen/Crediteur/Subcategorie kde-format Unknown Onbekend kde-format Bank Bank kde-format Cat (Category) Cat (Categorie) kde-format CCard (Credit Card) CCard (Creditcard) kde-format Invst (Investment) Invst (Investering) kde-format Oth A (Other Assets) Oth A (Overige Activa) kde-format Oth L (Other Liabilities) Oth L (Overige Passiva) kde-format Security Beveiliging kde-format Successfully imported 1 account. Er is 1 rekening succesvol geïmporteerd. Er zijn %n rekeningen succesvol geïmporteerd. kde-format Successfully imported %n accounts. Successfully imported 1 category. Er is 1 categorie succesvol geïmporteerd. Er zijn %n categorieën succesvol geïmporteerd. kde-format Successfully imported %n categories. 1 duplicate transaction was ignored. Er is 1 duplicaat-transactie overgeslagen. Er zijn %n duplicaat-transacties overgeslagen. kde-format %n duplicate transactions was ignored. Failed to import 1 transaction. Het importeren van 1 transactie is mislukt. Het importeren van %n transactie is mislukt. kde-format Failed to import %n transactions. 1 security was not imported. 1 effect niet geïmporteerd. %n effecten niet geïmporteerd. kde-format %n securities were not imported. 1 security transaction was not imported. Er is 1 effectentransactie niet geïmporteerd. Er zijn %n effectentransacties niet geïmporteerd. kde-format %n security transactions were not imported. Export QIF File QIF-bestand exporteren kde-format All All accounts Alle kde-format Export transaction description as: Exporteer transactiebeschrijving als: kde-format Memo Memo kde-format Subcategory Subcategorie kde-format &Import i18n: tag text i18n: file ./eqonomizeui.rc line 5 &Importeer kde-format &Accounts i18n: tag text i18n: file ./eqonomizeui.rc line 12 &Rekeningen kde-format &Transactions i18n: tag text i18n: file ./eqonomizeui.rc line 24 &Transacties kde-format &Securities i18n: tag text i18n: file ./eqonomizeui.rc line 41 &Effecten kde-format Stat&istics i18n: tag text i18n: file ./eqonomizeui.rc line 56 &Overzichten kde-format Your names NAME OF TRANSLATORS ,Launchpad Contributions:,Bert van der Perk,Vis,afiege, ,Launchpad Contributions:,Bert van der Perk,Hanna K.,Mark Haanen,Vis,afiege kde-format Your emails EMAIL OF TRANSLATORS ,,,m.b.vis@spronvis.nl,,,,,,,m.b.vis@spronvis.nl, kde-format Edit Exceptions Uitzonderingen bewerken kde-format Edit Recurrence Range Periode van herhaling bewerken kde-format Begins on: %1 Begint op: %1 kde-format No ending date Geen einddatum kde-format End after Eindigt na kde-format occurrence(s) herhaling(en) kde-format End on Eindigt op kde-format End date before start date. Einddatum is eerder dan begindatum. kde-format Enable recurrence Herhaal deze transactie kde-format Recurrence Rule Herhalingsregel kde-format Weekly Wekelijks kde-format Recur every Herhaal elke kde-format day(s) dag(en) kde-format week(s) on: week/weken op: kde-format month(s), after the start month maand(en), na de beginmaand kde-format Recur on the Herhaal op de kde-format 1st 1ste kde-format 2nd 2de kde-format 3rd 3de kde-format 4th 4de kde-format 5th 5de kde-format 6th 6de kde-format 7th 7de kde-format 8th 8ste kde-format 9th 9de kde-format 10th 10de kde-format 11th 11de kde-format 12th 12de kde-format 13th 13de kde-format 14th 14de kde-format 15th 15de kde-format 16th 16de kde-format 17th 17de kde-format 18th 18de kde-format 19th 19de kde-format 20th 20ste kde-format 21st 21ste kde-format 22nd 22ste kde-format 23rd 23ste kde-format 24th 24ste kde-format 25th 25ste kde-format 26th 26ste kde-format 27th 27ste kde-format 28th 28ste kde-format 29th 29ste kde-format 30th 30ste kde-format 31st 31ste kde-format Last Laatste kde-format 2nd Last Voorlaatste kde-format 3rd Last Op 2 na laatste kde-format 4th Last Op 3 na laatste kde-format 5th Last Op 4 na laatste kde-format day dag kde-format possibly on weekend mogelijk in het weekeinde kde-format but before weekend maar voor het weekeinde kde-format but after weekend maar na het weekeinde kde-format year(s), after the start year jaar/jaren, na het beginjaar kde-format Recur on day part before XXX of 'Recur on day XXX of month YYY' Herhaal op dag kde-format of part between XXX and YYY of 'Recur on day XXX of month YYY' van maand kde-format On the Part before NNN in 'Recur on the NNN. WEEKDAY of MONTH' Herhaal op de kde-format of part between WEEKDAY and MONTH in 'Recur on NNN. WEEKDAY of MONTH' van kde-format Recur on day # Herhaal op dag kde-format of the year part after NNN of 'Recur on day #NNN of the year' van het jaar kde-format Range… Geldigheidsperiode… kde-format Exceptions… Uitzonderingen… kde-format No day of week selected for weekly recurrence. Geen dag van de week gekozen bij wekelijkse herhaling. kde-format Selected day will never occur with selected frequency and start date. De gekozen dag zal nooit voorkomen bij de gekozen frekwentie en begindatum. kde-format Selected day does not exist in selected month. De gekozen dag bestaat niet in de gekozen maand. kde-format Dividend: %1 Dividend: %1 kde-format Account balancing Afletteren kde-format Security: %1 (bought) Effecten: %1 (gekocht) kde-format Security: %1 (sold) Effecten: %1 (verkocht) kde-format Shares bought: Aandelen gekocht: kde-format Shares sold: Aandelen verkocht: kde-format Payer: Debiteur: kde-format Payee: Crediteur: kde-format No income category available. Geen beschikbare inkomenscategorie. kde-format No expense category available. Geen beschikbare uitgavencategorie. kde-format Cannot create a regular transfer to/from a securities account. Van of naar een effectenrekening kan geen gewone overboeking worden ingevoerd. kde-format Cannot create a regular income to a securities account. Naar een effectenrekening kan geen gewoon inkomen worden geboekt. kde-format Zero price per share not allowed. Het is niet toegestaan om een prijs per aandeel van nul in te voeren. kde-format Cannot create a regular expense from a securities account. Van een effectenrekening kan geen gewone uitgave worden geboekt. kde-format Modify Transactions Transacties Bewerken kde-format Min amount: Minimum bedrag: kde-format Max amount: Maximum bedrag: kde-format Min income: Minimum inkomen: kde-format Max income: Maximum inkomen: kde-format Min cost: Minimum kosten: kde-format Max cost: Maximum kosten: kde-format Include Tonen kde-format Exclude Niet tonen kde-format From Account Van Rekening kde-format To Account Naar Rekening kde-format Payer Debiteur kde-format New/Edit Expense Uitgave toevoegen/bewerken kde-format Filter Filteren kde-format Total: Totaal: kde-format Average: Gemiddeld: kde-format Monthly: Per maand: kde-format Total cost: Totaal uitgaven: kde-format Total income: Totaal inkomsten: kde-format Total amount: Totaal bedrag: kde-format Monthly average: Maandelijks gemiddelde: kde-format Are you sure you want to delete all (%1) transactions in the selected split transaction? Weet u zeker dat u alle (%1) transacties in de geselecteerde gesplitste transactie wilt verwijderen? kde-format * Part of split transaction * Deel van gesplitste transactie kde-format * Part of split (%1) Deel van splitsing (%1) kde-format ** Recurring (editing occurrence) ** Herhalend (individuele gebeurtenis wordt bewerkt) kde-format Modify… Wijzigen… kde-format AccountComboBox New account… Nieuwe rekening… Multiple accounts/payments… New income category… Nieuwe inkomsten categorie… New expense category… Nieuwe uitgaven categorie… Paid with loan… New Account Nieuwe rekening New Income Category Nieuwe inkomsten categorie New Expense Category Nieuwe uitgaven categorie AccountsMenu All Accounts Alle rekeningen All Categories Combined Alle categorieën gecombineerd %n accounts %n rekening %n rekeningen %n categories %n categorie %n categorieën Balancing Account balancing Afletteren Account balancing Balancing of an account Afletteren Account Balance Adjustment Budget Balancing Balans Balancing Name of account for transactions that adjust account balances Balans Couldn't open %1 for reading Kan %1 niet openen om te lezen Not a valid Eqonomize! file (XML parse error: "%1" at line %2, col %3) Ongeldig Eqonomize! bestand (XML parserfout: "%1" in regel %2, kolom %3) Invalid root element %1 in XML document Ongeldig bronelement %1 in XML document Unknown XML element: "%1" at line %2, col %3 XML parse error: "%1" at line %2, col %3 European Euro Unable to load %n currency/currencies. No exchange rates found. USD currency missing. imported Unable to load %n account(s). Kan %n rekening niet inlezen. Kan %n rekeningen niet inlezen. Unable to load %n category/categories. Kan %n categorie niet inlezen. Kan %n categorieen niet inlezen. Unable to load %n security/securities. Financial security (e.g. stock, mutual fund) Kan %n effect niet inlezen. Kan %n effecten niet inlezen. Download command (%1) failed: %2. Failed to download file from %1: %2. Upload command (%1) failed: %2. yyyy-yy Financial year when first month is not January (e.g. 2018-19). Transaction Accounts Betaalrekeningen Savings Accounts Spaarrekeningen Credit Cards Creditcards Debts Schulden Securities Financial security (e.g. stock, mutual fund) Effecten Cash Contant geld Transaction Account Betaalrekening Savings Account Spaarrekening Credit Card Creditcard Debt Schuld Other Overig Unable to load %n security/securities. Kan %n effect niet inlezen. Kan %n effecten niet inlezen. Unable to load %n transaction(s). Kan %n transactie niet inlezen. Kan %n transacties niet inlezen. File is a directory Bestand is een directory Couldn't open file for writing Kan bestand niet openen om te schrijven Error while writing file; file was not saved Fout tijdens het schrijven van het bestand; bestand is niet opgeslagen Unnamed Onbenoemd Uncategorized Zonder categorie CategoriesComparisonChart Save As… Opslaan als… Print… Afdrukken… From Vanaf To Tot Source: Bron: All Expenses Alle uitgaven All Incomes Alle inkomsten Theme: Chart type: Pie Chart Bar Chart Default Standaard All Expenses, without subcategories Alle uitgaven, zonder subcategorieën All Expenses, with subcategories Alle uitgaven, mit subcategorieën All Incomes, without subcategories Alle inkomsten, zonder subcategorieën All Incomes, with subcategories Alle inkomsten, zonder subcategorieën All Accounts Alle rekeningen Expenses: %1 Uitgaven: %1 Incomes: %1 Inkomsten: %1 Error Invalid date. Ongeldige datum. To date is before from date. Tot-datum ligt voor Vanaf-datum. From date is after to date. Vanaf-datum ligt na Tot-datum. Couldn't open file for writing. Kan bestand niet openen voor schrijven. Error while writing file; file was not saved. Fout tijdens het schrijven van het bestand; bestand is niet opgeslagen. Expenses Uitgaven Expenses, %1 Uitgaven, %1 Incomes, %1 Inkomsten, %1 Incomes Inkomsten Accounts Rekeningen Expenses, %2: %1 Uitgaven, %2: %1 Incomes, %2: %1 Inkomsten, %2: %1 Other descriptions Referring to the transaction description property (transaction title/generic article name) Andere omschrijvingen No description Referring to the transaction description property (transaction title/generic article name) Geen omschrijving Other accounts Andere rekeningen Other categories Andere categorieën %1 Value: %2 %1 Waarde: %2 No description Referring to the Transaction description property (transaction title/generic article name) Geen omschrijving No description Referring to the generic description property Geen omschrijving Value Waarde Income Inkomsten Cost Kosten Value (%1) Waarde (%1) Income (%1) Inkomsten (%1) Cost (%1) Uitgaven (%1) No description Geen omschrijving CategoriesComparisonChartDialog Chart Grafiek CategoriesComparisonReport Save As… Opslaan als… Print… Afdrukken… Source: Bron: All Categories, excluding subcategories Alle categorieën, exclusief subcategorieën All Categories, including subcategories Alle categorieën, inclusief subcategorieën All Payees/Payers Alle crediteuren/debiteuren Subcategories Subcategorieën Descriptions for Referring to the Transaction description property (transaction title/generic article name) Omschrijving voor All descriptions Referring to the Transaction description property (transaction title/generic article name) Alle omschrijvingen No description Referring to the Transaction description property (transaction title/generic article name) Geen omschrijving All Categories Alle categorieën Expenses: %1 Uitgaven: %1 Incomes: %1 Inkomsten: %1 Descriptions for Omschrijving voor Payees/payers for Crediteuren/debiteuren voor Descriptions Referring to the Transaction description property (transaction title/generic article name) Omschrijvingen Period: Periode: From Vanaf To Tot Columns: Kolommen: Value Waarde Daily Dagelijks Monthly Maandelijks Yearly Jaarlijks Quantity Hoeveelheid Average value Gemiddelde waarde All descriptions Alle omschrijvingen All payees Alle crediteuren All payers Alle debiteuren No description Geen omschrijving Descriptions for Referring to the generic description property Omschrijving voor Descriptions Referring to the generic description property Omschrijvingen All descriptions Referring to the generic description property Alle omschrijvingen No description Referring to the generic description property Geen omschrijving All Payees and Payers Alle crediteuren en debiteuren Tag: %1 Label: %1 All Accounts Alle rekeningen Descriptions for Referring to the transaction description property (transaction title/generic article name) Omschrijving voor Descriptions Referring to the transaction description property (transaction title/generic article name) Omschrijvingen Months Maanden Years Jaar Tags Labels Total: Totaal: All descriptions Referring to the transaction description property (transaction title/generic article name) Alle omschrijvingen All payees/payers Alle crediteuren/debiteuren No description Referring to the transaction description property (transaction title/generic article name) Geen omschrijving No payee Geen crediteur No payer Geen debiteur Error Invalid date. Ongeldige datum. To date is before from date. Tot-datum ligt voor Vanaf-datum. From date is after to date. Vanaf-datum ligt na Tot-datum. Couldn't open file for writing. Kan bestand niet openen voor schrijven. Error while writing file; file was not saved. Fout tijdens het schrijven van het bestand; bestand is niet opgeslagen. Expenses, %2: %1 Uitgaven, %2: %1 Expenses, %3: %2, %1 Uitgaven, %3: %2, %1 Incomes, %2: %1 Inkomsten, %2: %1 Incomes, %3: %2, %1 Inkomsten, %3: %2, %1 %3: %2, %1 %3: %2, %1 %2: %1 %2: %1 Tags, %1 Labels, %1 Incomes & Expenses, %1 Inkomsten en uitgaven, %1 Expenses: %2, %1 Uitgaven: %2, %1 Incomes: %2, %1 Inkomsten: %2, %1 %2, %1 %2, %1 %1 %1 Incomes & Expenses Inkomsten en uitgaven %1 (%2&ndash;%3) html format; %1: title; %2: from date; %3: to date %1 (%2&ndash;%3) %1 (to %2) html format; %1: title; %2: to date %1 (tot %2) Category Categorie Payee Crediteur Description Referring to the transaction description property (transaction title/generic article name) Omschrijving Cost Kosten Payer Debiteur Income Inkomsten Payee/Payer Crediteur/debiteur Tag Label Daily Average Dagelijks gemiddelde Monthly Average Maandelijks gemiddelde Yearly Average Jaarlijks gemiddelde Average Cost Gemiddelde kosten Average Income Gemiddelde inkomsten Average Value Gemiddelde waarde No payee/payer Geen crediteur/debiteur Total Totaal All Tags Alle labels Total incomes Totaal inkomsten Total expenses Totaal uitgaven Total (Profits) Totaal (winst) CategoriesComparisonReportDialog Report Rapportage ConfirmScheduleDialog The following transactions was scheduled to occur today or before today. Confirm that they have indeed occurred (or will occur today). De volgende transacties waren gepland om vandaag of eerder plaats te vinden. Bevestig dat ze plaats hebben gevonden (of vandaag nog plaats zullen vinden). Date Datum Type Type Description Omschrijving Name Naam Description Generic Description Omschrijving Description Transaction description property (transaction title/generic article name) Omschrijving Amount Bedrag Edit… Bewerk… Postpone… Uitstellen… Delete Verwijderen Error Can only postpone to future dates. Kan alleen uitstellen naar een datum in de toekomst. ConfirmScheduleListViewItem Transfer Overboeking Dividend Dividend Income Inkomsten Expense Uitgaven Securities Purchase Financial security (e.g. stock, mutual fund) Effecten aankopen Securities Sale Financial security (e.g. stock, mutual fund) Effecten verkopen Security Buy Effecten aankopen Security Sell Effecten verkopen Debt Payment CurrencyConversionDialog Currency Converter DebtFee Debt payment: %1 (fee) DebtInterest Debt payment: %1 (interest) DebtPayment Debt payment: %1 DebtReduction Debt payment: %1 (reduction) DescriptionsMenu All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Alle omschrijvingen gecombineerd All Tags Combined All Payees Combined Alle crediteuren gecombineerd All Payers Combined Alle debiteuren gecombineerd All Payees/Payers Combined Alle debiteuren/crediteuren gecombineerd No description Referring to the transaction description property (transaction title/generic article name) Geen omschrijving No payee Geen crediteur No payer Geen debiteur No payee/payer Geen crediteur/debiteur %n descriptions Referring to the transaction description property (transaction title/generic article name) %n omschrijving %n omschrijvingen %n tags %n label %n labels %n payees %n crediteur %n crediteuren %n payers %n debiteur %n debiteuren %n payees/payers %n crediteur/debiteur %n crediteuren/debiteuren EditAssetsAccountDialog Type: Soort: Cash Contant geld Current Account Lopende rekening Savings Account Spaarrekening Credit Card Creditcard Liabilities Passiva Transactional Account Betaalrekening Debt Schuld Securities Effecten Other Overig Currency: Edit Bewerk Name: Naam: Bank: Bank: Initial balance: Openingsbalans: Debt: Initial balance Openingsbalans Group: Groep: no group geen groep Transferred to: Date: Datum: Lender: Default account for budgeted transactions Standaard rekening voor gebudgetteerde transacties Description: Omschrijving: Account is closed Warning Type cannot be changed to securities for accounts with transactions. Issuer: Zero value not allowed. Geen waarde niet toegestaan. Error Transaction Account Betaalrekening Opening balance: Account balance Openingsbalans: Opening balance Account balance Openingsbalans New currency… If you change the currency of an account, the currency of all associated transactions will also change, without any conversion. Do do wish to continue anyway? Empty name. Lege naam. The entered name is used by another account. De ingevoerde naam is al gebruikt voor een andere rekening. EditCurrencyDialog Edit Currency New Currency Code: Symbol: Prefix Suffix Default Standaard Name: Naam: Decimals: Date: Datum: Main currency Error Error saving currencies: %1. Empty code. Code already exists. EditDebtPaymentDialog Debt Payment EditDebtPaymentWidget Debt: Date: Datum: Debt reduction: Reduction payment: Interest: Paid Added to debt Fee: Account: Rekening: Expense category: Uitgaven categorie: Associated file: Bijbehorend bestand: Select a file Open the file Comments: Opmerkingen: Related to: Label for linked transactions Links: Total value: Totale waarde: Error No suitable account available. Geen geschikte rekening beschikbaar. Invalid date. Ongeldige datum. Interest must not be zero. At least one value must non-zero. EditExceptionsDialog Edit Exceptions Uitzonderingen bewerken Occurrences: Herhalingen: Add Exception Remove Exception Exceptions: Uitzonderingen: Only the first fifty occurrences are shown. Invalid date. Ongeldige datum EditExpensesAccountDialog Name: Naam: Parent category: None Monthly budget: Maandelijks budget: Description: Omschrijving: Error Empty name. Lege naam. The entered name is used by another expense category. De ingevoerde naam is gebruikt voor een andere kosten categorie. EditIncomesAccountDialog Name: Naam: Parent category: None Monthly budget: Maandelijks budget: Description: Omschrijving: Error Empty name. Lege naam. The entered name is used by another income category. De ingevoerde naam is gebruikt voor een andere inkomsten categorie. EditLoanTransactionWidget Date: Datum: Account: Rekening: Comments: Opmerkingen: Total value: Totale waarde: No suitable account available. Geen geschikte rekening beschikbaar. Invalid date. Ongeldige datum EditMultiAccountDialog Expense with Multiple Payments Income with Multiple Payments EditMultiAccountWidget Description: Omschrijving: Description: Generic Description Omschrijving: Description: Transaction description property (transaction title/generic article name) Omschrijving: Quantity: Hoeveelheid: Category: Categorie: Tags: Labels: Associated file: Bijbehorend bestand: Select a file Open the file Comments: Opmerkingen: Related to: Label for linked transactions Links: Transactions: Transacties: Date Datum Account Rekening Payee Crediteur Payer Debiteur Cost Kosten Income Inkomsten Total cost: Totaal uitgaven: New Tag Nieuw label Tag: Label: Value Waarde New Nieuw Edit… Bewerk… Delete Verwijderen Total value: Totale waarde: Error No suitable expense categories available. A split must contain at least two transactions. Een splitsing moet minstens twee transacties bevatten. EditMultiItemDialog Split Transaction Gesplitste transactie EditMultiItemWidget Description: Omschrijving: Description: Generic Description Omschrijving: Date: Datum: Account: Rekening: Payee/Payer: Crediteur/debiteur: Transactions: Transacties: Type Type Description Generic Description Omschrijving Description: Transaction description property (transaction title/generic article name) Omschrijving: Tags: Labels: Associated file: Bijbehorend bestand: Select a file Open the file Comments: Opmerkingen: Related to: Label for linked transactions Links: Description Transaction description property (transaction title/generic article name) Omschrijving Payment Betaling Deposit Storting New Nieuw New Expense… Nieuwe kosten… New Income… Nieuwe inkomsten… New Deposit… Nieuwe storting… New Withdrawal… Nieuwe opname… New Securities Purchase… Financial security (e.g. stock, mutual fund) Nieuwe effectenaankoop… New Securities Sale… Financial security (e.g. stock, mutual fund) Nieuwe effectenverkoop… Shares Bought… Aandelen gekocht… Shares Sold… Aandelen verkocht… Account/Category Rekening/Categorie Value Waarde Income Inkomsten Expense Uitgaven New Dividend… Nieuw dividend… Edit… Bewerk… Delete Verwijderen Total value: Totale waarde: Error No suitable account available. Geen geschikte rekening beschikbaar. Invalid date. Ongeldige datum. A split must contain at least two transactions. Een splitsing moet minstens twee transacties bevatten. Cannot transfer money to and from the same account. Kan geen geld overmaken naar en van dezelde rekening. EditQuotationsDialog Quotations Noteringen Date Datum Price per Share Prijs per aandeel Quotations Financial quotation Noteringen Quotes Financial quote Noteringen Price per Share Financial Shares Prijs per aandeel Add Toevoegen Modify Wijzigen Delete Verwijderen Import… Importeer… Export… Exporteren… Quotes for %1 Financial quote Noteringen voor %1 Quotations for %1 Financial quotation Noteringen voor %1 Quotations for %1 Noteringen voor %1 Error Couldn't open %1 for reading. Kan bestand %1 niet openen om te lezen. Error reading %1. Fout bij lezen %1. Successfully imported %n quote(s). Er is %n notering succesvol geïmporteerd. Er is %n noteringen succesvol geïmporteerd. Unable to import any quotes. Het importeren van noteringen is niet gelukt. Failed to import %n data row(s). Het importeren van %n rij met gegevens is niet gelukt. Het importeren van %n rijen met gegevens is niet gelukt. Required columns missing. Benodigde kolommen ontbreken. Invalid value. Ongeldige waarde. Invalid date. Ongeldige datum. No data found. Geen gegevens gevonden. Information Unrecognized date format. Onherkenbare datumnotatie. Specify Format Geef notatie aan The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. De notatie van datums en/of getallen in het CSV-bestand is niet eenduidig. Kies a.u.b. de juiste notatie. Date format: Datumnotatie: Value format: Notatie van waarde: Couldn't open file for writing. Kan bestand niet openen voor schrijven. Quotes: %1 Noteringen: %1 Error while writing file; file was not saved. Fout tijdens het schrijven van het bestand; bestand is niet opgeslagen. EditRangeDialog Edit Recurrence Range Periode van herhaling bewerken Begins on: %1 Begint op: %1 No ending date Geen einddatum End after Eindigt na occurrence(s) herhaling(en) End on Eindigt op Error Invalid date. Ongeldige datum. End date before start date. Einddatum is eerder dan begindatum. EditReinvestedDividendDialog Reinvested Dividend Geherinvesteerd dividend Security: Effecten: Shares added: Aandelen toegevoegd: Security: Financial security (e.g. stock, mutual fund) Effecten: Shares added: Financial shares Aandelen toegevoegd: Date: Datum: Invalid date. Ongeldige datum. EditScheduledDebtPaymentDialog Transaction Transactie Recurrence Herhaling Edit Debt Payment New Debt Payment EditScheduledLoanTransactionDialog Recurrence Herhaling EditScheduledMultiAccountDialog Transactions Transacties Recurrence Herhaling New Expense with Multiple Payments New Income with Multiple Payments Edit Expense with Multiple Payments Edit Income with Multiple Payments EditScheduledMultiItemDialog Transactions Transacties Recurrence Herhaling New Split Transaction Nieuwe gesplitste transactie Edit Split Transaction Bewerk gesplitste transactie EditScheduledTransactionDialog Expense Uitgaven Dividend Dividend Income Inkomsten Reinvested Dividend Geherinvesteerd dividend Transfer Overboeking Security Buy Effecten aankopen Security Sell Effecten verkopen Securities Purchase Financial security (e.g. stock, mutual fund) Effecten aankopen Securities Sale Financial security (e.g. stock, mutual fund) Effecten verkopen Recurrence Herhaling New Expense Nieuwe kosten New Expense Paid with Loan New Dividend Nieuw dividend New Income Nieuwe inkomsten New Transfer Nieuwe overboeking New Securities Purchase Financial security (e.g. stock, mutual fund) Nieuwe effectenaankoon New Reinvested Dividend New Securities Sale Financial security (e.g. stock, mutual fund) Nieuwe effectenverkoop Edit Reinvested Dividend Edit Securities Purchase Financial security (e.g. stock, mutual fund) Gekochte effecten bewerken Edit Securities Sale Financial security (e.g. stock, mutual fund) Gekochte effecten bewerken New Security Buy Nieuwe effectenaankoop New Security Sell Nieuwe effectenverkoop Edit Expense Kosten bewerken Edit Dividend Dividend bewerken Edit Income Inkomsten bewerken Edit Transfer Overboeking bewerken Edit Securities Bought Gekochte effecten bewerken Edit Securities Sold Verkochte effecten bewerken EditSecurityDialog Type: Soort: Mutual Fund Beleggingsfonds Bond Obligatie Stock Aandelen Stock Financial stock Aandelen Other Overig Name: Naam: Account: Rekening: Decimals in shares: Financial shares Decimalen in aandelen: Initial shares: Financial shares Aanvankelijke aandelen: Decimals in quotes: Financial quote Initial quote: Financial quote Aanvankelijke notering: Empty name. Lege naam. No suitable account available. Geen geschikte rekening beschikbaar. Initial quotation: Financial quotation Aanvankelijke Notering: Decimals in shares: Decimalen in aandelen: Initial shares: Aanvankelijke aandelen: Decimals in Shares: Decimalen in Aandelen: Initial Shares: Aanvankelijke Aandelen: Initial quotation: Aanvankelijke Notering: Date: Datum: Description: Omschrijving: Error No suitable account or income category available. Geen geschikte rekening of inkomsten categorie beschikbaar. EditSecurityTradeDialog Security Trade Effectenhandel From security: Van effecten: Shares moved: Effecten verplaatst: All Alle To security: Naar effecten: Shares received: Effecten ontvangen: Securities Exchange Shares of one security directly exchanged for shares of another; Financial security (e.g. stock, mutual fund) Effectenhandel From security: Financial security (e.g. stock, mutual fund) Van effecten: Shares moved: Financial shares Effecten verplaatst: To security: Financial security (e.g. stock, mutual fund) Naar effecten: Shares received: Financial shares Effecten ontvangen: Value: Waarde: Date: Datum: Error No other security available for exchange in the account. Shares of one security directly exchanged for shares of another; Financial security (e.g. stock, mutual fund) Geen andere effecten beschikbaar om te verhandelen op deze rekening. No other security available for trade in the account. Geen andere effecten beschikbaar om te verhandelen op deze rekening. Selected to and from securities are the same. Financial security (e.g. stock, mutual fund) Gekozen effecten Van en Naar zijn hetzelfde. Zero shares not allowed. Financial shares Nul effecten niet toegestaan. Selected to and from securities are the same. Gekozen effecten Van en Naar zijn hetzelfde. Invalid date. Ongeldige datum. Zero shares not allowed. Nul effecten niet toegestaan. Zero value not allowed. Geen waarde niet toegestaan. EditSplitDialog Split Transaction Gesplitste transactie Description: Omschrijving: Date: Datum: Account: Rekening: Transactions: Transacties: Type Type Description Omschrijving Name: Naam: Name Naam Description Generic Description Omschrijving Account/Category Rekening/Categorie Payment Betaling Deposit Storting New Nieuw New Expense… Nieuwe kosten… New Income… Nieuwe inkomsten… New Deposit… Nieuwe storting… New Withdrawal… Nieuwe opname… Shares Bought… Aandelen Gekocht… Shares Sold… Aandelen Verkocht… New Dividend… Nieuw dividend… Edit… Bewerk… Total value: Totale waarde: No suitable account available. Geen geschikte rekening beschikbaar. Invalid date. Ongeldige datum Future dates is not allowed. Datums in de toekomst zijn niet toegestaan. A split must contain at least two transactions. Een splitsing moet minstens twee transacties bevatten. Cannot transfer money to and from the same account. Kan geen geld overmaken naar en van dezelde rekening. Eqonomize Accounts && Categories Rekeningen && Categorieën Expenses Uitgaven Incomes Inkomsten Transfers Overboekingen Transaction Accounts Betaalrekeningen Savings Accounts Spaarrekeningen Credit Cards Creditcards Debts Schulden Securities Effecten Schedule Planning Account / Category Rekening / categorie Remaining Budget (%1) Resterend budget (%1) Change (%1) Mutatie (%1) Total (%1) Totaal (%1) %2 of %1 %2 remains of %1 budget %2 van %1 Accounts Rekeningen Includes budgeted transactions Inclusief gebudgetteerde transacties Tags Labels Period Periode From Vanaf To Tot Select Period Selecteer periode Current Month Huidige maand Current Year Huidig jaar Current Whole Month Huidige hele maand Current Whole Year Huidig heel jaar Whole Past Month Hele afgelopen maand Whole Past Year Heel vorig jaar Previous Month Vorige maand Previous Year Vorig jaar Show partial budget Toon gedeeltelijk budget Edit Budget Bewerk budget Budget: Budget: Month: Maand: Result previous month: Resultaat vorige maand: New Security… Nieuw effecten… New Transaction Nieuwe transactie Set Quotation… Voer notering in… Name Naam Value Waarde Shares Aandelen Quotation Notering Cost Kosten Profit Winst Yearly Rate Jaarlijkse ontwikkeling Type Type Account Rekening Statistics Period Statistieken periode New Schedule Nieuwe planning Edit Bewerk Remove Verwijderen Next Occurrence Volgende gebeurtenis Description Omschrijving Description Generic Description Omschrijving Amount Bedrag Payee/Payer Crediteur/debiteur Comments Beschrijving Set Schedule Confirmation Time Schedule confirmation time: Set Budget Period First day in budget month: 1st 1ste 2nd 2de 3rd 3de 4th 4de 5th 5de 6th 6de 7th 7de 8th 8ste 9th 9de 10th 10de 11th 11de 12th 12de 13th 13de 14th 14de 15th 15de 16th 16de 17th 17de 18th 18de 19th 19de 20th 20ste 21st 21ste 22nd 22ste 23rd 23ste 24th 24ste 25th 25ste 26th 26ste 27th 27ste 28th 28ste Last Laatste 2nd Last Voorlaatste 3rd Last Op 2 na laatste 4th Last Op 3 na laatste 5th Last Op 4 na laatste Timestamp Tijdstempel Links Links Remove Link Link verwijderen Link to "%1" create link to transaction (link used as verb) Link aan "%1" All Alle Import Options Ignore duplicate transactions Rename duplicate accounts Rename duplicate categories Rename duplicate securities Synchronization Settings Web address: Download command: Duplicate Transaction… duplicate as verb Dupliceer transactie… Create Link create link to or between transaction(s) Maak link New Tag… Nieuw label… Rename Tag… Label hernoemen… Remove Tag Label verwijderen New Tag Nieuw label Tag name: Label naam: Remove tag? Label verwijderen? Do you wish to remove the tag "%1" from %n transaction(s)? Rename Tag Label hernoemen optional Link Transactions create link between selected transactions (link used as verb) Link de transacties Create Link to Transaction Maak link naar transactie Upload command: mandatory Automatic synchronization Upload Uploading… Error uploading file Error uploading %1: %2. Synchronizing… Error synchronizing file Error synchronizing %1: %2. Synchronization error Synchronize file? The file has been modified by a different user or program. Do you wish to merge changes? New version available A new version of %1 is available.<br><br>You can get version %2 at %3. Abort First month in budget year: Right align Rechts uitlijnen %f = local file (temporary), %u = url Failed to download exchange rates from %1: %2. Error reading data from %1: %2. Unrecognized Currency No exchange rate is available for the default currency (%1). If you wish to use multiple currencies you should set the exchange rate manually. Set Main Currency Currency: Replace all occurrences of the former main currency Transaction Account Betaalrekening S&ynchronize Import %1 File… Reconcile Account… Adjust balance… Referring to account balance Close Account Mark account as closed Rekeningen sluiten New Expense Paid with Loan… Show payee and quantity Toon crediteur en hoeveelheid Show quantity and payer/payee properties for incomes and expenses. Set Schedule Confirmation Time… Select Font… Selecteer lettertype… Language Taal Default Standaard Restart required Only use this when unable to find the cause of the incorrect recorded account balance. Reopen Account Mark account as not closed New Debt Payment… New Unpaid Interest… Use Exchange Rate for Transaction Date Use the exchange rate nearest the transaction date, instead of the latest available rate, when converting the value of transactions. %1 exited unexpectedly before the file was saved and data was lost. Do you want to load the last auto-saved version of the file? Eqonomize! Accounting File Adjust Account Balance New Security Nieuw waardepapier Edit Security Bewerk waardepapier Total value: Totale waarde: Cost: Kosten: Profit: Winst: Rate: Rentabiliteit: Are you sure you want to delete the security "%1" and all associated transactions? Weet je zeker dat je het waardepapier "%1" en alle geassocieerde transacties wilt verwijderen ? Error No security available. Geen effecten beschikbaar. Set Quotation (%1) Voer notering in (%1) Price per share: Prijs per aandeel: Date: Datum: Invalid date. Ongeldige datum. Future dates are not allowed. Datum in de toekomst is niet toegestaan. Security Transactions Waardepapier transacties Bond Obligatie Stock Aandelen Mutual Fund Beleggingsfonds Other Overig Add Loan Add Category Ledger Grootboek To date is before from date. Tot-datum ligt voor Vanaf-datum. From date is after to date. Vanaf-datum ligt na Tot-datum. Cash Contant geld Check Account Lopende rekening Savings Account Spaarrekening Salary Salaris Bills Rekeningen Clothing Kleding Groceries Boodschappen Leisure Vrijetijd Couldn't open file Kan bestand niet openen Error loading %1: %2. Fout tijdens inlezen %1: %2. Couldn't save file Kan bestand niet opslaan Error saving %1: %2. Fout bij opslaan %1: %2. Updating exchange rates… Error saving currencies: %1. New currency… Transaction Schedule Transactie planning Total Totaal Accounts &amp; Categories html format Rekeningen &amp; categorieën Accounts &amp; Categories (%1&ndash;%2) html format Rekeningen &amp; categorieën (%1&ndash;%2) Accounts &amp; Categories (to %1) html format Rekeningen &amp; categorieën (naar %1) Change Noun, how much the account balance has changed Mutatie Balance Balans Current Account Lopende rekening Credit Card Creditcard Liabilities Passiva Set Quote… Financial quote Voer notering in… Quote Financial quote Notering Set Quote (%1) Financial quote Voer notering in (%1) Stock Financial stock Aandelen Balance Noun. Balance of an account Saldo Category Categorie Budget Budget Remaining Budget Resterend budget Total Incomes Totale inkomsten Costs Kosten Total Expenses Totale uitgaven Account/Category Noun, how much the account balance has changed Rekening/categorie Empty expenses list. Lege uitgaven lijst. Empty incomes list. Lege inkomsten lijst. Empty transfers list. Lege transactie lijst. Empty securities list. Lege waardepapieren lijst. Empty schedule list. Lege planning. Couldn't open file for writing. Kan bestand niet openen voor schrijven. Error while writing file; file was not saved. Fout tijdens het schrijven van het bestand; bestand is niet opgeslagen. &File &Bestand &Accounts &Rekeningen &Transactions &Transacties &Securities &Effecten Stat&istics &Overzichten S&ettings &Instellungen &Help File Bestand Transactions Transacties Statistics Overzichten &New &Nieuw &Open… &Openen… Open Recent Recent geopend Clear List Lijst wissen &Save Op&slaan Save As… Opslaan als… &Revert &Herladen &Print… Af&drukken… Print Preview… Afdrukvoorbeeld… Import Importeer Import CSV File… Importeer CSV bestand… Import QIF File… Importeer QIF bestand… Export View… Exporteer overzicht… Export As QIF File… Exporteer als QIF bestand… Update Exchange Rates Currency Converter &Quit &Afsluiten Add Account… Rekening toevoegen… New Account… Nieuwe rekening… New Loan… New Income Category… Nieuwe inkomsten categorie… New Expense Category… Nieuwe uitgaven categorie… Add Account Rekening toevoegen Assets Activa Description Transaction description property (transaction title/generic article name) Omschrijving Security Transactions Financial security (e.g. stock, bond) Waardepapier transacties &Loans &Leningen Edit… Bewerk… Balance… Balans… Show Transactions Toon transacties Show Ledger Toon grootboek New Expense… Nieuwe kosten… New Income… Nieuwe inkomsten… New Transfer… Nieuwe overboeking… New Split Transaction… Nieuwe gesplitste transactie… New Expense with Multiple Payments… Refund… Restitutie… Repayment… Terugbetaling… New Refund/Repayment… Nieuw restitutie/terugbetaling… Edit Transaction(s) (Occurrence)… Bewerk transactie(s) (gebeurtenis)… Edit Occurrence… Bewerk herhaling… Edit Schedule (Recurrence)… Bewerk planning (herhaling)… Edit Schedule… Bewerk planning… Edit Split Transaction… Bewerk gesplitste transactie… Join Transactions… join transactions together Transacties samenvoegen… Split Up Transaction split up joined transactions Splits transactie Edit Timestamp… Tijdstempel bewerken… Select Associated File Open Associated File Remove Transaction(s) (Occurrence) Verwijder transactie(s) (gebeurtenis) Remove Occurrence Verwijder herhaling Delete Schedule (Recurrence) Verwijder planning (herhaling) Delete Schedule Verwijder planning Remove Split Transaction Verwijder gesplitste transactie Edit Security… Bewerk waardepapier… Remove Security Verwijder waardepapier Shares Bought… Aandelen gekocht… Shares Sold… Aandelen verkocht… Shares Moved… Aandelen verplaatst… Dividend… Dividend… Reinvested Dividend… Herinversteerd dividend… Transactions… Transacties… Edit Quotations… Bewerk noteringen… Development Over Time Report… Rapportage per periode… Categories Comparison Report… Rapportage per categorie… Development Over Time Chart… Grafiek per periode… Categories Comparison Chart… Grafiek per categorie… Use Additional Transaction Properties Extra transactie-eigenschappen gebruiken Set Main Currency… Set Budget Period… Initial Period Start met periode Remember Last Dates Onthoud laatst gebuikte datums Backup Frequency Daily Dagelijks Weekly Wekelijks Fortnightly Monthly Maandelijks Never Cloud Synchronization (experimental)… Dark Mode Help Report Bug About %1 About Qt Please restart the application for the language change to take effect. A personal accounting program Een persoonlijk boekhoudprogramma License: GNU General Public License Version 3 Crash Recovery Herstellen na vastlopen Untitled Naamloos Securities Financial security (e.g. stock, mutual fund) Effecten New Security… Financial security (e.g. stock, mutual fund) Nieuw effecten… Set Quotation… Financial quotation Voer notering in… Shares Financial shares Aandelen Quotation Financial quotation Notering New Security Financial security (e.g. stock, mutual fund) Nieuw effecten Edit Security Financial security (e.g. stock, mutual fund) Bewerk effecten Delete security? Financial security (e.g. stock, mutual fund) Are you sure you want to delete the security "%1" and all associated transactions? Financial security (e.g. stock, mutual fund) Weet je zeker dat je het effecten "%1" en alle geassocieerde transacties wilt verwijderen ? No security available. Financial security (e.g. stock, mutual fund) Geen effecten beschikbaar. Set Quotation (%1) Financial quotation Voer notering in (%1) Price per share: Financial shares Prijs per aandeel: Security Transactions Financial security (e.g. stock, mutual fund) Effecten transacties Checking Account Transactional account Betaalrekening Balance Account balance Saldo Empty securities list. Financial security (e.g. stock, mutual fund) Lege effecten lijst. &Securities Financial security (e.g. stock, mutual fund) &Effecten Balance… Balance account Balans… Edit Security… Financial security (e.g. stock, mutual fund) Bewerk effecten… Remove Security Financial security (e.g. stock, mutual fund) Verwijder effecten Shares Bought… Financial shares Aandelen gekocht… Shares Sold… Financial shares Aandelen verkocht… Edit Quotations… Financial quotation Bewerk noteringen… The current file has been modified. Do you want to save it? Het huidige bestand is gewijzigd. Wilt u het bestand opslaan? Save file? Confirm Schedule Bevestig planning New Account Nieuwe rekening New Loan New Income Category Nieuwe inkomsten categorie New Expense Category Nieuwe uitgaven categorie Balance Account Balansrekening Book value: Boek waarde: of which %1 is balance adjustment Referring to account balance Real value: Echte waarde: Edit Account Bewerk rekening Edit Income Category Bewerk inkomsten categorie Edit Expense Category Bewerk uitgaven categorie Remove subcategories? Do you wish to remove the category including all subcategories? Move transactions? Verplaats transactie? Move to: Verplaatsen naar: Remove irreversibly from all accounts (do not do this if account has been closed!) The category contains some expenses. What do you want to do with them? De categorie bevat enkele uitgaven. Wat wil je er mee doen? The category contains some incomes. What do you want to do with them? De categorie bevat enkele inkomsten. Wat wil je er mee doen? The account contains some transactions. What do you want to do with them? Het account bevat enkele transacties. Wat wil je er mee doen? Remove Category? Verwijder categorie? The category contains some expenses that will be removed. Do you still want to remove the category? De categorie bevat enkele uitgaven die verwijderd zullen worden. Wil je nog steeds de categorie verwijderen? The category contains some incomes that will be removed. Do you still want to remove the category? De categorie bevat enkele inkomsten die verwijderd zullen worden. Wil je nog steeds de categorie verwijderen? Remove Account? Verwijder account? The account contains some transactions that will be removed. Do you still want to remove the account? De categorie bevat enkele transacties die verwijderd zullen worden. Wil je nog steeds de categorie verwijderen? %2 of %1 %1: budget; %2: remaining budget %2 van %1 Balance… Verb. Balance an account Balans… Shares Exchanged… Shares of one security directly exchanged for shares of another; Financial shares Aandelen verplaatst… Shares of one security directly exchanged for shares of another Financial shares Edit Quotes… Financial quote Bewerk noteringen… Balance Account Verb Balansrekening %1 (with no budget) %1 (zonder budget) %1 (with budget %2) %1 (met budget %2) EqonomizeCalendarWidget Today Vandaag EqonomizeDateEdit Today Vandaag EqonomizeTranslator OK Only used when Qt translation is missing OK Cancel Only used when Qt translation is missing Annuleren Close Only used when Qt translation is missing Sluiten Yes Only used when Qt translation is missing Ja No Only used when Qt translation is missing Nee &Yes Only used when Qt translation is missing &Ja &No Only used when Qt translation is missing &Nee &Open Only used when Qt translation is missing &Openen &Save Only used when Qt translation is missing Op&slaan &Select All Only used when Qt translation is missing Look in: Only used when Qt translation is missing Kijk in: File &name: Only used when Qt translation is missing Bestands&naam: Files of type: Only used when Qt translation is missing Bestanden van type: EqonomizeValueEdit Error Empty denominator. Empty factor. Division by zero. Unknown or ambiguous currency, or unrecognized characters, in expression: %1. Empty base. Empty exponent. Unrecognized characters in expression. ExportQIFDialog Export QIF File QIF-bestand exporteren Account: Rekening: All All accounts Alle Export transaction description as: Exporteer transactiebeschrijving als: Export transaction description as: Referring to generic description Exporteer transactiebeschrijving als: Payee Crediteur Memo Memo Subcategory Subcategorie Date format: Datumnotatie: Value format: Notatie van waarde: File: Bestand: Error Selected file is a directory. Geselecteerd bestand is een directory. Overwrite The selected file already exists. Would you like to overwrite the old copy? Het geselecteerde bestand bestaat al. Wil u de oude versie overschrijven? You selected a directory! U heeft een map geselecteerd! Couldn't open file for writing. Kan bestand niet openen voor schrijven. Error while writing file; file was not saved. Fout tijdens het schrijven van het bestand; bestand is niet opgeslagen. ImportCSVDialog Import CSV file Importeer CSV bestand Transaction Type Selection Selectie transactiesoort Expenses Uitgaven Incomes Inkomsten Transfers Overboekingen Expenses and incomes (negative cost) Uitgaven en inkomsten (negatieve kosten) Expenses and incomes (separate columns) Uitgaven en inkomsten (afgezonderde kolommen) All types Alle soorten Presets: File Selection Bestandselectie File: Bestand: First data row: Eerste gegevens rij: Auto Automatisch Column delimiter: Kolom scheiding: Comma Komma Tabulator Tabulator Semicolon Puntkomma Space Witruimte Other Overig Columns Specification Kolommen specificatie Save as preset… Imports data as expenses and incomes. Costs have negative value. Value is the only required column. Importeer gegevens als uitgaven en inkomsten. Kosten hebben negatieve waarde. Waarde is de enige vereiste kolom. Imports data as expenses and incomes. Costs and incomes have separate columns. Income and cost both all required columns. Importeer gegevens als uitgaven en inkomsten. Kosten en inkomsten hebben gescheiden kolommen. Inkomsten en kosten zijn beide vereiste kolommen. Warning The same column number is selected multiple times. Do you wish to proceed anyway? Description: Omschrijving: Description: Transaction description property (transaction title/generic article name) Omschrijving: Column Kolom Value Waarde Cost: Kosten: Date: Datum: Category: Categorie: From account: Van rekening: Quantity: Hoeveelheid: Payee: Crediteur: Tags: Labels: Comments: Opmerkingen: Create missing categories and accounts Maak ontbrekende categorieën en rekeningen Save Preset Imports data as expenses. Costs have positive value. Value is the only required column. Importeer gegevens als uitgaven. Kosten hebben positieve waarde. Waarde is de enige vereiste kolom. Imports data as incomes. Value is the only required column. Importeer gegevens als inkomsten. Waarde is de enige vereiste kolom. Income: Inkomsten: To account: Naar rekening: Payer: Debiteur: Imports data as transfers. Value is the only required column. Importeer gegevens als overboekingen. Waarde is de enige vereiste kolom. Amount: Hoeveelheid: Imports data as expenses and incomes. Costs have negative value. Value and category are both required columns. Importeer gegevens als uitgaven en inkomsten. Kosten hebben negatieve waarde. Waarde en categorie zijn beide vereiste kolommen. Value: Waarde: Account: Rekening: Payee/payer: Crediteur/debiteur: Imports data as expenses and incomes. Costs and incomes have separate columns. Income, cost, and category are all required columns. Importeer gegevens als uitgaven en inkomsten. Kosten en inkomsten hebben gescheiden kolommen. Inkomsten, kosten en categorie zijn alle vereiste kolommen. Imports data as expenses, incomes, and transfers. Costs have negative or positive value. Value, to, and from are all required columns. Accounts and categories must be existing. Importeer gegevens als uitgaven, inkomsten en overboekingen. Kosten hebben negatieve of positieve waarde. Waarde, naar en van zijn alle vereiste kolommen. Rekeningen en categorieën moeten bestaan. From: Van: To: Naar: Error A file must be selected. Er moet een bestand gelecteerd zijn. Selected file is a directory. Geselecteerd bestand is een directory. Selected file does not exist. Geselecteerd bestand bestaat niet. Empty delimiter. Leeg scheidingsteken. The same column number is selected multiple times. Hetzelfde kolomnummer is meerdere keren geselecteerd. Selected from account is the same as the to account. Geselecteerde Van Rekening is hetzelfde als de Naar Rekening. Invalid date. Ongeldige datum. Couldn't open %1 for reading. Kan bestand %1 niet openen om te lezen. Error reading %1. Fout bij lezen %1. Uncategorized Zonder categorie Successfully imported %n transaction(s). Er is %n transactie succesvol geïmporteerd. Er is %n transacties succesvol geïmporteerd. Unable to import any transactions. Het importeren van transacties is niet gelukt. Failed to import %n data row(s). Het importeren van %n rij met gegevens is niet gelukt. Het importeren van %n rijen met gegevens is niet gelukt. Required columns missing. Benodigde kolommen ontbreken. Invalid value. Ongeldige waarde. Empty category name. De naam van een categorie is leeg. Empty account name. De naam van een rekening is leeg. Unknown category found. Onbekende catagorie gevonden. Unknown account found. Er is een onbekende rekening aangetroffen. Cannot import security transactions (to/from security accounts). Kan geen effectentransacties importeren (van/naar effectenrekeningen). Balancing account wrongly used. Referring to the account used for adjustments of account balances. Balansrekening verkeerd gebuikt. Balancing account wrongly used. Balansrekening verkeerd gebuikt. Same to and from account/category. Rekening/Categorie van en naar zijn hetzelfde. No data found. Geen gegevens gevonden. Information Unrecognized date format. Onherkenbare datumnotatie. Specify Format Geef notatie aan The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. De notatie van datums en/of getallen in het CSV-bestand is niet eenduidig. Kies a.u.b. de juiste notatie. Date format: Datumnotatie: Value format: Notatie van waarde: ImportQIFDialog Import QIF file Importeer QIF-bestand File Selection Bestandselectie Select a QIF file to import. When you click next, the file be analysed and you might need to answer some questions about the format of the file. Kies een QIF-bestand om te importeren. Wanneer u op Volgende klikt, zal het bestand geanaliseerd worden, en zult u eventueel nog enkele vragen over de indeling van het bestand moeten beantwoorden. File: Bestand: Local Definitions Lokale definities Unknown elements where found in the QIF file. It is possible that this is because of localized type names. Please map them to the correct standard names. Er zijn onbekende elementen aangetroffen in het QIF-bestand. Mogelijk komt dit door gelokaliseerde type-namen. Geef alstublieft de juiste vertalingen naar standaardnamen aan. Local Text Lokale tekst Standard Text Standaardtekst Select standard text: Selecteer standaardtekst: Date Format Datumnotatie The date format in the QIF file is ambiguous. Please select the correct format. De datumnotatie in het QIF-bestand is niet eenduidig. Kies a.u.b. de juiste notatie. Date format: Datumnotatie: Default Account Standaard tegenrekening Could not find any account definitions in the QIF file. Please select a default account. It is also possible that this is caused by a localized opening balance text. Er zijn geen rekeningdefinities in het QIF-bestand aangetroffen. U kunt een terugval-rekening kiezen. Het is ook mogelijk dat dit probleem het gevolg is van een gelokaliseerde openingsbalanstekst. Default account: Standaard account: Opening balance text: Openingsbalanstekst: Descriptions Omschrijvingen Transactions in QIF files does not have any specific description property. You are therefore given the option to choose how the description of imported transactions will be set. Bij transacties in QIF-bestanden wordt geen omschrijving vermeld. U kunt aangeven welke omschrijving aan geïmporteerde transacties wordt toegevoegd. Subcategories as: Subcategorieën als: Description Omschrijving Transactions in QIF files does not have any specific description property. You are therefore given the option to choose how the description of imported transactions will be set. Referring to generic description Bij transacties in QIF-bestanden wordt geen omschrijving vermeld. U kunt aangeven welke omschrijving aan geïmporteerde transacties wordt toegevoegd. Category Categorie Ignore Negeer Payee as: Crediteur als: Payee Crediteur Memo as: Notitie als: Comments Beschrijving Priority: Prioriteit: Subcategory/Payee/Comments Subcategorie/Crediteur/Opmerkingen Payee/Subcategory/Comments Crediteur/Subcategorie/Opmerkingen Subcategory/Comments/Payee Subcategorie/Opmerkingen/Crediteur Payee/Comments/Subcategory Crediteur/Opmerkingen/Subcategorie Comments/Subcategory/Payee Opmerkingen/Subcategorie/Crediteur Comments/Payee/Subcategory Opmerkingen/Crediteur/Subcategorie Import File No (further) issues were found. Press finish to import the selected QIF file. Ignore duplicate transactions Error A file must be selected. Er moet een bestand gelecteerd zijn. Selected file is a directory. Geselecteerd bestand is een directory. Selected file does not exist. Geselecteerd bestand bestaat niet. Couldn't open %1 for reading. Kan bestand %1 niet openen om te lezen. Error reading %1. Fout bij lezen %1. Unknown Onbekend Account Rekening Bank Bank Cash Contant geld Cat (Category) Cat (Categorie) CCard (Credit Card) CCard (Creditcard) Invst (Investment) Invst (Investering) Oth A (Other Assets) Oth A (Overige Activa) Oth L (Other Liabilities) Oth L (Overige Passiva) Security Beveiliging Other Overig Unrecognized date format. Onherkenbare datumnotatie. Successfully imported %n transaction(s). Er is %n transactie succesvol geïmporteerd. Er is %n transacties succesvol geïmporteerd. Successfully imported %n account(s). Er is %n rekening succesvol geïmporteerd. Er is %n rekeningen succesvol geïmporteerd. Successfully imported %n category/categories. Er is %n categorie succesvol geïmporteerd. Er is %n categorien succesvol geïmporteerd. %n duplicate transaction(s) was ignored. Er is %n duplicaat-transactie overgeslagen. Er is %n duplicaat-transacties overgeslagen. Failed to import %n transaction(s). Het importeren van %n transactie is mislukt. Het importeren van %n transacties is mislukt. %n security/securities were not imported. Financial security (e.g. stock, mutual fund) %n effect niet geïmporteerd. %n effecten niet geïmporteerd. %n security transaction(s) were not imported. Financial security (e.g. stock, mutual fund) Er is %n effectentransactie niet geïmporteerd. Er is %n effectentransacties niet geïmporteerd. %n security/securities were not imported. %n effect niet geïmporteerd. %n effecten niet geïmporteerd. %n security transaction(s) were not imported. Er is %n effectentransactie niet geïmporteerd. Er is %n effectentransacties niet geïmporteerd. Information Income Dividend: %1 Dividend: %1 Reinvested dividend: %1 Geherinvesteerd dividend: %1 LedgerDialog Account: Rekening: Edit Account… Bewerk Rekening… Export… Exporteren… Print… Afdrukken… Reconcile Accounting context Mark all as reconciled Accounting context Change: Accounting context Mutatie: R Header for account reconciled checkbox column Date Datum Type Type Description Omschrijving Name Naam Description Generic Description Omschrijving Account/Category Rekening/categorie Deposit Storting Withdrawal Opname Balance Balans Balance Account balance Saldo Payee/Payer Crediteur/debiteur Tags Labels Comments Beschrijving Deposit Money put into account Storting Withdrawal Money taken out from account Opname Balance Noun. Balance of an account Saldo New Nieuw Edit… Bewerk… Delete Verwijderen Join… join transactions together Samenvoegen… Split Up split up joined transactions Splitsen Edit Transaction(s)… Bewerk transactie(s)… Join Transactions… Transacties samenvoegen… Split Up Transaction Splits transacties Remove Transaction(s) Verwijder transactie(s) Mark as reconciled Reconciled: %1 (%2) Accounting context Book value: %1 (%2) Accounting context Boek waarde: %1 (%2) Error Invalid date. Opening date is after closing date. Closing date is before opening date. Empty transaction list. Lege transactielijst. Couldn't open file for writing. Kan bestand niet openen voor schrijven. Error while writing file; file was not saved. Fout tijdens het schrijven van het bestand; bestand is niet opgeslagen. Ledger Grootboek Transactions for %1 Transacties voor %1 Select Time Period From: Van: To: Naar: To date is before from date. Tot-datum ligt voor Vanaf-datum. Balance change: Account balance Delete transactions? Are you sure you want to delete all (%1) selected transactions? Wilt u alle (%1) geselecteerde transacties verwijderen? Cannot set the value of security transactions using the dialog for modifying multiple transactions. Financial security (e.g. stock, mutual fund) Met het scherm voor het wijzigen van meerdere transacties kunt u de waarde van beleggingstransacties niet instellen. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name); Financial security (e.g. stock, mutual fund) Kan de omschrijving van dividenden en effectentransacties niet wijzigen. Cannot change payer of dividends and security transactions. Financial security (e.g. stock, mutual fund) Kan de debiteur van dividenden en effectentransacties niet wijzigen. Opening balance Account balance Openingsbalans Account Balance Adjustment Current balance: Account balance Average balance: Account balance Account Balancing Balancing of an account Afletteren Balancing Balancing of an account Balans Balancing Account balancing Balans Cannot set the value of security transactions using the dialog for modifying multiple transactions. Met het scherm voor het wijzigen van meerdere transacties kunt u de waarde van beleggingstransacties niet instellen. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name) Kan de omschrijving van dividenden en effectentransacties niet wijzigen. Cannot change description of dividends and security transactions. Referring to the generic description property Kan de omschrijving van dividenden en effectentransacties niet wijzigen. Current debt: Total debt reduction: Total interest and fees: Number of transactions: Cannot change description of dividends and security transactions. Kan de omschrijving van dividenden en effectentransacties niet wijzigen. Cannot change payer of dividends and security transactions. Kan de debiteur van dividenden en effectentransacties niet wijzigen. Cannot change date of transactions that are part of a split transaction. Kan de datum van transacties die deel zijn van een gesplitste transactie niet wijzigen. Initial balance Openingsbalans Split Transaction Gesplitste transactie Debt Payment Ascending order Reduction Fee Interest Income Inkomsten Repayment Aflossing Expense Uitgaven Opening balance: Accounting context Openingsbalans: Closing balance: Accounting context Description Transaction description property (transaction title/generic article name) Omschrijving Cannot change description of dividends and security transactions. Referring to the Transaction description property (transaction title/generic article name) Kan de omschrijving van dividenden en effectentransacties niet wijzigen. Refund Terugstorten Balancing Balans Transfer Overboeking LinksWidget Remove Link Link verwijderen All Alle Remove Verwijderen MultiItemListViewItem Dividend Dividend Income Inkomsten Repayment Aflossing Expense Uitgaven Refund Terugstorten Securities Purchase Financial security (e.g. stock, mutual fund) Effecten aankopen Securities Sale Financial security (e.g. stock, mutual fund) Effecten verkopen Account Balance Adjustment Account Balancing Balancing of an account Afletteren Balancing Balancing of an account Balans Security Buy Effecten aankopen Security Sell Effecten verkopen Balancing Balans Transfer Overboeking MultipleTransactionsEditDialog Modify Transactions Transacties bewerken Description: Omschrijving: Name: Naam: Description: Transaction description property (transaction title/generic article name) Omschrijving: Amount: Hoeveelheid: Income: Inkomsten: Cost: Kosten: Date: Datum: Category: Categorie: Payer: Debiteur: Payee: Crediteur: New Income Category Nieuwe Inkomsten Categorie New Expense Category Nieuwe Uitgaven Categorie New Income Category… Nieuwe Inkomsten Categorie… New Expense Category… Nieuwe Uitgaven Categorie… Error No income category available. Geen beschikbare inkomsten categorie. No expense category available. Geen beschikbare uitgavencategorie. Invalid date. Ongeldige datum. OverTimeChart Save As… Opslaan als… Print… Afdrukken… Source: Bron: Incomes and Expenses Inkomsten en uitgaven Profits Winsten Expenses Uitgaven Incomes Inkomsten All Categories Combined Alle categorieën gecombineerd All Descriptions Combined Alle omschrijvingen gecombineerd Theme: Chart type: Line Chart Vertical Bar Chart Horizontal Bar Chart Stacked Bar Chart Default Standaard Tags Labels All Accounts Combined Alle rekeningen gecombineerd All Accounts Split Alle rekeningen apart All Subcategories and Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Alle subcategorieën en omschrijvingen gecombineerd All Descriptions Split Referring to the transaction description property (transaction title/generic article name) Alle omschrijvingen apart No description Referring to the transaction description property (transaction title/generic article name) Geen omschrijving All Payees/Payers Split Alle crediteuren/debiteuren apart No payee/payer Geen crediteur/debiteur All Tags Split Alle labels apart Other tags Andere labels Other payees/payers Andere crediteuren/debiteuren Other descriptions Referring to the transaction description property (transaction title/generic article name) Andere omschrijvingen Profits, %1 Winsten, %1 Assets Activa All Descriptions Combined Referring to the generic description property Alle omschrijvingen gecombineerd Assets and Liabilities Activa en passiva All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Alle omschrijvingen gecombineerd All Payees/Payers Combined Alle debiteuren/crediteuren gecombineerd All Accounts Alle rekeningen Start date: Begindatum: End date: Einddatum: Value: Waarde: Annual total Totaal per jaar Monthly total Totaal per maand Daily average Gemiddeld per dag Quantity Hoeveelheid Average value Gemiddelde waarde All Payers Combined Alle debiteuren gecombineerd All Payees Combined Alle crediteuren gecombineerd All Subcategories Split Alle subcategorieën apart All Descriptions Split Referring to the generic description property Alle omschrijvingen apart No description Referring to the generic description property Geen omschrijving Value Waarde Includes budgeted transactions Inclusief gebudgetteerde transacties Incomes − Expenses, %1 Inkomsten − uitgaven, %1 Incomes − Expenses Inkomsten − uitgaven Incomes & Expenses Inkomsten en uitgaven Incomes: %1 Inkomsten: %1 Expenses: %1 Uitgaven: %1 %2: %1 %2: %1 Incomes: %2, %1 Inkomsten: %2, %1 Expenses: %2, %1 Uitgaven: %2, %1 %3: %2, %1 %3: %2, %1 %2, %1 %2, %1 Incomes: %3, %2, %1 Inkomsten: %3, %2, %1 Expenses: %3, %2, %1 Uitgaven: %3, %2, %1 %4: %3, %2, %1 %4: %3, %2, %1 no payee/payer geen crediteur/debiteur %3, %2, %1 %3, %2, %1 Other accounts Andere rekeningen %1 Value: %2 Date: %3 %1 Waarde: %2 Datum: %3 MMMM yyyy Month and year All Descriptions Split Alle omschrijvingen apart All Payers Split Alle debiteuren apart All Payees Split Alle crediteuren apart No description Geen omschrijving No payer Geen debiteur No payee Geen crediteur All Categories Split Alle categorieën apart Error Invalid date. Ongeldige datum. Couldn't open file for writing. Kan bestand niet openen voor schrijven. Error while writing file; file was not saved. Fout tijdens het schrijven van het bestand; bestand is niet opgeslagen. Other payees Andere crediteuren Other payers Andere debiteuren Value (%1) Waarde (%1) Profit (%1) Winst (%1) Income (%1) Inkomsten (%1) Cost (%1) Uitgaven (%1) Time Tijd %1/%2 %1: Category; %2: Payee/Payer %1/%2 All Descriptions Combined Referring to the Transaction description property (transaction title/generic article name) Alle omschrijvingen gecombineerd All Descriptions Split Referring to the Transaction description property (transaction title/generic article name) Alle omschrijvingen apart No description Referring to the Transaction description property (transaction title/generic article name) Geen omschrijving Daily average value Dagelijks gemiddelde waarde Daily average profit Dagelijks gemiddelde winst Daily average income Dagelijks gemiddelde inkomsten Daily average cost Dagelijks gemiddelde kosten Average income Gemiddelde inkomsten Average cost Gemiddelde kosten Annual value Jaarlijkse waarde Annual profit Jaarlijkse winst Annual income Jaarlijkse inkomsten Annual cost Jaarlijkse kosten Monthly value Maandelijkse waarde Monthly profit Maandelijkse winst Monthly income Maandelijkse inkomsten Monthly cost Maandelijkse kosten Includes scheduled and budgeted transactions Inclusief geplande en gebudgetteerde transacties Includes scheduled transactions Inclusief geplande transacties Tags, %1 Labels, %1 Value: %1 Waarde: %1 Assets & Liabilities Activa en passiva Change: %1 Mutatie: %1 Excluding any profits or losses in trading of security shares Financial security (e.g. stock, mutual fund) Incomes & Expenses, %1 Inkomsten en uitgaven, %1 Incomes, %1 Inkomsten, %1 Expenses, %1 Uitgaven, %1 Incomes, %2: %1 Inkomsten, %2: %1 Expenses, %2: %1 Uitgaven, %2: %1 Incomes, %3: %2, %1 Inkomsten, %3: %2, %1 Expenses, %3: %2, %1 Uitgaven, %3: %2, %1 Incomes, %4: %3, %2, %1 Inkomsten, %4: %3, %2, %1 Expenses, %4: %3, %2, %1 Uitgaven, %4: %3, %2, %1 Liabilities Passiva no payer geen debiteur %1/%2 %1: Description; %2: Payer/Payer %1/%2 %1/%2 %1: Description; %2: Payee/Payer %1/%2 %1/%2 %1: Description; %2: Payer %1/%2 no payee geen crediteur %1/%2 %1: Description; %2: Payee %1/%2 OverTimeChartDialog Chart Grafiek OverTimeReport Save As… Opslaan als… Print… Afdrukken… Source: Bron: Profits Winsten Expenses Uitgaven Incomes Inkomsten Assets & Liabilities Activa en passiva Tags Labels All Categories Combined Alle categorieën gecombineerd All Descriptions Combined Alle omschrijvingen gecombineerd Columns: Kolommen: Categories Categorieën Total: Totaal: Value Waarde Daily Dagelijks Monthly Maandelijks Yearly Jaarlijks Quantity Hoeveelheid Average value Gemiddelde waarde No description Geen omschrijving All Descriptions Combined Referring to the generic description property Alle omschrijvingen gecombineerd No description Referring to the generic description property Geen omschrijving All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Alle omschrijvingen gecombineerd All Accounts Alle rekeningen No description Referring to the transaction description property (transaction title/generic article name) Geen omschrijving Error Couldn't open file for writing. Kan bestand niet openen voor schrijven. Error while writing file; file was not saved. Fout tijdens het schrijven van het bestand; bestand is niet opgeslagen. Average Profit Gemiddelde winst Incomes, %1 Inkomsten, %1 Average Income Gemiddelde inkomsten Expenses, %1 Uitgaven, %1 Average Cost Gemiddelde kosten Incomes, %2: %1 Inkomsten, %2: %1 Incomes: %1 Inkomsten: %1 Expenses, %2: %1 Uitgaven, %2: %1 Expenses: %1 Uitgaven: %1 Incomes, %3: %2, %1 Inkomsten, %3: %2, %1 Incomes: %2, %1 Inkomsten: %2, %1 Expenses, %3: %2, %1 Uitgaven, %3: %2, %1 Expenses: %2, %1 Uitgaven: %2, %1 Change: %1 Noun, how much the account balance has changed Mutatie: %1 Average Change Gemiddelde mutatie Change Noun, how much the account balance has changed Mutatie Value: %1 Waarde: %1 Year Jaar Month Maand Assets Activa Deposit Storting Withdrawal Opname Liabilities Passiva %2: %1 %2: %1 %1 %1 Average Value Gemiddelde waarde %3: %2, %1 %3: %2, %1 %2, %1 %2, %1 Daily Average Dagelijks gemiddelde Monthly Average Maandelijks gemiddelde Yearly Average Jaarlijks gemiddelde Subtotal Subtotaal Total Totaal Deposit Money put into account Storting Withdrawal Money taken out from account Opname Includes scheduled transactions Inclusief geplande transacties Adjusted for the average month / year (%1 / %2 days) Aangepast voor de gemiddelde maand / jaar (%1 / %2 dagen) All Categories Combined Referring to the generic description property Alle categorieën gecombineerd OverTimeReportDialog Report Rapportage QApplication Start with expenses list displayed Startweergave met de lijst van uitgaven Start with incomes list displayed Startweergave met de lijst van inkomsten Start with transfers list displayed Startweergave met de lijst van overboekingen Synchronize file Document to open Document om te openen %1 is already running. QObject Transfer Overboeking Dividend Dividend Income Inkomsten Expense Uitgaven Securities Purchase Financial security (e.g. stock, mutual fund) Effecten aankopen Securities Sale Financial security (e.g. stock, mutual fund) Effecten verkopen Security Buy Effecten aankopen Security Sell Effecten verkopen Debt Payment Split Transaction Gesplitste transactie RecurrenceEditWidget Enable recurrence Herhaal deze transactie Recurrence Rule Herhalingsregel Daily Dagelijks Weekly Wekelijks Monthly Maandelijks Yearly Jaarlijks Recur every Herhaal elke day(s) dag(en) week(s) on: week/weken op: month(s), after the start month maand(en), na de beginmaand Recur on the Herhaal op de 1st 1ste 2nd 2de 3rd 3de 4th 4de 5th 5de 6th 6de 7th 7de 8th 8ste 9th 9de 10th 10de 11th 11de 12th 12de 13th 13de 14th 14de 15th 15de 16th 16de 17th 17de 18th 18de 19th 19de 20th 20ste 21st 21ste 22nd 22ste 23rd 23ste 24th 24ste 25th 25ste 26th 26ste 27th 27ste 28th 28ste 29th 29ste 30th 30ste 31st 31ste Last Laatste 2nd Last Voorlaatste 3rd Last Op 2 na laatste 4th Last Op 3 na laatste 5th Last Op 4 na laatste day dag possibly on weekend mogelijk in het weekeinde but before weekend maar voor het weekeinde but after weekend maar na het weekeinde nearest weekend day year(s), after the start year jaar/jaren, na het beginjaar on nearest weekday Recur on day part before XXX of 'Recur on day XXX of month YYY' Herhaal op dag of part between XXX and YYY of 'Recur on day XXX of month YYY' On the Part before NNN in 'Recur on the NNN. WEEKDAY of MONTH' Herhaal op de of part between WEEKDAY and MONTH in 'Recur on NNN. WEEKDAY of MONTH' Recur on day # Herhaal op dag of the year part after NNN of 'Recur on day #NNN of the year' van het jaar Range… Geldigheidsperiode… Occurrences/Exceptions… Herhaligen/uitzonderingen… Exceptions… Uitzonderingen… Error No day of week selected for weekly recurrence. Geen dag van de week gekozen bij wekelijkse herhaling. Selected day will never occur with selected frequency and start date. De gekozen dag zal nooit voorkomen bij de gekozen frekwentie en begindatum. Selected day does not exist in selected month. De gekozen dag bestaat niet in de gekozen maand. RefundDialog Repayment Aflossing Refund Terugstorten Date: Datum: Cost: Kosten: Income: Inkomsten: Quantity returned: Hoeveelheid geretourneerd: Account: Rekening: Quantity: Hoeveelheid: Payee: Crediteur: Payer: Debiteur: Comments: Opmerkingen: Link Link the transactions together Link Join Join the transactions together Samenvoegen Error Zero value not allowed. Geen waarde niet toegestaan. Invalid date. Ongeldige datum. SecurityBuy Security: %1 (bought) Effecten: %1 (gekocht) Security: %1 (bought) Financial security (e.g. stock, mutual fund) Effecten: %1 (gekocht) SecuritySell Security: %1 (sold) Effecten: %1 (verkocht) Security: %1 (sold) Financial security (e.g. stock, mutual fund) Effecten: %1 (verkocht) SecurityTransactionsDialog Transactions for %1 Transacties voor %1 Date Datum Type Type Value Waarde Shares Financial shares Aandelen Shares Bought Financial shares Aandelen gekocht Shares Bought (Recurring) Financial shares Aandelen gekocht (herhalend) Dividend (Recurring) Dividend (herhalend) Dividend (Scheduled) Dividend (gepland) Reinvested Dividend (Recurring) Geherinvesteerd dividend (herhalend) Reinvested Dividend (Scheduled) Geherinvesteerd dividend (gepland) Shares Bought Fincancial shares Aandelen gekocht Shares Sold Financial shares Aandelen verkocht Shares Sold (Exchanged) Shares of one security directly exchanged for shares of another; Financial shares Aandelen verkocht (handel) Shares Bought (Exchanged) Shares of one security directly exchanged for shares of another; Financial shares Aandelen gekocht (handel) Shares Bought (Recurring) Fincancial shares Aandelen gekocht (herhalend) Shares Sold (Recurring) Financial shares Aandelen verkocht (herhalend) Shares Bought (Scheduled) Financial shares Aandelen gekocht (gepland) Shares Sold (Scheduled) Financial shares Aandelen verkocht (gepland) Shares Aandelen Edit… Bewerk… Delete Verwijderen Shares Bought Aandelen gekocht Shares Sold Aandelen verkocht Dividend Dividend Reinvested Dividend Geherinvesteerd dividend Shares Sold (Traded) Aandelen verkocht (handel) Shares Bought (Traded) Aandelen gekocht (handel) Shares Bought (Recurring) Aandelen gekocht (herhalend) Shares Sold (Recurring) Aandelen verkocht (herhalend) Shares Bought (Scheduled) Aandelen gekocht (gepland) Shares Sold (Scheduled) Aandelen verkocht (gepland) Recurring Dividend Herhalend dividend Scheduled Dividend Gepland dividend SplitListViewItem Dividend Dividend Income Inkomsten Repayment Aflossing Expense Uitgaven Refund Terugstorten Security Buy Effecten aankopen Security Sell Effecten verkopen Balancing Balans Transfer Overboeking TagButton no tags geen labels TagMenu New tag… Nieuw label… New Tag Nieuw label Tag: Label: TransactionEditDialog Edit Expense Kosten bewerken Edit Dividend Dividend bewerken Edit Income Inkomsten bewerken Edit Transfer Overboeking bewerken Edit Securities Purchase Financial security (e.g. stock, mutual fund) Gekochte effecten bewerken Edit Securities Sale Financial security (e.g. stock, mutual fund) Verkochte effecten bewerken Edit Reinvested Dividend Edit Securities Bought Gekochte effecten bewerken Edit Securities Sold Verkochte effecten bewerken TransactionEditWidget Security: Effecten: Cost: Kosten: Income: Inkomsten: Shares bought: Aandelen gekocht: Shares sold: Aandelen verkocht: All Alle Price per share: Prijs per aandeel: Date: Datum: Description: Omschrijving: Name: Naam: Amount: Hoeveelheid: Withdrawal: Money taken out from account Opname: New Security… Financial security (e.g. stock, mutual fund) Shares added: Financial shares Aandelen toegevoegd: Set security share value Total value: Totale waarde: Deposit: Money put into account Storting: Downpayment: Quantity: Hoeveelheid: From: Van: To: Naar: Category: Categorie: To account: Naar rekening: Payer: Debiteur: Payer of parent split transaction From account: Van rekening: Downpayment account: Payee: Crediteur: Payee of parent split transaction Lender: Tags: Labels: Associated file: Bijbehorend bestand: Select a file Open the file Comments: Opmerkingen: Related to: Label for linked transactions Links: New Security Financial security (e.g. stock, mutual fund) Nieuw effecten No security available. Financial security (e.g. stock, mutual fund) Geen effecten beschikbaar. New Tag Nieuw label Tag: Label: New Account Nieuwe Rekening New Income Category Nieuwe Inkomsten Categorie New Expense Category Nieuwe Uitgaven Categorie New Account… Nieuwe Rekening… New Income Category… Nieuwe Inkomsten Categorie… New Expense Category… Nieuwe Uitgaven Categorie… Security: Financial security (e.g. stock, mutual fund) Effecten: Shares bought: Financial shares Aandelen gekocht: Shares sold: Financial shares Aandelen verkocht: Price per share: Financial shares Prijs per aandeel: Description: Transaction description property (transaction title/generic article name) Omschrijving: Transaction title/generic article name Number of items included in the transaction. Entered cost is total cost for all items. Error No suitable account available. Geen geschikte rekening beschikbaar. No income category available. Geen beschikbare inkomsten categorie. No suitable account or income category available. Geen geschikte rekening of inkomsten categorie beschikbaar. No expense category available. Geen beschikbare uitgavencategorie. No security available. Geen effecten beschikbaar. Invalid date. Ongeldige datum. Cannot transfer money to and from the same account. Kan geen geld overmaken naar en van dezelde rekening. Downpayment must be less than total cost. Cannot create a regular transfer to/from a securities account. Van of naar een effectenrekening kan geen gewone overboeking worden ingevoerd. Cannot create a regular income to a securities account. Naar een effectenrekening kan geen gewoon inkomen worden geboekt. Zero shares not allowed. Nul effecten niet toegestaan. Zero value not allowed. Geen waarde niet toegestaan. Zero price per share not allowed. Het is niet toegestaan om een prijs per aandeel van nul in te voeren. Cannot create a regular expense from a securities account. Van een effectenrekening kan geen gewone uitgave worden geboekt. Loan for %1 TransactionFilterWidget From: Van: To: Naar: Min amount: Minimum bedrag: Max amount: Maximum bedrag: Category: Categorie: To account: Naar rekening: Min income: Minimum inkomen: Max income: Maximum inkomen: From account: Van rekening: Min cost: Minimum kosten: Max cost: Maximum kosten: Tag: Label: Description: Omschrijving: Description: Transaction description property (transaction title/generic article name) Omschrijving: Payer: Debiteur: Payee: Crediteur: Include Tonen Exclude Niet tonen Exact match Exclude subcategories Clear Wissen All Alle Error Invalid date. Ongeldige datum. To date is before from date. Tot-datum ligt voor Vanaf-datum. From date is after to date. Vanaf-datum ligt na Tot-datum. TransactionListWidget Date Datum Description Omschrijving Cost Kosten Category Categorie From Account Van rekening Payee Crediteur Tags Labels Income Inkomsten To Account Naar rekening Payer Debiteur Amount Bedrag From Vanaf To Tot Comments Beschrijving Add Toevoegen Apply Toepassen Delete Verwijderen * Part of <a href="%1">split transaction</a> * Deel van <a href="%1">gesplitste transactie</a> Expense Uitgaven Transfer Overboeking Name Naam Description Generic Description Omschrijving Description Transaction description property (transaction title/generic article name) Omschrijving New/Edit Expense Uitgave toevoegen/bewerken New/Edit Income Inkomsten toevoegen/bewerken New/Edit Transfer Overboeking toevoegen/bewerken Filter Filteren Quantity: Hoeveelheid: Total: Totaal: Average: Gemiddeld: Clear Wissen Cost: Kosten: Monthly: Per maand: Sort by creation time Expenses Uitgaven Incomes Inkomsten Transfers Overboekingen Quantity Hoeveelheid Right align Rechts uitlijnen Total cost: Totaal uitgaven: Total income: Totaal inkomsten: Total amount: Totaal bedrag: Monthly average: Maandelijks gemiddelde: Error Cannot set the value of security transactions using the dialog for modifying multiple transactions. Financial security (e.g. stock, mutual fund) Met het scherm voor het wijzigen van meerdere transacties kunt u de waarde van beleggingstransacties niet instellen. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name); Financial security (e.g. stock, mutual fund) Kan de omschrijving van dividenden en effectentransacties niet wijzigen. Cannot change payer of dividends and security transactions. Financial security (e.g. stock, mutual fund) Kan de debiteur van dividenden en effectentransacties niet wijzigen. Cannot change date of transactions that are part of a split transaction, unless all individual transactions are selected. Cannot set the value of security transactions using the dialog for modifying multiple transactions. Met het scherm voor het wijzigen van meerdere transacties kunt u de waarde van beleggingstransacties niet instellen. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name) Kan de omschrijving van dividenden en effectentransacties niet wijzigen. Cannot change date, description, expense category or payee of transactions that are part of a debt payment using the dialog for modifying multiple transactions. Referring to the transaction description property (transaction title/generic article name) Cannot change description of dividends and security transactions. Referring to the Transaction description property (transaction title/generic article name) Kan de omschrijving van dividenden en effectentransacties niet wijzigen. Cannot change description of dividends and security transactions. Referring to the generic description property Kan de omschrijving van dividenden en effectentransacties niet wijzigen. Cannot change description of dividends and security transactions. Kan de omschrijving van dividenden en effectentransacties niet wijzigen. Cannot change payer of dividends and security transactions. Kan de debiteur van dividenden en effectentransacties niet wijzigen. Cannot change date of transactions that are part of a split transaction. Kan de datum van transacties die deel zijn van een gesplitste transactie niet wijzigen. Delete transactions? Are you sure you want to delete all (%1) transactions in the selected split transaction? Weet u zeker dat u alle (%1) transacties in de geselecteerde gesplitste transactie wilt verwijderen? Join as multiple accounts/payments? Do you wish join the selected expenses as an expense with multiple accounts/payments? Do you wish join the selected incomes as an income with multiple accounts/payments? Are you sure you want to delete all (%1) selected transactions? Wilt u alle (%1) geselecteerde transacties verwijderen? * Part of split transaction * Deel van gesplitste transactie * Part of split (%1) * Deel van splitsing (%1) ** Recurring (editing occurrence) ** Herhalend (individuele gebeurtenis wordt bewerkt) Modify… Wijzigen… Edit… Bewerk… Eqonomize-1.5.3/translations/eqonomize_pt.ts000066400000000000000000021035521416454732000213060ustar00rootroot00000000000000 Balancing Balanço kde-format Couldn't open %1 for reading Impossível abrir %1 para leitura kde-format Not a valid Eqonomize! file (XML parse error: "%2" at line %3, col %4) Ficheiro Eqonomize! inválido (Erro de análise XML: "%2" na linha %3, coluna %4) kde-format Invalid root element %1 in XML document Elemento raíz inválido %1 no documento XML kde-format Unable to load 1 account. Impossível carregar 1 conta Impossível carregar %n contas. kde-format Unable to load %n accounts. Unable to load 1 category. Impossível carregar 1 categoria. Impossível carregar %n categorias. kde-format Unable to load %n categories. Unable to load 1 security. Impossível carregar 1 segurança. Impossível carregar %n seguranças. kde-format Unable to load %n securities. Unable to load 1 transaction. Impossível carregar 1 transacção. Impossível carregar %n transacções. kde-format Unable to load %n transactions. File is a directory O ficheiro é uma pasta kde-format Couldn't open file for writing Impossível abrir o ficheiro para escrita kde-format Error while writing file; file was not saved Erro quando tentava gravar o ficheiro: ficheiro não gravado kde-format From De kde-format To até kde-format Source: Fonte: kde-format All Expenses Todas as despesas kde-format All Incomes Todas as receitas kde-format All Accounts Todas as contas kde-format Expenses: %1 Despesas: %1 kde-format Incomes: %1 Receitas: %1 kde-format Invalid date. Data inválida. kde-format To date is before from date. Data final anterior à data inicial. kde-format From date is after to date. Data inicial posterior à data final. kde-format The selected file already exists. Would you like to overwrite the old copy? O ficheiro selecionado já existe. Deseja substituir a cópia antiga? kde-format You selected a directory! Selecionou uma pasta! kde-format Couldn't open file for writing. Impossível abrir o ficheiro para escrita. kde-format Error while writing file; file was not saved. Erro ao gravar o ficheiro: ficheiro não gravado. kde-format No description Sem descrição kde-format All Categories Todas as categorias kde-format Descriptions for Descrições para kde-format Payees/payers for Beneficiários/pagadores para kde-format Period: Período: kde-format Columns: Colunas kde-format Value Valor kde-format Daily Diariamente kde-format Monthly Mensalmente kde-format Yearly Anualmente kde-format Quantity Quantidade kde-format Average value Valor médio kde-format All descriptions Todas as descrições kde-format All payees Todos os beneficiários kde-format All payers Todos os pagadores kde-format No payee Sem beneficiário kde-format No payer Sem pagador kde-format Expenses: %2, %1 Despesas: %2, %1 kde-format Incomes: %2, %1 Rendimentos: %2, %1 kde-format Incomes & Expenses Rendimentos & Despesas kde-format %1 (%2&ndash;%3) html format; %1: title; %2: from date; %3: to date %1 (%2&ndash;%3) kde-format %1 (to %2) html format; %1: title; %2: to date %1 (à %2) kde-format Category Categoria kde-format Cost Custo kde-format Income Receita kde-format Daily Average Média diária kde-format Monthly Average Média mensal kde-format Yearly Average Média anual kde-format Average Cost Custo médio kde-format Average Income Rendimento médio kde-format Average Value Valor médio kde-format Total Total kde-format Total incomes Total de receitas kde-format Total expenses Total de despesas kde-format Total (Profits) Total (lucros) kde-format Expense Despesa kde-format Transfer Transferência kde-format Security Buy Compra de seguranças kde-format Security Sell Venda de seguranças kde-format Recurrence Recorrência kde-format New Expense Nova despesa kde-format New Dividend Novo dividendo kde-format New Income Nova receita kde-format New Transfer Nova transferência kde-format New Security Buy Nova compra segura kde-format New Security Sell Nova venda segura kde-format Edit Expense Editar despesa kde-format Edit Dividend Editar dividendo kde-format Edit Income Editar receita kde-format Edit Transfer Editar transferência kde-format Edit Securities Bought Editar seguranças compradas kde-format Edit Securities Sold Editar seguranças vendidas kde-format Dividend Dividendo kde-format Repayment Repagamento kde-format Refund Reembolsar kde-format Split Transaction Dividir transação kde-format Description: Descrição: kde-format Date: Data: kde-format Account: Conta: kde-format Transactions: Transações kde-format Type Tipo kde-format Description Descrição kde-format Account/Category Conta/Categoria kde-format Payment Pagamento kde-format Deposit Depósito kde-format New Novo kde-format New Expense… Nova despesa… kde-format New Income… Nova receita… kde-format New Deposit… Novo depósito kde-format New Withdrawal… Novo levantamento… kde-format New Security Shares Bought… Novas ações seguras compradas kde-format Security Shares Sold… Venda de ações de segurança kde-format New Dividend… Novo dividendo… kde-format Edit… Editar… kde-format Total value: Valor total: kde-format No suitable account available. Sem conta adequada disponível kde-format Future dates is not allowed. Não são permitidas datas futuras. kde-format A split must contain at least two transactions. Uma divisão tem de conter pelo menos duas transacções kde-format Cannot transfer money to and from the same account. Não pode ser transferido dinheiro de e para a mesma conta kde-format Cost: Custo: kde-format Income: Receita: kde-format Quantity: Quantidade: kde-format Comments: Comentários: kde-format Reinvested Dividend Dividendos reinvestidos kde-format Security: Segurança: kde-format Shares added: Ações adicionadas: kde-format Security Trade Transação segura kde-format From security: De segurança: kde-format Shares moved: Ações movidas: kde-format All Todas kde-format To security: Para segurança: kde-format Shares received: Ações recebidas: kde-format Value: Valor: kde-format No other security available for trade in the account. Sem outra segurança disponível na conta para trocar. kde-format Selected to and from securities are the same. Seguranças seleccionadas de e para são as mesmas. kde-format Zero shares not allowed. Zero ações não é permitido kde-format Zero value not allowed. Valor zero não permitido kde-format Quotations Cotações kde-format Date Data kde-format Price per Share Preço por ação kde-format Quotations for %1 Cotações para %1 kde-format The following transactions was scheduled to occur today or before today. Confirm that they have indeed occurred (or will occur today). As seguintes transacções foram agendadas para ocorrerem hoje ou antes de hoje. Confirme se elas ocorreram (ou se irão ocorrer hoje). kde-format Amount Montante kde-format Postpone… Adiar… kde-format Can only postpone to future dates. Só pode adiar para datas futuras kde-format Transactions for %1 Transações para %1 kde-format Shares Ações kde-format Shares Bought Ações compradas kde-format Shares Sold Ações vendidas kde-format Shares Sold (Traded) Ações vendidas (trocadas) kde-format Shares Bought (Traded) Ações compradas (trocadas) kde-format Shares Bought (Recurring) Ações compradas (recorrente) kde-format Shares Sold (Recurring) Ações vendidas (recorrente) kde-format Shares Bought (Scheduled) Ações compradas (agendado) kde-format Shares Sold (Scheduled) Ações vendidas (agendado) kde-format Recurring Dividend Dividendos recorrentes kde-format Scheduled Dividend Dividendos agendados kde-format Type: Tipo: kde-format Mutual Fund Fundo mútuo kde-format Bond Ação kde-format Stock Cotações kde-format Other Outro kde-format Name: Nome: kde-format Decimals in Shares: Decimais em ações kde-format Initial Shares: Ações iniciais kde-format Initial quotation: Cotação inicial: kde-format No suitable account or income category available. Não há conta ou categoria de rendimento apropriadas disponíveis kde-format Cash Dinheiro kde-format Current Account Conta corrente kde-format Savings Account Conta Poupanças kde-format Credit Card Cartão de crédito kde-format Liabilities Passivos kde-format Securities Seguranças kde-format Initial balance: Balanço Inicial kde-format Default account for budgeted transactions Conta predefinida para transações orçamentadas kde-format Empty name. Nome em branco kde-format The entered name is used by another account. O nome escolhido é utilizado por outra conta kde-format Monthly budget: Orçamento mensal kde-format The entered name is used by another income category. O nome introduzido é utilizado por outra categoria de receitas kde-format The entered name is used by another expense category. O nome introduzido é utilizado por outra categoria de despesa kde-format Accounts Contas kde-format Accounts & Categories Contas & Categorias kde-format Expenses Despesas kde-format Incomes Receitas kde-format Transfers Transferências kde-format Schedule Agenda kde-format Scheduled Transactions Transações agendadas kde-format Account / Category Conta/Categoria kde-format Remaining Budget (%1) Saldo remanescente (%1) kde-format Change (%1) Mudança (%1) kde-format Total (%1) Total (%1) kde-format %2 of %1 %2 remains of %1 budget %2 de %1 kde-format Includes budgeted transactions Incluir transações orçamentadas. kde-format Period Período kde-format Select Period Seleccionar período kde-format Current Month Mês Atual kde-format Current Year Ano atual kde-format Current Whole Month Todo o mês atual kde-format Current Whole Year Todo o ano atual kde-format Whole Past Month Todo o mês passado kde-format Whole Past Year Todo o ano passado kde-format Previous Month Mês anterior kde-format Previous Year Ano Passado kde-format Show partial budget Mostrar orçamento parcial kde-format Edit Budget Editar orçamento kde-format Budget: Orçamento: kde-format Month: Mês: kde-format Result previous month: Resultados do mês anterior: kde-format New Security… Nova segurança … kde-format New Transaction Nova transação kde-format Set Quotation… Definir cotação kde-format Name Nome kde-format Quotation Cotação kde-format Profit Lucro kde-format Yearly Rate Taxa anual kde-format Account Conta kde-format Statistics Period Estatísticas do período kde-format New Schedule Novo agendamento kde-format Edit Editar kde-format Next Occurrence Ocorrência Seguinte kde-format Comments Comentários kde-format New Security Nova segurança kde-format Edit Security Editar segurança kde-format Profit: Lucro: kde-format Rate: Taxa: kde-format Are you sure you want to delete the security "%1" and all associated transactions? Tem a certeza que quer apagar a segurança "%1" e todas as transações associadas? kde-format No security available. Sem segurança disponível kde-format Set Quotation (%1) Definir cotação (%1) kde-format Price per share: Preço por ação: kde-format Future dates are not allowed. Datas futuras não são permitidas. kde-format Security Transactions Transações seguras kde-format Ledger Diário kde-format Untitled Sem título kde-format Check Account Verificar conta kde-format Salary Salário kde-format Bills Contas kde-format Clothing Roupas kde-format Groceries Mercearias kde-format Leisure Lazer kde-format Couldn't fetch %1. Impossível obter %1. kde-format Error loading %1: %2. Erro ao carregar %1: %2. kde-format Couldn't open file Impossível abrir o ficheiro kde-format Error saving %1: %2. Erro ao gravar %1: %2. kde-format Couldn't save file Não pode gravar o ficheiro kde-format Failed to upload file to %1. Falha ao enviar ficheiro para %1. kde-format Report Relatório kde-format Chart Gráfico kde-format Transaction Schedule Agendamento de transação kde-format Accounts &amp; Categories html format Contas &amp; Categorias kde-format Accounts &amp; Categories (%1&ndash;%2) html format Contas &amp; Categorias (%1&ndash;%2) kde-format Accounts &amp; Categories (to %1) html format Contas &amp;Categorias (para %1) kde-format Change Alterar kde-format Balance Balanço kde-format Budget Orçamento kde-format Remaining Budget Orçamento restante kde-format Total Incomes Total de receitas kde-format Costs Custos kde-format Total Expenses Total de despesas kde-format Empty expenses list. Lista de despesas vazia. kde-format Empty incomes list. Lista de receitas vazia. kde-format Empty transfers list. Lista de tranferências vazia. kde-format Empty securities list. Lista de seguranças vazia. kde-format Empty schedule list. Lista de agendamentos vazia. kde-format Export View… Vista Exportação kde-format Print View… Imprimir… kde-format Initial Period Período inicial kde-format Remember Last Dates Lembrar ultimas datas kde-format Import CSV File… Importar ficheiro CSV kde-format Import QIF File… Importar ficheiro QIF kde-format Export As QIF File… Exportar como ficheiro QIF… kde-format Add Account… Adicionar conta… kde-format New Account… Nova conta… kde-format New Income Category… Nova categoria de receitas kde-format New Expense Category… Nova categoria de despesas… kde-format Balance… Balanço… kde-format Show Transactions Mostrar transações kde-format New Transfer… Nova transferência… kde-format New Split Transaction… Nova transação dividida kde-format Edit Transaction(s) (Occurrence)… Editar transações (ocorrência)… kde-format Edit Occurrence… Editar ocorrência… kde-format Edit Schedule (Recurrence)… Editar agenda (recorrência)… kde-format Edit Schedule… Editar agenda… kde-format Remove Transaction(s) (Occurrence) Remover transações (ocorrência) kde-format Remove Occurrence Remover ocorrência kde-format Delete Schedule (Recurrence) Apagar agendamento (recorrência) kde-format Delete Schedule Apagar agendamento kde-format Edit Split Transaction… Editar transação dividida… kde-format Remove Split Transaction Remover transação dividida kde-format Join Transactions… Unir transações… kde-format Split Up Transaction Dividir transação kde-format Refund… Reembolsar… kde-format Repayment… Retribuição… kde-format New Refund/Repayment… Novo reembolso/retribuição… kde-format Edit Security… Editar segurança… kde-format Remove Security Remover segurança kde-format Shares Sold… Ações vendidas… kde-format Shares Bought… Ações compradas… kde-format Dividend… Dividendo… kde-format Reinvested Dividend… Dividendo reinvestido kde-format Shares Moved… Ações movidas… kde-format Edit Quotations… Editar cotações… kde-format Transactions… Transações… kde-format Development Over Time Report… Relatório de desenvolvimento ao longo do tempo kde-format Categories Comparison Report… Relatório comparativo de categorias… kde-format Categories Comparison Chart… Gráfico comparativo de categorias… kde-format Development Over Time Chart… Gráfico de desenvolvimento ao longo do tempo kde-format Use Additional Transaction Properties Usar propriedades adicionais da transação kde-format Eqonomize! exited unexpectedly before the file was saved and data was lost. Do you want to load the last auto-saved version of the file? Eqonomize! saiu inesperadamente antes do ficheiro ser gravado e os dados foram perdidos. Quer carregar a última gravação automática do ficheiro? kde-format Crash Recovery Recuperação de erro kde-format The current file has been modified. Do you want to save it? O ficheiro atual foi modificado. Quer gravá-lo? kde-format Confirm Schedule Confirmar agendamento kde-format New Account Nova conta kde-format New Income Category Nova categoria de receitas kde-format New Expense Category Nova categoria de despesas kde-format Balance Account Conta Balanço kde-format Book value: Valor contabilístico: kde-format Real value: Valor real: kde-format Edit Account Editar conta kde-format Edit Income Category Editar categoria de receitas kde-format Edit Expense Category Editar categoria de despesas kde-format Move transactions? Mover transações? kde-format Move to: Mover para: kde-format The category contains some expenses. What do you want to do with them? A categoria contém algumas despesas. O que lhes deseja fazer? kde-format The category contains some incomes. What do you want to do with them? A categoria contém algumas receitas. O que lhes deseja fazer? kde-format The account contains some transactions. What do you want to do with them? A conta contém algumas transações. O que lhes deseja fazer? kde-format The category contains some expenses that will be removed. Do you still want to remove the category? A categoria contém algumas despesas que serão removidas. Quer remover a categoria, mesmo assim? kde-format Remove Category? Remover categoria? kde-format The category contains some incomes that will be removed. Do you still want to remove the category? A categoria contém algumas receitas que serão removidas. Quer remover a categoria, mesmo assim? kde-format The account contains some transactions that will be removed. Do you still want to remove the account? A conta contém algumas transações que serão removidas. Quer remover a conta, mesmo assim? kde-format Remove Account? Remover conta? kde-format %2 of %1 %1: budget; %2: remaining budget %2 de %1 kde-format %1 (with no budget) %1 (não orçamentada) kde-format %1 (with budget %2) %1 (com orçamento %2) kde-format Import CSV file Importar ficheiro CSV kde-format Transaction Type Selection Seleção do tipo de transação kde-format Expenses and incomes (negative cost) Despesas e receitas (custo negativo) kde-format Expenses and incomes (separate columns) Despesas e receitas (colunas separadas) kde-format All types Todos os tipos kde-format File Selection Selecção de ficheiros kde-format File: Ficheiro: kde-format First data row: Primeira linha de dados kde-format Auto Automático kde-format Column delimiter: Delimitador de coluna kde-format Comma Vírgula kde-format Tabulator Tabulador kde-format Semicolon Ponto e vírgula kde-format Space Espaço kde-format Columns Specification Especificação das colunas kde-format Column Coluna kde-format Category: Categoria: kde-format From account: Da conta: kde-format Create missing categories and accounts Criar categorias e contas em falta kde-format Imports data as expenses. Costs have positive value. Value is the only required column. Importar dados como despesas. Custos têm valor positivo. Valor é a única coluna requerida. kde-format Imports data as incomes. Value is the only required column. Importar dados como receitas. Valor é a única coluna requerida. kde-format To account: Para a conta: kde-format Imports data as transfers. Value is the only required column. Importar dados como transferências. Valor é a única coluna requerida. kde-format Amount: Montante: kde-format Imports data as expenses and incomes. Costs have negative value. Value and category are both required columns. Importar dados como despesas e receitas. Custos têm valor negativo. Valor e categoria são ambas colunas requeridas. kde-format Imports data as expenses and incomes. Costs and incomes have separate columns. Income, cost, and category are all required columns. Importar dados como despesas e receitas. Custos e receitas têm colunas separadas. Receitas, custos e categoria são todas colunas requeridas. kde-format Imports data as expenses, incomes, and transfers. Costs have negative or positive value. Value, to, and from are all required columns. Accounts and categories must be existing. Importar dados como despesas receitas e transferências. Custos têm valor negativo ou positivo. Valor, De e Para são todas colunas requeridas. Contas e categorias têm de existir. kde-format From: De: kde-format To: Para: kde-format A file must be selected. Deve selecionar um ficheiro. kde-format Selected file is a directory. O ficheiro selecionado é uma pasta. kde-format Selected file does not exist. O ficheiro selecionado não existe. kde-format Empty delimiter. Delimitador vazio kde-format The same column number is selected multiple times. O mesmo número de coluna é selecionado múltiplas vezes. kde-format Selected from account is the same as the to account. A seleção Da conta é a mesma que Para a conta. kde-format Couldn't open %1 for reading. Impossível abrir %1 para leitura. kde-format Error reading %1. Erro ao ler %1. kde-format Successfully imported 1 transaction. Importou com sucesso 1 transação. Importou com sucesso %n transações. kde-format Successfully imported %n transactions. Unable to import any transactions imported. Impossível importar quaisquer transações importadas kde-format Failed to import 1 data row. Falha ao importar 1 linha de dados Falha ao importar %n linhas de dados kde-format Failed to import %n data rows. Required columns missing. Faltam colunas requeridas kde-format Invalid value. Valor inválido. kde-format Empty category name. Nome de categoria vazio. kde-format Empty account name. Nome de conta vazio. kde-format Unknown category found. Encontrada categoria desconhecida. kde-format Unknown account found. Encontrada conta desconhecida. kde-format Cannot import security transactions (to/from security accounts). Impossível importar transações de seguranças (de/para contas Segurança). kde-format Balancing account wrongly used. Conta Balanço usada erradamente kde-format Same to and from account/category. Mesma De e Para conta/categoria kde-format No data found. Não foram encontrados dados kde-format Unrecognized date format. Formato de data não reconhecido. kde-format Specify Format Especifique formato kde-format The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. O formato de datas e/ou números no ficheiro CSV é ambíguo. Por favor selecione o formato correto. kde-format Date format: Formato da data: kde-format Value format: Formato do valor: kde-format tomorrow the day after today amanhã kde-format today this day hoje kde-format yesterday the day before today ontem kde-format &Today @option today &Hoje kde-format To&morrow @option tomorrow A&manhã kde-format Next &Week @option next week &Semana seguinte kde-format Next M&onth @option next month Mês s&eguinte kde-format No Date @option do not specify a date Sem data kde-format Export… Exportar… kde-format Print… Imprimir… kde-format Withdrawal Levantamento kde-format Join… Juntar… kde-format Split Up Dividir… kde-format Empty transaction list. Lista de transações vazia. kde-format Are you sure you want to delete all (%1) selected transactions? Tem a certeza que quer apagar todas (%1) as transações selecionadas? kde-format Cannot set the value of security transactions using the dialog for modifying multiple transactions. Impossível definir o valor de transações de seguranças usando o diálogo para modificar múltiplas transações. kde-format Cannot change description of dividends and security transactions. Impossível mudar a descrição de transações de dividendos e seguranças. kde-format Cannot change payer of dividends and security transactions. Impossível alterar o pagador de transações de dividendos e seguranças. kde-format Cannot change date of transactions that are part of a split transaction. Impossível alterar a data de transações que fazer parte de uma transação dividida. kde-format Eqonomize! Eqonomize! A personal accounting program Um programa de finanças pessoais Start with expenses list displayed Iniciar com a lista de despesas mostrada Start with incomes list displayed Iniciar com a lista de receitas mostrada Start with transfers list displayed Iniciar com a lista de transferências mostrada Document to open Documento a abrir Incomes and Expenses Receitas e despesas kde-format Profits Lucros kde-format All Categories Combined Todas as categorias combinadas kde-format All Descriptions Combined Todas as descrições combinadas kde-format All Payees/Payers Combined Todos os beneficiários/pagadores combinados kde-format Start date: Data inicial: kde-format End date: Data final: kde-format Monthly total Total mensal kde-format Daily average Média diária kde-format All Payers Combined Todos os pagadores combinados kde-format All Payees Combined Todos os beneficiários combinados kde-format All Descriptions Split Todas as descições divididas kde-format All Payers Split Todos os pagadores divididos kde-format All Payees Split Todos os beneficiários divididos kde-format All Categories Split Todas as categorias divididas kde-format Value (%1) Valor (%1) kde-format Profit (%1) Lucro (%1) kde-format Income (%1) Receita (%1) kde-format Cost (%1) Custo (%1) kde-format Time Horas kde-format no payer sem pagador kde-format %1/%2 %1: Description; %2: Payer %1/%2 kde-format no payee sem beneficiário kde-format %1/%2 %1: Description; %2: Payee %1/%2 kde-format Error after saving file; data may not have been saved. Erro após gravar o ficheiro: Os dados podem não ter sido gravados. kde-format Average Profit Lucro médio kde-format Year Ano kde-format Month Mês kde-format Includes scheduled transactions Inclui transações agendadas kde-format Adjusted for the average month / year (%1 / %2 days) Ajustado para a média mensal/anual (%1/ %2 dia) kde-format Subtotal Subtotal kde-format Unnamed Sem nome kde-format Uncategorized Sem categoria kde-format Import QIF file Importar ficheiro QIF kde-format Select a QIF file to import. When you click next, the file be analysed and you might need to answer some questions about the format of the file. Selecione o ficheiro QIF a importar. Ao selecionar próximo, o ficheiro será analisado e poderá ser necessário responder a algumas questões sobre o formato do ficheiro. kde-format Local Definitions Definições locais kde-format Unknown elements where found in the QIF file. It is possible that this is because of localized type names. Please map them to the correct standard names. Foram encontrados elementos desconhecidos no ficheiro QIF. É possível que tenha a ver com nomes de tipos localizados. Por favor corrija-os para os nomes padrão. kde-format Local Text Texto local kde-format Standard Text Texto normal kde-format Select standard text: Selecione o texto normal: kde-format Date Format Formato da data kde-format The date format in the QIF file is ambiguous. Please select the correct format. O formato da data no ficheiro é ambíguo. Por favor, seleccione o formato correto. kde-format Default Account Conta predefinida kde-format Could not find any account definitions in the QIF file. Please select a default account. It is also possible that this is caused by a localized opening balance text. Impossível encontrar definições de conta no ficheiro QIF. Por favor selecione uma conta predefinida. É possível que o motivo seja um texto localizado no Balanço de abertura. kde-format Default account: Conta predefinida: kde-format Opening balance text: Texto do balanço de abertura: kde-format Descriptions Descrições kde-format Transactions in QIF files does not have any specific description property. You are therefore given the option to choose how the description of imported transactions will be set. As transações nos ficheiros QIF não têm propriedades descritivas específicas. Logo, é-lhe dada a opção de escolher como será definida a descrição das transações importadas. kde-format Subcategories as: Subcategorias como: kde-format Ignore Ignorar kde-format Payee as: Beneficiário como: kde-format Payee Beneficiário kde-format Memo as: Memorando como: kde-format Priority: Prioridade: kde-format Subcategory/Payee/Comments Subcategoria/Beneficiário/Comentários kde-format Payee/Subcategory/Comments Beneficiário/Subcategoria/Comentários kde-format Subcategory/Comments/Payee Subcategoria/Comentários/Beneficiário kde-format Payee/Comments/Subcategory Beneficiário/Comentários/Subcategoria kde-format Comments/Subcategory/Payee Comentários/Subcategoria/Beneficiário kde-format Comments/Payee/Subcategory Comentários/Beneficiário/Subcategoria kde-format Unknown Desconhecido kde-format Bank Banco kde-format Cat (Category) Cat (Categoria) kde-format CCard (Credit Card) CCred (Cartão de crédito) kde-format Invst (Investment) Invst (Investimento) kde-format Oth A (Other Assets) Out A (Outros ativos) kde-format Oth L (Other Liabilities) Out P (Outros passivos) kde-format Security Segurança kde-format Successfully imported 1 account. Importou com sucesso 1 conta. Importou com sucesso %n contas. kde-format Successfully imported %n accounts. Successfully imported 1 category. Importou com sucesso 1 categoria. Importou com sucesso %n categorias. kde-format Successfully imported %n categories. 1 duplicate transaction was ignored. Foi ignorada 1 transação duplicada. Foram ignoradas %n transações duplicadas. kde-format %n duplicate transactions was ignored. Failed to import 1 transaction. Falhou a importação de 1 transação. Falhou a importação de %n transações. kde-format Failed to import %n transactions. 1 security was not imported. Não foi importada 1 segurança Não foram importadas %n seguranças kde-format %n securities were not imported. 1 security transaction was not imported. Não foi importada 1 transação de segurança Não foram importadas %n transações de seguranças kde-format %n security transactions were not imported. Export QIF File Exportar ficheiro QIF kde-format All All accounts Todas kde-format Export transaction description as: Exportar descrição da transação como: kde-format Memo Memorando kde-format Subcategory Subcategoria kde-format &Import i18n: tag text i18n: file ./eqonomizeui.rc line 5 &Importar kde-format &Accounts i18n: tag text i18n: file ./eqonomizeui.rc line 12 &Contas kde-format &Transactions i18n: tag text i18n: file ./eqonomizeui.rc line 24 &Transacções kde-format &Securities i18n: tag text i18n: file ./eqonomizeui.rc line 41 &Seguranças kde-format Stat&istics i18n: tag text i18n: file ./eqonomizeui.rc line 56 Estatíst&icas kde-format Your names NAME OF TRANSLATORS ,Launchpad Contributions:,Mário Pereira Martins,Ricardo Jorge Maçãs,Tiago Silva, ,Launchpad Contributions:,Hanna K.,Mário Pereira Martins,Pedro Albuquerque,Ricardo Jorge Maçãs,Rogério Carbonera,Sérgio Marques,Tiago Silva kde-format Your emails EMAIL OF TRANSLATORS ,,mario.martins@javali.pt,,,,,,mario.martins@javali.pt,,,rogerio.carbonera@gmail.com,, kde-format Edit Exceptions Editar as exceções kde-format Edit Recurrence Range Editar o intervalo de recorrência kde-format Begins on: %1 Começa em: %1 kde-format No ending date Sem data final kde-format End after Acaba após kde-format occurrence(s) ocorrência(s) kde-format End on Acaba a kde-format End date before start date. Data final anterior à data inicial kde-format Enable recurrence Ativar recorrência kde-format Recurrence Rule Regra de recorrência kde-format Weekly Semanalmente kde-format Recur every recorrer a cada kde-format day(s) dia(s) kde-format week(s) on: semana(s) em: kde-format month(s), after the start month mês(meses) após o mês inicial kde-format Recur on the Recorrer no: kde-format 1st kde-format 2nd kde-format 3rd kde-format 4th kde-format 5th kde-format 6th kde-format 7th kde-format 8th kde-format 9th kde-format 10th 10º kde-format 11th 11º kde-format 12th 12º kde-format 13th 13º kde-format 14th 14º kde-format 15th 15º kde-format 16th 16º kde-format 17th 17º kde-format 18th 18º kde-format 19th 19º kde-format 20th 20º kde-format 21st 21 kde-format 22nd 22º kde-format 23rd 23º kde-format 24th 24º kde-format 25th 25º kde-format 26th 26º kde-format 27th 27º kde-format 28th 28º kde-format 29th 29º kde-format 30th 30º kde-format 31st 31º kde-format Last Último kde-format 2nd Last Penúltimo kde-format 3rd Last Antepenúltimo kde-format 4th Last 4º último kde-format 5th Last 5º último kde-format day dia kde-format possibly on weekend possivelmente no fim de semana kde-format but before weekend mas antes do fim de semana kde-format but after weekend mas depois do fim de semana kde-format year(s), after the start year ano(s), após o ano inicial kde-format Recur on day part before XXX of 'Recur on day XXX of month YYY' Recorrer no dia kde-format of part between XXX and YYY of 'Recur on day XXX of month YYY' de kde-format On the Part before NNN in 'Recur on the NNN. WEEKDAY of MONTH' à kde-format of part between WEEKDAY and MONTH in 'Recur on NNN. WEEKDAY of MONTH' de kde-format Recur on day # Recorrer no dia # kde-format of the year part after NNN of 'Recur on day #NNN of the year' do ano kde-format Range… Intervalo… kde-format Exceptions… Exceções… kde-format No day of week selected for weekly recurrence. Não selecionou dia da semana para recorrência semanal. kde-format Selected day will never occur with selected frequency and start date. Com a frequência e data inicial escolhidas, o dia selecionado nunca ocorre. kde-format Selected day does not exist in selected month. O dia selecionado não existe no mês escolhido. kde-format Dividend: %1 Dividendo: %1 kde-format Account balancing Balanço da conta kde-format Security: %1 (bought) Segurança: %1 (comprada) kde-format Security: %1 (sold) Segurança: %1 (vendida) kde-format Shares bought: Ações compradas: kde-format Shares sold: Ações vendidas kde-format Payer: Pagador: kde-format Payee: Beneficiário kde-format No income category available. Sem categorias de receitas disponíveis kde-format No expense category available. Sem categorias de despesas disponíveis kde-format Cannot create a regular transfer to/from a securities account. Impossível criar uma transferência regular de/para uma conta de seguranças. kde-format Cannot create a regular income to a securities account. Impossível criar uma receita regular para uma conta de seguranças. kde-format Zero price per share not allowed. Não é permitido preço zero por ação kde-format Cannot create a regular expense from a securities account. Impossível criar uma despesa regular de uma conta de seguranç.as kde-format Modify Transactions Modificar transações kde-format Min amount: Montante mínimo: kde-format Max amount: Montante máximo: kde-format Min income: Receita mínima: kde-format Max income: Receita máxima: kde-format Min cost: Custo mínimo: kde-format Max cost: Custo máximo: kde-format Include Incluir kde-format Exclude Excluir kde-format From Account Da conta kde-format To Account Para a conta kde-format Payer Pagador kde-format New/Edit Expense Nova/Editar despesa kde-format Filter Filtro kde-format Total: Total: kde-format Average: Média: kde-format Monthly: Mensalmente kde-format Total cost: Custo total: kde-format Total income: Receita total kde-format Total amount: Montante total: kde-format Monthly average: Média mensal: kde-format Are you sure you want to delete all (%1) transactions in the selected split transaction? Tem a certeza que quer apagar todas as (%1) transações na transação dividida selecionada? kde-format * Part of split transaction Parte de transação dividida kde-format * Part of split (%1) * Parte da divisão (%1) kde-format ** Recurring (editing occurrence) ** A recorrer (editar ocurrência) kde-format Modify… Modificar… kde-format AccountComboBox New account… Nova conta… Multiple accounts/payments… New income category… Nova categoria de receitas… New expense category… Nova categoria de despesas… Paid with loan… New Account Nova conta New Income Category Nova categoria de receitas New Expense Category Nova categoria de despesas AccountsMenu All Accounts Todas as contas All Categories Combined Todas as categorias combinadas %n accounts %n conta %n contas %n categories %n categoria %n categorias Balancing Account balancing Balanço da conta Account balancing Balancing of an account Balanço da conta Account Balance Adjustment Ajuste da conta de saldo Budget Balancing Balanço Balancing Name of account for transactions that adjust account balances Balanço Couldn't open %1 for reading Impossível abrir %1 para leitura Not a valid Eqonomize! file (XML parse error: "%1" at line %2, col %3) Ficheiro Eqonomize! inválido (Erro de análise XML: "%1" na linha %2, coluna %3) Invalid root element %1 in XML document Elemento raíz inválido %1 no documento XML Unknown XML element: "%1" at line %2, col %3 XML parse error: "%1" at line %2, col %3 European Euro Unable to load %n currency/currencies. No exchange rates found. USD currency missing. imported Unable to load %n account(s). Impossível carregar %n conta. Impossível carregar %n contas. Unable to load %n category/categories. Impossível carregar %n categoria. Impossível carregar %n categorias. Unable to load %n security/securities. Financial security (e.g. stock, mutual fund) Impossível carregar %n título. Impossível carregar %n títulos. Unable to load %n transaction(s). Impossível carregar %n transacção. Impossível carregar %n transacções. Download command (%1) failed: %2. Failed to download file from %1: %2. Upload command (%1) failed: %2. yyyy-yy Financial year when first month is not January (e.g. 2018-19). Transaction Accounts Contas correntas Savings Accounts Contas poupanças Credit Cards Cartãos de crédito Debts Dívidas Securities Financial security (e.g. stock, mutual fund) Títulos financeiros Cash Dinheiro Transaction Account Conta corrente Savings Account Conta poupanças Credit Card Cartão de crédito Debt Dívida Other Outro File is a directory O ficheiro é uma pasta Couldn't open file for writing Impossível abrir o ficheiro para escrita Error while writing file; file was not saved Erro quando tentava gravar o ficheiro: ficheiro não gravado Unnamed Sem nome Uncategorized Sem categoria CategoriesComparisonChart Save As… Gravar como… Print… Imprimir… From De To até Source: Fonte: All Expenses Todas as despesas All Incomes Todas as receitas Theme: Chart type: Pie Chart Bar Chart Default Predefinida All Expenses, without subcategories Todas as despesas, sem subcategorias All Expenses, with subcategories Todas as despesas, com subcategorias All Incomes, without subcategories Todas as receitas, sem subcategorias All Incomes, with subcategories Todas as receitas, com subcategorias All Accounts Todas as contas Expenses: %1 Despesas: %1 Incomes: %1 Receitas: %1 Error Erro Invalid date. Data inválida. To date is before from date. Data final anterior à data inicial. From date is after to date. Data inicial posterior à data final. Couldn't open file for writing. Impossível abrir o ficheiro para escrita. Error while writing file; file was not saved. Erro ao gravar o ficheiro: ficheiro não gravado. Expenses Despesas Expenses, %1 Despesas, %1 Incomes, %1 Receitas, %1 Incomes Receitas Accounts Contas Expenses, %2: %1 Despesas, %2: %1 Incomes, %2: %1 Rendimentos, %2: %1 Other descriptions Referring to the transaction description property (transaction title/generic article name) Outras descrições No description Referring to the transaction description property (transaction title/generic article name) Sem descrição Other accounts Outras contas Other categories Outras categorias %1 Value: %2 %1 Valor: %2 No description Referring to the Transaction description property (transaction title/generic article name) Sem descrição No description Referring to the generic description property Sem descrição Value Valor Income Receita Cost Custo Value (%1) Valor (%1) Income (%1) Receita (%1) Cost (%1) Custo (%1) No description Sem descrição CategoriesComparisonChartDialog Chart Gráfico CategoriesComparisonReport Save As… Gravar como… Print… Imprimir… Source: Fonte: All Categories, excluding subcategories Todas as categorias, excluindo subcategorias All Categories, including subcategories Todas as categorias, incluindo subcategorias All Payees/Payers Todos os beneficiários/pagadores Subcategories Subcategorias Descriptions for Referring to the Transaction description property (transaction title/generic article name) Descrições para All descriptions Referring to the Transaction description property (transaction title/generic article name) Todas as descrições No description Referring to the Transaction description property (transaction title/generic article name) Sem descrição All Categories Todas as categorias Expenses: %1 Despesas: %1 Incomes: %1 Receitas: %1 Descriptions for Descrições para Payees/payers for Beneficiários/pagadores para Descriptions Referring to the Transaction description property (transaction title/generic article name) Descrições Period: Período: From De To até Columns: Colunas: Value Valor Daily Diariamente Monthly Mensalmente Yearly Anualmente Quantity Quantidade Average value Valor médio All descriptions Todas as descrições All payees Todos os beneficiários All payers Todos os pagadores No description Sem descrição Descriptions for Referring to the generic description property Descrições para Descriptions Referring to the generic description property Descrições All descriptions Referring to the generic description property Todas as descrições No description Referring to the generic description property Sem descrição All Payees and Payers Todos os beneficiários e pagadores Tag: %1 Etiqueta: %1 All Accounts Todas as contas Descriptions for Referring to the transaction description property (transaction title/generic article name) Descrições para Descriptions Referring to the transaction description property (transaction title/generic article name) Descrições Months Meses Years Anos Tags Etiquetas Total: Total: All descriptions Referring to the transaction description property (transaction title/generic article name) Todas as descrições All payees/payers Todos os beneficiários/pagadores No description Referring to the transaction description property (transaction title/generic article name) Sem descrição No payee Sem beneficiário No payer Sem pagador Error Erro Invalid date. Data inválida. To date is before from date. Data final anterior à data inicial. From date is after to date. Data inicial posterior à data final. Couldn't open file for writing. Impossível abrir o ficheiro para escrita. Error while writing file; file was not saved. Erro ao gravar o ficheiro: ficheiro não gravado. Expenses, %2: %1 Despesas, %2: %1 Expenses, %3: %2, %1 Despesas, %3: %2, %1 Incomes, %2: %1 Rendimentos, %2: %1 Incomes, %3: %2, %1 Rendimentos, %3: %2, %1 %3: %2, %1 %3: %2, %1 %2: %1 %2: %1 Tags, %1 Etiquetas, %1 Incomes & Expenses, %1 Rendimentos & Despesas, %1 Expenses: %2, %1 Despesas: %2, %1 Incomes: %2, %1 Rendimentos: %2, %1 %2, %1 %2, %1 %1 %1 Incomes & Expenses Rendimentos & Despesas %1 (%2&ndash;%3) html format; %1: title; %2: from date; %3: to date %1 (%2&ndash;%3) %1 (to %2) html format; %1: title; %2: to date %1 (à %2) Category Categoria Payee Beneficiário Description Referring to the transaction description property (transaction title/generic article name) Descrição Cost Custo Payer Pagador Income Receita Payee/Payer Beneficiário/pagador Tag Etiqueta Daily Average Média diária Monthly Average Média mensal Yearly Average Média anual Average Cost Custo médio Average Income Rendimento médio Average Value Valor médio No payee/payer Sem beneficiário/pagador Total Total All Tags Todas as etiquetas Total incomes Total de receitas Total expenses Total de despesas Total (Profits) Total (lucros) CategoriesComparisonReportDialog Report Relatório ConfirmScheduleDialog The following transactions was scheduled to occur today or before today. Confirm that they have indeed occurred (or will occur today). As seguintes transacções foram agendadas para ocorrerem hoje ou antes de hoje. Confirme se elas ocorreram (ou se irão ocorrer hoje). Date Data Type Tipo Description Descrição Name Nome Description Generic Description Descrição Description Transaction description property (transaction title/generic article name) Descrição Amount Montante Edit… Editar… Postpone… Adiar… Delete Apagar Error Erro Can only postpone to future dates. Só pode adiar para datas futuras. ConfirmScheduleListViewItem Transfer Transferência Dividend Dividendo Income Receita Expense Despesa Securities Purchase Financial security (e.g. stock, mutual fund) Compra de títulos Securities Sale Financial security (e.g. stock, mutual fund) Venda de títulos Security Buy Compra de seguranças Security Sell Venda de seguranças Debt Payment CurrencyConversionDialog Currency Converter DebtFee Debt payment: %1 (fee) DebtInterest Debt payment: %1 (interest) DebtPayment Debt payment: %1 DebtReduction Debt payment: %1 (reduction) DescriptionsMenu All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Todas as descrições combinadas All Tags Combined All Payees Combined Todos os beneficiários combinados All Payers Combined Todos os pagadores combinados All Payees/Payers Combined Todos os beneficiários/pagadores combinados No description Referring to the transaction description property (transaction title/generic article name) Sem descrição No payee Sem beneficiário No payer Sem pagador No payee/payer Sem beneficiário/pagador %n descriptions Referring to the transaction description property (transaction title/generic article name) %n descriçaõ %n descrições %n tags %n etiqueta %n etiquetas %n payees %n beneficiário %n beneficiários %n payers %n pagador %n pagadores %n payees/payers %n beneficiário/pagador %n beneficiários/pagadores EditAssetsAccountDialog Type: Tipo: Cash Dinheiro Current Account Conta corrente Savings Account Conta poupanças Credit Card Cartão de crédito Liabilities Passivos Transactional Account Conta corrente Securities Títulos financeiros Other Outro Currency: Edit Editar Name: Nome: Bank: Banco: Initial balance: Saldo Inicial: Debt: Initial balance Salda inicial Group: Grupo: no group nenhum grupo Transferred to: Date: Data: Lender: Credor: Default account for budgeted transactions Conta predefinida para transações orçamentadas Description: Descrição: Account is closed Warning Type cannot be changed to securities for accounts with transactions. Issuer: Zero value not allowed. Error Erro Transaction Account Conta corrente Opening balance: Account balance Saldo inicial: Opening balance Account balance Saldo inicial New currency… If you change the currency of an account, the currency of all associated transactions will also change, without any conversion. Do do wish to continue anyway? Empty name. Nome em branco. The entered name is used by another account. O nome escolhido é utilizado por outra conta. EditCurrencyDialog Edit Currency New Currency Code: Symbol: Prefix Suffix Default Predefinida Name: Nome: Decimals: Date: Data: Main currency Error Erro Error saving currencies: %1. Empty code. Code already exists. EditDebtPaymentDialog Debt Payment EditDebtPaymentWidget Debt: Date: Data: Debt reduction: Reduction payment: Interest: Paid Added to debt Fee: Account: Conta: Expense category: Categoria de despesas: Associated file: Arquivo associado: Select a file Open the file Comments: Comentários: Related to: Label for linked transactions Links: Total value: Valor total: Error Erro No suitable account available. Sem conta adequada disponível. Invalid date. Data inválida. Interest must not be zero. At least one value must non-zero. EditExceptionsDialog Edit Exceptions Editar as exceções Occurrences: Ocorrências: Add Exception Remove Exception Exceptions: Exceções: Only the first fifty occurrences are shown. Invalid date. Data inválida. EditExpensesAccountDialog Name: Nome: Parent category: None Monthly budget: Orçamento mensal: Description: Descrição: Error Erro Empty name. Nome em branco. The entered name is used by another expense category. O nome introduzido é utilizado por outra categoria de despesa. EditIncomesAccountDialog Name: Nome: Parent category: None Monthly budget: Orçamento mensal: Description: Descrição: Error Erro Empty name. Nome em branco. The entered name is used by another income category. O nome introduzido é utilizado por outra categoria de receitas. EditLoanTransactionWidget Date: Data: Account: Conta: Comments: Comentários: Total value: Valor total: No suitable account available. Sem conta adequada disponível Invalid date. Data inválida. EditMultiAccountDialog Expense with Multiple Payments Income with Multiple Payments EditMultiAccountWidget Description: Descrição: Description: Generic Description Descrição: Description: Transaction description property (transaction title/generic article name) Descrição: Quantity: Quantidade: Category: Categoria: Tags: Etiquetas: Associated file: Arquivo associado: Select a file Open the file Comments: Comentários: Related to: Label for linked transactions Links: Transactions: Transações: Date Data Account Conta Payee Beneficiário Payer Pagador Cost Custo Income Receita Total cost: Custo total: New Tag Nova etiqueta Tag: Etiqueta: Value Valor New Novo Edit… Editar… Delete Apagar Total value: Valor total: Error Erro No suitable expense categories available. A split must contain at least two transactions. Uma divisão tem de conter pelo menos duas transacções. EditMultiItemDialog Split Transaction Dividir transação EditMultiItemWidget Description: Descrição: Description: Generic Description Descrição: Date: Data: Account: Conta: Payee/Payer: Beneficiário/pagador: Transactions: Transações: Type Tipo Description Generic Description Descrição Description: Transaction description property (transaction title/generic article name) Descrição: Tags: Etiquetas: Associated file: Arquivo associado: Select a file Open the file Comments: Comentários: Related to: Label for linked transactions Links: Description Transaction description property (transaction title/generic article name) Descrição Payment Pagamento Deposit Depósito New Novo New Expense… Nova despesa… New Income… Nova receita… New Deposit… Novo depósito… New Withdrawal… Novo levantamento… New Securities Purchase… Financial security (e.g. stock, mutual fund) Nova compra títulos… New Securities Sale… Financial security (e.g. stock, mutual fund) Nova venda títulos… Shares Bought… Ações compradas… Shares Sold… Ações vendidas… Account/Category Conta/Categoria Value Valor Income Receita Expense Despesa New Dividend… Novo dividendo… Edit… Editar… Delete Apagar Total value: Valor total: Error Erro No suitable account available. Sem conta adequada disponível. Invalid date. Data inválida. A split must contain at least two transactions. Uma divisão tem de conter pelo menos duas transacções. Cannot transfer money to and from the same account. Não pode ser transferido dinheiro de e para a mesma conta. EditQuotationsDialog Quotations Cotações Date Data Price per Share Preço por ação Quotations Financial quotation Cotações Quotes Financial quote Cotações Price per Share Financial Shares Preço por ação Add Addicionar Modify Modificar Delete Apagar Import… Importar… Export… Exportar… Quotes for %1 Financial quote Cotações para %1 Quotations for %1 Financial quotation Cotações para %1 Quotations for %1 Cotações para %1 Error Erro Couldn't open %1 for reading. Impossível abrir %1 para leitura. Error reading %1. Erro ao ler %1. Successfully imported %n quote(s). Importou com sucesso %n cotaçaõ. Importou com sucesso %n cotações. Unable to import any quotes. Failed to import %n data row(s). Falha ao importar %n linha de dados. Falha ao importar %n linhas de dados. Required columns missing. Invalid value. Valor inválido. Invalid date. Data inválida. No data found. Information Informação Unrecognized date format. Formato de data não reconhecido. Specify Format Especifique formato The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. O formato de datas e/ou números no ficheiro CSV é ambíguo. Por favor selecione o formato correto. Date format: Formato da data: Value format: Formato do valor: Couldn't open file for writing. Impossível abrir o ficheiro para escrita. Quotes: %1 Cotações: %1 Error while writing file; file was not saved. Erro ao gravar o ficheiro: ficheiro não gravado. EditRangeDialog Edit Recurrence Range Editar o intervalo de recorrência Begins on: %1 Começa em: %1 No ending date Sem data final End after Acaba após occurrence(s) ocorrência(s) End on Acaba a Error Erro Invalid date. Data inválida. End date before start date. Data final anterior à data inicial. EditReinvestedDividendDialog Reinvested Dividend Dividendos reinvestidos Security: Segurança: Shares added: Ações adicionadas: Security: Financial security (e.g. stock, mutual fund) Título: Shares added: Financial shares Ações adicionadas: Date: Data: Error Erro Invalid date. Data inválida. EditScheduledDebtPaymentDialog Transaction Transação Recurrence Recorrência Edit Debt Payment New Debt Payment EditScheduledLoanTransactionDialog Recurrence Recorrência EditScheduledMultiAccountDialog Transactions Transações Recurrence Recorrência New Expense with Multiple Payments New Income with Multiple Payments Edit Expense with Multiple Payments Edit Income with Multiple Payments EditScheduledMultiItemDialog Transactions Transações Recurrence Recorrência New Split Transaction Nova transação dividida Edit Split Transaction Editar transação dividida EditScheduledTransactionDialog Expense Despesa Dividend Dividendo Income Receita Reinvested Dividend Dividendos reinvestidos Transfer Transferência Security Buy Compra de seguranças Security Sell Venda de seguranças Securities Purchase Financial security (e.g. stock, mutual fund) Compra de títulos Securities Sale Financial security (e.g. stock, mutual fund) Venda de títulos Recurrence Recorrência New Expense Nova despesa New Expense Paid with Loan New Dividend Novo dividendo New Income Nova receita New Transfer Nova transferência New Securities Purchase Financial security (e.g. stock, mutual fund) Nova compra títulos New Reinvested Dividend New Securities Sale Financial security (e.g. stock, mutual fund) Nova venda títulos Edit Reinvested Dividend Edit Securities Purchase Financial security (e.g. stock, mutual fund) Editar títulos compradas Edit Securities Sale Financial security (e.g. stock, mutual fund) Editar títulos vendidas New Security Buy Nova compra segura New Security Sell Nova venda segura Edit Expense Editar despesa Edit Dividend Editar dividendo Edit Income Editar receita Edit Transfer Editar transferência Edit Securities Bought Editar seguranças compradas Edit Securities Sold Editar seguranças vendidas EditSecurityDialog Type: Tipo: Mutual Fund Fundo mútuo Bond Ação Stock Cotações Stock Financial stock Cotações Other Outro Name: Nome: Account: Conta: Decimals in shares: Financial shares Decimais em ações: Initial shares: Financial shares Ações iniciais: Decimals in quotes: Financial quote Initial quote: Financial quote Cotação inicial: Empty name. Nome em branco. No suitable account available. Sem conta adequada disponível. Initial quotation: Financial quotation Cotação inicial: Decimals in Shares: Decimais em ações Initial Shares: Ações iniciais Initial quotation: Cotação inicial: Date: Data: Description: Descrição: Error Erro No suitable account or income category available. Não há conta ou categoria de rendimento apropriadas disponíveis. EditSecurityTradeDialog Security Trade Transação segura From security: De segurança: Shares moved: Ações movidas: All Todas To security: Para segurança: Shares received: Ações recebidas: Securities Exchange Shares of one security directly exchanged for shares of another; Financial security (e.g. stock, mutual fund) Transação ações From security: Financial security (e.g. stock, mutual fund) De título: Shares moved: Financial shares Ações movidas: To security: Financial security (e.g. stock, mutual fund) Para título: Shares received: Financial shares Ações recebidas: Value: Valor: Date: Data: Error Erro No other security available for exchange in the account. Shares of one security directly exchanged for shares of another; Financial security (e.g. stock, mutual fund) Sem outra título disponível na conta para trocar. No other security available for trade in the account. Sem outra segurança disponível na conta para trocar. Selected to and from securities are the same. Financial security (e.g. stock, mutual fund) Títulos seleccionadas de e para são as mesmas. Zero shares not allowed. Financial shares Zero ações não é permitido. Selected to and from securities are the same. Seguranças seleccionadas de e para são as mesmas. Invalid date. Data inválida. Zero shares not allowed. Zero ações não é permitido Zero value not allowed. Valor zero não permitido. EditSplitDialog Split Transaction Dividir transação Description: Descrição: Date: Data: Account: Conta: Transactions: Transações Type Tipo Description Descrição Name: Nome: Name Nome Description Generic Description Descrição Account/Category Conta/Categoria Payment Pagamento Deposit Depósito New Novo New Expense… Nova despesa… New Income… Nova receita… New Deposit… Novo depósito New Withdrawal… Novo levantamento… Shares Bought… Ações compradas… Shares Sold… Ações vendidas… New Dividend… Novo dividendo… Edit… Editar… Total value: Valor total: No suitable account available. Sem conta adequada disponível Invalid date. Data inválida. Future dates is not allowed. Não são permitidas datas futuras. A split must contain at least two transactions. Uma divisão tem de conter pelo menos duas transacções Cannot transfer money to and from the same account. Não pode ser transferido dinheiro de e para a mesma conta Eqonomize Accounts && Categories Contas e categorias Expenses Despesas Incomes Receitas Transfers Transferências Transaction Accounts Contas correntas Savings Accounts Contas poupanças Credit Cards Cartãos de crédito Debts Dívidas Securities Títulos Schedule Agenda Account / Category Conta/categoria Remaining Budget (%1) Orçamento restante (%1) Change (%1) Mudança (%1) Total (%1) Total (%1) %2 of %1 %2 remains of %1 budget %2 de %1 Accounts Contas Includes budgeted transactions Incluir transações orçamentadas Tags Etiquetas Period Período From De To até Select Period Seleccionar período Current Month Mês atual Current Year Ano atual Current Whole Month Todo o mês atual Current Whole Year Todo o ano atual Whole Past Month Todo o mês passado Whole Past Year Todo o ano passado Previous Month Mês anterior Previous Year Ano passado Show partial budget Mostrar orçamento parcial Edit Budget Editar orçamento Budget: Orçamento: Month: Mês: Result previous month: Resultados do mês anterior: New Security… Nova segurança … New Transaction Nova transação Set Quotation… Definir cotação Name Nome Value Valor Shares Ações Quotation Cotação Cost Custo Profit Lucro Yearly Rate Taxa anual Type Tipo Account Conta Statistics Period Estatísticas do período New Schedule Novo agendamento Edit Editar Remove Remover Next Occurrence Ocorrência seguinte Description Descrição Description Generic Description Descrição Amount Montante Payee/Payer Beneficiário/pagador Comments Comentários Set Schedule Confirmation Time Schedule confirmation time: Set Budget Period First day in budget month: 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 10º 11th 11º 12th 12º 13th 13º 14th 14º 15th 15º 16th 16º 17th 17º 18th 18º 19th 19º 20th 20º 21st 21 22nd 22º 23rd 23º 24th 24º 25th 25º 26th 26º 27th 27º 28th 28º Last Último 2nd Last Penúltimo 3rd Last Antepenúltimo 4th Last 4º último 5th Last 5º último Timestamp Marca temporal Links Remove Link Remover link Link to "%1" create link to transaction (link used as verb) Link a "%1" Information Informação All Todas Import Options Ignore duplicate transactions Rename duplicate accounts Rename duplicate categories Rename duplicate securities Synchronization Settings Web address: Download command: Duplicate Transaction… duplicate as verb Duplicar transação… Create Link create link to or between transaction(s) Criar link New Tag… Nova etiqueta… Rename Tag… Renomear etiqueta… Remove Tag Remover etiqueta New Tag Nova etiqueta Tag name: Nome de etiqueta: Remove tag? Remover etiqueta? Do you wish to remove the tag "%1" from %n transaction(s)? Rename Tag Renomear etiqueta optional Link Transactions create link between selected transactions (link used as verb) Link as transações Create Link to Transaction Criar link para transação Upload command: mandatory Automatic synchronization Upload Uploading… Error uploading file Error uploading %1: %2. Synchronizing… Error synchronizing file Error synchronizing %1: %2. Synchronization error Synchronize file? The file has been modified by a different user or program. Do you wish to merge changes? New version available A new version of %1 is available.<br><br>You can get version %2 at %3. Abort First month in budget year: Right align Alinhar à direita %f = local file (temporary), %u = url Failed to download exchange rates from %1: %2. Error reading data from %1: %2. Unrecognized Currency No exchange rate is available for the default currency (%1). If you wish to use multiple currencies you should set the exchange rate manually. Set Main Currency Currency: Replace all occurrences of the former main currency Transaction Account Conta corrente S&ynchronize Import %1 File… Reconcile Account… Reconciliar conta… Adjust balance… Referring to account balance Ajustar o saldo… Close Account Mark account as closed Fechar conta New Expense Paid with Loan… Show payee and quantity Mostre beneficiáro e quantidade Show quantity and payer/payee properties for incomes and expenses. Set Schedule Confirmation Time… Select Font… Language Língua Default Predefinida Restart required Only use this when unable to find the cause of the incorrect recorded account balance. Reopen Account Mark account as not closed Shares of one security directly exchanged for shares of another Financial shares Use Exchange Rate for Transaction Date Use the exchange rate nearest the transaction date, instead of the latest available rate, when converting the value of transactions. Adjust Account Balance Ajustar o saldo da conta New Security Nova segurança Edit Security Editar segurança Total value: Valor total: Cost: Custo: Profit: Lucro: Rate: Taxa: Are you sure you want to delete the security "%1" and all associated transactions? Tem a certeza que quer apagar a segurança "%1" e todas as transações associadas? Error Erro No security available. Sem segurança disponível Set Quotation (%1) Definir cotação (%1) Price per share: Preço por ação: Date: Data: Invalid date. Data inválida. Future dates are not allowed. Datas futuras não são permitidas. Security Transactions Transações seguras Bond Ação Stock Cotações Mutual Fund Fundo mútuo Other Outro Add Loan Add Category Ledger Diário To date is before from date. Data final anterior à data inicial. From date is after to date. Data inicial posterior à data final. Cash Dinheiro Check Account Verificar conta Savings Account Conta poupanças Salary Salário Bills Contas Clothing Roupas Groceries Mercearias Leisure Lazer Couldn't open file Impossível abrir o ficheiro Error loading %1: %2. Erro ao carregar %1: %2. Couldn't save file Não pode gravar o ficheiro Error saving %1: %2. Erro ao gravar %1: %2. Updating exchange rates… Error saving currencies: %1. New currency… Transaction Schedule Agendamento de transação Total Total Accounts &amp; Categories html format Contas e categorias Accounts &amp; Categories (%1&ndash;%2) html format Contas e categorias (%1&ndash;%2) Accounts &amp; Categories (to %1) html format Contas e categorias (para %1) Change Noun, how much the account balance has changed Mudança Balance Balanço Current Account Conta corrente Credit Card Cartão de crédito Liabilities Passivos Set Quote… Financial quote Definir cotação… Quote Financial quote Cotação Set Quote (%1) Financial quote Definir cotação (%1) Stock Financial stock Cotações Balance Noun. Balance of an account Saldo Category Categoria Budget Orçamento Remaining Budget Orçamento restante Total Incomes Total de receitas Costs Custos Total Expenses Total de despesas Account/Category Noun, how much the account balance has changed Conta/categoria Empty expenses list. Lista de despesas vazia. Empty incomes list. Lista de receitas vazia. Empty transfers list. Lista de tranferências vazia. Empty securities list. Lista de seguranças vazia. Empty schedule list. Lista de agendamentos vazia. Couldn't open file for writing. Impossível abrir o ficheiro para escrita. Error while writing file; file was not saved. Erro ao gravar o ficheiro: ficheiro não gravado. &File &Ficheiro &Accounts &Contas &Transactions &Transacções &Securities &Seguranças Stat&istics Estatíst&icas S&ettings &Configuração &Help &Ajuda File Ficheiro Transactions Transações Statistics Estatísticas &New &Novo &Open… &Abrir… Open Recent Abrir um recente Clear List Limpar a lista &Save &Gravar Save As… Gravar como… &Revert Ac&tualizar &Print… &Imprimir… Print Preview… Antevisão da impressão… Import Importar Import CSV File… Importar ficheiro CSV… Import QIF File… Importar ficheiro QIF… Export View… Vista exportação… Export As QIF File… Exportar como ficheiro QIF… Update Exchange Rates Currency Converter &Quit &Sair Add Account… Adicionar conta… New Account… Nova conta… New Loan… New Income Category… Nova categoria de receitas… New Expense Category… Nova categoria de despesas… Add Account Adicionar conta Assets Ativos Description Transaction description property (transaction title/generic article name) Descrição Security Transactions Financial security (e.g. stock, bond) Transações seguras &Loans &Empréstimos Edit… Editar… Balance… Balanço… Show Transactions Mostrar transações Show Ledger Mostrar diário New Expense… Nova despesa… New Income… Nova receita… New Transfer… Nova transferência… New Split Transaction… Nova transação dividida… New Expense with Multiple Payments… Nova despesa com múltiplos pagamentos… Refund… Reembolsar… Repayment… Retribuição… New Refund/Repayment… Novo reembolso/retribuição… Edit Transaction(s) (Occurrence)… Editar transações (ocorrência)… Edit Occurrence… Editar ocorrência… Edit Schedule (Recurrence)… Editar agenda (recorrência)… Edit Schedule… Editar agenda… Edit Split Transaction… Editar transação dividida… Join Transactions… join transactions together Unir transações… Split Up Transaction split up joined transactions Dividir transação Edit Timestamp… Editar marca temporal… Select Associated File Open Associated File Remove Transaction(s) (Occurrence) Remover transações (ocorrência) Remove Occurrence Remover ocorrência Delete Schedule (Recurrence) Apagar agendamento (recorrência) Delete Schedule Apagar agendamento Remove Split Transaction Remover transação dividida New Debt Payment… Novo pagamento de dívida… New Unpaid Interest… Novo divindo não pago… Edit Security… Editar segurança… Remove Security Remover segurança Shares Bought… Ações compradas… Shares Sold… Ações vendidas… Shares Moved… Ações movidas… Dividend… Dividendo… Reinvested Dividend… Dividendo reinvestido… Transactions… Transações… Edit Quotations… Editar cotações… Development Over Time Report… Relatório de desenvolvimento ao longo do tempo… Categories Comparison Report… Relatório comparativo de categorias… Development Over Time Chart… Gráfico de desenvolvimento ao longo do tempo… Categories Comparison Chart… Gráfico comparativo de categorias… Use Additional Transaction Properties Usar propriedades adicionais da transação Set Main Currency… Set Budget Period… Definir o período do orçamento… Initial Period Período inicial Remember Last Dates Lembrar últimas datas Backup Frequency Frequência do backup Daily Diariamente Weekly Semanalmente Fortnightly Monthly Mensalmente Never Nunca Cloud Synchronization (experimental)… Dark Mode Tema escuro Help Ajuda Report Bug Reportar bug About %1 Sobre %1 About Qt Sobre Qt Please restart the application for the language change to take effect. A personal accounting program Um programa de finanças pessoais Crash Recovery Recuperação de erro %1 exited unexpectedly before the file was saved and data was lost. Do you want to load the last auto-saved version of the file? %1 foi fechado inesperadamente antes do ficheiro ter sido guardado e perderam-se dados. Deseja abrir a última versão guardada automaticamente do ficheiro? Untitled Sem título Securities Financial security (e.g. stock, mutual fund) Título financeiro New Security… Financial security (e.g. stock, mutual fund) Nova título… Set Quotation… Financial quotation Definir cotação… Shares Financial shares Ações Quotation Financial quotation Cotação New Security Financial security (e.g. stock, mutual fund) Nova título Edit Security Financial security (e.g. stock, mutual fund) Editar título Delete security? Financial security (e.g. stock, mutual fund) Are you sure you want to delete the security "%1" and all associated transactions? Financial security (e.g. stock, mutual fund) Tem a certeza que quer apagar a título "%1" e todas as transações associadas? No security available. Financial security (e.g. stock, mutual fund) Sem título disponível. Set Quotation (%1) Financial quotation Definir cotação (%1) Price per share: Financial shares Preço por ação: Security Transactions Financial security (e.g. stock, mutual fund) Transações títulos Checking Account Transactional account Conta corrente Balance Account balance Saldo Empty securities list. Financial security (e.g. stock, mutual fund) Lista de títulos vazia. &Securities Financial security (e.g. stock, mutual fund) &Títulos Balance… Balance account Balanço… Edit Security… Financial security (e.g. stock, mutual fund) Editar título… Remove Security Financial security (e.g. stock, mutual fund) Remover título Shares Bought… Financial shares Ações compradas… Shares Sold… Financial shares Ações vendidas… Edit Quotations… Financial quotation Editar cotações… License: GNU General Public License Version 3 Licença: GNU General Public License Version 3 Eqonomize! Accounting File Ficheiro da conta Eqonomize! Save file? Guardar ficheiro? The current file has been modified. Do you want to save it? O ficheiro atual foi modificado. Quer gravá-lo? Confirm Schedule Confirmar agendamento New Account Nova conta New Loan Novo empréstimo New Income Category Nova categoria de receitas New Expense Category Nova categoria de despesas Balance Account Conta balanço Book value: Valor contabilístico: of which %1 is balance adjustment Referring to account balance do qual %1 é um ajuste do saldo Real value: Valor real: Edit Account Editar conta Edit Income Category Editar categoria de receitas Edit Expense Category Editar categoria de despesas Remove subcategories? Remover subcategorias? Do you wish to remove the category including all subcategories? Deseja remover a categoria, incluindo todas as subcategorias? Move transactions? Mover transações? Move to: Mover para: Remove irreversibly from all accounts (do not do this if account has been closed!) The category contains some expenses. What do you want to do with them? A categoria contém algumas despesas. O que lhes deseja fazer? The category contains some incomes. What do you want to do with them? A categoria contém algumas receitas. O que lhes deseja fazer? The account contains some transactions. What do you want to do with them? A conta contém algumas transações. O que lhes deseja fazer? Remove Category? Remover categoria? The category contains some expenses that will be removed. Do you still want to remove the category? A categoria contém algumas despesas que serão removidas. Quer remover a categoria, mesmo assim? The category contains some incomes that will be removed. Do you still want to remove the category? A categoria contém algumas receitas que serão removidas. Quer remover a categoria, mesmo assim? Remove Account? Remover conta? The account contains some transactions that will be removed. Do you still want to remove the account? A conta contém algumas transações que serão removidas. Quer remover a conta, mesmo assim? %2 of %1 %1: budget; %2: remaining budget %2 de %1 Balance… Verb. Balance an account Balanço… Shares Exchanged… Shares of one security directly exchanged for shares of another; Financial shares Ações movidas… Edit Quotes… Financial quote Editar cotações… Balance Account Verb Conta balanço %1 (with no budget) %1 (não orçamentada) %1 (with budget %2) %1 (com orçamento %2) EqonomizeCalendarWidget Today Hoje EqonomizeDateEdit Today Hoje EqonomizeTranslator OK Only used when Qt translation is missing Cancel Only used when Qt translation is missing Cancelar Close Only used when Qt translation is missing Fechar Yes Only used when Qt translation is missing Sim No Only used when Qt translation is missing Não &Yes Only used when Qt translation is missing &Sim &No Only used when Qt translation is missing &Não &Open Only used when Qt translation is missing &Save Only used when Qt translation is missing &Gravar &Select All Only used when Qt translation is missing Look in: Only used when Qt translation is missing File &name: Only used when Qt translation is missing Files of type: Only used when Qt translation is missing EqonomizeValueEdit Error Erro Empty denominator. Empty factor. Division by zero. Unknown or ambiguous currency, or unrecognized characters, in expression: %1. Empty base. Empty exponent. Unrecognized characters in expression. ExportQIFDialog Export QIF File Exportar ficheiro QIF Account: Conta: All All accounts Todas Export transaction description as: Exportar descrição da transação como: Export transaction description as: Referring to generic description Exportar descrição da transação como: Payee Beneficiário Memo Memorando Subcategory Subcategoria Date format: Formato da data: Value format: Formato do valor: File: Ficheiro: Error Erro Selected file is a directory. O ficheiro selecionado é uma pasta. Overwrite The selected file already exists. Would you like to overwrite the old copy? O ficheiro selecionado já existe. Deseja substituir a cópia antiga? You selected a directory! Selecionou uma pasta! Couldn't open file for writing. Impossível abrir o ficheiro para escrita. Error while writing file; file was not saved. Erro ao gravar o ficheiro: ficheiro não gravado. ImportCSVDialog Import CSV file Importar ficheiro CSV Transaction Type Selection Seleção do tipo de transação Expenses Despesas Incomes Receitas Transfers Transferências Expenses and incomes (negative cost) Despesas e receitas (custo negativo) Expenses and incomes (separate columns) Despesas e receitas (colunas separadas) All types Todos os tipos Presets: File Selection Selecção de ficheiros File: Ficheiro: First data row: Primeira linha de dados: Auto Automático Column delimiter: Delimitador de coluna: Comma Vírgula Tabulator Tabulador Semicolon Ponto e vírgula Space Espaço Other Outro Columns Specification Especificação das colunas Save as preset… Imports data as expenses and incomes. Costs have negative value. Value is the only required column. Importar dados como despesas e receitas. Custos têm valor negativo. Valor é a única coluna requerida. Imports data as expenses and incomes. Costs and incomes have separate columns. Income and cost both all required columns. Importar dados como despesas e receitas. Custos e receitas têm colunas separadas. Receitas e custos são ambas colunas requeridas. Warning The same column number is selected multiple times. Do you wish to proceed anyway? Description: Descrição: Description: Transaction description property (transaction title/generic article name) Descrição: Column Coluna Value Valor Cost: Custo: Date: Data: Category: Categoria: From account: Da conta: Quantity: Quantidade: Payee: Beneficiário: Tags: Etiquetas: Comments: Comentários: Create missing categories and accounts Criar categorias e contas em falta Save Preset Imports data as expenses. Costs have positive value. Value is the only required column. Importar dados como despesas. Custos têm valor positivo. Valor é a única coluna requerida. Imports data as incomes. Value is the only required column. Importar dados como receitas. Valor é a única coluna requerida. Income: Receita: To account: Para a conta: Payer: Pagador: Imports data as transfers. Value is the only required column. Importar dados como transferências. Valor é a única coluna requerida. Amount: Montante: Imports data as expenses and incomes. Costs have negative value. Value and category are both required columns. Importar dados como despesas e receitas. Custos têm valor negativo. Valor e categoria são ambas colunas requeridas. Value: Valor: Account: Conta: Payee/payer: Beneficiário/pagador: Imports data as expenses and incomes. Costs and incomes have separate columns. Income, cost, and category are all required columns. Importar dados como despesas e receitas. Custos e receitas têm colunas separadas. Receitas, custos e categoria são todas colunas requeridas. Imports data as expenses, incomes, and transfers. Costs have negative or positive value. Value, to, and from are all required columns. Accounts and categories must be existing. Importar dados como despesas receitas e transferências. Custos têm valor negativo ou positivo. Valor, De e Para são todas colunas requeridas. Contas e categorias têm de existir. From: De: To: Para: Error Erro A file must be selected. Deve selecionar um ficheiro. Selected file is a directory. O ficheiro selecionado é uma pasta. Selected file does not exist. O ficheiro selecionado não existe. Empty delimiter. Delimitador vazio. The same column number is selected multiple times. O mesmo número de coluna é selecionado múltiplas vezes. Selected from account is the same as the to account. A seleção Da conta é a mesma que Para a conta. Invalid date. Data inválida. Couldn't open %1 for reading. Impossível abrir %1 para leitura. Error reading %1. Erro ao ler %1. Uncategorized Sem categoria Successfully imported %n transaction(s). Importou com sucesso %n transação. Importou com sucesso %n transações. Unable to import any transactions. Impossível importar quaisquer transações. Failed to import %n data row(s). Falha ao importar %n linha de dados. Falha ao importar %n linhas de dados. Required columns missing. Faltam colunas requeridas. Invalid value. Valor inválido. Empty category name. Nome de categoria vazio. Empty account name. Nome de conta vazio. Unknown category found. Encontrada categoria desconhecida. Unknown account found. Encontrada conta desconhecida. Cannot import security transactions (to/from security accounts). Impossível importar transações de títulos (de/para contas título). Balancing account wrongly used. Referring to the account used for adjustments of account balances. Conta balanço usada erradamente. Balancing account wrongly used. Conta Balanço usada erradamente. Same to and from account/category. Mesma De e Para conta/categoria. No data found. Não foram encontrados dados. Information Informação Unrecognized date format. Formato de data não reconhecido. Specify Format Especifique formato The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. O formato de datas e/ou números no ficheiro CSV é ambíguo. Por favor selecione o formato correto. Date format: Formato da data: Value format: Formato do valor: ImportQIFDialog Import QIF file Importar ficheiro QIF File Selection Selecção de ficheiros Select a QIF file to import. When you click next, the file be analysed and you might need to answer some questions about the format of the file. Selecione o ficheiro QIF a importar. Ao selecionar próximo, o ficheiro será analisado e poderá ser necessário responder a algumas questões sobre o formato do ficheiro. File: Ficheiro: Local Definitions Definições locais Unknown elements where found in the QIF file. It is possible that this is because of localized type names. Please map them to the correct standard names. Foram encontrados elementos desconhecidos no ficheiro QIF. É possível que tenha a ver com nomes de tipos localizados. Por favor corrija-os para os nomes padrão. Local Text Texto local Standard Text Texto normal Select standard text: Selecione o texto normal: Date Format Formato da data The date format in the QIF file is ambiguous. Please select the correct format. O formato da data no ficheiro é ambíguo. Por favor, seleccione o formato correto. Date format: Formato da data: Default Account Conta predefinida Could not find any account definitions in the QIF file. Please select a default account. It is also possible that this is caused by a localized opening balance text. Impossível encontrar definições de conta no ficheiro QIF. Por favor selecione uma conta predefinida. É possível que o motivo seja um texto localizado no saldo inicial. Default account: Conta predefinida: Opening balance text: Texto do saldo inicial: Descriptions Descrições Transactions in QIF files does not have any specific description property. You are therefore given the option to choose how the description of imported transactions will be set. As transações nos ficheiros QIF não têm propriedades descritivas específicas. Logo, é-lhe dada a opção de escolher como será definida a descrição das transações importadas. Subcategories as: Subcategorias como: Description Descrição Transactions in QIF files does not have any specific description property. You are therefore given the option to choose how the description of imported transactions will be set. Referring to generic description As transações nos ficheiros QIF não têm propriedades descritivas específicas. Logo, é-lhe dada a opção de escolher como será definida a descrição das transações importadas. Category Categoria Ignore Ignorar Payee as: Beneficiário como: Payee Beneficiário Memo as: Memorando como: Comments Comentários Priority: Prioridade: Subcategory/Payee/Comments Subcategoria/Beneficiário/Comentários Payee/Subcategory/Comments Beneficiário/Subcategoria/Comentários Subcategory/Comments/Payee Subcategoria/Comentários/Beneficiário Payee/Comments/Subcategory Beneficiário/Comentários/Subcategoria Comments/Subcategory/Payee Comentários/Subcategoria/Beneficiário Comments/Payee/Subcategory Comentários/Beneficiário/Subcategoria Import File No (further) issues were found. Press finish to import the selected QIF file. Não foram detectatdas (mais) problemas. Carregue em terminar para importar o ficheiro QIF seleccionado. Ignore duplicate transactions Error Erro A file must be selected. Deve selecionar um ficheiro. Selected file is a directory. O ficheiro selecionado é uma pasta. Selected file does not exist. O ficheiro selecionado não existe. Couldn't open %1 for reading. Impossível abrir %1 para leitura. Error reading %1. Erro ao ler %1. Unknown Desconhecido Account Conta Bank Banco Cash Dinheiro Cat (Category) Cat (Categoria) CCard (Credit Card) CCred (Cartão de crédito) Invst (Investment) Invst (Investimento) Oth A (Other Assets) Oth A (outros ativos) Oth L (Other Liabilities) Oth L (outros passivos) Security Título Other Outro Unrecognized date format. Formato de data não reconhecido. Successfully imported %n transaction(s). Importou com sucesso %n transação. Importou com sucesso %n transações. Successfully imported %n account(s). Importou com sucesso %n conta. Importou com sucesso %n contas. Successfully imported %n category/categories. Importou com sucesso %n categoria. Importou com sucesso %n categorias. %n duplicate transaction(s) was ignored. Foi ignorada %n transação duplicada. Foram ignoradas %n transações duplicadas. Failed to import %n transaction(s). Falhou a importação de %n transação. Falhou a importação de %n transações. %n security/securities were not imported. Financial security (e.g. stock, mutual fund) Não foi importada %n título. Não foram importadas %n títulos. %n security transaction(s) were not imported. Financial security (e.g. stock, mutual fund) Não foi importada %n transação de título. Não foram importadas %n transações de títulos. Information Informação Income Dividend: %1 Dividendo: %1 Reinvested dividend: %1 Dividendos reinvestidos: %1 LedgerDialog Account: Conta: Edit Account… Editar conta… Export… Exportar… Print… Imprimir… Reconcile Accounting context Reconciliar Mark all as reconciled Accounting context Change: Accounting context Mudança: R Header for account reconciled checkbox column Date Data Type Tipo Description Descrição Name Nome Description Generic Description Descrição Account/Category Conta/categoria Deposit Depósito Withdrawal Levantamento Balance Balanço Balance Account balance Saldo Payee/Payer Beneficiário/pagador Tags Etiquetas Comments Comentários Deposit Money put into account Depósito Withdrawal Money taken out from account Levantamento Balance Noun. Balance of an account Saldo New Novo Edit… Editar… Delete Apagar Join… join transactions together Juntar… Split Up split up joined transactions Dividir Edit Transaction(s)… Editar transações… Join Transactions… Unir transações… Split Up Transaction Dividir transação Remove Transaction(s) Remover transações Mark as reconciled Reconciled: %1 (%2) Accounting context Reconciliado: %1 (%2) Book value: %1 (%2) Accounting context Valor contabilístico: %1 (%2) Error Erro Invalid date. Data inválida. Opening date is after closing date. Closing date is before opening date. Empty transaction list. Lista de transações vazia. Couldn't open file for writing. Impossível abrir o ficheiro para escrita. Error while writing file; file was not saved. Erro ao gravar o ficheiro: ficheiro não gravado. Ledger Diário Transactions for %1 Transações para %1 Select Time Period From: De: To: Para: To date is before from date. Data final anterior à data inicial. Balance change: Account balance Delete transactions? Apagar transações? Are you sure you want to delete all (%1) selected transactions? Tem a certeza que quer apagar todas (%1) as transações selecionadas? Cannot set the value of security transactions using the dialog for modifying multiple transactions. Financial security (e.g. stock, mutual fund) Impossível definir o valor de transações de títulos usando o diálogo para modificar múltiplas transações. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name); Financial security (e.g. stock, mutual fund) Impossível mudar a descrição de transações de dividendos e títulos. Cannot change payer of dividends and security transactions. Financial security (e.g. stock, mutual fund) Impossível alterar o pagador de transações de dividendos e títulos. Opening balance Account balance Saldo inicial Account Balance Adjustment Ajuste da conta de saldo Current balance: Account balance Saldo atual: Average balance: Account balance Saldo médio: Account Balancing Balancing of an account Balanço da conta Balancing Balancing of an account Balanço Balancing Account balancing Balanço Cannot set the value of security transactions using the dialog for modifying multiple transactions. Impossível definir o valor de transações de seguranças usando o diálogo para modificar múltiplas transações. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name) Impossível mudar a descrição de transações de dividendos e seguranças. Cannot change description of dividends and security transactions. Referring to the generic description property Impossível mudar a descrição de transações de dividendos e seguranças. Current debt: Dívida actual: Total debt reduction: Total interest and fees: Number of transactions: Cannot change description of dividends and security transactions. Impossível mudar a descrição de transações de dividendos e seguranças. Cannot change payer of dividends and security transactions. Impossível alterar o pagador de transações de dividendos e seguranças. Cannot change date of transactions that are part of a split transaction. Impossível alterar a data de transações que fazer parte de uma transação dividida. Split Transaction Dividir transação Debt Payment Ascending order Reduction Redução Fee Interest Dividendo Income Receita Repayment Repagamento Expense Despesa Opening balance: Accounting context Saldo inicial: Closing balance: Accounting context Saldo final: Description Transaction description property (transaction title/generic article name) Descrição Cannot change description of dividends and security transactions. Referring to the Transaction description property (transaction title/generic article name) Impossível mudar a descrição de transações de dividendos e seguranças. Refund Reembolsar Balancing Balanço Transfer Transferência LinksWidget Remove Link Remover link All Todas Remove Remover MultiItemListViewItem Dividend Dividendo Income Receita Repayment Repagamento Expense Despesa Refund Reembolsar Securities Purchase Financial security (e.g. stock, mutual fund) Compra de títulos Securities Sale Financial security (e.g. stock, mutual fund) Venda de títulos Account Balance Adjustment Ajuste da conta de saldo Account Balancing Balancing of an account Balanço da conta Balancing Balancing of an account Balanço Security Buy Compra de seguranças Security Sell Venda de seguranças Balancing Balanço Transfer Transferência MultipleTransactionsEditDialog Modify Transactions Modificar transações Description: Descrição: Name: Nome: Description: Transaction description property (transaction title/generic article name) Descrição: Amount: Montante: Income: Receita: Cost: Custo: Date: Data: Category: Categoria: Payer: Pagador: Payee: Beneficiário: New Income Category Nova categoria de receitas New Expense Category Nova categoria de despesas New Income Category… Nova categoria de receitas New Expense Category… Nova categoria de despesas… Error Erro No income category available. Sem categorias de receitas disponíveis. No expense category available. Sem categorias de despesas disponíveis. Invalid date. Data inválida. OverTimeChart Save As… Gravar como… Print… Imprimir… Source: Fonte: Incomes and Expenses Receitas e despesas Profits Lucros Expenses Despesas Incomes Receitas All Categories Combined Todas as categorias combinadas All Descriptions Combined Todas as descrições combinadas Theme: Chart type: Line Chart Vertical Bar Chart Horizontal Bar Chart Stacked Bar Chart Default Predefinida Tags Etiquetas All Accounts Combined Todas as contas combinadas All Accounts Split Todas as contas divididos All Subcategories and Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Todas as subcategorias e descrições combinadas All Descriptions Split Referring to the transaction description property (transaction title/generic article name) Todas as descições divididas No description Referring to the transaction description property (transaction title/generic article name) Sem descrição All Payees/Payers Split Todos os beneficiários/pagadores divididos No payee/payer Sem beneficiário/pagador All Tags Split Todas as etiquetas divididas Other tags Outras etiquetas Other payees/payers Outras beneficiários/pagadores Other descriptions Referring to the transaction description property (transaction title/generic article name) Outras descrições Profits, %1 Lucros, %1 Assets Ativos All Descriptions Combined Referring to the generic description property Todas as descrições combinadas Assets and Liabilities Ativos e passivos All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Todas as descrições combinadas All Payees/Payers Combined Todos os beneficiários/pagadores combinados All Accounts Todas as contas Start date: Data inicial: End date: Data final: Value: Valor: Annual total Total anual Monthly total Total mensal Daily average Média diária Quantity Quantidade Average value Valor médio All Payers Combined Todos os pagadores combinados All Payees Combined Todos os beneficiários combinados All Subcategories Split Todas as subcategorias divididas All Descriptions Split Referring to the generic description property Todas as descições divididas No description Referring to the generic description property Sem descrição Value Valor Includes budgeted transactions Incluir transações orçamentadas Incomes − Expenses, %1 Rendimentos − despesas, %1 Incomes − Expenses Rendimentos − despesas Incomes & Expenses Rendimentos e despesas Incomes: %1 Receitas: %1 Expenses: %1 Despesas: %1 %2: %1 %2: %1 Incomes: %2, %1 Rendimentos: %2, %1 Expenses: %2, %1 Despesas: %2, %1 %3: %2, %1 %3: %2, %1 %2, %1 %2, %1 Incomes: %3, %2, %1 Rendimentos: %3, %2, %1 Expenses: %3, %2, %1 Despesas: %3, %2, %1 %4: %3, %2, %1 %4: %3, %2, %1 no payee/payer sem beneficiário/pagador %3, %2, %1 %3, %2, %1 Other accounts Outras contas %1 Value: %2 Date: %3 %1 Valor: %2 Data: %3 MMMM yyyy Month and year All Descriptions Split Todas as descições divididas All Payers Split Todos os pagadores divididos All Payees Split Todos os beneficiários divididos No description Sem descrição No payer Sem pagador No payee Sem beneficiário All Categories Split Todas as categorias divididas Error Erro Invalid date. Data inválida. Couldn't open file for writing. Impossível abrir o ficheiro para escrita. Error while writing file; file was not saved. Erro ao gravar o ficheiro: ficheiro não gravado. Other payees Outras beneficiários Other payers Outros pagadores Value (%1) Valor (%1) Profit (%1) Lucro (%1) Income (%1) Receita (%1) Cost (%1) Custo (%1) Time Horas %1/%2 %1: Category; %2: Payee/Payer %1/%2 All Descriptions Combined Referring to the Transaction description property (transaction title/generic article name) Todas as descrições combinadas All Descriptions Split Referring to the Transaction description property (transaction title/generic article name) Todas as descições divididas No description Referring to the Transaction description property (transaction title/generic article name) Sem descrição Daily average value Valor médio diário Daily average profit Lucro médio diário Daily average income Rendimento médio diário Daily average cost Custo médio diário Average income Rendimento médio Average cost Custo médio Annual value Valor anual Annual profit Lucro anual Annual income Rendimento anual Annual cost Custo anual Monthly value Valor mensal Monthly profit Lucro mensal Monthly income Rendimento mensal Monthly cost Custo mensal Includes scheduled and budgeted transactions Incluir transações agendadas e orçamentadas Includes scheduled transactions Inclui transações agendadas Tags, %1 Etiquetas, %1 Value: %1 Valor: %1 Assets & Liabilities Ativos e passivos Change: %1 Mudança: %1 Excluding any profits or losses in trading of security shares Financial security (e.g. stock, mutual fund) Incomes & Expenses, %1 Rendimentos e despesas, %1 Incomes, %1 Receitas, %1 Expenses, %1 Despesas, %1 Incomes, %2: %1 Rendimentos, %2: %1 Expenses, %2: %1 Despesas, %2: %1 Incomes, %3: %2, %1 Rendimentos, %3: %2, %1 Expenses, %3: %2, %1 Despesas, %3: %2, %1 Incomes, %4: %3, %2, %1 Rendimentos, %4: %3, %2, %1 Expenses, %4: %3, %2, %1 Despesas, %4: %3, %2, %1 Liabilities Passivos no payer sem pagador %1/%2 %1: Description; %2: Payer/Payer %1/%2 %1/%2 %1: Description; %2: Payee/Payer %1/%2 %1/%2 %1: Description; %2: Payer %1/%2 no payee sem beneficiário %1/%2 %1: Description; %2: Payee %1/%2 OverTimeChartDialog Chart Gráfico OverTimeReport Save As… Gravar como… Print… Imprimir… Source: Fonte: Profits Lucros Expenses Despesas Incomes Receitas Assets & Liabilities Ativos e passivos Tags Etiquetas All Categories Combined Todas as categorias combinadas All Descriptions Combined Todas as descrições combinadas Columns: Colunas: Categories Categorias Total: Total: Value Valor Daily Diariamente Monthly Mensalmente Yearly Anualmente Quantity Quantidade Average value Valor médio No description Sem descrição All Descriptions Combined Referring to the generic description property Todas as descrições combinadas No description Referring to the generic description property Sem descrição All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Todas as descrições combinadas All Accounts Todas as contas No description Referring to the transaction description property (transaction title/generic article name) Sem descrição Error Erro Couldn't open file for writing. Impossível abrir o ficheiro para escrita. Error while writing file; file was not saved. Erro ao gravar o ficheiro: ficheiro não gravado. Average Profit Lucro médio Incomes, %1 Receitas, %1 Average Income Rendimento médio Expenses, %1 Despesas, %1 Average Cost Custo médio Incomes, %2: %1 Rendimentos, %2: %1 Incomes: %1 Receitas: %1 Expenses, %2: %1 Despesas, %2: %1 Expenses: %1 Despesas: %1 Incomes, %3: %2, %1 Rendimentos, %3: %2, %1 Incomes: %2, %1 Rendimentos: %2, %1 Expenses, %3: %2, %1 Despesas, %3: %2, %1 Expenses: %2, %1 Despesas: %2, %1 Change: %1 Noun, how much the account balance has changed Mudança: %1 Average Change Mudança médio Change Noun, how much the account balance has changed Mudança Value: %1 Valor: %1 Year Ano Month Mês Assets Ativos Deposit Depósito Withdrawal Levantamento Liabilities Passivos %2: %1 %2: %1 %1 %1 Average Value Valor médio %3: %2, %1 %3: %2, %1 %2, %1 %2, %1 Daily Average Média diária Monthly Average Média mensal Yearly Average Média anual Subtotal Subtotal Total Total Deposit Money put into account Depósito Withdrawal Money taken out from account Levantamento Includes scheduled transactions Inclui transações agendadas Adjusted for the average month / year (%1 / %2 days) Ajustado para a média mensal/anual (%1/ %2 dia) All Categories Combined Referring to the generic description property Todas as categorias combinadas OverTimeReportDialog Report Relatório QApplication Start with expenses list displayed Iniciar com a lista de despesas mostrada Start with incomes list displayed Iniciar com a lista de receitas mostrada Start with transfers list displayed Iniciar com a lista de transferências mostrada Synchronize file Document to open Documento a abrir %1 is already running. QObject Transfer Transferência Dividend Dividendo Income Receita Expense Despesa Securities Purchase Financial security (e.g. stock, mutual fund) Compra de títulos Securities Sale Financial security (e.g. stock, mutual fund) Venda de títulos Security Buy Compra de seguranças Security Sell Venda de seguranças Debt Payment Split Transaction Dividir transação RecurrenceEditWidget Enable recurrence Ativar recorrência Recurrence Rule Regra de recorrência Daily Diariamente Weekly Semanalmente Monthly Mensalmente Yearly Anualmente Recur every recorrer a cada day(s) dia(s) week(s) on: semana(s) em: month(s), after the start month mês(meses) após o mês inicial Recur on the Recorrer no 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 10º 11th 11º 12th 12º 13th 13º 14th 14º 15th 15º 16th 16º 17th 17º 18th 18º 19th 19º 20th 20º 21st 21 22nd 22º 23rd 23º 24th 24º 25th 25º 26th 26º 27th 27º 28th 28º 29th 29º 30th 30º 31st 31º Last Último 2nd Last Penúltimo 3rd Last Antepenúltimo 4th Last 4º último 5th Last 5º último day dia possibly on weekend possivelmente no fim de semana but before weekend mas antes do fim de semana but after weekend mas depois do fim de semana nearest weekend day year(s), after the start year ano(s), após o ano inicial on nearest weekday Recur on day part before XXX of 'Recur on day XXX of month YYY' Recorrer no dia of part between XXX and YYY of 'Recur on day XXX of month YYY' de On the Part before NNN in 'Recur on the NNN. WEEKDAY of MONTH' à of part between WEEKDAY and MONTH in 'Recur on NNN. WEEKDAY of MONTH' de Recur on day # Recorrer no dia # of the year part after NNN of 'Recur on day #NNN of the year' do ano Range… Intervalo… Occurrences/Exceptions… Ocorrências/exceções… Exceptions… Exceções… Error Erro No day of week selected for weekly recurrence. Não selecionou dia da semana para recorrência semanal. Selected day will never occur with selected frequency and start date. Com a frequência e data inicial escolhidas, o dia selecionado nunca ocorre. Selected day does not exist in selected month. O dia selecionado não existe no mês escolhido. RefundDialog Repayment Repagamento Refund Reembolsar Date: Data: Cost: Custo: Income: Receita: Quantity returned: Quantidade devolvida: Account: Conta: Quantity: Quantidade: Payee: Beneficiário: Payer: Pagador: Comments: Comentários: Link Link the transactions together Link Join Join the transactions together Unir Error Erro Zero value not allowed. Valor zero não permitido. Invalid date. Data inválida. SecurityBuy Security: %1 (bought) Segurança: %1 (comprada) Security: %1 (bought) Financial security (e.g. stock, mutual fund) Título: %1 (comprada) SecuritySell Security: %1 (sold) Segurança: %1 (vendida) Security: %1 (sold) Financial security (e.g. stock, mutual fund) Título: %1 (vendida) SecurityTransactionsDialog Transactions for %1 Transações para %1 Date Data Type Tipo Value Valor Shares Financial shares Ações Shares Bought Financial shares Ações compradas Shares Bought (Recurring) Financial shares Ações compradas (recorrente) Dividend (Recurring) Dividendo (recorrente) Dividend (Scheduled) Dividendo (agendado) Reinvested Dividend (Recurring) Dividendos reinvestidos (recorrente) Reinvested Dividend (Scheduled) Dividendos reinvestidos (agendado) Shares Bought Fincancial shares Ações compradas Shares Sold Financial shares Ações vendidas Shares Sold (Exchanged) Shares of one security directly exchanged for shares of another; Financial shares Ações vendidas (trocadas) Shares Bought (Exchanged) Shares of one security directly exchanged for shares of another; Financial shares Ações compradas (trocadas) Shares Bought (Recurring) Fincancial shares Ações compradas (recorrente) Shares Sold (Recurring) Financial shares Ações vendidas (recorrente) Shares Bought (Scheduled) Financial shares Ações compradas (agendado) Shares Sold (Scheduled) Financial shares Ações vendidas (agendado) Shares Ações Edit… Editar… Delete Apagar Shares Bought Ações compradas Shares Sold Ações vendidas Dividend Dividendo Reinvested Dividend Dividendos reinvestidos Shares Sold (Traded) Ações vendidas (trocadas) Shares Bought (Traded) Ações compradas (trocadas) Shares Bought (Recurring) Ações compradas (recorrente) Shares Sold (Recurring) Ações vendidas (recorrente) Shares Bought (Scheduled) Ações compradas (agendado) Shares Sold (Scheduled) Ações vendidas (agendado) Recurring Dividend Dividendos recorrentes Scheduled Dividend Dividendos agendados SplitListViewItem Dividend Dividendo Income Receita Repayment Repagamento Expense Despesa Refund Reembolsar Security Buy Compra de seguranças Security Sell Venda de seguranças Balancing Balanço Transfer Transferência TagButton no tags Sem etiqueta TagMenu New tag… Nova etiqueta… New Tag Nova etiqueta Tag: Etiqueta: TransactionEditDialog Edit Expense Editar despesa Edit Dividend Editar dividendo Edit Income Editar receita Edit Transfer Editar transferência Edit Securities Purchase Financial security (e.g. stock, mutual fund) Editar títulos compradas Edit Securities Sale Financial security (e.g. stock, mutual fund) Editar títulos vendidas Edit Reinvested Dividend Edit Securities Bought Editar seguranças compradas Edit Securities Sold Editar seguranças vendidas TransactionEditWidget Security: Segurança: Cost: Custo: Income: Receita: Shares bought: Ações compradas: Shares sold: Ações vendidas All Todas Price per share: Preço por ação: Date: Data: Description: Descrição: Name: Nome: Amount: Montante: Withdrawal: Money taken out from account Levantamento: New Security… Financial security (e.g. stock, mutual fund) Shares added: Financial shares Ações adicionadas: Set security share value Total value: Valor total: Deposit: Money put into account Depósito: Downpayment: Quantity: Quantidade: From: De: To: Para: Category: Categoria: To account: Para a conta: Payer: Pagador: Payer of parent split transaction From account: Da conta: Downpayment account: Conta do pagamento inicial: Payee: Beneficiário: Payee of parent split transaction Beneficiário da transação dividida Lender: Credor: Tags: Etiquetas: Associated file: Arquivo associado: Select a file Open the file Comments: Comentários: Related to: Label for linked transactions Links: New Security Financial security (e.g. stock, mutual fund) Nova segurança No security available. Financial security (e.g. stock, mutual fund) Sem título disponível. New Tag Nova etiqueta Tag: Etiqueta: New Account Nova conta New Income Category Nova categoria de receitas New Expense Category Nova categoria de despesas New Account… Nova conta… New Income Category… Nova categoria de receitas New Expense Category… Nova categoria de despesas… Security: Financial security (e.g. stock, mutual fund) Título: Shares bought: Financial shares Ações compradas: Shares sold: Financial shares Ações vendidas: Price per share: Financial shares Preço por ação: Description: Transaction description property (transaction title/generic article name) Descrição: Transaction title/generic article name Number of items included in the transaction. Entered cost is total cost for all items. Error Erro No suitable account available. Sem conta adequada disponível. No income category available. Sem categorias de receitas disponíveis. No suitable account or income category available. Não há conta ou categoria de rendimento apropriadas disponíveis. No expense category available. Sem categorias de despesas disponíveis. No security available. Sem segurança disponível Invalid date. Data inválida. Cannot transfer money to and from the same account. Não pode ser transferido dinheiro de e para a mesma conta. Downpayment must be less than total cost. Cannot create a regular transfer to/from a securities account. Impossível criar uma transferência regular de/para uma conta de títulos. Cannot create a regular income to a securities account. Impossível criar uma receita regular para uma conta de títulos. Zero shares not allowed. Zero ações não é permitido. Zero value not allowed. Valor zero não permitido. Zero price per share not allowed. Não é permitido preço zero por ação. Cannot create a regular expense from a securities account. Impossível criar uma despesa regular de uma conta de títulos. Loan for %1 TransactionFilterWidget From: De: To: Para: Min amount: Montante mínimo: Max amount: Montante máximo: Category: Categoria: To account: Para a conta: Min income: Receita mínima: Max income: Receita máxima: From account: Da conta: Min cost: Custo mínimo: Max cost: Custo máximo: Tag: Etiqueta: Description: Descrição: Description: Transaction description property (transaction title/generic article name) Descrição: Payer: Pagador: Payee: Beneficiário: Include Incluir Exclude Excluir Exact match Exclude subcategories Clear All Todas Error Erro Invalid date. Data inválida. To date is before from date. Data final anterior à data inicial. From date is after to date. Data inicial posterior à data final. TransactionListWidget Date Data Description Descrição Cost Custo Category Categoria From Account Da conta Payee Beneficiário Tags Etiquetas Income Receita To Account Para a conta Payer Pagador Amount Montante From De To até Comments Comentários Add Addicionar Apply Aplicar Delete Apagar * Part of <a href="%1">split transaction</a> * Parte de <a href="%1">transação dividida</a> Expense Despesa Transfer Transferência Name Nome Description Generic Description Descrição Description Transaction description property (transaction title/generic article name) Descrição New/Edit Expense Nova/editar despesa New/Edit Income Nova/editar receita New/Edit Transfer Nova/editar transferência Filter Filtro Quantity: Quantidade: Total: Total: Average: Média: Clear Cost: Custo: Monthly: Mensalmente: Sort by creation time Expenses Despesas Incomes Receitas Transfers Transferências Quantity Quantidade Right align Alinhar à direita Total cost: Custo total: Total income: Receita total: Total amount: Montante total: Monthly average: Média mensal: Error Erro Cannot set the value of security transactions using the dialog for modifying multiple transactions. Financial security (e.g. stock, mutual fund) Impossível definir o valor de transações de títulos usando o diálogo para modificar múltiplas transações. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name); Financial security (e.g. stock, mutual fund) Impossível mudar a descrição de transações de dividendos e títulos. Cannot change payer of dividends and security transactions. Financial security (e.g. stock, mutual fund) Impossível alterar o pagador de transações de dividendos e títulos. Cannot change date of transactions that are part of a split transaction, unless all individual transactions are selected. Cannot set the value of security transactions using the dialog for modifying multiple transactions. Impossível definir o valor de transações de seguranças usando o diálogo para modificar múltiplas transações. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name) Impossível mudar a descrição de transações de dividendos e seguranças. Cannot change date, description, expense category or payee of transactions that are part of a debt payment using the dialog for modifying multiple transactions. Referring to the transaction description property (transaction title/generic article name) Cannot change description of dividends and security transactions. Referring to the Transaction description property (transaction title/generic article name) Impossível mudar a descrição de transações de dividendos e seguranças. Cannot change description of dividends and security transactions. Referring to the generic description property Impossível mudar a descrição de transações de dividendos e seguranças. Cannot change description of dividends and security transactions. Impossível mudar a descrição de transações de dividendos e seguranças. Cannot change payer of dividends and security transactions. Impossível alterar o pagador de transações de dividendos e seguranças. Cannot change date of transactions that are part of a split transaction. Impossível alterar a data de transações que fazer parte de uma transação dividida. Delete transactions? Apagar transações? Are you sure you want to delete all (%1) transactions in the selected split transaction? Tem a certeza que quer apagar todas as (%1) transações na transação dividida selecionada? Join as multiple accounts/payments? Do you wish join the selected expenses as an expense with multiple accounts/payments? Do you wish join the selected incomes as an income with multiple accounts/payments? Are you sure you want to delete all (%1) selected transactions? Tem a certeza que quer apagar todas (%1) as transações selecionadas? * Part of split transaction Parte de transação dividida * Part of split (%1) * Parte da divisão (%1) ** Recurring (editing occurrence) ** A recorrer (editar ocurrência) Modify… Modificar… Edit… Editar… Eqonomize-1.5.3/translations/eqonomize_pt_BR.ts000066400000000000000000020454551416454732000217000ustar00rootroot00000000000000 Balancing balanço kde-format Couldn't open %1 for reading Não foi possível abrir %1 para leitura kde-format Not a valid Eqonomize! file (XML parse error: "%2" at line %3, col %4) Não é um arquivo Eqonomize! válido (XML parse error: "%2" at line %3, col %4) kde-format Invalid root element %1 in XML document Elemento %1 da raíz inválido no documento XML kde-format Unable to load 1 account. Não foi possível carregar 1 conta. Impossível carregar %n contas. kde-format Unable to load %n accounts. Unable to load 1 category. Impossível carregar 1 categoraia. Impossível carregar %n categorias. kde-format Unable to load %n categories. Unable to load 1 security. Impossível carregar 1 segurança. Impossível carrgar %n seguranças. kde-format Unable to load %n securities. Unable to load 1 transaction. Impossível carregar 1 transação. Impossível carregar %n transações. kde-format Unable to load %n transactions. File is a directory O arquivo é um diretório. kde-format Couldn't open file for writing Impossível abrir o arquivo para editá-lo. kde-format Error while writing file; file was not saved Erro gravando o arquivo; arquivo não foi salvo. kde-format From De kde-format To Para kde-format Source: Fonte: kde-format All Expenses Todos Gastos kde-format All Incomes Todas Receitas kde-format All Accounts Todas as Contas kde-format Expenses: %1 Desepesas: %1 kde-format Incomes: %1 Receitas: %1 kde-format Invalid date. Data Inválida kde-format To date is before from date. Antes da data. kde-format From date is after to date. Depois da data. kde-format The selected file already exists. Would you like to overwrite the old copy? Este arquivo já existe. Deseja substituí-lo? kde-format You selected a directory! Você selecionou um diretório. kde-format Couldn't open file for writing. Não é possível abrir o arquivo para salvá-lo. kde-format Error while writing file; file was not saved. Erro durante o salvamento do arquivo; ele não foi salvo. kde-format No description Nenhuma descrição kde-format All Categories Todas categorias kde-format Descriptions for Descrições para kde-format Payees/payers for Credores/devedores para kde-format Period: Período: kde-format Columns: Colunas: kde-format Value Valor kde-format Daily Diário kde-format Monthly Mensal kde-format Yearly Anualmente kde-format Quantity Quantidade kde-format Average value valor médio kde-format All descriptions todas descrições kde-format All payees Todos Emitentes kde-format All payers Todos sacados kde-format No payee nenhuem emitente kde-format No payer nehum sacado kde-format Expenses: %2, %1 Despesas: %2, %1 kde-format Incomes: %2, %1 Receitas: %2, %1 kde-format Incomes & Expenses Receitas e Despesas kde-format %1 (%2&ndash;%3) html format; %1: title; %2: from date; %3: to date %1 (%2&ndash;%3) kde-format %1 (to %2) html format; %1: title; %2: to date %1 (to %2) kde-format Category Categoria kde-format Cost Custo kde-format Income Renda kde-format Daily Average Balanço do DIa kde-format Monthly Average Balanço do Mês kde-format Yearly Average Balanço Anual kde-format Average Cost Balanço de custo kde-format Average Income BAlanço de Receita kde-format Average Value Balanço de caixa kde-format Total Total kde-format Total incomes Receitas Totais kde-format Total expenses Gastos Totais kde-format Total (Profits) Total (receitas) kde-format Expense Despesa kde-format Transfer Transferir kde-format Security Buy Compra Segura kde-format Security Sell Venda Segura kde-format Recurrence Recorrência kde-format New Expense Nova Despesa kde-format New Dividend Novo Dividendo kde-format New Income Nova Receita kde-format New Transfer Nova Transferência kde-format New Security Buy Nova compra segura kde-format New Security Sell Nova venda segura kde-format Edit Expense Edite a despesa kde-format Edit Dividend Editar Dividendo kde-format Edit Income Editar Receita kde-format Edit Transfer Editar Transfêrencia kde-format Edit Securities Bought Editar seguranças compradas kde-format Edit Securities Sold Editar seguranças vendidas kde-format Dividend Dividendo kde-format Repayment "Re-pagamento" kde-format Refund Reembolso kde-format Split Transaction Dividir Transação kde-format Description: Descrição: kde-format Date: Data: kde-format Account: Conta: kde-format Transactions: Transações kde-format Type Digitar kde-format Description Descrição kde-format Account/Category Conta/Categoria kde-format Payment Pagamento kde-format Deposit Depósito kde-format New Novo kde-format New Expense… Nova despesa… kde-format New Income… Nova receita… kde-format New Deposit… Novo Depósito… kde-format New Withdrawal… Novo saque… kde-format New Security Shares Bought… Nova Compra de Segurança Partilhada kde-format Security Shares Sold… Ações de segurança vendidas… kde-format New Dividend… Novo Dividendo kde-format Edit… Editar… kde-format Total value: Valor Total: kde-format No suitable account available. Nenhuma conta possível avaliável kde-format Future dates is not allowed. Datas futuras não são permitidas. kde-format A split must contain at least two transactions. Para dividir é nescessário no míninmo duas transações. kde-format Cannot transfer money to and from the same account. Não podemos transferir o mesmo dinheiro para a mesma conta. kde-format Cost: Custo: kde-format Income: Renda: kde-format Quantity: Quantidade kde-format Comments: Comentários: kde-format Reinvested Dividend Dividendo Reaplicado kde-format Security: Segurança kde-format Shares added: Ações Adicionadas kde-format Security Trade Negócio Seguro kde-format From security: De segurança. kde-format Shares moved: Ações movidas: kde-format All Tudo kde-format To security: Para segurança. kde-format Shares received: Ações recebidas: kde-format Value: Valor: kde-format No other security available for trade in the account. Nenhuma outra segurança avaliável para negociar na conta. kde-format Selected to and from securities are the same. destino e a origem das seguranças são as mesmas. kde-format Zero shares not allowed. Nenhuma ação não autorizada. kde-format Zero value not allowed. Nnehum valor não autorizado. kde-format Quotations Cotações kde-format Date Data kde-format Price per Share Preço por Ação kde-format Quotations for %1 Cotações para %1 kde-format The following transactions was scheduled to occur today or before today. Confirm that they have indeed occurred (or will occur today). As transações a seguir estavam agendadas para ocorrerem hoje ou ontem. Confirme se elas realmente ocorreram (ou irão ocorrer hoje). kde-format Amount Quantia kde-format Postpone… Adiar… kde-format Can only postpone to future dates. Só pode ser adiado para datas futuras. kde-format Transactions for %1 Transações para %1 kde-format Shares Ações kde-format Shares Bought Ações compradas kde-format Shares Sold Ações vendidas kde-format Shares Sold (Traded) Ações vendidas (Negociada) kde-format Shares Bought (Traded) Ações compradas (Negociada) kde-format Shares Bought (Recurring) Ações compradas (Retornando) kde-format Shares Sold (Recurring) Ações vendidas (Retornando) kde-format Shares Bought (Scheduled) Ações compradas (Agendadas) kde-format Shares Sold (Scheduled) Ações vendidads (Agendadas) kde-format Recurring Dividend Dividendo à ser recorrido kde-format Scheduled Dividend Dividendo agendado kde-format Type: Tipo: kde-format Mutual Fund Fundo Mútuo kde-format Bond Ação kde-format Stock Bolsa kde-format Other Outro kde-format Name: Nome: kde-format Decimals in Shares: Decimais nas ações: kde-format Initial Shares: Ações inicias: kde-format Initial quotation: Cotações iniciais: kde-format No suitable account or income category available. Nenhuma conta possível ou categoria de receita disponível. kde-format Cash Dinheiro kde-format Current Account Conta Atual kde-format Savings Account SAlvando conta kde-format Credit Card Cartão de Crédito kde-format Liabilities Obrigações kde-format Securities Segurança kde-format Initial balance: Balanço inicial kde-format Default account for budgeted transactions Conta principal para transações orçamentadas kde-format Empty name. Nome em branco. kde-format The entered name is used by another account. O nome digitado é usado por uma outra conta. kde-format Monthly budget: Orçamento mensal. kde-format The entered name is used by another income category. O nome digitado já é usado por outra categoria de receita. kde-format The entered name is used by another expense category. O nome digitado já é usado por outra categoria de despesa. kde-format Accounts Contas kde-format Accounts & Categories Contas e Categorias. kde-format Expenses Gastos kde-format Incomes Receitas kde-format Transfers Transferências kde-format Schedule Agenda kde-format Scheduled Transactions Transações agendadas kde-format Account / Category Conta / Categoria kde-format Remaining Budget (%1) Orçamento restante (%1) kde-format Change (%1) Change (%1) kde-format Total (%1) Total(%1) kde-format %2 of %1 %2 remains of %1 budget %2 de %1 kde-format Includes budgeted transactions Incluir transações orçamentadas kde-format Period Período kde-format Select Period Selecione o período kde-format Current Month Mês corrente kde-format Current Year Ano corrente kde-format Current Whole Month Todo o mês corrente kde-format Current Whole Year Todo ano corrente kde-format Whole Past Month Todo mês passado kde-format Whole Past Year Todo ano passado kde-format Previous Month Mês anterior kde-format Previous Year Ano anterior kde-format Show partial budget Mostrar orçamento parcial. kde-format Edit Budget Editar Orçamento kde-format Budget: Orçamento: kde-format Month: Mês: kde-format Result previous month: Resultado do mes anterior. kde-format New Security… Nova securamça… kde-format New Transaction Nova transação kde-format Set Quotation… Definir cotação… kde-format Name Nome kde-format Quotation Cotação kde-format Profit Lucro kde-format Yearly Rate Taxa mais recente kde-format Account Conta kde-format Statistics Period Estatísticas do período kde-format New Schedule Nova agenda kde-format Edit Editar kde-format Next Occurrence Próxima Ocorrência kde-format Comments Comentários kde-format New Security Nova securamça… kde-format Edit Security Editar Segurança kde-format Profit: Renda: kde-format Rate: Taxa: kde-format Are you sure you want to delete the security "%1" and all associated transactions? Você tem certeza que deseja deletar a segurança "%1" e todas suas transações? kde-format No security available. Nenhum asegurança disponível. kde-format Set Quotation (%1) Definir cotação (%1) kde-format Price per share: Preço por ação: kde-format Future dates are not allowed. Datas futuras não são permitidas kde-format Security Transactions Transações de segurança kde-format Ledger Alimentador kde-format Untitled Sem título kde-format Check Account Confirir conta kde-format Salary Salário kde-format Bills Contas kde-format Clothing Vestuário kde-format Groceries Alimentação kde-format Leisure Lazer kde-format Couldn't fetch %1. Impossivel realizar %1 kde-format Error loading %1: %2. Erro carregando %1: %2 kde-format Couldn't open file Não foi possível abrir o arquivo kde-format Error saving %1: %2. Erro salvando %1: %2 kde-format Couldn't save file Não foi possível salvar o arquivo kde-format Failed to upload file to %1. Falhou ao enviar o arquivo para %1 kde-format Report Relatório kde-format Chart Gráfico kde-format Transaction Schedule Agenda de transações kde-format Accounts &amp; Categories html format Contas &amp; Categorias kde-format Accounts &amp; Categories (%1&ndash;%2) html format Contas &amp; Categorias (%1&ndash;%2) kde-format Accounts &amp; Categories (to %1) html format Contas &amp; Categorias (to %1) kde-format Change Change kde-format Balance Balanço kde-format Budget Orçamento kde-format Remaining Budget Orçamento restante kde-format Total Incomes Receitas totais kde-format Costs Custos kde-format Total Expenses Despesas totais kde-format Empty expenses list. Limpar lista de despesas kde-format Empty incomes list. Limpar lista de receitas kde-format Empty transfers list. Limpat lista de transferências kde-format Empty securities list. Lista de seguranças em branco. kde-format Empty schedule list. Lista de agendamentos em branco. kde-format Export View… Exporta vizualização… kde-format Print View… Ver impressão… kde-format Initial Period Período Inicial kde-format Remember Last Dates Lembrar últimas datas kde-format Import CSV File… Importar arquivo CSV kde-format Import QIF File… IMportar arquivo QIF… kde-format Export As QIF File… Exportar como qif… kde-format Add Account… Adicionar Conta… kde-format New Account… Nova conta;;; kde-format New Income Category… Noca categoria de receita… kde-format New Expense Category… Noca categoria de despesa kde-format Balance… Balanço kde-format Show Transactions Exibir transações kde-format New Transfer… Nova transferência kde-format New Split Transaction… Nova transação dividída kde-format Edit Transaction(s) (Occurrence)… Editar Transação(ões) (Ocorrência) kde-format Edit Occurrence… Editar ocorrência kde-format Edit Schedule (Recurrence)… Editar agenda (recorrência) kde-format Edit Schedule… Editar agenda… kde-format Remove Transaction(s) (Occurrence) Remover Transações (ocorrência) kde-format Remove Occurrence Remover Pcorrência kde-format Delete Schedule (Recurrence) Deletar agenda (Reocorrencia) kde-format Delete Schedule Deletar agenda kde-format Edit Split Transaction… Editar dividir transação… kde-format Remove Split Transaction REmover dividir transação kde-format Join Transactions… Juntar translação… kde-format Split Up Transaction Dividir transação kde-format Refund… Fundo renovado… kde-format Repayment… Pagamento renovado… kde-format New Refund/Repayment… Fundo/Pagamento renovaso… kde-format Edit Security… Editar segurança… kde-format Remove Security Remover Segurança kde-format Shares Sold… Ações vendidas kde-format Shares Bought… Ações compradas kde-format Dividend… Dividendo… kde-format Reinvested Dividend… Dividendo reinvestido kde-format Shares Moved… Ações movidas… kde-format Edit Quotations… Editar cotações… kde-format Transactions… Transações… kde-format Development Over Time Report… Relatória de desenvolvimento pelo tempo kde-format Categories Comparison Report… Relatório de comparação de cateforias kde-format Categories Comparison Chart… Tabela de comparação de categorias kde-format Development Over Time Chart… Gráfico de desenvolvimento pelo tempo… kde-format Use Additional Transaction Properties Usar propriedades adicionais das transações kde-format Eqonomize! exited unexpectedly before the file was saved and data was lost. Do you want to load the last auto-saved version of the file? Eqonomize! kde-format Crash Recovery Recuperação de Falhas kde-format The current file has been modified. Do you want to save it? O arquivo atual foi modificado. Você gostaria de salvá-lo? kde-format Confirm Schedule Confirmar agenda kde-format New Account Nova conta kde-format New Income Category Nova categoria de Receitas kde-format New Expense Category Nova gategoria de Despesas kde-format Balance Account Balanço da Conta kde-format Book value: Valor contábil kde-format Real value: Valor real kde-format Edit Account Editar Conta kde-format Edit Income Category Editar categoria de receitas kde-format Edit Expense Category Editar categoria de despesas kde-format Move transactions? Mover transações? kde-format Move to: Mover para: kde-format The category contains some expenses. What do you want to do with them? A categoria contém algumas despesas. O que você gostaria de fazer com elas? kde-format The category contains some incomes. What do you want to do with them? A categoria contém algumas receitas. O que você gostaria de fazer com elas? kde-format The account contains some transactions. What do you want to do with them? A categoria contém algumas transações. O que você gostaria de fazer com elas? kde-format The category contains some expenses that will be removed. Do you still want to remove the category? A categoria contém algumas DESPESAS que serão removidas. Você ainda quer remover a categoria? kde-format Remove Category? Remover Categoria? kde-format The category contains some incomes that will be removed. Do you still want to remove the category? A categoria contém algumas RECEITAS que serão removidas. Você ainda quer remover a categoria? kde-format The account contains some transactions that will be removed. Do you still want to remove the account? A categoria contém algumas TRANSAÇÕES que serão removidas. Você ainda quer remover a categoria? kde-format Remove Account? Remover conta? kde-format %2 of %1 %1: budget; %2: remaining budget %2 de %1 kde-format %1 (with no budget) %1 (sem nhenum orçamento) kde-format %1 (with budget %2) %1 (com orçamento %2) kde-format Import CSV file Importar arquivo CSV kde-format Transaction Type Selection Selecione o tipo da transação kde-format Expenses and incomes (negative cost) Despesas e receitas (custo negativo) kde-format Expenses and incomes (separate columns) Despesas e receitas (colunas separadas) kde-format All types Todos os tipos kde-format File Selection Seleção de Arquivo kde-format File: Arquivo: kde-format First data row: Fila de primero arquivo kde-format Auto Auto kde-format Column delimiter: Deliitador de coluna: kde-format Comma Vírgula kde-format Tabulator Tabulação kde-format Semicolon Ponto e vírgula kde-format Space Espaço kde-format Columns Specification ESpecificações das Colunas kde-format Column Coluna kde-format Category: Categoria: kde-format From account: Da conta: kde-format Create missing categories and accounts Criar categorias e contas que estão faltando. kde-format Imports data as expenses. Costs have positive value. Value is the only required column. mportar conteúdo como despesas. A única coluna necessária é VALOR. kde-format Imports data as incomes. Value is the only required column. Importar conteúdo como receitas. A única coluna necessária é VALOR. kde-format To account: Para conta: kde-format Imports data as transfers. Value is the only required column. Importar dados como transferâncias. A única coluna necessária é Valor. kde-format Amount: Quantidade: kde-format Imports data as expenses and incomes. Costs have negative value. Value and category are both required columns. Importar dados como despesas e receitas. Custos têm valores negaticos. As colunas valor e categoria são necessárias. kde-format Imports data as expenses and incomes. Costs and incomes have separate columns. Income, cost, and category are all required columns. Importar dados como despesas e receitas. Custos e receitas têm colunas separadas. Receitam custo e categoria são todas colunas requeridas. kde-format Imports data as expenses, incomes, and transfers. Costs have negative or positive value. Value, to, and from are all required columns. Accounts and categories must be existing. Importar dados como dspesas, receitas e transferências, Custos têm um valor negativo ou positivo. "Valor", "De" e "Para" são todas colunas necessárias. Contas e Categorias devem existir. kde-format From: De: kde-format To: Para: kde-format A file must be selected. Todos arquivos devem ser selecionados. kde-format Selected file is a directory. O arquivo selecionado é uma pasta. kde-format Selected file does not exist. O aquivo não existe! kde-format Empty delimiter. Limpar delimitador. kde-format The same column number is selected multiple times. O mesmo numero de coluna esta delecionado multíplas vezes. kde-format Selected from account is the same as the to account. A conta de destino e origem são as mesmas kde-format Couldn't open %1 for reading. Não foi possível abrir %1 para ler. kde-format Error reading %1. Erro lendo %1. kde-format Successfully imported 1 transaction. 1 transação importada com sucesso. %n Transações importadas com sucesso. kde-format Successfully imported %n transactions. Unable to import any transactions imported. Impossível importar uma das transações. kde-format Failed to import 1 data row. Falhou ao importar 1 linha de dados. Falhou ao importar %n linhas de dados. kde-format Failed to import %n data rows. Required columns missing. Faltando colunas necessárias kde-format Invalid value. Valor inválido. kde-format Empty category name. Nome de categoria lem branco. kde-format Empty account name. Nome de conta lem branco. kde-format Unknown category found. Nenhuma categoria encontrada. kde-format Unknown account found. Nenhuma conta encontrada. kde-format Cannot import security transactions (to/from security accounts). Não é possíevl importar transações de segurança (de/para contas de segurança) kde-format Balancing account wrongly used. Balanceamento da conta usado errado kde-format Same to and from account/category. Meso destino e origem de conta/xategoria kde-format No data found. Nenhum arquivo encontrado kde-format Unrecognized date format. Formato de data não reconhecido kde-format Specify Format Especifique o formato kde-format The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. O formato de dats e/ou numeros neste arquivo CSV é ambíguo. Por favor selecione o formato correto. kde-format Date format: Formato de data: kde-format Value format: Formato do valor: kde-format tomorrow the day after today amanhã kde-format today this day hoje kde-format yesterday the day before today Ontem kde-format &Today @option today &Hoje kde-format To&morrow @option tomorrow A&manhã kde-format Next &Week @option next week Próxima &semana kde-format Next M&onth @option next month Próximo &Mês kde-format No Date @option do not specify a date Sem Data kde-format Export… Exportar… kde-format Print… Imprimir… kde-format Withdrawal Sacar kde-format Join… Juntar… kde-format Split Up Dividir kde-format Empty transaction list. Lista de transações limpa. kde-format Are you sure you want to delete all (%1) selected transactions? Você tem certeza que deseja deletar todas (%1) transações selecionadas? kde-format Cannot set the value of security transactions using the dialog for modifying multiple transactions. Impossível mudar o valor das transações de segurança usando o diálogo para modificar transações múltiplas. kde-format Cannot change description of dividends and security transactions. Impossível mudar a descrição de dividendos e transações de segurança; kde-format Cannot change payer of dividends and security transactions. Impossível mudar o sacado de dividendos e transações de segurança; kde-format Cannot change date of transactions that are part of a split transaction. Impossível mudar a data das transações que são parte de uma transação divídida. kde-format Eqonomize! Eqonomize! A personal accounting program Um programa de gerenceiamento financeiro pessoal Start with expenses list displayed Começar com a lista de despesas exibidas. Start with incomes list displayed Começar com a lista de receitas vizualizadas. Start with transfers list displayed Começar com a lista de transações vizualizadas. Document to open Documento para abrir Incomes and Expenses Despesas e Receitas kde-format Profits Rendas kde-format All Categories Combined Todas categórias Comibinadas kde-format All Descriptions Combined Todas descrições Comibinadas kde-format All Payees/Payers Combined Todas emitentes/sacados Comibinadas kde-format Start date: Data de início kde-format End date: Data final: kde-format Monthly total Total mensal kde-format Daily average Média diéria kde-format All Payers Combined Todos sacados (pagadores) combinados kde-format All Payees Combined Todos emitentes combinados kde-format All Descriptions Split Todas descrições divídidas kde-format All Payers Split Todos sacados divídidos kde-format All Payees Split Todos emitentes divididos kde-format All Categories Split Todas categorias dividídas. kde-format Value (%1) Valoe (%1) kde-format Profit (%1) Renda (%1) kde-format Income (%1) Lucro (%1) kde-format Cost (%1) Custo (%1) kde-format Time Hora kde-format no payer nenhuma devedor kde-format %1/%2 %1: Description; %2: Payer %1/%2 kde-format no payee nenhum emitente kde-format %1/%2 %1: Description; %2: Payee %1/%2 kde-format Error after saving file; data may not have been saved. Erro depois do salvamento, o conteúdo pode não ter sido salvo. kde-format Average Profit Lucro médio kde-format Year Ano kde-format Month Mês kde-format Includes scheduled transactions Incluir transações agendadas. kde-format Adjusted for the average month / year (%1 / %2 days) Ajustado para média mês/ano (%1 / %2 dias) kde-format Subtotal Subtotal kde-format Unnamed Sem nome kde-format Uncategorized Não categorizado kde-format Import QIF file Importar arquivo QIF kde-format Select a QIF file to import. When you click next, the file be analysed and you might need to answer some questions about the format of the file. Selecionar um arquivo QIF para importar. Quando você clicar em próximo, o arquivo será analisado e talvez seja necessário responder algumas questões sobre o formato do arquivo. kde-format Local Definitions Definições locais, kde-format Unknown elements where found in the QIF file. It is possible that this is because of localized type names. Please map them to the correct standard names. Elementos desconhecidos foram encontrados no arquivo QIF. Isso é possível por arquivos digitados localizados, Por favor mapeiem eles para os padrões corretos. kde-format Local Text Texto local kde-format Standard Text Texto Padrão kde-format Select standard text: Texto padrão selecionado kde-format Date Format Formato da Data kde-format The date format in the QIF file is ambiguous. Please select the correct format. O formato de data deste arquivo QIF é ambíguo. Por favor selecione o formato correto. kde-format Default Account Conta padrão kde-format Could not find any account definitions in the QIF file. Please select a default account. It is also possible that this is caused by a localized opening balance text. Não foi possível achar nenhuma conta definida neste arquivo QIF. Por favor selecione a conta padrão. Isso pode ocorrer por causa de um texto de abertura de balanço localizado. kde-format Default account: Conta padrão: kde-format Opening balance text: Texto de abertura de balanço: kde-format Descriptions Descrições kde-format Transactions in QIF files does not have any specific description property. You are therefore given the option to choose how the description of imported transactions will be set. As transações em arquivos QIF não precisam ter nenhuma descrição própria específicada. Você, tem, então a opção de como a descrição das transações importadas serão definidas. kde-format Subcategories as: Subcategorias como: kde-format Ignore Ignorar kde-format Payee as: Credor como: kde-format Payee Credor kde-format Memo as: Anotações: kde-format Priority: Prioridade kde-format Subcategory/Payee/Comments Subcategoria/Credor/Comentários kde-format Payee/Subcategory/Comments Credor/subcategoria/Comentários kde-format Subcategory/Comments/Payee Subcategoria/Comentários/Credor kde-format Payee/Comments/Subcategory Emitente/Comentários/Subcategorias kde-format Comments/Subcategory/Payee Comentários/Subcategorias/Emitentes kde-format Comments/Payee/Subcategory Comentários/Emitentes/Subcategorias kde-format Unknown Disconhecido kde-format Bank Banco kde-format Cat (Category) Cat (Categoria) kde-format CCard (Credit Card) Ccrédito (Cartão de crédito) kde-format Invst (Investment) Invst (investimento) kde-format Oth A (Other Assets) Oth A (Outros ativos) kde-format Oth L (Other Liabilities) Other L (Outros recursos) kde-format Security Segurança kde-format Successfully imported 1 account. 1 conta importada com sucesso %n contas importadascom sucesso. kde-format Successfully imported %n accounts. Successfully imported 1 category. 1 categoria importada com sucesso %n categorias importadascom sucesso. kde-format Successfully imported %n categories. 1 duplicate transaction was ignored. 1 transação duplicada foi ignorada. %n transações duplicadas foram ignoradas. kde-format %n duplicate transactions was ignored. Failed to import 1 transaction. 1 transação falhou ao importar. %n falharam ao importar. kde-format Failed to import %n transactions. 1 security was not imported. 1 segurança não foi importada. %n seguranças não foram importadas. kde-format %n securities were not imported. 1 security transaction was not imported. 1 transação de segurança não foi importada. %n transações de segurança não foram importadas. kde-format %n security transactions were not imported. Export QIF File Exportar arquivo QIF kde-format All All accounts Tudo kde-format Export transaction description as: Exportar descrição de transações como: kde-format Memo Memorando kde-format Subcategory Subcategoria kde-format &Import i18n: tag text i18n: file ./eqonomizeui.rc line 5 &Importar kde-format &Accounts i18n: tag text i18n: file ./eqonomizeui.rc line 12 &Contas kde-format &Transactions i18n: tag text i18n: file ./eqonomizeui.rc line 24 &Transações kde-format &Securities i18n: tag text i18n: file ./eqonomizeui.rc line 41 &Seguranças kde-format Stat&istics i18n: tag text i18n: file ./eqonomizeui.rc line 56 Stat&isticas kde-format Your names NAME OF TRANSLATORS ,Launchpad Contributions:,Francisco Matelli,Renato Rosa,gabrielgv, ,Launchpad Contributions:,Francisco Matelli,Renato Rosa,Rogério Carbonera,gabrielgv kde-format Your emails EMAIL OF TRANSLATORS ,,emailqueeuleio@gmail.com,,gabriel.velloso@gmail.com,,,emailqueeuleio@gmail.com,,rogerio.carbonera@gmail.com,gabriel.velloso@gmail.com kde-format Edit Exceptions Editar Exceções kde-format Edit Recurrence Range Editar Intervalo de Recorrência kde-format Begins on: %1 Começa em: %1 kde-format No ending date Nenhuma data de término kde-format End after Final depois kde-format occurrence(s) ocorrência(s) kde-format End on Final em kde-format End date before start date. Data de término antes da data de ínicio kde-format Enable recurrence Habilirae Recorrência kde-format Recurrence Rule Regra de Recorrência kde-format Weekly Semanal kde-format Recur every Recorrer sempre kde-format day(s) dia(s) kde-format week(s) on: semana(s) em: kde-format month(s), after the start month mês(es), depois do mês de ínicio kde-format Recur on the Recorrência no kde-format 1st kde-format 2nd kde-format 3rd kde-format 4th kde-format 5th kde-format 6th kde-format 7th kde-format 8th kde-format 9th kde-format 10th 10º kde-format 11th 11º kde-format 12th 12º kde-format 13th 13º kde-format 14th 14º kde-format 15th 15º kde-format 16th 16º kde-format 17th 17º kde-format 18th 18º kde-format 19th 19º kde-format 20th 20º kde-format 21st 21º kde-format 22nd 22º kde-format 23rd 23º kde-format 24th 24º kde-format 25th 25º kde-format 26th 26º kde-format 27th 27º kde-format 28th 28º kde-format 29th 29º kde-format 30th 30º kde-format 31st 31º kde-format Last Última kde-format 2nd Last Penúltima kde-format 3rd Last Antepenúltima kde-format 4th Last Antes da antepenúltima kde-format 5th Last Dois antes da antepenúltima kde-format day dia kde-format possibly on weekend possívelmente no final de semana kde-format but before weekend mas antes do final de semana kde-format but after weekend mas depois do final de semana kde-format year(s), after the start year ano(s), depois do ano de começo kde-format Recur on day part before XXX of 'Recur on day XXX of month YYY' Recurso no dia kde-format of part between XXX and YYY of 'Recur on day XXX of month YYY' of kde-format On the Part before NNN in 'Recur on the NNN. WEEKDAY of MONTH' No kde-format of part between WEEKDAY and MONTH in 'Recur on NNN. WEEKDAY of MONTH' of kde-format Recur on day # Recurso no dia# kde-format of the year part after NNN of 'Recur on day #NNN of the year' do ano kde-format Range… Distância… kde-format Exceptions… Exceções… kde-format No day of week selected for weekly recurrence. Nenhum dia da semana selecionada para a Recorrência semanal. kde-format Selected day will never occur with selected frequency and start date. O dia selecionado nunca ocorrerá com frequência e data inicial. kde-format Selected day does not exist in selected month. O dia selecionado não existe neste mês. kde-format Dividend: %1 Dividendo: %1 kde-format Account balancing Balanceamento da conta kde-format Security: %1 (bought) Segurança: %1 (comprado) kde-format Security: %1 (sold) Segurança: %1 (vendido) kde-format Shares bought: Ações compradas: kde-format Shares sold: Ações vendidas kde-format Payer: Devedor: kde-format Payee: Emitente: kde-format No income category available. Nenhuma categoria de receita avaliável. kde-format No expense category available. Nenhuma categoria de despesa avaliável. kde-format Cannot create a regular transfer to/from a securities account. Impossível criar uma transferância regular de/para contas de segurança. kde-format Cannot create a regular income to a securities account. Impossível crirar receitas regulares em contas de segurança. kde-format Zero price per share not allowed. Preço zero por ação não é permitido. kde-format Cannot create a regular expense from a securities account. Impossível crirar despesas regulares em contas de segurança. kde-format Modify Transactions Modificar Transações kde-format Min amount: Quantia mínima: kde-format Max amount: Quantia máxima: kde-format Min income: Receita mínima: kde-format Max income: Receita máxima: kde-format Min cost: Custo mínimo: kde-format Max cost: Receita máximo: kde-format Include Incluir kde-format Exclude Excluir kde-format From Account Da Conta kde-format To Account Para Conta kde-format Payer Sacado (devedor) kde-format New/Edit Expense Novo/Editar Despesa kde-format Filter Filtro kde-format Total: Total: kde-format Average: Média: kde-format Monthly: Mensalmente: kde-format Total cost: Custo total: kde-format Total income: Receita total: kde-format Total amount: Total: kde-format Monthly average: Balanço mensal kde-format Are you sure you want to delete all (%1) transactions in the selected split transaction? Você tem certeza que quer deletar todas (%1) transações selecionada dessa parcela? kde-format * Part of split transaction *Parte de parcela de um transação. kde-format * Part of split (%1) Parte da parcela (%1) kde-format ** Recurring (editing occurrence) **Recorrendo (editar ocorrência) kde-format Modify… Modificar… kde-format AccountComboBox New account… Nova conta… Multiple accounts/payments… Múltiplas contas/pagamentos… New income category… Nova categoria de receitas… New expense category… Nova categoria de despesas… Paid with loan… Pago com empréstimo… New Account Nova conta New Income Category Nova categoria de receitas New Expense Category Nova categoria de despesas AccountsMenu All Accounts Todas as contas All Categories Combined Todas as categorias combinadas %n accounts %n conta %n contas %n categories %n categoria %n categorias Balancing Account balancing Balanceamento da conta Account balancing Balancing of an account Balanceamento da conta Account Balance Adjustment Ajuste do saldo da conta Budget Balancing balanço Balancing Name of account for transactions that adjust account balances Balanceamento Couldn't open %1 for reading Não foi possível abrir o arquivo %1 para leitura Not a valid Eqonomize! file (XML parse error: "%1" at line %2, col %3) Não é um arquivo Eqonomize! válido (XML parse error: "%1" at line %2, col %3) Invalid root element %1 in XML document Elemento %1 da raíz inválido no documento XML Unknown XML element: "%1" at line %2, col %3 Elemento XML desconhecido: "%1" na linha %2, col %3 XML parse error: "%1" at line %2, col %3 XML parse error: "%1" at line %2, col %3 European Euro Euro europeu Unable to load %n currency/currencies. Não foi possível carregar a moeda %n. Não foi possível carregar as moedas %n. No exchange rates found. Não foram encontradas taxas de câmbio. USD currency missing. Falta a moeda USD. imported importado Unable to load %n account(s). Não foi possível carregar a conta %n. Não foi possível carregar as contas %n. Unable to load %n category/categories. Não foi possível carregar a categoria %n. Não foi possível carregar as categorias %n. Unable to load %n security/securities. Financial security (e.g. stock, mutual fund) Não foi possível carregar %n título. Não foi possível carregar %n títulos. Unable to load %n transaction(s). Não foi possível carregar a transação %n. Não foi possível carregar as transações %n. Download command (%1) failed: %2. Comando de download (%1) falhou: %2. Failed to download file from %1: %2. Falha ao baixar o arquivo de %1: %2. Upload command (%1) failed: %2. Comando para upload (%1) falhou: %2. yyyy-yy Financial year when first month is not January (e.g. 2018-19). yyyy-yy Transaction Accounts Contas de transações Savings Accounts Contas poupança Credit Cards Cartões de crédito Debts Dívidas Securities Financial security (e.g. stock, mutual fund) Títulos Cash Dinheiro Transaction Account Conta de transações Savings Account Conta poupança Credit Card Cartão de crédito Debt Dívida Other Outro File is a directory Arquivo é um diretório Couldn't open file for writing Não foi possível abrir o arquivo para editá-lo Error while writing file; file was not saved Erro ao escrever os dados no arquivo; não foi possível salvá-lo Unnamed Sem nome Uncategorized Não categorizado CategoriesComparisonChart Save As… Salvar como… Print… Imprimir… From De To Até Source: Fonte: All Expenses Todos Gastos All Incomes Todas Receitas Theme: Tema: Chart type: Tipo de gráfico: Pie Chart Gráfico de torta Bar Chart Gráfico de barra Default Padrão All Expenses, without subcategories Todas as despesas, sem subcategorias All Expenses, with subcategories Todas as despesas, com subcategorias All Incomes, without subcategories Todas as receitas, sem subcategorias All Incomes, with subcategories Todas as receitas, com subcategorias All Accounts Todas as contas Expenses: %1 Despesas: %1 Incomes: %1 Receitas: %1 Error Erro Invalid date. Data inválida. To date is before from date. Antes da data. From date is after to date. Depois da data. Couldn't open file for writing. Não foi possível abrir o arquivo para salvá-lo. Error while writing file; file was not saved. Erro ao escrever os dados no arquivo; não foi possível salvá-lo. Expenses Despesas Expenses, %1 Despesas, %1 Incomes, %1 Receitas, %1 Incomes Receitas Accounts Contas Expenses, %2: %1 Despesas, %2: %1 Incomes, %2: %1 Receitas, %2: %1 Other descriptions Referring to the transaction description property (transaction title/generic article name) Outras descrições No description Referring to the transaction description property (transaction title/generic article name) Nenhuma descrição Other accounts Outras contas Other categories Outras categorias %1 Value: %2 %1 Valor: %2 No description Referring to the Transaction description property (transaction title/generic article name) Nenhuma descrição No description Referring to the generic description property Nenhuma descrição Value Valor Income Receita Cost Custo Value (%1) Valoe (%1) Income (%1) Lucro (%1) Cost (%1) Custo (%1) No description Nenhuma descrição CategoriesComparisonChartDialog Chart Gráfico CategoriesComparisonReport Save As… Salvar como… Print… Imprimir… Source: Fonte: All Categories, excluding subcategories Todas as categorias, excluindo subcategorias All Categories, including subcategories Todas as categorias, incluindo subcategorias All Payees/Payers Todos emitentes/sacados Subcategories Subcategorias Descriptions for Referring to the Transaction description property (transaction title/generic article name) Descrições para All descriptions Referring to the Transaction description property (transaction title/generic article name) todas descrições No description Referring to the Transaction description property (transaction title/generic article name) Nenhuma descrição All Categories Todas categorias Expenses: %1 Despesas: %1 Incomes: %1 Receitas: %1 Descriptions for Descrições para Payees/payers for Beneficiários/pagadores para Descriptions Referring to the Transaction description property (transaction title/generic article name) Descrições Period: Período: From De To Até Columns: Colunas: Value Valor Daily O contexto é esse: "o valor: diário, mensal, anual" Diário Monthly Mensal Yearly Anual Quantity Quantidade Average value Valor médio All descriptions todas descrições All payees Todos emitentes All payers Todos sacados No description Nenhuma descrição Descriptions for Referring to the generic description property Descrições para Descriptions Referring to the generic description property Descrições All descriptions Referring to the generic description property todas descrições No description Referring to the generic description property Nenhuma descrição All Payees and Payers Todos os beneficiários e pagadores Tag: %1 Etiqueta: %1 Descriptions for Referring to the transaction description property (transaction title/generic article name) Descrições para Descriptions Referring to the transaction description property (transaction title/generic article name) Descrições Months Meses Years Anos Tags Etiquetas Total: Total: All descriptions Referring to the transaction description property (transaction title/generic article name) Todas as descrições All payees/payers Todos emitentes/sacados No description Referring to the transaction description property (transaction title/generic article name) Nenhuma descrição No payee Nenhum beneficiário No payer Nenhum pagador Error Erro Invalid date. Data inválida. To date is before from date. Antes da data. From date is after to date. Depois da data. Couldn't open file for writing. Não foi possível abrir o arquivo para salvá-lo. Error while writing file; file was not saved. Erro ao escrever os dados no arquivo; não foi possível salvá-lo. Expenses, %2: %1 Despesas, %2: %1 Expenses, %3: %2, %1 Despesas, %3: %2, %1 Incomes, %2: %1 Receitas, %2: %1 Incomes, %3: %2, %1 Receitas, %3: %2, %1 %3: %2, %1 %3: %2, %1 %2: %1 %2: %1 Tags, %1 Etiquetas, %1 Incomes & Expenses, %1 Receitas e Despesas, %1 Expenses: %2, %1 Despesas: %2, %1 Incomes: %2, %1 Receitas: %2, %1 %2, %1 %2, %1 %1 %1 Incomes & Expenses Receitas e Despesas %1 (%2&ndash;%3) html format; %1: title; %2: from date; %3: to date %1 (%2&ndash;%3) %1 (to %2) html format; %1: title; %2: to date %1 (para %2) Category Categoria Payee Beneficiário Description Referring to the transaction description property (transaction title/generic article name) Descrição Cost Custo Payer Pagador Income Receita Payee/Payer Beneficiário/Pagador Tag Etiqueta Daily Average Média diária Monthly Average Média mensal Yearly Average Média anual Average Cost Custo médio Average Income Renda média Average Value Valor médio No payee/payer Nenhum beneficiário/pagador Total Total All Tags Todas as etiquetas Total incomes Receitas totais Total expenses Gastos totais Total (Profits) Total (Lucros) CategoriesComparisonReportDialog Report Relatório ConfirmScheduleDialog The following transactions was scheduled to occur today or before today. Confirm that they have indeed occurred (or will occur today). As transações a seguir estavam agendadas para ocorrerem hoje ou ontem. Confirme se elas realmente ocorreram (ou irão ocorrer hoje). Date Data Type Tipo Description Descrição Name Nome Description Generic Description Descrição Description Transaction description property (transaction title/generic article name) Descrição Amount Quantia Edit… Editar… Postpone… Adiar… Delete Deletar Error Erro Can only postpone to future dates. Só pode ser adiado para datas futuras. ConfirmScheduleListViewItem Transfer Transferir Dividend Dividendo Income Receita Expense Despesa Securities Purchase Financial security (e.g. stock, mutual fund) Compras de títulos Securities Sale Financial security (e.g. stock, mutual fund) Venda de títulos Security Buy Compra Segura Security Sell Venda Segura Debt Payment Pagamento de dívida CurrencyConversionDialog Currency Converter Conversor de moeda DebtFee Debt payment: %1 (fee) Pagamento de dívida %1 (taxas) DebtInterest Debt payment: %1 (interest) Pagamento de dívida: %1 (juros) DebtPayment Debt payment: %1 Pagamento de dívida %1 DebtReduction Debt payment: %1 (reduction) Pagamento de dívida: %1 (redução) DescriptionsMenu All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Todas as descrições combinadas All Tags Combined Todas as etiquetas combinadas All Payees Combined Todos os beneficiários combinados All Payers Combined Todos os pagadores combinados All Payees/Payers Combined Todos os beneficiários/pagadores combinados No description Referring to the transaction description property (transaction title/generic article name) Nenhuma descrição No payee Nenhum beneficiário No payer Nenhum pagador No payee/payer Nenhum beneficiário/pagador %n descriptions Referring to the transaction description property (transaction title/generic article name) %n descrição %n descrições %n tags %n etiqueta %n etiquetas %n payees %n beneficiário %n beneficiários %n payers %n pagador %n pagadores %n payees/payers %n beneficiário/pagador %n beneficiários/pagadores EditAssetsAccountDialog Type: Tipo: Cash Dinheiro Current Account Conta Atual Savings Account Conta poupanças Credit Card Cartão de crédito Liabilities Obrigações Debt Dívida Securities Segurança Other Outro Currency: Moeda: Edit Editar Name: Nome: Bank: Banco: Initial balance: Balanço inicial Group: Grupo: no group nenhum grupo Debt: Dívida: Transferred to: Transferido para: Date: Data: Lender: Quem empresta o dinheiro do empréstimo Credor: Default account for budgeted transactions Conta padrão para transações orçamentadas Description: Descrição: Account is closed Conta está fechada Warning aviso, alerta, atenção!? Aviso Type cannot be changed to securities for accounts with transactions. O tipo de conta não pode ser alterado para contas com transações. Issuer: bandeira do cartão de crédito Emissor: Zero value not allowed. Valor zero não é permitido. Error Erro Transaction Account Conta corrente Opening balance: Account balance Saldo inicial: Opening balance Account balance Saldo inicial New currency… Nova moeda… If you change the currency of an account, the currency of all associated transactions will also change, without any conversion. Do do wish to continue anyway? Se você alterar a moeda de uma conta, todas as transações associadas também sofrerão essa mudança, sem nenhuma conversão. Deseja continuar mesmo assim? Empty name. Nome em branco. The entered name is used by another account. O nome inserido já está sendo utilizado por outra conta. EditCurrencyDialog Edit Currency Editar moeda New Currency Nova moeda Code: Código: Symbol: Símbolo: Prefix Prefixo Suffix Sufixo Default Padrão Name: Nome: Decimals: Decimais: Date: Data: Main currency Moeda principal Error Erro Error saving currencies: %1. Erro ao salvar a moeda: %1. Empty code. Código vazio. Code already exists. Código já existe. EditDebtPaymentDialog Debt Payment Pagamento de dívida EditDebtPaymentWidget Debt: Dívida: Date: Data: Debt reduction: Redução da dívida: Reduction payment: Pagamento de redução: Interest: Juros: Paid Pago Added to debt Adicionado à dívida Fee: Taxa: Account: Conta: Expense category: Categoria de despesas: Associated file: Arquivo associado: Select a file Selecione um arquivo Open the file Abrir o arquivo Comments: Comentários: Related to: Label for linked transactions Links: Total value: Valor total: Error Erro No suitable account available. Não há uma conta adequada disponível. Invalid date. Data inválida. Interest must not be zero. Os juros não devem ser zero. At least one value must non-zero. Pelo menos um valor deve ser diferente de zero. EditExceptionsDialog Edit Exceptions Editar exceções Occurrences: Ocorrências: Add Exception Adicionar exceção Remove Exception Remover exceção Exceptions: Exceções: Only the first fifty occurrences are shown. Somente as primeiras cinquenta ocorrências são exibidas. Invalid date. Data Inválida EditExpensesAccountDialog Name: Nome: Parent category: Categoria mãe: None Nenhuma Monthly budget: Orçamento mensal: Description: Descrição: Error Erro Empty name. Nome em branco. The entered name is used by another expense category. O nome inserido já está sendo utilizado por outra categoria de despesa. EditIncomesAccountDialog Name: Nome: Parent category: Categoria mãe: None Nenhuma Monthly budget: Orçamento mensal: Description: Descrição: Error Erro Empty name. Nome em branco. The entered name is used by another income category. O nome inserido já está sendo utilizado por outra categoria de receita. EditLoanTransactionWidget Date: Data: Account: Conta: Comments: Comentários: Total value: Valor Total: No suitable account available. Nenhuma conta possível avaliável Invalid date. Data Inválida EditMultiAccountDialog Expense with Multiple Payments Despesa com pagamentos múltiplos Income with Multiple Payments Receita com pagamentos múltiplos EditMultiAccountWidget Description: Descrição: Description: Generic Description Descrição: Description: Transaction description property (transaction title/generic article name) Descrição: Quantity: Quantidade: Category: Categoria: Tags: Etiquetas: Associated file: Arquivo associado: Select a file Selecione um arquivo Open the file Abrir o arquivo Comments: Comentários: Related to: Label for linked transactions Links: Transactions: Transações: Date Data Account Conta Payee Beneficiário Payer Pagador Cost Custo Income Receita Total cost: Custo total: Value Valor New Novo Edit… Editar… Delete Deletar Total value: Valor Total: Error Erro No suitable expense categories available. Não há categorias de despesas adequadas disponíveis. A split must contain at least two transactions. tradução um pouco diferente da source Uma transação dividida deve ter, no mínimo, duas partes. EditMultiItemDialog Split Transaction Dividir transação EditMultiItemWidget Description: Descrição: Description: Generic Description Descrição: Date: Data: Account: Conta: Payee/Payer: Beneficiário/pagador: Transactions: Transações: Type Tipo Description Generic Description Descrição Description: Transaction description property (transaction title/generic article name) Descrição: Tags: Etiquetas: Associated file: Arquivo associado: Select a file Selecione um arquivo Open the file Abrir o arquivo Comments: Comentários: Related to: Label for linked transactions Links: Description Transaction description property (transaction title/generic article name) Descrição Payment Pagamento Deposit Depósito New Novo New Expense… Nova despesa… New Income… Nova receita… New Deposit… Novo depósito… New Withdrawal… Novo saque… New Securities Purchase… Financial security (e.g. stock, mutual fund) Nova compra de títulos… New Securities Sale… Financial security (e.g. stock, mutual fund) Nova venda de títulos… Shares Bought… Ações compradas Shares Sold… Ações vendidas Account/Category Conta/Categoria Value Valor Income Receita Expense Despesa New Dividend… Novo dividendo… Edit… Editar… Delete Deletar Total value: Valor total: Error Erro No suitable account available. Não há uma conta adequada disponível. Invalid date. Data inválida. A split must contain at least two transactions. Uma transação dividida deve ter, no mínimo, duas partes. Cannot transfer money to and from the same account. Não é possível transferir dinheiro para a mesma conta de origem. EditQuotationsDialog Quotations Cotações Date Data Price per Share Preço por Ação Quotations Financial quotation Cotações Quotes Financial quote Cotações Price per Share Financial Shares Preço por ação Add Adicionar Modify Modificar Delete Deletar Import… Importar… Export… Exportar… Quotes for %1 Financial quote Cotações para %1 Quotations for %1 Financial quotation Cotações para %1 Quotations for %1 Cotações para %1 Error Erro Couldn't open %1 for reading. Não foi possível abrir o arquivo %1 para leitura. Error reading %1. Erro ao ler o arquivo %1. Successfully imported %n quote(s). %n cotação importada com sucesso. %n cotações importadas com sucesso. Unable to import any quotes. Não foi possível importar nenhuma cotação. Failed to import %n data row(s). Falha ao importar %n linha de dados. Falha ao importar %n linhas de dados. Required columns missing. Colunas necessárias estão faltando. Invalid value. Valor inválido. Invalid date. Data inválida. No data found. Nenhum dado encontrado. Information Informação Unrecognized date format. Formato da data não reconhecido. Specify Format Especifique o formato The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. O formato de datas e/ou números neste arquivo CSV é ambíguo. Por favor selecione o formato correto. Date format: Formato da data: Value format: Formato do valor: Couldn't open file for writing. Não foi possível abrir o arquivo para salvá-lo. Quotes: %1 Cotações: %1 Error while writing file; file was not saved. Erro ao escrever os dados no arquivo; não foi possível salvá-lo. EditRangeDialog Edit Recurrence Range Editar intervalo de recorrência Begins on: %1 Começa em: %1 No ending date Nenhuma data de término End after Finaliza após occurrence(s) ocorrência(s) End on Finaliza em Error Erro Invalid date. Data inválida. End date before start date. Data de término antes da data de ínicio. EditReinvestedDividendDialog Reinvested Dividend Dividendo Reaplicado Security: Segurança Shares added: Ações Adicionadas Security: Financial security (e.g. stock, mutual fund) Segurança Shares added: Financial shares Ações Adicionadas Date: Data: Invalid date. Data Inválida EditScheduledDebtPaymentDialog Transaction Transação Recurrence Recorrência Edit Debt Payment Editar pagamento de dívida New Debt Payment Se refere ao pagamento de um passivo Novo pagamento de dívida EditScheduledLoanTransactionDialog Recurrence Recorrência EditScheduledMultiAccountDialog Transactions Transações Recurrence Recorrência New Expense with Multiple Payments Nova despesa com pagamentos múltiplos New Income with Multiple Payments Nova receita com pagamentos múltiplos Edit Expense with Multiple Payments Editar despesa com pagamentos múltiplos Edit Income with Multiple Payments Editar receita com pagamentos múltiplos EditScheduledMultiItemDialog Transactions Transações Recurrence Recorrência New Split Transaction Nova transação dividida Edit Split Transaction Editar transação dividida EditScheduledTransactionDialog Expense Despesa Dividend Dividendo Income Receita Reinvested Dividend Dividendo reinvestido Transfer Transferir Security Buy Compra Segura Security Sell Venda Segura Securities Purchase Financial security (e.g. stock, mutual fund) Compra de títulos Securities Sale Financial security (e.g. stock, mutual fund) Venda de títulos Recurrence Recorrência New Expense Nova despesa New Expense Paid with Loan Nova despesa paga com empréstimo New Dividend Novo dividendo New Income Nova receita New Transfer Nova transferência New Securities Purchase Financial security (e.g. stock, mutual fund) Nova compra de títulos New Reinvested Dividend Novo dividendo reinvestido New Securities Sale Financial security (e.g. stock, mutual fund) Nova venda de títulos Edit Reinvested Dividend Editar dividendo reinvestido Edit Securities Purchase Financial security (e.g. stock, mutual fund) Editar compra de títulos Edit Securities Sale Financial security (e.g. stock, mutual fund) Editar venda de títulos New Security Buy Nova compra segura New Security Sell Nova venda segura Edit Expense Editar despesa Edit Dividend Editar dividendo Edit Income Editar receita Edit Transfer Editar transfêrencia Edit Securities Bought Editar seguranças compradas Edit Securities Sold Editar seguranças vendidas EditSecurityDialog Type: Tipo: Mutual Fund Fundo mútuo Bond Ação Stock Bolsa Stock Financial stock aparentemente, se refere a quantidade de ações que o usuário já possui Ações financeiras Other Outro Name: Nome: Account: Conta: Decimals in shares: Financial shares Decimais em ações: Initial shares: Financial shares Ações iniciais: Decimals in quotes: Financial quote Decimais em cotações: Initial quote: Financial quote Cotações iniciais: Empty name. Nome em branco. No suitable account available. Não há uma conta adequada disponível. Initial quotation: Financial quotation Cotações iniciais: Decimals in Shares: Decimais nas ações: Initial Shares: Ações inicias: Initial quotation: Cotações iniciais: Date: Data: Description: Descrição: Error Erro No suitable account or income category available. Nenhuma conta possível ou categoria de receita disponível. EditSecurityTradeDialog Security Trade Negócio Seguro From security: De segurança. Shares moved: Ações movidas: All Tudo To security: Para segurança. Shares received: Ações recebidas: Securities Exchange Shares of one security directly exchanged for shares of another; Financial security (e.g. stock, mutual fund) Troca de títulos From security: Financial security (e.g. stock, mutual fund) Do título: Shares moved: Financial shares Ações movidas: To security: Financial security (e.g. stock, mutual fund) Para o título: Shares received: Financial shares Ações recebidas: Value: Valor: Date: Data: Error Erro No other security available for exchange in the account. Shares of one security directly exchanged for shares of another; Financial security (e.g. stock, mutual fund) Nenhum outro título disponível para fazer a troca nessa conta. No other security available for trade in the account. Nenhuma outra segurança avaliável para negociar na conta. Selected to and from securities are the same. Financial security (e.g. stock, mutual fund) Destino e origem dos títulos são os mesmos. Zero shares not allowed. Financial shares Não são permitidas ações zero. Selected to and from securities are the same. destino e a origem das seguranças são as mesmas. Invalid date. Data inválida. Zero shares not allowed. Nenhuma ação não autorizada. Zero value not allowed. Nnehum valor não autorizado. EditSplitDialog Split Transaction Dividir Transação Description: Descrição: Date: Data: Account: Conta: Transactions: Transações Type Digitar Description Descrição Name: Nome: Name Nome Description Generic Description Descrição Account/Category Conta/Categoria Payment Pagamento Deposit Depósito New Novo New Expense… Nova despesa… New Income… Nova receita… New Deposit… Novo Depósito… New Withdrawal… Novo saque… Shares Bought… Ações compradas Shares Sold… Ações vendidas New Dividend… Novo Dividendo Edit… Editar… Total value: Valor Total: No suitable account available. Nenhuma conta possível avaliável Invalid date. Data Inválida Future dates is not allowed. Datas futuras não são permitidas. A split must contain at least two transactions. Para dividir é nescessário no míninmo duas transações. Cannot transfer money to and from the same account. Não podemos transferir o mesmo dinheiro para a mesma conta. Eqonomize Accounts && Categories Contas e categorias Expenses Despesas Incomes Receitas Transfers Transferências Transaction Accounts Contas correntas Savings Accounts Contas poupanças Credit Cards Cartãos de crédito Debts Dívidas Securities Segurança Schedule Agenda Account / Category Conta / categoria Remaining Budget (%1) Orçamento restante (%1) Change (%1) Change (%1) Total (%1) Total(%1) %2 of %1 %2 remains of %1 budget %2 de %1 Accounts Contas Includes budgeted transactions Incluir transações orçamentadas Tags Etiquetas Period Período From De To Se refere ao período de transações (data) Até Select Period Selecione o período Current Month Mês corrente Current Year Ano corrente Current Whole Month Todo o mês corrente Current Whole Year Todo ano corrente Whole Past Month Todo mês passado Whole Past Year Todo ano passado Previous Month Mês anterior Previous Year Ano anterior Show partial budget Mostrar orçamento parcial Edit Budget Editar orçamento Budget: Orçamento: Month: Mês: Result previous month: Resultado do mês anterior: New Security… Nova securamça… New Transaction Nova transação Set Quotation… Definir cotação… Name Nome Value Valor Shares Ações Quotation Cotação Cost Custo Profit Lucro Yearly Rate Taxa anual Type Tipo Account Conta Statistics Period Estatísticas do período New Schedule Se refere a adição de transações à agenda (evento ou programação ou agendamento) Novo evento Edit Editar Remove Remover Next Occurrence Próxima ocorrência Description Descrição Description Generic Description Descrição Amount Quantia Payee/Payer Beneficiário/pagador Comments Comentários Set Schedule Confirmation Time Tradução feita com mais informações do que o texto original pois é um campo que precisa passar mais informações ao usuário Definir horário de confirmação dos eventos da agenda Schedule confirmation time: Horário de confirmação dos eventos da agenda Set Budget Period Definir período do orçamento First day in budget month: Primeiro dia do mês do orçamento: 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 10º 11th 11º 12th 12º 13th 13º 14th 14º 15th 15º 16th 16º 17th 17º 18th 18º 19th 19º 20th 20º 21st 21º 22nd 22º 23rd 23º 24th 24º 25th 25º 26th 26º 27th 27º 28th 28º Last Última 2nd Last Penúltima 3rd Last Antepenúltima 4th Last Antes da antepenúltima 5th Last Dois antes da antepenúltima Timestamp para o contexto (editar data e hora da transação), é a melhor tradução Data/Hora Links Remove Link Remover ligação Link to "%1" create link to transaction (link used as verb) Link a "%1" Information Informação All Tudo Import Options nome da caixa de diálogo Opções da importação Ignore duplicate transactions Ignorar transações duplicadas Rename duplicate accounts Renomear contas duplicadas Rename duplicate categories Renomear categorias duplicadas Rename duplicate securities Renomear títulos duplicados Synchronization Settings Configurações de sincronização Web address: Endereço web: Download command: Comando de download: Duplicate Transaction… duplicate as verb Duplicar transação… Create Link create link to or between transaction(s) Criar ligação New Tag… Nova etiqueta… Rename Tag… Renomear etiqueta… Remove Tag Remover etiqueta New Tag Nova etiqueta Tag name: Nome da etiqueta: Remove tag? Remover etiqueta? Do you wish to remove the tag "%1" from %n transaction(s)? Você deseja remover a etiqueta "%1" da transação %n? Você deseja remover a etiqueta "%1" das transações %n? Rename Tag Renomear etiqueta optional opcional Link Transactions create link between selected transactions (link used as verb) Link as transações Create Link to Transaction Criar link para transação Upload command: Comando para enviar: mandatory obrigatório Automatic synchronization Sincronização automática Upload Enviar Uploading… Carregando… Error uploading file Erro ao enviar o arquivo Error uploading %1: %2. Erro ao enviar %1: %2. Synchronizing… Sincronizando… Error synchronizing file Erro ao sincronizar o arquivo Error synchronizing %1: %2. Erro ao sincronizar %1: %2. Synchronization error Erro de sincronização Synchronize file? Arquivo de sincronização? The file has been modified by a different user or program. Do you wish to merge changes? Esse arquivo foi modificado por um usuário ou programa diferente. Você deseja mesclar as alterações? New version available Nova versão disponível A new version of %1 is available.<br><br>You can get version %2 at %3. Uma nova versão do %1 está disponível.<br><br>Você pode obter a versão %2 em %3. Abort Abortar First month in budget year: Primeiro mês do ano orçamentário: Right align Alinhar à direita %f = local file (temporary), %u = url %f = arquivo local (temporário), %u = url Failed to download exchange rates from %1: %2. Falha ao fazer o download das taxas de câmbio de %1: %2. Error reading data from %1: %2. Erro ao ler os dados de %1: %2. Unrecognized Currency Moeda desconhecida No exchange rate is available for the default currency (%1). If you wish to use multiple currencies you should set the exchange rate manually. Nenhuma taxa de câmbio está disponível para a moeda padrão (%1). Se você deseja utilizar múltiplas moedas você deve configurar a taxa de câmbio manualmente. Set Main Currency Definir a moeda principal Currency: Moeda: Replace all occurrences of the former main currency Substituir todas as ocorrências da antiga moeda principal Transaction Account Conta corrente S&ynchronize S&incronizar Import %1 File… Importar arquivo %1… Reconcile Account… Reconciliar a conta… Adjust balance… Referring to account balance Ajustar o balanço da conta… Close Account Mark account as closed Fechar a conta New Expense Paid with Loan… Nova despesa paga com empréstimo… Show payee and quantity Exibir beneficiário e quantidade Show quantity and payer/payee properties for incomes and expenses. Exibir quantidade e pagador/beneficiário para receitas e despesas. Set Schedule Confirmation Time… Definir horário de confirmação… Select Font… Selecionar fonte… Language Idioma Default Padrão Restart required Reinício necessário Only use this when unable to find the cause of the incorrect recorded account balance. Caixa de diálogo para ajustar o saldo da conta para corrigir eventuais erros ou falta de registros. Somente use isso quando não conseguir identificar a causa do saldo incorreto registrado. Reopen Account Mark account as not closed Reabrir a conta New Debt Payment… Novo pagamento de dívida… New Unpaid Interest… Novos juros não pagos… Shares Exchanged… Shares of one security directly exchanged for shares of another; Financial shares Ações trocadas… Shares of one security directly exchanged for shares of another Financial shares Ações de um título diretamente trocadas por ações de outro Edit Quotes… Financial quote Editar cotações… Use Exchange Rate for Transaction Date Use a taxa de câmbio para a data da transação Use the exchange rate nearest the transaction date, instead of the latest available rate, when converting the value of transactions. Use a taxa de câmbio mais próxima da data da transação, ao invés da última taxa disponível, ao converter o valor das transações. %1 exited unexpectedly before the file was saved and data was lost. Do you want to load the last auto-saved version of the file? Um pouco diferente da versão em inglês mas tem um diálogo bem melhorado O %1 foi fechado inesperadamente antes que o arquivo fosse salvo e dados podem ter sido perdidos. Uma versão salva automaticamente está disponível, você deseja carregá-la? Eqonomize! Accounting File Arquivo de conta do Eqonomize! Adjust Account Balance Ajustar o saldo da conta New Security Nova securamça… Edit Security Editar Segurança Total value: Valor total: Cost: Custo: Profit: Lucro: Rate: Taxa: Are you sure you want to delete the security "%1" and all associated transactions? Você tem certeza que deseja deletar a segurança "%1" e todas suas transações? Error Erro No security available. Nenhum asegurança disponível. Set Quotation (%1) Definir cotação (%1) Price per share: Preço por ação: Date: Data: Invalid date. Data inválida. Future dates are not allowed. Datas futuras não são permitidas. Security Transactions Transações de segurança Bond Obrigação? Ação Stock Bolsa Mutual Fund Fundo mútuo Other Outro Add Loan Adicionar empréstimo Add Category Adicionar categoria Ledger "Livro Razão" é a tradução direta mas se refere a um termo mais técnico para escritórios de contabilidade Livro de registros To date is before from date. Antes da data. From date is after to date. Depois da data. Cash Dinheiro Check Account Confirir conta Savings Account Contas poupança Salary Salário Bills Contas Clothing Vestuário Groceries Mercearias Leisure Lazer Couldn't open file Não foi possível abrir o arquivo Error loading %1: %2. Erro durante o carregamento do %1: %2. Couldn't save file Não foi possível salvar o arquivo Error saving %1: %2. ou: "Erro ao salvar o arquivo...?" Erro ao salvar o %1: %2. Updating exchange rates… Atualizando taxas de câmbios... Error saving currencies: %1. Erro ao salvar as moedas: %1. New currency… Nova moeda… Transaction Schedule Agenda de transações Total Total Accounts &amp; Categories html format Contas &amp; Categorias Accounts &amp; Categories (%1&ndash;%2) html format Contas &amp; Categorias (%1&ndash;%2) Accounts &amp; Categories (to %1) html format Contas &amp; Categorias (to %1) Change Noun, how much the account balance has changed Coluna que mostra o valor movimentado na categoria/conta Movimentado Balance Balanço Current Account Conta atual Credit Card Cartão de crédito Liabilities Passivos Set Quote… Financial quote Definir cotação… Quote Financial quote Cotação Set Quote (%1) Financial quote Definir cotação (%1) Stock Financial stock Ação Balance Noun. Balance of an account Saldo Category Categoria Budget Orçamento Remaining Budget Orçamento restante Total Incomes Receitas totais Costs Custos Total Expenses Despesas totais Account/Category Noun, how much the account balance has changed Conta/categoria Empty expenses list. acredito que se refiram ao resultado de um relatório, não a uma ação (limpar). Lista de despesas limpa. Empty incomes list. Lista de receitas limpa. Empty transfers list. Lista de transferências limpa. Empty securities list. Lista de seguranças em branco. Empty schedule list. Lista de eventos vazia. Couldn't open file for writing. Não foi possível abrir o arquivo para salvá-lo. Error while writing file; file was not saved. Erro ao escrever os dados no arquivo; não foi possível salvá-lo. &File &Arquivo &Accounts &Contas &Transactions &Transações &Securities &Seguranças Stat&istics E&statísticas S&ettings C&onfigurações &Help A&juda File Arquivo Transactions Transações Statistics Estatísticas &New &Novo &Open… &Abrir… Open Recent Abrir recente Clear List Limpar lista &Save &Salvar Save As… Salvar como… &Revert &Reverter &Print… &Imprimir… Print Preview… Pré-visualização da impressão… Import Importar Import CSV File… Importar arquivo CSV… Import QIF File… Importar arquivo QIF… Export View… Exportar visualização… Export As QIF File… Exportar como um arquivo QIF… Update Exchange Rates Atualizar taxas de câmbio Currency Converter Conversor de moeda &Quit &Sair Add Account… Adicionar conta… New Account… Nova conta… New Loan… Novo empréstimo… New Income Category… Nova categoria de receita… New Expense Category… Nova categoria de despesa… Add Account Adicionar conta Assets Ativos Description Transaction description property (transaction title/generic article name) Descrição Security Transactions Financial security (e.g. stock, bond) Transações de segurança Edit… Editar… Balance… Balanço Show Transactions Exibir transações Show Ledger Essa opção lista todas as transações de todas as contas e categorias Mostrar o livro de registros New Expense… Nova despesa… New Income… Nova receita… New Transfer… Nova transferência… New Split Transaction… Nova transação dividida… New Expense with Multiple Payments… Nova despesa com pagamentos múltiplos… Refund… Ambos, "Refund e repayment" serão traduzidos para reembolso. Reembolso… Repayment… Ambos, "Refund e repayment" serão traduzidos para reembolso. Reembolso… New Refund/Repayment… Novo reembolso… Edit Transaction(s) (Occurrence)… Editar transação(ões) (ocorrência)… Edit Occurrence… Editar ocorrência… Edit Schedule (Recurrence)… Editar evento (recorrência)… Edit Schedule… Editar evento… Edit Split Transaction… Editar transação dividida… Join Transactions… join transactions together Unir transações… Split Up Transaction split up joined transactions Dividir a transação Edit Timestamp… Editar Data/Hora… Select Associated File Selecionar arquivo associado Open Associated File Abrir arquivo associado Remove Transaction(s) (Occurrence) Remover transação(ões) (ocorrência) Remove Occurrence Remover ocorrência Delete Schedule (Recurrence) Deletar evento (recorrência) Delete Schedule se refere apenas a um evento único, não a agenda completa Deletar evento Remove Split Transaction Se refere a parte ou o todo da transação dividida? não ficou claro. Remover transação dividida Edit Security… Editar segurança… Remove Security Remover Segurança Shares Bought… Ações compradas Shares Sold… Ações vendidas Shares Moved… Ações movidas… Dividend… Dividendo… Reinvested Dividend… Dividendo reinvestido… Transactions… Transações… Edit Quotations… Editar cotações… Development Over Time Report… Relatório de desenvolvimento ao longo do tempo… Categories Comparison Report… Relatório de comparação de categorias… Development Over Time Chart… Gráfico de desenvolvimento ao longo do tempo… Categories Comparison Chart… Gráfico de comparação de categorias… Use Additional Transaction Properties Usar propriedades adicionais das transações Set Main Currency… Definir moeda principal… Set Budget Period… Essa string se refere ao período em que os orçamentos devem ser considerados Definir período para os orçamentos… Initial Period Período inicial Remember Last Dates Lembrar datas recentes Backup Frequency Frequência do backup Daily Diariamente Weekly Semanalmente Fortnightly Quinzenalmente Monthly Mensalmente Never Nunca Cloud Synchronization (experimental)… Sincronização com a nuvem (experimental)… Dark Mode Tema escuro Help Ajuda Report Bug Reportar um bug About %1 sobre O eqonomize Sobre o %1 About Qt Sobre o Qt Please restart the application for the language change to take effect. Por favor, reinicie a aplicação para que a alteração de idioma tenha efeito. A personal accounting program Um programa de gerenciamento financeiro pessoal License: GNU General Public License Version 3 Licença: GNU General Public License Version 3 Crash Recovery É exibida quando o eqonomize é aberto depois de ser fechado inesperadamente Recuperação de falhas Untitled Sem título Securities Financial security (e.g. stock, mutual fund) Títulos New Security… Financial security (e.g. stock, mutual fund) Novo título… Set Quotation… Financial quotation Definir cotação… Shares Financial shares Ações Quotation Financial quotation Cotação New Security Financial security (e.g. stock, mutual fund) Novo título Edit Security Financial security (e.g. stock, mutual fund) Editar título Delete security? Financial security (e.g. stock, mutual fund) Deletar título? Are you sure you want to delete the security "%1" and all associated transactions? Financial security (e.g. stock, mutual fund) Você tem certeza que deseja deletar o título "%1" e todas as suas transações associadas? No security available. Financial security (e.g. stock, mutual fund) Nenhum asegurança disponível. Set Quotation (%1) Financial quotation Definir cotação (%1) Price per share: Financial shares Preço por ação: Security Transactions Financial security (e.g. stock, mutual fund) Transações de títulos Checking Account Transactional account Conta corrente Balance Account balance Balanço Empty securities list. Financial security (e.g. stock, mutual fund) Lista de títulos vazia. &Loans &Empréstimos &Securities Financial security (e.g. stock, mutual fund) o ideal seria o "í", mas como ele possui um acento, não é possível utilizar a combinação ALT+I para ativar o menu Tít&ulos Balance… Balance account Balanço Edit Security… Financial security (e.g. stock, mutual fund) Editar título… Remove Security Financial security (e.g. stock, mutual fund) Remover título Shares Bought… Financial shares Ações compradas… Shares Sold… Financial shares Ações vendidas… Edit Quotations… Financial quotation Editar cotações… The current file has been modified. Do you want to save it? O arquivo atual foi modificado. Você gostaria de salvá-lo? Save file? Salvar o arquivo? Confirm Schedule Confirmar evento New Account Nova conta New Loan Novo empréstimo New Income Category Nova categoria de receitas New Expense Category Nova gategoria de despesas Balance Account Balanço da Conta Book value: Valor contábil: of which %1 is balance adjustment Referring to account balance dos quais %1 são ajustes de saldo Real value: Valor real: Edit Account Editar conta Edit Income Category Editar categoria de receitas Edit Expense Category Editar categoria de despesas Remove subcategories? Remover subcategorias? Do you wish to remove the category including all subcategories? Você deseja remover a categoria junto com todas as suas subcategorias? Move transactions? Mover transações? Move to: Mover para: Remove irreversibly from all accounts (do not do this if account has been closed!) Remover irreversivelmente de todas as contas (não faça isso se a conta tiver sido fechada!) The category contains some expenses. What do you want to do with them? A categoria contém algumas despesas. O que você gostaria de fazer com elas? The category contains some incomes. What do you want to do with them? A categoria contém algumas receitas. O que você gostaria de fazer com elas? The account contains some transactions. What do you want to do with them? A categoria contém algumas transações. O que você gostaria de fazer com elas? Remove Category? Remover categoria? The category contains some expenses that will be removed. Do you still want to remove the category? A categoria contém algumas despesas que também serão removidas. Você ainda deseja removê-la? The category contains some incomes that will be removed. Do you still want to remove the category? A categoria contém algumas receitas que também serão removidas. Você ainda deseja removê-la? Remove Account? Remover conta? The account contains some transactions that will be removed. Do you still want to remove the account? A categoria contém algumas transações que serão removidas. Você ainda deseja remover a categoria? %2 of %1 %1: budget; %2: remaining budget %2 de %1 Balance… Verb. Balance an account Balanço Balance Account Verb Balanço da Conta %1 (with no budget) %1 (sem nenhum orçamento) %1 (with budget %2) %1 (com orçamento %2) EqonomizeCalendarWidget Today Hoje EqonomizeDateEdit Today Hoje EqonomizeTranslator OK Only used when Qt translation is missing OK Cancel Only used when Qt translation is missing Cancelar Close Only used when Qt translation is missing Fechar &Yes Only used when Qt translation is missing &Sim &No Only used when Qt translation is missing &Não &Open Only used when Qt translation is missing &Abrir &Save Only used when Qt translation is missing &Salvar &Select All Only used when Qt translation is missing &Selecionar tudo Look in: Only used when Qt translation is missing falta contexto para realizar a tradução correta Procurar em: File &name: Only used when Qt translation is missing Nome do &arquivo: Files of type: Only used when Qt translation is missing Arquivos do tipo: EqonomizeValueEdit Error Erro Empty denominator. Denominador vazio. Empty factor. Fator vazio. Division by zero. Divisão por zero. Unknown or ambiguous currency, or unrecognized characters, in expression: %1. Moeda desconhecida ou ambígua, ou caracteres não reconhecidos, na expressão: %1. Empty base. Base vazia. Empty exponent. Expoente vazio. Unrecognized characters in expression. Caracteres desconhecidos na expressão. ExportQIFDialog Export QIF File Exportar arquivo QIF Account: Conta: All All accounts Tudo Export transaction description as: Exportar descrição de transações como: Export transaction description as: Referring to generic description Exportar descrição de transações como: Payee Credor Memo Memorando Subcategory Subcategoria Date format: Formato da data: Value format: Formato do valor: File: Arquivo: Error Erro Selected file is a directory. O arquivo selecionado é um diretório. Overwrite Sobrescrever The selected file already exists. Would you like to overwrite the old copy? O arquivo selecionado já existe. Deseja substituí-lo? You selected a directory! Você selecionou um diretório. Couldn't open file for writing. Não foi possível abrir o arquivo para salvá-lo. Error while writing file; file was not saved. Erro ao escrever os dados no arquivo; não foi possível salvá-lo. ImportCSVDialog Import CSV file Importar arquivo CSV Transaction Type Selection Selecione o tipo da transação Expenses Despesas Incomes Receitas Transfers Transferências Expenses and incomes (negative cost) Despesas e receitas (custo negativo) Expenses and incomes (separate columns) Despesas e receitas (colunas separadas) All types Todos os tipos Presets: Predefinições: File Selection Seleção de arquivo File: Arquivo: First data row: Primeira linha de dados: Auto Automático? Auto Column delimiter: Delimitador de coluna: Comma Vírgula Tabulator Tabulação Semicolon Ponto e vírgula Space Espaço Other Outro Columns Specification Especificações das colunas Save as preset… Salvar como predefinição… Imports data as expenses and incomes. Costs have negative value. Value is the only required column. Importar dados como despesas e receitas. Custos têm valores negativos. A única coluna necessária é a 'Valor'. Imports data as expenses and incomes. Costs and incomes have separate columns. Income and cost both all required columns. Importar dados como despesas e receitas. Custos e receitas têm colunas separadas. As colunas 'Receitas' e 'Custo' são necessárias. Warning Alerta The same column number is selected multiple times. Do you wish to proceed anyway? Uma coluna de mesmo número foi selecionada várias vezes. Você deseja proceder mesmo assim? Description: Descrição: Description: Transaction description property (transaction title/generic article name) Descrição: Column Coluna Value Valor Cost: Custo: Date: Data: Category: Categoria: From account: Da conta: Quantity: Quantidade: Payee: Beneficiário: Tags: Etiquetas: Comments: Comentários: Create missing categories and accounts Criar categorias e contas que estão faltando Save Preset Salvar predefinição Imports data as expenses. Costs have positive value. Value is the only required column. Importar os dados como receitas. Custos tem valor positivo. A única coluna obrigatória é o 'Valor'. Imports data as incomes. Value is the only required column. Importar os dados como receitas. A única coluna necessária é o 'Valor'. Income: Receita: To account: Para a conta: Payer: Pagador: Imports data as transfers. Value is the only required column. Importar os dados como transferências. A única coluna necessária é o 'Valor'. Amount: Quantidade: Imports data as expenses and incomes. Costs have negative value. Value and category are both required columns. Importar dados como despesas e receitas. Custos têm valores negaticos. As colunas valor e categoria são necessárias. Value: Valor: Account: Conta: Payee/payer: Beneficiário/pagador: Imports data as expenses and incomes. Costs and incomes have separate columns. Income, cost, and category are all required columns. Importar dados como despesas e receitas. Custos e receitas têm colunas separadas. Receitam custo e categoria são todas colunas requeridas. Imports data as expenses, incomes, and transfers. Costs have negative or positive value. Value, to, and from are all required columns. Accounts and categories must be existing. Accounts and categories must be existing. Importar os dados como despesas, receitas e transferências. Custos tem valor negativo ou positivo. As colunas 'Valor', 'Para' e 'De' são necessárias. Contas e Categorias devem ser existentes. From: De: To: Para: Error Erro A file must be selected. Um arquivo deve ser selecionado. Selected file is a directory. O arquivo selecionado é um diretório. Selected file does not exist. O arquivo selecionado não existe. Empty delimiter. Delimitador vazio. The same column number is selected multiple times. O mesmo numero de coluna esta delecionado multíplas vezes. Selected from account is the same as the to account. A conta de destino e origem são as mesmas. Invalid date. Data inválida. Couldn't open %1 for reading. "Não foi possível abrir O ARQUIVO %1 para ler."? Não foi possível abrir %1 para ler. Error reading %1. "Erro ao ler O ARQUIVO %1."? Erro ao ler %1. Uncategorized Não categorizado Successfully imported %n transaction(s). %n transação foi importada com sucesso. %n transações foram importadas com sucesso. Unable to import any transactions. Não foi possível importar nenhuma transação. Failed to import %n data row(s). Falha ao importar %n linha de dado. Falha ao importar %n linhas de dados. Required columns missing. Colunas necessárias estão faltando. Invalid value. Valor inválido. Empty category name. Nome de categoria em branco. Empty account name. Nome da conta em branco. Unknown category found. Nenhuma categoria encontrada. Unknown account found. Nenhuma conta encontrada. Cannot import security transactions (to/from security accounts). Não é possível importar transações de segurança (de/para contas de segurança). Balancing account wrongly used. Referring to the account used for adjustments of account balances. Balanceamento da conta usado de maneira errada. Balancing account wrongly used. Balanceamento da conta usado errado Same to and from account/category. Mesmo destino e origem de conta/categoria. No data found. Nenhum dado encontrado. Information Informação Unrecognized date format. Formato de data não reconhecido. Specify Format Especifique o formato The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. O formato da data e/ou números neste arquivo CSV é ambíguo. Por favor, selecione o formato correto. Date format: Formato da data: Value format: Formato do valor: ImportQIFDialog Import QIF file Importar arquivo QIF File Selection Seleção de arquivo Select a QIF file to import. When you click next, the file be analysed and you might need to answer some questions about the format of the file. Selecionar um arquivo QIF para importar. Quando você clicar em próximo, o arquivo será analisado e talvez seja necessário responder algumas questões sobre o formato do mesmo. File: Arquivo: Local Definitions Definições locais Unknown elements where found in the QIF file. It is possible that this is because of localized type names. Please map them to the correct standard names. Elementos desconhecidos foram encontrados no arquivo QIF. É possível que isto se deva a nomes de tipos localizados. Por favor, mapeie-os para os nomes com padrão corretos. Local Text Texto local Standard Text Texto padrão Select standard text: Texto padrão selecionado: Date Format Formato da data The date format in the QIF file is ambiguous. Please select the correct format. O formato da data deste arquivo QIF é ambíguo. Por favor, selecione o formato correto. Date format: Formato da data: Default Account Conta padrão Could not find any account definitions in the QIF file. Please select a default account. It is also possible that this is caused by a localized opening balance text. Não foi possível encontrar nenhuma conta definida neste arquivo QIF. Por favor, selecione a conta padrão. Também é possível que isto seja causado por um texto de balanço de abertura localizado. Default account: Conta padrão: Opening balance text: Texto de abertura do saldo: Descriptions Descrições Transactions in QIF files does not have any specific description property. You are therefore given the option to choose how the description of imported transactions will be set. As transações em arquivos QIF não precisam ter nenhuma descrição própria específicada. Você, tem, então a opção de como a descrição das transações importadas serão definidas. Subcategories as: Subcategorias como: Description Descrição Transactions in QIF files does not have any specific description property. You are therefore given the option to choose how the description of imported transactions will be set. Referring to generic description As transações em arquivos QIF não precisam ter nenhuma descrição própria específicada. Você, tem, então a opção de como a descrição das transações importadas serão definidas. Category Categoria Ignore Ignorar Payee as: Credor como: Payee Credor Memo as: Anotações: Comments Comentários Priority: Prioridade Subcategory/Payee/Comments Subcategoria/Credor/Comentários Payee/Subcategory/Comments Credor/subcategoria/Comentários Subcategory/Comments/Payee Subcategoria/Comentários/Credor Payee/Comments/Subcategory Emitente/Comentários/Subcategorias Comments/Subcategory/Payee Comentários/Subcategorias/Emitentes Comments/Payee/Subcategory Comentários/Emitentes/Subcategorias Import File Importar arquivo No (further) issues were found. Press finish to import the selected QIF file. Não foram encontrados (outros) problemas. Pressione terminar para importar o arquivo QIF selecionado. Ignore duplicate transactions Ignorar transações duplicadas Error Erro A file must be selected. Um arquivo deve ser selecionado. Selected file is a directory. O arquivo selecionado é um diretório. Selected file does not exist. O aquivo selecionado não existe. Couldn't open %1 for reading. Não foi possível abrir o arquivo %1 para ler. Error reading %1. Erro ao ler o arquivo %1. Unknown Desconhecido Account Conta Bank Banco Cash Dinheiro Cat (Category) Cat (categoria) CCard (Credit Card) CCrédito (cartão de crédito) Invst (Investment) Invst (investimento) Oth A (Other Assets) Out A (outros ativos) Oth L (Other Liabilities) Out P (outros passivos) Security Títulos Other Outro Unrecognized date format. Formato da data não reconhecido. Successfully imported %n transaction(s). %n transação foi importada com sucesso. %n transações foram importadas com sucesso. Successfully imported %n account(s). %n conta foi importada com sucesso. %n contas foram importadas com sucesso. Successfully imported %n category/categories. %n categoria foi importada com sucesso. %n categorias foram importadas com sucesso. %n duplicate transaction(s) was ignored. %n transação duplicada foi ignorada. %n transações duplicadas foram ignoradas. Failed to import %n transaction(s). Falha ao importar %n transação. Falha ao importar %n transações. %n security/securities were not imported. Financial security (e.g. stock, mutual fund) %n título não foi importado. %n títulos não foram importados. %n security transaction(s) were not imported. Financial security (e.g. stock, mutual fund) %n transação de título não foi importada. %n transações de títulos não foram importadas. Information Informação Income Dividend: %1 Dividendo: %1 Reinvested dividend: %1 Dividendo reinvestido: %1 LedgerDialog Account: Conta: Edit Account… Editar conta… Export… Exportar… Print… Imprimir… Reconcile Accounting context Renconciliar Mark all as reconciled Accounting context Marcar todas como reconciliadas Change: Accounting context Se refere ao valor movimentado dentro de um período na tela de reconciliação Movimentado: R Header for account reconciled checkbox column R Date Data Type Tipo Description Descrição Name Nome Description Generic Description Descrição Account/Category Conta/categoria Deposit Depósito Withdrawal Sacar Balance Balanço Balance Account balance Balanço Payee/Payer Beneficiário/pagador Tags Etiquetas Comments Comentários Deposit Money put into account Depósito Withdrawal Money taken out from account Saque Balance Noun. Balance of an account Saldo New Novo Edit… Editar… Delete Deletar Join… join transactions together Unir… Split Up split up joined transactions Dividir Edit Transaction(s)… Editar transação(ões)… Join Transactions… Juntar translação… Split Up Transaction Dividir transação Remove Transaction(s) Remover transação(ões) Mark as reconciled Marcar como reconciliada Reconciled: %1 (%2) Accounting context Reconciliado: %1 (%2) Book value: %1 (%2) Accounting context Valor contábil: %1 (%2) Error Erro Invalid date. Data inválida. Opening date is after closing date. A data de abertura é após a data de fechamento. Closing date is before opening date. A data de fechamento é antes da data de abertura. Empty transaction list. Lista de transações vazia. Couldn't open file for writing. Não foi possível abrir o arquivo para salvá-lo. Error while writing file; file was not saved. Erro ao escrever os dados no arquivo; não foi possível salvá-lo. Ledger Livro de registros Transactions for %1 Transações para %1 Select Time Period Selecione um período de tempo From: De: To: Para: To date is before from date. A data final selecionada é antes da data de início. Balance change: Account balance Mudança de saldo: Delete transactions? Deletar transações? Are you sure you want to delete all (%1) selected transactions? Você tem certeza que deseja deletar todas (%1) as transações selecionadas? Cannot set the value of security transactions using the dialog for modifying multiple transactions. Financial security (e.g. stock, mutual fund) Não é possível alterar o valor das transações de títulos usando o diálogo para modificar transações múltiplas. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name); Financial security (e.g. stock, mutual fund) Não é possível alterar a descrição de dividendos e de transações de títulos. Cannot change payer of dividends and security transactions. Financial security (e.g. stock, mutual fund) Não é possível alterar o pagador de dividendos e de transações de títulos. Opening balance Account balance Saldo inicial Account Balance Adjustment Ajuste do saldo da conta Current balance: Account balance Saldo atual: Average balance: Account balance Saldo médio: Balancing Balancing of an account balanço Balancing Account balancing balanço Cannot set the value of security transactions using the dialog for modifying multiple transactions. Impossível mudar o valor das transações de segurança usando o diálogo para modificar transações múltiplas. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name) Impossível mudar a descrição de dividendos e transações de segurança; Cannot change description of dividends and security transactions. Referring to the generic description property Impossível mudar a descrição de dividendos e transações de segurança; Current debt: Dívida atual: Total debt reduction: Redução total da dívida: Total interest and fees: Total de juros e taxas: Number of transactions: Número de transações: Cannot change description of dividends and security transactions. Impossível mudar a descrição de dividendos e transações de segurança; Cannot change payer of dividends and security transactions. Impossível mudar o sacado de dividendos e transações de segurança; Cannot change date of transactions that are part of a split transaction. Impossível mudar a data das transações que são parte de uma transação divídida. Split Transaction Transação dividida Debt Payment Pagamento de dívida Ascending order Ordem ascendente Reduction Redução Fee Taxa Interest Juros Income Receita Repayment Reembolso Expense Despesa Opening balance: Accounting context Saldo inicial: Closing balance: Accounting context Saldo final: Description Transaction description property (transaction title/generic article name) Descrição Cannot change description of dividends and security transactions. Referring to the Transaction description property (transaction title/generic article name) Impossível mudar a descrição de dividendos e transações de segurança; Refund Reembolso Balancing balanço Transfer Transferência LinksWidget Remove Link Remover link All Tudo Remove Remover MultiItemListViewItem Dividend Dividendo Income Receita Repayment Reembolso Expense Despesa Refund Eu discordo do desenvolvedor nessa string. Ela se refere a uma despesa com valor positivo que pode ser criada em uma transação dividida, ela passa a ser um desconto no valor total da transação, não um reembolso. Desconto Securities Purchase Financial security (e.g. stock, mutual fund) Compra de títulos Securities Sale Financial security (e.g. stock, mutual fund) Venda de títulos Account Balance Adjustment Ajuste do saldo da conta Balancing Balancing of an account balanço Security Buy Compra Segura Security Sell Venda Segura Balancing balanço Transfer Transferir MultipleTransactionsEditDialog Modify Transactions Modificar transações Description: Descrição: Name: Nome: Description: Transaction description property (transaction title/generic article name) Descrição: Amount: Quantidade: Income: Receita: Cost: Custo: Date: Data: Category: Categoria: Payer: Pagador: Payee: Beneficiário: New Income Category Nova categoria de Receitas New Expense Category Nova gategoria de Despesas New Income Category… Noca categoria de receita… New Expense Category… Noca categoria de despesa Error Erro No income category available. Nenhuma categoria de receita disponível. No expense category available. Nenhuma categoria de despesa disponível. Invalid date. Data inválida. OverTimeChart Save As… Salvar como… Print… Imprimir… Source: Fonte: Incomes and Expenses Receitas e despesas Profits Lucros Expenses Despesas Incomes Receitas All Categories Combined Combinar todas as categorias All Descriptions Combined Todas descrições Comibinadas Theme: Tema: Chart type: Tipo de gráfico: Line Chart Gráfico de linha Vertical Bar Chart Gráfico de barra vertical Horizontal Bar Chart Gráfico de barra horizontal Stacked Bar Chart Gráfico de barra empilhada Default Padrão All Accounts Combined Combinar todas as contas All Accounts Split Combinar todas as transações divididas All Subcategories and Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Combinar todas as subcategorias e descrições All Descriptions Split Referring to the transaction description property (transaction title/generic article name) Separar todas as descrições No description Referring to the transaction description property (transaction title/generic article name) Nenhuma descrição All Payees/Payers Split Separar todos os beneficiários/pagadores No payee/payer Nenhum beneficiário/pagador All Tags Split Separar todas as etiquetas Other tags Outras etiquetas Other payees/payers Outros beneficiários/pagadores Other descriptions Referring to the transaction description property (transaction title/generic article name) Outras descrições Profits, %1 Rendas, %1 Assets Ativos All Descriptions Combined Referring to the generic description property Todas descrições Comibinadas Assets and Liabilities Ativos e passivos Tags Etiquetas All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Combinar todas as descrições All Payees/Payers Combined Combinar todos os beneficiários/pagadores Start date: Data inicial: End date: Data final: Value: Valor: Annual total Total anual Monthly total Total mensal Daily average Média diária Quantity Quantidade Average value Valor médio All Payers Combined Combinar todos os pagadores All Payees Combined Combinar todos os beneficiários All Subcategories Split Separar todas as subcategorias All Descriptions Split Referring to the generic description property Todas descrições divídidas No description Referring to the generic description property Nenhuma descrição Value Valor Includes budgeted transactions Incluir transações orçamentadas Incomes − Expenses, %1 Receitas − Despesas, %1 Incomes − Expenses Receitas − Despesas Incomes & Expenses Receitas & Despesas Incomes: %1 Receitas: %1 Expenses: %1 Despesas: %1 %2: %1 %2: %1 Incomes: %2, %1 Receitas: %2, %1 Expenses: %2, %1 Despesas: %2, %1 %3: %2, %1 %3: %2, %1 %2, %1 %2, %1 Incomes: %3, %2, %1 Receitas: %3, %2, %1 Expenses: %3, %2, %1 Despesas: %3, %2, %1 %4: %3, %2, %1 %4: %3, %2, %1 no payee/payer nenhuem emitente/sacado %3, %2, %1 %3, %2, %1 Other accounts Outras contas %1 Value: %2 Date: %3 %1 Valor: %2 Data: %3 MMMM yyyy Month and year MMMM aaaa All Descriptions Split Todas descrições divídidas All Payers Split Separar todos os pagadores All Payees Split Separar todos os beneficiários No description Nenhuma descrição No payer Nenhum pagador No payee Nenhum beneficiário All Categories Split Dividir todas as categorias Error Erro Invalid date. Data inválida. Couldn't open file for writing. Não foi possível abrir o arquivo para salvá-lo. Error while writing file; file was not saved. Erro ao escrever os dados no arquivo; não foi possível salvá-lo. Other payees Outros beneficiários Other payers Outros pagadores Value (%1) Valoe (%1) Profit (%1) Renda (%1) Income (%1) Lucro (%1) Cost (%1) Custo (%1) Time Hora %1/%2 %1: Category; %2: Payee/Payer %1/%2 All Descriptions Combined Referring to the Transaction description property (transaction title/generic article name) Todas descrições Comibinadas All Descriptions Split Referring to the Transaction description property (transaction title/generic article name) Todas descrições divídidas No description Referring to the Transaction description property (transaction title/generic article name) Nenhuma descrição Daily average value Valor médio diário Daily average profit Lucro médio diário Daily average income Renda média diária Daily average cost Custo médio diário Average income Renda média Average cost Custo médio Annual value Valor anual Annual profit Lucro anual Annual income Renda anual Annual cost Custo anual Monthly value Valor mensal Monthly profit Lucro mensal Monthly income Renda mensal Monthly cost Custo mensal Includes scheduled and budgeted transactions Inclui transações agendadas e orçamentadas Includes scheduled transactions Inclui transações agendadas Tags, %1 Etiquetas, %1 Value: %1 Valor: %1 Assets & Liabilities Ativos & passivos Change: %1 Change: %1 Excluding any profits or losses in trading of security shares Financial security (e.g. stock, mutual fund) talvez precise de um ajuste fino Excluindo quaisquer lucros ou perdas na negociação de títulos e/ou ações Incomes & Expenses, %1 Receitas e despesas, %1 Incomes, %1 Receitas, %1 Expenses, %1 Desepesas, %1 Incomes, %2: %1 Receitas, %2: %1 Expenses, %2: %1 Despesas, %2: %1 Incomes, %3: %2, %1 Receitas, %3: %2, %1 Expenses, %3: %2, %1 Despesas, %3: %2, %1 Incomes, %4: %3, %2, %1 Receitas, %4: %3, %2, %1 Expenses, %4: %3, %2, %1 Despesas, %4: %3, %2, %1 Liabilities Passivos no payer nenhuma devedor %1/%2 %1: Description; %2: Payer/Payer %1/%2 %1/%2 %1: Description; %2: Payee/Payer %1/%2 %1/%2 %1: Description; %2: Payer %1/%2 no payee nenhum emitente %1/%2 %1: Description; %2: Payee %1/%2 OverTimeChartDialog Chart Gráfico OverTimeReport Save As… Salvar como… Print… Imprimir… Source: Fonte: Profits Lucros Expenses Despesas Incomes Receitas Assets & Liabilities Ativos & passivos Tags Etiquetas All Categories Combined Todas categórias comibinadas All Descriptions Combined Todas descrições Comibinadas Columns: Colunas: Categories Categorias Total: Total: Value Valor Daily Diário Monthly Mensal Yearly Anual Quantity Quantidade Average value Valor médio No description Nenhuma descrição All Descriptions Combined Referring to the generic description property Todas descrições Comibinadas No description Referring to the generic description property Nenhuma descrição All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Todas descrições comibinadas No description Referring to the transaction description property (transaction title/generic article name) Nenhuma descrição Error Erro Couldn't open file for writing. Não foi possível abrir o arquivo para salvá-lo. Error while writing file; file was not saved. Erro ao escrever os dados no arquivo; não foi possível salvá-lo. Average Profit Lucro médio Incomes, %1 Receitas, %1 Average Income Renda média Expenses, %1 Despesas, %1 Average Cost Custo médio Incomes, %2: %1 Receitas, %2: %1 Incomes: %1 Receitas: %1 Expenses, %2: %1 Despesas, %2: %1 Expenses: %1 Despesas: %1 Incomes, %3: %2, %1 Receitas, %3: %2, %1 Incomes: %2, %1 Receitas: %2, %1 Expenses, %3: %2, %1 Despesas, %3: %2, %1 Expenses: %2, %1 Despesas: %2, %1 Change: %1 Noun, how much the account balance has changed Movimentado: %1 Average Change Balanço de change Change Noun, how much the account balance has changed Movimentado Value: %1 Valor: %1 Year Ano Month Mês Assets Ativos Deposit Depósito Withdrawal Sacar Liabilities Passivos %2: %1 %2: %1 %1 %1 Average Value Valor médio %3: %2, %1 %3: %2, %1 %2, %1 %2, %1 Daily Average Média diária Monthly Average Média mensal Yearly Average Média anual Subtotal Subtotal Total Total Deposit Money put into account Depósito Withdrawal Money taken out from account Saque Includes scheduled transactions Incluir transações agendadas Adjusted for the average month / year (%1 / %2 days) Ajustado para média do mês/ano (%1 / %2 dias) All Categories Combined Referring to the generic description property Todas categórias Comibinadas OverTimeReportDialog Report Relatório QApplication Start with expenses list displayed Começar com a lista de despesas exibida Start with incomes list displayed Começar com a lista de receitas exibida Start with transfers list displayed Começar com a lista de transferências exibida Synchronize file Arquivo de sincronização Document to open Documento para abrir %1 is already running. %1 já está em funcionamento. QObject Transfer Transferência Dividend Dividendo Income Receita Expense Despesa Securities Purchase Financial security (e.g. stock, mutual fund) Compra de títulos Securities Sale Financial security (e.g. stock, mutual fund) Venda de títulos Security Buy Compra Segura Security Sell Venda Segura Debt Payment Pagamento de dívida Split Transaction Transação dividida RecurrenceEditWidget Enable recurrence Habilitar recorrência Recurrence Rule Regra de recorrência Daily Diariamente Weekly Semanalmente Monthly Mensalmente Yearly Anualmente Recur every Recorrer a cada day(s) dia(s) week(s) on: semana(s) no(s) dia(s): month(s), after the start month mês(es), depois do mês de início Recur on the Recorrência no(a) 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 10º 11th 11º 12th 12º 13th 13º 14th 14º 15th 15º 16th 16º 17th 17º 18th 18º 19th 19º 20th 20º 21st 21º 22nd 22º 23rd 23º 24th 24º 25th 25º 26th 26º 27th 27º 28th 28º 29th 29º 30th 30º 31st 31º Last Último 2nd Last Penúltimo 3rd Last Antepenúltimo 4th Last Antes do antepenúltimo 5th Last Dois antes do antepenúltimo day dia possibly on weekend possivelmente no final de semana but before weekend mas antes do final de semana but after weekend mas depois do final de semana nearest weekend day dia de fim de semana mais próximo year(s), after the start year ano(s), depois do ano de começo on nearest weekday no dia da semana mais próximo Recur on day part before XXX of 'Recur on day XXX of month YYY' Nos dias No dia of part between XXX and YYY of 'Recur on day XXX of month YYY' de On the Part before NNN in 'Recur on the NNN. WEEKDAY of MONTH' Na of part between WEEKDAY and MONTH in 'Recur on NNN. WEEKDAY of MONTH' de Recur on day # No dia # of the year part after NNN of 'Recur on day #NNN of the year' do ano Range… Se refere ao período em que uma transação recorrente deve se repetir Duração… Occurrences/Exceptions… Ocorrências/Exceções… Exceptions… Exceções… Error Erro No day of week selected for weekly recurrence. Nenhum dia da semana selecionado para a recorrência semanal. Selected day will never occur with selected frequency and start date. O dia selecionado nunca ocorrerá com frequência selecionada e a data inicial. Selected day does not exist in selected month. O dia selecionado não existe neste mês. RefundDialog Repayment Reembolso Refund Reembolso Date: Data: Cost: Custo: Income: Se refere ao valor do reembolso. Acredito que o termo "valor", ao invés do padrão "receita", seja mais adequado. Valor: Quantity returned: Quantidade devolvida: Account: Conta: Quantity: Quantidade: Payee: Beneficiário: Payer: Pagador: Comments: Comentários: Link Link the transactions together Link Join Join the transactions together Unir Error Erro Zero value not allowed. Valor zero não autorizado. Invalid date. Data inválida. SecurityBuy Security: %1 (bought) Segurança: %1 (comprado) Security: %1 (bought) Financial security (e.g. stock, mutual fund) Títulos: %1 (comprado) SecuritySell Security: %1 (sold) Segurança: %1 (vendido) Security: %1 (sold) Financial security (e.g. stock, mutual fund) Títulos: %1 (vendido) SecurityTransactionsDialog Transactions for %1 Transações para %1 Date Data Type Tipo Value Valor Shares Financial shares Ações Shares Bought Financial shares Ações compradas Shares Bought (Recurring) Financial shares Ações compradas (recorrentes) Dividend (Recurring) Dividendo (recorrente) Dividend (Scheduled) Dividendo (agendado) Reinvested Dividend (Recurring) Dividendo reinvestido (recorrente) Reinvested Dividend (Scheduled) Dividendo reinvestido (agendado) Shares Bought Fincancial shares Ações compradas Shares Sold Financial shares Ações vendidas Shares Sold (Exchanged) Shares of one security directly exchanged for shares of another; Financial shares Ações vendidas (trocadas) Shares Bought (Exchanged) Shares of one security directly exchanged for shares of another; Financial shares Ações compradas (trocadas) Shares Bought (Recurring) Fincancial shares Ações compradas (Retornando) Shares Sold (Recurring) Financial shares Ações vendidas (recorrentes) Shares Bought (Scheduled) Financial shares Ações compradas (agendadas) Shares Sold (Scheduled) Financial shares Ações vendidas (agendadas) Shares Ações Edit… Editar… Delete Deletar Shares Bought Ações compradas Shares Sold Ações vendidas Dividend Dividendo Reinvested Dividend Dividendo reinvestido Shares Sold (Traded) Ações vendidas (Negociada) Shares Bought (Traded) Ações compradas (Negociada) Shares Bought (Recurring) Ações compradas (Retornando) Shares Sold (Recurring) Ações vendidas (Retornando) Shares Bought (Scheduled) Ações compradas (Agendadas) Shares Sold (Scheduled) Ações vendidads (Agendadas) Recurring Dividend Dividendo à ser recorrido Scheduled Dividend Dividendo agendado SplitListViewItem Dividend Dividendo Income Renda Repayment "Re-pagamento" Expense Despesa Refund Reembolso Security Buy Compra Segura Security Sell Venda Segura Balancing balanço Transfer Transferir TagButton no tags sem etiquetas TagMenu New tag… Nova etiqueta… New Tag Nova etiqueta Tag: Etiqueta: TransactionEditDialog Edit Expense Editar despesa Edit Dividend Editar dividendo Edit Income Editar receita Edit Transfer Editar transfêrencia Edit Securities Purchase Financial security (e.g. stock, mutual fund) Editar compra de títulos Edit Securities Sale Financial security (e.g. stock, mutual fund) Editar venda de títulos Edit Reinvested Dividend Editar dividendo reinvestido Edit Securities Bought Editar seguranças compradas Edit Securities Sold Editar seguranças vendidas TransactionEditWidget Security: Segurança Cost: Custo: Income: Receita: Shares bought: Ações compradas: Shares sold: Ações vendidas All Tudo Price per share: Preço por ação: Date: Data: Description: Descrição: Name: Nome: Amount: Quantidade: Withdrawal: Money taken out from account Saque: New Security… Financial security (e.g. stock, mutual fund) Novo título… Shares added: Financial shares Ações adicionadas: Set security share value Definir o valor das ações do título Total value: Valor total: Deposit: Money put into account Depósito: Downpayment: valor dado como entrada (pagamento inicial) para o empréstimo Pagamento inicial: Quantity: Quantidade: From: De: To: Para: Category: Categoria: To account: Para a conta: Payer: Pagador: Payer of parent split transaction Pagador dessa parte da transação dividida From account: Da conta: Downpayment account: Conta do pagamento inicial: Payee: Beneficiário: Payee of parent split transaction Beneficiário da transação dividida Lender: Credor: Tags: Etiquetas: Associated file: Arquivo associado: Select a file Selecione um arquivo Open the file Abrir o arquivo Comments: Comentários: Related to: Label for linked transactions Relacionado a: New Security Financial security (e.g. stock, mutual fund) Novo título No security available. Financial security (e.g. stock, mutual fund) Nenhum título disponível. New Account Nova conta New Income Category Nova categoria de Receitas New Expense Category Nova gategoria de Despesas New Account… Nova conta;;; New Income Category… Noca categoria de receita… New Expense Category… Noca categoria de despesa Security: Financial security (e.g. stock, mutual fund) Título: Shares bought: Financial shares Ações compradas: Shares sold: Financial shares Ações vendidas: Price per share: Financial shares Preço por ação: Description: Transaction description property (transaction title/generic article name) Descrição: Transaction title/generic article name Título da transação Number of items included in the transaction. Entered cost is total cost for all items. Número de itens incluídos na transação (o custo inserido é valor total para todos os itens). Error Erro No suitable account available. Não há uma conta adequada disponível. No income category available. Nenhuma categoria de receita disponível. No suitable account or income category available. Nenhuma conta possível ou categoria de receita disponível. No expense category available. Nenhuma categoria de despesa disponível. No security available. Nenhum asegurança disponível. Invalid date. Data inválida. Cannot transfer money to and from the same account. Não é possível transferir dinheiro para a mesma conta de origem. Downpayment must be less than total cost. O pagamento inicial deve ser menor do que o custo total. Cannot create a regular transfer to/from a securities account. Não é possível criar uma transferência regular a partir de uma conta de títulos. Cannot create a regular income to a securities account. Não é possível criar uma receita regular a partir de uma conta de títulos. Zero shares not allowed. O número zero para as ações não é permitido. Zero value not allowed. O valor zero não é permitido. Zero price per share not allowed. Preço zero por ação não é permitido. Cannot create a regular expense from a securities account. Não é possível criar uma despesa regular a partir de uma conta de títulos. Loan for %1 Empréstimo para %1 TransactionFilterWidget From: De: To: se refere a data limite no widget de filtros Até: Min amount: Quantia mínima: Max amount: Quantia máxima: Category: Categoria: To account: Para a conta: Min income: Receita mínima: Max income: Receita máxima: From account: Da conta: Min cost: Custo mínimo: Max cost: Custo máximo: Tag: Etiqueta: Description: Descrição: Description: Transaction description property (transaction title/generic article name) Descrição: Payer: Devedor: Payee: Emitente: Include Incluir Exclude Excluir Exact match Combinação exata Exclude subcategories Excluir subcategorias Clear Limpar All Tudo Error Erro Invalid date. Data inválida. To date is before from date. Antes da data. From date is after to date. Depois da data. TransactionListWidget Date Data Description Descrição Cost Custo Category Categoria From Account Da conta Payee Beneficiário Tags Etiquetas Income Receita To Account Para a conta Payer Pagador Amount Quantia From De To Para Comments Comentários Add Adicionar Apply Aplicar Delete Deletar * Part of <a href="%1">split transaction</a> * Parte de uma <a href="%1">transação dividida</a> Expense Despesa Transfer Transferir Name Nome Description Generic Description Descrição Description Transaction description property (transaction title/generic article name) Descrição New/Edit Expense Novo/editar despesa New/Edit Income Novo/editar receita New/Edit Transfer Novo/editar transfêrencia Filter Filtrar Quantity: Quantidade: Total: Total: Average: Média: Clear Limpar Cost: Custo: Monthly: Mensalmente: Sort by creation time Ordenar por data de criação Expenses Despesas Incomes Receitas Transfers Transferências Quantity Quantidade Right align Alinhar à direita Total cost: Custo total: Total income: Receita total: Total amount: Quantia total: Monthly average: Média mensal: Error Erro Cannot set the value of security transactions using the dialog for modifying multiple transactions. Financial security (e.g. stock, mutual fund) Não é possível alterar o valor das transações de títulos utilizando o diálogo para modificar transações múltiplas. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name); Financial security (e.g. stock, mutual fund) Não é possível alterar a descrição de dividendos e transações de títulos. Cannot change payer of dividends and security transactions. Financial security (e.g. stock, mutual fund) Não é possível alterar o pagador de dividendos e de transações de títulos. Cannot change date of transactions that are part of a split transaction, unless all individual transactions are selected. Não é possível alterar a data das transações que fazem parte de uma transação dividida (a menos que todas as transações individuais sejam selecionadas). Cannot set the value of security transactions using the dialog for modifying multiple transactions. Impossível mudar o valor das transações de segurança usando o diálogo para modificar transações múltiplas. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name) Impossível mudar a descrição de dividendos e transações de segurança; Cannot change date, description, expense category or payee of transactions that are part of a debt payment using the dialog for modifying multiple transactions. Referring to the transaction description property (transaction title/generic article name) Não é possível alterar a data, descrição, categoria de despesa ou o pagador de uma transação que é parte de um pagamento de dívidas utilizando o diálogo para modificar transações múltiplas. Cannot change description of dividends and security transactions. Referring to the Transaction description property (transaction title/generic article name) Impossível mudar a descrição de dividendos e transações de segurança; Cannot change description of dividends and security transactions. Referring to the generic description property Impossível mudar a descrição de dividendos e transações de segurança; Cannot change description of dividends and security transactions. Impossível mudar a descrição de dividendos e transações de segurança; Cannot change payer of dividends and security transactions. Impossível mudar o sacado de dividendos e transações de segurança; Cannot change date of transactions that are part of a split transaction. Impossível mudar a data das transações que são parte de uma transação divídida. Delete transactions? Deletar transações? Are you sure you want to delete all (%1) transactions in the selected split transaction? Você tem certeza que deseja deletar todas as transações (%1) desta transação dividida selecionada? Join as multiple accounts/payments? Juntar como múltiplas contas/pagamentos? Do you wish join the selected expenses as an expense with multiple accounts/payments? Você deseja juntar as despesas selecionadas como uma despesa com múltiplas contas/pagamentos? Do you wish join the selected incomes as an income with multiple accounts/payments? Você deseja juntar as receitas selecionadas como uma receita com múltiplas contas/pagamentos? Are you sure you want to delete all (%1) selected transactions? Você tem certeza que deseja deletar todas as transações (%1) selecionadas? * Part of split transaction * Parte de uma transação dividida * Part of split (%1) Difícil... * Parte da parcela (%1) ** Recurring (editing occurrence) ** Recorrente (editando ocorrência) Modify… Modificar… Edit… Editar… Eqonomize-1.5.3/translations/eqonomize_ro.ts000066400000000000000000021051471416454732000213050ustar00rootroot00000000000000 Balancing Echilibrare kde-format Couldn't open %1 for reading Nu s-a putut deschide %1 pentru citire kde-format Not a valid Eqonomize! file (XML parse error: "%2" at line %3, col %4) Nu este un fișier Eqonomize! valid (eroare procesare XML: „%2” la linia %3, col %4) kde-format Invalid root element %1 in XML document Element rădăcină %1 nevalid în documentul XML kde-format Unable to load 1 account. Nu s-a putut încărca 1 cont. Nu s-au putut încărca %n conturi. Nu s-au putut încărca %n de conturi. kde-format Unable to load %n accounts. Unable to load 1 category. Nu s-a putut încărca 1 categorie. Nu s-au putut încărca %n categorii. Nu s-au putut încărca %n de categorii. kde-format Unable to load %n categories. Unable to load 1 security. Nu s-a putut încărca 1 titlu de valoare. Nu s-au putut încărca %n titluri de valoare. Nu s-au putut încărca %n de titluri de valoare. kde-format Unable to load %n securities. Unable to load 1 transaction. Nu s-a putut încărca 1 tranzacție. Nu s-au putut încărca %n tranzacții. Nu s-au putut încărca %n de tranzacții. kde-format Unable to load %n transactions. File is a directory Fișierul este un director kde-format Couldn't open file for writing Nu s-a putut deschide fișierul pentru scriere kde-format Error while writing file; file was not saved S-a întâlnit o eroare la salvarea fișierului; acesta nu a fost salvat kde-format From De la kde-format To La kde-format Source: Sursă: kde-format All Expenses Toate cheltuielile kde-format All Incomes Toate veniturile kde-format All Accounts Toate conturile kde-format Expenses: %1 Cheltuieli: %1 kde-format Incomes: %1 Venituri: %1 kde-format Invalid date. Dată nevalidă. kde-format To date is before from date. Data „la” este înaintea datei „de la”. kde-format From date is after to date. Data „de la” este după data „la”. kde-format The selected file already exists. Would you like to overwrite the old copy? Fișierul selectat deja există. Doriți să suprascrieți copia veche? kde-format You selected a directory! Ați selectat un director! kde-format Couldn't open file for writing. Nu s-a putut deschide fișierul pentru scriere. kde-format Error while writing file; file was not saved. Eroare la scrierea fișierului; acesta nu a fost salvat. kde-format No description Fără descriere kde-format All Categories Toate categoriile kde-format Descriptions for Descrieri pentru kde-format Payees/payers for Beneficiari/plătitori pentru kde-format Period: Perioadă: kde-format Columns: Coloane: kde-format Value Valoare kde-format Daily Zilnic kde-format Monthly Lunar kde-format Yearly Anual kde-format Quantity Cantitate kde-format Average value Valoare medie kde-format All descriptions Toate descrierile kde-format All payees Toți beneficiarii kde-format All payers Toți plătitorii kde-format No payee Nici un beneficiar kde-format No payer Nici un plătitor kde-format Expenses: %2, %1 Cheltuieli: %2, %1 kde-format Incomes: %2, %1 Venituri: %2, %1 kde-format Incomes & Expenses Venituri și cheltuieli kde-format %1 (%2&ndash;%3) html format; %1: title; %2: from date; %3: to date %1 (%2&ndash;%3) kde-format %1 (to %2) html format; %1: title; %2: to date %1 (la %2) kde-format Category Categorie kde-format Cost Cost kde-format Income Venit kde-format Daily Average Medie zilnică kde-format Monthly Average Media lunară kde-format Yearly Average Medie anuală kde-format Average Cost Cost mediu kde-format Average Income Venit mediu kde-format Average Value Valoare medie kde-format Total Total kde-format Total incomes Venituri totale kde-format Total expenses Cheltuieli totale kde-format Total (Profits) Total (profituri) kde-format Expense Cheltuială kde-format Transfer Transfer kde-format Security Buy Cumpărare titlu de valoare kde-format Security Sell Vânzare titlu de valoare kde-format Recurrence Recurență kde-format New Expense Cheltuială nouă kde-format New Dividend Dividend nou kde-format New Income Venit nou kde-format New Transfer Transfer nou kde-format New Security Buy Cumpărare nouă titlu de valoare kde-format New Security Sell Vânzare nouă titlu de valoare kde-format Edit Expense Editează cheltuială kde-format Edit Dividend Editează dividend kde-format Edit Income Editează venit kde-format Edit Transfer Editează transfer kde-format Edit Securities Bought Editează titluri de valoare cumpărate kde-format Edit Securities Sold Editează titluri de valoare vândute kde-format Dividend Dividend kde-format Repayment Restituire kde-format Refund Rambursare kde-format Split Transaction Împarte tranzacția kde-format Description: Descriere: kde-format Date: Dată: kde-format Account: Cont: kde-format Transactions: Tranzacții: kde-format Type Tip kde-format Description Descriere kde-format Account/Category Cont/Categorie kde-format Payment Plată kde-format Deposit Depozit kde-format New Nou kde-format New Expense… Cheltuială nouă… kde-format New Income… Venit nou… kde-format New Deposit… Depozit nou… kde-format New Withdrawal… Retragere nouă… kde-format New Security Shares Bought… Titluri de valoare nou cumpărate… kde-format Security Shares Sold… Titluri de valoare vândute… kde-format New Dividend… Dividend nou… kde-format Edit… Editează… kde-format Total value: Valoare totală: kde-format No suitable account available. Nici un cont potrivit nu este disponibil. kde-format Future dates is not allowed. Datele în viitor nu sunt permise. kde-format A split must contain at least two transactions. O împărțire trebuie să conțină cel puțin două tranzacții. kde-format Cannot transfer money to and from the same account. Nu se pot transfera bani din și către același cont. kde-format Cost: Cost: kde-format Income: Venit: kde-format Quantity: Cantitate: kde-format Comments: Comentarii: kde-format Reinvested Dividend Dividend reinvestit kde-format Security: Titlu de valoare: kde-format Shares added: Acțiuni adăugate: kde-format Security Trade Tranzacție titlu de valoare kde-format From security: De la titlu de valoare: kde-format Shares moved: Acțiuni mutate: kde-format All Tot kde-format To security: Către titlu de valoare: kde-format Shares received: Acțiuni primite: kde-format Value: Valoare: kde-format No other security available for trade in the account. Nici un alt titlu de valoare nu este disponibil pentru tranzacționare în cont. kde-format Selected to and from securities are the same. Titlurile de valoare selectate „de la” și „la” sunt identice. kde-format Zero shares not allowed. Acțiuni zero nu este permis. kde-format Zero value not allowed. Valoarea zero nu este permisă. kde-format Quotations Cotație kde-format Date Dată kde-format Price per Share Preț per acțiune kde-format Quotations for %1 Cotații pentru %1 kde-format The following transactions was scheduled to occur today or before today. Confirm that they have indeed occurred (or will occur today). Următoarele tranzacții au fost planificate să se producă azi sau mai înainte. Confirmați că s-au produs (sau că se vor produce astăzi). kde-format Amount Cantitate kde-format Postpone… Amână… kde-format Can only postpone to future dates. Nu se poate amâna decât în viitor. kde-format Transactions for %1 Tranzacții pentru %1 kde-format Shares Acțiuni kde-format Shares Bought Acțiuni cumpărate kde-format Shares Sold Acțiuni vândute kde-format Shares Sold (Traded) Acțiuni vândute (schimbate) kde-format Shares Bought (Traded) Acțiuni vândute (schimbate) kde-format Shares Bought (Recurring) Acțiuni cumpărate (recurent) kde-format Shares Sold (Recurring) Acțiuni vândute (recurent) kde-format Shares Bought (Scheduled) Acțiuni cumpărate (planificate) kde-format Shares Sold (Scheduled) Acțiuni vândute (planificate) kde-format Recurring Dividend Dividend recurent kde-format Scheduled Dividend Dividend planificat kde-format Type: Tip: kde-format Mutual Fund Fond mutual kde-format Bond Obligațiune kde-format Stock Stoc kde-format Other Altul kde-format Name: Nume: kde-format Decimals in Shares: Zecimale în acțiuni: kde-format Initial Shares: Acțiuni inițiale: kde-format Initial quotation: Cotație inițială: kde-format No suitable account or income category available. Nu există nici un cont sau tip de venit potrivit. kde-format Cash Numerar kde-format Current Account Cont curent kde-format Savings Account Cont economii kde-format Credit Card Carte de credit kde-format Liabilities Pasive kde-format Securities Titluri de valoare kde-format Initial balance: Balanță inițială: kde-format Default account for budgeted transactions Cont implicit pentru tranzacții cu buget kde-format Empty name. Nume nedefinit. kde-format The entered name is used by another account. Numele introdus este folosit la alt cont. kde-format Monthly budget: Buget lunar: kde-format The entered name is used by another income category. Numele introdus este folosit la altă categorie de venituri. kde-format The entered name is used by another expense category. Numele introdus este folosit la altă categorie de cheltuieli. kde-format Accounts Conturi kde-format Accounts & Categories Conturi și categorii kde-format Expenses Cheltuieli kde-format Incomes Venituri kde-format Transfers Transferuri kde-format Schedule Planificare kde-format Scheduled Transactions Tranzacții planificate kde-format Account / Category Cont / categorie kde-format Remaining Budget (%1) Buget rămas (%1) kde-format Change (%1) Schimbare (%1) kde-format Total (%1) Total (%1) kde-format %2 of %1 %2 remains of %1 budget %2 din %1 kde-format Includes budgeted transactions Include tranzacții cu buget kde-format Period Perioadă kde-format Select Period Selectare perioadă kde-format Current Month Luna curentă kde-format Current Year Anul curent kde-format Current Whole Month Toată luna curentă kde-format Current Whole Year Tot anul curent kde-format Whole Past Month Toată luna trecută kde-format Whole Past Year Tot anul trecut kde-format Previous Month Luna anterioară kde-format Previous Year Anul anterior kde-format Show partial budget Arată bugetul parțial kde-format Edit Budget Editează buget kde-format Budget: Buget: kde-format Month: Luna: kde-format Result previous month: Rezultat luna trecută: kde-format New Security… Titlu de valoare nou… kde-format New Transaction Tranzacție nouă… kde-format Set Quotation… Stabilire cotație… kde-format Name Nume kde-format Quotation Cotație kde-format Profit Profit kde-format Yearly Rate Rată anuală kde-format Account Cont kde-format Statistics Period Perioadă statistică kde-format New Schedule Planificare nouă kde-format Edit Editează kde-format Next Occurrence Următoarea apariție kde-format Comments Comentarii kde-format New Security Titlu de valoare nou kde-format Edit Security Modifică titlu de valoare kde-format Profit: Profit: kde-format Rate: Rată: kde-format Are you sure you want to delete the security "%1" and all associated transactions? Sigur doriți ștergerea titlului de valoare „%1” și toate tranzacțiile asociate? kde-format No security available. Nu este disponibil nici un titlu de valoare. kde-format Set Quotation (%1) Stabilește cotația (%1) kde-format Price per share: Preț per acțiune: kde-format Future dates are not allowed. Datele în viitor nu sunt permise. kde-format Security Transactions Tranzacții titluri de valoare. kde-format Ledger Registru kde-format Untitled Fără titlu kde-format Check Account Cont cec kde-format Salary Salariu kde-format Bills Facturi kde-format Clothing Îmbrăcăminte kde-format Groceries Alimente kde-format Leisure Timp liber kde-format Couldn't fetch %1. Nu s-a putut aduce %1. kde-format Error loading %1: %2. Eroare la încărcarea %1: %2. kde-format Couldn't open file Nu s-a putut deschide fișierul. kde-format Error saving %1: %2. Eroare la salvarea %1: %2. kde-format Couldn't save file Nu s-a putut salva fișierul kde-format Failed to upload file to %1. Eroare la încărcarea fișierului la %1. kde-format Report Raport kde-format Chart Grafic kde-format Transaction Schedule Planificare tranzacție kde-format Accounts &amp; Categories html format Conturi și categorii kde-format Accounts &amp; Categories (%1&ndash;%2) html format Conturi și categorii (%1&ndash;%2) kde-format Accounts &amp; Categories (to %1) html format Conturi și categorii (la %1) kde-format Change Modifică kde-format Balance Balanță kde-format Budget Buget kde-format Remaining Budget Buget rămas kde-format Total Incomes Venituri totale kde-format Costs Costuri kde-format Total Expenses Cheltuieli totale kde-format Empty expenses list. Listă de cheltuieli goală. kde-format Empty incomes list. Listă de venituri goală. kde-format Empty transfers list. Listă de transferuri goală. kde-format Empty securities list. Listă de titluri de valoare goală. kde-format Empty schedule list. Listă de planificări goală. kde-format Export View… Exportare vizualizare… kde-format Print View… Vizualizare tipărire… kde-format Initial Period Perioadă inițială kde-format Remember Last Dates Ține minte ultimele date kde-format Import CSV File… Importare fișier CSV… kde-format Import QIF File… Importare fișier QIF… kde-format Export As QIF File… Exportare ca fișier QIF… kde-format Add Account… Adăugare cont… kde-format New Account… Cont nou… kde-format New Income Category… Categorie de venit nouă… kde-format New Expense Category… Categorie de cheltuială nouă… kde-format Balance… Echilibrare… kde-format Show Transactions Arată tranzacțiile kde-format New Transfer… Transfer nou… kde-format New Split Transaction… Tranzacție împărțită nouă… kde-format Edit Transaction(s) (Occurrence)… Editare tranzacții (recurență)… kde-format Edit Occurrence… Editare recurență… kde-format Edit Schedule (Recurrence)… Editare planificare (recurență)… kde-format Edit Schedule… Editare planificare… kde-format Remove Transaction(s) (Occurrence) Elimină tranzacții (recurență) kde-format Remove Occurrence Elimină recurența kde-format Delete Schedule (Recurrence) Șterge planificare (recurență) kde-format Delete Schedule Șterge planificare kde-format Edit Split Transaction… Editare tranzacție împărțită… kde-format Remove Split Transaction Eliminare tranzacție împărțită kde-format Join Transactions… Alăturare tranzacții… kde-format Split Up Transaction Împărțește tranzacția kde-format Refund… Rambursare… kde-format Repayment… Restituire kde-format New Refund/Repayment… Rambursare/restituire nouă… kde-format Edit Security… Editare titlu de valoare… kde-format Remove Security Eliminare titlu de valoare kde-format Shares Sold… Acțiuni vândute… kde-format Shares Bought… Acțiuni cumpărate… kde-format Dividend… Dividend… kde-format Reinvested Dividend… Dividend reinvestit… kde-format Shares Moved… Acțiuni mutate… kde-format Edit Quotations… Editare cotații… kde-format Transactions… Tranzacții… kde-format Development Over Time Report… Raport evoluție în timp… kde-format Categories Comparison Report… Raport comparare categorii… kde-format Categories Comparison Chart… Grafic comparare categorii… kde-format Development Over Time Chart… Grafic evoluție în timp… kde-format Use Additional Transaction Properties Folosește proprietăți adiționale la tranzacții kde-format Eqonomize! exited unexpectedly before the file was saved and data was lost. Do you want to load the last auto-saved version of the file? Eqonomize! a ieșit în mod neașteptat înainte de salvarea fișierului și datele s-au pierdut. Doriți încărcarea ultimei versiuni de fișier salvate automat? kde-format Crash Recovery Restaurare după terminare prematură kde-format The current file has been modified. Do you want to save it? Fișierul curent a fost modificat. Doriți să-l salvați? kde-format Confirm Schedule Confirmă planificarea kde-format New Account Cont nou kde-format New Income Category Categorie de venit nouă kde-format New Expense Category Categorie de cheltuieli nouă kde-format Balance Account Echilibrare cont kde-format Book value: Valoare registru: kde-format Real value: Valoare reală: kde-format Edit Account Modifică contul kde-format Edit Income Category Editează categoria de venit kde-format Edit Expense Category Editează categoria de cheltuieli kde-format Move transactions? Mutare tranzacții? kde-format Move to: Mută în: kde-format The category contains some expenses. What do you want to do with them? Categoria conține cheltuieli. Ce doriți să faceți cu ele? kde-format The category contains some incomes. What do you want to do with them? Categoria conține venituri. Ce doriți să faceți cu ele? kde-format The account contains some transactions. What do you want to do with them? Contul conține tranzacții. Ce doriți să le faceți cu ele? kde-format The category contains some expenses that will be removed. Do you still want to remove the category? Categoria conține cheltuieli care vor fi eliminate. Încă doriți eliminarea categoriei? kde-format Remove Category? Eliminare categorie? kde-format The category contains some incomes that will be removed. Do you still want to remove the category? Categoria conține venituri care vor fi eliminate. Sigur doriți să eliminați categoria? kde-format The account contains some transactions that will be removed. Do you still want to remove the account? Contul conține tranzacții care vor fi eliminate. Sigur doriți să eliminați contul? kde-format Remove Account? Eliminare cont? kde-format %2 of %1 %1: budget; %2: remaining budget %2 din %1 kde-format %1 (with no budget) %1 (fără buget) kde-format %1 (with budget %2) %1 (cu buget %2) kde-format Import CSV file Importare fișier CSV kde-format Transaction Type Selection Selecție tip tranzacție kde-format Expenses and incomes (negative cost) Cheltuieli și venituri (cost negativ) kde-format Expenses and incomes (separate columns) Cheltuieli și venituri (coloane separate) kde-format All types Toate tipurile kde-format File Selection Selectare fişier kde-format File: Fișier: kde-format First data row: Primul rând de date: kde-format Auto Automat kde-format Column delimiter: Separator coloane: kde-format Comma Virgulă kde-format Tabulator Tabulator kde-format Semicolon Punct și virgulă kde-format Space Spațiu kde-format Columns Specification Specificații coloane kde-format Column Coloană kde-format Category: Categorie: kde-format From account: De la contul: kde-format Create missing categories and accounts Creare categorii și conturi lipsă kde-format Imports data as expenses. Costs have positive value. Value is the only required column. Importă datele ca cheltuieli. Costurile au valori pozitive. Singura coloană necesară este valoarea. kde-format Imports data as incomes. Value is the only required column. Importă datele ca venituri. Singura coloană necesară este valoarea. kde-format To account: Către contul: kde-format Imports data as transfers. Value is the only required column. Importă datele ca transferuri. Singura coloană necesară este valoarea. kde-format Amount: Cantitate: kde-format Imports data as expenses and incomes. Costs have negative value. Value and category are both required columns. Importă datele ca cheltuieli și venituri. Costurile au valori negative. Valoarea și categoria sunt coloane necesare. kde-format Imports data as expenses and incomes. Costs and incomes have separate columns. Income, cost, and category are all required columns. Importă datele ca cheltuieli și venituri. Costurile și veniturile au coloane separate. Veniturile, costurile și categoria sunt coloane necesare. kde-format Imports data as expenses, incomes, and transfers. Costs have negative or positive value. Value, to, and from are all required columns. Accounts and categories must be existing. Importă datele ca cheltuieli, venituri și transferuri. Costurile au valori pozitive sau negative. Valoarea, destinația și originea sunt coloane necesare. Trebuie să existe și conturile și categoriile. kde-format From: Din: kde-format To: Către: kde-format A file must be selected. Trebuie să selectați un fișier. kde-format Selected file is a directory. Fișierul selectat este un director. kde-format Selected file does not exist. Fișierul selectat nu există. kde-format Empty delimiter. Separator gol. kde-format The same column number is selected multiple times. Același număr de coloană este selectat de mai multe ori. kde-format Selected from account is the same as the to account. Contul origine este același cu cel destinație. kde-format Couldn't open %1 for reading. Nu s-a putut deschide %1 pentru citire. kde-format Error reading %1. Eroare la citirea %1. kde-format Successfully imported 1 transaction. S-a importat cu succes 1 tranzacție. S-au importat cu succes %n tranzacții. S-au importat cu succes %n de tranzacții. kde-format Successfully imported %n transactions. Unable to import any transactions imported. Nu se poate importa nici o tranzacție. kde-format Failed to import 1 data row. Nu s-a putut importa 1 rând. Nu s-au putut importa %n rânduri. Nu s-au putut importa %n de rânduri. kde-format Failed to import %n data rows. Required columns missing. Coloanele necesare lipsesc. kde-format Invalid value. Valoare nevalidă. kde-format Empty category name. Nume categorie gol. kde-format Empty account name. Nume cont gol. kde-format Unknown category found. S-a găsit o categorie necunoscută. kde-format Unknown account found. S-a găsit un cont necunoscut. kde-format Cannot import security transactions (to/from security accounts). Nu s-au putut importa tranzacțiile de titluri de valoare (din/către conturile de titluri de valoare) kde-format Balancing account wrongly used. Cont de echilibrare folosit incorect. kde-format Same to and from account/category. Cont/categorie origine și destinație identice. kde-format No data found. Nu s-au găsit date. kde-format Unrecognized date format. Format dată nerecunoscut. kde-format Specify Format Specificați formatul kde-format The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. Formatul datelor și/sau numerelor din fișierul CSV este ambiguu. Selectați formatul corect. kde-format Date format: Format dată: kde-format Value format: Format valoare: kde-format tomorrow the day after today mâine kde-format today this day astăzi kde-format yesterday the day before today ieri kde-format &Today @option today As&tăzi kde-format To&morrow @option tomorrow &Mâine kde-format Next &Week @option next week Săptămâna &viitoare kde-format Next M&onth @option next month Luna viit&oare kde-format No Date @option do not specify a date Fără dată kde-format Export… Export… kde-format Print… Tipărire… kde-format Withdrawal Retragere kde-format Join… Alipire… kde-format Split Up Împărțire kde-format Empty transaction list. Listă de tranzacții goală. kde-format Are you sure you want to delete all (%1) selected transactions? Sigur doriți ștergerea tuturor (%1) tranzacții selectate? kde-format Cannot set the value of security transactions using the dialog for modifying multiple transactions. Nu se poate modifica valoarea tranzacțiilor cu titluri de valoare prin fereastra de modificare tranzacții multiple. kde-format Cannot change description of dividends and security transactions. Nu se poate schimba descrierea dividendelor și tranzacțiilor cu titluri de valoare. kde-format Cannot change payer of dividends and security transactions. Nu se poate schimba plătitorul dividendelor și tranzacțiilor cu titluri de valoare. kde-format Cannot change date of transactions that are part of a split transaction. Nu se poate schimba data tranzacțiilor care sunt parte a unei tranzacții împărțite. kde-format Eqonomize! Eqonomize! A personal accounting program Un program de contabilitate personală. Start with expenses list displayed Se afișează lista începuturilor de cheltuieli Start with incomes list displayed Se afișează lista începuturilor de venituri Start with transfers list displayed Se afișează lista începuturilor de transferuri Document to open Documentul de deschis Incomes and Expenses Venituri și cheltuieli kde-format Profits Profituri kde-format All Categories Combined Toate categoriile combinate kde-format All Descriptions Combined Toate descrierile combinate kde-format All Payees/Payers Combined Toți beneficiarii/plătitorii combinați kde-format Start date: Data de început: kde-format End date: Data de sfârșit: kde-format Monthly total Total lunar kde-format Daily average Medie zilnică kde-format All Payers Combined Toți plătitorii combinați kde-format All Payees Combined Toți beneficiarii combinați kde-format All Descriptions Split Toate descrierile împărțite kde-format All Payers Split Toți plătitorii împărțiți kde-format All Payees Split Toți beneficiarii împărțiți kde-format All Categories Split Toate categoriile împărțite kde-format Value (%1) Valoare (%1) kde-format Profit (%1) Profit (%1) kde-format Income (%1) Venit (%1) kde-format Cost (%1) Cost (%1) kde-format Time Timp kde-format no payer nici un plătitor kde-format %1/%2 %1: Description; %2: Payer %1/%2 kde-format no payee nici un beneficiar kde-format %1/%2 %1: Description; %2: Payee %1/%2 kde-format Error after saving file; data may not have been saved. Eroare după salvarea fișierului; este posibil ca datele să nu fie salvate. kde-format Average Profit Profit mediu kde-format Year An kde-format Month Lună kde-format Includes scheduled transactions Include tranzacțiile planificate kde-format Adjusted for the average month / year (%1 / %2 days) Ajustat pentru luna / anul mediu (%1 / %2 zile) kde-format Subtotal Subtotal kde-format Unnamed Fără nume kde-format Uncategorized Fără categorie kde-format Import QIF file Importă fișier QIF kde-format Select a QIF file to import. When you click next, the file be analysed and you might need to answer some questions about the format of the file. Selectați fișierul QIF pentru importare. Când apăsați „Următor”, fișierul va fi analizat și s-ar putea să trebuiască să răspundeți la câteva întrebări despre formatul fișierului. kde-format Local Definitions Definiții locale kde-format Unknown elements where found in the QIF file. It is possible that this is because of localized type names. Please map them to the correct standard names. S-au găsit elemente necunoscute în fișierul QIF, posibil datorită localizării numelor de tipuri. Asociați-le cu numele standard corecte. kde-format Local Text Text local kde-format Standard Text Text standard kde-format Select standard text: Selectați textul standard: kde-format Date Format Format dată kde-format The date format in the QIF file is ambiguous. Please select the correct format. Formatul de dată în fișierul QIF este ambiguu. Selectați formatul corect. kde-format Default Account Cont implicit kde-format Could not find any account definitions in the QIF file. Please select a default account. It is also possible that this is caused by a localized opening balance text. Nu s-au putut găsi definiții de conturi în fișierul QIF. Selectați un cont implicit. Această eroare poate fi cauzată și de localizarea textului balanței de deschidere. kde-format Default account: Cont implicit: kde-format Opening balance text: Text balanță de deschidere: kde-format Descriptions Descrieri kde-format Transactions in QIF files does not have any specific description property. You are therefore given the option to choose how the description of imported transactions will be set. Tranzacțiile într-un fișier QIF nu au descrieri specifice. Aveți opțiunea de a stabili descrierea tranzacțiilor importate. kde-format Subcategories as: Subcategorii ca: kde-format Ignore Ignoră kde-format Payee as: Beneficiar ca: kde-format Payee Beneficiar kde-format Memo as: Notă ca: kde-format Priority: Prioritate: kde-format Subcategory/Payee/Comments Subcategorie/beneficiar/comentarii kde-format Payee/Subcategory/Comments Beneficiar/subcategorie/comentarii kde-format Subcategory/Comments/Payee Subcategorie/comentarii/beneficiar kde-format Payee/Comments/Subcategory Beneficiar/comentarii/subcategorie kde-format Comments/Subcategory/Payee Comentarii/subcategorie/beneficiar kde-format Comments/Payee/Subcategory Comentarii/beneficiar/subcategorie kde-format Unknown Necunoscut kde-format Bank Bancă kde-format Cat (Category) Cat (Categorie) kde-format CCard (Credit Card) CCard (card credit) kde-format Invst (Investment) Invst (Investiție) kde-format Oth A (Other Assets) Alte R (Alte resurse) kde-format Oth L (Other Liabilities) Alte P (alte pasive) kde-format Security Titlu de valoare kde-format Successfully imported 1 account. S-a importat cu succes 1 cont. S-au importat cu succes %n conturi. S-au importat cu succes %n de conturi. kde-format Successfully imported %n accounts. Successfully imported 1 category. S-a importat cu succes 1 categorie. S-au importat cu succes %n categorii. S-au importat cu succes %n de categorii. kde-format Successfully imported %n categories. 1 duplicate transaction was ignored. 1 tranzacție duplicată a fost ignorată. %n tranzacții duplicate au fost ignorate. %n de tranzacții duplicate au fost ignorate. kde-format %n duplicate transactions was ignored. Failed to import 1 transaction. Nu s-a putut importa 1 tranzacție. Nu s-au putut importa %n tranzacții. Nu s-au putut importa %n de tranzacții. kde-format Failed to import %n transactions. 1 security was not imported. Nu s-a putut importa 1 titlu de valoare. Nu s-au putut importa %n titluri de valoare. Nu s-au putut importa %n de titluri de valoare. kde-format %n securities were not imported. 1 security transaction was not imported. Nu s-a putut importa 1 tranzacție cu titluri de valoare. Nu s-au putut importa %n tranzacții cu titluri de valoare. Nu s-au putut importa %n de tranzacții cu titluri de valoare. kde-format %n security transactions were not imported. Export QIF File Exportă fișier QIF kde-format All All accounts Toate kde-format Export transaction description as: Exportă descriere tranzacție ca: kde-format Memo Notă kde-format Subcategory Subcategorie kde-format &Import i18n: tag text i18n: file ./eqonomizeui.rc line 5 &Importă kde-format &Accounts i18n: tag text i18n: file ./eqonomizeui.rc line 12 &Conturi kde-format &Transactions i18n: tag text i18n: file ./eqonomizeui.rc line 24 &Tranzacții kde-format &Securities i18n: tag text i18n: file ./eqonomizeui.rc line 41 Titluri de &valoare kde-format Stat&istics i18n: tag text i18n: file ./eqonomizeui.rc line 56 Stat&istici kde-format Your names NAME OF TRANSLATORS ,Launchpad Contributions:,Adi Roiban,Bogdan Enache,Bogdan Enache kde-format Your emails EMAIL OF TRANSLATORS ,,adi@roiban.ro,,enachebogdan@gmx.net kde-format Edit Exceptions Editează excepțiile kde-format Edit Recurrence Range Editează intervalul de recurență kde-format Begins on: %1 Începe pe: %1 kde-format No ending date Nu se termină kde-format End after Se termină după kde-format occurrence(s) recurențe kde-format End on Se termină pe kde-format End date before start date. Dată de sfărșit înaintea celei de început. kde-format Enable recurrence Activează recurență kde-format Recurrence Rule Regulă de recurență kde-format Weekly Săptămânal kde-format Recur every Se repetă la fiecare kde-format day(s) zi(le) kde-format week(s) on: săptămână(i) în: kde-format month(s), after the start month luni, după luna de pornire kde-format Recur on the Se repetă în kde-format 1st prima kde-format 2nd a 2-a kde-format 3rd a 3-a kde-format 4th a 4-a kde-format 5th a 5-a kde-format 6th a 6-a kde-format 7th a 7-a kde-format 8th a 8-a kde-format 9th a 9-a kde-format 10th a 10-a kde-format 11th a 11-a kde-format 12th a 12-a kde-format 13th a 13-a kde-format 14th a 14-a kde-format 15th a 15-a kde-format 16th a 16-a kde-format 17th a 17-a kde-format 18th a 18-a kde-format 19th a 19-a kde-format 20th a 20-a kde-format 21st a 21-a kde-format 22nd a 22-a kde-format 23rd a 23-a kde-format 24th a 24-a kde-format 25th a 25-a kde-format 26th a 26-a kde-format 27th a 27-a kde-format 28th a 28-a kde-format 29th a 29-a kde-format 30th a 30-a kde-format 31st a 31-a kde-format Last ultima kde-format 2nd Last penultima kde-format 3rd Last antepenultima kde-format 4th Last a 4-a de la coadă kde-format 5th Last a 5-a de la coadă kde-format day zi kde-format possibly on weekend posibil în sfârșit de săptămână kde-format but before weekend dar înainte de sfârșit de săptămână kde-format but after weekend dar după sfârșit de săptămână kde-format year(s), after the start year an(i), după anul de început kde-format Recur on day part before XXX of 'Recur on day XXX of month YYY' Se repetă în ziua kde-format of part between XXX and YYY of 'Recur on day XXX of month YYY' din kde-format On the Part before NNN in 'Recur on the NNN. WEEKDAY of MONTH' Pe kde-format of part between WEEKDAY and MONTH in 'Recur on NNN. WEEKDAY of MONTH' din kde-format Recur on day # Se repetă în ziua # kde-format of the year part after NNN of 'Recur on day #NNN of the year' a anului kde-format Range… Perioadă… kde-format Exceptions… Excepții… kde-format No day of week selected for weekly recurrence. Nu ați selectat ziua săptămânii pentru recurența săptămânală. kde-format Selected day will never occur with selected frequency and start date. Ziua selectata nu va apărea folosind frecvența și data de pornire selectate. kde-format Selected day does not exist in selected month. Ziua selectată nu există în luna selectată. kde-format Dividend: %1 Dividend: %1 kde-format Account balancing Echilibrare cont kde-format Security: %1 (bought) Titlu de valoare: %1 (cumpărat) kde-format Security: %1 (sold) Titlu de valoare: %1 (vândut) kde-format Shares bought: Acțiuni cumpărate: kde-format Shares sold: Acțiuni vândute: kde-format Payer: Plătitor: kde-format Payee: Beneficiar: kde-format No income category available. Nu este definită nici o categorie de venit. kde-format No expense category available. Nu este definită nici o categorie de cheltuieli. kde-format Cannot create a regular transfer to/from a securities account. Nu se poate crea un transfer obișnuit din/de la un cont de titluri de valoare. kde-format Cannot create a regular income to a securities account. Nu se poate crea un venit obișnuit întrun cont de titluri de valoare. kde-format Zero price per share not allowed. Preț zero pe acțiune nu este permis. kde-format Cannot create a regular expense from a securities account. Nu se pot crea cheltuieli obișnuite întrun cont de titluri de valoare. kde-format Modify Transactions Modifică tranzacții kde-format Min amount: Cantitate minimă: kde-format Max amount: Cantitate maximă: kde-format Min income: Venit minim: kde-format Max income: Venit maxim: kde-format Min cost: Cost minim: kde-format Max cost: Cost maxim: kde-format Include Include kde-format Exclude Exclude kde-format From Account Din contul kde-format To Account Către contul kde-format Payer Plătitor kde-format New/Edit Expense Cheltuială nouă/modificare kde-format Filter Filtru kde-format Total: Total: kde-format Average: Mediu: kde-format Monthly: Lunar: kde-format Total cost: Cost total: kde-format Total income: Venit total: kde-format Total amount: Sumă totală: kde-format Monthly average: Medie lunară: kde-format Are you sure you want to delete all (%1) transactions in the selected split transaction? Sigur doriți ștergerea tuturor (%1) tranzacții din tranzacția împărțită selectată? kde-format * Part of split transaction * Parte tranzacție împărțită kde-format * Part of split (%1) * Parte din împărțire (%1) kde-format ** Recurring (editing occurrence) ** Recurentă (editare frecvență) kde-format Modify… Modificare… kde-format AccountComboBox New account… Cont nou… Multiple accounts/payments… New income category… Categorie de venit nouă… New expense category… Categorie de cheltuială nouă… Paid with loan… New Account Cont nou New Income Category Categorie de venit nouă New Expense Category Categorie de cheltuieli nouă AccountsMenu All Accounts Toate conturile All Categories Combined Toate categoriile combinate %n accounts %n categories Balancing Account balancing Echilibrare cont Account balancing Balancing of an account Echilibrare cont Account Balance Adjustment Budget Balancing Echilibrare Balancing Name of account for transactions that adjust account balances Echilibrare Couldn't open %1 for reading Nu s-a putut deschide %1 pentru citire Not a valid Eqonomize! file (XML parse error: "%1" at line %2, col %3) Nu este un fișier Eqonomize! valid (eroare procesare XML: „%1” la linia %2, col %3) Invalid root element %1 in XML document Element rădăcină %1 nevalid în documentul XML Unknown XML element: "%1" at line %2, col %3 XML parse error: "%1" at line %2, col %3 European Euro Unable to load %n currency/currencies. No exchange rates found. USD currency missing. imported Unable to load %n account(s). Nu s-a putut încărca %n cont. Nu s-au putut încărca %n conturi. Nu s-au putut încărca %n de conturi. Unable to load %n category/categories. Nu s-a putut încărca %n categorie. Nu s-au putut încărca %n categorii. Nu s-au putut încărca %n de categorii. Unable to load %n security/securities. Financial security (e.g. stock, mutual fund) Nu s-a putut încărca %n titlu de valoare. Nu s-au putut încărca %n titluri de valoare. Nu s-au putut încărca %n de titluri de valoare. Unable to load %n transaction(s). Nu s-a putut încărca %n tranzacție. Nu s-au putut încărca %n tranzacții. Nu s-au putut încărca %n de tranzacții. Download command (%1) failed: %2. Failed to download file from %1: %2. Upload command (%1) failed: %2. yyyy-yy Financial year when first month is not January (e.g. 2018-19). Transaction Accounts Conturi curente Savings Accounts Conturi de economii Credit Cards Carduri de credit Debts Datorii Securities Financial security (e.g. stock, mutual fund) Titluri de valoare Cash Numerar Transaction Account Cont curent Savings Account Cont de economii Credit Card Carte de credit Debt Datorie Other Altul File is a directory Fișierul este un director Couldn't open file for writing Nu s-a putut deschide fișierul pentru scriere Error while writing file; file was not saved S-a întâlnit o eroare la salvarea fișierului; acesta nu a fost salvat Unnamed Fără nume Uncategorized Fără categorie CategoriesComparisonChart Save As… Salvează ca… Print… Tipărire… From De la To La Source: Sursă: All Expenses Toate cheltuielile All Incomes Toate veniturile Theme: Chart type: Pie Chart Bar Chart Default Implicit All Expenses, without subcategories All Expenses, with subcategories All Incomes, without subcategories All Incomes, with subcategories All Accounts Toate conturile Expenses: %1 Cheltuieli: %1 Incomes: %1 Venituri: %1 Error Invalid date. Dată nevalidă. To date is before from date. Data „la” este înaintea datei „de la”. From date is after to date. Data „de la” este după data „la”. Couldn't open file for writing. Nu s-a putut deschide fișierul pentru scriere. Error while writing file; file was not saved. Eroare la scrierea fișierului; acesta nu a fost salvat. Expenses Cheltuieli Expenses, %1 Cheltuieli, %1 Incomes, %1 Venituri, %1 Incomes Venituri Accounts Conturi Expenses, %2: %1 Cheltuieli, %2: %1 Incomes, %2: %1 Venituri, %2: %1 Other descriptions Referring to the transaction description property (transaction title/generic article name) No description Referring to the transaction description property (transaction title/generic article name) Fără descriere Other accounts Other categories %1 Value: %2 No description Referring to the Transaction description property (transaction title/generic article name) Fără descriere No description Referring to the generic description property Fără descriere Value Valoare Income Venit Cost Cost Value (%1) Valoare (%1) Income (%1) Venit (%1) Cost (%1) Cost (%1) No description Fără descriere CategoriesComparisonChartDialog Chart Grafic CategoriesComparisonReport Save As… Salvează ca… Print… Tipărire… Source: Sursă: All Categories, excluding subcategories All Categories, including subcategories All Payees/Payers Toți beneficiarii/plătitorii Subcategories Descriptions for Referring to the Transaction description property (transaction title/generic article name) Descrieri pentru All descriptions Referring to the Transaction description property (transaction title/generic article name) Toate descrierile No description Referring to the Transaction description property (transaction title/generic article name) Fără descriere All Categories Toate categoriile Expenses: %1 Cheltuieli: %1 Incomes: %1 Venituri: %1 Descriptions for Descrieri pentru Payees/payers for Beneficiari/plătitori pentru Descriptions Referring to the Transaction description property (transaction title/generic article name) Descrieri Period: Perioadă: From De la To La Columns: Coloane: Value Valoare Daily Zilnic Monthly Lunar Yearly Anual Quantity Cantitate Average value Valoare medie All descriptions Toate descrierile All payees Toți beneficiarii All payers Toți plătitorii No description Fără descriere Descriptions for Referring to the generic description property Descrieri pentru Descriptions Referring to the generic description property Descrieri All descriptions Referring to the generic description property Toate descrierile No description Referring to the generic description property Fără descriere All Payees and Payers Toți beneficiarii și plătitorii Tag: %1 All Accounts Toate conturile Descriptions for Referring to the transaction description property (transaction title/generic article name) Descrieri pentru Descriptions Referring to the transaction description property (transaction title/generic article name) Descrieri Months Luni Years Ani Tags Total: Total: All descriptions Referring to the transaction description property (transaction title/generic article name) Toate descrierile All payees/payers Toți beneficiarii/plătitorii No description Referring to the transaction description property (transaction title/generic article name) Fără descriere No payee Nici un beneficiar No payer Nici un plătitor Error Invalid date. Dată nevalidă. To date is before from date. Data „la” este înaintea datei „de la”. From date is after to date. Data „de la” este după data „la”. Couldn't open file for writing. Nu s-a putut deschide fișierul pentru scriere. Error while writing file; file was not saved. Eroare la scrierea fișierului; acesta nu a fost salvat. Expenses, %2: %1 Cheltuieli, %2: %1 Expenses, %3: %2, %1 Cheltuieli, %3: %2, %1 Incomes, %2: %1 Venituri, %2: %1 Incomes, %3: %2, %1 Venituri, %3: %2, %1 %3: %2, %1 %2: %1 Tags, %1 Incomes & Expenses, %1 Venituri și cheltuieli, %1 Expenses: %2, %1 Cheltuieli: %2, %1 Incomes: %2, %1 Venituri: %2, %1 %2, %1 %1 %1 Incomes & Expenses Venituri și cheltuieli %1 (%2&ndash;%3) html format; %1: title; %2: from date; %3: to date %1 (%2&ndash;%3) %1 (to %2) html format; %1: title; %2: to date %1 (la %2) Category Categorie Payee Beneficiar Description Referring to the transaction description property (transaction title/generic article name) Descriere Cost Cost Payer Plătitor Income Venit Payee/Payer Beneficiar/plătitor Tag Daily Average Medie zilnică Monthly Average Media lunară Yearly Average Medie anuală Average Cost Cost mediu Average Income Venit mediu Average Value Valoare medie No payee/payer Nici un beneficiar/plătitor Total Total All Tags Total incomes Venituri totale Total expenses Cheltuieli totale Total (Profits) Total (profituri) CategoriesComparisonReportDialog Report Raport ConfirmScheduleDialog The following transactions was scheduled to occur today or before today. Confirm that they have indeed occurred (or will occur today). Următoarele tranzacții au fost planificate să se producă azi sau mai înainte. Confirmați că s-au produs (sau că se vor produce astăzi). Date Dată Type Tip Description Descriere Name Nume Description Generic Description Descriere Description Transaction description property (transaction title/generic article name) Descriere Amount Cantitate Edit… Editează… Postpone… Amână… Delete Șterge Error Can only postpone to future dates. Nu se poate amâna decât în viitor. ConfirmScheduleListViewItem Transfer Transfer Dividend Dividend Income Venit Expense Cheltuială Securities Purchase Financial security (e.g. stock, mutual fund) Cumpărare titlu de valoare Securities Sale Financial security (e.g. stock, mutual fund) Vânzare titlu de valoare Security Buy Cumpărare titlu de valoare Security Sell Vânzare titlu de valoare Debt Payment CurrencyConversionDialog Currency Converter DebtFee Debt payment: %1 (fee) DebtInterest Debt payment: %1 (interest) DebtPayment Debt payment: %1 DebtReduction Debt payment: %1 (reduction) DescriptionsMenu All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Toate descrierile combinate All Tags Combined All Payees Combined Toți beneficiarii combinați All Payers Combined Toți plătitorii combinați All Payees/Payers Combined Toți beneficiarii/plătitorii combinați No description Referring to the transaction description property (transaction title/generic article name) Fără descriere No payee Nici un beneficiar No payer Nici un plătitor No payee/payer Nici un beneficiar/plătitor %n descriptions Referring to the transaction description property (transaction title/generic article name) %n tags %n payees %n payers %n payees/payers EditAssetsAccountDialog Type: Tip: Cash Numerar Current Account Cont curent Savings Account Cont de economii Credit Card Carte de credit Liabilities Pasive Transactional Account Cont curent Debt Datorie Securities Titluri de valoare Other Altul Currency: Edit Editează Name: Nume: Bank: Bancă: Initial balance: Balanță inițială: Debt: Initial balance Balanță inițială Group: no group Transferred to: Date: Dată: Lender: Default account for budgeted transactions Cont implicit pentru tranzacții cu buget Description: Descriere: Account is closed Warning Type cannot be changed to securities for accounts with transactions. Issuer: Zero value not allowed. Valoarea zero nu este permisă. Error Transaction Account Cont curent Opening balance: Account balance Soldul de deschidere: Opening balance Account balance Soldul de deschidere New currency… If you change the currency of an account, the currency of all associated transactions will also change, without any conversion. Do do wish to continue anyway? Empty name. Nume nedefinit. The entered name is used by another account. Numele introdus este folosit la alt cont. EditCurrencyDialog Edit Currency New Currency Code: Symbol: Prefix Suffix Default Implicit Name: Nume: Decimals: Date: Dată: Main currency Error Error saving currencies: %1. Empty code. Code already exists. EditDebtPaymentDialog Debt Payment EditDebtPaymentWidget Debt: Date: Dată: Debt reduction: Reduction payment: Interest: Paid Added to debt Fee: Account: Cont: Expense category: Associated file: Select a file Open the file Comments: Comentarii: Related to: Label for linked transactions Legături: Total value: Valoare totală: Error No suitable account available. Nici un cont potrivit nu este disponibil. Invalid date. Dată nevalidă. Interest must not be zero. At least one value must non-zero. EditExceptionsDialog Edit Exceptions Editează excepțiile Occurrences: Recurențe: Add Exception Remove Exception Exceptions: Excepții: Only the first fifty occurrences are shown. Invalid date. Dată nevalidă. EditExpensesAccountDialog Name: Nume: Parent category: None Monthly budget: Buget lunar: Description: Descriere: Error Empty name. Nume nedefinit. The entered name is used by another expense category. Numele introdus este folosit la altă categorie de cheltuieli. EditIncomesAccountDialog Name: Nume: Parent category: None Monthly budget: Buget lunar: Description: Descriere: Error Empty name. Nume nedefinit. The entered name is used by another income category. Numele introdus este folosit la altă categorie de venituri. EditLoanTransactionWidget Date: Dată: Account: Cont: Comments: Comentarii: Total value: Valoare totală: No suitable account available. Nici un cont potrivit nu este disponibil. Invalid date. Dată nevalidă. EditMultiAccountDialog Expense with Multiple Payments Income with Multiple Payments EditMultiAccountWidget Description: Descriere: Description: Generic Description Descriere: Description: Transaction description property (transaction title/generic article name) Descriere: Quantity: Cantitate: Category: Categorie: Tags: Associated file: Select a file Open the file Comments: Comentarii: Related to: Label for linked transactions Legături: Transactions: Tranzacții: Date Dată Account Cont Payee Beneficiar Payer Plătitor Cost Cost Income Venit Total cost: Cost total: Value Valoare New Nou Edit… Editează… Delete Șterge Total value: Valoare totală: Error No suitable expense categories available. A split must contain at least two transactions. O împărțire trebuie să conțină cel puțin două tranzacții. EditMultiItemDialog Split Transaction Împarte tranzacția EditMultiItemWidget Description: Descriere: Description: Generic Description Descriere: Date: Dată: Account: Cont: Payee/Payer: Beneficiar/plătitor: Transactions: Tranzacții: Type Tip Description Generic Description Descriere Description: Transaction description property (transaction title/generic article name) Descriere: Tags: Associated file: Select a file Open the file Comments: Comentarii: Related to: Label for linked transactions Legături: Description Transaction description property (transaction title/generic article name) Descriere Payment Plată Deposit Depozit New Nou New Expense… Cheltuială nouă… New Income… Venit nou… New Deposit… Depozit nou… New Withdrawal… Retragere nouă… New Securities Purchase… Financial security (e.g. stock, mutual fund) Cumpărare nouă titlu de valoare… New Securities Sale… Financial security (e.g. stock, mutual fund) Vânzare nouă titlu de valoare… Shares Bought… Acțiuni cumpărate… Shares Sold… Acțiuni vândute… Account/Category Cont/Categorie Value Valoare Income Venit Expense Cheltuială New Dividend… Dividend nou… Edit… Editează… Delete Șterge Total value: Valoare totală: Error No suitable account available. Nici un cont potrivit nu este disponibil. Invalid date. Dată nevalidă. A split must contain at least two transactions. O împărțire trebuie să conțină cel puțin două tranzacții. Cannot transfer money to and from the same account. Nu se pot transfera bani din și către același cont. EditQuotationsDialog Quotations Cotație Date Dată Price per Share Preț per acțiune Quotations Financial quotation Cotație Quotes Financial quote Cotație Price per Share Financial Shares Preț per acțiune Add Adaugă Modify Modificare Delete Șterge Import… Importă… Export… Export… Quotes for %1 Financial quote Cotații pentru %1 Quotations for %1 Financial quotation Cotații pentru %1 Quotations for %1 Cotații pentru %1 Error Couldn't open %1 for reading. Nu s-a putut deschide %1 pentru citire. Error reading %1. Eroare la citirea %1. Successfully imported %n quote(s). Unable to import any quotes. Failed to import %n data row(s). Nu s-a putut importa %n rând. Nu s-au putut importa %n rânduri. Nu s-au putut importa %n de rânduri. Required columns missing. Coloanele necesare lipsesc. Invalid value. Valoare nevalidă. Invalid date. Dată nevalidă. No data found. Nu s-au găsit date. Information Unrecognized date format. Format dată nerecunoscut. Specify Format Specificați formatul The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. Formatul datelor și/sau numerelor din fișierul CSV este ambiguu. Selectați formatul corect. Date format: Format dată: Value format: Format valoare: Couldn't open file for writing. Nu s-a putut deschide fișierul pentru scriere. Quotes: %1 Cotație: %1 Error while writing file; file was not saved. Eroare la scrierea fișierului; acesta nu a fost salvat. EditRangeDialog Edit Recurrence Range Editează intervalul de recurență Begins on: %1 Începe pe: %1 No ending date Nu se termină End after Se termină după occurrence(s) recurențe End on Se termină pe Error Invalid date. Dată nevalidă. End date before start date. Dată de sfărșit înaintea celei de început. EditReinvestedDividendDialog Reinvested Dividend Dividend reinvestit Security: Titlu de valoare: Shares added: Acțiuni adăugate: Security: Financial security (e.g. stock, mutual fund) Titlu de valoare: Shares added: Financial shares Acțiuni adăugate: Date: Dată: Invalid date. Dată nevalidă. EditScheduledDebtPaymentDialog Transaction Tranzacție Recurrence Recurență Edit Debt Payment New Debt Payment EditScheduledLoanTransactionDialog Recurrence Recurență EditScheduledMultiAccountDialog Transactions Tranzacții Recurrence Recurență New Expense with Multiple Payments New Income with Multiple Payments Edit Expense with Multiple Payments Edit Income with Multiple Payments EditScheduledMultiItemDialog Transactions Tranzacții Recurrence Recurență New Split Transaction Tranzacție împărțită nouă Edit Split Transaction Editare tranzacție împărțită EditScheduledTransactionDialog Expense Cheltuială Dividend Dividend Income Venit Reinvested Dividend Dividend reinvestit Transfer Transfer Security Buy Cumpărare titlu de valoare Security Sell Vânzare titlu de valoare Securities Purchase Financial security (e.g. stock, mutual fund) Cumpărare titlu de valoare Securities Sale Financial security (e.g. stock, mutual fund) Vânzare titlu de valoare Recurrence Recurență New Expense Cheltuială nouă New Expense Paid with Loan New Dividend Dividend nou New Income Venit nou New Transfer Transfer nou New Securities Purchase Financial security (e.g. stock, mutual fund) Cumpărare nouă titlu de valoare New Reinvested Dividend New Securities Sale Financial security (e.g. stock, mutual fund) Vânzare nouă titlu de valoare Edit Reinvested Dividend Edit Securities Purchase Financial security (e.g. stock, mutual fund) Editează titluri de valoare cumpărate Edit Securities Sale Financial security (e.g. stock, mutual fund) Editează titluri de valoare vândute New Security Buy Cumpărare nouă titlu de valoare New Security Sell Vânzare nouă titlu de valoare Edit Expense Editează cheltuială Edit Dividend Editează dividend Edit Income Editează venit Edit Transfer Editează transfer Edit Securities Bought Editează titluri de valoare cumpărate Edit Securities Sold Editează titluri de valoare vândute EditSecurityDialog Type: Tip: Mutual Fund Fond mutual Bond Obligațiune Stock Stoc Stock Financial stock Stoc Other Altul Name: Nume: Account: Cont: Decimals in shares: Financial shares Zecimale în acțiuni: Initial shares: Financial shares Acțiuni inițiale: Decimals in quotes: Financial quote Initial quote: Financial quote Cotație inițială: Empty name. Nume nedefinit. No suitable account available. Nici un cont potrivit nu este disponibil. Initial quotation: Financial quotation Cotație inițială: Decimals in Shares: Zecimale în acțiuni: Initial Shares: Acțiuni inițiale: Initial quotation: Cotație inițială: Date: Dată: Description: Descriere: Error No suitable account or income category available. Nu există nici un cont sau tip de venit potrivit. EditSecurityTradeDialog Security Trade Tranzacție titlu de valoare From security: De la titlu de valoare: Shares moved: Acțiuni mutate: All Tot To security: Către titlu de valoare: Shares received: Acțiuni primite: Securities Exchange Shares of one security directly exchanged for shares of another; Financial security (e.g. stock, mutual fund) Tranzacție titlu de valoare From security: Financial security (e.g. stock, mutual fund) De la titlu de valoare: Shares moved: Financial shares Acțiuni mutate: To security: Financial security (e.g. stock, mutual fund) Către titlu de valoare: Shares received: Financial shares Acțiuni primite: Value: Valoare: Date: Dată: Error No other security available for exchange in the account. Shares of one security directly exchanged for shares of another; Financial security (e.g. stock, mutual fund) Nici un alt titlu de valoare nu este disponibil pentru tranzacționare în cont. No other security available for trade in the account. Nici un alt titlu de valoare nu este disponibil pentru tranzacționare în cont. Selected to and from securities are the same. Financial security (e.g. stock, mutual fund) Titlurile de valoare selectate „de la” și „la” sunt identice. Zero shares not allowed. Financial shares Acțiuni zero nu este permis. Selected to and from securities are the same. Titlurile de valoare selectate „de la” și „la” sunt identice. Invalid date. Dată nevalidă. Zero shares not allowed. Acțiuni zero nu este permis. Zero value not allowed. Valoarea zero nu este permisă. EditSplitDialog Split Transaction Împarte tranzacția Description: Descriere: Date: Dată: Account: Cont: Transactions: Tranzacții: Type Tip Description Descriere Name: Nume: Name Nume Description Generic Description Descriere Account/Category Cont/Categorie Payment Plată Deposit Depozit New Nou New Expense… Cheltuială nouă… New Income… Venit nou… New Deposit… Depozit nou… New Withdrawal… Retragere nouă… Shares Bought… Acțiuni cumpărate… Shares Sold… Acțiuni vândute… New Dividend… Dividend nou… Edit… Editează… Total value: Valoare totală: No suitable account available. Nici un cont potrivit nu este disponibil. Invalid date. Dată nevalidă. Future dates is not allowed. Datele în viitor nu sunt permise. A split must contain at least two transactions. O împărțire trebuie să conțină cel puțin două tranzacții. Cannot transfer money to and from the same account. Nu se pot transfera bani din și către același cont. Eqonomize Accounts && Categories Conturi și categorii Expenses Cheltuieli Incomes Venituri Transfers Transferuri Transaction Accounts Conturi curente Savings Accounts Conturi de economii Credit Cards Carduri de credit Debts Datorii Securities Titluri de valoare Schedule Planificare Account / Category Cont / categorie Remaining Budget (%1) Buget rămas (%1) Change (%1) Schimbare (%1) Total (%1) Total (%1) %2 of %1 %2 remains of %1 budget %2 din %1 Accounts Conturi Includes budgeted transactions Include tranzacții cu buget Tags Period Perioadă From De la To La Select Period Selectare perioadă Current Month Luna curentă Current Year Anul curent Current Whole Month Toată luna curentă Current Whole Year Tot anul curent Whole Past Month Toată luna trecută Whole Past Year Tot anul trecut Previous Month Luna anterioară Previous Year Anul anterior Show partial budget Arată bugetul parțial Edit Budget Editează buget Budget: Buget: Month: Luna: Result previous month: Rezultat luna trecută: New Security… Titlu de valoare nou… New Transaction Tranzacție nouă Set Quotation… Stabilire cotație… Name Nume Value Valoare Shares Acțiuni Quotation Cotație Cost Cost Profit Profit Yearly Rate Rată anuală Type Tip Account Cont Statistics Period Perioadă statistică New Schedule Planificare nouă Edit Editează Remove Elimină Next Occurrence Următoarea apariție Description Descriere Description Generic Description Descriere Amount Cantitate Payee/Payer Beneficiar/plătitor Comments Comentarii Set Schedule Confirmation Time Schedule confirmation time: Set Budget Period First day in budget month: 1st prima 2nd a 2-a 3rd a 3-a 4th a 4-a 5th a 5-a 6th a 6-a 7th a 7-a 8th a 8-a 9th a 9-a 10th a 10-a 11th a 11-a 12th a 12-a 13th a 13-a 14th a 14-a 15th a 15-a 16th a 16-a 17th a 17-a 18th a 18-a 19th a 19-a 20th a 20-a 21st a 21-a 22nd a 22-a 23rd a 23-a 24th a 24-a 25th a 25-a 26th a 26-a 27th a 27-a 28th a 28-a Last ultima 2nd Last penultima 3rd Last antepenultima 4th Last a 4-a de la coadă 5th Last a 5-a de la coadă Timestamp Links Legături Remove Link Link to "%1" create link to transaction (link used as verb) All Import Options Ignore duplicate transactions Rename duplicate accounts Rename duplicate categories Rename duplicate securities Synchronization Settings Web address: Download command: Duplicate Transaction… duplicate as verb Create Link create link to or between transaction(s) New Tag… Rename Tag… Remove Tag New Tag Tag name: Remove tag? Do you wish to remove the tag "%1" from %n transaction(s)? Rename Tag optional Right align Aliniați la dreapta Upload command: mandatory Automatic synchronization Upload Uploading… Error uploading file Error uploading %1: %2. Synchronizing… Error synchronizing file Error synchronizing %1: %2. Synchronization error Synchronize file? The file has been modified by a different user or program. Do you wish to merge changes? New version available A new version of %1 is available.<br><br>You can get version %2 at %3. Abort First month in budget year: %f = local file (temporary), %u = url Failed to download exchange rates from %1: %2. Error reading data from %1: %2. Unrecognized Currency No exchange rate is available for the default currency (%1). If you wish to use multiple currencies you should set the exchange rate manually. Set Main Currency Currency: Replace all occurrences of the former main currency Transaction Account Cont curent S&ynchronize Import %1 File… Reconcile Account… Adjust balance… Referring to account balance Close Account Mark account as closed New Expense Paid with Loan… Show payee and quantity Arată beneficiarul și cantitatea Show quantity and payer/payee properties for incomes and expenses. Select Font… Dark Mode Please restart the application for the language change to take effect. Only use this when unable to find the cause of the incorrect recorded account balance. Reopen Account Mark account as not closed New Debt Payment… New Unpaid Interest… Eqonomize! Accounting File Adjust Account Balance New Security Titlu de valoare nou Edit Security Modifică titlu de valoare Total value: Valoare totală: Cost: Cost: Profit: Profit: Rate: Rată: Are you sure you want to delete the security "%1" and all associated transactions? Sigur doriți ștergerea titlului de valoare „%1” și toate tranzacțiile asociate? Error No security available. Nu este disponibil nici un titlu de valoare. Set Quotation (%1) Stabilește cotația (%1) Price per share: Preț per acțiune: Date: Dată: Invalid date. Dată nevalidă. Future dates are not allowed. Datele în viitor nu sunt permise. Security Transactions Tranzacții titluri de valoare. Bond Obligațiune Stock Stoc Mutual Fund Fond mutual Other Altul Add Loan Add Category Ledger Registru To date is before from date. Data „la” este înaintea datei „de la”. From date is after to date. Data „de la” este după data „la”. Cash Numerar Check Account Cont cec Savings Account Cont de economii Salary Salariu Bills Facturi Clothing Îmbrăcăminte Groceries Alimente Leisure Timp liber Couldn't open file Nu s-a putut deschide fișierul Error loading %1: %2. Eroare la încărcarea %1: %2. Couldn't save file Nu s-a putut salva fișierul Error saving %1: %2. Eroare la salvarea %1: %2. Updating exchange rates… Error saving currencies: %1. New currency… Transaction Schedule Planificare tranzacție Total Total Accounts &amp; Categories html format Conturi și categorii Accounts &amp; Categories (%1&ndash;%2) html format Conturi și categorii (%1&ndash;%2) Accounts &amp; Categories (to %1) html format Conturi și categorii (la %1) Change Noun, how much the account balance has changed Schimbare Balance Balanță Current Account Cont curent Credit Card Carte de credit Liabilities Pasive Set Quote… Financial quote Stabilire cotație… Quote Financial quote Cotație Set Quote (%1) Financial quote Stabilește cotația (%1) Stock Financial stock Stoc Balance Noun. Balance of an account Balanță Category Categorie Budget Buget Remaining Budget Buget rămas Total Incomes Venituri totale Costs Costuri Total Expenses Cheltuieli totale Account/Category Noun, how much the account balance has changed Cont/Categorie Empty expenses list. Listă de cheltuieli goală. Empty incomes list. Listă de venituri goală. Empty transfers list. Listă de transferuri goală. Empty securities list. Listă de titluri de valoare goală. Empty schedule list. Listă de planificări goală. Couldn't open file for writing. Nu s-a putut deschide fișierul pentru scriere. Error while writing file; file was not saved. Eroare la scrierea fișierului; acesta nu a fost salvat. &File &Fișier &Accounts &Conturi &Transactions &Tranzacții &Securities Titluri de &valoare Stat&istics Stat&istici S&ettings C&onfigurări &Help &Ajutor File Fișier Transactions Tranzacții Statistics Statistici &New &Nou &Open… &Deschide… Open Recent Deschide recent Clear List Curăţă lista &Save &Salvează Save As… Salvează ca… &Revert &Reîncarcă &Print… &Tipărire… Print Preview… Previzualizare tipărire… Import Importă Import CSV File… Importare fișier CSV… Import QIF File… Importare fișier QIF… Export View… Exportare vizualizare… Export As QIF File… Exportare ca fișier QIF… Update Exchange Rates Currency Converter &Quit &Termină Add Account… Adăugare cont… New Account… Cont nou… New Loan… New Income Category… Categorie de venit nouă… New Expense Category… Categorie de cheltuială nouă… Add Account Adăugare cont Assets Resurse Description Transaction description property (transaction title/generic article name) Descriere Security Transactions Financial security (e.g. stock, bond) Tranzacții titluri de valoare. &Loans C&redite Edit… Editează… Balance… Echilibrare… Show Transactions Arată tranzacțiile Show Ledger New Expense… Cheltuială nouă… New Income… Venit nou… New Transfer… Transfer nou… New Split Transaction… Tranzacție împărțită nouă… New Expense with Multiple Payments… Refund… Rambursare… Repayment… Restituire… New Refund/Repayment… Rambursare/restituire nouă… Edit Transaction(s) (Occurrence)… Editare tranzacții (recurență)… Edit Occurrence… Editare recurență… Edit Schedule (Recurrence)… Editare planificare (recurență)… Edit Schedule… Editare planificare… Edit Split Transaction… Editare tranzacție împărțită… Join Transactions… join transactions together Alăturare tranzacții… Split Up Transaction split up joined transactions Împărțește tranzacția Edit Timestamp… Select Associated File Open Associated File Remove Transaction(s) (Occurrence) Elimină tranzacții (recurență) Remove Occurrence Elimină recurența Delete Schedule (Recurrence) Șterge planificare (recurență) Delete Schedule Șterge planificare Remove Split Transaction Eliminare tranzacție împărțită Edit Security… Editare titlu de valoare… Remove Security Eliminare titlu de valoare Shares Bought… Acțiuni cumpărate… Shares Sold… Acțiuni vândute… Shares Moved… Acțiuni mutate… Dividend… Dividend… Reinvested Dividend… Dividend reinvestit… Transactions… Tranzacții… Edit Quotations… Editare cotații… Development Over Time Report… Raport evoluție în timp… Categories Comparison Report… Raport comparare categorii… Development Over Time Chart… Grafic evoluție în timp… Categories Comparison Chart… Grafic comparare categorii… Use Additional Transaction Properties Folosește proprietăți adiționale la tranzacții Set Main Currency… Use Exchange Rate for Transaction Date Use the exchange rate nearest the transaction date, instead of the latest available rate, when converting the value of transactions. Set Budget Period… Initial Period Perioadă inițială Remember Last Dates Ține minte ultimele date Set Schedule Confirmation Time… Backup Frequency Daily Zilnic Weekly Săptămânal Fortnightly Monthly Lunar Never Language Limba Default Implicit Cloud Synchronization (experimental)… Help Report Bug About %1 About Qt Restart required A personal accounting program Un program de contabilitate personală License: GNU General Public License Version 3 Crash Recovery Restaurare după terminare prematură %1 exited unexpectedly before the file was saved and data was lost. Do you want to load the last auto-saved version of the file? %1 a ieșit în mod neașteptat înainte de salvarea fișierului și datele s-au pierdut. Doriți încărcarea ultimei versiuni de fișier salvate automat? Untitled Fără titlu Securities Financial security (e.g. stock, mutual fund) Titluri de valoare New Security… Financial security (e.g. stock, mutual fund) Titlu de valoare nou… Set Quotation… Financial quotation Stabilire cotație… Shares Financial shares Acțiuni Quotation Financial quotation Cotație New Security Financial security (e.g. stock, mutual fund) Titlu de valoare nou Edit Security Financial security (e.g. stock, mutual fund) Modifică titlu de valoare Delete security? Financial security (e.g. stock, mutual fund) Are you sure you want to delete the security "%1" and all associated transactions? Financial security (e.g. stock, mutual fund) Sigur doriți ștergerea titlului de valoare „%1” și toate tranzacțiile asociate? No security available. Financial security (e.g. stock, mutual fund) Nu este disponibil nici un titlu de valoare. Set Quotation (%1) Financial quotation Stabilește cotația (%1) Price per share: Financial shares Preț per acțiune: Security Transactions Financial security (e.g. stock, mutual fund) Tranzacții titluri de valoare Checking Account Transactional account Cont curent Balance Account balance Balanță Empty securities list. Financial security (e.g. stock, mutual fund) Listă de titluri de valoare goală. &Securities Financial security (e.g. stock, mutual fund) Titluri de &valoare Balance… Balance account Echilibrare… Edit Security… Financial security (e.g. stock, mutual fund) Editare titlu de valoare… Remove Security Financial security (e.g. stock, mutual fund) Eliminare titlu de valoare Shares Bought… Financial shares Acțiuni cumpărate… Shares Sold… Financial shares Acțiuni vândute… Edit Quotations… Financial quotation Editare cotații… The current file has been modified. Do you want to save it? Fișierul curent a fost modificat. Doriți să-l salvați? Save file? Confirm Schedule Confirmă planificarea New Account Cont nou New Loan New Income Category Categorie de venit nouă New Expense Category Categorie de cheltuieli nouă Balance Account Echilibrare cont Book value: Valoare registru: of which %1 is balance adjustment Referring to account balance Real value: Valoare reală: Edit Account Modifică contul Edit Income Category Editează categoria de venit Edit Expense Category Editează categoria de cheltuieli Remove subcategories? Do you wish to remove the category including all subcategories? Move transactions? Mutare tranzacții? Move to: Mută în: Remove irreversibly from all accounts (do not do this if account has been closed!) The category contains some expenses. What do you want to do with them? Categoria conține cheltuieli. Ce doriți să faceți cu ele? The category contains some incomes. What do you want to do with them? Categoria conține venituri. Ce doriți să faceți cu ele? The account contains some transactions. What do you want to do with them? Contul conține tranzacții. Ce doriți să le faceți cu ele? Remove Category? Eliminare categorie? The category contains some expenses that will be removed. Do you still want to remove the category? Categoria conține cheltuieli care vor fi eliminate. Încă doriți eliminarea categoriei? The category contains some incomes that will be removed. Do you still want to remove the category? Categoria conține venituri care vor fi eliminate. Sigur doriți să eliminați categoria? Remove Account? Eliminare cont? The account contains some transactions that will be removed. Do you still want to remove the account? Contul conține tranzacții care vor fi eliminate. Sigur doriți să eliminați contul? %2 of %1 %1: budget; %2: remaining budget %2 din %1 Balance… Verb. Balance an account Echilibrare… Shares Exchanged… Shares of one security directly exchanged for shares of another; Financial shares Acțiuni mutate… Shares of one security directly exchanged for shares of another Financial shares Edit Quotes… Financial quote Editare cotații… Balance Account Verb Echilibrare cont %1 (with no budget) %1 (fără buget) %1 (with budget %2) %1 (cu buget %2) EqonomizeCalendarWidget Today Astăzi EqonomizeDateEdit Today Astăzi EqonomizeTranslator OK Only used when Qt translation is missing Cancel Only used when Qt translation is missing Anulează Close Only used when Qt translation is missing Închide Yes Only used when Qt translation is missing Da No Only used when Qt translation is missing Nu &Yes Only used when Qt translation is missing &Da &No Only used when Qt translation is missing &Nu &Open Only used when Qt translation is missing &Deschide &Save Only used when Qt translation is missing &Salvează &Select All Only used when Qt translation is missing Look in: Only used when Qt translation is missing File &name: Only used when Qt translation is missing &Nume de fișier: Files of type: Only used when Qt translation is missing Fișiere de tip: EqonomizeValueEdit Error Empty denominator. Empty factor. Division by zero. Unknown or ambiguous currency, or unrecognized characters, in expression: %1. Empty base. Empty exponent. Unrecognized characters in expression. ExportQIFDialog Export QIF File Exportă fișier QIF Account: Cont: All All accounts Tot Export transaction description as: Exportă descriere tranzacție ca: Export transaction description as: Referring to generic description Exportă descriere tranzacție ca: Payee Beneficiar Memo Notă Subcategory Subcategorie Date format: Format dată: Value format: Format valoare: File: Fișier: Error Selected file is a directory. Fișierul selectat este un director. Overwrite The selected file already exists. Would you like to overwrite the old copy? Fișierul selectat deja există. Doriți să suprascrieți copia veche? You selected a directory! Ați selectat un director! Couldn't open file for writing. Nu s-a putut deschide fișierul pentru scriere. Error while writing file; file was not saved. Eroare la scrierea fișierului; acesta nu a fost salvat. ImportCSVDialog Import CSV file Importare fișier CSV Transaction Type Selection Selecție tip tranzacție Expenses Cheltuieli Incomes Venituri Transfers Transferuri Expenses and incomes (negative cost) Cheltuieli și venituri (cost negativ) Expenses and incomes (separate columns) Cheltuieli și venituri (coloane separate) All types Toate tipurile Presets: File Selection Selectare fişier File: Fișier: First data row: Primul rând de date: Auto Automat Column delimiter: Separator coloane: Comma Virgulă Tabulator Tabulator Semicolon Punct și virgulă Space Spațiu Other Altul Columns Specification Specificații coloane Save as preset… Imports data as expenses and incomes. Costs have negative value. Value is the only required column. Importă datele ca cheltuieli și venituri. Costurile au valori negative. Singura coloană necesară este valoarea. Imports data as expenses and incomes. Costs and incomes have separate columns. Income and cost both all required columns. Importă datele ca cheltuieli și venituri. Costurile și veniturile au coloane separate. Veniturile și costurile sunt coloane necesare. Warning The same column number is selected multiple times. Do you wish to proceed anyway? Description: Descriere: Description: Transaction description property (transaction title/generic article name) Descriere: Column Coloană Value Valoare Cost: Cost: Date: Dată: Category: Categorie: From account: De la contul: Quantity: Cantitate: Payee: Beneficiar: Tags: Comments: Comentarii: Create missing categories and accounts Creare categorii și conturi lipsă Save Preset Imports data as expenses. Costs have positive value. Value is the only required column. Importă datele ca cheltuieli. Costurile au valori pozitive. Singura coloană necesară este valoarea. Imports data as incomes. Value is the only required column. Importă datele ca venituri. Singura coloană necesară este valoarea. Income: Venit: To account: Către contul: Payer: Plătitor: Imports data as transfers. Value is the only required column. Importă datele ca transferuri. Singura coloană necesară este valoarea. Amount: Cantitate: Imports data as expenses and incomes. Costs have negative value. Value and category are both required columns. Importă datele ca cheltuieli și venituri. Costurile au valori negative. Valoarea și categoria sunt coloane necesare. Value: Valoare: Account: Cont: Payee/payer: Beneficiar/plătitor: Imports data as expenses and incomes. Costs and incomes have separate columns. Income, cost, and category are all required columns. Importă datele ca cheltuieli și venituri. Costurile și veniturile au coloane separate. Veniturile, costurile și categoria sunt coloane necesare. Imports data as expenses, incomes, and transfers. Costs have negative or positive value. Value, to, and from are all required columns. Accounts and categories must be existing. Importă datele ca cheltuieli, venituri și transferuri. Costurile au valori pozitive sau negative. Valoarea, destinația și originea sunt coloane necesare. Trebuie să existe și conturile și categoriile. From: Din: To: Către: Error A file must be selected. Trebuie să selectați un fișier. Selected file is a directory. Fișierul selectat este un director. Selected file does not exist. Fișierul selectat nu există. Empty delimiter. Separator gol. The same column number is selected multiple times. Același număr de coloană este selectat de mai multe ori. Selected from account is the same as the to account. Contul origine este același cu cel destinație. Invalid date. Dată nevalidă. Couldn't open %1 for reading. Nu s-a putut deschide %1 pentru citire. Error reading %1. Eroare la citirea %1. Uncategorized Fără categorie Successfully imported %n transaction(s). S-a importat cu succes %n tranzacție. S-au importat cu succes %n tranzacții. S-au importat cu succes %n de tranzacții. Unable to import any transactions. Nu se poate importa nici o tranzacție. Failed to import %n data row(s). Nu s-a putut importa %n rând. Nu s-au putut importa %n rânduri. Nu s-au putut importa %n de rânduri. Required columns missing. Coloanele necesare lipsesc. Invalid value. Valoare nevalidă. Empty category name. Nume categorie gol. Empty account name. Nume cont gol. Unknown category found. S-a găsit o categorie necunoscută. Unknown account found. S-a găsit un cont necunoscut. Cannot import security transactions (to/from security accounts). Nu s-au putut importa tranzacțiile de titluri de valoare (din/către conturile de titluri de valoare). Balancing account wrongly used. Referring to the account used for adjustments of account balances. Cont de echilibrare folosit incorect. Balancing account wrongly used. Cont de echilibrare folosit incorect. Same to and from account/category. Cont/categorie origine și destinație identice. No data found. Nu s-au găsit date. Information Unrecognized date format. Format dată nerecunoscut. Specify Format Specificați formatul The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. Formatul datelor și/sau numerelor din fișierul CSV este ambiguu. Selectați formatul corect. Date format: Format dată: Value format: Format valoare: ImportQIFDialog Import QIF file Importă fișier QIF File Selection Selectare fişier Select a QIF file to import. When you click next, the file be analysed and you might need to answer some questions about the format of the file. Selectați fișierul QIF pentru importare. Când apăsați „Următor”, fișierul va fi analizat și s-ar putea să trebuiască să răspundeți la câteva întrebări despre formatul fișierului. File: Fișier: Local Definitions Definiții locale Unknown elements where found in the QIF file. It is possible that this is because of localized type names. Please map them to the correct standard names. S-au găsit elemente necunoscute în fișierul QIF, posibil datorită localizării numelor de tipuri. Asociați-le cu numele standard corecte. Local Text Text local Standard Text Text standard Select standard text: Selectați textul standard: Date Format Format dată The date format in the QIF file is ambiguous. Please select the correct format. Formatul de dată în fișierul QIF este ambiguu. Selectați formatul corect. Date format: Format dată: Default Account Cont implicit Could not find any account definitions in the QIF file. Please select a default account. It is also possible that this is caused by a localized opening balance text. Nu s-au putut găsi definiții de conturi în fișierul QIF. Selectați un cont implicit. Această eroare poate fi cauzată și de localizarea textului balanței de deschidere. Default account: Cont implicit: Opening balance text: Text balanță de deschidere: Descriptions Descrieri Transactions in QIF files does not have any specific description property. You are therefore given the option to choose how the description of imported transactions will be set. Tranzacțiile într-un fișier QIF nu au descrieri specifice. Aveți opțiunea de a stabili descrierea tranzacțiilor importate. Subcategories as: Subcategorii ca: Description Descriere Transactions in QIF files does not have any specific description property. You are therefore given the option to choose how the description of imported transactions will be set. Referring to generic description Tranzacțiile într-un fișier QIF nu au descrieri specifice. Aveți opțiunea de a stabili descrierea tranzacțiilor importate. Category Categorie Ignore Ignoră Payee as: Beneficiar ca: Payee Beneficiar Memo as: Notă ca: Comments Comentarii Priority: Prioritate: Subcategory/Payee/Comments Subcategorie/beneficiar/comentarii Payee/Subcategory/Comments Beneficiar/subcategorie/comentarii Subcategory/Comments/Payee Subcategorie/comentarii/beneficiar Payee/Comments/Subcategory Beneficiar/comentarii/subcategorie Comments/Subcategory/Payee Comentarii/subcategorie/beneficiar Comments/Payee/Subcategory Comentarii/beneficiar/subcategorie Import File No (further) issues were found. Press finish to import the selected QIF file. Ignore duplicate transactions Error A file must be selected. Trebuie să selectați un fișier. Selected file is a directory. Fișierul selectat este un director. Selected file does not exist. Fișierul selectat nu există. Couldn't open %1 for reading. Nu s-a putut deschide %1 pentru citire. Error reading %1. Eroare la citirea %1. Unknown Necunoscut Account Cont Bank Bancă Cash Numerar Cat (Category) Cat (Categorie) CCard (Credit Card) CCard (card credit) Invst (Investment) Invst (Investiție) Oth A (Other Assets) Oth A (Alte resurse) Oth L (Other Liabilities) Oth L (alte pasive) Security Titlu de valoare Other Altul Unrecognized date format. Format dată nerecunoscut. Successfully imported %n transaction(s). S-a importat cu succes %n tranzacție. S-au importat cu succes %n tranzacții. S-au importat cu succes %n de tranzacții. Successfully imported %n account(s). S-a importat cu succes %n cont. S-au importat cu succes %n conturi. S-au importat cu succes %n de conturi. Successfully imported %n category/categories. S-a importat cu succes %n categorie. S-au importat cu succes %n categorii. S-au importat cu succes %n de categorii. %n duplicate transaction(s) was ignored. %n tranzacție duplicată a fost ignorată. %n tranzacții duplicate au fost ignorate. %n de tranzacții duplicate au fost ignorate. Failed to import %n transaction(s). Nu s-a putut importa %n tranzacție. Nu s-au putut importa %n tranzacții. Nu s-au putut importa %n de tranzacții. %n security/securities were not imported. Financial security (e.g. stock, mutual fund) Nu s-a putut importa %n titlu de valoare. Nu s-au putut importa %n titluri de valoare. Nu s-au putut importa %n de titluri de valoare. %n security transaction(s) were not imported. Financial security (e.g. stock, mutual fund) Nu s-a putut importa %n tranzacție cu titluri de valoare. Nu s-au putut importa %n tranzacții cu titluri de valoare. Nu s-au putut importa %n de tranzacții cu titluri de valoare. Information Income Dividend: %1 Dividend: %1 Reinvested dividend: %1 Dividend reinvestit: %1 LedgerDialog Account: Cont: Edit Account… Modifică contul… Export… Export… Print… Tipărire… Reconcile Accounting context Mark all as reconciled Accounting context Change: Accounting context Schimbare: R Header for account reconciled checkbox column Date Dată Type Tip Description Descriere Name Nume Description Generic Description Descriere Account/Category Cont/Categorie Deposit Depozit Withdrawal Retragere Balance Balanță Balance Account balance Balanță Payee/Payer Beneficiar/plătitor Tags Comments Comentarii Deposit Money put into account Depozit Withdrawal Money taken out from account Retragere Balance Noun. Balance of an account Balanță New Nou Edit… Editează… Delete Șterge Join… join transactions together Alipire… Split Up split up joined transactions Împărțire Edit Transaction(s)… Editare tranzacții… Join Transactions… Alăturare tranzacții… Split Up Transaction Împărțește tranzacția Remove Transaction(s) Elimină tranzacții Mark as reconciled Reconciled: %1 (%2) Accounting context Book value: %1 (%2) Accounting context Valoare registru: %1 (%2) Error Invalid date. Dată nevalidă. Opening date is after closing date. Closing date is before opening date. Empty transaction list. Listă de tranzacții goală. Couldn't open file for writing. Nu s-a putut deschide fișierul pentru scriere. Error while writing file; file was not saved. Eroare la scrierea fișierului; acesta nu a fost salvat. Ledger Registru Transactions for %1 Tranzacții pentru %1 Select Time Period From: Din: To: Către: To date is before from date. Data „la” este înaintea datei „de la”. Balance change: Account balance Delete transactions? Are you sure you want to delete all (%1) selected transactions? Sigur doriți ștergerea tuturor (%1) tranzacții selectate? Cannot set the value of security transactions using the dialog for modifying multiple transactions. Financial security (e.g. stock, mutual fund) Nu se poate modifica valoarea tranzacțiilor cu titluri de valoare prin fereastra de modificare tranzacții multiple. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name); Financial security (e.g. stock, mutual fund) Nu se poate schimba descrierea dividendelor și tranzacțiilor cu titluri de valoare. Cannot change payer of dividends and security transactions. Financial security (e.g. stock, mutual fund) Nu se poate schimba plătitorul dividendelor și tranzacțiilor cu titluri de valoare. Opening balance Account balance Soldul de deschidere Account Balance Adjustment Current balance: Account balance Average balance: Account balance Account Balancing Balancing of an account Echilibrare cont Balancing Balancing of an account Echilibrare Balancing Account balancing Echilibrare Cannot set the value of security transactions using the dialog for modifying multiple transactions. Nu se poate modifica valoarea tranzacțiilor cu titluri de valoare prin fereastra de modificare tranzacții multiple. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name) Nu se poate schimba descrierea dividendelor și tranzacțiilor cu titluri de valoare. Cannot change description of dividends and security transactions. Referring to the generic description property Nu se poate schimba descrierea dividendelor și tranzacțiilor cu titluri de valoare. Current debt: Total debt reduction: Total interest and fees: Number of transactions: Cannot change description of dividends and security transactions. Nu se poate schimba descrierea dividendelor și tranzacțiilor cu titluri de valoare. Cannot change payer of dividends and security transactions. Nu se poate schimba plătitorul dividendelor și tranzacțiilor cu titluri de valoare. Cannot change date of transactions that are part of a split transaction. Nu se poate schimba data tranzacțiilor care sunt parte a unei tranzacții împărțite. Initial balance Balanță inițială Split Transaction Împarte tranzacția Debt Payment Ascending order Reduction Fee Interest Income Venit Repayment Restituire Expense Cheltuială Opening balance: Accounting context Soldul de deschidere: Closing balance: Accounting context Description Transaction description property (transaction title/generic article name) Descriere Cannot change description of dividends and security transactions. Referring to the Transaction description property (transaction title/generic article name) Nu se poate schimba descrierea dividendelor și tranzacțiilor cu titluri de valoare. Refund Rambursare Balancing Echilibrare Transfer Transfer LinksWidget Remove Link All Remove Elimină MultiItemListViewItem Dividend Dividend Income Venit Repayment Restituire Expense Cheltuială Refund Rambursare Securities Purchase Financial security (e.g. stock, mutual fund) Cumpărare titlu de valoare Securities Sale Financial security (e.g. stock, mutual fund) Vânzare titlu de valoare Account Balance Adjustment Account Balancing Balancing of an account Echilibrare cont Balancing Balancing of an account Echilibrare Security Buy Cumpărare titlu de valoare Security Sell Vânzare titlu de valoare Balancing Echilibrare Transfer Transfer MultipleTransactionsEditDialog Modify Transactions Modifică tranzacții Description: Descriere: Name: Nume: Description: Transaction description property (transaction title/generic article name) Descriere: Amount: Cantitate: Income: Venit: Cost: Cost: Date: Dată: Category: Categorie: Payer: Plătitor: Payee: Beneficiar: New Income Category Categorie de venit nouă New Expense Category Categorie de cheltuieli nouă New Income Category… Categorie de venit nouă… New Expense Category… Categorie de cheltuială nouă… Error No income category available. Nu este definită nici o categorie de venit. No expense category available. Nu este definită nici o categorie de cheltuieli. Invalid date. Dată nevalidă. OverTimeChart Save As… Salvează ca… Print… Tipărire… Source: Sursă: Incomes and Expenses Venituri și cheltuieli Profits Profituri Expenses Cheltuieli Incomes Venituri All Categories Combined Toate categoriile combinate All Descriptions Combined Toate descrierile combinate Theme: Chart type: Line Chart Vertical Bar Chart Horizontal Bar Chart Stacked Bar Chart Default Implicit Tags All Accounts Combined Toate conturile combinate All Accounts Split Toate conturile împărțiți All Subcategories and Descriptions Combined Referring to the transaction description property (transaction title/generic article name) All Descriptions Split Referring to the transaction description property (transaction title/generic article name) Toate descrierile împărțite No description Referring to the transaction description property (transaction title/generic article name) Fără descriere All Payees/Payers Split Toți beneficiarii/plătitorii împărțiți No payee/payer Nici un beneficiar/plătitor All Tags Split Other tags Other payees/payers Other descriptions Referring to the transaction description property (transaction title/generic article name) Profits, %1 Profituri, %1 Assets Resurse All Descriptions Combined Referring to the generic description property Toate descrierile combinate Assets and Liabilities All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Toate descrierile combinate All Payees/Payers Combined Toți beneficiarii/plătitorii combinați All Accounts Toate conturile Start date: Data de început: End date: Data de sfârșit: Value: Valoare: Annual total Monthly total Total lunar Daily average Medie zilnică Quantity Cantitate Average value Valoare medie All Payers Combined Toți plătitorii combinați All Payees Combined Toți beneficiarii combinați All Subcategories Split All Descriptions Split Referring to the generic description property Toate descrierile împărțite No description Referring to the generic description property Fără descriere Value Valoare Includes budgeted transactions Include tranzacții cu buget Incomes − Expenses, %1 Venituri − cheltuieli, %1 Incomes − Expenses Venituri − cheltuieli Incomes & Expenses Venituri și cheltuieli Incomes: %1 Venituri: %1 Expenses: %1 Cheltuieli: %1 %2: %1 Incomes: %2, %1 Venituri: %2, %1 Expenses: %2, %1 Cheltuieli: %2, %1 %3: %2, %1 %2, %1 Incomes: %3, %2, %1 Venituri: %3, %2, %1 Expenses: %3, %2, %1 Cheltuieli: %3, %2, %1 %4: %3, %2, %1 no payee/payer nici un beneficiar/plătitor %3, %2, %1 Other accounts %1 Value: %2 Date: %3 MMMM yyyy Month and year All Descriptions Split Toate descrierile împărțite All Payers Split Toți plătitorii împărțiți All Payees Split Toți beneficiarii împărțiți No description Fără descriere No payer Nici un plătitor No payee Nici un beneficiar All Categories Split Toate categoriile împărțite Error Invalid date. Dată nevalidă. Couldn't open file for writing. Nu s-a putut deschide fișierul pentru scriere. Error while writing file; file was not saved. Eroare la scrierea fișierului; acesta nu a fost salvat. Other payees Other payers Value (%1) Valoare (%1) Profit (%1) Profit (%1) Income (%1) Venit (%1) Cost (%1) Cost (%1) Time Timp %1/%2 %1: Category; %2: Payee/Payer %1/%2 All Descriptions Combined Referring to the Transaction description property (transaction title/generic article name) Toate descrierile combinate All Descriptions Split Referring to the Transaction description property (transaction title/generic article name) Toate descrierile împărțite No description Referring to the Transaction description property (transaction title/generic article name) Fără descriere Daily average value Daily average profit Daily average income Daily average cost Average income Average cost Annual value Annual profit Annual income Annual cost Monthly value Monthly profit Monthly income Monthly cost Includes scheduled and budgeted transactions Include tranzacții planificate și bugetate Includes scheduled transactions Include tranzacțiile planificate Tags, %1 Value: %1 Valoare: %1 Assets & Liabilities Change: %1 Schimbare: %1 Excluding any profits or losses in trading of security shares Financial security (e.g. stock, mutual fund) Incomes & Expenses, %1 Venituri și cheltuieli, %1 Incomes, %1 Venituri, %1 Expenses, %1 Cheltuieli, %1 Incomes, %2: %1 Venituri, %2: %1 Expenses, %2: %1 Cheltuieli, %2: %1 Incomes, %3: %2, %1 Venituri, %3: %2, %1 Expenses, %3: %2, %1 Cheltuieli, %3: %2, %1 Incomes, %4: %3, %2, %1 Venituri, %4: %3, %2, %1 Expenses, %4: %3, %2, %1 Cheltuieli, %4: %3, %2, %1 Liabilities Pasive no payer nici un plătitor %1/%2 %1: Description; %2: Payer/Payer %1/%2 %1/%2 %1: Description; %2: Payee/Payer %1/%2 %1/%2 %1: Description; %2: Payer %1/%2 no payee nici un beneficiar %1/%2 %1: Description; %2: Payee %1/%2 OverTimeChartDialog Chart Grafic OverTimeReport Save As… Salvează ca… Print… Tipărire… Source: Sursă: Profits Profituri Expenses Cheltuieli Incomes Venituri Assets & Liabilities Tags All Categories Combined Toate categoriile combinate All Descriptions Combined Toate descrierile combinate Columns: Coloane: Categories Total: Total: Value Valoare Daily Zilnic Monthly Lunar Yearly Anual Quantity Cantitate Average value Valoare medie No description Fără descriere All Descriptions Combined Referring to the generic description property Toate descrierile combinate No description Referring to the generic description property Fără descriere All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Toate descrierile combinate All Accounts Toate conturile No description Referring to the transaction description property (transaction title/generic article name) Fără descriere Error Couldn't open file for writing. Nu s-a putut deschide fișierul pentru scriere. Error while writing file; file was not saved. Eroare la scrierea fișierului; acesta nu a fost salvat. Average Profit Profit mediu Incomes, %1 Venituri, %1 Average Income Venit mediu Expenses, %1 Cheltuieli, %1 Average Cost Cost mediu Incomes, %2: %1 Venituri, %2: %1 Incomes: %1 Venituri: %1 Expenses, %2: %1 Cheltuieli, %2: %1 Expenses: %1 Cheltuieli: %1 Incomes, %3: %2, %1 Venituri, %3: %2, %1 Incomes: %2, %1 Venituri: %2, %1 Expenses, %3: %2, %1 Cheltuieli, %3: %2, %1 Expenses: %2, %1 Cheltuieli: %2, %1 Change: %1 Noun, how much the account balance has changed Schimbare: %1 Average Change Schimbare mediu Change Noun, how much the account balance has changed Schimbare Value: %1 Valoare: %1 Year An Month Lună Assets Resurse Deposit Depozit Withdrawal Retragere Liabilities Pasive %2: %1 %1 %1 Average Value Valoare medie %3: %2, %1 %2, %1 Daily Average Medie zilnică Monthly Average Media lunară Yearly Average Medie anuală Subtotal Subtotal Total Total Deposit Money put into account Depozit Withdrawal Money taken out from account Retragere Includes scheduled transactions Include tranzacțiile planificate Adjusted for the average month / year (%1 / %2 days) Ajustat pentru luna / anul mediu (%1 / %2 zile) All Categories Combined Referring to the generic description property Toate categoriile combinate OverTimeReportDialog Report Raport QApplication Start with expenses list displayed Se afișează lista începuturilor de cheltuieli Start with incomes list displayed Se afișează lista începuturilor de venituri Start with transfers list displayed Se afișează lista începuturilor de transferuri Synchronize file Document to open Documentul de deschis %1 is already running. QObject Transfer Transfer Dividend Dividend Income Venit Expense Cheltuială Securities Purchase Financial security (e.g. stock, mutual fund) Cumpărare titlu de valoare Securities Sale Financial security (e.g. stock, mutual fund) Vânzare titlu de valoare Security Buy Cumpărare titlu de valoare Security Sell Vânzare titlu de valoare Debt Payment Split Transaction Împarte tranzacția RecurrenceEditWidget Enable recurrence Activează recurență Recurrence Rule Regulă de recurență Daily Zilnic Weekly Săptămânal Monthly Lunar Yearly Anual Recur every Se repetă la fiecare day(s) zi(le) week(s) on: săptămână(i) în: month(s), after the start month luni, după luna de pornire Recur on the Se repetă în 1st prima 2nd a 2-a 3rd a 3-a 4th a 4-a 5th a 5-a 6th a 6-a 7th a 7-a 8th a 8-a 9th a 9-a 10th a 10-a 11th a 11-a 12th a 12-a 13th a 13-a 14th a 14-a 15th a 15-a 16th a 16-a 17th a 17-a 18th a 18-a 19th a 19-a 20th a 20-a 21st a 21-a 22nd a 22-a 23rd a 23-a 24th a 24-a 25th a 25-a 26th a 26-a 27th a 27-a 28th a 28-a 29th a 29-a 30th a 30-a 31st a 31-a Last ultima 2nd Last penultima 3rd Last antepenultima 4th Last a 4-a de la coadă 5th Last a 5-a de la coadă day zi possibly on weekend posibil în sfârșit de săptămână but before weekend dar înainte de sfârșit de săptămână but after weekend dar după sfârșit de săptămână nearest weekend day year(s), after the start year an(i), după anul de început on nearest weekday Recur on day part before XXX of 'Recur on day XXX of month YYY' Se repetă în ziua of part between XXX and YYY of 'Recur on day XXX of month YYY' din On the Part before NNN in 'Recur on the NNN. WEEKDAY of MONTH' Pe of part between WEEKDAY and MONTH in 'Recur on NNN. WEEKDAY of MONTH' din Recur on day # Se repetă în ziua # of the year part after NNN of 'Recur on day #NNN of the year' a anului Range… Perioadă… Occurrences/Exceptions… Recurențe/excepții… Exceptions… Excepții… Error No day of week selected for weekly recurrence. Nu ați selectat ziua săptămânii pentru recurența săptămânală. Selected day will never occur with selected frequency and start date. Ziua selectata nu va apărea folosind frecvența și data de pornire selectate. Selected day does not exist in selected month. Ziua selectată nu există în luna selectată. RefundDialog Repayment Restituire Refund Rambursare Date: Dată: Cost: Cost: Income: Venit: Quantity returned: Cantitate returnată: Account: Cont: Quantity: Cantitate: Payee: Beneficiar: Payer: Plătitor: Comments: Comentarii: Link Link the transactions together Join Join the transactions together Alipire Error Zero value not allowed. Valoarea zero nu este permisă. Invalid date. Dată nevalidă. SecurityBuy Security: %1 (bought) Titlu de valoare: %1 (cumpărat) Security: %1 (bought) Financial security (e.g. stock, mutual fund) Titlu de valoare: %1 (cumpărat) SecuritySell Security: %1 (sold) Titlu de valoare: %1 (vândut) Security: %1 (sold) Financial security (e.g. stock, mutual fund) Titlu de valoare: %1 (vândut) SecurityTransactionsDialog Transactions for %1 Tranzacții pentru %1 Date Dată Type Tip Value Valoare Shares Financial shares Acțiuni Shares Bought Financial shares Acțiuni cumpărate Shares Bought (Recurring) Financial shares Acțiuni cumpărate (recurent) Dividend (Recurring) Dividend (recurent) Dividend (Scheduled) Dividend (planificate) Reinvested Dividend (Recurring) Dividend reinvestit (recurent) Reinvested Dividend (Scheduled) Dividend reinvestit (planificate) Shares Bought Fincancial shares Acțiuni cumpărate Shares Sold Financial shares Acțiuni vândute Shares Sold (Exchanged) Shares of one security directly exchanged for shares of another; Financial shares Acțiuni vândute (schimbate) Shares Bought (Exchanged) Shares of one security directly exchanged for shares of another; Financial shares Acțiuni vândute (schimbate) Shares Bought (Recurring) Fincancial shares Acțiuni cumpărate (recurent) Shares Sold (Recurring) Financial shares Acțiuni vândute (recurent) Shares Bought (Scheduled) Financial shares Acțiuni cumpărate (planificate) Shares Sold (Scheduled) Financial shares Acțiuni vândute (planificate) Shares Acțiuni Edit… Editează… Delete Șterge Shares Bought Acțiuni cumpărate Shares Sold Acțiuni vândute Dividend Dividend Reinvested Dividend Dividend reinvestit Shares Sold (Traded) Acțiuni vândute (schimbate) Shares Bought (Traded) Acțiuni vândute (schimbate) Shares Bought (Recurring) Acțiuni cumpărate (recurent) Shares Sold (Recurring) Acțiuni vândute (recurent) Shares Bought (Scheduled) Acțiuni cumpărate (planificate) Shares Sold (Scheduled) Acțiuni vândute (planificate) Recurring Dividend Dividend recurent Scheduled Dividend Dividend planificat SplitListViewItem Dividend Dividend Income Venit Repayment Restituire Expense Cheltuială Refund Rambursare Security Buy Cumpărare titlu de valoare Security Sell Vânzare titlu de valoare Balancing Echilibrare Transfer Transfer TagButton no tags TagMenu New tag… New Tag Tag: TransactionEditDialog Edit Expense Editează cheltuială Edit Dividend Editează dividend Edit Income Editează venit Edit Transfer Editează transfer Edit Securities Purchase Financial security (e.g. stock, mutual fund) Editează titluri de valoare cumpărate Edit Securities Sale Financial security (e.g. stock, mutual fund) Editează titluri de valoare vândute Edit Reinvested Dividend Edit Securities Bought Editează titluri de valoare cumpărate Edit Securities Sold Editează titluri de valoare vândute TransactionEditWidget Security: Titlu de valoare: Cost: Cost: Income: Venit: Shares bought: Acțiuni cumpărate: Shares sold: Acțiuni vândute: All Tot Price per share: Preț per acțiune: Date: Dată: Description: Descriere: Name: Nume: Amount: Cantitate: Withdrawal: Money taken out from account Retragere: New Security… Financial security (e.g. stock, mutual fund) Titlu de valoare nou… Shares added: Financial shares Acțiuni adăugate: Set security share value Total value: Valoare totală: Deposit: Money put into account Depozit: Downpayment: Quantity: Cantitate: From: Din: To: Către: Category: Categorie: To account: Către contul: Payer: Plătitor: Payer of parent split transaction From account: De la contul: Downpayment account: Payee: Beneficiar: Payee of parent split transaction Lender: Tags: Associated file: Select a file Open the file Comments: Comentarii: Related to: Label for linked transactions Legături: New Security Financial security (e.g. stock, mutual fund) Titlu de valoare nou No security available. Financial security (e.g. stock, mutual fund) Nu este disponibil nici un titlu de valoare. New Account Cont nou New Income Category Categorie de venit nouă New Expense Category Categorie de cheltuieli nouă New Account… Cont nou… New Income Category… Categorie de venit nouă… New Expense Category… Categorie de cheltuială nouă… Security: Financial security (e.g. stock, mutual fund) Titlu de valoare: Shares bought: Financial shares Acțiuni cumpărate: Shares sold: Financial shares Acțiuni vândute: Price per share: Financial shares Preț per acțiune: Description: Transaction description property (transaction title/generic article name) Descriere: Transaction title/generic article name Number of items included in the transaction. Entered cost is total cost for all items. Error No suitable account available. Nici un cont potrivit nu este disponibil. No income category available. Nu este definită nici o categorie de venit. No suitable account or income category available. Nu există nici un cont sau tip de venit potrivit. No expense category available. Nu este definită nici o categorie de cheltuieli. No security available. Nu este disponibil nici un titlu de valoare. Invalid date. Dată nevalidă. Cannot transfer money to and from the same account. Nu se pot transfera bani din și către același cont. Downpayment must be less than total cost. Cannot create a regular transfer to/from a securities account. Nu se poate crea un transfer obișnuit din/de la un cont de titluri de valoare. Cannot create a regular income to a securities account. Nu se poate crea un venit obișnuit întrun cont de titluri de valoare. Zero shares not allowed. Acțiuni zero nu este permis. Zero value not allowed. Valoarea zero nu este permisă. Zero price per share not allowed. Preț zero pe acțiune nu este permis. Cannot create a regular expense from a securities account. Nu se pot crea cheltuieli obișnuite întrun cont de titluri de valoare. Loan for %1 TransactionFilterWidget From: Din: To: Către: Min amount: Cantitate minimă: Max amount: Cantitate maximă: Category: Categorie: To account: Către contul: Min income: Venit minim: Max income: Venit maxim: From account: De la contul: Min cost: Cost minim: Max cost: Cost maxim: Tag: Description: Descriere: Description: Transaction description property (transaction title/generic article name) Descriere: Payer: Plătitor: Payee: Beneficiar: Include Include Exclude Exclude Exact match Exclude subcategories Clear Şterge All Tot Error Invalid date. Dată nevalidă. To date is before from date. Data „la” este înaintea datei „de la”. From date is after to date. Data „de la” este după data „la”. TransactionListWidget Date Dată Description Descriere Cost Cost Category Categorie From Account Din contul Payee Beneficiar Tags Income Venit To Account Către contul Payer Plătitor Amount Cantitate From De la To La Comments Comentarii Add Adaugă Apply Aplică Delete Șterge * Part of <a href="%1">split transaction</a> * Parte <a href="%1">tranzacție împărțită</a> Expense Cheltuială Transfer Transfer Name Nume Description Generic Description Descriere Description Transaction description property (transaction title/generic article name) Descriere New/Edit Expense Cheltuială nouă/modificare New/Edit Income Venit nouă/modificare New/Edit Transfer Transfer nouă/modificare Filter Filtru Quantity: Cantitate: Total: Total: Average: Mediu: Clear Şterge Cost: Cost: Monthly: Lunar: Sort by creation time Expenses Cheltuieli Incomes Venituri Transfers Transferuri Quantity Cantitate Right align Aliniați la dreapta Total cost: Cost total: Total income: Venit total: Total amount: Sumă totală: Monthly average: Medie lunară: Error Cannot set the value of security transactions using the dialog for modifying multiple transactions. Financial security (e.g. stock, mutual fund) Nu se poate modifica valoarea tranzacțiilor cu titluri de valoare prin fereastra de modificare tranzacții multiple. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name); Financial security (e.g. stock, mutual fund) Nu se poate schimba descrierea dividendelor și tranzacțiilor cu titluri de valoare. Cannot change payer of dividends and security transactions. Financial security (e.g. stock, mutual fund) Nu se poate schimba plătitorul dividendelor și tranzacțiilor cu titluri de valoare. Cannot change date of transactions that are part of a split transaction, unless all individual transactions are selected. Cannot set the value of security transactions using the dialog for modifying multiple transactions. Nu se poate modifica valoarea tranzacțiilor cu titluri de valoare prin fereastra de modificare tranzacții multiple. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name) Nu se poate schimba descrierea dividendelor și tranzacțiilor cu titluri de valoare. Cannot change date, description, expense category or payee of transactions that are part of a debt payment using the dialog for modifying multiple transactions. Referring to the transaction description property (transaction title/generic article name) Cannot change description of dividends and security transactions. Referring to the Transaction description property (transaction title/generic article name) Nu se poate schimba descrierea dividendelor și tranzacțiilor cu titluri de valoare. Cannot change description of dividends and security transactions. Referring to the generic description property Nu se poate schimba descrierea dividendelor și tranzacțiilor cu titluri de valoare. Cannot change description of dividends and security transactions. Nu se poate schimba descrierea dividendelor și tranzacțiilor cu titluri de valoare. Cannot change payer of dividends and security transactions. Nu se poate schimba plătitorul dividendelor și tranzacțiilor cu titluri de valoare. Cannot change date of transactions that are part of a split transaction. Nu se poate schimba data tranzacțiilor care sunt parte a unei tranzacții împărțite. Delete transactions? Are you sure you want to delete all (%1) transactions in the selected split transaction? Sigur doriți ștergerea tuturor (%1) tranzacții din tranzacția împărțită selectată? Join as multiple accounts/payments? Do you wish join the selected expenses as an expense with multiple accounts/payments? Do you wish join the selected incomes as an income with multiple accounts/payments? Are you sure you want to delete all (%1) selected transactions? Sigur doriți ștergerea tuturor (%1) tranzacții selectate? * Part of split transaction * Parte tranzacție împărțită * Part of split (%1) * Parte din împărțire (%1) ** Recurring (editing occurrence) ** Recurentă (editare frecvență) Modify… Modificare… Edit… Editează… Eqonomize-1.5.3/translations/eqonomize_ru.ts000066400000000000000000020756361416454732000213240ustar00rootroot00000000000000 Balancing Баланс kde-format Couldn't open %1 for reading Не могу открыть %1 для чтения kde-format Not a valid Eqonomize! file (XML parse error: "%2" at line %3, col %4) Не правильный Eqonomize! файл (Ошибка разбора XML: "%2" в линии %3, позиции %4) kde-format Invalid root element %1 in XML document Неверный корневой элемент %1 в XML документе kde-format Unable to load 1 account. _n: Невозможно загрузить 1 счет. Невозможно загрузить %n счета. kde-format Unable to load %n accounts. Unable to load 1 category. _n: Невозможно загрузить 1 категорию. Невозможно загрузить %n категорий. kde-format Unable to load %n categories. Unable to load 1 security. _n: Невозможно загрузить 1 ценную бумагу Невозможно загрузить %n ценных бумаг. kde-format Unable to load %n securities. Unable to load 1 transaction. _n: Невозможно загрузить 1 транзакцию. Невозможно загрузить %n транзакций. kde-format Unable to load %n transactions. File is a directory Файл является каталогом kde-format Couldn't open file for writing Невозможно открыть файл для записи kde-format Error while writing file; file was not saved Ошибка записи в файл. Файл не сохранен. kde-format From Из kde-format To К kde-format Source: Источник: kde-format All Expenses Все расходы kde-format All Incomes Все доходы kde-format All Accounts Все счета kde-format Expenses: %1 Расходы: %1 kde-format Incomes: %1 Доходы: %1 kde-format Invalid date. Неверные данные. kde-format The selected file already exists. Would you like to overwrite the old copy? Выбранный файл уже открыт. Хотите перезаписать старую копию? kde-format You selected a directory! Вы выбрали директорию! kde-format Couldn't open file for writing. Не могу открыть файл для записи. kde-format Error while writing file; file was not saved. Ошибка чтения файла; Файл не сохранен kde-format No description Без описания kde-format All Categories Все категории kde-format Descriptions for Описание для kde-format Payees/payers for Получатель/платильщик для kde-format Period: Период: kde-format Columns: Колонки: kde-format Value Значение kde-format Daily Ежедневно kde-format Monthly Ежемесячно kde-format Yearly Ежегодно kde-format Quantity Количество kde-format Average value Среднее значение kde-format All descriptions Все описания kde-format All payees Все получатели kde-format All payers Все платильщики kde-format No payee Без получателя kde-format No payer Без платильщика kde-format Expenses: %2, %1 Расход: %2, %1 kde-format Incomes: %2, %1 Доход: %2, %1 kde-format Incomes & Expenses Расход и Доход kde-format %1 (%2&ndash;%3) html format; %1: title; %2: from date; %3: to date %1 с %2 по %3 kde-format %1 (to %2) html format; %1: title; %2: to date _: html формат; %1: заголовок; %2: дата %1 (to %2) kde-format Category Категория kde-format Cost Цена kde-format Income Доход kde-format Daily Average Средний ежедневный kde-format Monthly Average Средний ежемесячный kde-format Yearly Average Средний ежегодный kde-format Average Cost Средняя цена kde-format Average Income Средний доход kde-format Average Value Среднее значение kde-format Total Итог kde-format Total incomes Итого доходов kde-format Total expenses Итого расходов kde-format Total (Profits) Итог (Прибыль) kde-format Expense Расход kde-format Transfer Перевод kde-format Security Buy Покупки ценных бумаг kde-format Security Sell Продажи ценных бумаг kde-format Recurrence Повторение kde-format New Expense Новый расход kde-format New Dividend Новые дивиденты kde-format New Income Новый доход kde-format New Transfer Новый перевод kde-format New Security Buy Новые покупки ценных бумаг kde-format New Security Sell Новые продажи ценных бумаг kde-format Edit Expense Править расход kde-format Edit Dividend Править дивиденты kde-format Edit Income Править доход kde-format Edit Transfer Править перевод kde-format Edit Securities Bought Править ценные покупки kde-format Edit Securities Sold Править ценные продажи kde-format Dividend Дивидент kde-format Repayment Оплата kde-format Refund Получение оплаты kde-format Split Transaction Разбить транзацию kde-format Description: Описание: kde-format Date: Дата: kde-format Account: Счет: kde-format Transactions: Транзакция: kde-format Type Тип kde-format Description Описание kde-format Account/Category Счет/Категория kde-format Payment Платеж kde-format Deposit Депозит kde-format New Новый kde-format New Expense… Новый расход… kde-format New Income… Новый доход… kde-format New Deposit… Новый депозит… kde-format New Withdrawal… Новое изъятие… kde-format Security Shares Sold… Продажи ценных акций… kde-format New Dividend… Новые дивиденты… kde-format Edit… Правка… kde-format Total value: Итог: kde-format No suitable account available. Имеющийся счет не пригоден kde-format Future dates is not allowed. Будущие даты не разрешены. kde-format A split must contain at least two transactions. Разделение должно быть ограниченно минимум двумя транзакциями. kde-format Cannot transfer money to and from the same account. Невозможно перевести деньги на тот же самый счет. kde-format Cost: Цена: kde-format Income: Доход: kde-format Quantity: Количество: kde-format Comments: Коментарии: kde-format Reinvested Dividend Вкладываемые дивиденты kde-format Security: Ценные бумаги: kde-format Shares added: Добавить акции: kde-format Security Trade Торговля ценными бумагами kde-format From security: К ценным бумагам: kde-format Shares moved: Переместить акции: kde-format All Все kde-format To security: К ценным бумагам. kde-format Shares received: Полученные акции: kde-format Value: Стоимость: kde-format No other security available for trade in the account. Нет других ценных бумаг для торговли в счете. kde-format Selected to and from securities are the same. Выбранные источник и назначение для ценных бумаг один и тот же. kde-format Zero shares not allowed. Акции с нулевой стоимостью не разрешены. kde-format Zero value not allowed. Нулевая стоимость не разрешена. kde-format Quotations Котировка kde-format Date Дата kde-format Price per Share Fuzzy entfernt: Wertpapiere müssen nicht Aktien sein - es gibt Staatsanleihen, Optionen, Genossenschaftsanteile … Anteile ist da umfassender als das wohl Favorisierte "Aktien" Цена через акции kde-format Quotations for %1 Курс для %1 kde-format The following transactions was scheduled to occur today or before today. Confirm that they have indeed occurred (or will occur today). Следующие транзакции по графику были сегодня или в прошлом. Подтвердите это случилось (или случится сегодня) kde-format Amount Количество kde-format Postpone… Отложить… kde-format Can only postpone to future dates. Могу только отложить до будущего. kde-format Transactions for %1 Транзакции для %1 kde-format Shares Акции kde-format Shares Bought Купленные акции kde-format Shares Sold Проданные акции kde-format Shares Sold (Traded) Проданные акции (торгуемые) kde-format Shares Bought (Traded) Купленные акции (торгуемые) kde-format Shares Bought (Recurring) Купленные акции(повторно) kde-format Shares Sold (Recurring) Проданные акции (повторно) kde-format Shares Bought (Scheduled) Купленные акции (по плану) kde-format Shares Sold (Scheduled) Проданные акции (по плану) kde-format Recurring Dividend Повторный дивидент kde-format Scheduled Dividend Планируемый дивидент kde-format Type: Тип: kde-format Mutual Fund Взаимный капитал kde-format Bond Связь kde-format Stock Начало kde-format Other Другое kde-format Name: Имя: kde-format Decimals in Shares: Десятичные в акциях: kde-format Initial Shares: Начальные акции: kde-format Initial quotation: Начальная котировка: kde-format No suitable account or income category available. Не годный счет или категория доходов. kde-format Cash Наличные kde-format Current Account Текущий счет kde-format Savings Account Сбережения kde-format Credit Card Кредитная карта kde-format Liabilities Задолженность kde-format Securities Ценные бумаги kde-format Initial balance: Начальный баланс: kde-format Default account for budgeted transactions Счет по умолчанию для бюджетных транзакций kde-format Empty name. Пустое имя. kde-format The entered name is used by another account. Введенное имя уже используется в другом бюджете kde-format Monthly budget: Месячный бюджет kde-format The entered name is used by another income category. Введенное имя уже используется в другой категории доходов. kde-format The entered name is used by another expense category. Введенное имя уже используется в другой категории расходов. kde-format Accounts Счета kde-format Accounts & Categories Счета и категории kde-format Expenses Расходы kde-format Incomes Доходы kde-format Transfers Трансферы kde-format Schedule Планировщик kde-format Scheduled Transactions Запланированные переводы kde-format Account / Category Счет / Категория kde-format Remaining Budget (%1) Оставшийся бюджет(%1) kde-format Change (%1) Изменение (%1) kde-format Total (%1) Итог (%1) kde-format %2 of %1 %2 remains of %1 budget %2 из %1 kde-format Includes budgeted transactions Включая бюджетные транзакции kde-format Period Период kde-format Select Period Выберите период kde-format Current Month Текущий месяц kde-format Current Year Текущий год kde-format Current Whole Month Текущий итог месяца kde-format Current Whole Year Текущий итого года kde-format Whole Past Month Итог прошлого месяца kde-format Whole Past Year Итог прошлого года kde-format Previous Month Предыдущий месяц kde-format Previous Year Предыдущий год kde-format Show partial budget Показать неполный бюджет kde-format Edit Budget Править бюджет kde-format Budget: Бюджет: kde-format Month: Месяц: kde-format Result previous month: Результат прошлого месяца kde-format New Security… Новые ценные бумаги… kde-format New Transaction Новая транзакция kde-format Set Quotation… Набор котировок… kde-format Name Имя kde-format Quotation Котировка kde-format Profit Прибыль kde-format Yearly Rate Ежегодная плата kde-format Account Счет kde-format Statistics Period Статистика периода kde-format New Schedule Новый план kde-format Edit Правка kde-format Next Occurrence Следующее событие kde-format Comments Комментарии kde-format New Security Новая ценная бумага kde-format Edit Security Редактировать ценную бумагу kde-format Profit: Прибыль: kde-format Rate: Ставка: kde-format Are you sure you want to delete the security "%1" and all associated transactions? Вы уверены что хотите удалить ценную бумагу "%1" и все связанные с ней транзакции? kde-format No security available. Нет имеющихся ценных бумаг. kde-format Set Quotation (%1) Набор котировок (%1) kde-format Price per share: Стоимость через акции: kde-format Future dates are not allowed. Будущие даты не разрешены. kde-format Security Transactions Транзакции ценных бумаг kde-format Ledger Главная книга kde-format Untitled Безымянный kde-format Check Account Контроль счета kde-format Salary Жалование kde-format Bills Счета kde-format Clothing Одежда kde-format Groceries Бакалея kde-format Leisure Досуг kde-format Couldn't fetch %1. Не выбран %1 . kde-format Error loading %1: %2. Ошибка загруки %1: %2 kde-format Couldn't open file Невозможно открыть файл kde-format Error saving %1: %2. Ошибка сохранения %1: %2 kde-format Couldn't save file Не сохранен файл kde-format Failed to upload file to %1. Неудачно загружен файл %1 kde-format Report Отчет kde-format Chart Диаграмма kde-format Transaction Schedule Расписание транзакций kde-format Accounts &amp; Categories html format Бюджет и категории kde-format Accounts &amp; Categories (%1&ndash;%2) html format Бюджет и категории (%1&ndash;%2) kde-format Accounts &amp; Categories (to %1) html format Бюджет и категории (к %1) kde-format Change Изменение kde-format Balance Баланс kde-format Budget Бюджет kde-format Remaining Budget Оставшийся бюджет kde-format Total Incomes Итого доходов kde-format Costs Затраты kde-format Total Expenses Итого Расходов kde-format Empty expenses list. Пустой список расходов. kde-format Empty incomes list. Пустой список доходов. kde-format Empty transfers list. Пустой список транзакций. kde-format Empty securities list. Пустой список ценных бумаг. kde-format Empty schedule list. Пустое расписание. kde-format Export View… Просмотр экспорта… kde-format Print View… Просмотр печати… kde-format Initial Period Начальный период kde-format Remember Last Dates Запомнить последнюю дату kde-format Import CSV File… Импорт CSV-файла… kde-format Import QIF File… Импорт QIF-файла… kde-format Export As QIF File… Экспортировать как QIF-файл… kde-format Add Account… Добавить счет… kde-format New Account… Новый счет… kde-format New Income Category… Новая категория доходов kde-format New Expense Category… Новая категория расходов kde-format Balance… Баланс… kde-format Show Transactions Показать транзакция kde-format New Transfer… Новый трансфер… kde-format New Split Transaction… Новое разделение транзакции.. kde-format Edit Occurrence… Править событие… kde-format Edit Schedule… Редактировать расписание… kde-format Remove Occurrence Удалить событие kde-format Delete Schedule Удалить план kde-format Edit Split Transaction… Редактировать разделенные транзакции. kde-format Remove Split Transaction Удалить разделенные транзакции kde-format Join Transactions… Соединить транзакции kde-format Refund… Платеж… kde-format Repayment… Оплата… kde-format New Refund/Repayment… Новый платеж/оплата… kde-format Edit Security… Редактировать ценную бумагу… kde-format Remove Security Удалить ценную бумагу kde-format Shares Sold… Общие продажи… kde-format Shares Bought… Общие покупки… kde-format Dividend… Дивиденды… kde-format Reinvested Dividend… Снова инвестированные дивиденды… kde-format Shares Moved… Общие перемещения… kde-format Edit Quotations… Редактировать котировки… kde-format Transactions… Транзакции… kde-format Development Over Time Report… Отчет по датам. kde-format Categories Comparison Report… Отчет по категориям kde-format Categories Comparison Chart… Диаграмма сравнения категорий kde-format Development Over Time Chart… Временная диаграмма kde-format Use Additional Transaction Properties Использовать свойства добавленной транзакции kde-format Eqonomize! exited unexpectedly before the file was saved and data was lost. Do you want to load the last auto-saved version of the file? Eqonomize! неожиданно завершилась перед сохранением файла и данные потеряны. Хотите загрузить последние авто-сохраненную версию файла? kde-format Crash Recovery Der Begriff ist Müll … Крах восстановления kde-format The current file has been modified. Do you want to save it? Текущий файл модифицирован. Желаете сохранить? kde-format Confirm Schedule Подтвердить расписание kde-format New Account Новый счет kde-format New Income Category Новая категория доходов kde-format New Expense Category Новая категория расходов kde-format Balance Account Баланс счета kde-format Book value: Книга ценности: kde-format Real value: Реальная ценность: kde-format Edit Account Редактировать счет kde-format Edit Income Category Редактировать категорию доходов kde-format Edit Expense Category Редактировать категорию расходов kde-format Move transactions? Переместить транзакцию? kde-format Move to: Переместить в: kde-format The category contains some expenses. What do you want to do with them? Категория содержит некоторые расходы. Что вы хотите с ними сделать? kde-format Remove Category? Удалить категорию? kde-format The category contains some incomes that will be removed. Do you still want to remove the category? Категория содержит некоторые доходы, вы ее хотите удалить? kde-format The account contains some transactions that will be removed. Do you still want to remove the account? Счет содержит некоторые транзакции, вы его хотите удалить? kde-format Remove Account? Удалить счет? kde-format %2 of %1 %1: budget; %2: remaining budget %2 из %1 kde-format %1 (with budget %2) %1 ( с бюджета %2) kde-format Import CSV file Импорт CSV файла kde-format Transaction Type Selection Выбор типа транзакции kde-format Expenses and incomes (negative cost) Расходы и доходы (отрицательная величина) kde-format Expenses and incomes (separate columns) Расходы и доходы (разделенные колонки) kde-format All types Все типы kde-format File Selection Выбор файла kde-format File: Файл: kde-format First data row: Первая строка данных: kde-format Auto Авто kde-format Column delimiter: Разделитель колонок: kde-format Comma Запятая kde-format Tabulator Табулятор kde-format Semicolon Точка с запятой kde-format Space Пробел kde-format Columns Specification Спецификация колонки kde-format Column Колонка kde-format Category: Категория: kde-format From account: Со счета: kde-format Create missing categories and accounts Создать найденные категории и счета kde-format Imports data as incomes. Value is the only required column. Импортировать данные как доходы. kde-format To account: К счету: kde-format Imports data as transfers. Value is the only required column. Импорт данных как трансферы. kde-format Amount: Количество: kde-format From: Из: kde-format To: К: kde-format A file must be selected. Файл должен быть выбран kde-format Selected file is a directory. Выберите файл или директорию. kde-format Selected file does not exist. Выбранный файл не существует. kde-format Empty delimiter. Пустой разделитель. kde-format Selected from account is the same as the to account. Выбранный счет тот же самый. kde-format Couldn't open %1 for reading. Не могу открыть %1 для чтения. kde-format Error reading %1. Ошибка чтения %1. kde-format Successfully imported 1 transaction. _n: Успешный импорт 1 транзакции. Успешный импорт %n транзакций. kde-format Successfully imported %n transactions. Unable to import any transactions imported. Невозможно импортировать любые транзакции. kde-format Failed to import 1 data row. _n: Ошибка импорта данных из 1 строчки. Ошибка импорта данных из %n строчек. kde-format Failed to import %n data rows. Required columns missing. Недостает необходимых колонок. kde-format Invalid value. Неверное значение. kde-format Empty category name. Пустое имя категории. kde-format Empty account name. Пустое имя счета. kde-format Unknown category found. Найдена неизвестная категория. kde-format Unknown account found. Найден неизвестный счет. kde-format Cannot import security transactions (to/from security accounts). Невозможно импортировать транзакции с ценными бумагами (к/из счета ценных бумаг) kde-format Balancing account wrongly used. Счет баланса неверно используется. kde-format Same to and from account/category. Категория и счет одинаковы. kde-format No data found. Данные не найдены. kde-format Unrecognized date format. Не распознаваемый формат даты kde-format Specify Format Специфический формат kde-format The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. Формат дат и/или номеров в CVS файле двусмыслен.Пожалуйста выберите корректный формат. kde-format Date format: формат даты: kde-format Value format: формат валюты: kde-format tomorrow the day after today завтра kde-format today this day сегодня kde-format yesterday the day before today Вчера kde-format &Today @option today &Сегодня kde-format To&morrow @option tomorrow &Завтра kde-format Next &Week @option next week Следующая &неделя kde-format Next M&onth @option next month Следующий &месяц kde-format No Date @option do not specify a date Без даты kde-format Export… Экспорт… kde-format Print… Печать… kde-format Withdrawal Отзыв kde-format Join… соеденить.. kde-format Split Up Разделить вдоль kde-format Empty transaction list. Пустой список транзакций. kde-format Are you sure you want to delete all (%1) selected transactions? Вы уверены что хотите удалить все (%1) выбранные транзакции? kde-format Eqonomize! Eqonomize! Start with expenses list displayed Старт со списка расходов Start with incomes list displayed Старт со списка доходов Start with transfers list displayed Старт со списка переводов Document to open Документ открыт Incomes and Expenses Доходы и Расходы kde-format Profits Прибыль kde-format All Categories Combined Объединить все категории kde-format All Descriptions Combined Объединить все описания kde-format All Payees/Payers Combined Объединить всех получателей/плательщиков. kde-format Start date: Дата начала: kde-format End date: Дата конца: kde-format Monthly total Итог месяца kde-format Daily average Среднее еженедельно kde-format All Payers Combined Объединить всех плательщиков kde-format All Payees Combined Объединить всех получателей. kde-format All Descriptions Split Все описания разбить kde-format All Payers Split Всех плательщиков разделить kde-format All Payees Split Всех получателей разделить kde-format All Categories Split Все категории разделить kde-format Value (%1) Значение (%1) kde-format Profit (%1) Прибыль (%1) kde-format Income (%1) Доход (%1) kde-format Cost (%1) Цена (%1) kde-format Time Время kde-format no payer нет платильщика kde-format %1/%2 %1: Description; %2: Payer %1/%2 kde-format no payee нет получателя kde-format %1/%2 %1: Description; %2: Payee %1/%2 kde-format Error after saving file; data may not have been saved. Ошибка перед сохранением файла; данные могут быть не сохранены kde-format Average Profit Средняя выгода kde-format Year Год kde-format Month Месяц kde-format Includes scheduled transactions Включая запланированные транзакции kde-format Adjusted for the average month / year (%1 / %2 days) Установлено для среднего месяца / года (%1 / %2 дней) kde-format Subtotal Промежуточная сумма kde-format Unnamed Неназваный kde-format Uncategorized Без категории kde-format Import QIF file Импорт QIF файла kde-format Local Text Локальный текст kde-format Standard Text Стандартный текст kde-format Select standard text: Выбрать стандартный текст: kde-format Date Format Формат даты kde-format Default Account Счет по умолчанию kde-format Default account: Счет по умолчанию: kde-format Opening balance text: Открытый текст баланса: kde-format Descriptions Описания kde-format Subcategories as: Субкатегория как: kde-format Ignore Игнорировать kde-format Payee as: Получатель как: kde-format Payee Получатель kde-format Memo as: Запомнить как: kde-format Priority: Приоритет: kde-format Subcategory/Payee/Comments Субкатегория/Получатель/Комментарии kde-format Payee/Subcategory/Comments Получатель/Субкатегория/Комментарии kde-format Subcategory/Comments/Payee Субкатегория/Комментарии/Получатель kde-format Payee/Comments/Subcategory Получатель/Комментарии/Субкатегория kde-format Comments/Subcategory/Payee Комментарии/Субкатегория/Получатель kde-format Comments/Payee/Subcategory Комментарии/Получатель/Субкатегория kde-format Unknown Неизвестно kde-format Bank Банк kde-format Cat (Category) Кат. (Категория) kde-format CCard (Credit Card) Кредитная карта kde-format Invst (Investment) Инвест. (Инвестиции) kde-format Oth A (Other Assets) Другие активы kde-format Oth L (Other Liabilities) Существующие задолжности kde-format Security Ценные бумаги kde-format Successfully imported 1 account. _n: Успешно импортирован 1 счет. Успешно импортированы %n счета(ов). kde-format Successfully imported %n accounts. Successfully imported 1 category. _n: Успешный импорт 1 категории. Успешный импорт %n категорий. kde-format Successfully imported %n categories. 1 duplicate transaction was ignored. _n: 1 дубликат транзакции был игнорирован. %n дубликатов транзакций было игнорировано. kde-format %n duplicate transactions was ignored. Failed to import 1 transaction. _n: Ошибка импорта 1 транзакции. Ошибка импорта %n транзакций. kde-format Failed to import %n transactions. 1 security was not imported. _n: 1 ценная бумага не была импортирована. %n ценных бумаг не было импортировано. kde-format %n securities were not imported. 1 security transaction was not imported. _n: 1 транзакция с ценными бумагами не была импортирована. %n транзакций с ценными бумагами не было импортировано. kde-format %n security transactions were not imported. Export QIF File Экспорт в QIF файл kde-format All All accounts Все счета kde-format Memo Записка kde-format Subcategory Субкатегория kde-format &Import i18n: tag text i18n: file ./eqonomizeui.rc line 5 &Импорт kde-format &Accounts i18n: tag text i18n: file ./eqonomizeui.rc line 12 &Счет kde-format &Transactions i18n: tag text i18n: file ./eqonomizeui.rc line 24 &Транзакции kde-format &Securities i18n: tag text i18n: file ./eqonomizeui.rc line 41 &Ценные бумаги kde-format Stat&istics i18n: tag text i18n: file ./eqonomizeui.rc line 56 Стат&истика kde-format Your names NAME OF TRANSLATORS Rodion Samusik,,Launchpad Contributions:,Sergey Vostrikov,Vitaliy Berdinskikh,rodion, ,Launchpad Contributions:,Andrey Klimenko,Rodion,Sergey Vostrikov,Vitaliy Berdinskikh,Vladimir Maslennikov,rodion kde-format Your emails EMAIL OF TRANSLATORS rodion@sbchel.ru,,,s.vostrikov@gmail.com,skipper13@root.ua,rodion@sbchel.ru,,,,,s.vostrikov@gmail.com,skipper13@root.ua,zombo@mail.ru,rodion@sbchel.ru kde-format End after Закончить после kde-format occurrence(s) наличность kde-format End on Закончить на kde-format End date before start date. Дата конца перед датой начала. kde-format Enable recurrence Разрешить повторение kde-format Recurrence Rule Правила повторения kde-format Weekly Еженедельно kde-format Recur every Повторять каждый kde-format day(s) день(и) kde-format week(s) on: неделю(и): kde-format month(s), after the start month месяц(ы), после стартового месяца kde-format Recur on the Повторять на kde-format 1st 1. kde-format 2nd 2. kde-format 3rd 3. kde-format 4th 4. kde-format 5th 5. kde-format 6th 6. kde-format 7th 7. kde-format 8th 8. kde-format 9th 9. kde-format 10th 10. kde-format 11th 11. kde-format 12th 12. kde-format 13th 13. kde-format 14th 14. kde-format 15th 15. kde-format 16th 16. kde-format 17th 17. kde-format 18th 18. kde-format 19th 19. kde-format 20th 20. kde-format 21st 21. kde-format 22nd 22. kde-format 23rd 23. kde-format 24th 24. kde-format 25th 25. kde-format 26th 26. kde-format 27th 27. kde-format 28th 28. kde-format 29th 29. kde-format 30th 30. kde-format 31st 31. kde-format Last Последний kde-format 2nd Last Предпоследний kde-format 3rd Last 3-й с конца kde-format 4th Last 4-й с конца kde-format 5th Last 5-й с конца kde-format day День kde-format possibly on weekend возможно на выходные kde-format but before weekend но перед выходными kde-format but after weekend но после выходных kde-format year(s), after the start year год(ы), после стартового года. kde-format Range… Диапазон… kde-format Exceptions… Исключения… kde-format No day of week selected for weekly recurrence. Нет дня недели выбранного для недельной рекурсии. kde-format Selected day will never occur with selected frequency and start date. Выбранный день никогда не наступит, с выбранной частотой и стартовой датой kde-format Selected day does not exist in selected month. Выбранный день не существует в выбранном месяце. kde-format Dividend: %1 Дивиденты: %1 kde-format Account balancing Баланс счета kde-format Security: %1 (bought) Ценные бумаги: %1 (покупка) kde-format Security: %1 (sold) Ценные бумаги: %1 (продажа) kde-format Shares bought: Распределенные покупки: kde-format Shares sold: Распределенные продажи: kde-format Payer: Платильщик: kde-format Payee: Получатель: kde-format No income category available. Нет доступной категории доходов. kde-format No expense category available. Нет доступной категории расходов kde-format Cannot create a regular transfer to/from a securities account. Невозможно создать регулярный трансфер в/из счета ценным бумаг. kde-format Cannot create a regular income to a securities account. Невозможно создать регулярный доход в счете ценных бумаг. kde-format Cannot create a regular expense from a securities account. Невозможно создать регулярный расход с счета ценных бумаг. kde-format Modify Transactions Модифицировать транзакции kde-format Min amount: Минимальный объем: kde-format Max amount: Максимальный объем: kde-format Min income: Минимальный доход: kde-format Max income: Максимальный доход: kde-format Min cost: Минимальная цена: kde-format Max cost: Максимальная ценна: kde-format Include Включить kde-format Exclude Исключить kde-format From Account С счета kde-format To Account К счету kde-format Payer Платильщик kde-format New/Edit Expense Новый/Редактировать расход kde-format Filter Фильтр kde-format Total: Итог: kde-format Average: Среднее: kde-format Monthly: Ежемесячно: kde-format Total cost: Итого цена: kde-format Total income: Итого доходов: kde-format Total amount: Итого объем: kde-format Monthly average: Среднее в месяц: kde-format Are you sure you want to delete all (%1) transactions in the selected split transaction? Вы уверены, что хотите удалить все (%1) транзакции в выбранном разбиение тразакции? kde-format * Part of split transaction * Часть разбитой транзакции kde-format * Part of split (%1) * Часть разбивки (%1) kde-format ** Recurring (editing occurrence) ** Периодически (редактирование) kde-format Modify… Модифицировано… kde-format AccountComboBox New account… Новый счет… Multiple accounts/payments… New income category… Новая категория доходов… New expense category… Новая категория расходов… Paid with loan… New Account Новый счет New Income Category Новая категория доходов New Expense Category Новая категория расходов AccountsMenu All Accounts Все счета All Categories Combined Объединить все категории %n accounts %n categories Balancing Account balancing Баланс счета Account balancing Balancing of an account Баланс счета Account Balance Adjustment Budget Balancing Баланс Balancing Name of account for transactions that adjust account balances Баланс Couldn't open %1 for reading Не могу открыть %1 для чтения Not a valid Eqonomize! file (XML parse error: "%1" at line %2, col %3) Не правильный Eqonomize! файл (Ошибка разбора XML: "%1" в линии %2, позиции %3) Invalid root element %1 in XML document Неверный корневой элемент %1 в XML документе Unknown XML element: "%1" at line %2, col %3 XML parse error: "%1" at line %2, col %3 European Euro Unable to load %n currency/currencies. No exchange rates found. USD currency missing. imported Unable to load %n account(s). Невозможно загрузить %n счет. Невозможно загрузить %n счета. Невозможно загрузить %n счета. Unable to load %n category/categories. Невозможно загрузить %n категорию. Невозможно загрузить %n категорий. Невозможно загрузить %n категорий. Unable to load %n security/securities. Financial security (e.g. stock, mutual fund) Невозможно загрузить %n ценную бумагу. Невозможно загрузить %n ценных бумаг. Невозможно загрузить %n ценных бумаг. Download command (%1) failed: %2. Failed to download file from %1: %2. Upload command (%1) failed: %2. yyyy-yy Financial year when first month is not January (e.g. 2018-19). Transaction Accounts Текущие счета Savings Accounts Сбережения Credit Cards Кредитные карты Debts Долги Securities Financial security (e.g. stock, mutual fund) Ценные бумаги Cash Наличные Transaction Account Текущий счет Savings Account Сбережения Credit Card Кредитная карта Debt Долг Other Другое Unable to load %n security/securities. Невозможно загрузить %n ценную бумагу. Невозможно загрузить %n ценных бумаг. Невозможно загрузить %n ценных бумаг. Unable to load %n transaction(s). Невозможно загрузить %n транзакцию. Невозможно загрузить %n транзакций. Невозможно загрузить %n транзакций. File is a directory Файл является каталогом Couldn't open file for writing Невозможно открыть файл для записи Error while writing file; file was not saved Ошибка записи в файл. Файл не сохранен Unnamed Неназваный Uncategorized Без категории CategoriesComparisonChart Save As… Сохранить как… Print… Печать… From Из To К Source: Источник: All Expenses Все расходы All Incomes Все доходы Theme: Chart type: Pie Chart Bar Chart Default All Expenses, without subcategories All Expenses, with subcategories All Incomes, without subcategories All Incomes, with subcategories All Accounts Все счета Expenses: %1 Расходы: %1 Incomes: %1 Доходы: %1 Error Invalid date. Неверные данные. Couldn't open file for writing. Не могу открыть файл для записи. Error while writing file; file was not saved. Ошибка чтения файла; Файл не сохранен. Expenses Расходы Expenses, %1 Расходы, %1 Incomes, %1 Доходы, %1 Incomes Доходы Accounts Счета Expenses, %2: %1 Расход, %2: %1 Incomes, %2: %1 Доход, %2: %1 Other descriptions Referring to the transaction description property (transaction title/generic article name) No description Referring to the transaction description property (transaction title/generic article name) Без описания Other accounts Other categories %1 Value: %2 No description Referring to the Transaction description property (transaction title/generic article name) Без описания No description Referring to the generic description property Без описания Value Значение Income Доход Cost Цена Value (%1) Значение (%1) Income (%1) Доход (%1) Cost (%1) Цена (%1) No description Без описания CategoriesComparisonChartDialog Chart Диаграмма CategoriesComparisonReport Save As… Сохранить как… Print… Печать… Source: Источник: All Categories, excluding subcategories All Categories, including subcategories All Payees/Payers Все получатели/платильщики Subcategories Descriptions for Referring to the Transaction description property (transaction title/generic article name) Описание для All descriptions Referring to the Transaction description property (transaction title/generic article name) Все описания No description Referring to the Transaction description property (transaction title/generic article name) Без описания All Categories Все категории Expenses: %1 Расходы: %1 Incomes: %1 Доходы: %1 Descriptions for Описание для Payees/payers for Получатель/платильщик для Descriptions Referring to the Transaction description property (transaction title/generic article name) Описания Period: Период: From Из To К Columns: Колонки: Value Значение Daily Ежедневно Monthly Ежемесячно Yearly Ежегодно Quantity Количество Average value Среднее значение All descriptions Все описания All payees Все получатели All payers Все платильщики No description Без описания Descriptions for Referring to the generic description property Описание для Descriptions Referring to the generic description property Описания All descriptions Referring to the generic description property Все описания No description Referring to the generic description property Без описания All Payees and Payers Все получатели и платильщики Tag: %1 All Accounts Все счета Descriptions for Referring to the transaction description property (transaction title/generic article name) Описание для Descriptions Referring to the transaction description property (transaction title/generic article name) Описания Months Месяцы Years Года Tags Total: Итог: All descriptions Referring to the transaction description property (transaction title/generic article name) Все описания All payees/payers Все получатели/платильщики No description Referring to the transaction description property (transaction title/generic article name) Без описания No payee Без получателя No payer Без платильщика Error Invalid date. Неверные данные. Couldn't open file for writing. Не могу открыть файл для записи. Error while writing file; file was not saved. Ошибка чтения файла; Файл не сохранен. Expenses, %2: %1 Расход, %2: %1 Expenses, %3: %2, %1 Расход, %3: %2, %1 Incomes, %2: %1 Доход, %2: %1 Incomes, %3: %2, %1 Доход, %3: %2, %1 %3: %2, %1 %2: %1 Tags, %1 Incomes & Expenses, %1 Расход и Доход, %1 Expenses: %2, %1 Расход: %2, %1 Incomes: %2, %1 Доход: %2, %1 %2, %1 %1 %1 Incomes & Expenses Расход и Доход %1 (%2&ndash;%3) html format; %1: title; %2: from date; %3: to date %1 с %2 по %3 %1 (to %2) html format; %1: title; %2: to date %1 (to %2) Category Категория Payee Получатель Description Referring to the transaction description property (transaction title/generic article name) Описание Cost Цена Payer Платильщик Income Доход Payee/Payer Получатель/платильщик Tag Daily Average Средний ежедневный Monthly Average Средний ежемесячный Yearly Average Средний ежегодный Average Cost Средняя цена Average Income Средний доход Average Value Среднее значение No payee/payer Без получателя/платильщика Total Итог All Tags Total incomes Итого доходов Total expenses Итого расходов Total (Profits) Итог (Прибыль) CategoriesComparisonReportDialog Report Отчет ConfirmScheduleDialog The following transactions was scheduled to occur today or before today. Confirm that they have indeed occurred (or will occur today). Следующие транзакции по графику были сегодня или в прошлом. Подтвердите это случилось (или случится сегодня). Date Дата Type Тип Name Имя Description Описание Description Generic Description Описание Description Transaction description property (transaction title/generic article name) Описание Amount Количество Edit… Правка… Postpone… Отложить… Delete Удалить Error Can only postpone to future dates. Могу только отложить до будущего. ConfirmScheduleListViewItem Transfer Перевод Dividend Дивидент Income Доход Expense Расход Securities Purchase Financial security (e.g. stock, mutual fund) Покупки ценных бумаг Securities Sale Financial security (e.g. stock, mutual fund) Продажи ценных бумаг Security Buy Покупки ценных бумаг Security Sell Продажи ценных бумаг Debt Payment CurrencyConversionDialog Currency Converter DebtFee Debt payment: %1 (fee) DebtInterest Debt payment: %1 (interest) DebtPayment Debt payment: %1 DebtReduction Debt payment: %1 (reduction) DescriptionsMenu All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Объединить все описания All Tags Combined All Payees Combined All Payers Combined Объединить всех плательщиков All Payees/Payers Combined No description Referring to the transaction description property (transaction title/generic article name) Без описания No payee Без получателя No payer Без платильщика No payee/payer Без получателя/платильщика %n descriptions Referring to the transaction description property (transaction title/generic article name) %n tags %n payees %n payers %n payees/payers EditAssetsAccountDialog Type: Тип: Cash Наличные Current Account Текущий счет Savings Account Сбережения Credit Card Кредитная карта Liabilities Задолженность Transactional Account Чековый счет Debt Долг Securities Ценные бумаги Other Другое Currency: Edit Правка Name: Имя: Bank: Банк: Initial balance: Начальный баланс: Debt: Initial balance Начальный баланс Group: no group Transferred to: Date: Дата: Lender: Default account for budgeted transactions Счет по умолчанию для бюджетных транзакций Description: Описание: Account is closed Warning Type cannot be changed to securities for accounts with transactions. Issuer: Zero value not allowed. Нулевая стоимость не разрешена. Error Transaction Account Текущий счет Opening balance: Account balance Сальдо начальное: Opening balance Account balance Сальдо начальное New currency… If you change the currency of an account, the currency of all associated transactions will also change, without any conversion. Do do wish to continue anyway? Empty name. Пустое имя. The entered name is used by another account. Введенное имя уже используется в другом бюджете. EditCurrencyDialog Edit Currency New Currency Code: Symbol: Prefix Suffix Default Name: Имя: Decimals: Date: Дата: Main currency Error Error saving currencies: %1. Empty code. Code already exists. EditDebtPaymentDialog Debt Payment EditDebtPaymentWidget Debt: Date: Дата: Debt reduction: Reduction payment: Interest: Paid Added to debt Fee: Account: Счет: Expense category: Associated file: Select a file Open the file Comments: Коментарии: Related to: Label for linked transactions Ссылки: Total value: Итог: Error No suitable account available. Имеющийся счет не пригоден. Invalid date. Неверные данные. Interest must not be zero. At least one value must non-zero. EditExceptionsDialog Edit Exceptions Occurrences: Наличность: Add Exception Remove Exception Exceptions: Исключения: Only the first fifty occurrences are shown. Invalid date. Неверные данные. EditExpensesAccountDialog Name: Имя: Parent category: None Monthly budget: Месячный бюджет: Description: Описание: Error Empty name. Пустое имя. The entered name is used by another expense category. Введенное имя уже используется в другой категории расходов. EditIncomesAccountDialog Name: Имя: Parent category: None Monthly budget: Месячный бюджет: Description: Описание: Error Empty name. Пустое имя. The entered name is used by another income category. Введенное имя уже используется в другой категории доходов. EditLoanTransactionWidget Date: Дата: Account: Счет: Comments: Коментарии: Total value: Итог: No suitable account available. Имеющийся счет не пригоден Invalid date. Неверные данные. EditMultiAccountDialog Expense with Multiple Payments Income with Multiple Payments EditMultiAccountWidget Description: Описание: Description: Generic Description Описание: Description: Transaction description property (transaction title/generic article name) Описание: Quantity: Количество: Category: Категория: Tags: Associated file: Select a file Open the file Comments: Коментарии: Related to: Label for linked transactions Ссылки: Transactions: Транзакция: Date Дата Account Счет Payee Получатель Payer Платильщик Cost Цена Income Доход Total cost: Итого цена: Value Значение New Новый Edit… Правка… Delete Удалить Total value: Итог: Error No suitable expense categories available. A split must contain at least two transactions. Разделение должно быть ограниченно минимум двумя транзакциями. EditMultiItemDialog Split Transaction Разбить транзацию EditMultiItemWidget Description: Описание: Description: Generic Description Описание: Date: Дата: Account: Счет: Payee/Payer: Получатель/Платильщик: Transactions: Транзакция: Type Тип Description Generic Description Описание Description: Transaction description property (transaction title/generic article name) Описание: Tags: Associated file: Select a file Open the file Comments: Коментарии: Related to: Label for linked transactions Ссылки: Description Transaction description property (transaction title/generic article name) Описание Payment Платеж Deposit Депозит New Новый New Expense… Новый расход… New Income… Новый доход… New Deposit… Новый депозит… New Withdrawal… Новое изъятие… New Securities Purchase… Financial security (e.g. stock, mutual fund) Новые покупки ценных бумаг… New Securities Sale… Financial security (e.g. stock, mutual fund) Новые продажи ценных бумаг… Shares Bought… Общие покупки… Shares Sold… Общие продажи… Account/Category Счет/Категория Value Значение Income Доход Expense Расход New Dividend… Новые дивиденты… Edit… Правка… Delete Удалить Total value: Итог: Error No suitable account available. Имеющийся счет не пригоден. Invalid date. Неверные данные. A split must contain at least two transactions. Разделение должно быть ограниченно минимум двумя транзакциями. Cannot transfer money to and from the same account. Невозможно перевести деньги на тот же самый счет. EditQuotationsDialog Quotations Котировка Date Дата Price per Share Цена через акции Quotations Financial quotation Котировка Quotes Financial quote Котировка Price per Share Financial Shares Цена через акции Add Добавить Modify Модифицировано Delete Удалить Import… Импорт… Export… Экспорт… Quotes for %1 Financial quote Курс для %1 Quotations for %1 Financial quotation Курс для %1 Quotations for %1 Курс для %1 Error Couldn't open %1 for reading. Не могу открыть %1 для чтения. Error reading %1. Ошибка чтения %1. Successfully imported %n quote(s). Unable to import any quotes. Failed to import %n data row(s). Ошибка импорта данных из %n строчки. Ошибка импорта данных из %n строчек. Ошибка импорта данных из %n строчек. Required columns missing. Недостает необходимых колонок. Invalid value. Неверное значение. Invalid date. Неверные данные. No data found. Данные не найдены. Information Unrecognized date format. Specify Format Специфический формат The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. Формат дат и/или номеров в CVS файле двусмыслен.Пожалуйста выберите корректный формат. Date format: формат даты: Value format: формат валюты: Couldn't open file for writing. Не могу открыть файл для записи. Quotes: %1 Котировка: %1 Error while writing file; file was not saved. EditRangeDialog Edit Recurrence Range Begins on: %1 No ending date End after Закончить после occurrence(s) наличность End on Закончить на Error Invalid date. Неверные данные. End date before start date. Дата конца перед датой начала. EditReinvestedDividendDialog Reinvested Dividend Вкладываемые дивиденты Security: Ценные бумаги: Shares added: Добавить акции: Security: Financial security (e.g. stock, mutual fund) Ценные бумаги: Shares added: Financial shares Добавить акции: Date: Дата: Invalid date. Неверные данные. EditScheduledDebtPaymentDialog Transaction Транзакция Recurrence Повторение Edit Debt Payment New Debt Payment EditScheduledLoanTransactionDialog Recurrence Повторение EditScheduledMultiAccountDialog Transactions Транзакции Recurrence Повторение New Expense with Multiple Payments New Income with Multiple Payments Edit Expense with Multiple Payments Edit Income with Multiple Payments EditScheduledMultiItemDialog Transactions Транзакции Recurrence Повторение New Split Transaction Новое разделение транзакции Edit Split Transaction Редактировать разделенные транзакции EditScheduledTransactionDialog Expense Расход Dividend Дивидент Income Доход Reinvested Dividend Вкладываемые дивиденты Transfer Перевод Security Buy Покупки ценных бумаг Security Sell Продажи ценных бумаг Securities Purchase Financial security (e.g. stock, mutual fund) Покупки ценных бумаг Securities Sale Financial security (e.g. stock, mutual fund) Продажи ценных бумаг Recurrence Повторение New Expense Новый расход New Expense Paid with Loan New Dividend Новые дивиденты New Income Новый доход New Transfer Новый перевод New Securities Purchase Financial security (e.g. stock, mutual fund) Новые покупки ценных бумаг New Reinvested Dividend New Securities Sale Financial security (e.g. stock, mutual fund) Новые продажи ценных бумаг Edit Reinvested Dividend Edit Securities Purchase Financial security (e.g. stock, mutual fund) Править ценные покупки Edit Securities Sale Financial security (e.g. stock, mutual fund) Править ценные продажи New Security Buy Новые покупки ценных бумаг New Security Sell Новые продажи ценных бумаг Edit Expense Править расход Edit Dividend Править дивиденты Edit Income Править доход Edit Transfer Править перевод Edit Securities Bought Править ценные покупки Edit Securities Sold Править ценные продажи EditSecurityDialog Type: Тип: Mutual Fund Взаимный капитал Bond Связь Stock Акция Stock Financial stock Акция Other Другое Name: Имя: Account: Счет: Decimals in shares: Financial shares Десятичные в акциях: Initial shares: Financial shares Начальные акции: Decimals in quotes: Financial quote Initial quote: Financial quote Начальная котировка: Empty name. Пустое имя. No suitable account available. Имеющийся счет не пригоден. Initial quotation: Financial quotation Начальная котировка: Decimals in Shares: Десятичные в акциях: Initial Shares: Начальные акции: Initial quotation: Начальная котировка: Date: Дата: Description: Описание: Error No suitable account or income category available. Не годный счет или категория доходов. EditSecurityTradeDialog Security Trade Торговля ценными бумагами From security: К ценным бумагам: Shares moved: Переместить акции: All Все To security: К ценным бумагам. Shares received: Полученные акции: Securities Exchange Shares of one security directly exchanged for shares of another; Financial security (e.g. stock, mutual fund) Торговля ценными бумагами From security: Financial security (e.g. stock, mutual fund) К ценным бумагам: Shares moved: Financial shares Переместить акции: To security: Financial security (e.g. stock, mutual fund) К ценным бумагам: Shares received: Financial shares Полученные акции: Value: Стоимость: Date: Дата: Error No other security available for exchange in the account. Shares of one security directly exchanged for shares of another; Financial security (e.g. stock, mutual fund) Нет других ценных бумаг для торговли в счете. No other security available for trade in the account. Нет других ценных бумаг для торговли в счете. Selected to and from securities are the same. Financial security (e.g. stock, mutual fund) Выбранные источник и назначение для ценных бумаг один и тот же. Zero shares not allowed. Financial shares Акции с нулевой стоимостью не разрешены. Selected to and from securities are the same. Выбранные источник и назначение для ценных бумаг один и тот же. Invalid date. Неверные данные. Zero shares not allowed. Акции с нулевой стоимостью не разрешены. Zero value not allowed. Нулевая стоимость не разрешена. EditSplitDialog Split Transaction Разбить транзацию Name: Имя: Date: Дата: Account: Счет: Transactions: Транзакция: Type Тип Name Имя Description Generic Description Описание Account/Category Счет/Категория Description: Описание: Payment Платеж Deposit Депозит New Новый New Expense… Новый расход… New Income… Новый доход… New Deposit… Новый депозит… New Withdrawal… Новое изъятие… Shares Bought… Общие покупки… Shares Sold… Общие продажи… New Dividend… Новые дивиденты… Edit… Правка… Total value: Итог: No suitable account available. Имеющийся счет не пригоден Invalid date. Неверные данные. Future dates is not allowed. Будущие даты не разрешены. A split must contain at least two transactions. Разделение должно быть ограниченно минимум двумя транзакциями. Cannot transfer money to and from the same account. Невозможно перевести деньги на тот же самый счет. Eqonomize Accounts && Categories Счета и категории Expenses Расходы Incomes Доходы Transfers Трансферы Transaction Accounts Текущие счета Savings Accounts Сбережения Credit Cards Кредитные карты Debts Долги Securities Ценные бумаги Schedule Планировщик Account / Category Счет / Категория Remaining Budget (%1) Оставшийся бюджет(%1) Change (%1) Изменение (%1) Total (%1) Итог (%1) %2 of %1 %2 remains of %1 budget %2 из %1 Accounts Счета Includes budgeted transactions Включая бюджетные транзакции Securities Financial security (e.g. stock, mutual fund) Ценные бумаги Assets Активы Tags Period Период From Из To К Select Period Выберите период Current Month Текущий месяц Current Year Текущий год Current Whole Month Текущий итог месяца Current Whole Year Текущий итого года Whole Past Month Итог прошлого месяца Whole Past Year Итог прошлого года Previous Month Предыдущий месяц Previous Year Предыдущий год Show partial budget Показать неполный бюджет Edit Budget Править бюджет Budget: Бюджет: Month: Месяц: Result previous month: Результат прошлого месяца: New Security… Новые ценные бумаги… New Transaction Новая транзакция Set Quotation… Набор котировок… Name Имя Value Значение Shares Акции Quotation Котировка Cost Цена Profit Прибыль Yearly Rate Ежегодная плата Type Тип Account Счет Statistics Period Статистика периода New Schedule Новый план Edit Правка Remove Удалить Next Occurrence Следующее событие Description Transaction description property (transaction title/generic article name) Описание Amount Количество Payee/Payer Получатель/платильщик Comments Комментарии Set Schedule Confirmation Time Schedule confirmation time: Set Budget Period First day in budget month: 1st 1. 2nd 2. 3rd 3. 4th 4. 5th 5. 6th 6. 7th 7. 8th 8. 9th 9. 10th 10. 11th 11. 12th 12. 13th 13. 14th 14. 15th 15. 16th 16. 17th 17. 18th 18. 19th 19. 20th 20. 21st 21. 22nd 22. 23rd 23. 24th 24. 25th 25. 26th 26. 27th 27. 28th 28. Last Последний 2nd Last Предпоследний 3rd Last 3-й с конца 4th Last 4-й с конца 5th Last 5-й с конца Set Quote (%1) Financial quote Набор котировок (%1) Stock Financial stock Акция Timestamp Links Ссылки Remove Link Link to "%1" create link to transaction (link used as verb) All Checking Account Transactional account Текущий счет Import Options Ignore duplicate transactions Rename duplicate accounts Rename duplicate categories Rename duplicate securities Synchronization Settings Web address: Download command: Do you wish to remove the tag "%1" from %n transaction(s)? optional Right align Правое выравнивание Upload command: mandatory Automatic synchronization Upload Uploading… Error uploading file Error uploading %1: %2. Synchronizing… Error synchronizing file Error synchronizing %1: %2. Synchronization error Synchronize file? The file has been modified by a different user or program. Do you wish to merge changes? New version available A new version of %1 is available.<br><br>You can get version %2 at %3. Abort First month in budget year: %f = local file (temporary), %u = url Failed to download exchange rates from %1: %2. Error reading data from %1: %2. Unrecognized Currency No exchange rate is available for the default currency (%1). If you wish to use multiple currencies you should set the exchange rate manually. Set Main Currency Currency: Replace all occurrences of the former main currency Transaction Account Текущий счет S&ynchronize Import %1 File… Reconcile Account… Adjust balance… Referring to account balance Close Account Mark account as closed Duplicate Transaction… duplicate as verb New Debt Payment… New Unpaid Interest… Show payee and quantity Show quantity and payer/payee properties for incomes and expenses. Use Exchange Rate for Transaction Date Use the exchange rate nearest the transaction date, instead of the latest available rate, when converting the value of transactions. Set Schedule Confirmation Time… Select Font… Language Язык Default New Tag… Rename Tag… Remove Tag Restart required %1 exited unexpectedly before the file was saved and data was lost. Do you want to load the last auto-saved version of the file? Eqonomize! Accounting File New Expense Paid with Loan… Adjust Account Balance Reopen Account Mark account as not closed New Tag Tag name: Remove tag? Rename Tag %1 (with no budget) Balance Account Verb Баланс счета Balance Account balance Баланс Balance… Balance account Баланс… Shares Exchanged… Shares of one security directly exchanged for shares of another; Financial shares Общие перемещения… Shares of one security directly exchanged for shares of another Financial shares Edit Quotes… Financial quote Редактировать котировки… New Security Новая ценная бумага Edit Security Редактировать ценную бумагу Total value: Итог: Cost: Цена: Profit: Прибыль: Rate: Ставка: Are you sure you want to delete the security "%1" and all associated transactions? Вы уверены что хотите удалить ценную бумагу "%1" и все связанные с ней транзакции? Error No security available. Нет имеющихся ценных бумаг. Set Quotation (%1) Набор котировок (%1) Price per share: Стоимость через акции: Date: Дата: Invalid date. Неверные данные. Future dates are not allowed. Будущие даты не разрешены. Security Transactions Транзакции ценных бумаг Bond Связь Stock Акция Mutual Fund Взаимный капитал Other Другое Add Loan Add Category Ledger Главная книга Cash Наличные Check Account Контроль счета Savings Account Сбережения Salary Жалование Bills Счета Clothing Одежда Groceries Бакалея Leisure Досуг Couldn't open file Невозможно открыть файл Error loading %1: %2. Ошибка загруки %1: %2. Couldn't save file Не сохранен файл Error saving %1: %2. Ошибка сохранения %1: %2. Updating exchange rates… Error saving currencies: %1. New currency… Transaction Schedule Расписание транзакций Total Итог Accounts &amp; Categories html format Бюджет и категории Accounts &amp; Categories (%1&ndash;%2) html format Бюджет и категории (%1&ndash;%2) Accounts &amp; Categories (to %1) html format Бюджет и категории (к %1) Change Noun, how much the account balance has changed Изменение Balance Баланс Current Account Текущий счет Credit Card Кредитная карта Liabilities Задолженность New Security… Financial security (e.g. stock, mutual fund) Новые ценные бумаги… Set Quotation… Financial quotation Набор котировок… Shares Financial shares Акции Quotation Financial quotation Котировка New Security Financial security (e.g. stock, mutual fund) Новая ценная бумага Edit Security Financial security (e.g. stock, mutual fund) Редактировать ценную бумагу Delete security? Financial security (e.g. stock, mutual fund) Are you sure you want to delete the security "%1" and all associated transactions? Financial security (e.g. stock, mutual fund) Вы уверены что хотите удалить ценную бумагу "%1" и все связанные с ней транзакции? No security available. Financial security (e.g. stock, mutual fund) Нет имеющихся ценных бумаг. Set Quotation (%1) Financial quotation Набор котировок (%1) Price per share: Financial shares Стоимость через акции: Security Transactions Financial security (e.g. stock, mutual fund) Транзакции ценных бумаг Balance Noun. Balance of an account Баланс Category Категория Budget Бюджет Remaining Budget Оставшийся бюджет Total Incomes Итого доходов Costs Затраты Total Expenses Итого Расходов Account/Category Noun, how much the account balance has changed Счет/Категория Empty expenses list. Пустой список расходов. Empty incomes list. Пустой список доходов. Empty transfers list. Пустой список транзакций. Empty securities list. Пустой список ценных бумаг. Empty schedule list. Пустое расписание. Couldn't open file for writing. Не могу открыть файл для записи. Error while writing file; file was not saved. Ошибка чтения файла; Файл не сохранен. &File &Файл &Accounts &Счет &Transactions &Транзакции &Securities &Ценные бумаги Stat&istics Стат&истика S&ettings &Настройкa &Help &Справка File Файл Transactions Транзакции Statistics Статистика &New Созд&ать &Open… &Открыть… Open Recent Последние файлы Clear List Очистить список &Save &Сохранить Save As… Сохранить как… &Revert О&бновить &Print… &Печать… Print Preview… Предварительный просмотр… Import Импорт Import CSV File… Импорт CSV-файла… Import QIF File… Импорт QIF-файла… Export View… Просмотр экспорта… Export As QIF File… Экспортировать как QIF-файл… Update Exchange Rates Currency Converter &Quit В&ыход Add Account… Добавить счет… New Account… Новый счет… New Loan… New Income Category… Новая категория доходов… New Expense Category… Новая категория расходов… Add Account Добавить счет Security Transactions Financial security (e.g. stock, bond) Транзакции ценных бумаг &Loans &Займы &Securities Financial security (e.g. stock, mutual fund) &Ценные бумаги Edit… Правка… Balance… Баланс… Show Transactions Показать транзакция Show Ledger New Expense… Новый расход… New Income… Новый доход… New Transfer… Новый трансфер… New Split Transaction… Новое разделение транзакции… New Expense with Multiple Payments… Refund… Платеж… Repayment… Оплата… New Refund/Repayment… Новый платеж/оплата… Edit Transaction(s) (Occurrence)… Edit Occurrence… Править событие… Edit Schedule (Recurrence)… Edit Schedule… Редактировать расписание… Edit Split Transaction… Редактировать разделенные транзакции… Join Transactions… join transactions together Соединить транзакции… Split Up Transaction split up joined transactions Create Link create link to or between transaction(s) Edit Timestamp… Select Associated File Open Associated File Remove Transaction(s) (Occurrence) Remove Occurrence Удалить событие Delete Schedule (Recurrence) Delete Schedule Удалить план Remove Split Transaction Удалить разделенные транзакции Edit Security… Редактировать ценную бумагу… Remove Security Удалить ценную бумагу Shares Bought… Общие покупки… Shares Sold… Общие продажи… Shares Moved… Общие перемещения… Dividend… Дивиденды… Reinvested Dividend… Снова инвестированные дивиденды… Transactions… Транзакции… Edit Quotations… Редактировать котировки… Development Over Time Report… Отчет по датам… Categories Comparison Report… Отчет по категориям… Development Over Time Chart… Временная диаграмма… Categories Comparison Chart… Диаграмма сравнения категорий… Use Additional Transaction Properties Использовать свойства добавленной транзакции Set Main Currency… Set Budget Period… Initial Period Начальный период Remember Last Dates Запомнить последнюю дату Backup Frequency Daily Ежедневно Weekly Еженедельно Fortnightly Monthly Ежемесячно Never Cloud Synchronization (experimental)… Dark Mode Тёмный режим Help Report Bug About %1 About Qt Please restart the application for the language change to take effect. A personal accounting program License: GNU General Public License Version 3 Crash Recovery Крах восстановления Untitled Безымянный Description Generic Description Описание The current file has been modified. Do you want to save it? Текущий файл модифицирован. Желаете сохранить? Save file? Confirm Schedule Подтвердить расписание New Account Новый счет New Loan New Income Category Новая категория доходов New Expense Category Новая категория расходов Balance Account Баланс счета Book value: Книга ценности: of which %1 is balance adjustment Referring to account balance Real value: Реальная ценность: Only use this when unable to find the cause of the incorrect recorded account balance. Edit Account Редактировать счет Edit Income Category Редактировать категорию доходов Edit Expense Category Редактировать категорию расходов Remove subcategories? Do you wish to remove the category including all subcategories? Move transactions? Переместить транзакцию? Move to: Переместить в: Remove irreversibly from all accounts (do not do this if account has been closed!) The category contains some expenses. What do you want to do with them? Категория содержит некоторые расходы. Что вы хотите с ними сделать? The category contains some incomes. What do you want to do with them? The account contains some transactions. What do you want to do with them? Remove Category? Удалить категорию? The category contains some expenses that will be removed. Do you still want to remove the category? The category contains some incomes that will be removed. Do you still want to remove the category? Категория содержит некоторые доходы, вы ее хотите удалить? Remove Account? Удалить счет? The account contains some transactions that will be removed. Do you still want to remove the account? Счет содержит некоторые транзакции, вы его хотите удалить? %2 of %1 %1: budget; %2: remaining budget %2 из %1 Set Quote… Financial quote Набор котировок… Quote Financial quote Котировка Empty securities list. Financial security (e.g. stock, mutual fund) Пустой список ценных бумаг. Balance… Verb. Balance an account Баланс… Edit Security… Financial security (e.g. stock, mutual fund) Редактировать ценную бумагу… Remove Security Financial security (e.g. stock, mutual fund) Удалить ценную бумагу Shares Bought… Financial shares Общие покупки… Shares Sold… Financial shares Общие продажи… Edit Quotations… Financial quotation Редактировать котировки… %1 (with budget %2) %1 ( с бюджета %2) EqonomizeCalendarWidget Today Сегодня EqonomizeDateEdit Today Сегодня EqonomizeTranslator OK Only used when Qt translation is missing Cancel Only used when Qt translation is missing Close Only used when Qt translation is missing &Yes Only used when Qt translation is missing &No Only used when Qt translation is missing &Open Only used when Qt translation is missing &Save Only used when Qt translation is missing &Select All Only used when Qt translation is missing Look in: Only used when Qt translation is missing File &name: Only used when Qt translation is missing Files of type: Only used when Qt translation is missing EqonomizeValueEdit Error Empty denominator. Empty factor. Division by zero. Unknown or ambiguous currency, or unrecognized characters, in expression: %1. Empty base. Empty exponent. Unrecognized characters in expression. ExportQIFDialog Export QIF File Экспорт в QIF файл Account: Счет: All All accounts Все счета Payee Получатель Memo Записка Subcategory Субкатегория Date format: формат даты: Value format: формат валюты: File: Файл: Error Selected file is a directory. Выберите файл или директорию. Overwrite The selected file already exists. Would you like to overwrite the old copy? Выбранный файл уже открыт. Хотите перезаписать старую копию? You selected a directory! Вы выбрали директорию! Couldn't open file for writing. Не могу открыть файл для записи. Error while writing file; file was not saved. Ошибка чтения файла; Файл не сохранен. ImportCSVDialog Import CSV file Импорт CSV файла Transaction Type Selection Выбор типа транзакции Expenses Расходы Incomes Доходы Transfers Трансферы Expenses and incomes (negative cost) Расходы и доходы (отрицательная величина) Expenses and incomes (separate columns) Расходы и доходы (разделенные колонки) All types Все типы Presets: File Selection Выбор файла File: Файл: First data row: Первая строка данных: Auto Авто Column delimiter: Разделитель колонок: Comma Запятая Tabulator Табулятор Semicolon Точка с запятой Space Пробел Other Другое Columns Specification Спецификация колонки Imports data as expenses and incomes. Costs have negative value. Value is the only required column. Imports data as expenses and incomes. Costs and incomes have separate columns. Income and cost both all required columns. Warning Description: Описание: Description: Transaction description property (transaction title/generic article name) Описание: Column Колонка Value Значение Cost: Цена: Date: Дата: Category: Категория: From account: Со счета: Quantity: Количество: Payee: Получатель: Tags: Comments: Коментарии: Create missing categories and accounts Создать найденные категории и счета Save as preset… Save Preset Imports data as expenses. Costs have positive value. Value is the only required column. Imports data as incomes. Value is the only required column. Импортировать данные как доходы. Income: Доход: To account: К счету: Payer: Платильщик: Imports data as transfers. Value is the only required column. Импорт данных как трансферы. Amount: Количество: Value: Стоимость: Account: Счет: Payee/payer: Получатель/платильщик: Imports data as expenses, incomes, and transfers. Costs have negative or positive value. Value, to, and from are all required columns. Accounts and categories must be existing. From: Из: To: К: Error A file must be selected. Файл должен быть выбран. Selected file is a directory. Выберите файл или директорию. Selected file does not exist. Выбранный файл не существует. Empty delimiter. Пустой разделитель. The same column number is selected multiple times. Do you wish to proceed anyway? Selected from account is the same as the to account. Выбранный счет тот же самый. Invalid date. Неверные данные. Couldn't open %1 for reading. Не могу открыть %1 для чтения. Error reading %1. Ошибка чтения %1. Uncategorized Без категории Successfully imported %n transaction(s). Успешный импорт %n транзакции. Успешный импорт %n транзакций. Успешный импорт %n транзакций. Unable to import any transactions. Невозможно импортировать любые транзакции. Failed to import %n data row(s). Ошибка импорта данных из %n строчки. Ошибка импорта данных из %n строчек. Ошибка импорта данных из %n строчек. Required columns missing. Недостает необходимых колонок. Invalid value. Неверное значение. Empty category name. Пустое имя категории. Empty account name. Пустое имя счета. Unknown category found. Найдена неизвестная категория. Unknown account found. Найден неизвестный счет. Cannot import security transactions (to/from security accounts). Невозможно импортировать транзакции с ценными бумагами (к/из счета ценных бумаг). Balancing account wrongly used. Referring to the account used for adjustments of account balances. Счет баланса неверно используется. Balancing account wrongly used. Счет баланса неверно используется. Same to and from account/category. Категория и счет одинаковы. No data found. Данные не найдены. Information Unrecognized date format. Не распознаваемый формат даты. Specify Format Специфический формат The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. Формат дат и/или номеров в CVS файле двусмыслен.Пожалуйста выберите корректный формат. Date format: формат даты: Value format: формат валюты: ImportQIFDialog Import QIF file Импорт QIF файла File Selection Выбор файла Select a QIF file to import. When you click next, the file be analysed and you might need to answer some questions about the format of the file. File: Файл: Local Definitions Unknown elements where found in the QIF file. It is possible that this is because of localized type names. Please map them to the correct standard names. Local Text Локальный текст Standard Text Стандартный текст Select standard text: Выбрать стандартный текст: Date Format Формат даты The date format in the QIF file is ambiguous. Please select the correct format. Date format: формат даты: Default Account Счет по умолчанию Could not find any account definitions in the QIF file. Please select a default account. It is also possible that this is caused by a localized opening balance text. Default account: Счет по умолчанию: Opening balance text: Открытый текст баланса: Descriptions Описания Subcategories as: Субкатегория как: Description Описание Category Категория Ignore Игнорировать Payee as: Получатель как: Payee Получатель Memo as: Запомнить как: Comments Комментарии Priority: Приоритет: Subcategory/Payee/Comments Субкатегория/Получатель/Комментарии Payee/Subcategory/Comments Получатель/Субкатегория/Комментарии Subcategory/Comments/Payee Субкатегория/Комментарии/Получатель Payee/Comments/Subcategory Получатель/Комментарии/Субкатегория Comments/Subcategory/Payee Комментарии/Субкатегория/Получатель Comments/Payee/Subcategory Комментарии/Получатель/Субкатегория Import File No (further) issues were found. Press finish to import the selected QIF file. Ignore duplicate transactions Error A file must be selected. Файл должен быть выбран. Selected file is a directory. Выберите файл или директорию. Selected file does not exist. Выбранный файл не существует. Couldn't open %1 for reading. Не могу открыть %1 для чтения. Error reading %1. Ошибка чтения %1. Unknown Неизвестно Account Счет Bank Банк Cash Наличные Cat (Category) Кат. (Категория) CCard (Credit Card) Кредитная карта Invst (Investment) Инвест. (Инвестиции) Oth A (Other Assets) Oth A (Другие активы) Oth L (Other Liabilities) Oth L (Существующие задолжности) Security Ценные бумаги Other Другое Unrecognized date format. Не распознаваемый формат даты. Successfully imported %n transaction(s). Успешный импорт %n транзакции. Успешный импорт %n транзакций. Успешный импорт %n транзакций. Successfully imported %n account(s). Successfully imported %n category/categories. %n duplicate transaction(s) was ignored. Failed to import %n transaction(s). %n security/securities were not imported. Financial security (e.g. stock, mutual fund) %n security transaction(s) were not imported. Financial security (e.g. stock, mutual fund) Information Income Dividend: %1 Дивиденты: %1 Reinvested dividend: %1 Вкладываемые дивиденты: %1 LedgerDialog Account: Счет: Export… Экспорт… Print… Печать… Reconcile Accounting context Change: Accounting context Изменение: Date Дата Type Тип Name Имя Description Generic Description Описание Account/Category Счет/Категория Deposit Депозит Withdrawal Отзыв Balance Баланс New Новый Edit… Правка… Delete Удалить Join… join transactions together Соеденить… Split Up split up joined transactions Разделить вдоль Reconciled: %1 (%2) Accounting context Error Invalid date. Неверные данные. Opening date is after closing date. Closing date is before opening date. Empty transaction list. Пустой список транзакций. Couldn't open file for writing. Не могу открыть файл для записи. Error while writing file; file was not saved. Ошибка чтения файла; Файл не сохранен. Ledger Главная книга Transactions for %1 Транзакции для %1 Select Time Period From: Из: To: К: To date is before from date. Balance change: Account balance Delete transactions? Are you sure you want to delete all (%1) selected transactions? Вы уверены что хотите удалить все (%1) выбранные транзакции? Opening balance Account balance Сальдо начальное Account Balance Adjustment Current balance: Account balance Average balance: Account balance Account Balancing Balancing of an account Баланс счета Balancing Balancing of an account Баланс Balancing Account balancing Баланс Current debt: Total debt reduction: Total interest and fees: Number of transactions: Initial balance Начальный баланс Description Transaction description property (transaction title/generic article name) Описание Balance Account balance Баланс Cannot set the value of security transactions using the dialog for modifying multiple transactions. Financial security (e.g. stock, mutual fund) Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name); Financial security (e.g. stock, mutual fund) Cannot change payer of dividends and security transactions. Financial security (e.g. stock, mutual fund) Split Transaction Разбить транзацию Debt Payment Reduction Fee Interest Income Доход Repayment Оплата Expense Расход Edit Account… Редактировать счет… Mark all as reconciled Accounting context Opening balance: Accounting context Сальдо начальное: Closing balance: Accounting context R Header for account reconciled checkbox column Payee/Payer Получатель/платильщик Tags Comments Комментарии Deposit Money put into account Депозит Withdrawal Money taken out from account Отзыв Balance Noun. Balance of an account Баланс Edit Transaction(s)… Join Transactions… Соединить транзакции… Remove Transaction(s) Mark as reconciled Book value: %1 (%2) Accounting context Книга ценности: %1 (%2) Ascending order Refund Получение оплаты Balancing Баланс Transfer Перевод LinksWidget Remove Link All Remove Удалить MultiItemListViewItem Dividend Дивидент Income Доход Repayment Оплата Expense Расход Refund Получение оплаты Securities Purchase Financial security (e.g. stock, mutual fund) Покупки ценных бумаг Securities Sale Financial security (e.g. stock, mutual fund) Продажи ценных бумаг Account Balance Adjustment Account Balancing Balancing of an account Баланс счета Balancing Balancing of an account Баланс Security Buy Покупки ценных бумаг Security Sell Продажи ценных бумаг Balancing Баланс Transfer Перевод MultipleTransactionsEditDialog Modify Transactions Модифицировать транзакции Name: Имя: Description: Transaction description property (transaction title/generic article name) Описание: Amount: Количество: Income: Доход: Cost: Цена: Date: Дата: Category: Категория: Payer: Платильщик: Payee: Получатель: New Income Category Новая категория доходов New Expense Category Новая категория расходов New Income Category… Новая категория доходов New Expense Category… Новая категория расходов Error No income category available. Нет доступной категории доходов. No expense category available. Нет доступной категории расходов. Invalid date. Неверные данные. OverTimeChart Save As… Сохранить как… Print… Печать… Source: Источник: Incomes and Expenses Доходы и Расходы Profits Прибыль Expenses Расходы Incomes Доходы All Categories Combined Объединить все категории All Descriptions Combined Объединить все описания Theme: Chart type: Line Chart Vertical Bar Chart Horizontal Bar Chart Stacked Bar Chart Default Tags All Accounts Combined Объединить все счета All Accounts Split Все счета разделить All Subcategories and Descriptions Combined Referring to the transaction description property (transaction title/generic article name) All Descriptions Split Referring to the transaction description property (transaction title/generic article name) Все описания разбить No description Referring to the transaction description property (transaction title/generic article name) Без описания All Payees/Payers Split Всех получателей/плательщиков разделить No payee/payer Без получателя/платильщика All Tags Split Other tags Other payees/payers Other descriptions Referring to the transaction description property (transaction title/generic article name) Profits, %1 Прибыль, %1 Assets Активы All Descriptions Combined Referring to the generic description property Объединить все описания Assets and Liabilities All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Объединить все описания All Payees/Payers Combined Объединить всех получателей/плательщиков All Accounts Все счета Start date: Дата начала: End date: Дата конца: Value: Стоимость: Annual total Monthly total Итог месяца Daily average Среднее еженедельно Quantity Количество Average value Среднее значение All Payers Combined Объединить всех плательщиков All Payees Combined Объединить всех получателей All Subcategories Split All Descriptions Split Referring to the generic description property Все описания разбить No description Referring to the generic description property Без описания Value Значение Includes budgeted transactions Включая бюджетные транзакции Incomes − Expenses, %1 Расход − Доход, %1 Incomes − Expenses Расход − Доход Incomes & Expenses Расход и Доход Incomes: %1 Доходы: %1 Expenses: %1 Расходы: %1 %2: %1 Incomes: %2, %1 Доход: %2, %1 Expenses: %2, %1 Расход: %2, %1 %3: %2, %1 %2, %1 Incomes: %3, %2, %1 Доход: %3, %2, %1 Expenses: %3, %2, %1 Расход: %3, %2, %1 %4: %3, %2, %1 no payee/payer без получателя/платильщика %3, %2, %1 Other accounts %1 Value: %2 Date: %3 MMMM yyyy Month and year All Descriptions Split Все описания разбить All Payers Split Всех плательщиков разделить All Payees Split Всех получателей разделить No description Без описания No payer Без платильщика No payee Без получателя All Categories Split Все категории разделить Error Invalid date. Неверные данные. Couldn't open file for writing. Не могу открыть файл для записи. Error while writing file; file was not saved. Ошибка чтения файла; Файл не сохранен. Other payees Other payers Value (%1) Значение (%1) Profit (%1) Прибыль (%1) Income (%1) Доход (%1) Cost (%1) Цена (%1) Time Время %1/%2 %1: Category; %2: Payee/Payer %1/%2 All Descriptions Combined Referring to the Transaction description property (transaction title/generic article name) Объединить все описания All Descriptions Split Referring to the Transaction description property (transaction title/generic article name) Все описания разбить No description Referring to the Transaction description property (transaction title/generic article name) Без описания Daily average value Daily average profit Daily average income Daily average cost Average income Average cost Annual value Annual profit Annual income Annual cost Monthly value Monthly profit Monthly income Monthly cost Includes scheduled and budgeted transactions Включая запланрованные и бюджетные транзакции Includes scheduled transactions Включая запланированные транзакции Tags, %1 Value: %1 Значение: %1 Assets & Liabilities Change: %1 Изменение: %1 Excluding any profits or losses in trading of security shares Financial security (e.g. stock, mutual fund) Incomes & Expenses, %1 Расход и Доход, %1 Incomes, %1 Доходы, %1 Expenses, %1 Расходы, %1 Incomes, %2: %1 Доход, %2: %1 Expenses, %2: %1 Расход, %2: %1 Incomes, %3: %2, %1 Доход, %3: %2, %1 Expenses, %3: %2, %1 Расход, %3: %2, %1 Incomes, %4: %3, %2, %1 Доход, %4: %3, %2, %1 Expenses, %4: %3, %2, %1 Расход, %4: %3, %2, %1 Liabilities Задолженность no payer без платильщика %1/%2 %1: Description; %2: Payer/Payer %1/%2 %1/%2 %1: Description; %2: Payee/Payer %1/%2 %1/%2 %1: Description; %2: Payer %1/%2 no payee без получателя %1/%2 %1: Description; %2: Payee %1/%2 OverTimeChartDialog Chart Диаграмма OverTimeReport Save As… Сохранить как… Print… Печать… Source: Источник: Profits Прибыль Expenses Расходы Incomes Доходы Assets & Liabilities Tags All Categories Combined Объединить все категории All Descriptions Combined Объединить все описания Columns: Колонки: Categories Total: Итог: Value Значение Daily Ежедневно Monthly Ежемесячно Yearly Ежегодно Quantity Количество Average value Среднее значение No description Без описания All Descriptions Combined Referring to the generic description property Объединить все описания No description Referring to the generic description property Без описания All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Объединить все описания All Accounts Все счета No description Referring to the transaction description property (transaction title/generic article name) Без описания Error Couldn't open file for writing. Не могу открыть файл для записи. Error while writing file; file was not saved. Ошибка чтения файла; Файл не сохранен. Average Profit Средняя выгода Incomes, %1 Доходы, %1 Average Income Средний доход Expenses, %1 Расходы, %1 Average Cost Средняя цена Incomes, %2: %1 Доход, %2: %1 Incomes: %1 Доходы: %1 Expenses, %2: %1 Расход, %2: %1 Expenses: %1 Расходы: %1 Incomes, %3: %2, %1 Доход, %3: %2, %1 Incomes: %2, %1 Доход: %2, %1 Expenses, %3: %2, %1 Расход, %3: %2, %1 Expenses: %2, %1 Расход: %2, %1 Change: %1 Noun, how much the account balance has changed Изменение: %1 Deposit Money put into account Депозит Withdrawal Money taken out from account Отзыв Change Noun, how much the account balance has changed Изменение Value: %1 Значение: %1 %2: %1 %1 %1 Average Value Среднее значение %3: %2, %1 %2, %1 Year Год Month Месяц Assets Активы Deposit Депозит Withdrawal Отзыв Liabilities Задолженность Daily Average Средний ежедневный Monthly Average Средний ежемесячный Yearly Average Средний ежегодный Subtotal Промежуточная сумма Total Итог Includes scheduled transactions Включая запланированные транзакции Adjusted for the average month / year (%1 / %2 days) Установлено для среднего месяца / года (%1 / %2 дней) All Categories Combined Referring to the generic description property Объединить все категории OverTimeReportDialog Report Отчет QApplication Start with expenses list displayed Старт со списка расходов Start with incomes list displayed Старт со списка доходов Start with transfers list displayed Старт со списка переводов Synchronize file Document to open Документ открыт %1 is already running. QObject Transfer Перевод Dividend Дивидент Income Доход Expense Расход Securities Purchase Financial security (e.g. stock, mutual fund) Покупки ценных бумаг Securities Sale Financial security (e.g. stock, mutual fund) Продажи ценных бумаг Security Buy Покупки ценных бумаг Security Sell Продажи ценных бумаг Debt Payment Split Transaction Разбить транзацию RecurrenceEditWidget Enable recurrence Разрешить повторение Recurrence Rule Правила повторения Daily Ежедневно Weekly Еженедельно Monthly Ежемесячно Yearly Ежегодно Recur every Повторять каждый day(s) день(и) week(s) on: неделю(и): month(s), after the start month месяц(ы), после стартового месяца Recur on the Повторять на 1st 1. 2nd 2. 3rd 3. 4th 4. 5th 5. 6th 6. 7th 7. 8th 8. 9th 9. 10th 10. 11th 11. 12th 12. 13th 13. 14th 14. 15th 15. 16th 16. 17th 17. 18th 18. 19th 19. 20th 20. 21st 21. 22nd 22. 23rd 23. 24th 24. 25th 25. 26th 26. 27th 27. 28th 28. 29th 29. 30th 30. 31st 31. Last Последний 2nd Last Предпоследний 3rd Last 3-й с конца 4th Last 4-й с конца 5th Last 5-й с конца day День possibly on weekend возможно на выходные but before weekend но перед выходными but after weekend но после выходных nearest weekend day year(s), after the start year год(ы), после стартового года on nearest weekday Recur on day part before XXX of 'Recur on day XXX of month YYY' of part between XXX and YYY of 'Recur on day XXX of month YYY' On the Part before NNN in 'Recur on the NNN. WEEKDAY of MONTH' of part between WEEKDAY and MONTH in 'Recur on NNN. WEEKDAY of MONTH' Recur on day # of the year part after NNN of 'Recur on day #NNN of the year' Range… Диапазон… Occurrences/Exceptions… Hаличность/исключения… Exceptions… Исключения… Error No day of week selected for weekly recurrence. Нет дня недели выбранного для недельной рекурсии. Selected day will never occur with selected frequency and start date. Выбранный день никогда не наступит, с выбранной частотой и стартовой датой. Selected day does not exist in selected month. Выбранный день не существует в выбранном месяце. RefundDialog Repayment Оплата Refund Получение оплаты Date: Дата: Cost: Цена: Income: Доход: Quantity returned: Возвращенное количество: Account: Счет: Quantity: Количество: Payee: Получатель: Payer: Платильщик: Comments: Коментарии: Link Link the transactions together Join Join the transactions together Соединить Error Zero value not allowed. Нулевая стоимость не разрешена. Invalid date. Неверные данные. SecurityBuy Security: %1 (bought) Ценные бумаги: %1 (покупка) Security: %1 (bought) Financial security (e.g. stock, mutual fund) Ценные бумаги: %1 (покупка) SecuritySell Security: %1 (sold) Ценные бумаги: %1 (продажа) Security: %1 (sold) Financial security (e.g. stock, mutual fund) Ценные бумаги: %1 (продажа) SecurityTransactionsDialog Transactions for %1 Транзакции для %1 Date Дата Type Тип Value Значение Shares Financial shares Акции Shares Bought Financial shares Купленные акции Shares Bought (Recurring) Financial shares Купленные акции(повторно) Dividend (Recurring) Дивидент (повторно) Dividend (Scheduled) Дивидент (по плану) Reinvested Dividend (Recurring) Вкладываемые дивиденты (повторно) Reinvested Dividend (Scheduled) Вкладываемые дивиденты (по плану) Shares Bought Fincancial shares Купленные акции Shares Sold Financial shares Проданные акции Shares Sold (Exchanged) Shares of one security directly exchanged for shares of another; Financial shares Проданные акции (торгуемые) Shares Bought (Exchanged) Shares of one security directly exchanged for shares of another; Financial shares Купленные акции (торгуемые) Shares Bought (Recurring) Fincancial shares Купленные акции(повторно) Shares Sold (Recurring) Financial shares Проданные акции (повторно) Shares Bought (Scheduled) Financial shares Купленные акции (по плану) Shares Sold (Scheduled) Financial shares Проданные акции (по плану) Shares Акции Edit… Правка… Delete Удалить Shares Bought Купленные акции Shares Sold Проданные акции Dividend Дивидент Reinvested Dividend Вкладываемые дивиденты Shares Sold (Traded) Проданные акции (торгуемые) Shares Bought (Traded) Купленные акции (торгуемые) Shares Bought (Recurring) Купленные акции(повторно) Shares Sold (Recurring) Проданные акции (повторно) Shares Bought (Scheduled) Купленные акции (по плану) Shares Sold (Scheduled) Проданные акции (по плану) Recurring Dividend Повторный дивидент Scheduled Dividend Планируемый дивидент SplitListViewItem Dividend Дивидент Income Доход Repayment Оплата Expense Расход Refund Получение оплаты Security Buy Покупки ценных бумаг Security Sell Продажи ценных бумаг Balancing Баланс Transfer Перевод TagButton no tags TagMenu New tag… New Tag Tag: TransactionEditDialog Edit Expense Править расход Edit Dividend Править дивиденты Edit Income Править доход Edit Transfer Править перевод Edit Securities Purchase Financial security (e.g. stock, mutual fund) Править ценные покупки Edit Securities Sale Financial security (e.g. stock, mutual fund) Править ценные продажи Edit Reinvested Dividend Edit Securities Bought Править ценные покупки Edit Securities Sold Править ценные продажи TransactionEditWidget Security: Ценные бумаги: Cost: Цена: Income: Доход: Shares bought: Распределенные покупки: Shares sold: Распределенные продажи: All Все Price per share: Стоимость через акции: Date: Дата: Name: Имя: Description: Описание: Amount: Количество: Withdrawal: Money taken out from account Отзыв: New Security… Financial security (e.g. stock, mutual fund) Новые ценные бумаги… Shares added: Financial shares Добавить акции: Set security share value Total value: Итог: Deposit: Money put into account Депозит: Downpayment: Quantity: Количество: From: Из: To: К: Category: Категория: To account: К счету: Payer: Платильщик: Payer of parent split transaction From account: Со счета: Downpayment account: Payee: Получатель: Payee of parent split transaction Lender: Tags: Associated file: Select a file Open the file Comments: Коментарии: Related to: Label for linked transactions Ссылки: New Security Financial security (e.g. stock, mutual fund) Новая ценная бумага No security available. Financial security (e.g. stock, mutual fund) Нет имеющихся ценных бумаг. New Account Новый счет New Income Category Новая категория доходов New Expense Category Новая категория расходов New Account… Новый счет… New Income Category… Новая категория доходов New Expense Category… Новая категория расходов Security: Financial security (e.g. stock, mutual fund) Ценные бумаги: Shares bought: Financial shares Распределенные покупки: Shares sold: Financial shares Распределенные продажи: Price per share: Financial shares Стоимость через акции: Description: Transaction description property (transaction title/generic article name) Описание: Transaction title/generic article name Number of items included in the transaction. Entered cost is total cost for all items. Error No suitable account available. Имеющийся счет не пригоден. No income category available. Нет доступной категории доходов. No suitable account or income category available. Не годный счет или категория доходов. No expense category available. Нет доступной категории расходов. No security available. Нет имеющихся ценных бумаг. Invalid date. Неверные данные. Cannot transfer money to and from the same account. Невозможно перевести деньги на тот же самый счет. Downpayment must be less than total cost. Cannot create a regular transfer to/from a securities account. Невозможно создать регулярный трансфер в/из счета ценным бумаг. Cannot create a regular income to a securities account. Невозможно создать регулярный доход в счете ценных бумаг. Zero shares not allowed. Акции с нулевой стоимостью не разрешены. Zero value not allowed. Нулевая стоимость не разрешена. Zero price per share not allowed. Cannot create a regular expense from a securities account. Невозможно создать регулярный расход с счета ценных бумаг. Loan for %1 TransactionFilterWidget From: Из: To: К: Min amount: Минимальный объем: Max amount: Максимальный объем: Category: Категория: To account: К счету: Min income: Минимальный доход: Max income: Максимальный доход: From account: Со счета: Min cost: Минимальная цена: Max cost: Максимальная ценна: Tag: Description: Описание: Description: Transaction description property (transaction title/generic article name) Описание: Payer: Платильщик: Payee: Получатель: Include Включить Exclude Исключить Exact match Exclude subcategories Clear Очистить All Все Error Invalid date. Неверные данные. TransactionListWidget Date Дата Name Имя Description Generic Description Описание Description Transaction description property (transaction title/generic article name) Описание Cost Цена Category Категория From Account С счета Payee Получатель Tags Income Доход To Account К счету Payer Платильщик Amount Количество From Из To К Comments Комментарии Add Добавить Apply применить Delete Удалить New/Edit Expense Новый/Редактировать расход New/Edit Income Новый/Редактировать доход New/Edit Transfer Новый/Редактировать перевод Filter Фильтр Quantity: Количество: Total: Итог: Cannot change date of transactions that are part of a split transaction, unless all individual transactions are selected. * Part of <a href="%1">split transaction</a> * Часть <a href="%1">разбитой транзакции</a> Average: Среднее: Clear Очистить Cost: Цена: Monthly: Ежемесячно: Sort by creation time Expenses Расходы Incomes Доходы Transfers Трансферы Quantity Количество Right align Правое выравнивание Total cost: Итого цена: Total income: Итого доходов: Total amount: Итого объем: Monthly average: Среднее в месяц: Error Cannot set the value of security transactions using the dialog for modifying multiple transactions. Financial security (e.g. stock, mutual fund) Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name); Financial security (e.g. stock, mutual fund) Cannot change payer of dividends and security transactions. Financial security (e.g. stock, mutual fund) Cannot change date, description, expense category or payee of transactions that are part of a debt payment using the dialog for modifying multiple transactions. Referring to the transaction description property (transaction title/generic article name) Delete transactions? Are you sure you want to delete all (%1) transactions in the selected split transaction? Вы уверены, что хотите удалить все (%1) транзакции в выбранном разбиение тразакции? Join as multiple accounts/payments? Do you wish join the selected expenses as an expense with multiple accounts/payments? Do you wish join the selected incomes as an income with multiple accounts/payments? Are you sure you want to delete all (%1) selected transactions? Вы уверены что хотите удалить все (%1) выбранные транзакции? * Part of split transaction * Часть разбитой транзакции * Part of split (%1) * Часть разбивки (%1) ** Recurring (editing occurrence) ** Периодически (редактирование) Modify… Модифицировано… Edit… Правка… Eqonomize-1.5.3/translations/eqonomize_sk.ts000066400000000000000000015566341416454732000213140ustar00rootroot00000000000000 Balancing Vyrovnanie kde-format Couldn't open %1 for reading %1 sa nedá čítať kde-format Not a valid Eqonomize! file (XML parse error: "%2" at line %3, col %4) Nie je Eqonomize! súbor (chyba XML: "%2" na riadku %3, stĺpec %4) kde-format Invalid root element %1 in XML document Nesprávny koreňový prvok %1 v XML dokumente kde-format File is a directory Súbor je adresár kde-format Couldn't open file for writing Nemôžem otvoriť pre zápis kde-format Error while writing file; file was not saved Chyba počas zápisu; súbor nebol uložený kde-format From Od kde-format To Do kde-format Source: Zdroj kde-format All Expenses Všetky výdavky kde-format All Incomes Všetky prijmy kde-format All Accounts Všetky účty kde-format Expenses: %1 Výdavky: %1 kde-format Incomes: %1 Prijmy: %1 kde-format Invalid date. Nesprávny dátum. kde-format To date is before from date. Dátum do je pred dátumom od. kde-format From date is after to date. Dátum od je po dátume do. kde-format The selected file already exists. Would you like to overwrite the old copy? Vybraný súbor už existuje. Prajete si ho prepísať? kde-format You selected a directory! Vybrali ste adresár. kde-format Couldn't open file for writing. Do súboru sa nedá zapisovať. kde-format Error while writing file; file was not saved. Chyba počas zápisu do súboru; súbor nebol uložený. kde-format No description Bez popisu kde-format All Categories Všetky kategórie kde-format Descriptions for Popis pre kde-format Payees/payers for Príjemca/platca pre kde-format Period: Doba: kde-format Columns: Stĺpce: kde-format Value Hodnota kde-format Daily Denne kde-format Monthly Mesačne kde-format Yearly Ročne kde-format Quantity Množstvo kde-format Average value Priemerná hodnota kde-format All descriptions Všetky popisy kde-format All payees Všetci príjemcovia kde-format All payers Všetci platitelia kde-format No payee Bez príjemcu kde-format No payer Bez platcu kde-format Expenses: %2, %1 Výdavky: %2, %1 kde-format Incomes: %2, %1 Prijmy: %2. %1 kde-format Incomes & Expenses Prijmy a výdavky kde-format %1 (%2&ndash;%3) html format; %1: title; %2: from date; %3: to date %1 (%2&ndash;%3) kde-format %1 (to %2) html format; %1: title; %2: to date %1 (do %2) kde-format Category Kategória kde-format Cost Cena kde-format Income Príjem kde-format Daily Average Denný priemer kde-format Monthly Average Mesačný priemer kde-format Yearly Average Ročný priemer kde-format Average Cost Priemerná cena kde-format Average Income Priemerný príjem kde-format Average Value Priemerná hodnota kde-format Total incomes Celkové prijmy kde-format Total expenses Celkové výdavky kde-format Total (Profits) Spolu (Zisky) kde-format Expense Výdaj kde-format Transfer Prevod kde-format Security Buy Nákup akcií kde-format Security Sell Predaj akcií kde-format Recurrence Opakovanie kde-format New Expense Nový výdavok kde-format New Dividend Nová dividenda kde-format New Income Nový príjem kde-format New Transfer Nový prevod kde-format New Security Buy Nový nákup akcií kde-format New Security Sell Nový predaj akcií kde-format Edit Expense Uprav vydavok kde-format Edit Dividend Uprav dividend kde-format Edit Income Uprav prijem kde-format Edit Transfer Uprav tranzakciu kde-format Edit Securities Bought Uprav nákup akcií kde-format Edit Securities Sold Uprav predaj akcií kde-format Dividend Dividendy kde-format Repayment Splatenie kde-format Refund Vrátenie kde-format Split Transaction Rozdeliť prevod kde-format Description: Popis: kde-format Date: Dátum: kde-format Account: Účet: kde-format Transactions: Prevody: kde-format Type Typ kde-format Description Popis kde-format Account/Category Účet/Kategória kde-format Payment Platba kde-format Deposit Vklad kde-format New Nový kde-format New Expense… Nový vydavok… kde-format New Income… Nový príjem… kde-format New Deposit… Nová záloha… kde-format New Withdrawal… Nový výber… kde-format Edit… Upraviť… kde-format Total value: Celková hodnota: kde-format No suitable account available. Nevhodný účet. kde-format Future dates is not allowed. Budúce dátumy nie sú povolené. kde-format A split must contain at least two transactions. Pre spojenie sú potrebné dva alebo viac prevodov. kde-format Cannot transfer money to and from the same account. Nemôžem preniesť peniaze na a z rovnakého účtu kde-format Cost: Cena: kde-format Income: Príjem: kde-format Quantity: Množstvo: kde-format Comments: Poznámky: kde-format Reinvested Dividend Znova investované dividendy kde-format Security: Akcii: kde-format Shares added: Podiel pridaný: kde-format Security Trade Obchod akcií kde-format From security: Z akcie: kde-format Shares moved: Podiel presunutý: kde-format All Všetky kde-format Shares received: Podiel pridaný: kde-format Value: Hodnota: kde-format Zero shares not allowed. Nulový prevod nie je povolený. kde-format Zero value not allowed. Nie je povolená nulová hodnota. kde-format Quotations Predbežný rozpočet kde-format Date Dátum kde-format Price per Share Prevodová cena kde-format Quotations for %1 Predbežný rozpočet pre %1 kde-format The following transactions was scheduled to occur today or before today. Confirm that they have indeed occurred (or will occur today). Nasledujúce prevody boli naplánované do dnešného dňa. Podtvrďte tie, ktoré sa vykonali. kde-format Amount Množstvo kde-format Postpone… Odložiť… kde-format Can only postpone to future dates. Je možné odložiť na iný dátum. kde-format Transactions for %1 Prevody pre %1 kde-format Shares Podiely kde-format Shares Bought Nákup podielov kde-format Shares Sold Predaj podielov kde-format Shares Sold (Traded) Predaj podielov (uskutočnený) kde-format Shares Bought (Traded) Nákup podielov (uskutočnený) kde-format Shares Bought (Recurring) Nákup podielov (opakované) kde-format Shares Sold (Recurring) Predaj podielov (opakované) kde-format Shares Bought (Scheduled) Nákup podielov (plánované) kde-format Shares Sold (Scheduled) Predaj podielov (plánované) kde-format Recurring Dividend Pravidelné dividendy kde-format Scheduled Dividend Plánované divodendy kde-format Type: Typ: kde-format Mutual Fund Investičný fond kde-format Bond Záväzok kde-format Stock Akcie kde-format Other Iné kde-format Name: Názov: kde-format Decimals in Shares: Desatinné prevody: kde-format Initial Shares: Prebiehajúce prevody: kde-format Initial quotation: Prebiehajúce plány rozpočtu: kde-format Cash Hotovosť kde-format Current Account Aktuálny účet kde-format Credit Card Platobná karta kde-format Liabilities Dlhy kde-format Securities Akcie kde-format Initial balance: Počiatočné vyrovnanie: kde-format Default account for budgeted transactions Predvolený účet pre rozpočet kde-format Empty name. Chýba názov. kde-format The entered name is used by another account. Zadaný názov je už použitý. kde-format Monthly budget: Mesačný rozpočet: kde-format The entered name is used by another income category. Zadaný názov je už použitý v kategórií prijmov. kde-format The entered name is used by another expense category. Zadaný názov je už použitý v kategórií výdavkov. kde-format Accounts Účty kde-format Accounts & Categories Účty a kategórie kde-format Expenses Výdavky kde-format Incomes Prijmy kde-format Transfers Prevody kde-format Schedule Plánovať kde-format Scheduled Transactions Plánované transakcie kde-format Account / Category Účet / Kategória kde-format Remaining Budget (%1) Zostatok rozpočtu (%1) kde-format Change (%1) Obrat (%1) kde-format Total (%1) Spolu (%1) kde-format %2 of %1 %2 remains of %1 budget %2 z %1 kde-format Includes budgeted transactions Obsahuje prevody rozpočtu kde-format Period Obdobie kde-format Select Period Vyberte obdobie kde-format Current Month Mesačný obrat kde-format Current Year Ročný obrat kde-format Current Whole Month Obrat počas mesiaca kde-format Current Whole Year Obrat počas roka kde-format Whole Past Month Počas minulého mesiaca kde-format Whole Past Year Počas minulého roka kde-format Previous Month Predchádzajúci mesiac kde-format Previous Year Predchádzajúci rok kde-format Show partial budget Zobraz čiastkový rozpočet kde-format Edit Budget Uprav rozpočet kde-format Budget: Rozpočet: kde-format Month: Mesiac: kde-format Result previous month: Výsledok minulého mesiaca: kde-format New Security… Nová akcia… kde-format New Transaction Nový prevod kde-format Set Quotation… Nastav predbežný rozpočet… kde-format Name Názov kde-format Quotation Predbežný rozpočet kde-format Profit Zisk kde-format Yearly Rate Ročný kurz kde-format Account Účet kde-format Statistics Period Štatistické obdobie kde-format New Schedule Nový plán kde-format Edit Upraviť kde-format Next Occurrence Ďalšia udalosť kde-format Comments Poznámka kde-format New Security Nová akcia kde-format Edit Security Uprav akciu kde-format Profit: Zisk: kde-format Rate: Kurz: kde-format Are you sure you want to delete the security "%1" and all associated transactions? Ste si istý, že chceťe odstrániť akciu %1 a všetky priradené prevody? kde-format Set Quotation (%1) Nastav predbežný rozpočet (%1) kde-format Price per share: Cena na prevod: kde-format Future dates are not allowed. Budúci dátum nie je povolený. kde-format Security Transactions Prevod akcii kde-format Ledger Hlavná kniha kde-format Check Account Kontrola účtu kde-format Salary Stály plat kde-format Bills Účet kde-format Clothing Oblečenie kde-format Groceries Potraviny kde-format Leisure Voľný čas kde-format Couldn't fetch %1. nemôžem preniesť %1. kde-format Error loading %1: %2. Chyba načítania %1: %2. kde-format Couldn't open file Nemôžem otvoriť súbor kde-format Error saving %1: %2. Chyba zápisu %1: %2. kde-format Couldn't save file Nemôžem uložiť súbor kde-format Failed to upload file to %1. Chyba pri posielaní súboru do %1 kde-format Report Výkaz kde-format Chart Graf kde-format Transaction Schedule Plánovanie prevodu kde-format Accounts &amp; Categories html format Účty &amp; Kategórie kde-format Accounts &amp; Categories (%1&ndash;%2) html format Účty &amp; Kategórie (%1&ndash;%2) kde-format Accounts &amp; Categories (to %1) html format Účty &amp; Kategórie (do %1) kde-format Change Obrat kde-format Balance Vyváženosť kde-format Budget Rozpočet kde-format Remaining Budget Zostatok z rozpočtu kde-format Total Incomes Celkové prijmy kde-format Costs Náklady kde-format Total Expenses Celkové výdavky kde-format Empty expenses list. Prázdny zoznam vydavkov. kde-format Empty incomes list. Prázdny zoznam prijmov. kde-format Empty transfers list. Prázdny zoznam prevodov. kde-format Empty securities list. Prázdny zoznam akcií. kde-format Empty schedule list. Prázdny zoznam plánov. kde-format Export View… Export pohľadu… kde-format Print View… Vytlač pohľad… kde-format Import CSV File… Importuj CSV súbor… kde-format Import QIF File… Importuj QIF súbor… kde-format Export As QIF File… Exportuj ako QIF súbor… kde-format Add Account… Pridať účet… kde-format New Account… Nový účet… kde-format New Income Category… Nová kategória prijmov… kde-format New Expense Category… Nová kategória vydavkov… kde-format Balance… Vyrovnanie… kde-format Show Transactions Zobraz prevody kde-format New Transfer… Nový prevod… kde-format New Split Transaction… Nové rozdelenie prevodu… kde-format Edit Transaction(s) (Occurrence)… Uprav prevod(-y) (udalosť)… kde-format Edit Occurrence… Uprav udalosť… kde-format Edit Schedule (Recurrence)… Uprav plán (opakovananý)… kde-format Edit Schedule… Uprav plán… kde-format Remove Transaction(s) (Occurrence) Odstrániť prevod(-y) (udalosť)… kde-format Remove Occurrence Odstrániť udalosť kde-format Delete Schedule (Recurrence) Vymazať plán (opakovananý) kde-format Delete Schedule Zmazať plán kde-format Edit Split Transaction… Uprav rozdelenie prevodov… kde-format Remove Split Transaction Odstráň rozdelenie prevodov kde-format Join Transactions… Pripoj prevod… kde-format %2 of %1 %1: budget; %2: remaining budget %2 z %1 kde-format Error after saving file; data may not have been saved. Chyba po zápise do súboru; údaje sa možno nezapísali. kde-format Your names NAME OF TRANSLATORS ,Launchpad Contributions:,Roman Priesol, ,Launchpad Contributions:,Roman Priesol kde-format Your emails EMAIL OF TRANSLATORS ,,randybb@gmail.com,,,roman@priesol.net kde-format AccountComboBox New account… Nový účet… Multiple accounts/payments… New income category… Nová kategória prijmov… New expense category… Nová kategória vydavkov… Paid with loan… New Account Nový účet New Income Category Nová kategória prijmov New Expense Category Nová kategória vydavkov AccountsMenu All Accounts Všetky účty All Categories Combined %n accounts %n categories Balancing Account Balance Adjustment Budget Balancing Vyrovnanie Balancing Name of account for transactions that adjust account balances Vyrovnanie Couldn't open %1 for reading %1 sa nedá čítať Not a valid Eqonomize! file (XML parse error: "%1" at line %2, col %3) Nie je Eqonomize! súbor (chyba XML: "%1" na riadku %2, stĺpec %3) Invalid root element %1 in XML document Nesprávny koreňový prvok %1 v XML dokumente Unknown XML element: "%1" at line %2, col %3 XML parse error: "%1" at line %2, col %3 European Euro Unable to load %n currency/currencies. No exchange rates found. USD currency missing. imported Unable to load %n account(s). Unable to load %n category/categories. Unable to load %n security/securities. Financial security (e.g. stock, mutual fund) Unable to load %n transaction(s). Download command (%1) failed: %2. Failed to download file from %1: %2. Upload command (%1) failed: %2. yyyy-yy Financial year when first month is not January (e.g. 2018-19). Transaction Accounts Bežné účty Savings Accounts Sporiace účty Credit Cards Kreditné karty Debts Dlhy Securities Financial security (e.g. stock, mutual fund) Akcie Cash Hotovosť Transaction Account Bežného účtu Savings Account Sporiaci účet Credit Card Kreditná karta Debt Dlh Other Iné File is a directory Súbor je adresár Couldn't open file for writing Nemôžem otvoriť pre zápis Error while writing file; file was not saved Chyba počas zápisu; súbor nebol uložený Unnamed Uncategorized CategoriesComparisonChart Save As… Uložiť ako… Print… Tlačiť… From Od To Do Source: Zdroj: All Expenses Všetky výdavky All Incomes Všetky prijmy Theme: Chart type: Pie Chart Bar Chart Default All Expenses, without subcategories All Expenses, with subcategories All Incomes, without subcategories All Incomes, with subcategories All Accounts Všetky účty Expenses: %1 Výdavky: %1 Incomes: %1 Prijmy: %1 Error Invalid date. Nesprávny dátum. To date is before from date. Dátum do je pred dátumom od. From date is after to date. Dátum od je po dátume do. Couldn't open file for writing. Do súboru sa nedá zapisovať. Error while writing file; file was not saved. Chyba počas zápisu do súboru; súbor nebol uložený. Expenses Výdavky Expenses, %1 Výdavky, %1 Incomes, %1 Prijmy, %1 Incomes Prijmy Accounts Účty Expenses, %2: %1 Výdavky, %2: %1 Incomes, %2: %1 Prijmy, %2: %1 Other descriptions Referring to the transaction description property (transaction title/generic article name) No description Referring to the transaction description property (transaction title/generic article name) Bez popisu Other accounts Other categories %1 Value: %2 No description Referring to the Transaction description property (transaction title/generic article name) Bez popisu No description Referring to the generic description property Bez popisu Value Hodnota Income Príjem Cost Cena No description Bez popisu CategoriesComparisonChartDialog Chart Graf CategoriesComparisonReport Save As… Uložiť ako… Print… Tlačiť… Source: Zdroj: All Categories, excluding subcategories All Categories, including subcategories All Payees/Payers Všetci príjemcovia/platitelia Subcategories Descriptions for Referring to the Transaction description property (transaction title/generic article name) Popis pre All descriptions Referring to the Transaction description property (transaction title/generic article name) Všetky popisy No description Referring to the Transaction description property (transaction title/generic article name) Bez popisu All Categories Všetky kategórie Expenses: %1 Výdavky: %1 Incomes: %1 Prijmy: %1 Descriptions for Popis pre Payees/payers for Príjemca/platca pre Period: Doba: From Od To Do Columns: Stĺpce: Value Hodnota Daily Denne Monthly Mesačne Yearly Ročne Quantity Množstvo Average value Priemerná hodnota All descriptions Všetky popisy All payees Všetci príjemcovia All payers Všetci platitelia No description Bez popisu Descriptions for Referring to the generic description property Popis pre All descriptions Referring to the generic description property Všetky popisy No description Referring to the generic description property Bez popisu All Payees and Payers Všetci príjemcovia a platitelia Tag: %1 All Accounts Všetky účty Descriptions for Referring to the transaction description property (transaction title/generic article name) Popis pre Descriptions Referring to the transaction description property (transaction title/generic article name) Popis Months Mesiaca Years Roky Tags Total: All descriptions Referring to the transaction description property (transaction title/generic article name) Všetky popisy All payees/payers Všetci príjemcovia/platitelia No description Referring to the transaction description property (transaction title/generic article name) Bez popisu No payee Bez príjemcu No payer Bez platcu Error Invalid date. Nesprávny dátum. To date is before from date. Dátum do je pred dátumom od. From date is after to date. Dátum od je po dátume do. Couldn't open file for writing. Do súboru sa nedá zapisovať. Error while writing file; file was not saved. Chyba počas zápisu do súboru; súbor nebol uložený. Expenses, %2: %1 Výdavky, %2: %1 Expenses, %3: %2, %1 Výdavky, %3: %2, %1 Incomes, %2: %1 Prijmy, %2: %1 Incomes, %3: %2, %1 Prijmy, %3: %2, %1 %3: %2, %1 %2: %1 Tags, %1 Incomes & Expenses, %1 Prijmy a výdavky, %1 Expenses: %2, %1 Výdavky: %2, %1 Incomes: %2, %1 Prijmy: %2. %1 %2, %1 Incomes & Expenses Prijmy a výdavky %1 (%2&ndash;%3) html format; %1: title; %2: from date; %3: to date %1 (%2&ndash;%3) %1 (to %2) html format; %1: title; %2: to date %1 (do %2) Category Kategória Payee Description Referring to the transaction description property (transaction title/generic article name) Popis Cost Cena Payer Income Príjem Payee/Payer Tag Daily Average Denný priemer Monthly Average Mesačný priemer Yearly Average Ročný priemer Average Cost Priemerná cena Average Income Priemerný príjem Average Value Priemerná hodnota No payee/payer Bez príjemcu/platcu Total Spolu All Tags Total incomes Celkové prijmy Total expenses Celkové výdavky Total (Profits) Spolu (Zisky) CategoriesComparisonReportDialog Report Výkaz ConfirmScheduleDialog The following transactions was scheduled to occur today or before today. Confirm that they have indeed occurred (or will occur today). Nasledujúce prevody boli naplánované do dnešného dňa. Podtvrďte tie, ktoré sa vykonali. Date Dátum Type Typ Name Názov Description Popis Description Generic Description Popis Description Transaction description property (transaction title/generic article name) Popis Amount Množstvo Edit… Upraviť… Postpone… Odložiť… Delete Odstrániť Error Can only postpone to future dates. Je možné odložiť na iný dátum. ConfirmScheduleListViewItem Transfer Prevod Dividend Dividendy Income Príjem Expense Výdaj Securities Purchase Financial security (e.g. stock, mutual fund) Nákup akcií Securities Sale Financial security (e.g. stock, mutual fund) Predaj akcií Security Buy Nákup akcií Security Sell Predaj akcií Debt Payment CurrencyConversionDialog Currency Converter DebtFee Debt payment: %1 (fee) DebtInterest Debt payment: %1 (interest) DebtPayment Debt payment: %1 DebtReduction Debt payment: %1 (reduction) DescriptionsMenu All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) All Tags Combined All Payees Combined All Payers Combined All Payees/Payers Combined No description Referring to the transaction description property (transaction title/generic article name) Bez popisu No payee Bez príjemcu No payer Bez platcu No payee/payer Bez príjemcu/platcu %n descriptions Referring to the transaction description property (transaction title/generic article name) %n tags %n payees %n payers %n payees/payers EditAssetsAccountDialog Type: Typ: Cash Hotovosť Current Account Aktuálny účet Savings Account Sporiaci účet Credit Card Platobná karta Liabilities Dlhy Transactional Account Šekový účet Debt Dlh Securities Akcie Other Iné Currency: Edit Upraviť Name: Názov: Bank: Initial balance: Počiatočné vyrovnanie: Debt: Initial balance Počiatočné vyrovnanie Group: no group Transferred to: Date: Dátum: Lender: Default account for budgeted transactions Predvolený účet pre rozpočet Description: Popis: Account is closed Warning Type cannot be changed to securities for accounts with transactions. Issuer: Zero value not allowed. Nie je povolená nulová hodnota. Error Transaction Account Bežného účtu Opening balance: Account balance Počiatočný zostatok: Opening balance Account balance Počiatočný zostatok New currency… If you change the currency of an account, the currency of all associated transactions will also change, without any conversion. Do do wish to continue anyway? Empty name. Chýba názov. The entered name is used by another account. Zadaný názov je už použitý. EditCurrencyDialog Edit Currency New Currency Code: Symbol: Prefix Suffix Default Name: Názov: Decimals: Date: Dátum: Main currency Error Error saving currencies: %1. Empty code. Code already exists. EditDebtPaymentDialog Debt Payment EditDebtPaymentWidget Debt: Date: Dátum: Debt reduction: Reduction payment: Interest: Paid Added to debt Fee: Account: Účet: Expense category: Associated file: Select a file Open the file Comments: Poznámky: Related to: Label for linked transactions Odkazy: Total value: Celková hodnota: Error No suitable account available. Nevhodný účet. Invalid date. Nesprávny dátum. Interest must not be zero. At least one value must non-zero. EditExceptionsDialog Edit Exceptions Occurrences: Add Exception Remove Exception Exceptions: Only the first fifty occurrences are shown. Invalid date. Nesprávny dátum. EditExpensesAccountDialog Name: Názov: Parent category: None Monthly budget: Mesačný rozpočet: Description: Popis: Error Empty name. Chýba názov. The entered name is used by another expense category. Zadaný názov je už použitý v kategórií výdavkov. EditIncomesAccountDialog Name: Názov: Parent category: None Monthly budget: Mesačný rozpočet: Description: Popis: Error Empty name. Chýba názov. The entered name is used by another income category. Zadaný názov je už použitý v kategórií prijmov. EditLoanTransactionWidget Date: Dátum: Account: Účet: Comments: Poznámky: Total value: Celková hodnota: No suitable account available. Nevhodný účet. Invalid date. Nesprávny dátum. EditMultiAccountDialog Expense with Multiple Payments Income with Multiple Payments EditMultiAccountWidget Description: Popis: Description: Generic Description Popis: Description: Transaction description property (transaction title/generic article name) Popis: Quantity: Množstvo: Category: Kategória: Tags: Associated file: Select a file Open the file Comments: Poznámky: Related to: Label for linked transactions Odkazy: Transactions: Prevody: Date Dátum Account Účet Payee Payer Cost Cena Income Príjem Total cost: Value Hodnota New Nový Edit… Upraviť… Delete Odstrániť Total value: Celková hodnota: Error No suitable expense categories available. A split must contain at least two transactions. Pre spojenie sú potrebné dva alebo viac prevodov. EditMultiItemDialog Split Transaction Rozdeliť prevod EditMultiItemWidget Description: Popis: Description: Generic Description Popis: Date: Dátum: Account: Účet: Payee/Payer: Transactions: Prevody: Type Typ Description Generic Description Popis Description: Transaction description property (transaction title/generic article name) Popis: Tags: Associated file: Select a file Open the file Comments: Poznámky: Related to: Label for linked transactions Odkazy: Description Transaction description property (transaction title/generic article name) Popis Payment Platba Deposit Vklad Account/Category Účet/Kategória Value Hodnota Income Príjem Expense Výdaj New Nový New Expense… Nový vydavok… New Income… Nový príjem… New Deposit… Nová záloha… New Withdrawal… Nový výber… New Securities Purchase… Financial security (e.g. stock, mutual fund) Nový predaj akcií… New Securities Sale… Financial security (e.g. stock, mutual fund) Uprav predaj akcií… New Dividend… Nová dividenda… Edit… Upraviť… Delete Odstrániť Total value: Celková hodnota: Error No suitable account available. Nevhodný účet. Invalid date. Nesprávny dátum. A split must contain at least two transactions. Pre spojenie sú potrebné dva alebo viac prevodov. Cannot transfer money to and from the same account. Nemôžem preniesť peniaze na a z rovnakého účtu. EditQuotationsDialog Quotations Predbežný rozpočet Date Dátum Price per Share Prevodová cena Quotations Financial quotation Predbežný rozpočet Quotes Financial quote Ceny Price per Share Financial Shares Prevodová cena Add Pridať Modify Delete Odstrániť Import… Export… Exportovat'… Quotes for %1 Financial quote Ceny pre %1 Quotations for %1 Financial quotation Predbežný rozpočet pre %1 Quotations for %1 Predbežný rozpočet pre %1 Error Couldn't open %1 for reading. Error reading %1. Successfully imported %n quote(s). Unable to import any quotes. Failed to import %n data row(s). Required columns missing. Invalid value. Invalid date. Nesprávny dátum. No data found. Information Unrecognized date format. Specify Format The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. Date format: Value format: Couldn't open file for writing. Do súboru sa nedá zapisovať. Quotes: %1 Predbežný rozpočet: %1 Error while writing file; file was not saved. Chyba počas zápisu do súboru; súbor nebol uložený. EditRangeDialog Edit Recurrence Range Begins on: %1 No ending date End after occurrence(s) End on Error Invalid date. Nesprávny dátum. End date before start date. EditReinvestedDividendDialog Reinvested Dividend Znova investované dividendy Security: Akcii: Shares added: Podiel pridaný: Security: Financial security (e.g. stock, mutual fund) Akcii: Shares added: Financial shares Podiel pridaný: Date: Dátum: Invalid date. Nesprávny dátum. EditScheduledDebtPaymentDialog Transaction Prevod Recurrence Opakovanie Edit Debt Payment New Debt Payment EditScheduledLoanTransactionDialog Recurrence Opakovanie EditScheduledMultiAccountDialog Transactions Prevody Recurrence Opakovanie New Expense with Multiple Payments New Income with Multiple Payments Edit Expense with Multiple Payments Edit Income with Multiple Payments EditScheduledMultiItemDialog Transactions Prevody Recurrence Opakovanie New Split Transaction Nové rozdelenie prevodu Edit Split Transaction Uprav rozdelenie prevodov EditScheduledTransactionDialog Expense Výdaj Dividend Dividendy Income Príjem Reinvested Dividend Znova investované dividendy Transfer Prevod Security Buy Nákup akcií Security Sell Predaj akcií Securities Purchase Financial security (e.g. stock, mutual fund) Nákup akcií Securities Sale Financial security (e.g. stock, mutual fund) Predaj akcií Recurrence Opakovanie New Expense Nový výdavok New Expense Paid with Loan New Dividend Nová dividenda New Income Nový príjem New Transfer Nový prevod New Securities Purchase Financial security (e.g. stock, mutual fund) Nový nákup akcií New Reinvested Dividend New Securities Sale Financial security (e.g. stock, mutual fund) Nový predaj akcií Edit Reinvested Dividend Edit Securities Purchase Financial security (e.g. stock, mutual fund) Uprav nákup akcií Edit Securities Sale Financial security (e.g. stock, mutual fund) Uprav predaj akcií New Security Buy Nový nákup akcií New Security Sell Nový predaj akcií Edit Expense Uprav vydavok Edit Dividend Uprav dividend Edit Income Uprav prijem Edit Transfer Uprav tranzakciu Edit Securities Bought Uprav nákup akcií Edit Securities Sold Uprav predaj akcií EditSecurityDialog Type: Typ: Mutual Fund Investičný fond Bond Záväzok Stock Akcie Stock Financial stock Akcie Other Iné Name: Názov: Account: Účet: Decimals in shares: Financial shares Desatinné prevody: Initial shares: Financial shares Prebiehajúce prevody: Decimals in quotes: Financial quote Initial quote: Financial quote Prebiehajúce cena: Empty name. Chýba názov. No suitable account available. Nevhodný účet. Initial quotation: Financial quotation Prebiehajúce plány rozpočtu: Decimals in Shares: Desatinné prevody: Initial Shares: Prebiehajúce prevody: Initial quotation: Prebiehajúce plány rozpočtu: Date: Dátum: Description: Popis: Error EditSecurityTradeDialog Security Trade Obchod akcií From security: Z akcie: Shares moved: Podiel presunutý: All Všetky Shares received: Podiel pridaný: Securities Exchange Shares of one security directly exchanged for shares of another; Financial security (e.g. stock, mutual fund) Obchod akcií From security: Financial security (e.g. stock, mutual fund) Z akcie: Shares moved: Financial shares Podiel presunutý: To security: Financial security (e.g. stock, mutual fund) Shares received: Financial shares Podiel pridaný: Value: Hodnota: Date: Dátum: Error No other security available for exchange in the account. Shares of one security directly exchanged for shares of another; Financial security (e.g. stock, mutual fund) Selected to and from securities are the same. Financial security (e.g. stock, mutual fund) Zero shares not allowed. Financial shares Nulový prevod nie je povolený. Invalid date. Nesprávny dátum. Zero shares not allowed. Nulový prevod nie je povolený. Zero value not allowed. Nie je povolená nulová hodnota. EditSplitDialog Split Transaction Rozdeliť prevod Name: Názov: Date: Dátum: Account: Účet: Transactions: Prevody: Type Typ Name Názov Description Generic Description Popis Account/Category Účet/Kategória Description: Popis: Payment Platba Deposit Vklad New Nový New Expense… Nový vydavok… New Income… Nový príjem… New Deposit… Nová záloha… New Withdrawal… Nový výber… Edit… Upraviť… Total value: Celková hodnota: No suitable account available. Nevhodný účet. Invalid date. Nesprávny dátum. Future dates is not allowed. Budúce dátumy nie sú povolené. A split must contain at least two transactions. Pre spojenie sú potrebné dva alebo viac prevodov. Cannot transfer money to and from the same account. Nemôžem preniesť peniaze na a z rovnakého účtu Eqonomize Accounts && Categories Účty a kategórie Expenses Výdavky Incomes Prijmy Transfers Prevody Securities Akcie Schedule Plánovať Account / Category Účet / Kategória Remaining Budget (%1) Zostatok rozpočtu (%1) Change (%1) Obrat (%1) Total (%1) Spolu (%1) %2 of %1 %2 remains of %1 budget %2 z %1 Accounts Účty Includes budgeted transactions Obsahuje prevody rozpočtu Securities Financial security (e.g. stock, mutual fund) Akcie Assets Aktíva Period Obdobie From Od To Do Select Period Vyberte obdobie Current Month Mesačný obrat Current Year Ročný obrat Current Whole Month Obrat počas mesiaca Current Whole Year Obrat počas roka Whole Past Month Počas minulého mesiaca Whole Past Year Počas minulého roka Previous Month Predchádzajúci mesiac Previous Year Predchádzajúci rok Show partial budget Zobraz čiastkový rozpočet Edit Budget Uprav rozpočet Budget: Rozpočet: Month: Mesiac: Result previous month: Výsledok minulého mesiaca: New Security… Nová akcia… New Transaction Nový prevod Set Quotation… Nastav predbežný rozpočet… Name Názov Value Hodnota Shares Podiely Quotation Predbežný rozpočet Cost Cena Profit Zisk Yearly Rate Ročný kurz Type Typ Account Účet Statistics Period Štatistické obdobie New Schedule Nový plán Edit Upraviť Remove Odstránit' Next Occurrence Ďalšia udalosť Description Transaction description property (transaction title/generic article name) Popis Amount Množstvo Payee/Payer Comments Poznámka Set Schedule Confirmation Time Schedule confirmation time: Set Budget Period First day in budget month: 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 26th 27th 28th Last 2nd Last 3rd Last 4th Last 5th Last Timestamp Links Odkazy Remove Link Link to "%1" create link to transaction (link used as verb) All Všetky Import Options Ignore duplicate transactions Rename duplicate accounts Rename duplicate categories Rename duplicate securities Synchronization Settings Web address: Download command: Duplicate Transaction… duplicate as verb New Tag… Rename Tag… Remove Tag New Tag Tag name: Remove tag? Do you wish to remove the tag "%1" from %n transaction(s)? Rename Tag optional Tags First month in budget year: Right align Desno poravnajte Upload command: mandatory Automatic synchronization Upload Uploading… Error uploading file Error uploading %1: %2. Synchronizing… Error synchronizing file Error synchronizing %1: %2. Synchronization error Synchronize file? The file has been modified by a different user or program. Do you wish to merge changes? New version available A new version of %1 is available.<br><br>You can get version %2 at %3. Import %1 File… Reconcile Account… Adjust balance… Referring to account balance Close Account Mark account as closed New Expense Paid with Loan… Show payee and quantity Show quantity and payer/payee properties for incomes and expenses. Use Exchange Rate for Transaction Date Use the exchange rate nearest the transaction date, instead of the latest available rate, when converting the value of transactions. Never Language Jazyk Default Cloud Synchronization (experimental)… Help Report Bug About %1 About Qt Restart required A personal accounting program License: GNU General Public License Version 3 Crash Recovery %1 exited unexpectedly before the file was saved and data was lost. Do you want to load the last auto-saved version of the file? Eqonomize! Accounting File %f = local file (temporary), %u = url Error saving currencies: %1. Transaction Account Bežného účtu Select Font… Dark Mode Temni način Please restart the application for the language change to take effect. Save file? The current file has been modified. Do you want to save it? Confirm Schedule Adjust Account Balance Book value: of which %1 is balance adjustment Referring to account balance Real value: Only use this when unable to find the cause of the incorrect recorded account balance. Edit Account Edit Income Category Edit Expense Category Remove subcategories? Do you wish to remove the category including all subcategories? Move transactions? Move to: Remove irreversibly from all accounts (do not do this if account has been closed!) The category contains some expenses. What do you want to do with them? The category contains some incomes. What do you want to do with them? The account contains some transactions. What do you want to do with them? Remove Category? The category contains some expenses that will be removed. Do you still want to remove the category? The category contains some incomes that will be removed. Do you still want to remove the category? Remove Account? The account contains some transactions that will be removed. Do you still want to remove the account? Reopen Account Mark account as not closed Transaction Accounts Bežné účty Debts Dlhy %1 (with no budget) %1 (with budget %2) New Security Nová akcia Edit Security Uprav akciu Total value: Celková hodnota: Cost: Cena: Profit: Zisk: Rate: Kurz: Are you sure you want to delete the security "%1" and all associated transactions? Ste si istý, že chceťe odstrániť akciu %1 a všetky priradené prevody? Error Set Quotation (%1) Nastav predbežný rozpočet (%1) Price per share: Cena na prevod: Date: Dátum: Invalid date. Nesprávny dátum. Future dates are not allowed. Budúci dátum nie je povolený. Security Transactions Prevod akcii Bond Záväzok Stock Akcie Mutual Fund Investičný fond Other Iné Add Loan Add Category Ledger Hlavná kniha To date is before from date. Dátum do je pred dátumom od. From date is after to date. Dátum od je po dátume do. Cash Hotovosť Check Account Kontrola účtu Savings Account Sporiaci účet Salary Stály plat Bills Účet Clothing Oblečenie Groceries Potraviny Leisure Voľný čas Couldn't open file Nemôžem otvoriť súbor Error loading %1: %2. Chyba načítania %1: %2. Couldn't save file Nemôžem uložiť súbor Error saving %1: %2. Chyba zápisu %1: %2. Abort Failed to download exchange rates from %1: %2. Error reading data from %1: %2. Unrecognized Currency No exchange rate is available for the default currency (%1). If you wish to use multiple currencies you should set the exchange rate manually. Set Main Currency Currency: Replace all occurrences of the former main currency Transaction Schedule Plánovanie prevodu Total Spolu Accounts &amp; Categories html format Účty &amp; Kategórie Accounts &amp; Categories (%1&ndash;%2) html format Účty &amp; Kategórie (%1&ndash;%2) Accounts &amp; Categories (to %1) html format Účty &amp; Kategórie (do %1) Change Noun, how much the account balance has changed Obrat Balance Vyváženosť Current Account Aktuálny účet Credit Card Platobná karta Liabilities Dlhy New Security… Financial security (e.g. stock, mutual fund) Nová akcia… Set Quotation… Financial quotation Nastav predbežný rozpočet… Shares Financial shares Podiely Quotation Financial quotation Predbežný rozpočet New Security Financial security (e.g. stock, mutual fund) Nová akcia Edit Security Financial security (e.g. stock, mutual fund) Uprav akciu Delete security? Financial security (e.g. stock, mutual fund) Are you sure you want to delete the security "%1" and all associated transactions? Financial security (e.g. stock, mutual fund) Ste si istý, že chceťe odstrániť akciu %1 a všetky priradené prevody? Set Quotation (%1) Financial quotation Nastav predbežný rozpočet (%1) Price per share: Financial shares Cena na prevod: Security Transactions Financial security (e.g. stock, mutual fund) Prevod akcii Stock Financial stock Akcie Checking Account Transactional account Bežného účtu Balance Account balance Zostatok Category Kategória Budget Rozpočet Remaining Budget Zostatok z rozpočtu Updating exchange rates… New currency… Total Incomes Celkové prijmy Costs Náklady Total Expenses Celkové výdavky Account/Category Noun, how much the account balance has changed Účet/Kategória Empty expenses list. Prázdny zoznam vydavkov. Empty incomes list. Prázdny zoznam prijmov. Empty transfers list. Prázdny zoznam prevodov. Empty securities list. Prázdny zoznam akcií. Empty schedule list. Prázdny zoznam plánov. Couldn't open file for writing. Do súboru sa nedá zapisovať. Error while writing file; file was not saved. Chyba počas zápisu do súboru; súbor nebol uložený. &File &Súbor &Accounts &Účty &Transactions &Prevody Stat&istics Š&tatisticka S&ettings &Nastavenie &Help &Pomocník File Súbor Transactions Prevody Statistics Štatisticka &New &Nový &Open… &Otvorit'… Open Recent Otvorit' nedávne Clear List Vyčistit' zoznam &Save &Uložiť Save As… Uložiť ako… &Revert &Znovu nahrat' S&ynchronize &Print… &Tlačiť… Print Preview… Náh'lad tlače… Import Importovat' Import CSV File… Importuj CSV súbor… Import QIF File… Importuj QIF súbor… Export View… Export pohľadu… Export As QIF File… Exportuj ako QIF súbor… Update Exchange Rates Currency Converter &Quit &Koniec Add Account… Pridať účet… New Account… Nový účet… New Loan… New Income Category… Nová kategória prijmov… New Expense Category… Nová kategória vydavkov… Add Account Pridať účet Security Transactions Financial security (e.g. stock, bond) Prevod akcii &Loans &Pôžičky &Securities Financial security (e.g. stock, mutual fund) &Akcie Edit… Upraviť… Balance… Vyrovnanie… Balance… Verb. Balance an account Vyrovnanie… Show Transactions Zobraz prevody Show Ledger New Expense… Nový vydavok… New Income… Nový príjem… New Transfer… Nový prevod… New Split Transaction… Nové rozdelenie prevodu… New Expense with Multiple Payments… Refund… Vrátenie… Repayment… Splatenie… New Refund/Repayment… Edit Transaction(s) (Occurrence)… Uprav prevod(-y) (udalosť)… Edit Occurrence… Uprav udalosť… Edit Schedule (Recurrence)… Uprav plán (opakovananý)… Edit Schedule… Uprav plán… Edit Split Transaction… Uprav rozdelenie prevodov… Join Transactions… join transactions together Pripoj prevod… Split Up Transaction split up joined transactions Edit Timestamp… Select Associated File Create Link create link to or between transaction(s) Open Associated File Remove Transaction(s) (Occurrence) Odstrániť prevod(-y) (udalosť) Remove Occurrence Odstrániť udalosť Delete Schedule (Recurrence) Vymazať plán (opakovananý) Delete Schedule Zmazať plán Remove Split Transaction Odstráň rozdelenie prevodov New Debt Payment… New Unpaid Interest… Remove Security Financial security (e.g. stock, mutual fund) Shares Exchanged… Shares of one security directly exchanged for shares of another; Financial shares Shares of one security directly exchanged for shares of another Financial shares Dividend… Dividendy… Reinvested Dividend… Znova investované dividendy… Transactions… Prevody… Edit Quotes… Financial quote Uprav ceny… Development Over Time Report… Categories Comparison Report… Development Over Time Chart… Categories Comparison Chart… Set Main Currency… Set Budget Period… Initial Period Remember Last Dates Set Schedule Confirmation Time… Backup Frequency Daily Denne Weekly Fortnightly Monthly Mesačne Untitled Description Generic Description Popis New Account Nový účet New Loan New Income Category Nová kategória prijmov New Expense Category Nová kategória vydavkov %2 of %1 %1: budget; %2: remaining budget %2 z %1 Set Quote… Financial quote Nastav cena… Quote Financial quote Cena Set Quote (%1) Financial quote Nastav cena (%1) Balance Noun. Balance of an account Zostatok Empty securities list. Financial security (e.g. stock, mutual fund) Prázdny zoznam akcií. Balance… Balance account Vyrovnanie… Edit Security… Financial security (e.g. stock, mutual fund) Uprav akciu… Shares Bought… Financial shares Nákup podielov… Shares Sold… Financial shares Predaj podielov… EqonomizeCalendarWidget Today Dnes EqonomizeDateEdit Today Dnes EqonomizeTranslator OK Only used when Qt translation is missing Cancel Only used when Qt translation is missing Zrušiť Close Only used when Qt translation is missing Zatvoriť &Yes Only used when Qt translation is missing Án&o &No Only used when Qt translation is missing &Nie &Open Only used when Qt translation is missing &Save Only used when Qt translation is missing &Uložiť &Select All Only used when Qt translation is missing Look in: Only used when Qt translation is missing File &name: Only used when Qt translation is missing Files of type: Only used when Qt translation is missing EqonomizeValueEdit Error Empty denominator. Empty factor. Division by zero. Unknown or ambiguous currency, or unrecognized characters, in expression: %1. Empty base. Empty exponent. Unrecognized characters in expression. ExportQIFDialog Export QIF File Account: Účet: All All accounts Všetky Date format: Value format: File: Error Selected file is a directory. Overwrite The selected file already exists. Would you like to overwrite the old copy? Vybraný súbor už existuje. Prajete si ho prepísať? You selected a directory! Vybrali ste adresár. Couldn't open file for writing. Do súboru sa nedá zapisovať. Error while writing file; file was not saved. Chyba počas zápisu do súboru; súbor nebol uložený. ImportCSVDialog Import CSV file Transaction Type Selection Expenses Výdavky Incomes Prijmy Transfers Prevody Expenses and incomes (negative cost) Expenses and incomes (separate columns) All types Presets: File Selection File: First data row: Auto Column delimiter: Comma Tabulator Semicolon Space Other Iné Columns Specification Description: Popis: Description: Transaction description property (transaction title/generic article name) Popis: Column Value Hodnota Cost: Cena: Date: Dátum: Category: Kategória: From account: Quantity: Množstvo: Payee: Tags: Comments: Poznámky: Create missing categories and accounts Save as preset… Save Preset Imports data as expenses. Costs have positive value. Value is the only required column. Imports data as incomes. Value is the only required column. Income: Príjem: To account: Payer: Imports data as transfers. Value is the only required column. Amount: Množstvo: Value: Hodnota: Account: Účet: Payee/payer: Imports data as expenses, incomes, and transfers. Costs have negative or positive value. Value, to, and from are all required columns. Accounts and categories must be existing. From: Od: To: Do: Error A file must be selected. Selected file is a directory. Selected file does not exist. Empty delimiter. The same column number is selected multiple times. Do you wish to proceed anyway? Imports data as expenses and incomes. Costs have negative value. Value is the only required column. Imports data as expenses and incomes. Costs and incomes have separate columns. Income and cost both all required columns. Warning Selected from account is the same as the to account. Invalid date. Nesprávny dátum. Couldn't open %1 for reading. Error reading %1. Uncategorized Successfully imported %n transaction(s). Unable to import any transactions. Failed to import %n data row(s). Required columns missing. Invalid value. Empty category name. Empty account name. Unknown category found. Unknown account found. Cannot import security transactions (to/from security accounts). Balancing account wrongly used. Referring to the account used for adjustments of account balances. Same to and from account/category. No data found. Information Unrecognized date format. Specify Format The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. Date format: Value format: ImportQIFDialog Import QIF file File Selection Select a QIF file to import. When you click next, the file be analysed and you might need to answer some questions about the format of the file. File: Local Definitions Unknown elements where found in the QIF file. It is possible that this is because of localized type names. Please map them to the correct standard names. Local Text Standard Text Select standard text: Date Format The date format in the QIF file is ambiguous. Please select the correct format. Date format: Default Account Could not find any account definitions in the QIF file. Please select a default account. It is also possible that this is caused by a localized opening balance text. Default account: Opening balance text: Description Popis Category Kategória Comments Poznámka Import File No (further) issues were found. Press finish to import the selected QIF file. Ignore duplicate transactions Error A file must be selected. Selected file is a directory. Selected file does not exist. Couldn't open %1 for reading. Error reading %1. Unknown Account Účet Bank Cash Hotovosť Cat (Category) CCard (Credit Card) Invst (Investment) Oth A (Other Assets) Oth L (Other Liabilities) Security Other Iné Unrecognized date format. Successfully imported %n transaction(s). Successfully imported %n account(s). Successfully imported %n category/categories. %n duplicate transaction(s) was ignored. Failed to import %n transaction(s). %n security/securities were not imported. Financial security (e.g. stock, mutual fund) %n security transaction(s) were not imported. Financial security (e.g. stock, mutual fund) Information Income Dividend: %1 Reinvested dividend: %1 Znova investované dividendy: %1 LedgerDialog Account: Účet: Export… Exportovat'… Print… Tlačiť… Reconcile Accounting context Change: Accounting context Obrat: Date Dátum Type Typ Name Názov Description Generic Description Popis Account/Category Účet/Kategória Deposit Vklad Withdrawal Výber Balance Vyváženosť New Nový Edit… Upraviť… Delete Odstrániť Join… join transactions together Split Up split up joined transactions Reconciled: %1 (%2) Accounting context Error Invalid date. Nesprávny dátum. Opening date is after closing date. Closing date is before opening date. Empty transaction list. Couldn't open file for writing. Do súboru sa nedá zapisovať. Error while writing file; file was not saved. Chyba počas zápisu do súboru; súbor nebol uložený. Ledger Hlavná kniha Transactions for %1 Prevody pre %1 Select Time Period From: Od: To: Do: To date is before from date. Dátum do je pred dátumom od. Balance change: Account balance Delete transactions? Are you sure you want to delete all (%1) selected transactions? Opening balance Account balance Počiatočný zostatok Account Balance Adjustment Current balance: Account balance Average balance: Account balance Balancing Balancing of an account Vyrovnanie Balancing Account balancing Vyrovnanie Current debt: Total debt reduction: Total interest and fees: Number of transactions: Initial balance Počiatočné vyrovnanie Description Transaction description property (transaction title/generic article name) Popis Balance Account balance Zostatok Cannot set the value of security transactions using the dialog for modifying multiple transactions. Financial security (e.g. stock, mutual fund) Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name); Financial security (e.g. stock, mutual fund) Cannot change payer of dividends and security transactions. Financial security (e.g. stock, mutual fund) Split Transaction Rozdeliť prevod Debt Payment Reduction Fee Interest Income Príjem Repayment Splatenie Expense Výdaj Edit Account… Mark all as reconciled Accounting context Opening balance: Accounting context Počiatočný zostatok: Closing balance: Accounting context R Header for account reconciled checkbox column Payee/Payer Tags Comments Poznámka Deposit Money put into account Vklad Withdrawal Money taken out from account Výber Balance Noun. Balance of an account Zostatok Edit Transaction(s)… Uprav prevod(-y)… Join Transactions… Pripoj prevod… Remove Transaction(s) Odstrániť prevod(-y) Mark as reconciled Book value: %1 (%2) Accounting context Ascending order Refund Vrátenie Balancing Vyrovnanie Transfer Prevod LinksWidget Remove Link All Všetky Remove Odstránit' MultiItemListViewItem Dividend Dividendy Income Príjem Repayment Splatenie Expense Výdaj Refund Vrátenie Securities Purchase Financial security (e.g. stock, mutual fund) Nákup akcií Securities Sale Financial security (e.g. stock, mutual fund) Predaj akcií Account Balance Adjustment Balancing Balancing of an account Vyrovnanie Security Buy Nákup akcií Security Sell Predaj akcií Balancing Vyrovnanie Transfer Prevod MultipleTransactionsEditDialog Modify Transactions Name: Názov: Description: Transaction description property (transaction title/generic article name) Popis: Amount: Množstvo: Income: Príjem: Cost: Cena: Date: Dátum: Category: Kategória: Payer: Payee: New Income Category… Nová kategória prijmov… New Expense Category… Nová kategória vydavkov… Error No income category available. No expense category available. Invalid date. Nesprávny dátum. OverTimeChart Save As… Uložiť ako… Print… Tlačiť… Source: Zdroj: Incomes and Expenses Prijmy a výdavky Profits Zisky Expenses Výdavky Incomes Prijmy No description Referring to the Transaction description property (transaction title/generic article name) Bez popisu Assets Aktíva All Categories Combined Assets and Liabilities All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) All Payees/Payers Combined All Accounts Všetky účty Start date: End date: Value: Hodnota: Annual total Monthly total Daily average Quantity Množstvo Average value Priemerná hodnota All Payers Combined All Payees Combined All Subcategories Split No description Referring to the generic description property Bez popisu Value Hodnota Includes budgeted transactions Obsahuje prevody rozpočtu Profits, %1 Zisky, %1 Incomes & Expenses Prijmy a výdavky Incomes: %1 Prijmy: %1 Expenses: %1 Výdavky: %1 Incomes: %2, %1 Prijmy: %2. %1 Expenses: %2, %1 Výdavky: %2, %1 Incomes: %3, %2, %1 Prijmy: %3, %2. %1 Expenses: %3, %2, %1 Výdavky: %3, %2, %1 %1 Value: %2 Date: %3 MMMM yyyy Month and year All Payers Split Theme: All Payees Split No description Bez popisu No payer Bez platcu No payee Bez príjemcu No payee/payer Bez príjemcu/platcu All Categories Split All Tags Split Error Invalid date. Nesprávny dátum. Couldn't open file for writing. Do súboru sa nedá zapisovať. Error while writing file; file was not saved. Chyba počas zápisu do súboru; súbor nebol uložený. Other tags Other payees Other payers Other payees/payers Daily average value Daily average profit Daily average income Daily average cost Average income Average cost Annual value Annual profit Annual income Annual cost Monthly value Monthly profit Monthly income Monthly cost Includes scheduled and budgeted transactions Includes scheduled transactions Tags, %1 Value: %1 Hodnota: %1 Assets & Liabilities Change: %1 Obrat: %1 Excluding any profits or losses in trading of security shares Financial security (e.g. stock, mutual fund) Incomes & Expenses, %1 Prijmy a výdavky, %1 Incomes, %1 Prijmy, %1 Expenses, %1 Výdavky, %1 Incomes, %2: %1 Prijmy, %2: %1 Expenses, %2: %1 Výdavky, %2: %1 Incomes, %3: %2, %1 Prijmy, %3: %2 %1 Expenses, %3: %2, %1 Výdavky, %3: %2, %1 Incomes, %4: %3, %2, %1 Prijmy, %4: %3, %2, %1 Expenses, %4: %3, %2, %1 Výdavky, %4: %3, %2, %1 Liabilities Dlhy %1/%2 %1: Description; %2: Payee/Payer Other accounts Time %1/%2 %1: Category; %2: Payee/Payer Chart type: Line Chart Vertical Bar Chart Horizontal Bar Chart Stacked Bar Chart Default Tags All Accounts Combined All Accounts Split All Subcategories and Descriptions Combined Referring to the transaction description property (transaction title/generic article name) All Descriptions Split Referring to the transaction description property (transaction title/generic article name) No description Referring to the transaction description property (transaction title/generic article name) Bez popisu All Payees/Payers Split Other descriptions Referring to the transaction description property (transaction title/generic article name) Incomes − Expenses, %1 Prijmy − výdavky, %1 Incomes − Expenses Prijmy − výdavky %2: %1 %3: %2, %1 %2, %1 %4: %3, %2, %1 no payee/payer bez príjemcu/platcu %3, %2, %1 no payer bez platcu no payee bez príjemcu OverTimeChartDialog Chart Graf OverTimeReport Save As… Uložiť ako… Print… Tlačiť… Source: Zdroj: Profits Zisky Expenses Výdavky Incomes Prijmy Assets & Liabilities Tags All Accounts Všetky účty Columns: Stĺpce: Categories Total: Value Hodnota Daily Denne Monthly Mesačne Yearly Ročne Quantity Množstvo Average value Priemerná hodnota No description Bez popisu No description Referring to the generic description property Bez popisu No description Referring to the transaction description property (transaction title/generic article name) Bez popisu Error Couldn't open file for writing. Do súboru sa nedá zapisovať. Error while writing file; file was not saved. Chyba počas zápisu do súboru; súbor nebol uložený. Deposit Money put into account Vklad Withdrawal Money taken out from account Výber Incomes, %1 Prijmy, %1 Average Income Priemerný príjem Expenses, %1 Výdavky, %1 Average Cost Priemerná cena Incomes, %2: %1 Prijmy, %2: %1 Incomes: %1 Prijmy: %1 Expenses, %2: %1 Výdavky, %2: %1 Expenses: %1 Výdavky: %1 Incomes, %3: %2, %1 Prijmy, %3: %2, %1 Incomes: %2, %1 Prijmy: %2. %1 Expenses, %3: %2, %1 Výdavky, %3: %2, %1 Expenses: %2, %1 Výdavky: %2, %1 Change: %1 Noun, how much the account balance has changed Obrat: %1 Change Noun, how much the account balance has changed Obrat Value: %1 Hodnota: %1 %2: %1 Average Value Priemerná hodnota %3: %2, %1 %2, %1 Year Month Assets Aktíva Deposit Vklad Withdrawal Výber Liabilities Dlhy Daily Average Denný priemer Monthly Average Mesačný priemer Yearly Average Ročný priemer Subtotal Total Spolu Includes scheduled transactions Adjusted for the average month / year (%1 / %2 days) OverTimeReportDialog Report Výkaz QApplication Start with expenses list displayed Start with incomes list displayed Start with transfers list displayed Synchronize file Document to open %1 is already running. QObject Transfer Prevod Dividend Dividendy Income Príjem Expense Výdaj Securities Purchase Financial security (e.g. stock, mutual fund) Nákup akcií Securities Sale Financial security (e.g. stock, mutual fund) Predaj akcií Security Buy Nákup akcií Security Sell Predaj akcií Debt Payment Split Transaction Rozdeliť prevod RecurrenceEditWidget Enable recurrence Recurrence Rule Daily Denne Weekly Monthly Mesačne Yearly Ročne Recur every day(s) week(s) on: month(s), after the start month Recur on the 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 26th 27th 28th 29th 30th 31st Last 2nd Last 3rd Last 4th Last 5th Last day possibly on weekend but before weekend but after weekend nearest weekend day year(s), after the start year on nearest weekday Recur on day part before XXX of 'Recur on day XXX of month YYY' of part between XXX and YYY of 'Recur on day XXX of month YYY' On the Part before NNN in 'Recur on the NNN. WEEKDAY of MONTH' of part between WEEKDAY and MONTH in 'Recur on NNN. WEEKDAY of MONTH' Recur on day # of the year part after NNN of 'Recur on day #NNN of the year' Range… Occurrences/Exceptions… Error No day of week selected for weekly recurrence. Selected day will never occur with selected frequency and start date. Selected day does not exist in selected month. RefundDialog Repayment Splatenie Refund Vrátenie Date: Dátum: Cost: Cena: Income: Príjem: Quantity returned: Množstvo: Account: Účet: Quantity: Množstvo: Payee: Payer: Comments: Poznámky: Link Link the transactions together Join Join the transactions together Pripoj Error Zero value not allowed. Nie je povolená nulová hodnota. Invalid date. Nesprávny dátum. SecurityBuy Security: %1 (bought) Financial security (e.g. stock, mutual fund) SecuritySell Security: %1 (sold) Financial security (e.g. stock, mutual fund) SecurityTransactionsDialog Transactions for %1 Prevody pre %1 Date Dátum Type Typ Value Hodnota Shares Financial shares Podiely Shares Bought Financial shares Nákup podielov Shares Bought (Recurring) Financial shares Nákup podielov (opakované) Dividend (Recurring) Dividendy (opakované) Dividend (Scheduled) Dividendy (plánované) Reinvested Dividend (Recurring) Znova investované dividendy (opakované) Reinvested Dividend (Scheduled) Znova investované dividendy (plánované) Shares Bought Fincancial shares Nákup podielov Shares Sold Financial shares Predaj podielov Shares Sold (Exchanged) Shares of one security directly exchanged for shares of another; Financial shares Predaj podielov (uskutočnený) Shares Bought (Exchanged) Shares of one security directly exchanged for shares of another; Financial shares Nákup podielov (uskutočnený) Shares Bought (Recurring) Fincancial shares Nákup podielov (opakované) Shares Sold (Recurring) Financial shares Predaj podielov (opakované) Shares Bought (Scheduled) Financial shares Nákup podielov (plánované) Shares Sold (Scheduled) Financial shares Predaj podielov (plánované) Shares Podiely Edit… Upraviť… Delete Odstrániť Shares Bought Nákup podielov Shares Sold Predaj podielov Dividend Dividendy Reinvested Dividend Znova investované dividendy Shares Sold (Traded) Predaj podielov (uskutočnený) Shares Bought (Traded) Nákup podielov (uskutočnený) Shares Bought (Recurring) Nákup podielov (opakované) Shares Sold (Recurring) Predaj podielov (opakované) Shares Bought (Scheduled) Nákup podielov (plánované) Shares Sold (Scheduled) Predaj podielov (plánované) Recurring Dividend Pravidelné dividendy Scheduled Dividend Plánované divodendy SplitListViewItem Dividend Dividendy Income Príjem Repayment Splatenie Expense Výdaj Refund Vrátenie Security Buy Nákup akcií Security Sell Predaj akcií Balancing Vyrovnanie Transfer Prevod TagButton no tags TagMenu New tag… New Tag Tag: TransactionEditDialog Edit Expense Uprav vydavok Edit Dividend Uprav dividend Edit Income Uprav prijem Edit Transfer Uprav tranzakciu Edit Securities Purchase Financial security (e.g. stock, mutual fund) Uprav nákup akcií Edit Securities Sale Financial security (e.g. stock, mutual fund) Uprav predaj akcií Edit Reinvested Dividend Edit Securities Bought Uprav nákup akcií Edit Securities Sold Uprav predaj akcií TransactionEditWidget Security: Akcii: Cost: Cena: Income: Príjem: All Všetky Price per share: Cena na prevod: Date: Dátum: Name: Názov: Description: Popis: Amount: Množstvo: Downpayment: Quantity: Množstvo: From: Od: To: Do: Category: Kategória: To account: Payer: From account: Downpayment account: Payee: Lender: Comments: Poznámky: No security available. Financial security (e.g. stock, mutual fund) New Account… Nový účet… New Income Category… Nová kategória prijmov… New Expense Category… Nová kategória vydavkov… Security: Financial security (e.g. stock, mutual fund) Akcii: New Security… Financial security (e.g. stock, mutual fund) Nová akcia… Shares added: Financial shares Podiel pridaný: Shares bought: Financial shares Nákup podielov: Shares sold: Financial shares Predaj podielov: Price per share: Financial shares Cena na prevod: Set security share value Total value: Celková hodnota: Description: Transaction description property (transaction title/generic article name) Popis: Transaction title/generic article name Withdrawal: Money taken out from account Výber: Deposit: Money put into account Vklad: Number of items included in the transaction. Entered cost is total cost for all items. Payer of parent split transaction Payee of parent split transaction Tags: Associated file: Select a file Open the file Related to: Label for linked transactions Odkazy: New Security Financial security (e.g. stock, mutual fund) Nová akcia Error No suitable account available. Nevhodný účet. No income category available. No suitable account or income category available. No expense category available. Invalid date. Nesprávny dátum. Cannot transfer money to and from the same account. Nemôžem preniesť peniaze na a z rovnakého účtu. Downpayment must be less than total cost. Cannot create a regular transfer to/from a securities account. Cannot create a regular income to a securities account. Zero shares not allowed. Nulový prevod nie je povolený. Zero value not allowed. Nie je povolená nulová hodnota. Zero price per share not allowed. Cannot create a regular expense from a securities account. Loan for %1 TransactionFilterWidget From: Od: To: Do: Min amount: Max amount: Category: Kategória: To account: Min income: Max income: From account: Min cost: Max cost: Tag: Description: Popis: Description: Transaction description property (transaction title/generic article name) Popis: Include Exclude Exact match Exclude subcategories Clear Vyčistit' All Všetky Error Invalid date. Nesprávny dátum. To date is before from date. Dátum do je pred dátumom od. From date is after to date. Dátum od je po dátume do. TransactionListWidget Date Dátum Name Názov Description Generic Description Popis Description Transaction description property (transaction title/generic article name) Popis Cost Cena Category Kategória From Account Payee Tags Income Príjem To Account Payer Amount Množstvo From Od To Do Comments Poznámka Add Pridat' Apply Použiť Delete Odstrániť New/Edit Expense New/Edit Income New/Edit Transfer Filter Quantity: Množstvo: Total: Cannot change date of transactions that are part of a split transaction, unless all individual transactions are selected. * Part of <a href="%1">split transaction</a> * Part of split (%1) Average: Clear Vyčistit' Cost: Cena: Monthly: Sort by creation time Expenses Výdavky Incomes Prijmy Transfers Prevody Quantity Množstvo Right align Desno poravnajte Total cost: Total income: Total amount: Monthly average: Error Cannot set the value of security transactions using the dialog for modifying multiple transactions. Financial security (e.g. stock, mutual fund) Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name); Financial security (e.g. stock, mutual fund) Cannot change payer of dividends and security transactions. Financial security (e.g. stock, mutual fund) Cannot change date, description, expense category or payee of transactions that are part of a debt payment using the dialog for modifying multiple transactions. Referring to the transaction description property (transaction title/generic article name) Delete transactions? Are you sure you want to delete all (%1) transactions in the selected split transaction? Join as multiple accounts/payments? Do you wish join the selected expenses as an expense with multiple accounts/payments? Do you wish join the selected incomes as an income with multiple accounts/payments? Are you sure you want to delete all (%1) selected transactions? ** Recurring (editing occurrence) Modify… Edit… Upraviť… Eqonomize-1.5.3/translations/eqonomize_sv.ts000066400000000000000000013553641416454732000213240ustar00rootroot00000000000000 AccountComboBox New account… Nytt konto… Paid with loan… Betalad med lån… Multiple accounts/payments… Flera konton/betalningar… New income category… Ny inkomstkategori… New expense category… Ny utgiftskategori… New Account Nytt konto New Income Category Ny inkomstkategori New Expense Category Ny utgiftskategori AccountsMenu All Accounts Alla konton All Categories Combined Alla kategorier kombinerade %n accounts %n konto %n konton %n categories %n kategori %n kategorier Balancing Account Balance Adjustment Justering av kontosaldo Budget Balancing Name of account for transactions that adjust account balances Balanskonto Couldn't open %1 for reading Kunde inte öppna och läsa %1 No exchange rates found in the downloaded ECB data. Inga växelkurser hittades i den nedladdade ECB-data. Not a valid Eqonomize! file (XML parse error: "%1" at line %2, col %3) Inte en korrekt Eqonomize!-fil (XML-fel: "%1" vid rad %2, kolumn %3) imported importerad Invalid root element %1 in XML document Felaktigt rotelement %1 i XML-dokumentet Unknown XML element: "%1" at line %2, col %3 Okänt XML-element: "%1" på rad %2, kolumn %3 XML parse error: "%1" at line %2, col %3 XML-tolkningsfel: "%1" på rad %2, kolumn %3 Unable to load %n currency/currencies. Kunde inte läsa in %n valuta. Kunde inte läsa in %n valutor. No exchange rates found in downloaded ECB data Inga växelkurser hittades i nedladdad ECB-data Unable to load %n account(s). Kunde inte läsa in %n konto. Kunde inte läsa in %n konton. Unable to load %n category/categories. Kunde inte läsa in %n kategori. Kunde inte läsa in %n kategorier. Unable to load %n security/securities. Financial security (e.g. stock, mutual fund) Kunde inte läsa in %n värdepapper. Kunde inte läsa in %n värdepapper. Unable to load %n transaction(s). Kunde inte läsa in %n transaktion. Kunde inte läsa in %n transaktioner. File is a directory Filen är en mapp European Euro Europeisk euro No exchange rates found. Inga växelkurser hittades. USD currency missing. USD-valuta saknas. Couldn't open file for writing Kunde öppna och skriva till filen Error while writing file; file was not saved Fil vid skrivande till fil; filen sparades inte Download command (%1) failed: %2. Nedladdningskommando (%1) misslyckades: %2. Failed to download file from %1: %2. Misslyckades med att ladda ned fil från %1: %2. Upload command (%1) failed: %2. Uppladdningskommando (%1) misslyckades: %2. yyyy-yy Financial year when first month is not January (e.g. 2018-19). yyyy/yyyy Transaction Accounts Transaktionskonton Savings Accounts Sparkonton Credit Cards Kreditkort Debts Skulder Securities Financial security (e.g. stock, mutual fund) Värdepapper Cash Kontanter Transaction Account Transaktionskonto Savings Account Sparkonto Credit Card Kreditkort Debt Skuld Other Annat Unnamed Namnlöst Uncategorized Okategoriserade CategoriesComparisonChart Save As… Spara som… Print… Skriv ut… From Från To Till Source: Källa: Theme: Tema: Chart type: Diagramtyp: Pie Chart Cirkeldiagram Vertical Bar Chart Vertikalt stapeldiagram Horizontal Bar Chart Horisontellt stapeldiagram Bar Chart Stapeldiagram Default Standard All Expenses, without subcategories Alla utgifter, utan underkategorier All Expenses, with subcategories Alla utgifter, med underkategorier All Incomes, without subcategories Alla inkomster, utan underkategorier All Incomes, with subcategories Alla inkomster, med underkategorier All Accounts Alla konton Expenses: %1 Utgifter: %1 Incomes: %1 Inkomster: %1 Error Fel Invalid date. Felaktigt datum. To date is before from date. Slutdatum är före startdatum. From date is after to date. Startdatum är efter slutdatum. Couldn't open file for writing. Kunde inte öppna och skriva till filen. Error while writing file; file was not saved. Fel vid skrivande av fil; filen sparades inte. Expenses Utgifter Expenses, %1 Utgifter, %1 Incomes, %1 Inkomster, %1 Incomes Inkomster Accounts Konton Expenses, %2: %1 Utgifter, %2: %1 Incomes, %2: %1 Inkomster, %2: %1 Other descriptions Referring to the transaction description property (transaction title/generic article name) Andra benämningar No description Referring to the transaction description property (transaction title/generic article name) Ingen benämning Other accounts Övriga konton Other categories Övriga kategorier Value Värde Income Inkomst Cost Kostnad %1 Value: %2 %1 Värde: %2 CategoriesComparisonChartDialog Chart Diagram CategoriesComparisonReport Save As… Spara som… Print… Skriv ut… Source: Källa: All Categories, excluding subcategories Alla kategorier, exklusive underkategorier All Categories, including subcategories Alla kategorier, inclusive underkategorier All Tags Alla etiketter All Payees and Payers Alla mottagare och utbetalare Subcategories Underkategorier All Categories Alla kategorier Expenses: %1 Utgifter: %1 Incomes: %1 Inkomster: %1 Tag: %1 Etikett: %1 All Accounts Alla konton Payees/payers for Mottagare/utbetalare för Period: Period: From Från To Till Columns: Kolumner: Value Värde Daily Dagligen Monthly Månadsvis Yearly Årligen Quantity Kvantitet Average value Genomsnittligt värde All payees Alla mottagare All payers Alla utbetalare Descriptions for Referring to the transaction description property (transaction title/generic article name) Benämningar för All Payees/Payers Alla mottagare/utbetalare Descriptions Referring to the transaction description property (transaction title/generic article name) Benämningar Months Månader Years År Tags Etiketter Total: Totalt: All descriptions Referring to the transaction description property (transaction title/generic article name) Alla benämningar All payees/payers Alla mottagare/utbetalare No description Referring to the transaction description property (transaction title/generic article name) Ingen benämning No payee Ingen mottagare No payer Ingen utbetalare Error Fel Invalid date. Felaktigt datum. To date is before from date. Slutdatum är före startdatum. From date is after to date. Startdatum är efter slutdatum. Couldn't open file for writing. Kunde inte öppna och skriva till filen. Error while writing file; file was not saved. Fel vid skrivande av fil; filen sparades inte. Expenses, %2: %1 Utgifter, %2: %1 Expenses, %3: %2, %1 Utgifter, %3: %2, %1 Incomes, %2: %1 Inkomster, %2: %1 Incomes, %3: %2, %1 Inkomster, %3: %2, %1 %3: %2, %1 %3: %2, %1 %2: %1 %2: %1 Tags, %1 Etiketter, %1 Incomes & Expenses, %1 Inkomster och utgifter, %1 Expenses: %2, %1 Utgifter: %2, %1 Incomes: %2, %1 Inkomster: %2, %1 %2, %1 %2, %1 %1 %1 Incomes & Expenses Inkomster och utgifter %1 (%2&ndash;%3) html format; %1: title; %2: from date; %3: to date %1 (%2 &ndash; %3) %1 (to %2) html format; %1: title; %2: to date %1 (till %2) Category Kategori Payee Mottagare Description Referring to the transaction description property (transaction title/generic article name) Benämning Cost Kostnad Payer Utbetalare Income Inkomst Payee/Payer Mottagare/utbetalare Tag Etikett Daily Average Dagligt genomsnitt Monthly Average Månatligt genomsnitt Yearly Average Årligt genomsnitt Average Cost Genomsnittlig kostnad Average Income Genomsnittlig inkomst Average Value Genomsnittligt värde No payee/payer Ingen mottagare/utbetalare Total Summa Total incomes Totalt inkomster Total expenses Totalt utgifter Total (Profits) Totalt (Förtjänster) CategoriesComparisonReportDialog Report Rapport ConfirmScheduleDialog The following transactions was scheduled to occur today or before today. Confirm that they have indeed occurred (or will occur today). Följande transaktioner var planerade att infalla idag eller tidigare. Bekräfta att de faktiskt genomfördes (eller kommer att genomföras idag). Date Datum Type Typ Description Transaction description property (transaction title/generic article name) Benämning Amount Värde Edit… Redigera… Postpone… Senarelägg… Delete Ta bort Error Fel Can only postpone to future dates. Kan enbart senarelägga till framtida datum. ConfirmScheduleListViewItem Transfer Överföring Dividend Utdelning Income Inkomst Expense Utgift Securities Purchase Financial security (e.g. stock, mutual fund) Värdepappersköp Securities Sale Financial security (e.g. stock, mutual fund) Värdepappersförsäljning Debt Payment Skuldbetalning CurrencyConversionDialog Currency Converter Valutaomvandlare DebtFee Debt payment: %1 (fee) Skuldbetalning: %1 (avgift) DebtInterest Debt payment: %1 (interest) Skuldbetalning: %1 (ränta) DebtPayment Debt payment: %1 Skuldbetalning: %1 DebtReduction Debt payment: %1 (reduction) Skuldbetalning: %1 (skuldminskning) DescriptionsMenu All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Alla benämningar kombinerade All Tags Combined All etiketter kombinerade All Payees Combined Alla mottagare kombinerade All Payers Combined Alla utbetalare kombinerade All Payees/Payers Combined Alla mottagare/utbetalare kombinerade No description Referring to the transaction description property (transaction title/generic article name) Ingen benämning No payee Ingen mottagare No payer Ingen utbetalare No payee/payer Ingen mottagare/utbetalare %n descriptions Referring to the transaction description property (transaction title/generic article name) %n benämning %n benämningar %n tags %n etikett %n etiketter %n payees %n mottagare %n mottagare %n payers %n utbetalare %n utbetalare %n payees/payers %n mottagare/utbetalare %n mottagare/utbetalare EditAssetsAccountDialog Type: Typ: Cash Kontanter Savings Account Sparkonto Credit Card Kreditkort Transactional Account Transaktionskonto Debt Skuld Securities Värdepapper Other Annat Group: Grupp: no group ingen grupp Currency: Valuta: Edit Redigera Name: Namn: Bank: Bank: Debt: Skuld: Transferred to: Överfört till: Date: Datum: Lender: Långivare: Default account for budgeted transactions Förvalt konto för budgeterade transaktioner Description: Beskrivning: Account is closed Kontot är avslutat Zero value not allowed. Nollvärde är inte tillåtet. New currency... Ny valuta... Warning Varning If you change the currency of an account, the currency of all associated transactions will also change, without any conversion. Do do wish to continue anyway. Om du ändrar valutan för ett konto, så kommer valutan för alla associerade transaktioner också att ändras, utan någon omvandling. Vill du trots det fortsätta. Type cannot be changed to securities for accounts with transactions. Typ kan inte ändras till värdepapper för konton med transaktioner. Issuer: Utgivare: Error Fel Transaction Account Transaktionskonto Opening balance: Account balance Startvärde: Opening balance Account balance Startvärde New currency… Ny valuta… If you change the currency of an account, the currency of all associated transactions will also change, without any conversion. Do do wish to continue anyway? Om du ändrar valutan för ett konto, så kommer valutan för alla associerade transaktioner också att ändras, utan någon omvandling. Vill du trots det fortsätta? Empty name. Tomt namn. The entered name is used by another account. Namnet används av ett annat konto. EditCurrencyDialog Edit Currency Redigera valuta New Currency Ny valuta Code: Kod: Symbol: Symbol: Prefix Prefix Suffix Suffix Default Förvald Name: Namn: Decimals: Decimaler: Date: Datum: Main currency Huvudvaluta Error Fel Error saving currencies: %1. Fel vid sparande av valutor: %1. Failed to save currencies. Misslyckades med att spara valutor. Empty code. Tom kod. Code already exists. Koden existerar redan. EditDebtPaymentDialog Debt Payment Skuldbetalning EditDebtPaymentWidget Debt: Skuld: Date: Datum: Debt reduction: Skuldminskning: Reduction payment: Skuldminskningsbetalning: Interest: Ränta: Paid Betald Added to debt Lagd på skulden Fee: Avgift: Account: Konto: Expense category: Utgiftskategori: Associated file: Associerad fil: Select a file Välj en fil Open the file Öppna filen Comments: Kommentarer: Related to: Label for linked transactions Relaterad till: Total value: Totalt värde: Error Fel No suitable account available. Inget lämpligt konto finns tillgängligt. Invalid date. Felaktigt datum. Interest must not be zero. Ränta får inte vara noll. At least one value must non-zero. Åtminstone ett värde måste vara annat än noll. EditExceptionsDialog Edit Exceptions Redigera undantag Occurrences: Förekomster: Add Exception Lägg till undantag Remove Exception Ta bort undantag Exceptions: Undantag: Only the first fifty occurrences are shown. Enbart de femtio första förekomsterna visas. EditExpensesAccountDialog Name: Namn: Parent category: Överordnad kategori: None Ingen Monthly budget: Månatlig budget: Description: Beskrivning: Error Fel Empty name. Tomt namn. The entered name is used by another expense category. Namnet används av en annan utgiftskategori. EditIncomesAccountDialog Name: Namn: Parent category: Överordnad kategori: None Ingen Monthly budget: Månatlig budget: Description: Beskrivning: Error Fel Empty name. Tomt namn. The entered name is used by another income category. Namnet används av en annan inkomstkategori. EditMultiAccountDialog Expense with Multiple Payments Utgift med flera betalningar Income with Multiple Payments Inkomst med flera betalningar EditMultiAccountWidget Quantity: Kvantitet: Category: Kategori: Comments: Kommentarer: Transactions: Transaktioner: Date Datum Account Konto Description: Transaction description property (transaction title/generic article name) Benämning: Tags: Etiketter: Associated file: Associerad fil: Select a file Välj en fil Open the file Öppna filen Related to: Label for linked transactions Relaterad till: Payee Mottagare Payer Utbetalare Cost Kostnad Income Inkomst New Ny Edit… Redigera… Delete Ta bort Total cost: Total kostnad: New Tag Ny etikett Tag: Etikett: Total value: Totalt värde: Error Fel No suitable expense categories available. Ingen lämplig utgiftskategori finns tillgänglig. A split must contain at least two transactions. En delad transaktion måste innehålla minst två transaktioner. EditMultiItemDialog Split Transaction Delad transaktion EditMultiItemWidget Date: Datum: Account: Konto: Payee/Payer: Mottagare/utbetalare: Transactions: Transaktioner: Type Typ Description: Transaction description property (transaction title/generic article name) Benämning: Tags: Etiketter: Associated file: Associerad fil: Select a file Välj en fil Open the file Öppna filen Comments: Kommentarer: Related to: Label for linked transactions Relaterad till: Description Transaction description property (transaction title/generic article name) Benämning Payment Betalning Deposit Insättning Account/Category Konto/kategori Value Värde Income Inkomst Expense Utgift New Ny New Expense… Ny utgift… New Income… Ny inkomst… New Deposit… Ny insättning… New Withdrawal… Nytt uttag… New Securities Purchase… Financial security (e.g. stock, mutual fund) Nytt värdepappersköp… New Securities Sale… Financial security (e.g. stock, mutual fund) Ny värdepappersförsäljning… New Dividend… Ny utdelning… Edit… Redigera… Delete Ta bort Total value: Totalt värde: Error Fel No suitable account available. Inget lämpligt konto finns tillgängligt. Invalid date. Felaktigt datum. A split must contain at least two transactions. En delad transaktion måste innehålla minst två transaktioner. Cannot transfer money to and from the same account. Kan inte överföra pengar till och från samma konto. EditQuotationsDialog Date Datum Quotes Financial quote Kurser Price per Share Financial Shares Pris per andel Add Lägg till Modify Ändra Delete Ta bort Import… Importera… Export… Exportera… Quotes for %1 Financial quote Kurser för %1 Error Fel Couldn't open %1 for reading. Kunde inte öppna och läsa %1. Error reading %1. Fel vid läsande av %1. Successfully imported %n quote(s). Lyckades importera kurser för %n datum. Lyckades importera kurser för %n datum. Unable to import any quotes. Lyckades inte importera några kurser. Failed to import %n data row(s). Misslyckades att importera %n datarad. Misslyckades att importera %n datarader. Required columns missing. Nödvändig kolumn fattas. Invalid value. Ogiltigt värde. Invalid date. Felaktigt datum. No data found. Ingen data funnen. Information Information Unrecognized date format. Obekant datum format. Specify Format Ange format The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. Formatet på datum och/eller nummer i CSV-filen är tvetydiga. Var vänlig välj det korrekta formatet. Date format: Datumformat: Value format: Värdeformat: Couldn't open file for writing. Kunde inte öppna och skriva till filen. Quotes: %1 Kurser: %1 Error while writing file; file was not saved. Fel vid skrivande av fil; filen sparades inte. EditRangeDialog Edit Recurrence Range Redigera återkomstomfånget Begins on: %1 Börjar på: %1 No ending date Inget slutdatum End after Sluta efter occurrence(s) förekomst(er) End on Sluta på Error Fel Invalid date. Felaktigt datum. End date before start date. Slutdatum är efter startdatum. EditReinvestedDividendDialog Reinvested Dividend Återinvesterad utdelning Security: Financial security (e.g. stock, mutual fund) Värdepapper: Shares added: Financial shares Andelar tillkomna: Date: Datum: Error Fel Invalid date. Felaktigt datum. EditScheduledDebtPaymentDialog Transaction Transaktion Recurrence Återkomst Edit Debt Payment Redigera skuldbetalning New Debt Payment Ny skuldbetalning EditScheduledMultiAccountDialog Transactions Transaktioner Recurrence Återkomst New Expense with Multiple Payments Ny utgift med flera betalningar New Income with Multiple Payments Ny inkomst med flera betalningar Edit Expense with Multiple Payments Redigera utgift med flera betalningar Edit Income with Multiple Payments Redigera inkomst med flera betalningar EditScheduledMultiItemDialog Transactions Transaktioner Recurrence Återkomst New Split Transaction Ny delad transaktion Edit Split Transaction Redigera delad transaktion EditScheduledTransactionDialog Expense Utgift Dividend Utdelning Income Inkomst Reinvested Dividend Återinvesterad utdelning Transfer Överföring Securities Purchase Financial security (e.g. stock, mutual fund) Värdepappersköp Securities Sale Financial security (e.g. stock, mutual fund) Värdepappersförsäljning Recurrence Återkomst New Expense Ny utgift New Expense Paid with Loan Ny utgift betalad med lån New Dividend Ny utdelning New Income Ny inkomst New Transfer Ny överföring New Securities Purchase Financial security (e.g. stock, mutual fund) Nytt värdepappersköp New Reinvested Dividend Ny återinvesterad utdelning New Securities Sale Financial security (e.g. stock, mutual fund) Ny värdepappersförsäljning Edit Reinvested Dividend Redigera återinvesterad utdelning Edit Securities Purchase Financial security (e.g. stock, mutual fund) Redigera värdepappersköp Edit Securities Sale Financial security (e.g. stock, mutual fund) Redigera värdepappersförsäljning Edit Expense Redigera utgift Edit Dividend Redigera utdelning Edit Income Redigera inkomst Edit Transfer Redigera överföring EditSecurityDialog Type: Typ: Mutual Fund Fond Stock Financial stock Aktie Other Övrigt Name: Namn: Account: Konto: Decimals in shares: Financial shares Decimaler i andelar: Initial shares: Financial shares Initiala andelar: Decimals in quotes: Financial quote Decimaler i kursangivelser: Initial quote: Financial quote Initial kurs: Date: Datum: Description: Beskrivning: Error Fel Empty name. Tomt namn. No suitable account available. Inget lämpligt konto finns tillgängligt. No suitable account or income category available. Inga lämpliga konton eller inkomstkategorier finns tillgängliga. EditSecurityTradeDialog All Alla Securities Exchange Shares of one security directly exchanged for shares of another; Financial security (e.g. stock, mutual fund) Värdepappersbyte From security: Financial security (e.g. stock, mutual fund) Från värdepapper: Shares moved: Financial shares Andelar flyttade: To security: Financial security (e.g. stock, mutual fund) Till värdepapper: Shares received: Financial shares Andelar tillkomna: Value: Värde: Date: Datum: Error Fel No other security available for exchange in the account. Shares of one security directly exchanged for shares of another; Financial security (e.g. stock, mutual fund) Inget annat värdepapper finns tillgängligt för byte i kontot. Selected to and from securities are the same. Financial security (e.g. stock, mutual fund) Valda värdepapper måste vara olika. Zero shares not allowed. Financial shares Noll andelar är inte tillåtet. Invalid date. Felaktigt datum. Zero value not allowed. Noll värde är inte tillåtet. Eqonomize Accounts && Categories Konton och kategorier Expenses Utgifter Incomes Inkomster Transfers Överföringar Schedule Planering Account / Category Konto / kategori Remaining Budget (%1) Återstående budget (%1) Change (%1) Förändring (%1) Total (%1) Totalvärde (%1) Accounts Konton Includes budgeted transactions Inkluderar budgeterade transaktioner Assets Tillgångar Tags Etiketter Period Period From Från To Till Select Period Välj period Current Month Innevarande månad Current Year Innevarande år Current Whole Month Hela innevarande månad Current Whole Year Hela innevarande år Whole Past Month Hela den gångna månaden Whole Past Year Hela det gångna året Previous Month Föregående månad Previous Year Föregående år Show partial budget Visa partiell budget Edit Budget Redigera budget Budget: Budget: Month: Månad: Result previous month: Resultat föregående månad: New Transaction Ny transaktion Name Namn Value Värde Cost Kostnad Profit Förtjänst Yearly Rate Årlig ränta Type Typ Account Konto Statistics Period Statistikperiod New Schedule Ny planering Edit Redigera Remove Ta bort Next Occurrence Nästa tillfälle Amount Värde Payee/Payer Mottagare/utbetalare Comments Kommentarer Set Schedule Confirmation Time Ange tid för planeringsbekräftelse Schedule confirmation time: Tid för planeringsbekräftelse: Set Budget Period Ange budgetperiod First day in budget month: Första dagen i budgetmånaden: 1st 1:a 2nd 2:a 3rd 3:e 4th 4:e 5th 5:e 6th 6:e 7th 7:e 8th 8:e 9th 9:e 10th 10:e 11th 11:e 12th 12:e 13th 13:e 14th 14:e 15th 15:e 16th 16:e 17th 17:e 18th 18:e 19th 19:e 20th 20:e 21st 21:a 22nd 22:a 23rd 23:e 24th 24:e 25th 25:e 26th 26:e 27th 27:e 28th 28:e Last Sista 2nd Last Näst sista 3rd Last 3:e sista 4th Last 4:e sista 5th Last 5:e sista Timestamp Tidsstämpel Links Länkar Remove Link Ta bort länk Link to "%1" create link to transaction (link used as verb) Sammanlänka med "%1" Information Information Select a transaction and choose %1 in the menu, to create a link between the transactions. To cancel, right-click the menu item. Markera en transaktion och välj %1 i menyn för att skapa länk mellan transaktionerna. För att avbryta, höger-klicka på menyalternativet. Do not show this message again Visa inte detta meddelande igen Link Transaction(s) create link to transaction (link used as verb) Sammanlänka transaktion(er) All Alla Synchronization Settings Synkroniseringsinställningar Web address: Webbadress: Download command: Neddladdningskommando: Duplicate Transaction… duplicate as verb Duplicera transaktion… New Tag… Ny etikett… Rename Tag… Byt namn på etikett… Remove Tag Ta bort etikett New Tag Ny etikett Tag name: Namn på etikett: Remove tag? Ta bort etikett? Do you wish to remove the tag "%1" from %n transaction(s)? Vill du ta bort etiketten "%1" från %n transaktion? Vill du ta bort etiketten "%1" från %n transaktioner? Do you wish to remove the tag "%1" from %2 transaction(s)? Vill du ta bort etiketten "%1" från %2 transaktion(er)? Rename Tag Byt namn på etikett Transaction Account Transaktionskonto Select Font… Välj teckensnitt… Transaction Accounts Transaktionskonton Savings Accounts Sparkonton Credit Cards Kreditkort Debts Skulder Securities Värdepapper optional valfri Upload command: Uppladdningskommando: mandatory nödvändig %f = local file, %u = url %f = lokal fil, %u = url Automatic synchronization Automatisk synkronisering Upload Ladda upp Uploading… Laddar upp… Error uploading file Fel vid uppladdning av fil Error uploading %1: %2. Fil vid uppladdning av %1: %2. Synchronizing… Synkroniserar… Error synchronizing file Fel vid synkronisering av fil Error synchronizing %1: %2. Fel vid synkronisering av %1: %2. Synchronization error Synkroniseringsfel Synchronize file? Synkronisera fil? The file has been modified by a different user or program. Do you wish to merge changes? Filen har ändrats av en användare eller ett annat program. Vill du slå samman förändringarna? &Synchronize S&ynkronisera Reconcile Account… Avstäm konto… Cloud Synchronization (experimental)… Molnsynkronisering (experimentell)… Only use this when unable to find the cause of the incorrect recorded account balance. Använd enbart detta när orsaken till det felaktiga bokförda kontosaldot inte kan hittas. Reopen Account Mark account as not closed Återöppna kontot Reopen Account Återöppna kontot Updating exchange rates... Updatera valutakurser... Abort Avbryt Failed to download exchange rates from %1: %2. Misslyckades med att ladda ned växelkurser från %1: %2. Error reading data from %1: %2. Fel vid läsande av data från %1: %2. Unrecognized Currency Okänd valuta No exchange rate is available for the default currency (%1). If you wish to use multiple currencies you should set the exchange rate manually. Inga växelkurser är tillgängliga för den förvalda vlutan (%1). Om du vill använda flera valutor så bör du ange växelkursen manuellt. Set Main Currency Ange huvudvaluta Currency: Valuta: New currency... Ny valuta... Replace all occurrences of the former main currency Ersätt alla förekomster av den tidigare huvudvalutan Update Exchange Rates Uppdatera växelkurser Adjust balance… Referring to account balance Justera saldo… Show payee and quantity Visa betalningsmottagare och kvantitet Show quantity and payer/payee properties for incomes and expenses. Visa kvantitet och utbetalare/mottage för inkomster och utgifter. Set Main Currency… Ange huvudvaluta… Adjust Account Balance Justera kontosaldo of which %1 is balance adjustment Referring to account balance varav %1 utgör saldojustering Total value: Totalt värde: Cost: Kostnad: Profit: Förtjänst: Rate: Ränta: Error Fel Date: Datum: First month in budget year: Första månaden på budgetåret: Invalid date. Felaktigt datum. Future dates are not allowed. Framtida datum är inte tillåtna. Bond Obligation Mutual Fund Fond Other Övrigt Right align Högerjustera Add Loan Lägg till lån Add Category Lägg till kategori Ledger Liggare To date is before from date. Slutdatum är före startdatum. From date is after to date. Startdatum är efter slutdatum. Cash Kontanter Savings Account Sparkonto Salary Lön Bills Räkningar Clothing Kläder Groceries Livsmedel Leisure Nöje Import Options Importalternativ Ignore duplicate transactions Hoppa över transaktionsdubbletter Rename duplicate accounts Byt namn på kontodubletter Rename duplicate categories Byt namn på kategoridubletter Rename duplicate securities Byt namn på värdepappersdubletter Couldn't open file Kunde inte öppna fil Error loading %1: %2. Fel vid läsande av %1: %2. %f = local file (temporary), %u = url %f = lokal fil (temporär), %u = url Couldn't save file Kunde inte spara fil Error saving %1: %2. Fel vid sparande av %1: %2. New version available Ny version tillgänglig A new version of %1 is available.<br><br>You can get version %2 at %3. En ny version av %1 finns tillgänglig.<br><br>Du kan hämta version %2 på %3. Transaction Schedule Planerade transaktioner Total Summa Accounts &amp; Categories html format Konton och kategorier Accounts &amp; Categories (%1&ndash;%2) html format Konton och kategorier (%1 &ndash; %2) Accounts &amp; Categories (to %1) html format Konton och kategorier (till %1) Change Noun, how much the account balance has changed Förändring Current Account Transaktionskonto Credit Card Kreditkort Liabilities Skulder Description Transaction description property (transaction title/generic article name) Benämning Category Kategori Budget Budget Remaining Budget Återstående budget Error saving currencies: %1. Fel vid sparande av valutor: %1. Total Incomes Totala inkomster Costs Kostnader Total Expenses Totala utgifter Account/Category Noun, how much the account balance has changed Konto/kategori Empty expenses list. Tom utgiftslista. Empty incomes list. Tom inkomstlista. Empty transfers list. Tom överföringslista. Empty schedule list. Inga planerade transaktioner i listan. Couldn't open file for writing. Kunde inte öppna och skriva till filen. Error while writing file; file was not saved. Fel vid skrivande av fil; filen sparades inte. &File &Arkiv &Accounts &Konton &Transactions &Transaktioner &Loans &Lån Stat&istics Stat&istik S&ettings I&nställningar &Help &Hjälp File Arkiv Transactions Transaktioner Statistics Statistik &New &Ny &Open… &Öppna… Open Recent Öppna senaste Clear List Rensa lista &Save &Spara Save As… Spara som… &Revert &Återställ S&ynchronize S&ynkronisera &Print… Skriv &ut… Print Preview… Förhandsgranskning… Import Importera Import CSV File… Importera CSV-fil… Import QIF File… Importera QIF-fil… Export View… Exportera vy… Export As QIF File… Exportera QIF-fil… &Quit &Avsluta Add Account… Lägg till konto… New Account… Nytt konto… New Income Category… Ny inkomstkategori… New Expense Category… Ny utgiftskategori… Add Account Lägg till konto Securities Financial security (e.g. stock, mutual fund) Värdepapper New Security… Financial security (e.g. stock, mutual fund) Nytt värdepapper… Shares Financial shares Andelar New Security Financial security (e.g. stock, mutual fund) Nytt värdepapper Edit Security Financial security (e.g. stock, mutual fund) Modifiera värdepapper Delete security? Financial security (e.g. stock, mutual fund) Ta bort värdepappret? Are you sure you want to delete the security "%1" and all associated transactions? Financial security (e.g. stock, mutual fund) Är du säker på att vill ta bort värdepappret "%1" och alla tillhörande transaktioner? No security available. Financial security (e.g. stock, mutual fund) Inget värdepapper o finns tillgängligt. Price per share: Financial shares Pris per andel: Security Transactions Financial security (e.g. stock, mutual fund) Värdepapperstransaktioner Stock Financial stock Aktie Updating exchange rates… Updatera valutakurser… Failed to save currencies. Misslyckades med att spara valutor. New currency… Ny valuta… Balance Noun. Balance of an account Saldo Empty securities list. Financial security (e.g. stock, mutual fund) Tom värdepapperslista. &Securities Financial security (e.g. stock, mutual fund) &Värdepapper Import %1 File… Importera %1-fil… Currency Converter Valutaomvandlare New Loan… Nytt lån… Edit… Redigera… Close Avsluta Show Transactions Visa transaktioner Show Ledger Visa liggare New Expense… Ny utgift… New Income… Ny inkomst… New Transfer… Ny överföring… New Split Transaction… Ny delad transaktion… New Expense with Multiple Payments… Ny utgift med flera betalningar… Refund… Återbetalning… Repayment… Återbetalning… New Refund/Repayment… Ny återbetalning… Edit Transaction(s) (Occurrence)… Redigera transaktion(er) (tillfälle)… Edit Occurrence… Redigera tillfället… Edit Schedule (Recurrence)… Redigera planering (återkomster)… Edit Schedule… Redigera planering… Edit Split Transaction… Redigera delad transaktion… Duplicate Transaction… Duplicera transaktion… Join Transactions… join transactions together Sammanslå transaktioner… Edit Timestamp… Redigera tidsstämpel… New Debt Payment… Ny betalning på skuld… New Unpaid Interest… Ny obetald ränta… New Expense Paid with Loan… Ny utgift betalad med lån… Edit Security… Financial security (e.g. stock, mutual fund) Redigera värdepapper… Remove Security Financial security (e.g. stock, mutual fund) Avlägsna värdepappret Shares Bought… Financial shares Andelar köpta… Shares Sold… Financial shares Andelar sålda… Show quantity and payer/payee for incomes and expenses. Visa kvantitet och utbetalare/mottage för inkomster och utgifter. Use Exchange Rate for Transaction Date Använd växelkurs för transaktionsdatum Use the exchange rate nearest the transaction date, instead of the latest available rate, when converting the value of transactions. Använd växelkursen för datum närmast transaktionens datum, istället för den seanste tillgängliga kursen, vid omvandling av transaktionsvärden. Set Budget Period… Ange budgetperiod… Set Schedule Confirmation Time… Ange tid för planeringsbekräftelse… Backup Frequency Frekvens för säkerhetskopiering Daily Dagligen Weekly Varje vecka Fortnightly Varannan vecka Monthly Månadsvis Never Aldrig Dark Mode Mörkt läge Language Språk Default Förvalt About %1 Om %1 New tag… Ny etikett… Rename tag… Byt namn på etikett… Remove tag Ta bort etikett Restart required Omstart krävs Please restart the application for the language change to take effect. Vängligen starta om programmet för att språkändringen skall ha effekt. A personal accounting program Ett bokföringsprogram License: GNU General Public License Version 3 Licens: GNU General Public License Version 3 %1 exited unexpectedly before the file was saved and data was lost. Do you want to load the last auto-saved version of the file? %1 avslutades oväntat innan filen sparades och data förlorades. Vill du öppna den senast automatiskt sparade versionen av filen? Split Up Transaction split up joined transactions Dela upp transaktionen Link Transactions create link between selected transactions (link used as verb) Sammanlänka transaktionerna Create Link to Transaction Skapa länk till transaktionen Close Account Mark account as closed Avsluta kontot Create Link create link to or between transaction(s) Skapa länk Remove Transaction(s) (Occurrence) Ta bort transaktion(er) (tillfälle) Remove Occurrence Ta bort tillfället Delete Schedule (Recurrence) Ta bort planering (återkomster) Delete Schedule Avlägsna planering Remove Split Transaction Ta bort delad transaktion Dividend… Utdelning… Reinvested Dividend… Återinvesterad utdelning… Transactions… Transaktioner… Development Over Time Report… Rapport med utveckling över tid… Categories Comparison Report… Rapport för jämförelse av kategorier… Development Over Time Chart… Diagram med utveckling över tid… Categories Comparison Chart… Diagram för jämförelse av kategorier… Use Additional Transaction Properties Använd ytterligare egenskaper för transaktioner Initial Period Initialt vald period Remember Last Dates Kom ihåg senaste datum Help Hjälp Report Bug Rapportera fel About Qt Om Qt Crash Recovery Krashåterhämtning Untitled Namnlös Checking Account Transactional account Transaktionskonto Select Associated File Välj associerad fil Open Associated File Öppna associerad fil Shares Exchanged… Shares of one security directly exchanged for shares of another; Financial shares Andelar flyttade… Shares of one security directly exchanged for shares of another Financial shares Andelar av ett väderpapper direkt utbytta mot andelar av ett annat Edit Quotes… Financial quote Redigera kursangivelser… Eqonomize! Accounting File Eqonomize! bokföringsfil Close Account Avsluta kontot Save file? Spara fil? The current file has been modified. Do you want to save it? Den nuvarande filen har ändrats. Vill du spara den? Confirm Schedule Bekräfta planerade transaktioner New Account Nytt konto New Loan Nytt lån New Income Category Ny inkomstkategori New Expense Category Ny utgiftskategori Book value: Bokfört värde: Real value: Verkligt värde: Edit Account Redigera konto Edit Income Category Redigera inkomstkategori Edit Expense Category Redigera utgiftskategori Remove subcategories? Ta bort underkategorier? Do you wish to remove the category including all subcategories? Vill du ta bort kategorin, inklusive alla underkategorier? Move transactions? Flytta transaktioner? Move to: Flytta till: Remove irreversibly from all accounts (do not do this if account has been closed!) Ta bort oåterkalleligt från alla konton (gör inte detta om kontot har avslutats!) The category contains some expenses. What do you want to do with them? Kategorin innehåller en del utgifter. Vad vill du göra med dem? The category contains some incomes. What do you want to do with them? Kategorin innehåller en del inkomster. Vad vill du göra med dem? The account contains some transactions. What do you want to do with them? Kontot innehåller en del transaktioner. Vad vill du göra med dem? Remove Category? Ta bort kategorin? The category contains some expenses that will be removed. Do you still want to remove the category? Kategorin innehåller en del utgifter som kommer att avlägsnas. Vill du ändå ta bort kategorin? The category contains some incomes that will be removed. Do you still want to remove the category? Kategorin innehåller en del inkomster som kommer att avlägsnas. Vill du ändå ta bort kategorin? Remove Account? Ta bort kontot? The account contains some transactions that will be removed. Do you still want to remove the account? Kontot innehåller en del transaktioner som kommer att avlägsnas. Vill du ändå ta bort kontot? %2 of %1 %1: budget; %2: remaining budget %2 av %1 Set Quote… Financial quote Ange kurs… Quote Financial quote Kurs Set Quote (%1) Financial quote Ange kurs (%1) Reopen Återöppna %1 (with no budget) %1 (utan någon budget) %1 (with budget %2) %1 (med budget %2) EqonomizeCalendarWidget Today Idag EqonomizeDateEdit Today Idag EqonomizeTranslator OK Only used when Qt translation is missing OK Cancel Only used when Qt translation is missing Avbryt Close Only used when Qt translation is missing Stäng Yes Only used when Qt translation is missing Ja No Only used when Qt translation is missing Nej &Yes Only used when Qt translation is missing &Ja &No Only used when Qt translation is missing &Nej &Open Only used when Qt translation is missing &Öppna &Save Only used when Qt translation is missing &Spara &Select All Only used when Qt translation is missing Markera &alla Select All Only used when Qt translation is missing Markera alla Look in: Only used when Qt translation is missing Titta i: File &name: Only used when Qt translation is missing Fil&namn: Files of type: Only used when Qt translation is missing Filer av typ: EqonomizeValueEdit Error Fel Empty denominator. Tom täljare. Empty factor. Tom faktor. Division by zero. Division med noll. Unknown or ambiguous currency, or unrecognized characters, in expression: %1. Okänd eller tvetydig valuta, eller okända tecken, i uttryck: %1. Empty base. Tom bas. Empty exponent. Tom exponent. Unrecognized characters in expression. Okända tecken i uttryck. ExportQIFDialog Export QIF File Exportera QIF-fil Account: Konto: All All accounts Alla Date format: Datumformat: Value format: Värdeformat: File: Fil: Error Fel Selected file is a directory. Vald fil är en mapp. Overwrite Skriv över The selected file already exists. Would you like to overwrite the old copy? Filen existerar redan. Vill du skriva över den gamla kopian? Couldn't open file for writing. Kunde inte öppna och skriva till filen. Error while writing file; file was not saved. Fel vid skrivande av fil; filen sparades inte. ImportCSVDialog Import CSV file Importera CSV-fil Transaction Type Selection Val av transaktionstyp Expenses Utgifter Incomes Inkomster Transfers Överföringar Expenses and incomes (negative cost) Utgifter och inkomster (negativ kostnad) Expenses and incomes (separate columns) Utgifter och inkomster (separata kolumner) All types Alla typer Presets: Förinställningar: File Selection Filval File: Fil: First data row: Första dataraden: Auto Auto Column delimiter: Kolumnavgränsare: Comma Komma Tabulator Tabulator Semicolon Semikolon Space Mellanslag Other Övrigt Columns Specification Kolumnspecificering Description: Transaction description property (transaction title/generic article name) Benämning: The same column number is selected multiple times. Do you wish to proceed anyway? Samma kolumnnummer är valt flera gånger. Vill du ändå fortsätta? Column Kolumn Value Värde Cost: Kostnad: Date: Datum: Category: Kategori: From account: Från konto: Quantity: Kvantitet: Payee: Mottagare: Tags: Etiketter: Comments: Kommentarer: Create missing categories and accounts Skapa saknade kategorier och konton Save Preset Spara förinställning Imports data as expenses. Costs have positive value. Value is the only required column. Importerar data som utgifter. Kostnader har positivt värde. Värde är enda nödvändiga kolumn. Imports data as incomes. Value is the only required column. Importerar data som inkomster. Värde är enda nödvändiga kolumn. Income: Inkomst: To account: Till konto: Payer: Utbetalare: Imports data as transfers. Value is the only required column. Importerar data som överföringar. Värde är enda nödvändiga kolumn. Amount: Värde: Imports data as expenses and incomes. Costs have negative value. Value and category are both required columns. Importerar data som utgifter och inkomster. Kostnader har negativt värde. Värde och kategori är både nödvändiga kolumner. Value: Värde: Account: Konto: Payee/payer: Mottagare/utbetalare: Imports data as expenses and incomes. Costs and incomes have separate columns. Income, cost, and category are all required columns. Importerar data som utgifter och inkomster. Kostnader och inkomster har separata kolumner. Kostnad, inkomst och kategori är alla nödvändiga kolumner. Imports data as expenses, incomes, and transfers. Costs have negative or positive value. Value, to, and from are all required columns. Accounts and categories must be existing. Importerar data som utgifter, inkomster och överföringar. Kostnader har negativt eller positivt värde. Värde, till och från är alla nödvändinga kolumner. Konton och kategorier måste existera. From: Från: To: Till: Error Fel A file must be selected. En fil måste väljas. Selected file is a directory. Vald fil är en mapp. Selected file does not exist. Vald fil existerar inte. Empty delimiter. Tom avgränsare. The same column number is selected multiple times. Samma kolumnnummer är valt flera gånger. Selected from account is the same as the to account. Valt från-konto är det samma som till-kontot. Invalid date. Felaktigt datum. Couldn't open %1 for reading. Kunde inte öppna och läsa %1. Error reading %1. Fel vid läsande av %1. Uncategorized Okategoriserade Successfully imported %n transaction(s). Lyckades importera %n transaktion. Lyckades importera %n transaktioner. Unable to import any transactions. Lyckades inte importera några transaktioner. Failed to import %n data row(s). Misslyckades att importera %n datarad. Misslyckades att importera %n datarader. Balancing account wrongly used. Referring to the account used for adjustments of account balances. Balanseringskonto felaktigt använt. Required columns missing. Nödvändig kolumn fattas. Save as preset… Spara som förinställning… Imports data as expenses and incomes. Costs have negative value. Value is the only required column. Importerar data som utgifter och inkomster. Kostnader har negativt värde. Värde är den enda nödvändiga kolumnen. Imports data as expenses and incomes. Costs and incomes have separate columns. Income and cost both all required columns. Importerar data som utgifter och inkomster. Kostnader och inkomster har separata kolumner. Kostnad och inkomst är båda nödvändiga kolumner. Warning Varning The same column number is selected multiple times. Proceed? Samma kolumnnummer är valt flera gånger. Vill du ändå fortsätta? Invalid value. Ogiltigt värde. Empty category name. Tomt kategorinamn. Empty account name. Tomt kontonamn. Unknown category found. Okänd kategori funnen. Unknown account found. Okänt konto funnet. Cannot import security transactions (to/from security accounts). Kan inte importera värdepapperstransaktioner (till/från konto för värdepapper). Same to and from account/category. Samma konto/kategori till och från. No data found. Ingen data funnen. Information Information Unrecognized date format. Obekant datum format. Specify Format Ange format The format of dates and/or numbers in the CSV file is ambiguous. Please select the correct format. Formatet på datum och/eller nummer i CSV-filen är tvetydiga. Var vänlig välj det korrekta formatet. Date format: Datumformat: Value format: Värdeformat: ImportQIFDialog Import QIF file Importera QIF-fil File Selection Filval Select a QIF file to import. When you click next, the file be analysed and you might need to answer some questions about the format of the file. Välj en QIF-fil att importera. När du klickar nästa kommer filen att analyseras och du kanske behöver svara på några frågor om format på filen. File: Fil: Local Definitions Lokala definitioner Unknown elements where found in the QIF file. It is possible that this is because of localized type names. Please map them to the correct standard names. Programmet fann okända element i QIF-filen. Det är möjligt att det beror på användande av översatta typnamn. Var vänliga passa ihop dessa med de korrekta standardnamnen. Local Text Lokal text Standard Text Standardtext Select standard text: Välj standardtext: Date Format Datumformat The date format in the QIF file is ambiguous. Please select the correct format. Datumformatet i QIF-filen är tvetydigt. Var vänlig välj det korrekta formatet. Date format: Datumformat: Default Account Förvalt konto Could not find any account definitions in the QIF file. Please select a default account. It is also possible that this is caused by a localized opening balance text. Programmet fann inga kontodefinitioner i QIF-filen. Var vänlig välj ett förvalt konto. Det är möjligt att detta beror på en översatt öppningsbalanstext. Default account: Förvalt konto: Opening balance text: Text för ingående saldo: Import File Importera fil No (further) issues were found. Press finish to import the selected QIF file. Inga (ytterligare) problem hittades. Tryck färdig för att importera den valda QIF-filen. Ignore duplicate transactions Hoppa över transaktionsdubbletter Error Fel A file must be selected. En fil måste väljas. Selected file is a directory. Vald fil är en mapp. Selected file does not exist. Vald fil existerar inte. Couldn't open %1 for reading. Kunde inte öppna och läsa %1. Error reading %1. Fel vid läsande av %1. Unknown Okänd Account Konto Bank Bank Cash Kontanter Cat (Category) Cat (Kategori) CCard (Credit Card) CCard (Kreditkort) Invst (Investment) Invst (Investering) Oth A (Other Assets) Oth A (Andra tillgångar) Oth L (Other Liabilities) Oth L (Andra skulder) Security Security (Värdepapper) Other Övrigt Unrecognized date format. Obekant datum format. Successfully imported %n transaction(s). Lyckades importera %n transaktion. Lyckades importera %n transaktioner. Successfully imported %n account(s). Lyckades importera %n konto. Lyckades importera %n konton. Successfully imported %n category/categories. Lyckades importera %n kategori. Lyckades importera %n kategorier. %n duplicate transaction(s) was ignored. %n transaktionskopia ignorerades. %n transaktionskopior ignorerades. Failed to import %n transaction(s). Misslyckades att importera %n transaktion. Misslyckades att importera %n transaktioner. %n security/securities were not imported. Financial security (e.g. stock, mutual fund) %n värdepapper importerades inte. %n värdepapper importerades inte. %n security transaction(s) were not imported. Financial security (e.g. stock, mutual fund) %n värdepapperstransaktion importerades inte. %n värdepapperstransaktioner importerades inte. Information Information Income Dividend: %1 Utdelning: %1 Reinvested dividend: %1 Återinvesterad utdelning: %1 LedgerDialog Account: Konto: Edit Account… Redigera konto… Export… Exportera… Print… Skriv ut… Mark all as reconciled Accounting context Markera alla som avstämda Opening balance: Accounting context Ingående saldo: Closing balance: Accounting context Utgående saldo: R Header for account reconciled checkbox column A Date Datum Type Typ Account/Category Konto/kategori Deposit Insättning Withdrawal Uttag Balance Noun. Balance of an account Saldo Yes Ja No Nej New Ny Edit… Redigera… Delete Ta bort Join… join transactions together Sammanslå… Split Up split up joined transactions Dela upp Reconciled value: <b>%1</b> (%2) Accounting context Avstämt värde: <b>%1</b> (%2) Book value: <b>%1</b> (%2) Accounting context Bokfört värde: <b>%1</b> (%2) Mark as reconciled Accounting context Markera som avstämd Error Fel Invalid date. Felaktigt datum. Opening date is after closing date. Startdatum är efter slutdatum. Closing date is before opening date. Slutdatum är efter startdatum. Ascending sort Stigande sortering Empty transaction list. Tom transaktionslista. Couldn't open file for writing. Kunde inte öppna och skriva till filen. Error while writing file; file was not saved. Fel vid skrivande av fil; filen sparades inte. Ledger Liggare Transactions for %1 Transaktioner för %1 Select Time Period Väld tidsperiod From: Från: To: Till: To date is before from date. Slutdatum är före startdatum. Balance change: Account balance Saldoförändring: Delete transactions? Ta bort transaktioner? Are you sure you want to delete all (%1) selected transactions? Vill du verkligen ta bort alla (%1) valda transaktioner? Cannot set the value of security transactions using the dialog for modifying multiple transactions. Financial security (e.g. stock, mutual fund) Kan inte ange värde för värdepapperstransaktioner med dialogen för att modifier flera transaktioner. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name); Financial security (e.g. stock, mutual fund) Kan inte ändra beskrivning för utdelningar och värdepapperstransaktioner. Cannot change payer of dividends and security transactions. Financial security (e.g. stock, mutual fund) Kan inte ändra utbetalare för utdelningar och värdepapperstransaktioner. Opening balance Account balance Ingående saldo Account Balance Adjustment Justering av kontosaldo Current balance: Account balance Nuvarande saldo: Average balance: Account balance Genomsnittligt saldo: Current debt: Nuvarande skuld: Edit Transaction(s)… Redigera transaktion(er)… Join Transactions… Sammanslå transaktioner… Split Up Transaction Dela upp transaktionen Open Associated File Öppna associerad fil Remove Transaction(s) Ta bort transaktion(er) Mark as reconciled Markera som avstämd Reconciled: %1 (%2) Accounting context Avstämt: %1 (%2) Ascending order Stigande ordning Total debt reduction: Total skuldminskning: Total interest and fees: Totala räntor och avgifter: Number of transactions: Antal transaktioner: Split Transaction Delad transaktion Reconcile Accounting context Kontoavstämning Change: Accounting context Förändring: Reconciled Accounting context Avstämd Payee/Payer Mottagare/utbetalare Comments Kommentarer Deposit Money put into account Insättning Withdrawal Money taken out from account Uttag Reconciled value: %1 (%2) Accounting context Avstämt värde: %1 (%2) Book value: %1 (%2) Accounting context Bokfört värde: %1 (%2) Debt Payment Skuldbetalning Tags Etiketter Reduction Minskning Fee Avgift Interest Ränta Income Inkomst Repayment Återbetalning Expense Utgift Description Transaction description property (transaction title/generic article name) Benämning Refund Återbetalning Transfer Överföring LedgerListViewItem Yes Ja No Nej LinksWidget Remove Link Ta bort länk All Alla Remove Ta bort MultiItemListViewItem Dividend Utdelning Income Inkomst Repayment Återbetalning Expense Utgift Refund Återbetalning Securities Purchase Financial security (e.g. stock, mutual fund) Värdepappersköp Securities Sale Financial security (e.g. stock, mutual fund) Värdepappersförsäljning Account Balance Adjustment Justering av kontosaldo Transfer Överföring MultipleTransactionsEditDialog Modify Transactions Ändra transaktioner Description: Transaction description property (transaction title/generic article name) Benämning: Amount: Värde: Income: Inkomst: Cost: Kostnad: Date: Datum: Category: Kategori: Payer: Utbetalare: Payee: Mottagare: Error Fel No income category available. Ingen inkomstkategori finns tillgänglig. No expense category available. Ingen utgiftskategori finns tillänglig. Invalid date. Felaktigt datum. OverTimeChart Save As… Spara som… Print… Skriv ut… Source: Källa: Incomes and Expenses Inkomster och utgifter Profits Förtjänst Expenses Utgifter Incomes Inkomster All Categories Combined Alla kategorier kombinerade Theme: Tema: Chart type: Diagramtyp: Line Chart Linjediagram Vertical Bar Chart Vertikalt stapeldiagram Horizontal Bar Chart Horisontellt stapeldiagram Stacked Bar Chart Staplat stapeldiagram All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Alla benämningar kombinerade All Subcategories and Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Alla underkategorier och benämningar kombinerade All Descriptions Split Referring to the transaction description property (transaction title/generic article name) Alla benämningar uppdelade No description Referring to the transaction description property (transaction title/generic article name) Ingen benämning Other descriptions Referring to the transaction description property (transaction title/generic article name) Andra benämningar Profits, %1 Förtjänst, %1 Assets Tillgångar Assets and Liabilities Tillgångar och skulder All Payees/Payers Combined Alla mottagare/utbetalare kombinerade All Accounts Alla konton Start date: Startdatum: End date: Slutdatum: Value: Värde: Annual total Årlig summa Monthly total Månatlig summa Daily average Dagligt genomsnitt Quantity Kvantitet Average value Genomsnittligt värde All Payers Combined Alla utbetalare kombinerade All Payees Combined Alla mottagare kombinerade All Subcategories Split Alla underkategorier uppdelade Annual value Årligt värde Annual profit Årlig förtjänst Annual income Årlig inkomst Annual cost Årlig kostnad Includes budgeted transactions Inkluderar budgeterade transaktioner Value: %1 Värde: %1 Assets & Liabilities Tillgångar och skulder Change: %1 Förändring: %1 Incomes & Expenses, %1 Inkomster och utgifter, %1 Incomes & Expenses Inkomster och utgifter Incomes, %1 Inkomster, %1 Expenses, %1 Utgifter, %1 Incomes, %2: %1 Inkomster, %2: %1 Incomes: %1 Inkomster: %1 Expenses, %2: %1 Utgifter, %2: %1 Expenses: %1 Utgifter: %1 Incomes, %3: %2, %1 Inkomster, %3: %2, %1 Incomes: %2, %1 Inkomster: %2, %1 Expenses, %3: %2, %1 Utgifter, %3: %2, %1 Expenses: %2, %1 Utgifter: %2, %1 Incomes, %4: %3, %2, %1 Inkomster, %4: %3, %2, %1 Incomes: %3, %2, %1 Inkomster: %3, %2, %1 Expenses, %4: %3, %2, %1 Utgifter, %4: %3, %2, %1 Expenses: %3, %2, %1 Utgifter: %3, %2, %1 no payee/payer ingen mottagare/utbetalare Liabilities Skulder Other accounts Övriga konton %1 Value: %2 Date: %3 %1 Värde: %2 Datum: %3 MMMM yyyy Month and year MMMM, yyyy All Payers Split Alla utbetalare uppdelade All Payees Split Alla mottagare uppdelade No payer Ingen utbetalare No payee Ingen mottagare All Categories Split Alla kategorier uppdelade Error Fel Invalid date. Felaktigt datum. Couldn't open file for writing. Kunde inte öppna och skriva till filen. Error while writing file; file was not saved. Fel vid skrivande av fil; filen sparades inte. Other payees Övriga mottagare Other payers Övriga utbetalare Time Tid %1/%2 %1: Category; %2: Payee/Payer %1/%2 Default Standard Tags Etiketter All Accounts Combined Alla konton kombinerade All Accounts Split Alla konton uppdelade All Payees/Payers Split Alla mottagare/utbetalare uppdelade No payee/payer Ingen mottagare/utbetalare All Tags Split Alla etiketter uppdelade Other tags Övriga etiketter Other payees/payers Övriga mottagare/utbetalare Value Värde Daily average value Genomsnittligt dagligt värde Daily average profit Genomsnittlig daglig förtjänst Daily average income Genomsnittlig daglig inkomst Daily average cost Genomsnittlig daglig kostnad Average income Genomsnittlig inkomst Average cost Genomsnittlig kostnad Monthly value Månatligt värde Monthly profit Månatlig förtjänst Monthly income Månatlig inkomst Monthly cost Månatlig kostnad Includes scheduled and budgeted transactions Inkluderar planerade och budgeterade transaktioner Includes scheduled transactions Inkluderar planerade transaktioner Incomes, %2: 1 Inkomster, %2: 1 Tags, %1 Etiketter, %1 Incomes − Expenses, %1 Inkomster − utgifter, %1 Incomes − Expenses Inkomster − utgifter Excluding any profits or losses in trading of security shares Financial security (e.g. stock, mutual fund) Exklusive vinster eller förluster från handel med värdepapper %2: %1 %2: %1 %3: %2, %1 %3: %2, %1 %2, %1 %2, %1 %4: %3, %2, %1 %4: %3, %2, %1 %3, %2, %1 %3: %2, %1 %1/%2 %1: Description; %2: Payer/Payer %1/%2 %1/%2 %1: Description; %2: Payee/Payer %1/%2 no payer ingen utbetalare no payee ingen mottagare OverTimeChartDialog Chart Diagram OverTimeReport Save As… Spara som… Print… Skriv ut… Source: Källa: Profits Förtjänst Expenses Utgifter Incomes Inkomster Tags Etiketter All Categories Combined Alla kategorier kombinerade Columns: Kolumner: Categories Kategorier Total: Totalt: Value Värde Daily Dagligen Monthly Månadsvis Yearly Årligen Quantity Kvantitet Average value Genomsnittligt värde All Descriptions Combined Referring to the transaction description property (transaction title/generic article name) Alla benämningar kombinerade Assets & Liabilities Tillgångar och skulder All Accounts Alla konton No description Referring to the transaction description property (transaction title/generic article name) Ingen benämning Error Fel Couldn't open file for writing. Kunde inte öppna och skriva till filen. Error while writing file; file was not saved. Fel vid skrivande av fil; filen sparades inte. Average Profit Genomsnittlig förtjänst Incomes, %1 Inkomster, %1 Average Income Genomsnittlig inkomst Expenses, %1 Utgifter, %1 Average Cost Genomsnittlig kostnad Incomes, %2: %1 Inkomster, %2: %1 Incomes: %1 Inkomster: %1 Expenses, %2: %1 Utgifter, %2: %1 Expenses: %1 Utgifter: %1 Incomes, %3: %2, %1 Inkomster, %3: %2, %1 Incomes: %2, %1 Inkomster: %2, %1 Expenses, %3: %2, %1 Utgifter, %3: %2, %1 Expenses: %2, %1 Utgifter: %2, %1 Change: %1 Noun, how much the account balance has changed Förändring: %1 Average Change Genomsnittlig förändring Change Noun, how much the account balance has changed Förändring Value: %1 Värde: %1 Year År Month Månad Assets Tillgångar Deposit Insättning Withdrawal Uttag Liabilities Skulder %2: %1 %2: %1 %1 %1 Average Value Genomsnittligt värde %3: %2, %1 %3: %2, %1 %2, %1 %2, %1 Daily Average Dagligt genomsnitt Monthly Average Månatligt genomsnitt Yearly Average Årligt genomsnitt Subtotal Delsumma Total Summa Deposit Money put into account Insättning Withdrawal Money taken out from account Uttag Includes scheduled transactions Inkluderar planerade transaktioner Adjusted for the average month / year (%1 / %2 days) Justerad för den genomsnittliga månaden / året (%1 / %2 dagar) OverTimeReportDialog Report Rapport QApplication Start with expenses list displayed Starta med utgiftslistan visad Start with incomes list displayed Starta med inkomstslistan visad Start with transfers list displayed Starta med överföringslistan visad Synchronize file Synkronisera fil Document to open Dokument att öppna %1 is already running. %1 körs redan. QObject Transfer Överföring Dividend Utdelning Income Inkomst Expense Utgift Securities Purchase Financial security (e.g. stock, mutual fund) Värdepappersköp Securities Sale Financial security (e.g. stock, mutual fund) Värdepappersförsäljning Debt Payment Skuldbetalning Split Transaction Delad transaktion RecurrenceEditWidget Enable recurrence Aktivera återkomst Recurrence Rule Regler för återkommande Daily Dagligen Weekly Veckovis Monthly Månadsvis Yearly Årligen Recur every Återkom efter day(s) dag(ar) week(s) on: vecka/veckor på: month(s), after the start month månad(er), efter startdatum Recur on the Återkom den 1st 1:a 2nd 2:a 3rd 3:e 4th 4:e 5th 5:e 6th 6:e 7th 7:e 8th 8:e 9th 9:e 10th 10:e 11th 11:e 12th 12:e 13th 13:e 14th 14:e 15th 15:e 16th 16:e 17th 17:e 18th 18:e 19th 19:e 20th 20:e 21st 21:a 22nd 22:a 23rd 23:e 24th 24:e 25th 25:e 26th 26:e 27th 27:e 28th 28:e 29th 29:e 30th 30:e 31st 31:a Last Sista 2nd Last Näst sista 3rd Last 3:e sista 4th Last 4:e sista 5th Last 5:e sista day dagen possibly on weekend möjligen på helgen but before weekend men före helgen but after weekend men efter helgen nearest weekend day närmast helgdag year(s), after the start year år, efter startåret on nearest weekday på närmaste vardag Recur on day part before XXX of 'Recur on day XXX of month YYY' Återkom dag of part between XXX and YYY of 'Recur on day XXX of month YYY' i On the Part before NNN in 'Recur on the NNN. WEEKDAY of MONTH' På den of part between WEEKDAY and MONTH in 'Recur on NNN. WEEKDAY of MONTH' i Recur on day # Återkom på dag # of the year part after NNN of 'Recur on day #NNN of the year' av året Range… Omfång… Occurrences/Exceptions… Förekomster/undantag… Error Fel No day of week selected for weekly recurrence. Ingen veckodag vald för upprepning. Selected day will never occur with selected frequency and start date. Vald dag kommer aldrig att inträffa med vald frekvens och startdatum. Selected day does not exist in selected month. Vald dag existerar inte i vald månad. RefundDialog Repayment Återbetalning Refund Återbetalning Date: Datum: Cost: Kostnad: Income: Inkomst: Quantity returned: Återlämnad kvantitet: Account: Konto: Quantity: Kvantitet: Payee: Mottagare: Payer: Utbetalare: Comments: Kommentarer: Link Link the transactions together Sammanlänka Join Join the transactions together Sammanslå Error Fel Zero value not allowed. Nollvärde är inte tillåtet. Invalid date. Felaktigt datum. SecurityBuy Security: %1 (bought) Financial security (e.g. stock, mutual fund) Värdepapper: %1 (köpt) SecuritySell Security: %1 (sold) Financial security (e.g. stock, mutual fund) Värdepapper: %1 (sålt) SecurityTransactionsDialog Transactions for %1 Transaktioner för %1 Date Datum Type Typ Value Värde Shares Financial shares Andelar Shares Bought Financial shares Andelar köpta Shares Bought (Recurring) Financial shares Andelar köpta (återkommande) Dividend (Recurring) Utdelning (återkommande) Dividend (Scheduled) Utdelning (planerad) Reinvested Dividend (Recurring) Återinvesterad utdelning (återkommande) Reinvested Dividend (Scheduled) Återinvesterad utdelning (planerad) Recurring Reinvested Dividend Återkommande återinvesterad utdelning Scheduled Reinvested Dividend Planerad återinvesterad utdelning Shares Sold Financial shares Andelar sålda Shares Sold (Exchanged) Shares of one security directly exchanged for shares of another; Financial shares Andelar sålda (flyttade) Shares Bought (Exchanged) Shares of one security directly exchanged for shares of another; Financial shares Andelar köpta (flyttade) Shares Sold (Recurring) Financial shares Andelar sålda (återkommande) Shares Bought (Scheduled) Financial shares Andelar köpta (planerad) Shares Sold (Scheduled) Financial shares Andelar sålda (planerad) Edit… Redigera… Delete Ta bort Dividend Utdelning Reinvested Dividend Återinvesterad utdelning Recurring Dividend Återkommande utdelning Scheduled Dividend Planerad utdelning TagButton no tags inga etiketter TagMenu New tag… Ny etikett… New Tag Ny etikett Tag: Etikett: TransactionEditDialog Edit Expense Redigera utgift Edit Dividend Redigera utdelning Edit Income Redigera inkomst Edit Transfer Redigera överföring Edit Securities Purchase Financial security (e.g. stock, mutual fund) Redigera värdepappersköp Edit Securities Sale Financial security (e.g. stock, mutual fund) Redigera värdepappersförsäljning Edit Reinvested Dividend Redigera återinvesterad utdelning TransactionEditWidget Cost: Kostnad: Income: Inkomst: All Alla Date: Datum: Amount: Värde: Downpayment: Handpenning: Shares added: Financial shares Andelar tillkomna: Value per share: Financial shares Värde per andel: Set security share value Uppdatera kurs för värdepapper Total value: Totalt värde: Quantity: Kvantitet: From: Från: To: Till: Category: Kategori: To account: Till konto: Payer: Utbetalare: From account: Från konto: Downpayment account: Konto för handpenning: Payee: Mottagare: Lender: Långivare: Comments: Kommentarer: No security available. Financial security (e.g. stock, mutual fund) Inget värdepapper finns tillgängligt. Security: Financial security (e.g. stock, mutual fund) Värdepapper: New Security… Financial security (e.g. stock, mutual fund) Nytt värdepapper… Shares bought: Financial shares Köpta andelar: Shares sold: Financial shares Sålda andelar: Price per share: Financial shares Pris per andel: Description: Transaction description property (transaction title/generic article name) Benämning: Transaction title/generic article name Transaktionstitel/allmänt artikelnamn Withdrawal: Uttag: Deposit: Insättning: Withdrawal: Money taken out from account Uttag: Deposit: Money put into account Insättning: Number of items included in the transaction. Entered cost is total cost for all items. Antal enheter inkluderade i transaktionen. Angiven kostnad är total kostnad för alla enheter. Payer of parent split transaction Utbetalare för överordnad delad transaktion Payee of parent split transaction Mottagare för överordnad delad transaktion Tags: Etiketter: Associated file: Associerad fil: Select a file Välj en fil Open the file Öppna filen Related to: Label for linked transactions Relaterad till: New Security Financial security (e.g. stock, mutual fund) Nytt värdepapper Error Fel No suitable account available. Inget lämpligt konto finns tillgängligt. No income category available. Ingen inkomstkategori finns tillgänglig. No suitable account or income category available. Inga lämpliga konton eller inkomstkategorier finns tillgängliga. No expense category available. Ingen utgiftskategori finns tillänglig. Invalid date. Felaktigt datum. Cannot transfer money to and from the same account. Kan inte överföra pengar till och från samma konto. Downpayment must be less than total cost. Handpenningen måste vara lägre än den totala kostnaden. Cannot create a regular transfer to/from a securities account. Kan inte skapa en vanlig överföring till/från ett konto för värdepapper. Cannot create a regular income to a securities account. Kan inte skapa en vanlig inkomst till ett konto för värdepapper. Zero shares not allowed. Noll andelar är inte tillåtet. Zero value not allowed. Noll värde är inte tillåtet. Zero price per share not allowed. Noll pris per andel är inte tillåtet. Cannot create a regular expense from a securities account. Kan inte skapa en normal utgift från ett konto för värdepapper. Loan for %1 Lån för %1 New Tag Ny etikett Tag: Etikett: TransactionFilterWidget From: Från: To: Till: Min amount: Lägsta värde: Max amount: Högsta värde: Category: Kategori: To account: Till konto: Min income: Lägsta inkomst: Max income: Högsta inkomst: From account: Från konto: Min cost: Lägsta kostnad: Max cost: Högsta kostnad: Description: Transaction description property (transaction title/generic article name) Beskrivning: Tag: Etikett: Payer: Utbetalare: Payee: Mottagare: Include Inkludera Exclude Exkludera Exact match Exakt matchning Exclude subcategories Uteslut underkategorier Clear Töm All Alla Error Fel Invalid date. Felaktigt datum. To date is before from date. Slutdatum är före startdatum. From date is after to date. Startdatum är efter slutdatum. TransactionListWidget Date Datum Cost Kostnad Category Kategori From Account Från konto Payee Mottagare Tags Etiketter Income Inkomst To Account Till konto Payer Utbetalare Amount Värde From Från To Till Comments Kommentarer Add Lägg till Apply Verkställ Delete Ta bort * Part of <a href="%1">split transaction</a> * Del av <a href="%1">delad transaktion</a> Description Transaction description property (transaction title/generic article name) Benämning New/Edit Expense Ny/ändra utgift New/Edit Income Ny/ändra inkomst New/Edit Transfer Ny/ändra överföring Filter Filter Quantity: Kvantitet: Total: Summa: Average: Genomsnitt: Clear Töm Cost: Kostnad: Monthly: Månadsvis: Sort by creation time Sortera efter bokföringstidpunkt Expenses Utgifter Incomes Inkomster Transfers Överföringar Quantity Kvantitet Right align Högerjustera Total cost: Total kostnad: Total income: Total inkomst: Total amount: Totalt värde: Monthly average: Månatligt genomsnitt: Error Fel Cannot set the value of security transactions using the dialog for modifying multiple transactions. Financial security (e.g. stock, mutual fund) Kan inte ange värde för värdepapperstransaktioner med dialogen för att modifier flera transaktioner. Cannot change description of dividends and security transactions. Referring to the transaction description property (transaction title/generic article name); Financial security (e.g. stock, mutual fund) Kan inte ändra beskrivning för utdelningar och värdepapperstransaktioner. Cannot change payer of dividends and security transactions. Financial security (e.g. stock, mutual fund) Kan inte ändra utbetalare för utdelningar och värdepapperstransaktioner. Cannot change date, description, expense category or payee of transactions that are part of a debt payment using the dialog for modifying multiple transactions. Referring to the transaction description property (transaction title/generic article name) Datum, benämning, utgiftskategori och mottagare kan inte ändras för skuldbetalningar i dialogen för att ändra flera transaktioner. Cannot change date of transactions that are part of a split transaction, unless all individual transactions are selected. Kan inte ändra datum på transaktioner som ingår i en delad transaktion, såvida inte alla enskilda transaktioner är valda. Cannot change date of transactions that are part of a split transaction, unless all transactions are selected. Kan inte ändra datum på transaktioner som ingår i en delad transaktion, såvida inte alla transaktioner är valda. Cannot change date or payee/payer of transactions that are part of a split transaction or debt payment, unless all transactions are selected. Datum, benämning, utgiftskategori och mottagare kan inte ändras för skuldbetalningar i dialogen för att ändra flera transaktioner, såvida inte alla transaktioner är valda. Cannot change date or payee/payer of transactions that are part of a split transaction. Kan inte ändra datum eller mottagare/utbetalare på transaktioner som ingår i en delad transaktion. Delete transactions? Ta bort transaktioner? Are you sure you want to delete all (%1) transactions in the selected split transaction? Vill du verkligen ta bort alla (%1) transaktioner i den valda delade transaktionen? Join as multiple accounts/payments? Sammanfoga som flera konton/betalning? Do you wish join the selected expenses as an expense with multiple accounts/payments? Vill du sammanfoga de valda utgifterna som en utgift med flera konton/betalningar? Do you wish join the selected incomes as an income with multiple accounts/payments? Vill du sammanfoga de valda inkomsterna som en inkomst med flera konton/betalningar? Are you sure you want to delete all (%1) selected transactions? Vill du verkligen ta bort alla (%1) valda transaktioner? * Part of split transaction * Del av delad transaktion * Part of split (%1) * Del av delad transaktion (%1) ** Recurring (editing occurrence) ** Återkommande (redigerar tillfälle) * Part of <a href="split transaction">split transaction</a> * Del av <a href="split transaction">delad transaktion</a> Modify… Ändra… Edit… Redigera… currencies.xml U.S. Dollar Amerikansk dollar Japansese Yen Japansk yen Bulgarian Lev Bulgarisk lev Czech Koruna Tjeckisk koruna Danish Krone Dansk krona British Pound Brittiskt pund Hungarian Forint Ungersk forint Polish Zloty Polsk zloty Romanian New Leu Rumänsk ny leu Swedish Krona Svensk krona Swiss Franc Schweizisk franc Norwegian Krone Norsk krona Croatian Kuna Kroatisk kuna Russian Ruble Rysk rubel Turkish New Lira Turkisk ny lira Australian Dollar Australiensisk dollar Brazilian Real Braziliansk real Canadian Dollar Kanadensisk dollar Chinese Yuan Renminbi Kinesisk yuan renminbi Hong Kong Dollar Hong Kong-dollar Indonesian Rupiah Indonesisk rupe Israeli New Sheqel Israelisk sheqel Indian Rupee Indisk rupie South Korean Won Sydkoreansk won Mexican Peso Mexikansk peso Malaysian Ringgit Malaysisk ringgit New Zeeland Dollar Nya Zeeländsk dollar Philippine Peso Filippinsk peso Singapore Dollar Singapore-dollar Thai Baht Thailändsk baht South African Rand Sydafrikansk rand Eqonomize-1.5.3/translations/pt_BR-phrasebook.qph000066400000000000000000000053461416454732000221000ustar00rootroot00000000000000 Income Receita Em alguns contextos, "Renda" foi utilizado como tradução. Assets Ativos Liabilities Passivos Profit Lucro Expenses Despesas Debt Dívida Fee Taxa Rate Tarifa Interest Juros Ledger Livro de registros Livro razão é a tradução direta mas optei por utilizar esse termo pois é menos técnico Lender Credor Issuer Emissor Bandeira do cartão de crédito Payee Beneficiário Quem recebe a outra parte da transação Securities Títulos Quotes Cotações Shares Ações Loan Empréstimo Transaction Account Conta de transações Savings Account Conta poupança Checking Account Conta corrente Repayment Reembolso Refund Reembolso Split Transaction Transação dividida Split Parte Reinvested Reinvestido Range Duração Tag Etiqueta Join Unir (New Entry) Balancing balanço Eqonomize-1.5.3/winicon.rc000066400000000000000000000001061416454732000154650ustar00rootroot00000000000000IDI_ICON1 ICON DISCARDABLE "data/eqonomize.ico"