pax_global_header00006660000000000000000000000064122700150010014476gustar00rootroot0000000000000052 comment=d327d7be8bbea09d7c3cc38600db0128112a9d55 vokoscreen-1.9.0/000077500000000000000000000000001227001500100136635ustar00rootroot00000000000000vokoscreen-1.9.0/.gitignore000066400000000000000000000005461227001500100156600ustar00rootroot00000000000000# Compiled Object files *.slo *.lo *.o # Compiled Dynamic libraries *.so *.so.* *.dylib *.dll # Compiled Static libraries *.lai *.la *.a # Libraries *.lib # Executables *.exe *.out *.app # Qt-es *.pro.user *.pro.user.* moc_*.cpp qrc_*.cpp Makefile *-build-* # Linux/Unixes .* !.tx !.gitignore *~ # vokoscreen language/*.qm vokoscreen # ffmpeg *.log vokoscreen-1.9.0/.tx/000077500000000000000000000000001227001500100143745ustar00rootroot00000000000000vokoscreen-1.9.0/.tx/config000066400000000000000000000002211227001500100155570ustar00rootroot00000000000000[main] host = https://www.transifex.com [vokoscreen.maints] file_filter = language/vokoscreen_.ts #source_file = main.ts source_lang = en vokoscreen-1.9.0/AUTHORS000066400000000000000000000000751227001500100147350ustar00rootroot00000000000000Author: - Volker Kohaupt Publishing: - Michael Kohaupt vokoscreen-1.9.0/CHANGE000066400000000000000000000016301227001500100145330ustar00rootroot000000000000001.8.0 New record area, countdown-timer, avconv support 1.7.0 Save last tab, remove v4l-utils, time display bug, samplerate usb-mikro, filesize statusline, 1.6.7 various changes 1.6.6 Remove autoframe, Sample now via asoundlib 1.6.5 save current tab 1.6.3 Systray Picture 64x64, gui save location 1.6.2 Window without Border, Maximized window is now recorded. 1.6.0 Release NEW: Statusbar, Area size display installed, Select webcam, Installed three settings for magnifier, Font size permanently, Image Audio Synchronization, Webcam noborder, Close menue and save settings, Image Audio Synchronization 1.5.0 Relaese 1.4.15 Rewriting the webcam modul. The package "v4l2-ctl" is no longer needed. 1.4.6 Rewriting the Alsamodul through their own routines. The package "alsa-utils" is no longer needed. 1.4.5 Relaese 1.4.4 Alsa Bug fixed 1.4.2 My own "Xwininfo" routine built-in. The package "Xwininfo" is no longer needed vokoscreen-1.9.0/COPYING000066400000000000000000000431151227001500100147220ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. vokoscreen-1.9.0/CREDITS000066400000000000000000000014511227001500100147040ustar00rootroot00000000000000Many thanks to: Dominique (maintainer for debian/ubuntu packages) Marc Kohaupt (technical ideas) Bersil (translations into Italian and Spanish) Ole "froksen" (danisch translation, source) atilacamurca (brazilian portuguese translation) agaida (code reworking) Karel (dutch translation) Phan Anh (vietnamese translation) Fisiu (maintainer for packman pakages) Rob Frohne (code for timestamp) Fayssal Chamekh (arabic translation) Lowrider (russian translation) Fitoschido (spanish translation) Varga Gabor (hungrian translation) Arthur Titeica (romanian translation) Llumex003 (asturian translation) zeugma (turkish translation) Christoph Schenk (swedish translation) Mariuz (polish translation) Adam Kosik (czech translation) Brommer Matthieu ( french translation) And many people who send us good ideas :-) vokoscreen-1.9.0/INSTALL000066400000000000000000000012671227001500100147220ustar00rootroot00000000000000Requires: - Qt 4 - alsa - libX11 - opencv - libmp3lame0 - ffmpeg or avconv - mkvtoolnix Optional: - pulseaudio and pulsaudio-utils BuildRequires: - pkgconfig - libqt4-devel - alsa-devel - libX11-devel - opencv-devel Compile: - get sources - extract vokoscren-.tar or - clone git repository: "git clone https://github.com/vkohaupt/vokoscreen.git" - change into the vokoscreen- directory - run "qmake" - run "make" openSUSE: Install Schemata: QT 4-Development Hint: To check that all external programs are installed, please run vokoscreen on the console and control the output section "---Begin Search external tools---" vokoscreen-1.9.0/QtSingleApplication/000077500000000000000000000000001227001500100175755ustar00rootroot00000000000000vokoscreen-1.9.0/QtSingleApplication/QtLockedFile000066400000000000000000000000321227001500100220210ustar00rootroot00000000000000#include "qtlockedfile.h" vokoscreen-1.9.0/QtSingleApplication/QtSingleApplication000066400000000000000000000000411227001500100234250ustar00rootroot00000000000000#include "qtsingleapplication.h" vokoscreen-1.9.0/QtSingleApplication/qtlocalpeer.cpp000066400000000000000000000147721227001500100226270ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of a Qt Solutions component. ** ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor ** the names of its contributors may be used to endorse or promote ** products derived from this software without specific prior written ** permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ****************************************************************************/ #include "qtlocalpeer.h" #include #include #if defined(Q_OS_WIN) #include #include typedef BOOL(WINAPI*PProcessIdToSessionId)(DWORD,DWORD*); static PProcessIdToSessionId pProcessIdToSessionId = 0; #endif #if defined(Q_OS_UNIX) #include #include #include #endif namespace QtLP_Private { #include "qtlockedfile.cpp" #if defined(Q_OS_WIN) #include "qtlockedfile_win.cpp" #else #include "qtlockedfile_unix.cpp" #endif } const char* QtLocalPeer::ack = "ack"; QtLocalPeer::QtLocalPeer(QObject* parent, const QString &appId) : QObject(parent), id(appId) { QString prefix = id; if (id.isEmpty()) { id = QCoreApplication::applicationFilePath(); #if defined(Q_OS_WIN) id = id.toLower(); #endif prefix = id.section(QLatin1Char('/'), -1); } prefix.remove(QRegExp("[^a-zA-Z]")); prefix.truncate(6); QByteArray idc = id.toUtf8(); quint16 idNum = qChecksum(idc.constData(), idc.size()); socketName = QLatin1String("qtsingleapp-") + prefix + QLatin1Char('-') + QString::number(idNum, 16); #if defined(Q_OS_WIN) if (!pProcessIdToSessionId) { QLibrary lib("kernel32"); pProcessIdToSessionId = (PProcessIdToSessionId)lib.resolve("ProcessIdToSessionId"); } if (pProcessIdToSessionId) { DWORD sessionId = 0; pProcessIdToSessionId(GetCurrentProcessId(), &sessionId); socketName += QLatin1Char('-') + QString::number(sessionId, 16); } #else socketName += QLatin1Char('-') + QString::number(::getuid(), 16); #endif server = new QLocalServer(this); QString lockName = QDir(QDir::tempPath()).absolutePath() + QLatin1Char('/') + socketName + QLatin1String("-lockfile"); lockFile.setFileName(lockName); lockFile.open(QIODevice::ReadWrite); } bool QtLocalPeer::isClient() { if (lockFile.isLocked()) return false; if (!lockFile.lock(QtLP_Private::QtLockedFile::WriteLock, false)) return true; bool res = server->listen(socketName); #if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(4,5,0)) // ### Workaround if (!res && server->serverError() == QAbstractSocket::AddressInUseError) { QFile::remove(QDir::cleanPath(QDir::tempPath())+QLatin1Char('/')+socketName); res = server->listen(socketName); } #endif if (!res) qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString())); QObject::connect(server, SIGNAL(newConnection()), SLOT(receiveConnection())); return false; } bool QtLocalPeer::sendMessage(const QString &message, int timeout) { if (!isClient()) return false; QLocalSocket socket; bool connOk = false; for(int i = 0; i < 2; i++) { // Try twice, in case the other instance is just starting up socket.connectToServer(socketName); connOk = socket.waitForConnected(timeout/2); if (connOk || i) break; int ms = 250; #if defined(Q_OS_WIN) Sleep(DWORD(ms)); #else struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 }; nanosleep(&ts, NULL); #endif } if (!connOk) return false; QByteArray uMsg(message.toUtf8()); QDataStream ds(&socket); ds.writeBytes(uMsg.constData(), uMsg.size()); bool res = socket.waitForBytesWritten(timeout); if (res) { res &= socket.waitForReadyRead(timeout); // wait for ack if (res) res &= (socket.read(qstrlen(ack)) == ack); } return res; } void QtLocalPeer::receiveConnection() { QLocalSocket* socket = server->nextPendingConnection(); if (!socket) return; while (socket->bytesAvailable() < (int)sizeof(quint32)) socket->waitForReadyRead(); QDataStream ds(socket); QByteArray uMsg; quint32 remaining; ds >> remaining; uMsg.resize(remaining); int got = 0; char* uMsgBuf = uMsg.data(); do { got = ds.readRawData(uMsgBuf, remaining); remaining -= got; uMsgBuf += got; } while (remaining && got >= 0 && socket->waitForReadyRead(2000)); if (got < 0) { qWarning("QtLocalPeer: Message reception failed %s", socket->errorString().toLatin1().constData()); delete socket; return; } QString message(QString::fromUtf8(uMsg)); socket->write(ack, qstrlen(ack)); socket->waitForBytesWritten(1000); delete socket; emit messageReceived(message); //### (might take a long time to return) } vokoscreen-1.9.0/QtSingleApplication/qtlocalpeer.h000066400000000000000000000052421227001500100222640ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of a Qt Solutions component. ** ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor ** the names of its contributors may be used to endorse or promote ** products derived from this software without specific prior written ** permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ****************************************************************************/ #ifndef QTLOCALPEER_H #define QTLOCALPEER_H #include #include #include #include "qtlockedfile.h" class QtLocalPeer : public QObject { Q_OBJECT public: QtLocalPeer(QObject *parent = 0, const QString &appId = QString()); bool isClient(); bool sendMessage(const QString &message, int timeout); QString applicationId() const { return id; } Q_SIGNALS: void messageReceived(const QString &message); protected Q_SLOTS: void receiveConnection(); protected: QString id; QString socketName; QLocalServer* server; QtLP_Private::QtLockedFile lockFile; private: static const char* ack; }; #endif // QTLOCALPEER_H vokoscreen-1.9.0/QtSingleApplication/qtlockedfile.cpp000066400000000000000000000137441227001500100227600ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of a Qt Solutions component. ** ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor ** the names of its contributors may be used to endorse or promote ** products derived from this software without specific prior written ** permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ****************************************************************************/ #include "qtlockedfile.h" /*! \class QtLockedFile \brief The QtLockedFile class extends QFile with advisory locking functions. A file may be locked in read or write mode. Multiple instances of \e QtLockedFile, created in multiple processes running on the same machine, may have a file locked in read mode. Exactly one instance may have it locked in write mode. A read and a write lock cannot exist simultaneously on the same file. The file locks are advisory. This means that nothing prevents another process from manipulating a locked file using QFile or file system functions offered by the OS. Serialization is only guaranteed if all processes that access the file use QLockedFile. Also, while holding a lock on a file, a process must not open the same file again (through any API), or locks can be unexpectedly lost. The lock provided by an instance of \e QtLockedFile is released whenever the program terminates. This is true even when the program crashes and no destructors are called. */ /*! \enum QtLockedFile::LockMode This enum describes the available lock modes. \value ReadLock A read lock. \value WriteLock A write lock. \value NoLock Neither a read lock nor a write lock. */ /*! Constructs an unlocked \e QtLockedFile object. This constructor behaves in the same way as \e QFile::QFile(). \sa QFile::QFile() */ QtLockedFile::QtLockedFile() : QFile() { #ifdef Q_OS_WIN wmutex = 0; rmutex = 0; #endif m_lock_mode = NoLock; } /*! Constructs an unlocked QtLockedFile object with file \a name. This constructor behaves in the same way as \e QFile::QFile(const QString&). \sa QFile::QFile() */ QtLockedFile::QtLockedFile(const QString &name) : QFile(name) { #ifdef Q_OS_WIN wmutex = 0; rmutex = 0; #endif m_lock_mode = NoLock; } /*! Opens the file in OpenMode \a mode. This is identical to QFile::open(), with the one exception that the Truncate mode flag is disallowed. Truncation would conflict with the advisory file locking, since the file would be modified before the write lock is obtained. If truncation is required, use resize(0) after obtaining the write lock. Returns true if successful; otherwise false. \sa QFile::open(), QFile::resize() */ bool QtLockedFile::open(OpenMode mode) { if (mode & QIODevice::Truncate) { qWarning("QtLockedFile::open(): Truncate mode not allowed."); return false; } return QFile::open(mode); } /*! Returns \e true if this object has a in read or write lock; otherwise returns \e false. \sa lockMode() */ bool QtLockedFile::isLocked() const { return m_lock_mode != NoLock; } /*! Returns the type of lock currently held by this object, or \e QtLockedFile::NoLock. \sa isLocked() */ QtLockedFile::LockMode QtLockedFile::lockMode() const { return m_lock_mode; } /*! \fn bool QtLockedFile::lock(LockMode mode, bool block = true) Obtains a lock of type \a mode. The file must be opened before it can be locked. If \a block is true, this function will block until the lock is aquired. If \a block is false, this function returns \e false immediately if the lock cannot be aquired. If this object already has a lock of type \a mode, this function returns \e true immediately. If this object has a lock of a different type than \a mode, the lock is first released and then a new lock is obtained. This function returns \e true if, after it executes, the file is locked by this object, and \e false otherwise. \sa unlock(), isLocked(), lockMode() */ /*! \fn bool QtLockedFile::unlock() Releases a lock. If the object has no lock, this function returns immediately. This function returns \e true if, after it executes, the file is not locked by this object, and \e false otherwise. \sa lock(), isLocked(), lockMode() */ /*! \fn QtLockedFile::~QtLockedFile() Destroys the \e QtLockedFile object. If any locks were held, they are released. */ vokoscreen-1.9.0/QtSingleApplication/qtlockedfile.h000066400000000000000000000063271227001500100224240ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of a Qt Solutions component. ** ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor ** the names of its contributors may be used to endorse or promote ** products derived from this software without specific prior written ** permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ****************************************************************************/ #ifndef QTLOCKEDFILE_H #define QTLOCKEDFILE_H #include #ifdef Q_OS_WIN #include #endif #if defined(Q_WS_WIN) # if !defined(QT_QTLOCKEDFILE_EXPORT) && !defined(QT_QTLOCKEDFILE_IMPORT) # define QT_QTLOCKEDFILE_EXPORT # elif defined(QT_QTLOCKEDFILE_IMPORT) # if defined(QT_QTLOCKEDFILE_EXPORT) # undef QT_QTLOCKEDFILE_EXPORT # endif # define QT_QTLOCKEDFILE_EXPORT __declspec(dllimport) # elif defined(QT_QTLOCKEDFILE_EXPORT) # undef QT_QTLOCKEDFILE_EXPORT # define QT_QTLOCKEDFILE_EXPORT __declspec(dllexport) # endif #else # define QT_QTLOCKEDFILE_EXPORT #endif namespace QtLP_Private { class QT_QTLOCKEDFILE_EXPORT QtLockedFile : public QFile { public: enum LockMode { NoLock = 0, ReadLock, WriteLock }; QtLockedFile(); QtLockedFile(const QString &name); ~QtLockedFile(); bool open(OpenMode mode); bool lock(LockMode mode, bool block = true); bool unlock(); bool isLocked() const; LockMode lockMode() const; private: #ifdef Q_OS_WIN Qt::HANDLE wmutex; Qt::HANDLE rmutex; QVector rmutexes; QString mutexname; Qt::HANDLE getMutexHandle(int idx, bool doCreate); bool waitMutex(Qt::HANDLE mutex, bool doBlock); #endif LockMode m_lock_mode; }; } #endif vokoscreen-1.9.0/QtSingleApplication/qtlockedfile_unix.cpp000066400000000000000000000066161227001500100240230ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of a Qt Solutions component. ** ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor ** the names of its contributors may be used to endorse or promote ** products derived from this software without specific prior written ** permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ****************************************************************************/ #include #include #include #include #include "qtlockedfile.h" bool QtLockedFile::lock(LockMode mode, bool block) { if (!isOpen()) { qWarning("QtLockedFile::lock(): file is not opened"); return false; } if (mode == NoLock) return unlock(); if (mode == m_lock_mode) return true; if (m_lock_mode != NoLock) unlock(); struct flock fl; fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 0; fl.l_type = (mode == ReadLock) ? F_RDLCK : F_WRLCK; int cmd = block ? F_SETLKW : F_SETLK; int ret = fcntl(handle(), cmd, &fl); if (ret == -1) { if (errno != EINTR && errno != EAGAIN) qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno)); return false; } m_lock_mode = mode; return true; } bool QtLockedFile::unlock() { if (!isOpen()) { qWarning("QtLockedFile::unlock(): file is not opened"); return false; } if (!isLocked()) return true; struct flock fl; fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 0; fl.l_type = F_UNLCK; int ret = fcntl(handle(), F_SETLKW, &fl); if (ret == -1) { qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno)); return false; } m_lock_mode = NoLock; return true; } QtLockedFile::~QtLockedFile() { if (isOpen()) unlock(); } vokoscreen-1.9.0/QtSingleApplication/qtlockedfile_win.cpp000066400000000000000000000145621227001500100236340ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of a Qt Solutions component. ** ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor ** the names of its contributors may be used to endorse or promote ** products derived from this software without specific prior written ** permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ****************************************************************************/ #include "qtlockedfile.h" #include #include #define MUTEX_PREFIX "QtLockedFile mutex " // Maximum number of concurrent read locks. Must not be greater than MAXIMUM_WAIT_OBJECTS #define MAX_READERS MAXIMUM_WAIT_OBJECTS Qt::HANDLE QtLockedFile::getMutexHandle(int idx, bool doCreate) { if (mutexname.isEmpty()) { QFileInfo fi(*this); mutexname = QString::fromLatin1(MUTEX_PREFIX) + fi.absoluteFilePath().toLower(); } QString mname(mutexname); if (idx >= 0) mname += QString::number(idx); Qt::HANDLE mutex; if (doCreate) { QT_WA( { mutex = CreateMutexW(NULL, FALSE, (TCHAR*)mname.utf16()); }, { mutex = CreateMutexA(NULL, FALSE, mname.toLocal8Bit().constData()); } ); if (!mutex) { qErrnoWarning("QtLockedFile::lock(): CreateMutex failed"); return 0; } } else { QT_WA( { mutex = OpenMutexW(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, (TCHAR*)mname.utf16()); }, { mutex = OpenMutexA(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, mname.toLocal8Bit().constData()); } ); if (!mutex) { if (GetLastError() != ERROR_FILE_NOT_FOUND) qErrnoWarning("QtLockedFile::lock(): OpenMutex failed"); return 0; } } return mutex; } bool QtLockedFile::waitMutex(Qt::HANDLE mutex, bool doBlock) { Q_ASSERT(mutex); DWORD res = WaitForSingleObject(mutex, doBlock ? INFINITE : 0); switch (res) { case WAIT_OBJECT_0: case WAIT_ABANDONED: return true; break; case WAIT_TIMEOUT: break; default: qErrnoWarning("QtLockedFile::lock(): WaitForSingleObject failed"); } return false; } bool QtLockedFile::lock(LockMode mode, bool block) { if (!isOpen()) { qWarning("QtLockedFile::lock(): file is not opened"); return false; } if (mode == NoLock) return unlock(); if (mode == m_lock_mode) return true; if (m_lock_mode != NoLock) unlock(); if (!wmutex && !(wmutex = getMutexHandle(-1, true))) return false; if (!waitMutex(wmutex, block)) return false; if (mode == ReadLock) { int idx = 0; for (; idx < MAX_READERS; idx++) { rmutex = getMutexHandle(idx, false); if (!rmutex || waitMutex(rmutex, false)) break; CloseHandle(rmutex); } bool ok = true; if (idx >= MAX_READERS) { qWarning("QtLockedFile::lock(): too many readers"); rmutex = 0; ok = false; } else if (!rmutex) { rmutex = getMutexHandle(idx, true); if (!rmutex || !waitMutex(rmutex, false)) ok = false; } if (!ok && rmutex) { CloseHandle(rmutex); rmutex = 0; } ReleaseMutex(wmutex); if (!ok) return false; } else { Q_ASSERT(rmutexes.isEmpty()); for (int i = 0; i < MAX_READERS; i++) { Qt::HANDLE mutex = getMutexHandle(i, false); if (mutex) rmutexes.append(mutex); } if (rmutexes.size()) { DWORD res = WaitForMultipleObjects(rmutexes.size(), rmutexes.constData(), TRUE, block ? INFINITE : 0); if (res != WAIT_OBJECT_0 && res != WAIT_ABANDONED) { if (res != WAIT_TIMEOUT) qErrnoWarning("QtLockedFile::lock(): WaitForMultipleObjects failed"); m_lock_mode = WriteLock; // trick unlock() to clean up - semiyucky unlock(); return false; } } } m_lock_mode = mode; return true; } bool QtLockedFile::unlock() { if (!isOpen()) { qWarning("QtLockedFile::unlock(): file is not opened"); return false; } if (!isLocked()) return true; if (m_lock_mode == ReadLock) { ReleaseMutex(rmutex); CloseHandle(rmutex); rmutex = 0; } else { foreach(Qt::HANDLE mutex, rmutexes) { ReleaseMutex(mutex); CloseHandle(mutex); } rmutexes.clear(); ReleaseMutex(wmutex); } m_lock_mode = QtLockedFile::NoLock; return true; } QtLockedFile::~QtLockedFile() { if (isOpen()) unlock(); if (wmutex) CloseHandle(wmutex); } vokoscreen-1.9.0/QtSingleApplication/qtsingleapplication.cpp000066400000000000000000000267061227001500100243660ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of a Qt Solutions component. ** ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor ** the names of its contributors may be used to endorse or promote ** products derived from this software without specific prior written ** permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ****************************************************************************/ #include "qtsingleapplication.h" #include "qtlocalpeer.h" #include /*! \class QtSingleApplication qtsingleapplication.h \brief The QtSingleApplication class provides an API to detect and communicate with running instances of an application. This class allows you to create applications where only one instance should be running at a time. I.e., if the user tries to launch another instance, the already running instance will be activated instead. Another usecase is a client-server system, where the first started instance will assume the role of server, and the later instances will act as clients of that server. By default, the full path of the executable file is used to determine whether two processes are instances of the same application. You can also provide an explicit identifier string that will be compared instead. The application should create the QtSingleApplication object early in the startup phase, and call isRunning() to find out if another instance of this application is already running. If isRunning() returns false, it means that no other instance is running, and this instance has assumed the role as the running instance. In this case, the application should continue with the initialization of the application user interface before entering the event loop with exec(), as normal. The messageReceived() signal will be emitted when the running application receives messages from another instance of the same application. When a message is received it might be helpful to the user to raise the application so that it becomes visible. To facilitate this, QtSingleApplication provides the setActivationWindow() function and the activateWindow() slot. If isRunning() returns true, another instance is already running. It may be alerted to the fact that another instance has started by using the sendMessage() function. Also data such as startup parameters (e.g. the name of the file the user wanted this new instance to open) can be passed to the running instance with this function. Then, the application should terminate (or enter client mode). If isRunning() returns true, but sendMessage() fails, that is an indication that the running instance is frozen. Here's an example that shows how to convert an existing application to use QtSingleApplication. It is very simple and does not make use of all QtSingleApplication's functionality (see the examples for that). \code // Original int main(int argc, char **argv) { QApplication app(argc, argv); MyMainWidget mmw; mmw.show(); return app.exec(); } // Single instance int main(int argc, char **argv) { QtSingleApplication app(argc, argv); if (app.isRunning()) return !app.sendMessage(someDataString); MyMainWidget mmw; app.setActivationWindow(&mmw); mmw.show(); return app.exec(); } \endcode Once this QtSingleApplication instance is destroyed (normally when the process exits or crashes), when the user next attempts to run the application this instance will not, of course, be encountered. The next instance to call isRunning() or sendMessage() will assume the role as the new running instance. For console (non-GUI) applications, QtSingleCoreApplication may be used instead of this class, to avoid the dependency on the QtGui library. \sa QtSingleCoreApplication */ void QtSingleApplication::sysInit(const QString &appId) { actWin = 0; peer = new QtLocalPeer(this, appId); connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&))); } /*! Creates a QtSingleApplication object. The application identifier will be QCoreApplication::applicationFilePath(). \a argc, \a argv, and \a GUIenabled are passed on to the QAppliation constructor. If you are creating a console application (i.e. setting \a GUIenabled to false), you may consider using QtSingleCoreApplication instead. */ QtSingleApplication::QtSingleApplication(int &argc, char **argv, bool GUIenabled) : QApplication(argc, argv, GUIenabled) { sysInit(); } /*! Creates a QtSingleApplication object with the application identifier \a appId. \a argc and \a argv are passed on to the QAppliation constructor. */ QtSingleApplication::QtSingleApplication(const QString &appId, int &argc, char **argv) : QApplication(argc, argv) { sysInit(appId); } /*! Creates a QtSingleApplication object. The application identifier will be QCoreApplication::applicationFilePath(). \a argc, \a argv, and \a type are passed on to the QAppliation constructor. */ QtSingleApplication::QtSingleApplication(int &argc, char **argv, Type type) : QApplication(argc, argv, type) { sysInit(); } #if defined(Q_WS_X11) /*! Special constructor for X11, ref. the documentation of QApplication's corresponding constructor. The application identifier will be QCoreApplication::applicationFilePath(). \a dpy, \a visual, and \a cmap are passed on to the QApplication constructor. */ QtSingleApplication::QtSingleApplication(Display* dpy, Qt::HANDLE visual, Qt::HANDLE cmap) : QApplication(dpy, visual, cmap) { sysInit(); } /*! Special constructor for X11, ref. the documentation of QApplication's corresponding constructor. The application identifier will be QCoreApplication::applicationFilePath(). \a dpy, \a argc, \a argv, \a visual, and \a cmap are passed on to the QApplication constructor. */ QtSingleApplication::QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap) : QApplication(dpy, argc, argv, visual, cmap) { sysInit(); } /*! Special constructor for X11, ref. the documentation of QApplication's corresponding constructor. The application identifier will be \a appId. \a dpy, \a argc, \a argv, \a visual, and \a cmap are passed on to the QApplication constructor. */ QtSingleApplication::QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap) : QApplication(dpy, argc, argv, visual, cmap) { sysInit(appId); } #endif /*! Returns true if another instance of this application is running; otherwise false. This function does not find instances of this application that are being run by a different user (on Windows: that are running in another session). \sa sendMessage() */ bool QtSingleApplication::isRunning() { return peer->isClient(); } /*! Tries to send the text \a message to the currently running instance. The QtSingleApplication object in the running instance will emit the messageReceived() signal when it receives the message. This function returns true if the message has been sent to, and processed by, the current instance. If there is no instance currently running, or if the running instance fails to process the message within \a timeout milliseconds, this function return false. \sa isRunning(), messageReceived() */ bool QtSingleApplication::sendMessage(const QString &message, int timeout) { return peer->sendMessage(message, timeout); } /*! Returns the application identifier. Two processes with the same identifier will be regarded as instances of the same application. */ QString QtSingleApplication::id() const { return peer->applicationId(); } /*! Sets the activation window of this application to \a aw. The activation window is the widget that will be activated by activateWindow(). This is typically the application's main window. If \a activateOnMessage is true (the default), the window will be activated automatically every time a message is received, just prior to the messageReceived() signal being emitted. \sa activateWindow(), messageReceived() */ void QtSingleApplication::setActivationWindow(QWidget* aw, bool activateOnMessage) { actWin = aw; if (activateOnMessage) connect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow())); else disconnect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow())); } /*! Returns the applications activation window if one has been set by calling setActivationWindow(), otherwise returns 0. \sa setActivationWindow() */ QWidget* QtSingleApplication::activationWindow() const { return actWin; } /*! De-minimizes, raises, and activates this application's activation window. This function does nothing if no activation window has been set. This is a convenience function to show the user that this application instance has been activated when he has tried to start another instance. This function should typically be called in response to the messageReceived() signal. By default, that will happen automatically, if an activation window has been set. \sa setActivationWindow(), messageReceived(), initialize() */ void QtSingleApplication::activateWindow() { if (actWin) { actWin->setWindowState(actWin->windowState() & ~Qt::WindowMinimized); actWin->raise(); actWin->activateWindow(); } } /*! \fn void QtSingleApplication::messageReceived(const QString& message) This signal is emitted when the current instance receives a \a message from another instance of this application. \sa sendMessage(), setActivationWindow(), activateWindow() */ /*! \fn void QtSingleApplication::initialize(bool dummy = true) \obsolete */ vokoscreen-1.9.0/QtSingleApplication/qtsingleapplication.h000066400000000000000000000075151227001500100240300ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of a Qt Solutions component. ** ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor ** the names of its contributors may be used to endorse or promote ** products derived from this software without specific prior written ** permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ****************************************************************************/ #ifndef QTSINGLEAPPLICATION_H #define QTSINGLEAPPLICATION_H #include class QtLocalPeer; #if defined(Q_WS_WIN) # if !defined(QT_QTSINGLEAPPLICATION_EXPORT) && !defined(QT_QTSINGLEAPPLICATION_IMPORT) # define QT_QTSINGLEAPPLICATION_EXPORT # elif defined(QT_QTSINGLEAPPLICATION_IMPORT) # if defined(QT_QTSINGLEAPPLICATION_EXPORT) # undef QT_QTSINGLEAPPLICATION_EXPORT # endif # define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllimport) # elif defined(QT_QTSINGLEAPPLICATION_EXPORT) # undef QT_QTSINGLEAPPLICATION_EXPORT # define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllexport) # endif #else # define QT_QTSINGLEAPPLICATION_EXPORT #endif class QT_QTSINGLEAPPLICATION_EXPORT QtSingleApplication : public QApplication { Q_OBJECT public: QtSingleApplication(int &argc, char **argv, bool GUIenabled = true); QtSingleApplication(const QString &id, int &argc, char **argv); QtSingleApplication(int &argc, char **argv, Type type); #if defined(Q_WS_X11) QtSingleApplication(Display* dpy, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0); QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE cmap= 0); QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0); #endif bool isRunning(); QString id() const; void setActivationWindow(QWidget* aw, bool activateOnMessage = true); QWidget* activationWindow() const; // Obsolete: void initialize(bool dummy = true) { isRunning(); Q_UNUSED(dummy) } public Q_SLOTS: bool sendMessage(const QString &message, int timeout = 5000); void activateWindow(); Q_SIGNALS: void messageReceived(const QString &message); private: void sysInit(const QString &appId = QString()); QtLocalPeer *peer; QWidget *actWin; }; #endif // QTSINGLEAPPLICATION_H vokoscreen-1.9.0/QtSingleApplication/qtsingleapplication.pri000066400000000000000000000010011227001500100243530ustar00rootroot00000000000000INCLUDEPATH += $$PWD DEPENDPATH += $$PWD QT *= network qtsingleapplication-uselib:!qtsingleapplication-buildlib { LIBS += -L$$QTSINGLEAPPLICATION_LIBDIR -l$$QTSINGLEAPPLICATION_LIBNAME } else { SOURCES += $$PWD/qtsingleapplication.cpp $$PWD/qtlocalpeer.cpp HEADERS += $$PWD/qtsingleapplication.h $$PWD/qtlocalpeer.h } win32 { contains(TEMPLATE, lib):contains(CONFIG, shared):DEFINES += QT_QTSINGLEAPPLICATION_EXPORT else:qtsingleapplication-uselib:DEFINES += QT_QTSINGLEAPPLICATION_IMPORT } vokoscreen-1.9.0/QtSingleApplication/qtsinglecoreapplication.cpp000066400000000000000000000123571227001500100252340ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of a Qt Solutions component. ** ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor ** the names of its contributors may be used to endorse or promote ** products derived from this software without specific prior written ** permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ****************************************************************************/ #include "qtsinglecoreapplication.h" #include "qtlocalpeer.h" /*! \class QtSingleCoreApplication qtsinglecoreapplication.h \brief A variant of the QtSingleApplication class for non-GUI applications. This class is a variant of QtSingleApplication suited for use in console (non-GUI) applications. It is an extension of QCoreApplication (instead of QApplication). It does not require the QtGui library. The API and usage is identical to QtSingleApplication, except that functions relating to the "activation window" are not present, for obvious reasons. Please refer to the QtSingleApplication documentation for explanation of the usage. A QtSingleCoreApplication instance can communicate to a QtSingleApplication instance if they share the same application id. Hence, this class can be used to create a light-weight command-line tool that sends commands to a GUI application. \sa QtSingleApplication */ /*! Creates a QtSingleCoreApplication object. The application identifier will be QCoreApplication::applicationFilePath(). \a argc and \a argv are passed on to the QCoreAppliation constructor. */ QtSingleCoreApplication::QtSingleCoreApplication(int &argc, char **argv) : QCoreApplication(argc, argv) { peer = new QtLocalPeer(this); connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&))); } /*! Creates a QtSingleCoreApplication object with the application identifier \a appId. \a argc and \a argv are passed on to the QCoreAppliation constructor. */ QtSingleCoreApplication::QtSingleCoreApplication(const QString &appId, int &argc, char **argv) : QCoreApplication(argc, argv) { peer = new QtLocalPeer(this, appId); connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&))); } /*! Returns true if another instance of this application is running; otherwise false. This function does not find instances of this application that are being run by a different user (on Windows: that are running in another session). \sa sendMessage() */ bool QtSingleCoreApplication::isRunning() { return peer->isClient(); } /*! Tries to send the text \a message to the currently running instance. The QtSingleCoreApplication object in the running instance will emit the messageReceived() signal when it receives the message. This function returns true if the message has been sent to, and processed by, the current instance. If there is no instance currently running, or if the running instance fails to process the message within \a timeout milliseconds, this function return false. \sa isRunning(), messageReceived() */ bool QtSingleCoreApplication::sendMessage(const QString &message, int timeout) { return peer->sendMessage(message, timeout); } /*! Returns the application identifier. Two processes with the same identifier will be regarded as instances of the same application. */ QString QtSingleCoreApplication::id() const { return peer->applicationId(); } /*! \fn void QtSingleCoreApplication::messageReceived(const QString& message) This signal is emitted when the current instance receives a \a message from another instance of this application. \sa sendMessage() */ vokoscreen-1.9.0/QtSingleApplication/qtsinglecoreapplication.h000066400000000000000000000050361227001500100246750ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of a Qt Solutions component. ** ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor ** the names of its contributors may be used to endorse or promote ** products derived from this software without specific prior written ** permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ****************************************************************************/ #ifndef QTSINGLECOREAPPLICATION_H #define QTSINGLECOREAPPLICATION_H #include class QtLocalPeer; class QtSingleCoreApplication : public QCoreApplication { Q_OBJECT public: QtSingleCoreApplication(int &argc, char **argv); QtSingleCoreApplication(const QString &id, int &argc, char **argv); bool isRunning(); QString id() const; public Q_SLOTS: bool sendMessage(const QString &message, int timeout = 5000); Q_SIGNALS: void messageReceived(const QString &message); private: QtLocalPeer* peer; }; #endif // QTSINGLECOREAPPLICATION_H vokoscreen-1.9.0/QtSingleApplication/qtsinglecoreapplication.pri000066400000000000000000000005041227001500100252330ustar00rootroot00000000000000INCLUDEPATH += $$PWD DEPENDPATH += $$PWD HEADERS += $$PWD/qtsinglecoreapplication.h $$PWD/qtlocalpeer.h SOURCES += $$PWD/qtsinglecoreapplication.cpp $$PWD/qtlocalpeer.cpp QT *= network win32:contains(TEMPLATE, lib):contains(CONFIG, shared) { DEFINES += QT_QTSINGLECOREAPPLICATION_EXPORT=__declspec(dllexport) } vokoscreen-1.9.0/QvkCredits.cpp000066400000000000000000000072461227001500100164570ustar00rootroot00000000000000 #include "QvkCredits.h" #include #include #include #include #include QvkCredits::QvkCredits() { setWindowFlags( Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint ); if( QX11Info::isCompositingManagerRunning() ) setAttribute( Qt::WA_TranslucentBackground, true ); resize( 600, 600 ); QDesktopWidget *desktop = QApplication::desktop(); int x = ( desktop->width() - width() ) / 2; int y = ( desktop->height() - height() ) / 2; move( x, y ); painter = new QPainter(); } QvkCredits::~QvkCredits() { delete painter; } void QvkCredits::paintEvent( QPaintEvent *event ) { (void)event; painter->begin( this ); QPixmap pixmap( 0, 0 ); pixmap.load( ":/pictures/Scroll.png" ); pixmap = pixmap.scaledToWidth( 550, Qt::SmoothTransformation ); QFont font; font.setPointSize( 10 ); font.setItalic( true ); int x = 155; int y = 155; int deltaX = 6; int deltaY = 15; painter->setPen( Qt::darkYellow ); painter->setFont( font ); painter->drawPixmap( 0, 0, pixmap ); painter->drawText( x - 1 * deltaX, y + 1 * deltaY, "Volker Kohaupt (developer)" ); painter->drawText( x - 2 * deltaX, y + 2 * deltaY, "Michael Kohaupt (public relations, support)" ); painter->drawText( x - 3 * deltaX, y + 3 * deltaY, "Dominique (maintainer for debian/ubuntu packages)" ); painter->drawText( x - 4 * deltaX, y + 4 * deltaY, "Marc Kohaupt (technical ideas)" ); painter->drawText( x - 5 * deltaX, y + 5 * deltaY, "Bersil (translations into Italian and Spanish)" ); painter->drawText( x - 6 * deltaX, y + 6 * deltaY, "atilacamurca (brazilian portuguese translation)" ); painter->drawText( x - 7 * deltaX, y + 7 * deltaY, "agaida (code reworking)" ); painter->drawText( x - 8 * deltaX, y + 8 * deltaY, "Karel (dutch translation)" ); painter->drawText( x - 9 * deltaX, y + 9 * deltaY, "Phan Anh (vietnamese translation)" ); painter->drawText( x - 10 * deltaX, y + 10 * deltaY, "Fisiu (maintainer for packman pakages)" ); painter->drawText( x - 11 * deltaX, y + 11 * deltaY, "Rob Frohne (code for timestamp)" ); painter->drawText( x - 12 * deltaX, y + 12 * deltaY, "Fayssal Chamekh (arabic translation)" ); painter->drawText( x - 13 * deltaX, y + 13 * deltaY, "Lowrider (russian translation)" ); painter->drawText( x - 14 * deltaX, y + 14 * deltaY, "Fitoschido (spanish translation)" ); painter->drawText( x - 15 * deltaX, y + 15 * deltaY, "Varga Gabor (hungrian translation)" ); painter->drawText( x - 16 * deltaX, y + 16 * deltaY, "Arthur Titeica (romanian translation)" ); painter->drawText( x - 17 * deltaX, y + 17 * deltaY, "Llumex003 (asturian translation)" ); painter->drawText( x - 18 * deltaX, y + 18 * deltaY, "zeugma (turkish translation)" ); painter->drawText( x - 18 * deltaX, y + 19 * deltaY, "Christoph Schenk (swedish translation)" ); painter->drawText( x - 18 * deltaX, y + 20 * deltaY, "Mariuz (polish translation)" ); painter->drawText( x - 18 * deltaX, y + 21 * deltaY, "Adam Kosik (czech translation)" ); painter->drawText( x - 18 * deltaX, y + 22 * deltaY, "Brommer Matthieu ( french translation)" ); painter->end(); } void QvkCredits::mousePressEvent ( QMouseEvent * event ) { (void)event; close(); } /** * closeEvent wird ausgelößt wenn das fenster geschloßen wird */ void QvkCredits::closeEvent( QCloseEvent * event ) { //qDebug() << "Begin void QvkCredits::closeEvent( QCloseEvent * event ) *****************************"; (void)event; emit closeCredits(); //qDebug() << "End void QvkCredits::closeEvent( QCloseEvent * event ) *****************************"; } vokoscreen-1.9.0/QvkCredits.h000066400000000000000000000007411227001500100161150ustar00rootroot00000000000000 #ifndef QVKCREDITS_H #define QVKCREDITS_H #include #include #include class QvkCredits: public QMainWindow { Q_OBJECT public: QvkCredits(); virtual ~QvkCredits(); QPainter * painter; signals: void closeCredits(); private slots: private: protected: void mousePressEvent ( QMouseEvent * event ); void paintEvent( QPaintEvent *event ); void closeEvent( QCloseEvent * event ); }; #endif vokoscreen-1.9.0/QvkMagnifier.cpp000066400000000000000000000307661227001500100167660ustar00rootroot00000000000000#include "QvkMagnifier.h" using namespace std; // Lupe Rund, Qadratisch, Oval QvkMagnifier::QvkMagnifier() { faktor = 2; label = new QLabel( this ); Magnifier400x200(); resize( 2 * distanceX * faktor, 2 * distanceY * faktor ); setWindowFlags( Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::ToolTip ); //With tooltip, no entry in Taskbar border = 3; label->setGeometry( QRect( 0 + border, 0 + border, this->width() - 2 * border, this->height() - 2 * border ) ); label->setAlignment( Qt::AlignCenter ); label->setScaledContents( true ); label->show(); QTimer *timer = new QTimer( this ); connect( timer, SIGNAL( timeout() ), this, SLOT( mytimer() ) ); timer->start( 40 ); } void QvkMagnifier::closeEvent( QCloseEvent * event ) { (void)event; emit closeMagnifier(); } void QvkMagnifier::getDialogMagnifier( QWidget *parent ) { QDialog *dialog = new QDialog( parent ); QFont qfont = dialog->font(); qfont.setPixelSize( 12 ); dialog->setFont( qfont ); QLabel* label = new QLabel( dialog ); label->setText(""); label->setGeometry( QRect( 20, 30, 120, 150) ); label->setAlignment( Qt::AlignCenter ); label->show(); QImage* qImage = new QImage( ":/pictures/magnifier.png" ); label->setPixmap( QPixmap::fromImage( *qImage, Qt::AutoColor ) ); label->setScaledContents( true ); radioButton1 = new QRadioButton( dialog ); radioButton1->setGeometry( 170, 50, 200, 21 ); radioButton1->setText( "200 x 200" ); radioButton1->show(); connect( radioButton1, SIGNAL( clicked() ), SLOT( Magnifier200x200() ) ); if ( formValue == 1 ) radioButton1->setChecked( true ); radioButton2 = new QRadioButton( dialog ); radioButton2->setGeometry( 170, 80, 200, 21 ); radioButton2->setText( "400 x 200" ); radioButton2->show(); connect( radioButton2, SIGNAL( clicked() ), SLOT( Magnifier400x200() ) ); if ( formValue == 2 ) radioButton2->setChecked( true ); radioButton3 = new QRadioButton( dialog ); radioButton3->setGeometry( 170, 110, 200, 21 ); radioButton3->setText( "600 x 200" ); radioButton3->show(); connect( radioButton3, SIGNAL( clicked() ), SLOT( Magnifier600x200() ) ); if ( formValue == 3 ) radioButton3->setChecked( true ); QPropertyAnimation *animation = new QPropertyAnimation( dialog, "geometry"); animation->setDuration( 1000 ); animation->setStartValue( QRect( parent->x() + parent->width()/2, parent->y() + parent->height()/2, 0, 0 ) ); animation->setEndValue( QRect( ( parent->x() ) + ( ( parent->width()/2 ) - ( 300/2 ) ), ( parent->y() ) + ( ( parent->height()/2) - ( 200/2 ) ), 300, 200 ) ); animation->setEasingCurve( QEasingCurve::OutBounce ); animation->start(); //dialog->setFixedSize( 300, 200 ); dialog->exec(); } void QvkMagnifier::Magnifier200x200() { distanceX = 50; distanceY = 50; resize( 2 * distanceX * faktor, 2 * distanceY * faktor ); label->setGeometry( QRect( 0 + border, 0 + border, this->width() - 2 * border, this->height() - 2 * border ) ); formValue = 1; } void QvkMagnifier::Magnifier400x200() { distanceX = 100; distanceY = 50; resize( 2 * distanceX * faktor, 2 * distanceY * faktor ); label->setGeometry( QRect( 0 + border, 0 + border, this->width() - 2 * border, this->height() - 2 * border ) ); formValue = 2; } void QvkMagnifier::Magnifier600x200() { distanceX = 150; distanceY = 50; resize( 2 * distanceX * faktor, 2 * distanceY * faktor ); label->setGeometry( QRect( 0 + border, 0 + border, this->width() - 2 * border, this->height() - 2 * border ) ); formValue = 3; } int QvkMagnifier::getDistanceX() { return distanceX; } int QvkMagnifier::getDistanceY() { return distanceY; } int QvkMagnifier::NewDistanceXLeft() { QCursor cursor; QDesktopWidget *desk = QApplication::desktop(); int newDistanceX = ( ( desk->screenGeometry().width() / 2 ) - cursor.pos().x() ) * ( distanceX + ( width() / 2 ) ) / ( desk->screenGeometry().width() / 2 - distanceX ) - ( width() / 2 ); return newDistanceX; } int QvkMagnifier::NewDistanceXRight() { QCursor cursor; QDesktopWidget *desk = QApplication::desktop(); int newDistanX = ( ( desk->screenGeometry().width() / 2 ) - cursor.pos().x() ) * ( -distanceX - ( width() / 2 ) ) / ( desk->screenGeometry().width() / 2 - distanceX ) - ( width() / 2 ); return newDistanX; } QvkMagnifier::~QvkMagnifier() { } void QvkMagnifier::setMagnifier() { QCursor cursor; QDesktopWidget *desk = QApplication::desktop(); // Lupe an oberen linke Ecke setzen if ( ( cursor.pos().x() < distanceX ) and ( cursor.pos().y() < distanceY ) ) { move( 2 * distanceX, 2 * distanceY ); return; } // Lupe obere rechte Ecke setzen if ( ( cursor.pos().x() > ( desk->screenGeometry().width() - distanceX ) ) and ( cursor.pos().y() < distanceY ) ) { move( desk->screenGeometry().width() - 2 * distanceX - width(), 2 * distanceY); return; } // Lupe am oberen Rand setzen // Linke Hälfte am oberen Rand if ( ( cursor.pos().y() < distanceY ) and ( cursor.pos().x() < desk->screenGeometry().width() / 2 ) ) { move( cursor.pos().x() + NewDistanceXLeft(), 2 * distanceY ); return; } // Rechte Hälfte am oberen Rand if ( ( cursor.pos().y() < distanceY ) and ( cursor.pos().x() > desk->screenGeometry().width() / 2 ) ) { move( cursor.pos().x() - NewDistanceXRight() - width(), 2 * distanceY ); return; } // Lupe an untere rechte Ecke setzen if ( ( cursor.pos().x() > desk->screenGeometry().width() - distanceX ) and ( cursor.pos().y() > desk->screenGeometry().height() - distanceY ) ) { move( desk->screenGeometry().width() - ( 2 * distanceX + width() ), desk->screenGeometry().height() - ( 2 * distanceY + height() ) ); return; } // Lupe am rechten Rand setzen // Obere Hälfte am rechten Rand if ( ( cursor.pos().x() > desk->screenGeometry().width() - distanceX ) and ( cursor.pos().y() < desk->screenGeometry().height() / 10 * 8 ) )// div 2 { move( desk->screenGeometry().width() - ( 2 * distanceX + width() ), cursor.pos().y() + 1 * distanceY ); return; } // untere Hälfte am rechten Rand if ( ( cursor.pos().x() > desk->screenGeometry().width() - distanceX ) and ( cursor.pos().y() > desk->screenGeometry().height() / 10 * 8 ) ) { move( desk->screenGeometry().width() - ( 2 * distanceX + width() ), cursor.pos().y() - distanceY - height() ); return; } // Lupe an linken unteren Ecke setzen if ( ( cursor.pos().x() < distanceX ) and ( cursor.pos().y() > desk->screenGeometry().height() - distanceY ) ) { move( 2 * distanceX, desk->screenGeometry().height() - 2 * distanceY - height() ); return; } // Lupe am unteren Rand setzen // Linke Hälfte unterer Rand if ( ( cursor.pos().x() < desk->screenGeometry().width() / 2 ) and ( cursor.pos().y() > desk->screenGeometry().height() - distanceY ) ) { move( cursor.pos().x() + NewDistanceXLeft(), desk->screenGeometry().height() - ( 2 * distanceY + height() ) ); return; } // Rechte Hälfte unterer Rand if ( ( cursor.pos().x() > desk->screenGeometry().width() / 2 ) and ( cursor.pos().y() > desk->screenGeometry().height() - distanceY ) ) { move( cursor.pos().x() - NewDistanceXRight() - width(), desk->screenGeometry().height() - 2 * distanceY - height() ); return; } // Lupe am linken Rand setzen // Obere Hälfte am linken Rand if ( ( cursor.pos().x() < distanceX ) and ( cursor.pos().y() < desk->screenGeometry().height() / 10 * 8 ) ) // div 2 { move( 2 * distanceX, cursor.pos().y() + distanceY ); return; } // Untere Hälfte am linken Rand if ( ( cursor.pos().x() < distanceX ) and ( cursor.pos().y() > desk->screenGeometry().height() / 10 * 8 ) ) { move( 2 * distanceX, cursor.pos().y() - distanceY - height() ); return; } // Linke obere Hälfte if ( ( cursor.pos().x() < desk->screenGeometry().width() / 2 ) and ( cursor.pos().y() < desk->screenGeometry().height() / 10 * 8 ) ) // div 2 move( cursor.pos().x() + NewDistanceXLeft(), cursor.pos().y() + distanceY ); // Rechte obere Hälfte if ( ( cursor.pos().x() > desk->screenGeometry().width() / 2 ) and ( cursor.pos().y() < desk->screenGeometry().height() / 10 * 8 ) ) move( cursor.pos().x() - NewDistanceXRight() - width(), cursor.pos().y() + distanceY ); // Linke untere Hälfte if ( ( cursor.pos().x() < desk->screenGeometry().width() / 2 ) and ( cursor.pos().y() > desk->screenGeometry().height() / 10 * 8 ) ) move( cursor.pos().x() + NewDistanceXLeft(), cursor.pos().y() - distanceY - height() ); // Rechte untere Hälfte if ( ( cursor.pos().x() > desk->screenGeometry().width() / 2 ) and ( cursor.pos().y() > desk->screenGeometry().height() / 10 * 8 ) ) move( cursor.pos().x() - NewDistanceXRight() -width(), cursor.pos().y() - distanceY - width() ); } void QvkMagnifier::mytimer() { QCursor cursor; QDesktopWidget *desk = QApplication::desktop(); // Qt::Window | Qt::WindowStaysOnTopHint setMagnifier(); // Obere linke Ecke if ( ( cursor.pos().x() < distanceX ) and ( cursor.pos().y() < distanceY ) ) { QPixmap originalPixmap = QPixmap(); originalPixmap = QPixmap::grabWindow( QApplication::desktop()->winId(), 0, 0, 2 * distanceX , 2 * distanceY ); label->setPixmap( originalPixmap ); return; } // Obere rechte Ecke if ( ( cursor.pos().x() > ( desk->screenGeometry().width() - distanceX ) ) and ( cursor.pos().y() < distanceY ) ) { QPixmap originalPixmap = QPixmap(); originalPixmap = QPixmap::grabWindow( QApplication::desktop()->winId(), desk->screenGeometry().width() - 2 * distanceX, 0, 2 * distanceX , 2 * distanceY ); label->setPixmap( originalPixmap ); return; } // Linke untere Ecke if ( ( cursor.pos().x() < distanceX ) and ( cursor.pos().y() > desk->screenGeometry().height() - distanceY ) ) { QPixmap originalPixmap = QPixmap(); originalPixmap = QPixmap::grabWindow( QApplication::desktop()->winId(), 0, desk->screenGeometry().height() - 2 * distanceY, 2 * distanceX , 2 * distanceY ); label->setPixmap( originalPixmap ); return; } // Rechte untere Ecke if ( ( cursor.pos().x() > desk->screenGeometry().width() - distanceX ) and ( cursor.pos().y() > desk->screenGeometry().height() - distanceY ) ) { QPixmap originalPixmap = QPixmap(); originalPixmap = QPixmap::grabWindow( QApplication::desktop()->winId(), desk->screenGeometry().width() - 2 * distanceX, desk->screenGeometry().height() - 2 * distanceY, 2 * distanceX , 2 * distanceY ); label->setPixmap( originalPixmap ); return; } // Unterer Rand if ( cursor.pos().y() > desk->screenGeometry().height() - distanceY ) { QPixmap originalPixmap = QPixmap(); originalPixmap = QPixmap::grabWindow( QApplication::desktop()->winId(), cursor.pos().x() - distanceX, desk->screenGeometry().height() - 2 * distanceY, 2 * distanceX , 2 * distanceY ); label->setPixmap( originalPixmap ); return; } // Oberen Rand if ( cursor.pos().y() < distanceY ) { QPixmap originalPixmap = QPixmap(); originalPixmap = QPixmap::grabWindow( QApplication::desktop()->winId(), cursor.pos().x() - distanceX, 0, 2 * distanceX, 2 * distanceY ); label->setPixmap( originalPixmap ); return; } // Rechter Rand if ( cursor.pos().x() > desk->screenGeometry().width() - distanceX ) { QPixmap originalPixmap = QPixmap(); originalPixmap = QPixmap::grabWindow( QApplication::desktop()->winId(), desk->screenGeometry().width() - 2 * distanceX, cursor.pos().y() - distanceY, 2 * distanceX , 2 * distanceY ); label->setPixmap( originalPixmap ); return; } // Linker Rand if ( cursor.pos().x() < distanceX ) { QPixmap originalPixmap = QPixmap(); originalPixmap = QPixmap::grabWindow( QApplication::desktop()->winId(), 0, cursor.pos().y() - distanceY, 2 * distanceX , 2 * distanceY ); label->setPixmap( originalPixmap ); return; } // Fläche QPixmap originalPixmap = QPixmap(); originalPixmap = QPixmap::grabWindow( QApplication::desktop()->winId(), cursor.pos().x() - distanceX, cursor.pos().y() - distanceY, 2 * distanceX , 2 * distanceY ); label->setPixmap( originalPixmap ); } vokoscreen-1.9.0/QvkMagnifier.h000066400000000000000000000017561227001500100164300ustar00rootroot00000000000000#ifndef QvkMagnifier_H #define QvkMagnifier_H #include #include #include #include #include #include #include #include #include #include class QvkMagnifier: public QDialog { Q_OBJECT public: QvkMagnifier(); virtual ~QvkMagnifier(); //QDialog *dialog; public slots: void getDialogMagnifier( QWidget *parent ); private slots: void closeEvent( QCloseEvent * event ); int NewDistanceXLeft(); int NewDistanceXRight(); void mytimer(); void setMagnifier(); void Magnifier200x200(); void Magnifier400x200(); void Magnifier600x200(); int getDistanceX(); int getDistanceY(); protected: signals: void closeMagnifier(); private: QLabel *label; int border; int distanceX; int distanceY; QRadioButton *radioButton1; QRadioButton *radioButton2; QRadioButton *radioButton3; int faktor; int formValue; }; #endif vokoscreen-1.9.0/QvkVersion.cpp000066400000000000000000000043461227001500100165050ustar00rootroot00000000000000#include "QvkVersion.h" QvkVersion::QvkVersion() { connect( &manager, SIGNAL( finished( QNetworkReply* ) ), SLOT( downloadFinished( QNetworkReply* ) ) ); } void QvkVersion::doDownload() { QNetworkRequest request( QUrl( "http://kohaupt-online.de/hp/version/VERSION" ) ); QNetworkReply *reply = manager.get( request ); currentDownloadsQList.append( reply ); } bool QvkVersion::saveToDisk( const QString &remoteFilename, QIODevice *data ) { QFile remoteFile( QDesktopServices::storageLocation ( QDesktopServices::TempLocation ) + QDir::separator() + remoteFilename ); if ( !remoteFile.open( QIODevice::WriteOnly ) ) { fprintf( stderr, "Could not open %s for writing: %s\n", qPrintable( remoteFilename ), qPrintable( remoteFile.errorString() ) ); return false; } remoteFile.write( data->readAll() ); remoteFile.close(); return true; } void QvkVersion::downloadFinished( QNetworkReply *reply ) { QString localVersionFilename = "vokoscreenVERSION"; QUrl url = reply->url(); if ( reply->error() ) { fprintf( stderr, "[vokoscreen] Download of %s failed: %s\n", url.toEncoded().constData(), qPrintable( reply->errorString() ) ); } else { if ( saveToDisk( localVersionFilename, reply ) ) printf( "[vokoscreen] Download of %s succeeded (saved to %s)\n", url.toEncoded().constData(), qPrintable( localVersionFilename ) ); } readVersionTempFile( localVersionFilename ); emit versionDownloadFinish(); } void QvkVersion::readVersionTempFile( QString localVersionFilename ) { QSettings settings( QDesktopServices::storageLocation ( QDesktopServices::TempLocation ) + QDir::separator() + localVersionFilename, QSettings::IniFormat ); settings.beginGroup( "Info" ); setRemoteVersion( settings.value( "Version" ).toString() ); settings.endGroup(); } void QvkVersion::setRemoteVersion( QString version ) { remoteVersion = version; } QString QvkVersion::getRemoteVersion() { return remoteVersion; } bool QvkVersion::isNewVersionAvailable( QString localVersion, QString remoteVersion ) { if ( remoteVersion > localVersion ) return true; else return false; }vokoscreen-1.9.0/QvkVersion.h000066400000000000000000000015061227001500100161450ustar00rootroot00000000000000#ifndef version_H #define version_H #include #include #include #include #include #include #include class QvkVersion: public QObject { Q_OBJECT public: QvkVersion(); public slots: QString getRemoteVersion(); bool isNewVersionAvailable( QString localVersion, QString remoteVersion ); private: QNetworkAccessManager manager; QList currentDownloadsQList; bool saveToDisk( const QString &filename, QIODevice *data ); QString remoteVersion; private slots: void doDownload(); void downloadFinished( QNetworkReply *reply ); void readVersionTempFile( QString localVersionFilename ); void setRemoteVersion( QString version ); signals: void versionDownloadFinish(); }; #endifvokoscreen-1.9.0/QvkWinInfo.cpp000066400000000000000000000055411227001500100164270ustar00rootroot00000000000000#include "QvkWinInfo.h" #include using namespace std; QvkWinInfo::QvkWinInfo() { myX = 0; myY = 0; myWidth = 0; myHeight = 0; setWindowFlags( Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint ); resize ( 50, 50 ); QRegion Fenster( 0, 0, 50, 50, QRegion::Rectangle ); QRegion mouseHole( 21, 21, 8, 8, QRegion::Rectangle ); QRegion Rechteck_LO( 0, 0, 23, 23, QRegion::Rectangle ); QRegion Rechteck_RO( 27, 0, 23, 23, QRegion::Rectangle ); QRegion Rechteck_LU( 0, 27, 23, 23, QRegion::Rectangle ); QRegion Rechteck_RU( 27, 27, 23, 23, QRegion::Rectangle ); QRegion r1 = Fenster.QRegion::subtract( mouseHole ); QRegion r2 = r1.QRegion::subtract( Rechteck_LO ); QRegion r3 = r2.QRegion::subtract( Rechteck_RO ); QRegion r4 = r3.QRegion::subtract( Rechteck_LU ); QRegion r5 = r4.QRegion::subtract( Rechteck_RU ); this->setMask( r5 ); lastWinID = this->winId(); windowTimer = new QTimer( this ); connect( windowTimer, SIGNAL( timeout() ), this, SLOT( selectWindow() ) ); windowTimer->start( 500 ); mouseTimer = new QTimer( this ); connect( mouseTimer, SIGNAL( timeout() ), this, SLOT( mousePosition() ) ); mouseTimer->start( 20 ); show(); } QvkWinInfo::~QvkWinInfo() { } void QvkWinInfo::paintEvent( QPaintEvent *event ) { (void)event; QPainter painter( this ); painter.setPen( QPen( Qt::blue, 4 ) ); painter.drawLine( 50/2, 0, 50/2, 50); painter.drawLine( 0, 50/2, 50, 50/2); } void QvkWinInfo::mousePosition() { QCursor cursor; move( cursor.pos().x() - 25 , cursor.pos().y() - 25 ); } void QvkWinInfo::selectWindow() { newWinID = QxtWindowSystem::activeWindow(); if ( lastWinID != newWinID ) { windowTimer->stop(); mouseTimer->stop(); myX = QxtWindowSystem::windowGeometry( newWinID ).x(); myY = QxtWindowSystem::windowGeometry( newWinID ).y(); myWidth = QxtWindowSystem::windowGeometry( newWinID ).width(); myHeight = QxtWindowSystem::windowGeometry( newWinID ).height(); // Cursor resize does not show in video in the first Frames resize( 10, 10 ); emit windowChanged(); this->close(); delete this; } } QString QvkWinInfo::x() { return QString::number( myX ); } QString QvkWinInfo::y() { return QString::number( myY ); } QString QvkWinInfo::width() { return QString::number( myWidth ); } QString QvkWinInfo::height() { return QString::number( myHeight ); } QString QvkWinInfo::WinID() { return QString().number( newWinID ); } WId QvkWinInfo::getWinID() { return newWinID; } vokoscreen-1.9.0/QvkWinInfo.h000066400000000000000000000013241227001500100160670ustar00rootroot00000000000000#ifndef QvkWinInfo_H #define QvkWinInfo_H #include "qxtwindowsystem.h" #include #include #include #include #include class QvkWinInfo: public QMainWindow { Q_OBJECT public: QvkWinInfo(); virtual ~QvkWinInfo(); public slots: QString x(); QString y(); QString width(); QString height(); QString WinID(); WId getWinID(); private slots: void selectWindow(); void mousePosition(); signals: void windowChanged(); protected: private: QTimer *windowTimer; QTimer *mouseTimer; WId lastWinID; WId newWinID; int myX; int myY; int myWidth; int myHeight; void paintEvent(QPaintEvent *event); }; #endif vokoscreen-1.9.0/SPECIAL-FEATURE000066400000000000000000000004741227001500100157640ustar00rootroot00000000000000Spezial Feature in vokoscreen.conf Path: ~/.config/vokoscreen/vokoscreen.conf The entrys must be made with a text editor [AREA] # Introduced in vokoscreen 1.7.22 Beta # Hide recordarea in Taskbar NoShowInTaskBar=1 [Standard] # Introduced in vokoscreen 1.7.22 Beta # Show recordarea in Taskbar NoShowInTaskBar=0 vokoscreen-1.9.0/TODO000066400000000000000000000003441227001500100143540ustar00rootroot00000000000000 qmake Warnungen wegen fehlenden qm Dateien beseitigen http://doc.qt.digia.com/4.3/qmake-advanced-usage.html#conditional-functions http://doc.qt.digia.com/4.3/qmake-manual.html http://www.qtforum.de/forum/viewtopic.php?p=36056 vokoscreen-1.9.0/VERSION000066400000000000000000000000641227001500100147330ustar00rootroot00000000000000[Info] Progname=vokoscreen Version=1.9.0 Beta=false vokoscreen-1.9.0/applications/000077500000000000000000000000001227001500100163515ustar00rootroot00000000000000vokoscreen-1.9.0/applications/INFO000066400000000000000000000001031227001500100170210ustar00rootroot00000000000000vokoscreen.desktop vokoscreen.png vokoscreen.xpm 32x32 for debian vokoscreen-1.9.0/applications/vokoscreen.desktop000066400000000000000000000003211227001500100221160ustar00rootroot00000000000000[Desktop Entry] Comment=screencast Exec=vokoscreen Icon=vokoscreen Name=vokoscreen StartupNotify=false Terminal=false Type=Application Categories=AudioVideo;Recorder; Keywords=Audio;Video;Recorder;Screencast; vokoscreen-1.9.0/applications/vokoscreen.png000066400000000000000000002355031227001500100212450ustar00rootroot00000000000000PNG  IHDR,ܜsRGBbKGD pHYs B(xtIME |~z IDATxi$u&{c̷իWU] {a^W6h[l6dl؆aؘaðFc#QIEIj6{!%񏸑yF{#v5Ȫ|FdF|93\.eYpe//.|ӟ*g];,lׯN/ )|SfDlmm]S#}ww T D!8mvyv2Y^ zre!q%"ܾ}{ŋA_O39{|RR9ff`wP ;lllp}9pN^Dwrrg55PQn>a}/aD5  f&&OwOOK==AuM}XEDmʹ9.3󐈆C8Q߉ 0E{`urȪ+-8կ~Ф3m ?kF'݄j Dc3y/^ j{GOTp͒A}`}}}|/w7Nl^H)'XTTDQpI`Zɥc;,"@[qMvQF%$:mv |]JQ)|;i}w$eY@$ `"Q ! ?u<DŭyO]]qy4eN4q3o SW{=E_7`M,% LD3Z[[C|k,΀Ȉ^&IƱq,9cq"9MbiD$Eҁd" BHM55Gl8W";Mċ8p ǵB]yosswIDV@NT/|ͽ}CIt0B=!1$&N$0q"lRiLJdT,ߩY*M e zcBHQGl.R&`Gs5(׮ȥ#y/yfDѪZ-5Df>&a]@DǛ0FUP ӿYvܳ4@DxWvyQ1!M&JQv2q\fd &HbRK +#a2""a$lI32t't'L? 38zi!i"Y$WiNZ"!NIQQ[ɼQZmMz_T*Qp6@];P |`!pr2,V!%3TűLyP%$bL mH*˒J H $ID|fb#Y Ϡ=҃AFfa @H'RN6!X  prnP[ r -O{(B;S`K9!Eoi1MDvssӢMǹ:>n=,V)amEx7B)_K8Y U3ĢE *JK %u6B^Z '>wGdBmQ{)T?gB2~FzOzi@jeA46R8Tarzp _7XGqjǞ{ˋ޶ g&P\p]PϩŅ;{wJ)<.0'dfZۣ .R.O&2\H k[e[Z+aLmL@U͒Y S# ٽvUs 2 9.HsJw^ IMd)TB ^JP }aҘLIGH8"q$8M"R*`Uz*|Գ;kځNϯ? A}"z+Y jaU +֪-{w3ZVJŋ)Xj][JiEi'I 6Pʲ6PڰVaZhmem ac m,PƲvzrWiUUڜOLf7 `$ADPTN(:ԩ*;PeYfHcH$&D0ՕmI4&`Lb4&f1^BDd!% v<ꔵ36Wdhz1sـ!Wp"!3ѱjQa kkw^J{v:RGYJ)㏷D>0qG=#;bi(>P*1\2a0VU2(RYJTeiQ(ͥr2O*r"U F 0 JȉKVJp$`V b)`cYIXbֽt/aO{1L?0)ŞI$XȈI8@ zJ!<_{ :ҐsV0-(fjqbB-$Plnn&uB-.8~>pV=%>>.'0Msm!ĥKLzgo}J[(c+1 o(c֖*20m03C1uŒl2,v[) #D)F饼rXI5DhF0YdM60iddzqu$ fV ZdhtRvܦb>B@}+"3ˢjq28`k9b4WWWC~\ڟ0 "Q}c{c6($Ŵ&}NcTt|JDcjD`{?j(Tyg87d kTpaDXRT[p޾0]X'N0^(E JU_ (mD`WNI3IeHlQݵNW"#&`IR0G6"HI1Ԧlz1t/fӏYc腄B W)Bɗ]DCdncFvy6Ğ\78%BеZƄ\v Xc0szJ D<l MUΏ| E?|?FDOg4g,#_djnHG4`!+1kao\T%Ge.K\YK]qx.K\kN0$\n " 5 FH2nmIBĜTZRq.JdBڜ5āJTnnV>> 766~DwEXg,?:qY7ˮ]B$agg>Je' ) Z'<H5DMtߏ)S]*z\ס5{>XsP5G~nF1#Lɹ[Gw&'?:b,xszV qE0P u TEV"mz1^&' LdI$9Rl $8,ҏުȭZp]"P3D$=,j +jjiuDk$I:BcId/\*r"ITq!; 6>X q !h"Uɼr??q)8i/ܒDu 9F1F+=휛Ԑ^Ҍþڌ;R70bb JLܜȒ&XI$LjKdE\ 1tbY DU%C %dD**)*1DW楧uw.IU_~=#46X)%oooORëG.f+ k;f'1h<G;@g!+?uDVx-`#'@QM`x75Nj%2D0WyVZƳ=0c 7EsuJS ², X<'OA8"RXl$*!" $X:,# ~Bfi)%䴒 ^qp>"C3yݚ3XzB"7JrNJq,ZV4E *K8*A2&`No No(Qg8_kD@૘d4)tEUA8U5 X@wETs)jT>g`S嚩4:#i|;16 ?%Y6Hmn3?f+-O[eHBwHV2K*Yn9J6ت~Bz!d)酌z't$QZC\G_qǜ$ GQx#"|V0of^\b.$\\{O?qbP\y Ndpu`"$ 4]Pa&QO\fWc@P P E} F#dOΘ?, [Nkg<3q*7}aPuF9-fgdu[GXL["5 ̌ȍblU@K͵"!NSȷǸ XN#6i<14~KI_ϯ zaw=LDXuy41ve%YOڠ1_D0(J Uanz4=Aq\gDHʣ t_)#է fWWoh*&|aJ9Luͭ@H|( юb|Z|1Yy5*UV;1\$a؝Fն~mpvZ|`): eX&w>f&k|tX\(RRʚ#<=npmOG(KJIZ%YZLT}RXW}HFY;ܑVĐ`? 80,(\:593}-Қ/ x8e^iu6,1HOG`7ۂū/}\B~ǎQnPZ, `.ʂuWFGG( a!ZahusssnI FYBښHBbbUBPC)gEi`!U,Fg<=U~G~]#H3X[ lAb)5^b\'^jќpsѦxno E nS ӏ 0@{ Hv0!ǣpãfR2T\UU|K|Sgz" fGԒ㉈#RdJ =,ݭ]+aum "~7JkrUK/J8vP*bC팝$)[pv#rPCu$}[N !:\~| S} 6Eᛅ.f釹e"@wsEA_g1 vSmPv@4?{a>]BA81VGAI[vefh :.˒ӴK5%s+U=ñWFZáʲZkԝT}w+`Msx۷"KUJ -Jñi#䅮8Hm4@ IDAT4E`g9{AUR2' ]Lm/tS5PCHP|8$ʃпj,41r$LnN]1HTZ ƶruMuB&(`zWv-SXxL3үCqaXz=$ϕTJMlxGDպvCNR(_q bՊHWa&a8R\*q,Abֿ0KeSJ!(bC+q) '3!Ԫ=t 6;SmId5d"k4 j@QfLI seZYj{t>p7Zd="}ZX*uVí\1"}cg,5iNilm+t~l1 l{ԶP0?uTkC""伸M&[,&/LaEPjz̏Βz~x!S4$fGKe2Hfa 9S$WX'^vn"/Pi^#TϻzpJ7F7u $ C )P.a6Zhc5RPZ e*zL9NKDWo@ QbhИ۹znLJqe󯳓Z㠶s#9HHjb-Xc*(fܘ"rePƝt9h"IQ(Hk41x}}]meD: :R.bH{n%)Lւ0(F@zk q=Е8tXZhsFՆEvܔ &Ha)  ЏAĊ0`9c#O ( (C[@)ZX&!mlƽUNz \I xmiT[ EȬP;PDžYv*6[ٿc JsZ4YDGC=y~2+;{=ʱ1j+^`+޼N]wmp<v֖ty-+pg 4=$)m*ҰK/!V+iX7o>`A E=Y~I$)I"<t8:10OP%5Kk\^0`i[0IGGg Rm>ֵ)w<@-:fE aS9@VWܡ㜕,c/S#!oLXP jJzBgmҥKԉWLB &"'%nXVvi ^&y! j`Ay>?i><%@\R"B 1z oC;(J42 ƣcd>1HHHDQ HAl3 Vbwx7kCqc<6wwP]aLSݽhCG;𖝋NposRŰ-:O]27kYj>89WS(x4.i\(&`uwDT!˂HDWwsIּސŻ[koSO=% zWH),d]@xp̚P i EΟ?E|'xJ1Z)7m8(U)#Q%dX\^}`eP1WBzEqp'^S(^ b䐉a&jiDJv>ɱ'5Eۀ'>y}paAӝ$;_Ms`Uf*E[K/"`(ʔ*,Kiǂ03g.zW;7a8>4֓e_{}W0ѵYr2yfBD+ )XIEWOy_ 9R-!i+va7n_nѸJq߾_yo#"#IR$Q Kuj0Xk`A9c2:K/@xWz+/#*r~/(o}E+bF5h0EԲ泹k uZ %{FY!t{"fGR̉0 9N8ՠ3nW2YŠaA\z1xTx.ipyccXY"7JTSd;H.T֓z8`8N,U?G^iz(&B_ĐRNͥ:ߏޞPəg&mRV "*ȏz+X\]%:yTo7_ƭ7ICvBTY NZ+hz,0,)%,E`0+m#] n8ۦwǞs6ݵ+ S.e_0)lnjMr?pBݩ}WFZt&9HZ<椕]D<:|[ga@n08לƥ|jT>7C帶6=\fUePxNS A>x)[6as@5OVjkC$,6QOgy!@<=Rsy(jP 600i|4*a+(,O/2Kz8n{n::Q) Iwff=<<_Xꕣe" Üe:h^F`,c+ 1 谥S*e}* x@q.]ğ|څ0:>WxM`sBjR1hK> \z^A疱f;hY˰LGZIdTc%Zk'?<z֫-<򑏛7`eG,nD\KOő{`ZXuKmt9: qqZg#aʘ*RMss;2SeNN) KDt7 8E)k|ye`qp4٢hI *PǸd1`lU24Z$bUNƫrxK ¿S?g>PJZo}/ 8r ٹ:k#V.^䇟ƹ,-,ꥋXZ"/  BƈTMTZ#sXҗJM&DJ?Jx|BG]|  œf( cY֯ѩ SW$P C&z@#DwnĴyEnP%Y0F3"h'ʸ;CdT5ɴ "W߭i'V0RJ~Ak &;{c\uU ] E4mlM㥘/|`U0DW C}kB'1_F??DMl|eđW_ ,/ H4&4p~Çן \r >x2i I0s eQ6) XJ(J m-֐B@4K)^Z` q~;[&+V!3N9+BY0՞C_U^4uLmj>]qdž@wVHs̟'!H2w 3чJNJLkS+KJCgKUYAi!3?)!pU}SZGWIBFL$l4 ܛnQ Ddi<+ (fp@b Z @OqIY($U$U*p$0AEԐQ_6& F0.ʚbRF"8I1A`@)]0ձ ,()frzJahgGLz󢡀[#:v[QTIiڪ½k5ӘFS>yHZ  `xVW<x?ȧkS?`"erQ>lLBy(PhfPӀZK:k#fZ\S`xz{̞3qG\]D|ּ厮369Ykv嶵sޯ_ ;tWC)VR-=,%:]03ptyЧHеYL,jS VenhtP9ӊT1)4DZ0XKؗzQ1= [q5EĥkW.]|?O@c }LE^biqp<!/=!MS? |鏾Tx2!e )"¥:t2yѰV[7>[>~$I!#\xpm,-/s*,- '0Q=>dCt(NqᾅA`gz8 U{iNՠU ~.HIl-0 VerV[Τy.O)'kkƄf~g6UO888(:i ; >wy`/06x611Җrt5kq~A(4!Ǻ,ɟSX[]>zڔ85s읍t1e)Ǒ]]j1?b!P9B(Y5QNyVYƬ+ R+iQ/K"m|{?'1s<~q<[?^FEB`2 Kđ[;9ߺ#we }~`m !d %i=HI !  )-'@=a_>4z*򼬚YS`:8c J=!o fK$U# 3 \3\ bfNnH~jWIn31 1ꊎ!Uv#oJmx@ OW2jfkELA6$HJ) S❙㍍weWt Se\)4M<}8|q5.n#:P85" e(xV˘heƸPQ8'"#yA Y?O_x/:[X[{X\ X={~| Zqc,VX\X@^x}L(/.( /": PXiͬJUWҥ_s>,b4+%eFfXY9GX\^AdHkceڞlmdvm̩Qy(>UEL6.45ImSx "S*a࿪х1qeln,s괧;jYiDc%M5 Az˜aaV< [(^KDq$y|Zp?ȫFc.#:+P3e205JeSՅ`_ZTH}=|qkŗ^{ kHF"1@ x㩏?G7D$%.3gy1XA ! D "F=%D)}JkIozgB:ta= ZZ8粘 {T"i,fD}u #L!jx'4!xz__O[] Yk`RŶ?k"ϙDH;fcRll5fjL| ':uL~6#0 D#U/-DT+|oT'$"yƇ6 IDATqƱR8|BZԛP chZ] ё+s瘮kuZMq=xIz  }|7|%>.\|QJ"HG~gG§>}0 Ijg [Ư?xא~-dYã!`( K0E\l`=]'`y 1!#M%_o3?Orx퍛xwΧ8 R2#M2! -8  3 gu1ļԯkxDa``Šk*N!Xx*xMwT0PV5Ϡzhx#|/9;/:`ӰʛOX7~aE/]H`9 GN39E-iiz b^:; 11ɇd֖}/`h|4WH+,^۪א%@'I\p賈cHF(ax;|k-dYe19B!`9s}ݟ~ <xb%ScQ //ǐ$}MX3Vjo)(ܺyis#~aFG{:EsX`Th].Q V+vBsSj*Ļ0 ,U%% ,7kҠHOsvf><.0kB])Ɯ ŞXF D^Bi W^xI-|W(tBTM1 >=OG?X^ZI Tee| "A4CUYOxDHy 3߫WKfͬ=D=1W[s-û??Ym"^}4ʨ{!pu|7~ ׮\Ƌ^+cmAhw`t4ⵍ Z|`x%Q5O vLf̂}1V%-ɖh{o kE`T~k%Q'7J̓˭-NrX7n /x8G"2]U/bJVRCV:\QF ҜDRvlg3my8ǽ){L׮Sbf9y-޼߼ ~X^y'ςݕBa* xc\4 C\q s#( Iڈ Rܹs {0- #3gN￀,`m ARu`*X@A ™3cyy  ~&zXt" +![~:zJ>ZsSltAd>^M)&b8<@^O@ KyX 8S|e<$%Q`UpQy tATxT~a\hem%M5T!yIzw2XM2@z`XR zAa&|WJuG9#U u2ɛ6=o?@ ݘl}5f/agsx'?jA G 6V906Qb{g?ӿia$i#c0+ 7{ ~Xǐ'43(ķs zG)&u8:0Fcq7ol6cW{O翁v(hggNc{$Ah;8<:>㞺嶟"ݹNKA|ȑ3|H'd W4rB2X@)vAAQ; `0zu94sA*rʕBdM3ս7QV,}7@q|8̑f!@5Ho4; ^8G;@PFy)zYHjob+rLl.̅zɵC35cTSQCg=&:gV[^(]~/]|87/}?0ꂤH`<{X^ljUhG!T?O|!DF<.Rw|by thyo{]")Cm"K Mo#Ko#K`4@'h4D}كF4U"aዟ,> QF/@JBF`A`F;vhZ,G ON2,fz笑P딄&Lk氾PJ&U/5ϐFh.6iNh)G.P/3xq.Ϥ D6%?3Hh:XJ, 6776mxpsJKE3a>V=C{S*2rB 퀴6s>uHp0;,?RϹ V ?6N̈iCJ !$A (1b RCb{63N`&t:?)m2D r1pks\$7B*ܸ&!Z`V ߸m t􏸝trtCO_{Fw'wԧvagSevqNgp'Y%7zEys4NN:j4nVd!gAL;ei6`U1I4mQ=p.8wrHAt{sQ/_fSN5}?"Z_h!8(_rc?!fw^73?)gdq\777.a~.H( YI<h% (J)|_?'R*Zq򝕀s `0ۻ0Nf;{i'?յSHgCsI,IĭӈK?я}1-\޺k͘PE<;i\{*(AWJ9Xc7^s TBJE?QLL rCUssXLKINqeispV9 v ;Ϟvm')6jرQF a7 á杣sP n巂!Q{MܷYxcMI"%P֡<#uaU f޸ V7V UīˋCaK`9kʐif{#vU$k_ #r k}k/6{XY}we'>8(1PR"M3$q׮7߄vvEJ5Pk!4+\QD:ɏ1RX3G`;NЏ< J,̵;ȵ=jd$`(_ʗQ2 ˂!6>>Z B'HGCjwxBDh/ɿ?neOa}pؖsS+/J7^j.WVˉWC0vy :n ։%7UV&\.~clR>\(Qr0G[fOsr`VJJ_b%%E""𝞈u c R P5uYBuV, xe>̣HNb "?>:OJ#4`c!"Iuxׯ;W^9%P R  ",.́ (n [~~ 0TsC0~`t_&zXx}te9>)?*ȳ-<)Oڝ0޼ `̍0_B:R J 26oAh}#C0aBe$1]sOE*0/?'- T.Kdl q >`J 7xhEǺ&~6e%ܣÑÔsX1iSES 470ع 'O.ZVj%AgyNy):UH§A_uXMP)Eve0:Kf `_Q "-l$<3pz5\03t:ܧ,_~,A\%7= .ZI23BW^y<, Fb6/uG`yAc{0/_~Z+,'0Y'NG/:sgqx~?c?V@I,bk! µ!s/ 6w$-HahTk`0 m$T{Er.$$WPQ rBSñ ʅ# "ޏ"UɣʰcVJʁj乛!\}O\UBEߒ/rmkn:[8a~ 5@ NbzMk CF{ӮؕRBKI Ӽ Xn6εHzTD \HI˽A+Tqgy|}}#M3( oQ0!ǭ|Gyl0!C2AK_#h5^FWm͙V3'p۱Cq0+EK)W_z +:5"L`$"9-"~\cw`5:B)Xaډ , ZTԆ ZT@3?d}~F?'}JٚF_3vfDIOi6,AzG);&1{ Smaʇa]&#: ט^:Sd#ǀ= Sk"n*; )%@ :KT. qc5E׏wWbocccm,)l_clƺ>Ut54kZdRw{ 翊G H²W$Ax'p2~N(E _MK( Ť!B="J6#϶sJ cFi6zv;7 DHXXtbȭ]c)Df9I?T!w>l,Ϝs"iKW RQc5 w|XU K)Orhp8Ҝi[h_\}E_1_MyzZqsj @;q1߉hi>!X,[89&͞KF5E5 ,XoEO8MD=jJgމ(ү< ) {4Xa~h@$iQ=/=] 0ȇ1Fk!Bگ:^yU!FH(p$bXs@ !Qr`FnyZDA Į*Os9oW_r0+/}Qn4>y8q A/T z‹PJBH$RPR"bdHW2!eD@.iy9Gd]x _}Nۄw>fŠ"F_fUn~gir쥾XMx[4l1CL 3ȧ;MvSs3#+ L ) q[F2 %^!Z"g+2[K nܸ7`1NFb!H`yk4MXaQjlx *c4aZ"U'͜X;߱c,$`" S֐R" #0{{b_Bpn~l0^YkSp v$q +WOGN % m u( <_x@z1 H$!*XsF@]j:߅1}D l;h[XcwRw5;& ?{A$`6f"y:".bV۞H+n$$FZ.3:,E"E8/R;YBb8i9Qyo@68uΉ b\?;g$a~#1^M&nf 9N~ l7E:ֻT&\V(θ}X4*? o¬IOXr|myL7ߑ?BPxi`OBhFƂe=soqP. ȇ/ 4"&Ja4!P Yn15hu#j$l \Ch}:r?~=vRTȏT¦,VD6޲@*9KW2Wy*T A.j=0"G{zh@aq]H|$t>aGswS d@"w?,;7mSM_Zwxx8LdZ^Aע*/ފYtVw49)NRXXc ppH:at`1 fH%`Nc FY ~{n!SrEi`PD{70Jl4[I=.^|*90A{:B[x_k߄v 8FXG#,//!iHID5FW/C@!;yh}4d  e![0zQc(#ۻeQF h!rS5#]X[a<مjR+E2|f?(slCaE$X1G?`Z_UejY7q",(f*;N+| VL2 *X\)X-X`Y0Ƹ'`GhO@ng?{r*۩MX)h؇9¨;,"m' jc1JSq(EŸh/,$v:V s$FBshz>!58Z_8 1< |KczEĈq! Cq$$1%!`A ?]">=D `#Ä`8/#pkB"T^4#!OQlp2?U1r?Vs$ ,67h u\U10)3sXf 0UբDOu)SAc)Ԍyk}4)3V91T񞯌TdbM;18 ~+X݀Y Zk#O#TBv|!ΪQ48Xܪ$: $~Vk8"BV嶏}-,Z:8!$>;. 0`TRwwe+^ IC(xT/>?3~lj%Q" D!(DQ%Q 0sp (ԙӸzwU"1}blgP:rH"sDa!$l OF`:sLF`;$]ɏ'cy*dhS(0Іab Hu/u|jSbWs:FSKD i }S0Vqn wO7$#ڛ&o,6Ƹ: Z3)ȏ4N\iRm f0 #z9h{mAi DD(YI>׀(,rTƋ+ %~ 1fCgYe1v>/Oy[$|#$q{$pLѿ_-nØ ڼix=6 !9ƻ~Zy !1p'*$|O~0f,ATw%)qV:iGi@H&Ryp. \b!+7M`|}Ј XRIh鱐vȞܒpX7X.]j_xqp?aX9b7׺,Ƙ!yxUj;&⠃qTJk"ЩۡZRV`N P cX–9T➨rQ<frU7U/r"9BQՃ]Q3ggzNToEJa)}?]XF"dw`o/nZư&^Zgc!T6 dwcv0TYƁW ""ƀ ADa*jy;k#G1(OqL ~\x&7S$&Mf:vP0GۦsxIIBPiD.emSذ1`0pjp ;B87TvܮF>}l!cc!ȵITd. %t:h% ,+R T^73cBW 35sȲa }J;wgkDxף'~;0DGh qQ_9,>0 8\ smGQ>ɿT[X(ƙԙ`Ai=ĭ[[̸/~9|{0͑z|2a\\sJʆ"UA[fk9l(.&{.fWmoP~꼰궪V!nNZٍ9 \h hRctgwGPV1^8ַZ\agqh~ : X1 CYftO!Y@@ɟqsଃRQXynʱ8a.l<.mVP V5W޼4Њc?Ex Rq˯g\xye!0DPJ .dR~ljIiBǓţ vSc&rc~NBz' FzѮ4{CIj]r$Nt 4Y'Њ f.U! xcI"z`sSXʿXGƘ\J"B2[gCosIj|gdM^MlnCa)K! UqaS⁳…hwX[@i@I8)MxܵqidQ WU@QD":s˝rcawrb_eBwNYr\(rH)IB1;C0ǍI ]3&SQM'hݏk>ȨۛyZNC|;ǔImMI=5f(} jCrRAҥKx}Qt10AfRN;Q%xu!Hoem2OZ݊@oP]<#\a V-yƂ@:,g)ba. ^~}^zx +8qm#`umk46Nl bmH%s cxHfc^UVujGAr J]mLt' E,&1 2LFlrZ?# HRLv&zPe% YTZ4%i蔦w_5uJI2٩ MdUIG;ai&k-APeúg0K&ƷL)kAVG)ޘVݖta'JXC1的`e4y :DQ"xgi[OTT}telmna{k룼;wqh!++瑴"$A|#\R+|,AI1V/९?")9f!Pdšw4ӱ~mrO&}FGKƼ0.$#j'-YNh± j!12_O֞yqEwÚY%~EN|֭A>""(%xc9̸cf,4l$N.׻/@#Mŋ }fLip gi9f}yJyQg eCd6zD@:g}q?:7;DQhmF =^\:}<~_1xY/qsQckЏT 1\e vιxWeT f yJl4Z+AfNH4`dZ",f|gͲft\4vBUI8!-7? auwA^dX֟F VIm@C\k=RdRIp ?J<DoဨU98tО_@:G1 Ǟȵ;WñWX!%f% ̘,<`}E jH`uy8S0D{?~zL)A0į*ĻLeƭ=ñ5rY` l,;X͕[q7vgUM18b<\:#b2~v'q?*삦SQ7Ϋ94Ld2CvpԺ_] 2|rCa@7>jKI87(h"(XCwKEZ訷ڴ) \%%5ir KO-͉ͤr0xs(cZ|KV8I^4!(hz p( mXnj D QDwQ Jnde975BgW~H?0z!H(||x4ko*oŝ7q  dBJX'j 28I(I:(XBF1,F:GlM d IJ%܀bD&:?rӸtE35K0vхaVap:&O]\ 힌uJAόq`,eK*Ԇq%v|X_mS((mIRPsDĠҮ*j\S[Ďz^S#s9-!g[ ]~gsP H!x X_@D+$1+*( R ܹǂhf (ų/(s\g_/!KGH:~lqTmdZFA :J@P Kk`r\ FMFp D*PRф2s-z|@o+s57H-AZc$3޾><ӭccL/"|f%HSγ)Maq%̼fzED2^{tZws̱ɵE1׍Rƨa͍iE 7YIAv˫غ;pxԇNcmmW\d<1Tڝ2-OLΊ1Mᡇމ<˰0?&?^X^^ecۘ0 |Z l%% D%")}2vO)/2N!NN ބ981U(H^@U|frQbc}s](AXNz*Ё#&GD"d  Mf( 㩎 EkK^U$:5?qw^qr'5 lO|o ˘]8 !%K ( q .n<3h.oChMW^=dji)7Vǚrdڡ?ʛ) o5dYFh/@o{;؍p5@{y ?(pSˏt`k+ᬆh??:Ņ+9Q |,`_~_ze ~t7]+/ θu ̌< F+` t H!P<YCH?sϣng;cra ál(XRh @*Tc\+ZpQ3(ȷj!j eWbzϨwr.v\ p,Xk)wEHPz0)(0#sHƘ,""(!xt 0ZHsa4_$0_8:!?ɃݫPyby%ܼyG}l$W8} 3b '] $[ }1#?0 J"t \U H=~\Emq4ʑj2i4˱!ヮ% D!d RH;vu#K!D X18AsW IDATH$ ?V8.w! #l ր`D0b-@ljq 5 >Pe̪HSڅo,8ϳ Dրla594& %$3` KbtjB3FL  .ŷqHRR2CY*dpfu" Vcw6S5LA{{{;NK<fl (G-{뾅DK3 9?ؖ~}(̹k/5V59dAAe,݄5C@t9X¹Rh=X[^o03H)9 BmGO!d B @Q F !W՘&1r57Y쓣$ (̎DPh. $.N]H)PIcqn ,@*%Σ%g6JEsu/t%iGV%7Fo-z Jlb2t0O]t/R:HsB>}M!\P~Z20j:|4 U>V\{& m /,ށkW^ŝmRt]$I 忀9ܰ2SeD F!m|;w|'זsP'>vqS+("ׄƳؙ%E2|YڈUy Rs!>,|B,,ȓ`0DXϾf,ӝ46 ϕ m R!N4I6%YH-q;.,KF6{Y im !ʧ"v֑1Ƨk,0 q4Ly _;CCYu8+#Ϥ?AgUBLQ ȺP4#{fv`B"Њ2g"8jY|3[">/IMzEݾ2ϑו5w(ԾH")Rɒ(K9j۲ZZnۿL01?o!wNJe%K-hE" $rϷ}w~x/3_&(P.wL|{9+] D,K 2,P4Z>.~<~qݨPP&pCpw]NJ8:SB4Nk:CH{QԆY&LkQԂoAp5pA^~p3ML:mlTjNF]vz&'lHtW%`j̮+/ & !J_so*GG rZn+X}?ghژbff:{q/p5u5|nw;'s>:U ۙwA$T>`$--:R΢ u# #4UT/YGt@Y` ' 4cf#|zݔ (ٕ7IS'Б W( I X%^^)2Zmbqxٙ K%9|[XZXZzDش4 5b{U|d2#8 ]KWKoDq|}LUjUXaKIl#":߲D|vJ㭐5Œ#CA kj{!whﮒ'#S:Sk7Q\իe[(71w` w k.I(h-!0$ҽ A"K:vR1h@W.]X} \ $W7o_쁹, dخٹv3+^= Y5 ~s" 6#U7(y{X[u:ia=~'(X5Tyr`wJ:?|V[^EDD>lU173͌vq}Q\xe~@k!C0G`()4Wcs5M"͢P(brr33p e9?6Askr~xw^<3Gd?9A;4V6O*!jImCcdE'?H՝^* rsAWD80az bTj<yߌV|lnx&4-,`jrӓ~cAݸ]WVCYlUQ(on!ڐ2(Q쳟/@J V(oUq"Hު&7juׯ@pA6MAZ0oT$8;N[ vFBླO`2 RyhA) Y(%Ge<Ѓ8rpgϜ7ghw:h7jp39)+E ?Y*psLc HE5{q3ڢc#}0M $ CA&r VWWPl6ljyx׳Ǝ*=~J?>:;Rð]t׿am0??8rze$ӳrYzg{t;+AD΢cCjXE5 DBl5t|}E|):GUYDz]ÆB3an HgwyuDna<;([ݺB 199~GH!!(&Q8thJafƅ%(cx7!rac`ub;VK =~sWxޝf$u!`c84j7c' $+LJZKAvSo^o̰-rʯ5C l::u (=YB1m[h4VkzQGI%aY 頃b+2 <QTK.ҥhZmeijZN<9 86g{Ut7)w =rՆZZ3A(4yܺ;7Fv?0Zf;뙙pptAqձ?%{֛?׮]GyMۦmLLL`z oƃgsn/.$j6Z腄$~U7[U2ҁ X.i0U K?}gyǰUrubDSgŏh5@y@_':~h|ʴw.f8+P҈/D4]DAb٪;g43=7eed;H~:MjUj5Z Z- <xgP,D!!(Byso/`qqZϏ%* 58# qt(R0DX4bjj J)LLL`ll O?q\zeNS`\Vq\,JRoʷW/Uܺvi*zRy?\(IM H@<:Wq5l0L#qUrxǐ尶z(zV+`Z& LlꊨooB2qbJRMx~e4MNT E?? `ӠI!TMJR!܇zH(l#o=Zpl~Šr`Vv ߞRh& ("2C[[[m B)E94򍅡H @'^Oa٘&t!줒;tԆ<0V#'N4*0LģHkض޾yS=\V67?xjF `Bijx\]! ,%2bLRE4M5M_:RO|lYu ^ŭ[ڊuzg?Y8qBo/߼x(+PA}#xR]xIQ\RتlmlnnB) ua>C},//#icFZepSXʂh4CLZ^P]4Mdsm, %ە}k7>(%VKkwy䑙t EJ@#tV4"3ٌ'82SRŒdo`aqdTBq( !4R&qF6C`շ!Ƿ?nɃكf?9LaBN@JRf edJ IDAT DB* 7NB&suaX&c#_(BX \_󿸈Jzu'iV7f̱̏rc,qȰd ^Vv0,$Jo:o=AiYp KxWJe 7gG> H)^x o.3&oA=1h6u/@<go'E27*:V^F&" ɓfsZVf đn b41O>OHw}W-VZӧ9jq-־z|k_oNG ݤ fnۮZ훫^6tr qXK_aaL\HD9ܤL&Û[T, HnJ$$$Kwx!m@0?.hQnqdI!o38[/<3$:~smO $%J3s:m.1V*7qsqN g5|Mf+a!%P"SNzLU@[;GG|- d%m^S{eCdWVk`ö-|_LM_ƥTT .`1hz_{#_ܬOixꩧ0==o}oPl*-f$qJiZ(?3Y>_$Uͦ:/Cw&EGC~tj AMv/h'~c߇{+&$4,TX$u8Bu_1^>r< Q(lDDF 0QeE6A/MAQsv+/_@wБt-PtBYSc`a\ƕeZMT7ב9+R닷9КLlBg ;+qdGj*)"&_0t 'Q&c 2,.\` |Y:ooy~'} DC xPfF_ϒBBH J>#EŔBcv7x4 !p1o&JR,ҥK@0MN)7Q]x7x@|_}{Jq/M>ҵ^{F;'phlǓ~py/y>o LAuk6l҆e1`DLzG YPxCQ1hA(B7n.s2) fwbM&Z:CDpsEb54uԷ8WQˋGL|CdJLDcsק9N\SK];XS͟'& 8[X\\Fb_P,X]]ᇸW)W1%YvNpVw!!dbq<$dpc~? (p|K_8:Z&]J`J\B*Ԉ{]r~R6:!ɭzdOaeRҠ?hUYZ-h4^ã_m ܿt~oC8!дftmXM[tZzQ1sA*V$u::2wuD(0T{fFh`nCO=0U@ v kDШVJd.o5|kc] 6]lB Sd-BdLn>P `z &}kͷ'H K~:*J >@)7n?y1+"SՏ]׻HU`"h'%^Y1xoӛMFG<3=1O~Y|3Ĺ'*rG;C&:B`g8.E$xz5eZlesp c&W$TBނ45LszUItwٳfX)E0pu\|9ih6` 9rp/l#J[4WSѯ4` u킒vzMJV~ >'qQ;v _gg J4-=zR)IcE\xK~Fy Lb@*T XJk( :1s(^p7 w㲤\TaRJs4 ɂj-2'Z'KE;x}<3ѣb;YBгlL6v flB(L!/bsc z '`kcFZ!:6 d˶`Y&&p1;~ Gӧ03=R2P,.\6u4UK[~ ò!a;[(+F>N![mNZ܁[VLz-T*[ɂq/G7oO_;MN (prK1#^߹1& 4-אg1;3G@<./u]LOOCEAyM}5ה^|ߧ p|}2pSSt`Ikvrmm?(}w)(( r ̌zGӀ^n.=x#aklڂl4]@5$"Tp,dux^Qa\/ٶL@kDdg͍-v ";)qZZǭT_AVab|q e3а\]@e )p\ؙٹ"2`!ĖCJʼnں8Z"? LA7fV 4u?O,--sZĎSc1=8jKZLA vcYi[g"BIh+Z_|'Q,O~$6VWW8r, lơVK;F\eJ(A4{t"ΫP*wY~M/ȶĞ<]2:~U _ZC`WUujmT#O̤J9- u*MPfy-&r aȎ9( Ag&fl;Ƕ7|eʀ2ƕyws)HQ!=tMDQĎ#̀ v R A LvPb0Rew>PUO"{SN߷3|QHƍXZZB^C@ӧ} ̌V^1iR7ޠf/v?vI~K=5$^FP `]/t.2a}}/O}L'q-ܾ}j\@6aJe;lVE|]Oh}v|/eئ0->|(DQDZcS3 U UX{JJ""^^^nA %114כ>tY"YQ.@,$UY.H[m4j,$boq̤ Q҄eJ±M ˱!0 @J,Љͦff{[ʕZm/@8߉uزle-u@PB!qRB* dž)/-I8DbT,׾@i#$Mq}$2:nܸjuzhY>4M0kyvO_-Fw*A ,ދAcj֍Y$43$8CnZk~v5l6X__f06V2 r ZRO')8AO[9e*H%AaK[d@jZޭA,!r+ AiQF "4;S-u[ީ潋tޕ5? Sdĝ:]!QH#x$D&2Gs}`b=U73 _qUR'Fi`Ů3NOn%THd w/]Łxŋx DFV&lۂeZ0- yWxXK:ء@2%'.ds[ODBgӡ_fRŝ038\BQħ+#r`$ 1񒮄̕XM"[`R B#DZ@&H(bvdٴ]D{pzK+I[t&gH*R*kuz8Gi:O_|ߏ.Q`Nںr 4Uzej9Uu$Ih0@#tUDQkAGa&W2L0 koYE|믿VnQT`dԸ3i=4MUE>AIe(Ӑ X)+z´!1± .r9AΞҡ*+m8y@Zzqdweٕ݀AF)rSܕ_k9Lw!GށG]w#" 2cBquUS*2lXdJQ" ,O+/c vt;t -@}#᯾Wy͞Q£ugP*s?1* |O硤ihR>O1BifFƉ]k`yNk ꫯ߽,oOP;Tt;w(QUQ1#(#n>tbZ=V_!K=?h?Vơ)5drlf AAGa\U&<HR e0)P&#iwz.:*{jhqP^ vtPEĈ8_5_`1ImYjh G@es++6:'DTB|*ڝNUr?֮C%jsI&}kuPjB2w"dRemBo Z:x j$yd< ޜGg,]DzecRo ž[i^8 ! E;yw5(wzֶ B)#p'|Aj nݪkȏR*H:FGF,nyw%>N>4]q pG]p`ꑶN 9ALau.`QpxD5@RB1  avH(V WRk;EWŔd ))",--%`'~ia TT}*Z*^[h&JL$P2(^˘< =㖔{ I{'BĒ(~ލ ǐ?A™;h-վf}zAd2<#Z ہ엯sÙt| q6m,cJVW&׶ ˿,Ȉ{X${m=u4%Ip)S(xAF+^{Vǀ$G9mQ'Um)%&ɿ{@u;."!I) bvvsl%}Q4){cN=n{oǤPZ|K'A@26ɐ b!0|? P,133VJϫzq%묤T1PTťh@7J*JI6 ô$iCeqep<,7Lq vnfe |L@Pwzj e`XFůBC0?1ϱwyy JDӧOcrrQ!ϋu}B H*Kt55+s ̀("3z{auv(Ve !xyyyܹ] ,*!Dw7*up)=E#Ͳ'.>l6ȩ08vxX0VD)+90h`H^߳J#\Da GIV*:>S`rF+2$r-c@$q4Vwq۔T"q%!cp2lm^ۆi!$I8nE.7 939- o$(DQEBKGs 38+ظ"2l8i9rH@+w<e }Zec'c#@ IDAT!zcr#͘ HVlAxOwL .Ν >պ[5bbȦi iQjf`2J "ͨ7YϻHhaO J&CTճ] h:~䤍vc+2J5%{mWcAC Vo]Hd^\'u A0}= 0Jn ]}`/vF=ڍ{R*Ȫ e\Q\)zm篡Z݂lZ'Q4>0QԝGσ|r U, #@@P8|*W"ţr޾ *066)\r%v +bKl)%4W#戈wٙYM$٦!E w|??HmR%U~B\[bVDBH2jh$F]xt0P v9C wz;#o$ɱS.1[M_tס ;n29J!`Z6;Wq%G T\PpmܹskxqБ @X:9`?x"`!e.*~,}݇^W'EGQe1iC$l {KXݺ0pxp |Ν; "j+B),sC^|7_GZD'8x)$!C%q/W @"b"Ĥ0 ˱@/0OО.ذJ(Z e,Xe低k8;W{hGRpaysWl=Zg(bK%b=#0k͘Y5yjNwɹ;Z23jv5j$I i^uV։:6WPk`P߲t^mP`x V/y6. sw@vC 2ŠfTQ 2 l`Q(|{ϣȧA)6qZ>U(UU#C  5waC103a]̚ ,x &Kmo6\PLT?w1v667a+v.h]GEU qݝmAd $<0bJMbQ0jD'8uk=H')r2x2FX[[XRX)L=K@Id9 ,StxFB xQQ(ʆs Aٟ2I-+oCIGrn|\숻[V,zn'!vc'BCxuoф,RR_T]Cb0 4˚odWC;O w`qLN7_D1FؾYHij V:E] aP۽A pFXJB,#Y`zrB9ULΜPb$Ksu""hUjFQcr'JFdʺN{@$ڌAMn"J\X3?rNi wSp5eY6RJZYE&~?sQj(x;X'ҘI6; >;tgOlVnbv`i@L(l*0յ=^(( MnR%FY.+)%f dw[~Q׾Zcd=μ?!l#c(R`֘fHә!cZ֙ 3A qhJ?BlWUI}*[g/ nbm}ӌZժB 5|9`mct'yE@XGܝ#ӬJ)*˲2>*XlwWS>>>> 43YcA3^urO,ρcn:ipļǶ'GzC>puYeVvGhs4kQu( Z#. W:57:k9חZOab! |__FjJ̠&? ]d8a0Z?2c@20N),,$J^虥3Bocc /N1ؕ e`g/?c1o {U'P]RJ7BL+>]\9G9A=<.4w)ʲ:1Yq,87ܑZ)B|~=CٟBTG /gs؝],+ .Mve˷(Nu;&O#ND WԻ?ZlBeIDoF7sѿ1` dcѠ?ߐSC#sP7ayXq5 01LlS,j])(u5;- Bg 598FX8x{%l9g;L#STo"fT]bAXpüJ'"z0 ^NGWb. Zk.RM.\El)7s@ӜӼJOH`\dlɡIYΣNp: BKݑ͠$6Tݭq95-^%ϱ9'qmy#c4v}Qn\,Ob$(FD6 0?BG7n_w%H%÷kV"P[QWݔV Ys4 FBH\~Ho╿=sc?w(K3|b u|s{ȒZ< 0aZ}53+v?N xR[:RӦD("oaI JCL|&NN~"D0--~{.SJ+'vY>كo錜N#9N8@<.js2B(!{kfѐse}u ҅XD>=ڀ?&b*AMd)$b8+"lm8BJ6N0ʧ·[g!˗7a(VC%RؼpGϦx/`e$/aCX*+-֋x)P(n/UfFόm!@[sbAV Dl\zM4D>x ]{y[~Qmֺj(p%Dqp /Ƿ5H!.Q`%0'Gv׫T I\ZN1T[ W3)Ӂ_̾qP{|t3 %dO* rr_%0*˫'`Yu@qecYGZ Rrs>q@9%1ؽ,{n~neͨv0j{X :5G-dN cL6o@o(Js3ar^'a]867N ` r@$p:F4KP31=#\ZhysϽuʲUVu:&W+s\t^ wqbxZRJQ 0^é} ? pY&WUv6R" I4~/dY[n]iv+D!#B?q^mԵO @`>`49peUlt:Ma[ ;N_zZpko ZK>bO7Ny.X`0؛ݘsfY Sn :<Πuu7`A]|zŋ9W!P5WxQc)hzMhi]򆗽iQ_6u΋(P ٸwV1\ƙiBelwAC$pu&VgR|kO#`uĹM1|O`8Xl6;dtZo6a2c8W~+(& 04 ([CG 2W V7{8|5$! @Ɛ4 e@.k44Tz$4p$v'hVup}#6U7uR6 aU\tgf>::tss XtQ_.M6~ 籽]7(u˗_ "@f`A(2l9e|O֞ tKde&Fg0W_}eYiH٤*̠~DN'oKc)w)i5 LDgwX>н0x<It⳧<W?J^smE;?PǞ-;s9Q-vi!u6i;2k,5* s?gEC L[\d rѮ.^8cOT."AusgU%H$".k#RSC⣿x @$po~S5}63R:W~ ӿ0HEQb!e8# M8{,Fwe乂}S2CQV刍zR"MSk6 tW;3F,,Kh$f6It{I y{":n;9Ԇ=s=syG^l]֌ 1j=g~oXUt#h9>Ka1|մGŚ=UeCš|;46@Q`P?1^Wo$<0x5%s=O~\|/>u_~h@/w擿na8&[t~ø=pj6.f /$޾*4,#\t?ΜQT E(R);ʅ(UB2h8f?P#V A)e|dRũ0[oUI=Am,Y֙DȬձtFq+ @K9$3r]2}lw`qS؆4ޤ(<ȥ5ZAs{G3z*X$E:IŬ xN.8gcr͝Wlwr2k@j Vy 9/6%^=,1֙yNJ#a`C+pxX]]쾅W£%]_*p"L c~8Zi ګ " xG/09U.Xk#Du5,YU*$TQ9]:ʎtYֶlސ4>43^uY 0Y^:H 7H|@ #v7 A/=L9/ nhsȵT9:aDn 1,hW|GGGRJ/@JҌnH{趽nDRu 6Gyɟ Ntre4)DaslYYBif#sȢtt]bittS9,KQyzTYDex! ._d% |SװXxq8sL ]ڂ!LV`ozF+ RJPE]&i5^kDI Ȧ>4>XQ _`Gb (R /"m7 ?QDXOqk|mg"!'qz[5N2Ai@G[`'UMknZ:`m974`p+eŜZ@؝I9nݠt[<[Hr8/nܽl|EcرQQ6kIV2 #چ|X{~n1CZoeN>eUO=zr$mr|/?4Vz+_q vt$}MLHtgSQmV)$L& [X2:U 2^;Wb03/`{VZ*9lrR/cxh?A/r#=EmYfݭ .UM:XZZR#6˲fVܦ;6%"n|ۘ1Ch9 Rb  Ck.- 48BY~:^~"#HZ3{l+ArɃ {IHR!w"kw`@mrO} zy^Li4 Y[^kz;"7Ȗn Khv0V9LdnF;l,ySi.>nUPbfӒOm0ݵKgDK.`USY~v1Cԧ>XY]]avag}ؙj-=?/cN],ƺ*f4Z@vq@C,5taYL,j!I2 L+Aa$ ފO?4M[U'PU#Drꊆў+gs:[DFBl439Osi d `tMO ѱKkhDӰK}Y4I\ݱUܹNwCYZ]T`xԕL~Vp%@ ܕϭ2gfL Qw0SE6C,@'qC s=k׮HO|k˫kX_[W>> ֛x{?˸=hiP]h3"\Zv~ҤAhr2 F-\c^&4I5!# Mww |k_Cb>Uwq3_8譶8"w !8u*p5fUd%:pUK"\;q|R!~^`SΡ=0%&0Պ @X(\aa:"_*y"M3;T8bf?y\a@nb+{ ^o xNo=GYFE$=DQBGGG?z>Ɵ}5Ji=aM~bs4z+[8@-c4{ik[^MKv]Tֶp1b̻+C4]U'J3  UAB,ZO} eY&B$ 7+7f:hZUE88o;: hhF\=(CUzJ/aD?wAmh/[r?qa?(A“.ӜUQZphyAaOQ_*7ˍϹU`" #C@v4#$pW*<#.Ȩ'6EyIOAIR[(pU\v =^? [\Ҟ8Y? F;DHI(Iש Z4 tZKg[j a(Q~f  'H  KS]|;*y#f._ .'ϛOyk]'<`$˨(2jl 3^~G;}v, Þ+C3RcBOs ۗY;w?Sp4itbɱ4f?ňo.P @a7uf{sr w.o+`2/<'UHA??'4fZ6Lsy3x~% ܇͌vejEY]&PW .͋XQXXK@ 1 ?#hwW}aX9Lp]DiKI:k[nwtHyqplP gtDtW'a-և}B7ޘ-*XIJ\hzf0-]q\bipOjMk<(\j"׍`bpꢩmaĄ\ȕc9.+n Nݺ =i&hX.qPf6 $I׿gyZ=i 9WA 2#)&BJ[P*jLLN]`\&qLdC&0[.5T#"&5u+]9e?a{{A"#zfzP@eS .xi(Mld}Pɛ1Zpq4{;R$@w}zB|xx,Km FAGBQ 3&yErSrZE۶ŝcn (>-P2PE8E]&TՎޔ}-G3䂴.M{ŴMk*|rY*{$f'm>}Z)RdͯAl<=DzXnyX\n1@&=diW?\Kmޤ=3t#o 9 )QEcLAx饗/~z>Ů2YF{TSآrKJPO p>tFØ q!"`fwE@w45ZŮfZ8$]t8(}r<[ :xu?`tn-ɗ/"YjmᄦΏHbqPnoYqm fPY`Osek0ڢe^+=L&DQG?>\8Pd`=$*dTQVG lFX=U u0Aub o53^J"3]0[Jô__a8٫"yq Gto6iW(M8{=u ~ iuZ.|B[<9)Ѭ`G3^Llɹ-texrw2M(MgZc8b0 O=>@Ji>!`-!lclWeOZ!$n pO t >UEݑ1FeMLz9T8_җ/|GB6yq0ȃ3vK^˅rQohPYoIQ`F$0HBޑҴRbfW ka].6T}1+QދeIb{,?LC|n,7uIHd3pNnqC{Нx`d- -N[k65[|<+m?D_"~.12B΅O ǜϦ3Bbii -CRJOO~F a^|eUSM2%mE*VN3.tgد8WlXB@U8U1իx'mq6c`p8`,M9RпP$QI+r|RվnqJ,+dE m`$w''YXVjۅU]ՌZ%"ybH+KCt C# JLtx} }!qw;N쌊PNReK[vN4@)ONsٔ,8hTc8Qۿ~̌~>06ח46tJ]j4QEI ),.rXm#)tBք(d2"13\:~U4Q|埗I$QϒNv( ϸؒ^0!G4bO4;X?Uϵ:yp! ^?jfkllr.E밣u.⛯up7:3<1pE`1浕:C>$v|ro2<3E ^KKv< IzwwWW7﹌K7ȊPjF0TTVT@9:󐵶UBbS2N%40c&iJ]G6i%'Dp8h4p83ditc~.sIPNJ q5}Q;8rP gvd7qQznYJh4ZZ{|`NRaGB2]E(("80^/ InN $7:/ty//5su#1?ДU6ƙ2ޛExJߊtRwJ3Q^{ $Ip3X] sq0 9b>>v.kŠCA֣_&U%t`t k֓O>}kZ#= CF#FK&vflrH}z+2Bp$WmS[0 %PxdK_|-ZCN-Xw'Zk)%dsoȚQ&4۟N@ 9'ܡek05xrLPtsuh !- BWʇ(:fQ uNbCsз."xB̦z} CD,/|MPp;8ŧY~ӢExX#HI¦A$pt㖎Oz#":n(Xʢh]Xׯ_y"IgKta3%Wg|܊}|zɣjZI9]c4Vr_ M&gDtH1qmi3p7Ķ$:jk{Iq<E({^Xin O&x 0]RZj&g>VÙ?6csܰR/V再:]qr;-#N-F ֳp%w|[#otGG'O_b">h}kyB5kg씃 >MCA oӟ4??'x[[[ƚX)E@Y#2CSN :Z+*EQL+C]`. WU zFj$q  Rsdi,K9Kgf ?#%Ԍkd x}C aծsQ3ʋy1nЕlu. bjeG8 wpBWW_3Ih)j=eJq`4ZBè2T۷o㳟,/?0~g{/ E4 1LM(ktSs}W>W⥗^DQ(!E1(Dŵ6[ y#MS.xoRipv2&M t<[;{tfVzVX#B:I"︑8|!` $Q) ƍD)帳8cwt$d3(k79YRzooor"K; ?rv}] |n!`V,:$ ˋA}:.nllx`;π۫9X\\*cgò 8#*D`@i}R"㺈Uyc6a7n͛764a5E4R Hgڄ/RERc'5H0$@@d$)f|xtϮaD/  ;p bG0C#@MSH7Ve /螫W~HzhvYeY꽽=X}wā^[}7/÷&lWš|@X!3H7r|9Vȼ+kJ HhӸ<|) : tENwM0 g_ɳ:2V\9EQ0 +9 4EQh R ekW^AYuw$@|y^ XezD5n X-[Pdu h|P.Xg%EHFY$$ 1٣|_PPonO{ck[k}GZN7U[XD21$ G!,EQ+ᆙ_w]Ȳl&F !qT4%M"5IP·sT9)Z'k2s9Fx{&iitNe8TKzW-&EP IDATaREáq{Ȳ Y"rEP&Yv3ֵ 0mw @@ds#uѪ VFqQjmfs*2::#mk #̪^I&($IL33ѧ7tf}Hd6܀-t֕` 0V6[@QzL+^~:# Asdz=^Z*ŽvEQ@)3"*5?nmYA l|PEA))EEe%ENE^𭴧"" ~  (DH$B&@2QĠ#Vfxkoy{]XQ?$wR[1oN#c0YAÚ}KŪEQP$u5;ի$d0:;33f3=ʥΦ0]،f0 uak?,?61Nwƀ@|aZ'Q"Θ: ;#S1I C5^@Fm-i~)jr/" tAAPe\`UZk]IJвsj7/eM RP6( E\).ry?i-BRA2(dD"IĦɈIDL2Q$BTf6hZp8dƐ.Y@ŽUa'ո:FϛߋL7wt\ܛ` w*|fg߫l<OV={iEZ'?ycX~GWpC((.j8Z5bz pu`̝f ɹһ~sNi*޽͏_Û$m)$2M5#$I,X$PXkSǢ<>;(څNpApxVv >EcC8łB(TĿLG /N'?B [D돊. bxI/u^xzB(adJ#ܲ(N _zu1n1n]PsCS:,<-Cd `6 UNT)UA@Hf7v^]񴠢(A~n1(x"|x7 C,@_uơN-J&RSktޕ#H'tH ;zW2Ґ4],%.%/aRf$,m)C0WB(5l6lzkfwiFZ4JN d,e X 3 HLA H&P1Dm Ϭkws7!ǢqD S3bri8$2Æ}މ <QL,cWD0XV ޫWvG+aݛEQ@(8Eajˈ+p8 r"^c hw3'-@==>els1KL9h|<8aY ы u[L:: 9-'Uϸ>aeۃy Uv;lXdDR FE^>ʳM̠U.Kh^:8 .@>!2@: C%#-06tO1LAEJEA$*`nD"ismF9DžJo(&3if~v1]:0F jqmHŒ!4> 4yV3 XսN͛7EQ~q o2'yQb<1Gf?0u uCK, f*3JT  X$B" &  L #55!T 5י1|I^/u'P:|i1S Ɠ-^_=TٮSUR aGGex|JBk]:{&NaXa9YZa9Hd1"$bC" {&iOj>Km3N"g#_"dKߩ{|EqMR-Qf>db~=!dÀ8/AyK`xBp Ft (lErE̝U䡫V׭3\jT;΁1KF?@|ÙK/RdG=EXT[BLEb* .p dD ̽M (ՀeTShRwPQʄQIHQ&+<kwyU:("vNp*[z}X_7"Q,LA Gǒ?*3 .Ut:PY[@k+XU2Y,ӪIPrEN^c5ESR CO. =a&c! M r\Y5 K% m8#TdX/X|4]TDV$jVSؚ`+DB@Uo&;ii@碨((@*o? (ģ0*Ҙ~amNQۈ9zPIZ6G0);>6jJͯ~+???L*brtX;;;Si2 ;N2v0!$I%um):XхbP!i@ 3J;n('V _ҴbԪX\pz{, gx;=/8 H.RElI0EL--}Y!,4%P왺r3iE1BHeɧrk:. zndIع pTH)b)&"s x>1zڊwǒ/"6 3)2-'ǒ Ut"⋫eVoN1_AgooϤ@Wsp&I2G/ꩩ( !JS]3$5"mGN+ࡇKHiHxRB5(E2?)x&%Jz*N{ B$[$Y]{R3 Jʲ{?6{,￵%oSDI.`OZ_׮cۻ,,k-qYJ)llllv !wsY87xvvuIůSr9\~NP]MrM*T cJj.N18/4D4|` J)Nk_ݫ;U3I]scEtE&L,utA eiojA !Ȩʆ&?8.t4֊=q%Uz:>W| Œ&f\'1F0Bs4Jh}G>$K$a-F=_Xs:Chr}K S,~Ԍ$$҂F|݉("O7WffjopM/|c4u՗ ꫇΃ QIfM )Xا2-J1$J/Zt"KEiVY,)!/]f2P4b<;qI'&kXˍu{YٲEth YZ8zHъM-*.{ԤNHO>`BO5_ײ԰$Y m@0aYp=Nc)ky)Sᩈ()i g(L#ڃy#z,LKg ź@Yi$ V>f  QRN= I3m-y)Q;%,":jV=Zc3c>jyn]ߗLk%Z;uXy U<ԂІdx766c.JE)XSylaHEN^`GduRPc I]S1EY8y2HE(U5ɡ@b"ҍ,sH 1n逝 dE/]ftcdFEI "EJ;n[f(pk՜=Q'85 H 1n [X?_ ˛wח*dM777J[KG@ag7U8?ҡ Qd$XZ>: )\FPprrrZ{dIȂ,Ny0Jd}gtb(-bgN3:_ń1{O"bש!wvQ1g&~.czB$ą6|$ d"!D5] 4!jRypPgy{,S,#48HVetq>-" XMn=AG)ͤPg_W$Q ?ڛ?[4YQ~`5yZZS.9%)(dS2MI"R~pDfp@%DUGvр5}q$Y.I,E c&Rd5# )r"XEd 4_K'"e=#`݀x,I"~&{oyF' @ppW_>!K ඈ/ubb cFD>tـUx 1wvvc}Lc_Oު%(R^/:F((<):Y&H˸@&C{hYh}-#Z $DW$ ^|}7H)doma}mb/$z<sn `2w)PB+*3zt&늢*Awn6Y kmc,FS\5cX*焸uzzjidPDʼnHfGR꼀""TZK6w TLhsN)` kfl݊Z+,Zcic m6ưVGfw뚭kv}XkaNOO+_KWab1,m<Zmq }i]׊J * 0LIq\[k+-R5{0u]WuӪ,뺮MY*SUWUecg. u:_ax]t ﳘy RJeJ)+[N~Uz%4d\t:'''/yZ|ppy܃ u9E_c![jcLcjl"ꪪlVeY===gu f3rƇSQ(^˜=7ܹs/E}facp||\9F$( >1gS=x!պߠ]L/ 6;:4{Z+ĩ˲4UUٲ,MY-\Ue)UUKCԹT U*N3(aJcqRؑu㚝%巙*)hFD'"r;w@*p F%=\!XLjR8qj`X@#c}B1"jGLZI XgE ,SYauu?4OUa)P %Ptl()Ɵ!"&<>nkyqm}j"ܹ_|E2`uBb4GO1R%M.THh~5@P:j]12TUUUhUUuԺ*6ƴ1j 1ջc158ק>];#Z( P"X< rB6h=LD;웠ځJ q'nˆ~!L<>:)йH  κU1 m`/lgggVUMѼUW@m)պځXc WUUeYUUUfkNNeYþok#JZ;1XF~xS^KF< *T9"rT޽P< 1X\F_ũn|Bۯi7777y2'0Len8/# f&49k2t&cg>GR~@S"x(-{xxXfk Bw;AkMׯ_hCw nI6!%"mGEllVuB`cEd`U &7o"RFX,+B.~!X% aGx}&"34F3 `4U7x |+_ u3< "F xh< `5r{'kHP4.$? :CL?y0C7VdYUa/v,lbpFVJjEwHE4 mwA{'VExuA k?? uUۍ743?:L&E4HLLJgVC*-Z6YYYRV)H?5o'PPIw =< C늷\~}muupr]g>ܽ{wx(鴨x_>۷oVU)<3LX>yT3s ҇ TeY'˲lgYiUp4rS ]zFe,YwNvJE>#" wBD"r`+⋸sP677?g>O=ADu>I)fJ!GhN?s"YRE<2erh@` 9a"j]?H>`VxܿS" v Lh&"Dt ``&"3"*]ȊX n ue8zFO?/Pt`X H"(7BB%R*WJpRj;ɝIR#"PnB0z[@0֖ =`i{sZ2\D&JD*5jRèJk׮a7od2[[[㱲ΜL&"C+4ei w?Rn)H)fb A{>{Y\KkbKGkKD,V)UQ6"r2?Cl!}/DDeYRvQj2LGDk}Uɭ>IY(v@׏A 5SaC/)*ņ2:])|-uȬc"Lu]S]Y]׹1u]t1&3\cr!Z^W[/-sú̓ /W^ye;˿}u"+ y|2T$_YY+++xkux/~1&t:ԡܹ;rɘy䖉6cfmͭw%"ց o[-s+`ۛken=a//⥗^of+++'Sx1d5ivq~C߷;;;^W{{{l:,,lf*ݺ6x' XIپ`J7T$u)y7EDQ&"3OY9)A'ema抙kfDnmDXk]{okjf~ ֻ`~?<~w7n[n|s˲(e4LzPΌ ^؅#*? Nh*"S4a34aRCheooo`Nm{Yxd5\L&Oi޲־i_1غ[V"Znƞ8v#Ѿqi鈻 rn FD"o}fg90LT3s-"3&k`onkk C< ԧzeʁ2hkZYk1 ^ffN"̻̼hm0Cf@O[_?oCw,[IENDB`vokoscreen-1.9.0/applications/vokoscreen.xpm000066400000000000000000000310121227001500100212520ustar00rootroot00000000000000/* XPM */ static char * vokoscreen_xpm[] = { "32 32 661 2", " c None", ". c #CBCBCB", "+ c #C9C9CA", "@ c #CACACB", "# c #A9A9BB", "$ c #6D6F9E", "% c #8387AA", "& c #9196B1", "* c #A1A5B8", "= c #AFB2BD", "- c #BCBEC3", "; c #C2C4C7", "> c #C4C6C9", ", c #C5C7CA", "' c #C5C7C9", ") c #9999B3", "! c #6367A4", "~ c #7E86B8", "{ c #757FB6", "] c #6C7DB3", "^ c #6479B2", "/ c #5D76B1", "( c #5D79B1", "_ c #617FB2", ": c #6786B3", "< c #6F8CB6", "[ c #7793B7", "} c #809AB9", "| c #8DA3BD", "1 c #98AABF", "2 c #A1AFBF", "3 c #ADB7C1", "4 c #B8BEC4", "5 c #BBC0C7", "6 c #BDC1C7", "7 c #BEC2C8", "8 c #C0C2C8", "9 c #C1C3C7", "0 c #989AB2", "a c #6E75AB", "b c #9098C3", "c c #909BC6", "d c #919FC7", "e c #91A2CA", "f c #92A6CC", "g c #92A8CE", "h c #92ABD1", "i c #92AED4", "j c #92B0D6", "k c #90B0D6", "l c #8EAFD5", "m c #89ACD4", "n c #6292C6", "o c #2C6DB2", "p c #2668AF", "q c #2967AD", "r c #356BAB", "s c #4271AB", "t c #5178AC", "u c #5E7FAD", "v c #6C85AF", "w c #798DB0", "x c #8795B3", "y c #9DA5B9", "z c #C2C3C4", "A c #9A9DB3", "B c #6F78AB", "C c #8792BF", "D c #8F9CC5", "E c #8E9FC8", "F c #8EA3CA", "G c #8FA5CD", "H c #92ABCF", "I c #8CA6C6", "J c #7E98B8", "K c #7F9CBC", "L c #89AACE", "M c #8FB4D8", "N c #93B7D8", "O c #699BCA", "P c #3377B7", "Q c #2E73B5", "R c #2E71B4", "S c #2D6EB1", "T c #2C6AAF", "U c #2B66AC", "V c #2A60A8", "W c #295AA5", "X c #2854A0", "Y c #254D9A", "Z c #355498", "` c #99A0B1", " . c #A6A9BA", ".. c #747EAD", "+. c #7A88BA", "@. c #8B9BC5", "#. c #8FA2C9", "$. c #8EA5CC", "%. c #8DA5C7", "&. c #7B8CA5", "*. c #717A89", "=. c #70767F", "-. c #6C7780", ";. c #8298AC", ">. c #92B4D3", ",. c #93BADC", "'. c #619BCB", "). c #307CBB", "!. c #2E7AB9", "~. c #2F77B8", "{. c #2F75B6", "]. c #2F72B3", "^. c #2F6DB0", "/. c #2F68AD", "(. c #2E63A9", "_. c #2F5EA5", ":. c #28539E", "<. c #264A94", "[. c #8490AC", "}. c #B5B7BF", "|. c #7883B0", "1. c #7284B8", "2. c #8196C2", "3. c #8BA1CA", "4. c #91A8CC", "5. c #7A889C", "6. c #4D505E", "7. c #85858E", "8. c #BABCC0", "9. c #6C6D75", "0. c #5E6067", "a. c #94A1AD", "b. c #9DBCD6", "c. c #5A9CCE", "d. c #2E82C0", "e. c #2E7FBE", "f. c #2F7ABA", "g. c #2F77B7", "h. c #2E72B4", "i. c #3068AD", "j. c #2A5FA6", "k. c #184B9A", "l. c #194492", "m. c #7183A8", "n. c #7C88B1", "o. c #6D82B7", "p. c #8096C3", "q. c #829BC7", "r. c #9EB0CA", "s. c #5D6378", "t. c #81828D", "u. c #8A8C93", "v. c #BFC2C6", "w. c #181A2D", "x. c #393A49", "y. c #A0A6AC", "z. c #7F8C99", "A. c #4D82A8", "B. c #2C86C0", "C. c #3177B3", "D. c #307AB7", "E. c #2E81C0", "F. c #2E7BBB", "G. c #3072B4", "H. c #1A57A3", "I. c #11499A", "J. c #124294", "K. c #687EA7", "L. c #7E8CB0", "M. c #6D83B8", "N. c #8098C4", "O. c #7F9BC7", "P. c #96A1B3", "Q. c #737897", "R. c #6F6F76", "S. c #151728", "T. c #CED1D6", "U. c #7E828F", "V. c #A1A7B1", "W. c #89909A", "X. c #373B48", "Y. c #4D6178", "Z. c #2E5E8E", "`. c #283B67", " + c #3072AB", ".+ c #2F87C5", "++ c #3081BF", "@+ c #2D7ABA", "#+ c #236EB3", "$+ c #1760A9", "%+ c #1255A2", "&+ c #124E9D", "*+ c #174A9A", "=+ c #6C83AD", "-+ c #7F8CAF", ";+ c #7188B9", ">+ c #8099C5", ",+ c #809CC7", "'+ c #757E90", ")+ c #A7ABBF", "!+ c #7F8289", "~+ c #606371", "{+ c #C5C9CF", "]+ c #9DA6AE", "^+ c #BBC4CB", "/+ c #4B505F", "(+ c #29293A", "_+ c #607287", ":+ c #3B78A7", "<+ c #27608C", "[+ c #2F88C1", "}+ c #2A89C5", "|+ c #237EBE", "1+ c #1B74B7", "2+ c #1468B0", "3+ c #125FAA", "4+ c #1258A5", "5+ c #1452A0", "6+ c #2F5EA6", "7+ c #6882AE", "8+ c #A2A9B7", "9+ c #8693B1", "0+ c #7189B9", "a+ c #7F99C6", "b+ c #809EC8", "c+ c #626B79", "d+ c #B3B7C0", "e+ c #989CA3", "f+ c #B8BDC4", "g+ c #ABB3BC", "h+ c #393A3E", "i+ c #B8BBBE", "j+ c #919EAC", "k+ c #7F8A99", "l+ c #6E8FA6", "m+ c #2F95C9", "n+ c #1E90CB", "o+ c #1B8BCA", "p+ c #1884C4", "q+ c #147BBE", "r+ c #1172B9", "s+ c #126AB3", "t+ c #1263AD", "u+ c #125BA7", "v+ c #1957A3", "w+ c #4974B3", "x+ c #5978AB", "y+ c #9CA6B7", "z+ c #98A2B7", "A+ c #6B84B6", "B+ c #7D98C6", "C+ c #7F9FC9", "D+ c #667687", "E+ c #83868C", "F+ c #242634", "G+ c #6A6D7B", "H+ c #ADB6BF", "I+ c #A1A3A5", "J+ c #B8BDC3", "K+ c #4D5465", "L+ c #606777", "M+ c #5B8198", "N+ c #1C88BA", "O+ c #1392CF", "P+ c #128BCB", "Q+ c #0C84C8", "R+ c #0C7BC1", "S+ c #1272B6", "T+ c #0E6BB5", "U+ c #0D63B0", "V+ c #115CA9", "W+ c #2F69AD", "X+ c #507AB6", "Y+ c #4C6FA9", "Z+ c #96A2B7", "`+ c #AEB3BE", " @ c #667FB2", ".@ c #7B98C5", "+@ c #7F9FCA", "@@ c #7996B6", "#@ c #6B7178", "$@ c #2C2C38", "%@ c #9095A0", "&@ c #979FA9", "*@ c #858D99", "=@ c #141529", "-@ c #545767", ";@ c #4B7F9A", ">@ c #118FC4", ",@ c #1297D4", "'@ c #108DCD", ")@ c #5390B4", "!@ c #708594", "~@ c #67747F", "{@ c #657583", "]@ c #4F769C", "^@ c #4B7DB9", "/@ c #4E7AB6", "(@ c #4269AA", "_@ c #919EB6", ":@ c #C9C8C6", "<@ c #617CAF", "[@ c #7996C4", "}@ c #7FA0CB", "|@ c #7FA3CC", "1@ c #7A94AF", "2@ c #8E959D", "3@ c #99A3AC", "4@ c #343749", "5@ c #33364A", "6@ c #8D9EAD", "7@ c #515563", "8@ c #7D909E", "9@ c #1E80A9", "0@ c #119DD7", "a@ c #1095D2", "b@ c #6D8E9F", "c@ c #626568", "d@ c #58575A", "e@ c #565558", "f@ c #575758", "g@ c #545658", "h@ c #616E7D", "i@ c #4E7EB6", "j@ c #4E7BB6", "k@ c #436CAE", "l@ c #8695B2", "m@ c #D5D1C9", "n@ c #617BAC", "o@ c #7895C4", "p@ c #80A0CB", "q@ c #7FA4CE", "r@ c #80A8CF", "s@ c #8CA8C1", "t@ c #646E7B", "u@ c #333745", "v@ c #4A4B57", "w@ c #8F9DAB", "x@ c #6E8294", "y@ c #4583A1", "z@ c #1495CD", "A@ c #0C9CDB", "B@ c #578EA8", "C@ c #585859", "D@ c #424347", "E@ c #313339", "F@ c #383940", "G@ c #36383E", "H@ c #444449", "I@ c #4F4F4F", "J@ c #5A697E", "K@ c #4D7BBA", "L@ c #4970B0", "M@ c #7186AC", "N@ c #667EAB", "O@ c #7A96C3", "P@ c #7FA3CD", "Q@ c #80A8D0", "R@ c #80ACD3", "S@ c #7EA6C7", "T@ c #7A9BB4", "U@ c #7D9DB4", "V@ c #78A4C0", "W@ c #75ACC9", "X@ c #50A5D0", "Y@ c #0F94D3", "Z@ c #1990C8", "`@ c #5B6268", " # c #505154", ".# c #35363E", "+# c #464850", "@# c #50525C", "## c #505460", "$# c #445770", "%# c #5B5F67", "&# c #44474C", "*# c #4E71A3", "=# c #4C72B2", "-# c #5F76A6", ";# c #ADB3BE", "># c #7286AE", ",# c #7590C0", "'# c #809ECA", ")# c #80A2CC", "!# c #80A7CF", "~# c #7FABD2", "{# c #80AFD6", "]# c #80B3D9", "^# c #80B8DC", "/# c #80BADE", "(# c #80BEE0", "_# c #50AAD8", ":# c #0A8BCE", "<# c #3486B1", "[# c #555A5C", "}# c #383B41", "|# c #4C5362", "1# c #5E606B", "2# c #5F6064", "3# c #617187", "4# c #525867", "5# c #5D7A98", "6# c #5B5A5C", "7# c #4C6388", "8# c #4D73B3", "9# c #4D68A1", "0# c #ADB2BF", "a# c #8A99B5", "b# c #6784B8", "c# c #80A1CB", "d# c #80A5CE", "e# c #80A9D1", "f# c #80ADD4", "g# c #80B2D7", "h# c #80B4D9", "i# c #80B8DD", "j# c #7EB9DD", "k# c #48A0D2", "l# c #0B84C9", "m# c #357AA2", "n# c #545758", "o# c #41576F", "p# c #525C6E", "q# c #5F6D7F", "r# c #514F4D", "s# c #717782", "t# c #777F90", "u# c #7F8B9C", "v# c #606165", "w# c #485C7C", "x# c #4E72B3", "y# c #3F5C9F", "z# c #A8AEBB", "A# c #A5ACBC", "B# c #5876AF", "C# c #80A0CA", "D# c #80A3CD", "E# c #80A7D0", "F# c #80ABD3", "G# c #80AED5", "H# c #7BB5DA", "I# c #4096CC", "J# c #0C7DC3", "K# c #2672A3", "L# c #505354", "M# c #627991", "N# c #646A78", "O# c #7E889A", "P# c #72757F", "Q# c #9CA1B4", "R# c #A0A7BC", "S# c #8E92A2", "T# c #545559", "U# c #496087", "V# c #4F70B0", "W# c #3D5BA3", "X# c #99A0B3", "Y# c #C2C3C6", "Z# c #4B69A7", "`# c #8099C6", " $ c #80AFD5", ".$ c #80B1D7", "+$ c #78AFD6", "@$ c #398BC5", "#$ c #0F75BC", "$$ c #1575B7", "%$ c #354048", "&$ c #727174", "*$ c #7B8598", "=$ c #9398AB", "-$ c #B9BED6", ";$ c #BFC4DD", ">$ c #B3B8CE", ",$ c #9597A3", "'$ c #373A41", ")$ c #4C6AA1", "!$ c #4E6CAC", "~$ c #4861A5", "{$ c #7C87A8", "]$ c #D5D2CB", "^$ c #4662A2", "/$ c #7F9CC7", "($ c #809FCA", "_$ c #80A6CE", ":$ c #80A8D1", "<$ c #75A9D3", "[$ c #3080BE", "}$ c #106DB5", "|$ c #1072BB", "1$ c #295B84", "2$ c #47484A", "3$ c #797A81", "4$ c #9499A9", "5$ c #B5BBD0", "6$ c #B8BDD3", "7$ c #A1A5B4", "8$ c #48484A", "9$ c #3C4D6C", "0$ c #4F72B4", "a$ c #4E69A9", "b$ c #4B61A5", "c$ c #65709E", "d$ c #D0CDC6", "e$ c #4E66A0", "f$ c #7F96C2", "g$ c #80ABD2", "h$ c #72A3CF", "i$ c #2874B7", "j$ c #1066AF", "k$ c #1368B0", "l$ c #1167B2", "m$ c #2B4D6E", "n$ c #3E454D", "o$ c #6C6C71", "p$ c #84858D", "q$ c #75757A", "r$ c #3C3B3D", "s$ c #253045", "t$ c #21488F", "u$ c #3D5DA2", "v$ c #4B63A5", "w$ c #4E61A4", "x$ c #4F5B95", "y$ c #CCCAC3", "z$ c #6173A3", "A$ c #768BBC", "B$ c #8097C3", "C$ c #809DC8", "D$ c #80A4CE", "E$ c #6F9DCB", "F$ c #2068AF", "G$ c #115FAA", "H$ c #1360AA", "I$ c #115EAB", "J$ c #1E4E82", "K$ c #203550", "L$ c #1A2533", "M$ c #1C283C", "N$ c #192E50", "O$ c #0D3172", "P$ c #103787", "Q$ c #15378C", "R$ c #2D4694", "S$ c #44549B", "T$ c #3E4991", "U$ c #BBBCC0", "V$ c #7E89AD", "W$ c #6579B1", "X$ c #8397C3", "Y$ c #8298C4", "Z$ c #819BC7", "`$ c #819EC9", " % c #81A0CB", ".% c #81A3CC", "+% c #81A4CE", "@% c #6C97C7", "#% c #1358A6", "$% c #0E55A4", "%% c #0E54A3", "&% c #0D52A2", "*% c #0B4FA2", "=% c #084390", "-% c #073679", ";% c #06357E", ">% c #08398E", ",% c #0B3890", "'% c #0A3089", ")% c #092883", "!% c #08207E", "~% c #162680", "{% c #1B2480", "]% c #A4A4B2", "^% c #9DA2B8", "/% c #3F539C", "(% c #697CB5", "_% c #667EB4", ":% c #6680B5", "<% c #6988B9", "[% c #6B8BBB", "}% c #6C8EBC", "|% c #6086B8", "1% c #2B60A3", "2% c #3064A4", "3% c #3467A5", "4% c #3969A6", "5% c #3E6CA7", "6% c #426CA6", "7% c #476EA6", "8% c #4C70A9", "9% c #5170A7", "0% c #5570A4", "a% c #5970A3", "b% c #5E71A2", "c% c #6271A1", "d% c #6671A0", "e% c #69719F", "f% c #6D709F", "g% c #A9ACBA", "h% c #C1C2C6", "i% c #8F96B3", "j% c #8E95AB", "k% c #969FB4", "l% c #A1ABBF", "m% c #A2ACBF", "n% c #A4AEC0", "o% c #A5AFC1", "p% c #A6B1C1", "q% c #A1AEBF", "r% c #A5B1C0", "s% c #A8B3C1", "t% c #ABB4C1", "u% c #ADB6C2", "v% c #AFB6C1", "w% c #B1B8C2", "x% c #B4B9C2", "y% c #B5B9C1", "z% c #BABDC4", "A% c #BBBEC3", "B% c #BEBFC3", "C% c #C3C4C6", "D% c #C4C5C5", "E% c #C7C7C6", "F% c #CDCDC9", "G% c #C3C5C8", "H% c #CECECA", "I% c #BDBCB8", "J% c #C4C3BF", "K% c #D6D4D1", "L% c #D8D6D3", "M% c #DBD9D5", "N% c #272727", "O% c #242424", "P% c #383838", "Q% c #3C3C3C", "R% c #404040", "S% c #444444", "T% c #474747", "U% c #4B4B4B", "V% c #5F5F5F", "W% c #6B6B6B", "X% c #717171", "Y% c #787878", "Z% c #7F7F7F", "`% c #878787", " & c #8F8F8F", ".& c #B4B4B4", "+& c #CFCFCF", "@& c #D5D5D5", "#& c #D9D9D9", "$& c #DADADA", "%& c #D8D8D8", "&& c #D3D3D3", "*& c #838383", "=& c #818181", "-& c #727272", ";& c #666666", ">& c #5C5C5C", ",& c #545454", "'& c #4E4E4E", ")& c #4A4A4A", "!& c #4C4C4C", " . + @ @ ", " # $ % & * = - ; > , , , ' ' ", " ) ! ~ { ] ^ / ( _ : < [ } | 1 2 3 4 5 6 7 7 8 9 ", " 0 a b c d e f g h i j k l m n o p q r s t u v w x y z ", " A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ` ", " ...+.@.#.$.%.&.*.=.-.;.>.,.'.).!.~.{.].^./.(._.:.<.[. ", " }.|.1.2.3.4.5.6.7.8.9.0.a.b.c.d.d.e.f.g.h.^.i.j.k.l.m. ", " n.o.p.q.r.s.t.u.v.w.x.y.z.A.B.C.D.E.F.~.G.q H.I.J.K. ", " L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.`. +.+++@+#+$+%+&+*+=+ ", " -+;+>+,+'+)+!+~+{+]+^+/+(+_+:+<+[+}+|+1+2+3+4+5+6+7+8+ ", " 9+0+a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+r+s+t+u+v+w+x+y+ ", " z+A+B+C+D+E+F+G+H+I+J+K+L+M+N+O+P+Q+R+S+T+U+V+W+X+Y+Z+ ", " `+ @.@+@@@#@$@%@&@*@a.=@-@;@>@,@'@)@!@~@{@]@$+^@/@(@_@ ", " :@<@[@}@|@1@2@3@4@5@6@7@8@9@0@a@b@c@d@e@f@g@h@i@j@k@l@ ", " m@n@o@p@q@r@s@t@u@v@w@x@y@z@A@B@C@D@E@F@G@H@I@J@K@L@M@ ", " N@O@+@P@Q@R@S@T@U@V@W@X@Y@Z@`@ #.#+#@###$#%#&#*#=#-#;# ", " >#,#'#)#!#~#{#]#^#/#(#_#:#<#[#}#|#1#2#3#4#5#6#7#8#9#0# ", " a#b#b+c#d#e#f#g#h#i#j#k#l#m#n#o#p#q#r#s#t#u#v#w#x#y#z# ", " A#B#,+C#D#E#F#G#g#h#H#I#J#K#L#M#N#O#P#Q#R#S#T#U#V#W#X# ", " Y#Z#`#b+c#d#Q@F# $.$+$@$#$$$%$&$*$=$-$;$>$,$'$)$!$~${$ ", " ]$^$N./$($)#_$:$R@G#<$[$}$|$1$2$3$4$5$6$7$8$9$0$a$b$c$ ", " d$e$f$>+,+($)#_$Q@g$h$i$j$k$l$m$n$o$p$q$r$s$t$u$v$w$x$Y#", " y$z$A$B$>+C$($)#D$!#E$F$G$H$3+I$J$K$L$M$N$O$P$Q$R$S$T$U$", " V$W$X$Y$Z$`$ %.%+%@%#%$%$%%%&%*%=%-%;%>%,%'%)%!%~%{%]%", " ^%/%(%_%:%b#<%[%}%|%1%2%3%4%5%6%7%8%9%0%a%b%c%d%e%f%g%", " h%i%j%k%l%m%n%o%p%p%q%r%s%t%u%v%w%x%y%z%A%B%C%D%E%F%G%", " E%H%I%J%K%L%M% ", " N%O% ", " P%Q%R%S%T%U% ", " V%W%X%Y%Z%`% & ", " .&+&@&#&$&%&&& ", " *&=&-&;&>&,&'&)&!& "}; vokoscreen-1.9.0/audio/000077500000000000000000000000001227001500100147645ustar00rootroot00000000000000vokoscreen-1.9.0/audio/QvkAlsaDevice.cpp000066400000000000000000000110571227001500100201560ustar00rootroot00000000000000#include "QvkAlsaDevice.h" #include "alsa_device.h" using namespace std; QvkAlsaDevice::QvkAlsaDevice( QString value ) { setCard( value ); setAlsaHw(); //setChannel(); setAlsaName(); setAlsaSample(); qDebug() << "[vokoscreen] Find CaptureCard:" << getAlsaName();//<< "with channel:" << getChannel() << "and" << getAlsaSample() << "Hz"; } QvkAlsaDevice::QvkAlsaDevice() { // Leerer Kontructor z.b für getAlsaVersion() abfragen } QvkAlsaDevice::~QvkAlsaDevice() { } QString QvkAlsaDevice::getAlsaVersion() { const char * version = snd_asoundlib_version(); return version; } void QvkAlsaDevice::setAlsaSample() { std::string stdString( getAlsaHw().toStdString() ); const char *device_name = stdString.c_str(); // Ungefähre Samplerrate setzen unsigned int samplerate = 40000; // Samplerrate ermitteln alsa_device_sample( device_name, samplerate ); // Samplerrate holen AlsaSample = QString::number( rcSampleRate ); } QString QvkAlsaDevice::getAlsaSample() { return AlsaSample; } bool QvkAlsaDevice::isbusy() { std::string stdString( getAlsaHw().toStdString() ); const char *device_name = stdString.c_str(); bool rc; alsa_device_busy( device_name ); if ( rcBusy == 0 ) rc = false; else rc = true; return rc; } void QvkAlsaDevice::setAlsaName() { register int err; int cardNum; QString alsaName; QString cardNumber = getCard().remove( "card" ); // Start with first card cardNum = -1; for (;;) { snd_ctl_t *cardHandle; if ( ( err = snd_card_next( &cardNum ) ) < 0 ) { printf( "Can't get the next card number: %s\n", snd_strerror( err ) ); break; } if ( cardNum < 0 ) break; if ( cardNumber == QString::number( cardNum ) ) { char str[ 64 ]; sprintf( str, "hw:%i", cardNum ); if ( ( err = snd_ctl_open( &cardHandle, str, 0 ) ) < 0 ) { printf( "Can't open card %i: %s\n", cardNum, snd_strerror( err ) ); continue; } snd_ctl_card_info_t *cardInfo; snd_ctl_card_info_alloca( &cardInfo ); if ( ( err = snd_ctl_card_info( cardHandle, cardInfo ) ) < 0 ) printf( "Can't get info for card %i: %s\n", cardNum, snd_strerror( err ) ); else { alsaName = snd_ctl_card_info_get_name( cardInfo ); } } } AlsaName = "[" + getAlsaHw() + "] " + alsaName; } QString QvkAlsaDevice::getAlsaName() { return AlsaName; } void QvkAlsaDevice::setChannel() { // Beim Start von vokoscreen könnte ein Gerät belegt sein // Die Kanäle werden kurz vor der Aufnahme ermittelt. if ( isbusy() == false ) { std::string stdString( getAlsaHw().toStdString() ); const char *device_name = stdString.c_str(); int i; for ( i = 1; i <= 255; i++ ) { alsa_device_open( device_name, i ); if ( rc == 1 ) { AlsaCannel = QString::number( i ); break; } } } } QString QvkAlsaDevice::getChannel() { return AlsaCannel; } void QvkAlsaDevice::setAlsaHw() { QString cardNumber = getCard().remove( "card" ); register int err; int cardNum; cardNum = -1; for (;;) { snd_ctl_t *cardHandle; if ( ( err = snd_card_next( &cardNum ) ) < 0 ) { printf( "Can't get the next card number: %s\n", snd_strerror( err ) ); break; } if ( cardNum < 0 ) break; if ( cardNumber == QString::number( cardNum ) ) { char str[ 64 ]; sprintf( str, "hw:%i", cardNum ); if ( ( err = snd_ctl_open( &cardHandle, str, 0 ) ) < 0 ) { printf( "Can't open card %i: %s\n", cardNum, snd_strerror( err ) ); continue; } snd_ctl_card_info_t *cardInfo; snd_ctl_card_info_alloca( &cardInfo ); if ( ( err = snd_ctl_card_info( cardHandle, cardInfo ) ) < 0 ) printf( "Can't get info for card %i: %s\n", cardNum, snd_strerror( err ) ); int devNum; devNum = -1; if ( ( err = snd_ctl_pcm_next_device( cardHandle, &devNum ) ) < 0 ) { printf( "Can't get next wave device number: %s\n", snd_strerror( err ) ); break; } if ( devNum < 0 ) break; AlsaHw = "hw:" + QString::number( cardNum ) + "," + QString::number( devNum ); } } snd_config_update_free_global(); } QString QvkAlsaDevice::getAlsaHw() { return AlsaHw; } void QvkAlsaDevice::setCard( QString value ) { cardx = value; } QString QvkAlsaDevice::getCard() { return cardx; } vokoscreen-1.9.0/audio/QvkAlsaDevice.h000066400000000000000000000023401227001500100176160ustar00rootroot00000000000000#ifndef QvkAlsaDevice_H #define QvkAlsaDevice_H #include #include #include #include #include #include #include #include #include #include struct AlsaDevice_ { char *device_name; int channels; snd_pcm_t *capture_handle; snd_pcm_t *playback_handle; int readN, writeN; struct pollfd *read_fd, *write_fd; }; class QvkAlsaDevice: public QObject { Q_OBJECT public: QvkAlsaDevice( QString cardx ); virtual ~QvkAlsaDevice(); QvkAlsaDevice(); public slots: QString getCard(); // libasound QString getAlsaHw(); // libasound QString getChannel(); // libasound QString getAlsaName(); // libasound QString getAlsaSample(); QString getAlsaVersion(); // libasound bool isbusy(); // libasound void setChannel(); private slots: void setCard( QString string ); void setAlsaHw(); void setAlsaName(); void setAlsaSample(); //void alsa_device_sample( const char *device_name, unsigned int rate ); signals: protected: private: QString cardx; QString AlsaHw; QString AlsaCannel; QString AlsaName; QString AlsaSample; }; #endif vokoscreen-1.9.0/audio/QvkAlsaWatcher.cpp000066400000000000000000000016241227001500100203530ustar00rootroot00000000000000 #include "QvkAlsaWatcher.h" using namespace std; QvkAlsaWatcher::QvkAlsaWatcher() { AlsaCardCounter = -1; QTimer *timer = new QTimer( this ); connect( timer, SIGNAL( timeout() ), this, SLOT( AlsaWatcherTimer() ) ); timer->start( 500 ); } QvkAlsaWatcher::~QvkAlsaWatcher() { } void QvkAlsaWatcher::AlsaWatcherTimer() { register int err; int cardNum; cardNum = -1; QStringList deviceList; for (;;) { if ( ( err = snd_card_next( &cardNum ) ) < 0 ) { printf( "Can't get the next card number: %s\n", snd_strerror( err ) ); break; } else { if ( cardNum > -1 ) deviceList.append( "card" + QString::number( cardNum ) ); } if ( cardNum < 0 ) break; } if ( AlsaCardCounter != deviceList.count() ) { AlsaCardCounter = deviceList.count() ; emit changed( deviceList ); } } vokoscreen-1.9.0/audio/QvkAlsaWatcher.h000066400000000000000000000010721227001500100200150ustar00rootroot00000000000000#ifndef QvkAlsaWatcher_H #define QvkAlsaWatcher_H #include #include #include #include #include class QvkAlsaWatcher: public QObject { Q_OBJECT public: QvkAlsaWatcher(); virtual ~QvkAlsaWatcher(); public slots: private slots: void AlsaWatcherTimer(); signals: /** * Dieses Signal wird ausgelöst wenn sich die Anzahl der Alsageräte ändert * int count -> Anzahl der Geräte */ void changed( QStringList ); protected: private: int AlsaCardCounter; }; #endif vokoscreen-1.9.0/audio/alsa_device.c000066400000000000000000000107371227001500100173770ustar00rootroot00000000000000 #include "alsa_device.h" struct AlsaDevice_ { char *device_name; int channels; snd_pcm_t *capture_handle; snd_pcm_t *playback_handle; int readN, writeN; struct pollfd *read_fd, *write_fd; }; AlsaDevice *alsa_device_sample( const char *device_name, unsigned int rate ) { int err; snd_pcm_hw_params_t *hw_params; static snd_output_t *jcd_out; AlsaDevice *dev = malloc( sizeof( *dev ) ); if ( !dev ) return NULL; dev->device_name = malloc( 1 + strlen( device_name ) ); if ( !dev->device_name ) { free(dev); return NULL; } strcpy(dev->device_name, device_name); err = snd_output_stdio_attach( &jcd_out, stdout, 0 ); if ( ( err = snd_pcm_open ( &dev->capture_handle, dev->device_name, SND_PCM_STREAM_CAPTURE, 0 ) ) < 0 ) { rc = 0; fprintf (stderr, "\033[0;31m[vokoscreen] alsa_device_sample() in alsadevice.c: cannot open audio device %s (%s)\033[0;0m\n", dev->device_name, snd_strerror (err) ); return NULL; } else { rc = 1; fprintf (stderr, "[vokoscreen] alsa_device_sample() in alsadevice.c: open audio device %s (%s)\n", dev->device_name, snd_strerror (err) ); } if ( ( err = snd_pcm_hw_params_malloc ( &hw_params ) ) < 0 ) { fprintf (stderr, "[vokoscreen] alsa_device_sample() in alsadevice.c: cannot allocate hardware parameter structure (%s)\n", snd_strerror( err ) ); } if ( ( err = snd_pcm_hw_params_any( dev->capture_handle, hw_params ) ) < 0 ) { fprintf (stderr, "[vokoscreen] alsa_device_sample() in alsadevice.c: cannot initialize hardware parameter structure (%s)\n", snd_strerror( err ) ); } if ( ( err = snd_pcm_hw_params_set_rate_near (dev->capture_handle, hw_params, &rate, 0 ) ) < 0 ) { fprintf( stderr, "[vokoscreen] alsa_device_sample() in alsadevice.c: cannot set sample rate (%s)\n", snd_strerror( err ) ); rc = 0; } else { rc = 1; rcSampleRate = rate; } fprintf ( stderr, "[vokoscreen] alsa_device_sample() in alsadevice.c: Samplerate = %d\n", rate ); snd_pcm_close( dev->capture_handle ); free( dev->device_name ); free( dev ); return dev; } AlsaDevice *alsa_device_open( const char *device_name, int channels ) { int err; snd_pcm_hw_params_t *hw_params; static snd_output_t *jcd_out; AlsaDevice *dev = malloc( sizeof( *dev ) ); if ( !dev ) return NULL; dev->device_name = malloc( 1 + strlen( device_name ) ); if ( !dev->device_name ) { free(dev); return NULL; } strcpy(dev->device_name, device_name); dev->channels = channels; err = snd_output_stdio_attach( &jcd_out, stdout, 0 ); int okOpen = 0; while ( okOpen == 0 ) { if ( ( err = snd_pcm_open ( &dev->capture_handle, dev->device_name, SND_PCM_STREAM_CAPTURE, 0 ) ) < 0 ) { rc = 0; } else { rc = 1; okOpen = 1; } } if ( ( err = snd_pcm_hw_params_malloc ( &hw_params ) ) < 0 ) { fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n", snd_strerror( err ) ); } if ((err = snd_pcm_hw_params_any (dev->capture_handle, hw_params)) < 0) { fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n", snd_strerror( err ) ); } if ( ( err = snd_pcm_hw_params_set_channels( dev->capture_handle, hw_params, channels ) ) < 0 ) { rc = 0; } else { rc = 1; } snd_pcm_close( dev->capture_handle ); free( dev->device_name ); free( dev ); return dev; } AlsaDevice *alsa_device_busy( const char *device_name ) { int err; static snd_output_t *jcd_out; AlsaDevice *dev = malloc(sizeof(*dev)); if (!dev) return NULL; dev->device_name = malloc(1+strlen(device_name)); if (!dev->device_name) { free(dev); return NULL; } strcpy(dev->device_name, device_name); err = snd_output_stdio_attach(&jcd_out, stdout, 0); if ( ( err = snd_pcm_open ( &dev->capture_handle, dev->device_name, SND_PCM_STREAM_CAPTURE, 0 ) ) < 0 ) { fprintf (stderr, "[vokoscreen] alsa_device_busy() in alsadevice.c: cannot open audio device %s (%s)\n", dev->device_name, snd_strerror (err) ); rcBusy = 1; return NULL; } else rcBusy = 0; snd_pcm_close(dev->capture_handle); free(dev->device_name); free(dev); return dev; } void alsa_device_close(AlsaDevice *dev) { snd_pcm_close(dev->capture_handle); snd_pcm_close(dev->playback_handle); free(dev->device_name); free(dev); } vokoscreen-1.9.0/audio/alsa_device.h000066400000000000000000000010401227001500100173670ustar00rootroot00000000000000#ifndef ALSA_DEVICE_H #define ALSA_DEVICE_H #include #include #include #ifdef __cplusplus extern "C" { #endif struct AlsaDevice_; typedef struct AlsaDevice_ AlsaDevice; AlsaDevice *alsa_device_open(const char *device_name, int channels ); AlsaDevice *alsa_device_busy( const char *device_name ); void alsa_device_close( AlsaDevice *dev ); AlsaDevice *alsa_device_sample( const char *device_name, unsigned int rate ); int rc; int rcBusy; int rcSampleRate; #ifdef __cplusplus } #endif #endif vokoscreen-1.9.0/audio/audio.pri000066400000000000000000000004651227001500100166060ustar00rootroot00000000000000INCLUDEPATH += $$PWD DEPENDPATH += $$PWD HEADERS += $$PWD/QvkAlsaWatcher.h \ $$PWD/QvkAlsaDevice.h \ $$PWD/alsa_device.h SOURCES += $$PWD/QvkAlsaWatcher.cpp \ $$PWD/QvkAlsaDevice.cpp \ $$PWD/alsa_device.c vokoscreen-1.9.0/future/000077500000000000000000000000001227001500100151755ustar00rootroot00000000000000vokoscreen-1.9.0/future/SourceToBinary.odg000066400000000000000000000320561227001500100206060ustar00rootroot00000000000000PKmB.++mimetypeapplication/vnd.oasis.opendocument.graphicsPKmB content.xml\ێܸ}WȣԼ3$@b;}ӴӊՒ ?|IM=\nSdYuXU~8(,Q.(No.gW7|r/E-6kV"K+G/g"2./pmʋjq&m.vx]j*3Ҏx+[!wTwS@/e.3@}UH$N]VU_wwwfNs; MXh179輥]**EJ7kSL&­] S 9m!Ⱦno&[lgxl*vU#EOVgY։ [q!b^?qe "Lzh@G@[4Ήrq_>~Y:nUȔ8 @h4l H:^0yVT- 0ZUdі C8`t:la.c7 1&h3wb98aAiEUivĸF8,..m%g X&<<̮ùvru*Շ:_nJ(c5=@W}^yxcf7Mxva)}pk&(,Y;o)ؔ H&eѬcO28^~ZB;]'Tuul0q-T3v3m(XlX/٦XfrبN3ǞI=iZmb쨎r I➂މOg[$W-,@UfSw$YV #xOݑ;Ĥ^jMT6Dt[:hiHOiW#Ç(ܤכ8JSܚ .0UO~&4n*^CQDŽS8B7FyR(/#p84SG\ӊ8|ȉVcU :?9~ŷʳ 1Puh BM(Z#岀wOX7:FQ;:oEZ&L۞vދ~}q`3OG`5<`w_$LyL^}7q?9!qѡ r!‘˧@=6 Hѩڢw8~h˴t{+S߲U+7KqWWycdxiwU~bjJEd~ē}9=v!x=<@(P^0P@#W{#)QDҡH"+|z< r01D`/RO d1:I!{b+a< Cz@؁8yXJ'[:c&]f߲rQM z.r<o-l<ފX ?Os0TŃel, :2JNvL#K8V6 Y۶ P#_ڔ6(T \Ro@ kB|uS+MHG\)lkZa!a;89Z N. E RI!3P,CnH}z8 pJ r<`C#9PrSЭ4t8#&S`L (.}H)>`m0 , IpIa%8pJB>d DZse $C34åKEeZIB0EhiD 0!|+Eq'ۯg]F.|~e犃X8bP\]"&@ =Lڇ6v9䋘 S\jM*vRD7zA^Ma8ˆuo`{*# `O]z%r S&5N-Uy#80 -p9eOѧ!8Qx<%> >DWck:bD&\,p.JHZ^ yv dCr.H8}sߥdj̳/xfwz-vcy>dl!|_p?LbҼs8Ů\@ၷ5'zg$oχ ӗgChB<gJD>e% ֍B%ԋIhF kXZ*䈚|h^Lf J ")EDYJ僆C>z׌Nfx{088u6̺Lp;:4z:E<&uZ(~,|/ehϩp :FH%O{T]%@<٪U {G_ϺT+-IP.;i>SGNOrdiR6<}bMՄaME=8'ט$If ew=cC8ON*&)F>}fig 0=Iz:ڽiƧCHiB7{A})FeſFE&1o k5a NL!kW9u9 ®@R5 mk7sԿ°t :YU3ݜe3Tkq_*2o %_3 8⁻-QiYlx,km{n5!CP}F%9Y=_inCxt#_Fଜ#u4};4()}d{ΏM:]o^PK80PKmB4hhmeta.xml 2013-07-09T09:23:172013-07-22T15:40:30PT01H18M38S33OpenOffice.org/3.2$Unix OpenOffice.org_project/320m12$Build-9483PKmBThumbnails/thumbnail.pngEWi8 ~c0df֨){K!Q0 "<E P eielEi2YCssq_Iq9l'*"'@l@R`+`mq42o6K髻cAT6=:!8x$@lD鍊Z{8gEW ]/>M,jyܐQG~(1YeAqcwc~r!N"sܣJa^ A2A!y5L΢{$F6HUnlUY`Îb](Qh杁Ci\7t8fA{-9uaȪ T: x毠QSǴUTbJ:T)oOtn5!K 2;޵G~8)&h*bA8~A} m,j):m <-n Wi/`11 ؾO]ܿX|&'h㟻\m4CY ;{I QV.aHx,{ͫ)wdىA4@2)4H}S )b A;p%T|'j;#l<$K"Ci6 +a X s hύ $B@S=y jǃ,.`:߯&)?ĥZ{MDU3Qk^W"jS~Ą43rIM2H2~FH$/V Xʄ6Ҝ 5RgK$_ QcD5sfDsYN?)  d1X4Ϙ=G\W.Ӱ̚lĐ[S Ͷ U'_ tSP ?Y\2,F PnĂ=qyq\4tstćTE%ºn 4]@T${$y hʷĐQ(7QӒ[wŃ_.@X' 5gɉRiqࡥGxʅna7"_ 6RJSMlzfbg胂汛,ow`2z:Ϊu]kaH׍LSa=z?g.M̓#y;YmEe_mn|ǿ@_= Do$A*~6o}v)7XPπj a QƖiB%= M;ؔgR~5UK+blL ņzC%BX!Ce>lwOmeMH6^b Wd𪋌ktJ߽` &Sߥ`2ݟH@-K0XF)DFKJh^2.Dea;=ΣެE3KA|FRHv;ݻ8rbs_w)$IlwGdrqrb4dfT]+Z#}>~y{ˮ];bc$" |]mW{3'\wWvGQEoT}Bre\>YK /dWvC4%Kc[Io^˚"jƆzwi}VFaz͜&=n1)q`v@b51= = Zcn7Ci7NF>xWbE (ҟɋsc:7u^BUMIf6B!VډQ8%"]ޣ!/Gw!qarDJFH9(H-VK1AƢ翡Mt:Đ*ݍъ :PoPyzAncyG$  ´õD ң(PoN*PY/OͼI-[,W2 Cf iiv뒁Uۗ|U|iCr*|R'k0L^P)[=@h-_7:W 6@حbi? 0p/SmӺm9g_i,F /|,_w8(׀h=9JmMNU.K*_gKm@U9[ʜ}:omYCȧ,p@:Ō"p}.Ւ=euV[b%6W{KVR?cExK~hpֵE2TƘHFk6W?꿟o:> ٳO~Vh3S[7Y@>eɌ7aJBd!w)/y:7lfEGҮ3!934`wZ{}j^.2ɏR @[K$OC/w[nG8/>k|+1T~5aMLboC% cS5kO!o :reT۔wvvfw(HyǍDK%MUĿRf{7:cCl"Ud#a5-N{p?i̓MVpc|1ӂzsZd LR%Q{9Y[,{e9P5U g_v Xp{2.b#|y"P/|lv?o `s%_PK* PKmB'Configurations2/accelerator/current.xmlPKPKmBConfigurations2/progressbar/PKmBConfigurations2/floater/PKmBConfigurations2/popupmenu/PKmBConfigurations2/toolpanel/PKmBConfigurations2/menubar/PKmBConfigurations2/toolbar/PKmBConfigurations2/images/Bitmaps/PKmBConfigurations2/statusbar/PKmB settings.xmlZmS8a {ahA B!&$ߤ˅Y>󜷞srW@%9;ġ."˜musOOȁ5:s(\Ovkۗ5Ԩf[m{u-"[]yň,.ss!ZiX>lVЪj!Y3%n٦u(yBcQVSJ߅VVEųj!|,ZwK[ca=WR},{]BoaqVy$bd}Yxq=:~nsS,}y%S|RjyzYV*h6;;?? _x_E{d1ðH+._c~J)Os(ٵWwIoQŒ!`"`AJn 3>CGt5ɀg(U8׀r`aAYp@2!/]e%R,&fB)R G_&e 4u\P} Y8O}(}ZnD}+nS&ύ LhU_ Q(I:n:Of[4>lb,,*.:Xh4!cbB>lDx wi`SHWQJO>>{. \<4mǑArq oR8<(VLV ~Xt,u*h GB?2 (ː Zxw8=F_p4^' w)"0I'!]gA7?7䈆PKwF%PKmBMETA-INF/manifest.xmln }{5I{\H`}%f[knWk=5zrE+ ;\Űeڈvu ,ƚU2NPK PPKmB.++mimetypePKmB@ G Qcontent.xmlPKmB80  styles.xmlPKmB4hh!meta.xmlPKmB* Thumbnails/thumbnail.pngPKmB'%Configurations2/accelerator/current.xmlPKmB&Configurations2/progressbar/PKmBH&Configurations2/floater/PKmB~&Configurations2/popupmenu/PKmB&Configurations2/toolpanel/PKmB&Configurations2/menubar/PKmB$'Configurations2/toolbar/PKmBZ'Configurations2/images/Bitmaps/PKmB'Configurations2/statusbar/PKmBwF% 'settings.xmlPKmB PO.META-INF/manifest.xmlPK6/vokoscreen-1.9.0/future/future000066400000000000000000000007131227001500100164330ustar00rootroot00000000000000Liberate from extern Program ffmpeg Library: libavutil51 --> openSUSE libavutil-devel - Development files for libavutil Example: /usr/share/ffmpeg/examples/decoding_encoding.c in package libffmpeg-devel Video Audio sychron /usr/bin/ffmpeg -xerror -loglevel info -f x11grab -framerate 200 -video_size 1680x1050 -i :0.0+0,0 -dcodec copy -f alsa -ac 1 -i hw:1,0 -acodec libmp3lame -c:v libx264 -preset veryfast -c:a libmp3lame -y /tmp/qx11grab-202059.mkv vokoscreen-1.9.0/future/mysettings000066400000000000000000000001441227001500100173250ustar00rootroot00000000000000The best Recording for internal Audio under Pulse -- Monitor of internes Audio Analog Surround 5.1 vokoscreen-1.9.0/language/000077500000000000000000000000001227001500100154465ustar00rootroot00000000000000vokoscreen-1.9.0/language/TESTING000066400000000000000000000003461227001500100165110ustar00rootroot00000000000000 Testing language in vokoscreen Step 1: switch to language vk@cvolker:~> export LANG=en_GB.UTF-8 Step 2: check if language is set vk@cvolker:~> locale Step 3: start vokoscreen vk@cvolker:~> vokoscreen Step 4: check all words vokoscreen-1.9.0/language/vokoscreen_ar.ts000066400000000000000000000164051227001500100206640ustar00rootroot00000000000000 QvkMail Mail last Video أرسل آخر فيديو Mail one or more selected Video أرسل ملفات فيديو محددة Send أرسل You find the Video as attachment سوف تجد الفيديو على شكل رابط Select one or more files اختر ملفاً أو أكثر QvkWebcam Noborder بدون حاشية Border حاشية Close أغلق QvkWebcamController Webcam كاميرا الوب Device is busy الجهاز مشغول حاليا Select webcam اِختر كاميرا screencast Fullscreen شاشة كاملة Window نافذة Area منطقة Magnification المكبّرة Audio الصوت Alsa Alsa Pulse Pulse Default افتراضي Codec الكوديك Do not record mouse cursor لا تسجل مؤشر الفأرة Videopath مسار الفيديو Player المشغّل Vokoscreen minimized when recording starts تصغير البرنامج عند بدء التسجيل Start اِبدأ Stop أوقِف Pause ألبِث Play شغّل Send أرسل Recording time مدة التسجيل Size in KB الحجم بالكيلوبايت Recording screensize أبعاد نافذة التسجيل Format الصيغة Settings fps إعدادات fps Open Directory افتح الدليل %1 %1 Countdown عدّ تنازلي Play last Video شغّل آخر ملف فيديو Send Video أرسل الفيديو Select one or more devices اِختر جهازاً أو أكثر Actual frames per second عدد المشاهد \ ثا الحالية Device %1 is busy الجهاز %1 مشغول حالياً Your Actual frames in the Settings is too heigh عدد المشاهد الحالية في الإعدادات كبير جداً Go واصِل Homepage صفحة البرنامج Mailinglist القائمة البريدية Support الدعم Developer المطور Frames المشاهد Beta openSUSE نسخة تجريبية openSUSE Beta Ubuntu نسخة تجريبية Ubuntu Donate تبرع Program for recording برنامج التسجيل Translations الترجمات Sourcecode الملف المصدري Show in systray أظهِر البرنامج في مساحة التبليغ New version available vokoscreen-1.9.0/language/vokoscreen_ast.ts000066400000000000000000000156141227001500100210520ustar00rootroot00000000000000 QvkMail Mail last Video Dunviar per corréu'l vidéu caberu Mail one or more selected Video Dunviar per corréu ún o más videos esbillaos Send Dunviar You find the Video as attachment Pues alcontrar el vidéu como axuntu Select one or more files Esbilla unu o más ficheros QvkWebcam Noborder Ensin bordes Border Borde Close Zarrar QvkWebcamController Webcam Cámara web Device is busy El preséu ta ocupáu Select webcam Esbillar cámara web screencast Fullscreen Pantalla completa Window Ventanu Area Fastera Magnification Lente Audio Audiu Alsa ALSA Pulse Pulse Default Per defeutu Codec Codec Do not record mouse cursor Nun grabar el mur Videopath Ruta'l vidéu Player Reproductor Vokoscreen minimized when recording starts Vokoscreen minimizáu cuando la grabación entame Start Entamar Stop Aparar Pause Posar Play Reproducir Send Dunviar Recording time Tiempu de grabación Size in KB Grandor en KB Recording screensize Grandor de pantalla al grabar Format Formatu Settings fps Axustar FPS Open Directory Abrir carpeta %1 %1 Countdown Cuenta atrás Play last Video Reproducir el vidéu caberu Send Video Dunviar vidéu Select one or more devices Esbilla un o más preseos Actual frames per second Cuadros per segundu d'anguaño Device %1 is busy El preséu %1 ta ocupáu Your Actual frames in the Settings is too heigh Los tos frames d'anguaño nos axustes son abondo altos Go DIr Homepage Páxina d'aniciu Mailinglist Lllista de corréu Support Sofitu Developer Desendolcador Frames Frames Beta openSUSE Beta openSUSE Beta Ubuntu Beta Ubuntu Donate Donar Program for recording Programa pa grabar Translations Tornes Sourcecode Códigu fonte Show in systray Amosar na bandexa'l sistema New version available vokoscreen-1.9.0/language/vokoscreen_ca.ts000066400000000000000000000155211227001500100206430ustar00rootroot00000000000000 QvkMail Mail last Video Envia l’últim vídeo per correu Mail one or more selected Video Envia un o més vídeos seleccionats Send Envia You find the Video as attachment Podeu trobar el vídeo com un fitxer adjunt Select one or more files Seleccioneu un o més fitxers QvkWebcam Noborder Sense vora Border Vora Close Tanca QvkWebcamController Webcam Càmera web Device is busy El dispositiu està ocupat Select webcam Seleccioneu la càmera web screencast Fullscreen Pantalla completa Window Finestra Area Àrea Magnification Ampliació Audio Àudio Alsa ALSA Pulse Pulse Default Per defecte Codec Còdec Do not record mouse cursor No enregistris el cursor del ratolí Videopath Camí del vídeo Player Reproductor Vokoscreen minimized when recording starts Minimitza el Vokoscreen en iniciar l’enregistrament Start Inicia Stop Atura Pause Pausa Play Reprodueix Send Envia Recording time Temps d’enregistrament Size in KB Mida en kB Recording screensize Format Format Settings fps Open Directory Obre la carpeta %1 %1 Countdown Compte regressiu Play last Video Reprodueix l’últim vídeo Send Video Envia el vídeo Select one or more devices Seleccioneu un o més dispositius Actual frames per second Device %1 is busy El dispositiu %1 està ocupat Your Actual frames in the Settings is too heigh Go Vés-hi Homepage Lloc web Mailinglist Llista de correu Support Assistència Developer Desenvolupador Frames Fotogramas Beta openSUSE Beta per a i’OpenSUSE Beta Ubuntu Beta per a l’Ubuntu Donate Feu una donació Program for recording Programa per a l’enregistrament Translations Traduccions Sourcecode Show in systray New version available vokoscreen-1.9.0/language/vokoscreen_cs_CZ.ts000066400000000000000000000153421227001500100212620ustar00rootroot00000000000000 QvkMail Mail last Video Odeslat poslední videosekvenci Mail one or more selected Video Poslat jednu nebo více vybraných videosekvencí Send Odeslat You find the Video as attachment V příloze se nachází videosekvence Select one or more files Vybrat jeden nebo více souborů QvkWebcam Noborder Bez ohraničení Border Ohraničení Close Zavřít QvkWebcamController Webcam Webkamera Device is busy Zařízení je zaneprázdněné Select webcam screencast Fullscreen Celá obrazovka Window Okno Area Výřez Magnification Zvětšení Audio Zvuk Alsa Alsa Pulse Pulse Default Výchozí Codec Kodek Do not record mouse cursor Nenahrávat kurzor myši Videopath Cesta k videosekvenci Player Přehrávač Vokoscreen minimized when recording starts Minimalizovat Vokoscreen po spuštění nahrávání Start Start Stop Stop Pause Pauza Play Přehrát Send Odeslat Recording time Doba nahrávání Size in KB Velikost v kB Recording screensize Velikost nahrávky Format Formát Settings fps Nastavení fps Open Directory Otevřít adresář %1 %1 Countdown Odpočítávání Play last Video Přehrát poslední videosekvenci Send Video Poslat videosekvenci Select one or more devices Actual frames per second Device %1 is busy Zařízení %1 je zaneprázdněn Your Actual frames in the Settings is too heigh Go Start Homepage Mailinglist Support Developer Frames Beta openSUSE Beta Ubuntu Donate Program for recording Translations Sourcecode Show in systray New version available vokoscreen-1.9.0/language/vokoscreen_da_DK.ts000066400000000000000000000152011227001500100212150ustar00rootroot00000000000000 QvkMail Mail last Video Mail seneste video Mail one or more selected Video Mail en eller flere af de valgte videoer Send Send You find the Video as attachment Du finder videoen som en vedhæftet fil. Select one or more files Vælg en eller flere filer QvkWebcam Noborder Ingen ramme Border Ramme Close Luk QvkWebcamController Webcam Webcam Device is busy Enheden er optaget Select webcam screencast Fullscreen Hele skærmen Window Vindue Area Område Magnification Lup Audio Lyd Alsa Alsa Pulse Pulse Default Standard Codec Codec Do not record mouse cursor Optag ikke musemarkør Videopath Videosti Player Afspiller Vokoscreen minimized when recording starts Vokoscreen bliver minimeret når optagelsen starter Start Start Stop Stop Pause Pause Play Afspil Send Send Recording time Optagetid Size in KB Størrelse i KB Recording screensize Optager skærmstørrelse Format Format Settings fps Indstillinger fps Open Directory Åben mappe %1 %1 Countdown Nedtælling Play last Video Afspil seneste video Send Video Send video Select one or more devices Vælg en eller flere enheder Actual frames per second Aktuelle billeder pr. sekund Device %1 is busy Device % 1 er optaget Your Actual frames in the Settings is too heigh Go Start Homepage Mailinglist Support Developer Frames Beta openSUSE Beta Ubuntu Donate Program for recording Translations Sourcecode Show in systray New version available vokoscreen-1.9.0/language/vokoscreen_de_AT.ts000066400000000000000000000153751227001500100212430ustar00rootroot00000000000000 QvkMail Mail last Video Letztes Video per mail senden Mail one or more selected Video Ein oder mehrere Videos versenden Send Senden You find the Video as attachment Video im Anhang Select one or more files Eine oder mehrere Dateien auswählen QvkWebcam Noborder Ohne Rahmen Border Rahmen Close Schliessen QvkWebcamController Webcam Webcam Device is busy Gerät ist belegt Select webcam Webcam auswählen screencast Fullscreen Vollbild Window Fenster Area Bereich Magnification Lupe Audio Audio Alsa Alsa Pulse Pulse Default Standard Codec Codec Do not record mouse cursor Mauscursor nicht aufnehmen Videopath Videopfad Player Player Vokoscreen minimized when recording starts vokoscreen minimieren wenn Aufnahme startet Start Start Stop Stop Pause Pause Play Play Send Senden Recording time Aufnahmezeit Size in KB Grösse in KB Recording screensize Aktueller Bildschirmbereich Format Format Settings fps fps Einstellungen Open Directory Öffne Verzeichnis %1 %1 Countdown Countdown Play last Video Letztes Video abspielen Send Video Video senden Select one or more devices Ein oder mehrere Geräte auswählen Actual frames per second Aktuelle fps Device %1 is busy Gerät %1 ist belegt Your Actual frames in the Settings is too heigh Die aktuelle Framerate in den Einstellungen ist zu hoch Go Weiter Homepage Webseite Mailinglist Mailliste Support Support Developer Entwickler Frames Frames Beta openSUSE Beta OpenSuse Beta Ubuntu Beta Ubuntu Donate Spende Program for recording Aufnahme über Translations Übersetzungen Sourcecode Quellcode Show in systray Im Systray anzeigen New version available vokoscreen-1.9.0/language/vokoscreen_de_CH.ts000066400000000000000000000154031227001500100212210ustar00rootroot00000000000000 QvkMail Mail last Video Letztes Video per mail versenden Mail one or more selected Video Ein oder mehrere Videos per mail senden Send Senden You find the Video as attachment Video im Anhang Select one or more files Eine oder mehrere Dateien senden QvkWebcam Noborder Ohne Rahmen Border Rahmen Close Schliessen QvkWebcamController Webcam Webcam Device is busy Gerät ist belegt Select webcam Webcam auswählen screencast Fullscreen Vollbild Window Fenster Area Bereich Magnification Lupe Audio Audio Alsa Alsa Pulse Pulse Default Standard Codec Codec Do not record mouse cursor Mauszeiger nicht aufnehmen Videopath Videopfad Player Player Vokoscreen minimized when recording starts vokoscreen minimieren wenn Aufnahme startet Start Start Stop Stop Pause Pause Play Play Send Senden Recording time Aufnahmezeit Size in KB Grösse in KB Recording screensize Aktueller Bildschirmbereich Format Format Settings fps fps Einstellungen Open Directory Öffne Verzeichnis %1 %1 Countdown Countdown Play last Video Letztes Video abspielen Send Video Video versenden Select one or more devices Ein oder mehrere Geräte auswählen Actual frames per second Aktuelle fps Device %1 is busy Gerät %1 ist belegt Your Actual frames in the Settings is too heigh Die aktuelle Framerate in den Einstellungen ist zu hoch Go Weiter Homepage Webseite Mailinglist Mailliste Support Support Developer Entwickler Frames Frames Beta openSUSE Beta OpenSuse Beta Ubuntu Beta Ubuntu Donate Spende Program for recording Aufnahme mit Translations Übersetzungen Sourcecode Quellcode Show in systray Im Systray anzeigen New version available vokoscreen-1.9.0/language/vokoscreen_de_DE.ts000066400000000000000000000154071227001500100212230ustar00rootroot00000000000000 QvkMail Mail last Video Sende letzte Aufnahme Mail one or more selected Video Ein oder mehrere Videos versenden Send Senden You find the Video as attachment Video im Anhang Select one or more files Eine oder mehrere Dateien auswählen QvkWebcam Noborder Ohne Fensterrahmen Border Rahmen Close Schliessen QvkWebcamController Webcam Webcam Device is busy Gerät ist belegt Select webcam Webcam auswählen screencast Fullscreen Vollbild Window Fenster Area Bereich Magnification Lupe Audio Audio Alsa Alsa Pulse Pulse Default Standard Codec Codec Do not record mouse cursor Mauszeiger nicht aufnehmen Videopath Videopfad Player Player Vokoscreen minimized when recording starts Vokoscreen bei Aufnahme minimieren Start Start Stop Stop Pause Pause Play Play Send Senden Recording time Aufnahmezeit Size in KB Grösse in KB Recording screensize Aktueller Bildschirmbereich Format Format Settings fps Framerate aus den Einstellungen Open Directory Verzeichnis öffnen %1 %1 Countdown Countdown Play last Video Letzte Aufnahme abspielen Send Video Sende Video Select one or more devices Ein oder mehrere Geräte auswählen Actual frames per second Aktuelle Framerate Device %1 is busy Gerät %1 ist belegt Your Actual frames in the Settings is too heigh Die aktuelle Framerate in den Einstellungen ist zu hoch Go Weiter Homepage Webseite Mailinglist Mailliste Support Support Developer Entwickler Frames Frames Beta openSUSE Beta OpenSuse Beta Ubuntu Beta Ubuntu Donate Spende Program for recording Aufnahme mit Translations Übersetzungen Sourcecode Quellcode Show in systray Im Systray anzeigen New version available vokoscreen-1.9.0/language/vokoscreen_es.ts000066400000000000000000000154501227001500100206700ustar00rootroot00000000000000 QvkMail Mail last Video Enviar último video por correo Mail one or more selected Video Enviar uno o más vídeos seleccionados Send Enviar You find the Video as attachment Encontrará el vídeo como un archivo adjunto Select one or more files Seleccione uno o más archivos QvkWebcam Noborder Sin borde Border Borde Close Cerrar QvkWebcamController Webcam Cámara web Device is busy El dispositivo está ocupado Select webcam Seleccione la cámara web screencast Fullscreen Pantalla completa Window Ventana Area Área Magnification Ampliación Audio Sonido Alsa ALSA Pulse Pulse Default Predeterminado Codec Códec Do not record mouse cursor No grabar el puntero del ratón Videopath Ruta del vídeo Player Reproductor Vokoscreen minimized when recording starts Minimizar Vokoscreen al iniciar la grabación Start Iniciar Stop Detener Pause Pausar Play Reproducir Send Enviar Recording time Tiempo de grabación Size in KB Tamaño en kB Recording screensize Format Formato Settings fps Open Directory Abrir carpeta %1 %1 Countdown Cuenta regresiva Play last Video Reproducir último vídeo Send Video Enviar vídeo Select one or more devices Seleccione uno o más dispositivos Actual frames per second Device %1 is busy El dispositivo «%1» está ocupado Your Actual frames in the Settings is too heigh Go Ir Homepage Sitio web Mailinglist Lista de correo Support Asistencia Developer Desarrollador Frames Fotogramas Beta openSUSE Beta para openSUSE Beta Ubuntu Beta para Ubuntu Donate Donar Program for recording Programa para grabar Translations Traducciones Sourcecode Show in systray New version available vokoscreen-1.9.0/language/vokoscreen_es_ES.ts000066400000000000000000000154561227001500100212650ustar00rootroot00000000000000 QvkMail Mail last Video Envia por email el último vídeo Mail one or more selected Video Enviar a uno o más vídeos seleccionados Send Enviar You find the Video as attachment Puedes encontrar el vídeo como archivo adjunto Select one or more files Seleccione uno o más archivos QvkWebcam Noborder Sin borde Border Borde Close Cerrar QvkWebcamController Webcam Webcam Device is busy El dispositivo está ocupado Select webcam screencast Fullscreen pantalla Window ventana Area área Magnification Lupa Audio Audio Alsa Alsa Pulse Pulse Default Predeterminado Codec Codec Do not record mouse cursor No grabar el cursor del ratón Videopath Ubicación del vídeo Player Reproductor Vokoscreen minimized when recording starts Minimizar Vokoscreen al comenzar la grabación Start iniciar Stop detener Pause Pausa Play Reproducir Send Enviar Recording time Tiempo de grabación Size in KB Tamaño en KB Recording screensize Tamaño de la pantalla a grabar Format Formato Settings fps Ajustes fps Open Directory Abrir directorio %1 %1 Countdown Cuenta regresiva Play last Video Reproducir último vídeo Send Video Enviar vídeo Select one or more devices Seleccione uno o más dispositivos Actual frames per second Fotogramas por segundo actuales Device %1 is busy El dispositivo %1 está ocupado Your Actual frames in the Settings is too heigh Tu configuración de fotogramas actual es demasiado alta Go iniciar Homepage Mailinglist Support Developer Frames Beta openSUSE Beta Ubuntu Donate Program for recording Translations Sourcecode Show in systray New version available vokoscreen-1.9.0/language/vokoscreen_fr_FR.ts000066400000000000000000000160271227001500100212600ustar00rootroot00000000000000 QvkMail Mail last Video Envoyer la dernière vidéo Mail one or more selected Video Envoyer une ou plusieurs vidéos sélectionnées Send Envoyer You find the Video as attachment Vous trouverez la vidéo en pièce jointe Select one or more files Sélectionnez un ou plusieurs fichiers QvkWebcam Noborder Pas de bordure Border Bordure Close Fermer QvkWebcamController Webcam Webcam Device is busy Le périphérique est en cours d'utilisation Select webcam Sélectionner la webcam screencast Fullscreen Plein écran Window Fenêtre Area Zone Magnification Agrandissement Audio Audio Alsa Alsa Pulse Pulse Default Par défaut Codec Codec Do not record mouse cursor Ne pas enregistrer le curseur de la souris Videopath Chemin de la vidéo Player Lecteur Vokoscreen minimized when recording starts Minimiser Vokoscreen quand l'enregistrement commence Start Démarrer Stop Arrêter Pause Pause Play Lire Send Envoyer Recording time Temps d'enregistrement Size in KB Taille en KB Recording screensize Taille d'écran de l'enregistrement Format Format Settings fps Réglage des FPS Open Directory Ouvrir le répertoire %1 % 1 Countdown Compte à rebours Play last Video Jouer la dernière vidéo Send Video Envoyer la vidéo Select one or more devices Sélectionnez un ou plusieurs fichiers Actual frames per second Images par secondes actuelles Device %1 is busy Le périphérique %1 est occupé Your Actual frames in the Settings is too heigh Votre nombre d'images par seconde dans les paramètres est trop élevé Go Démarrer Homepage Page d'accueil Mailinglist Liste de diffusion Support Support Developer Développeur Frames Images Beta openSUSE Bêta openSUSE Beta Ubuntu Bêta Ubuntu Donate Faire un don Program for recording Programme pour l'enregistrement Translations Traductions Sourcecode Show in systray New version available vokoscreen-1.9.0/language/vokoscreen_hu.ts000066400000000000000000000155721227001500100207020ustar00rootroot00000000000000 QvkMail Mail last Video Utolsó videó levélként Mail one or more selected Video Egy vagy több kiválasztott videó levélként Send Küldés You find the Video as attachment A videó csatolva Select one or more files Válasszon ki egy vagy több fájlt QvkWebcam Noborder Keret nélkül Border Kerettel Close Bezár QvkWebcamController Webcam Webkamera Device is busy Az eszköz foglalt Select webcam Válasszon webkamerát screencast Fullscreen Teljes képernyő Window Ablak Area Terület Magnification Nagyítás Audio Hangrendszer Alsa Alsa Pulse Pulse Default Alapértelmezett Codec Kodek Do not record mouse cursor Egérmutató elrejtése Videopath Videó mentés helye Player Lejátszó Vokoscreen minimized when recording starts Vokoscreen minimalizálása a felvétel megkezdésekor Start Start Stop Stop Pause Szünet Play Lejátszás Send Küldés Recording time Felvétel ideje Size in KB Méret KB-ban Recording screensize Felvétel képernyőmérete Format Formátum Settings fps Fps beállítás Open Directory Könyvtár megnyitása %1 %1 Countdown Visszaszámlálás Play last Video Utolsó videó lejátszása Send Video Videó küldése Select one or more devices Válasszon ki egy vagy több eszközt Actual frames per second Képkockák száma másodpercenként Device %1 is busy %1 eszköz foglalt Your Actual frames in the Settings is too heigh A beállított képkockaszám túl magas Go Indít Homepage Weboldal Mailinglist Levelezőlista Support Támogatás Developer Fejlesztés Frames Képkocka Beta openSUSE Beta openSUSE Beta Ubuntu Beta Ubuntu Donate Adományozás Program for recording Képrögzítő program Translations Fordítás Sourcecode Show in systray New version available vokoscreen-1.9.0/language/vokoscreen_it_CH.ts000066400000000000000000000144231227001500100212460ustar00rootroot00000000000000 QvkMail Mail last Video Mail one or more selected Video Send You find the Video as attachment Select one or more files QvkWebcam Noborder Border Close QvkWebcamController Webcam Device is busy screencast Compress: Comprimere: Mouse cursor not recording Non registrare il cursore del mouse Videopath Percorso Video Fullscreen Schermo intero Window Finestra Area Area Start Avvia Stop Ferma Play Riproduci Open Directory Apri cartella Magnification Lente d'ingrandimento Vokoscreen minimized when recording starts Minimizza Vokoscreen quando inizia la registrazione player Riproduttore frames fotogrammi codec codec standard standard webcam settings Impostazioni webcam Countdown Audio Alsa Pulse Frames: Default Codec Do not record mouse cursor Player Pause Play last Video Send Send Video Recording time Actual frames per second Size in KB Recording screensize Format Settings fps Your Actual frames in the Settings is too heigh Device %1 is busy Select one or more devices %1 vokoscreen-1.9.0/language/vokoscreen_it_IT.ts000066400000000000000000000157021227001500100212710ustar00rootroot00000000000000 QvkMail Mail last Video Spedisci via mail l'ultimo video Mail one or more selected Video Spedisci via mail uno o più video selezionati Send Invia You find the Video as attachment Troverete il video come allegato Select one or more files Selezionare uno o più file QvkWebcam Noborder Senza bordi Border Bordi Close Chiudi QvkWebcamController Webcam Webcam Device is busy La periferica è occupata Select webcam Seleziona webcam screencast Fullscreen schermo intero Window finestre Area area Magnification Lente di ingrandimento Audio Audio Alsa Alsa Pulse Pulse Default Predefinito Codec Codec Do not record mouse cursor Non registrare il cursore del mouse Videopath Ubicazione del video Player Riproduttore Vokoscreen minimized when recording starts Minimizza Vokoscreen quando inizia la registrazione Start inizio Stop Stop Pause Pausa Play Riproduci Send Invia Recording time Durata della registrazione Size in KB Dimensioni in KB Recording screensize Dimensioni dello schermo da registrare Format Formato Settings fps Impostazioni fps Open Directory Apri cartella %1 %1 Countdown Conto alla rovescia Play last Video Riproduci ultimo video Send Video Invia video Select one or more devices Selezionare una o più periferiche Actual frames per second Fotogrammi al secondo attuale Device %1 is busy Dispositivo %1 è occupato Your Actual frames in the Settings is too heigh La attuale impostazione dei fotogrammi è troppo alta Go inizio Homepage Pagina iniziale Mailinglist Mailinglist Support Assistenza Developer Sviluppatore Frames Fotogrammi Beta openSUSE Beta openSUSE Beta Ubuntu Beta Ubuntu Donate Donate Program for recording Programma per registrare Translations Traduzioni Sourcecode Codice sorgente Show in systray Mostra nella systray New version available Nuova versione disponibile vokoscreen-1.9.0/language/vokoscreen_nl_NL.ts000066400000000000000000000151361227001500100212640ustar00rootroot00000000000000 QvkMail Mail last Video Mail laatste Video Mail one or more selected Video Mail een of meer geselecteerde video 's Send Zenden You find the Video as attachment U vindt de video als bijlage Select one or more files Selecteer een of meer bestanden QvkWebcam Noborder Geen rand Border Rand Close Sluiten QvkWebcamController Webcam Webcam Device is busy Apparaat is bezig Select webcam screencast Fullscreen Volledig scherm Window Venster Area Gebied Magnification Vergroting Audio Audio Alsa Alsa Pulse Pulse Default Standaard Codec Codec Do not record mouse cursor Muiscursor niet opnemen Videopath Video map Player Speler Vokoscreen minimized when recording starts Vokoscreen in taakbalk als opname start Start Start Stop Stoppen Pause Pauzeren Play Afspelen Send Verzenden Recording time Opnametijd Size in KB Grootte in KB Recording screensize Grootte van scherm opname Format Formaat Settings fps Instellingen fps Open Directory Open direktory %1 %1 Countdown Countdown Play last Video Speel laatste Video Send Video Stuur Video Select one or more devices Actual frames per second Device %1 is busy Apparaat %1 is bezig Your Actual frames in the Settings is too heigh Go Start Homepage Mailinglist Support Developer Frames Beta openSUSE Beta Ubuntu Donate Program for recording Translations Sourcecode Show in systray New version available vokoscreen-1.9.0/language/vokoscreen_pl_PL.ts000066400000000000000000000155461227001500100212750ustar00rootroot00000000000000 QvkMail Mail last Video Wyślij ostatnie nagranie Mail one or more selected Video Wyślij jedno lub kilka nagrań Send Wyślij You find the Video as attachment Nagranie wideo znajduje się w załączniku Select one or more files Wybierz jeden lub wiele plików QvkWebcam Noborder Bez ramki Border Ramka Close Zamknij QvkWebcamController Webcam Kamera Device is busy Urządzenie zajęte Select webcam Wybierz kamerę screencast Fullscreen Pełny ekran Window Okno Area Obszar Magnification Powiększenie Audio Dźwięk Alsa Alsa Pulse Pulse Default Domyślne Codec Kodek Do not record mouse cursor Nie nagrywaj kursora myszy Videopath Ścieżka wideo Player Odtwarzacz Vokoscreen minimized when recording starts Zminimalizuj vokoscreen podczas nagrywania Start Start Stop Stop Pause Pauza Play Odtwórz Send Wyślij Recording time Czas nagrywania Size in KB Rozmiar w KB Recording screensize Rozmiar nagrywanego obrazu Format Format Settings fps Ustawiona liczba klatek Open Directory Wybierz katalog %1 %1 Countdown Odliczanie Play last Video Odtwórz ostatnie nagranie Send Video Wyślij nagranie Select one or more devices Wybierz jedno lub wiele urządzeń Actual frames per second Aktualna liczba klatek na sekundę Device %1 is busy Urządzenie %1 jest zajęte Your Actual frames in the Settings is too heigh Liczba klatek zapisana w ustawieniach jest większa od aktualnej liczby klatek Go Wznów Homepage Strona domowa Mailinglist Lista mailingowa Support Wsparcie Developer Programista Frames Klatki Beta openSUSE Beta openSUSE Beta Ubuntu Beta Ubuntu Donate Darowizna Program for recording Program nagrywający Translations Tłumaczenia Sourcecode Show in systray New version available vokoscreen-1.9.0/language/vokoscreen_pt_BR.ts000066400000000000000000000155031227001500100212660ustar00rootroot00000000000000 QvkMail Mail last Video Enviar último vídeo Mail one or more selected Video Enviar um ou mais Vídeos selecionados Send Enviar You find the Video as attachment Você encontra o Vídeo como anexo Select one or more files Selecione um ou mais arquivos QvkWebcam Noborder Sem borda Border Borda Close Fechar QvkWebcamController Webcam Webcam Device is busy Dispositivo está ocupado Select webcam Selecione webcam screencast Fullscreen Tela cheia Window Janela Area Área Magnification Zoom Audio Audio Alsa Alsa Pulse Pulse Default Padrão Codec Codec Do not record mouse cursor Não gravar o cursor do mouse Videopath Caminho do vídeo Player Player Vokoscreen minimized when recording starts Vokoscreen minimizado quando iniciar gravação Start Iniciar Stop Parar Pause pausa Play Reproduzir Send Enviar Recording time Tempo de Gravação Size in KB Tamanho em KB Recording screensize Tamanho da tela de Gravação Format Formato Settings fps Configurações de FPS Open Directory Abrir diretório %1 %1 Countdown Contagem Regressiva Play last Video Reproduzir último Vídeo Send Video Enviar Vídeo Select one or more devices Selecione um mais dispositivos Actual frames per second Frames por segundo Device %1 is busy O dispositivo %1 está ocupado Your Actual frames in the Settings is too heigh Suas configurações de Frames por Segundo estão muito altas Go Ir Homepage Homepage Mailinglist Lista de Email Support Suporte Developer Desenvolvedor Frames Frames Beta openSUSE Beta openSUSE Beta Ubuntu Beta Ubuntu Donate Doações Program for recording Programa para gravação Translations Traduções Sourcecode Show in systray New version available vokoscreen-1.9.0/language/vokoscreen_ro.ts000066400000000000000000000156061227001500100207040ustar00rootroot00000000000000 QvkMail Mail last Video Trimite pe email ultimul video Mail one or more selected Video Email cu unul sau mai multe fișiere video selectate Send Trimite You find the Video as attachment Gasești fișierul video ca atașament Select one or more files Selectează unul sau mai multe fișiere QvkWebcam Noborder Fără margine Border Margine Close Închide QvkWebcamController Webcam Cameră Web Device is busy Dispozitivul este ocupat Select webcam Alege camera web screencast Fullscreen Pe tot ecranul Window Fereastră Area Arie Magnification Mărire Audio Audio Alsa Alsa Pulse Pulse Default Implicit Codec Codec Do not record mouse cursor Nu înregistra cursorul de maus Videopath Calea video Player Lector Vokoscreen minimized when recording starts Vokoscreen va fi minimizat cănd începe înregistrarea Start Începe Stop Oprește Pause Pauză Play Redă Send Trimite Recording time Durata înregistrării Size in KB Mărimea în KB Recording screensize Aria de ecran pentru înregistrare Format Format Settings fps Setări fps Open Directory Deschide dosar %1 %1 Countdown Numărătoare inversă Play last Video Redă ultimul video Send Video Trimite video Select one or more devices Selectează unul sau mai multe dispozitive Actual frames per second Cadre reale pe secundă Device %1 is busy Diszpozitivul %1 este ocupat Your Actual frames in the Settings is too heigh Valoarea pentru cadre în Setări este prea mare Go Start Homepage Pagină web Mailinglist Listă de discuții Support Suport Developer Dezvoltator Frames Cadre Beta openSUSE Beta openSUSE Beta Ubuntu Beta Ubuntu Donate Donează Program for recording Program pentru înregistrare Translations Traduceri Sourcecode Show in systray New version available vokoscreen-1.9.0/language/vokoscreen_ro_RO.ts000066400000000000000000000154711227001500100213040ustar00rootroot00000000000000 QvkMail Mail last Video Trimite pe email ultimul video Mail one or more selected Video Email cu unul sau mai multe fișiere video selectate Send Trimite You find the Video as attachment Gasești fișierul video ca atașament Select one or more files Selectează unul sau mai multe fișiere QvkWebcam Noborder Fără margine Border Margine Close Închide QvkWebcamController Webcam Cameră Web Device is busy Dispozitivul este ocupat Select webcam screencast Fullscreen Pe tot ecranul Window Fereastră Area Arie Magnification Mărire Audio Audio Alsa Alsa Pulse Pulse Default Implicit Codec Codec Do not record mouse cursor Nu înregistra cursorul de maus Videopath Calea video Player Lector Vokoscreen minimized when recording starts Vokoscreen va fi minimizat cănd începe înregistrarea Start Începe Stop Oprește Pause Pauză Play Redă Send Trimite Recording time Durata înregistrării Size in KB Mărimea în KB Recording screensize Aria de ecran pentru înregistrare Format Format Settings fps Setări fps Open Directory Deschide dosar %1 %1 Countdown Numărătoare inversă Play last Video Redă ultimul video Send Video Trimite video Select one or more devices Selectează unul sau mai multe dispozitive Actual frames per second Cadre reale pe secundă Device %1 is busy Diszpozitivul %1 este ocupat Your Actual frames in the Settings is too heigh Valoarea pentru cadre în Setări este prea mare Go Începe Homepage Mailinglist Support Developer Frames Beta openSUSE Beta Ubuntu Donate Program for recording Translations Sourcecode Show in systray New version available vokoscreen-1.9.0/language/vokoscreen_ru.ts000066400000000000000000000173041227001500100207070ustar00rootroot00000000000000 QvkMail Mail last Video Отправить последний видеофайл Mail one or more selected Video Отправить по эл.почте один или несколько видеофайлов Send Отправить You find the Video as attachment Видеофайл будет представлен во вложении Select one or more files Выберите один или несколько файлов QvkWebcam Noborder Без рамки Border Рамка Close Закрыть QvkWebcamController Webcam Веб-камера Device is busy Устройство в настоящее время используется Select webcam Выберите веб-камеру screencast Fullscreen Весь экран Window Окно Area Область экрана Magnification Лупа Audio Звук Alsa Alsa Pulse Pulse Default По умолчанию Codec Кодек Do not record mouse cursor Не записывать указатель мыши Videopath Сохранять в папке: Player Проигрыватель Vokoscreen minimized when recording starts Сворачивать Vokoscreen во время начала записи Start Начать Stop Остановить Pause Приостановить Play Воспроизвести Send Отправить Recording time Время записи Size in KB Размер в КБ Recording screensize Размер записываемого экрана Format Формат Settings fps Настройка частоты Open Directory Открыть папку %1 %1 Countdown Обратный отсчёт Play last Video Воспроизвести последний видеофайл Send Video Отправить видеофайл Select one or more devices Выберите одно или несколько устройств Actual frames per second Фактическое кол-во кадров в с. Device %1 is busy Устройство %1 используется Your Actual frames in the Settings is too heigh Кол-во фактических кадров в с. превышено Go Перейти Homepage Веб-сайт Mailinglist Рассылка Support Поддержка Developer Разработчик Frames Кадры Beta openSUSE Beta openSUSE Beta Ubuntu Beta Ubuntu Donate Пожертвовать Program for recording Программа для записи Translations Переводы Sourcecode Исходный код Show in systray Показать значок на верхней панели New version available vokoscreen-1.9.0/language/vokoscreen_sv_SE.ts000066400000000000000000000152311227001500100212750ustar00rootroot00000000000000 QvkMail Mail last Video Mejla sensaste video Mail one or more selected Video Mejla en eller flera valda video Send Skicka You find the Video as attachment Du hittar videon som bilaga Select one or more files Välj en eller flera filer QvkWebcam Noborder Ingen ram Border Ram Close Stäng QvkWebcamController Webcam Webcam Device is busy Enheten är upptagen Select webcam screencast Fullscreen Fullskärm Window Fönster Area Område Magnification Förstoringsglas Audio Ljud Alsa Alsa Pulse Pulse Default Standard Codec Codec Do not record mouse cursor Spela inte in muspekaren Videopath Videosökväg Player Spelare Vokoscreen minimized when recording starts Vokoscreen är förminskad när inspelningen startas Start Starta Stop Stopp Pause Pausa Play Spela Send Skicka Recording time Inspelningstid Size in KB Storlek in kb Recording screensize Inspelning skärmstorlek Format Format Settings fps Inställningar fps Open Directory Öppen katalog %1 %1 Countdown Nedräkning Play last Video Spela förra videon Send Video Skicka video Select one or more devices Mejla en eller flera valda video Actual frames per second Aktuella antal bilder per sekund Device %1 is busy Device %1 är upptagen Your Actual frames in the Settings is too heigh Go Starta Homepage Mailinglist Support Developer Frames Beta openSUSE Beta Ubuntu Donate Program for recording Translations Sourcecode Show in systray New version available vokoscreen-1.9.0/language/vokoscreen_tr_TR.ts000066400000000000000000000154021227001500100213100ustar00rootroot00000000000000 QvkMail Mail last Video Son videoyu postala Mail one or more selected Video Bir veya daha fazla seçili videoyu postala Send Gönder You find the Video as attachment Video gibi eklenti bul Select one or more files Bir veya daha fazla dosya seçin QvkWebcam Noborder Çerçevesiz Border Çerçeve Close Kapat QvkWebcamController Webcam Web kamerası Device is busy Aygıt meşgul Select webcam Web kamera seç screencast Fullscreen Tam Ekran Window Pencere Area Bölge Magnification Büyütme Audio Ses Alsa Alsa Pulse Pulse Default Varsayılan Codec Kodek Do not record mouse cursor Fare imlecini kaydetme Videopath Video yolu Player Oynatıcı Vokoscreen minimized when recording starts Kayıt başladığında Vokoscreen programını küçült Start Başlat Stop Durdur Pause Duraklat Play Oynat Send Gönder Recording time Kayıt süresi Size in KB KB olarak boyut Recording screensize Kayıt ekran boyutu Format Biçim Settings fps fps ayarı Open Directory Dizin Aç %1 %1 Countdown Geri sayım Play last Video Son videoyu oynat Send Video Video Gönder Select one or more devices Bir veya daha fazla aygıt seçin Actual frames per second Saniye başına fiili kare Device %1 is busy Aygıt %1 meşgul Your Actual frames in the Settings is too heigh Aktif pencelereler ayarlar için çok yüksek Go Git Homepage Ana Sayfa Mailinglist Eposta listesi Support Destek Developer Geliştirici Frames Çerçeveler Beta openSUSE Beta openSUSE Beta Ubuntu Beta Ubuntu Donate Yardım et Program for recording Kayıt programı Translations Çeviriler Sourcecode Show in systray New version available vokoscreen-1.9.0/language/vokoscreen_vi.ts000066400000000000000000000162601227001500100206770ustar00rootroot00000000000000 QvkMail Mail last Video Gửi mail video mới nhất Mail one or more selected Video Gửi mail đối với một hoặc các video được chọn Send Gửi You find the Video as attachment Bạn đã tìm thấy video dưới dạng đính kèm Select one or more files Chọn một hoặc nhiều tập tin QvkWebcam Noborder Không có đường viền Border Đường viền Close Đóng lại QvkWebcamController Webcam Webcam Device is busy Thiết bị hiện đang bận Select webcam Chọn webcam screencast Fullscreen Toàn màn hình Window Cửa sổ Area Khu vực Magnification Phóng to Audio Audio Alsa Alsa Pulse Nhịp Default Mặc định Codec Codec Do not record mouse cursor Không ghi hình phần hiển thị của chuột Videopath Đường dẫn video Player Trình phát Vokoscreen minimized when recording starts Vokoscreen sẽ được thu nhỏ khi phần ghi hình được tiến hành Start Bắt đầu Stop Dừng lại Pause Tạm dừng Play Phát Send Gửi Recording time Thời gian ghi hình Size in KB Kích thước tính bằng KB Recording screensize Kích cỡ màn hình khi ghi hình Format Định dạng Settings fps Thiết lập cho khung hình mỗi giây Open Directory Mở thư mục %1 %1 Countdown Đếm ngược Play last Video Phát video mới nhất Send Video Gửi Video Select one or more devices Chọn một hoặc nhiều thiết bị Actual frames per second Khung hình thực mỗi giây Device %1 is busy Thiết bị %1 hiện đang bận Your Actual frames in the Settings is too heigh Khung hình thực tế của bạn trong phần thiết lập quá cao Go Thực hiện Homepage Trang chủ Mailinglist Danh sách email Support Hỗ trợ Developer Nhà phát triển Frames Khung ảnh Beta openSUSE Bản thử nghiệm openSUSE Beta Ubuntu Bản thử nghiệm Ubuntu Donate Ủng hộ tài chính Program for recording Chương trình dùng để ghi hình Translations Chuyển ngữ Sourcecode Show in systray New version available vokoscreen-1.9.0/language/vokoscreen_zh_CN.ts000066400000000000000000000151651227001500100212650ustar00rootroot00000000000000 QvkMail Mail last Video 邮寄最后一个视频 Mail one or more selected Video 邮寄一个或多个选取的视频 Send 邮寄 You find the Video as attachment 您会看到视频作为附件 Select one or more files 选取一个或多个文件 QvkWebcam Noborder 没有窗口边框 Border 窗口边框 Close 关闭 QvkWebcamController Webcam 摄像头 Device is busy 装置忙碌中 Select webcam screencast Fullscreen 全屏模式 Window 窗口 Area 区域 Magnification 放大 Audio 音频 Alsa Alsa Pulse Pulse Default 默认值 Codec 编码器 Do not record mouse cursor 不要录制鼠标 Videopath 视频路径 Player 播放器 Vokoscreen minimized when recording starts 开始录制时最小化 Vokoscreen Start 开始 Stop 停止 Pause 暂停 Play 播放 Send 寄送 Recording time 录制时间 Size in KB 大小(KB) Recording screensize 录制屏幕大小 Format 格式 Settings fps 设定帧率 Open Directory 开启目录 %1 %1 Countdown 倒计时 Play last Video 播放最后一个视频 Send Video 寄送视频 Select one or more devices 选取一个或多个装置 Actual frames per second 实际的帧率 Device %1 is busy 装置 %1 忙碌中 Your Actual frames in the Settings is too heigh Go 开始 Homepage Mailinglist Support Developer Frames Beta openSUSE Beta Ubuntu Donate Program for recording Translations Sourcecode Show in systray New version available vokoscreen-1.9.0/language/vokoscreen_zh_TW.ts000066400000000000000000000152351227001500100213150ustar00rootroot00000000000000 QvkMail Mail last Video 傳送最後一個影片 Mail one or more selected Video 傳送一個或多個影片 Send 傳送 You find the Video as attachment 您會看到影片當作附加檔案 Select one or more files 選擇一個或多個檔案 QvkWebcam Noborder 沒有視窗邊框 Border 視窗邊框 Close 關閉 QvkWebcamController Webcam 網路攝影機 Device is busy 裝置忙碌中 Select webcam screencast Fullscreen 全螢幕 Window 視窗 Area 區域 Magnification 放大 Audio 音訊 Alsa Alsa Pulse Pulse Default 預設值 Codec 編碼器 Do not record mouse cursor 不要錄製滑鼠游標 Videopath 影片路徑 Player 播放器 Vokoscreen minimized when recording starts 開始錄製時最小化 Vokoscreen Start 開始 Stop 停止 Pause 暫停 Play 播放 Send 傳送 Recording time 錄製時間 Size in KB 大小(KB) Recording screensize 錄製螢幕大小 Format 格式 Settings fps 設定影格率 Open Directory 開啟目錄 %1 %1 Countdown 倒數計時 Play last Video 播放最後一個影片 Send Video 傳送影片 Select one or more devices 選取一個或多個裝置 Actual frames per second 實際的影格率 Device %1 is busy 裝置 %1 忙碌中 Your Actual frames in the Settings is too heigh 您設定的影格率太高了 Go 開始 Homepage Mailinglist Support Developer Frames Beta openSUSE Beta Ubuntu Donate Program for recording Translations Sourcecode Show in systray New version available vokoscreen-1.9.0/libqxt/000077500000000000000000000000001227001500100151665ustar00rootroot00000000000000vokoscreen-1.9.0/libqxt/LICENSE000066400000000000000000000114201227001500100161710ustar00rootroot00000000000000Qt Extension Library Copyright (C) 2007 Qxt Foundation ------------------- Disclaimer ------------------------------------------------ Until the Qxt Foundation is legally established, copyright for the source code falls back to the original contributor. For information about the status of the Qxt Foundation, or about the copyright status of any part of Qxt, contact the Qxt project maintainers at Once the Qxt Foundation has been legally established, all contributors must transfer all copyright interest to the Qxt Foundation before their submissions will be added to the project. ------------------- License --------------------------------------------------- This library is free software; you can redistribute it and/or modify it under the terms of the Common Public License, version 1.0, as published by IBM or under the terms of the GNU Lesser General Public License, version 2.1, as published by the Free Software Foundation This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. You should have received a copy of the CPL along with this file. See the LICENSE file and the cpl1.0.txt file included with the source distribution for more information. If you did not receive a copy of the license, contact the Qxt Foundation. You should have received a copy of the LGPL along with this file. See the LICENSE file and the lgpl-2.1.txt file included with the source distribution for more information. If you did not receive a copy of the license, contact the Qxt Foundation. Parts of Qxt depend on Qt 4 and/or other libraries that have their own licenses. Qxt is independent of these licenses; however, use of these other libraries is subject to their respective license agreements. ------------------- Intent ---------------------------------------------------- The following section describes the opinions and intent of the Qxt Foundation with regards to the licensing and use of the Qxt source code and library. In the event that the CPL is found to be illegal or invalid, or if any application or clause of the license is subjected to question or abuse, this section is a general statement of the desired interpretation. This section has no legal standing and the statements made here are strictly subject to the text of the CPL; that is, if this section and the CPL are in disagreement, the text of the CPL takes precedence. In no way does this intent grant you any additional rights or impose any additional restrictions. If you have questions about licensing, contact the maintainers. Qxt is built and supported by open-source enthusiasts. - Please respect the open-source background of the contributors. The code is provided for everyone's use; you may not restrict the rights of anyone to use it. - No individual may claim ownership of any part of the code. It belongs to the community. - You may modify the source code to suit your needs, but these changes must be made free. If you distribute a modified form of Qxt, you must also distribute the entire source code of the modified form. - Digital Rights Management (DRM) puts unfair, unfree restrictions on users and developers. It is the opposite of Free Software. We can't stop you from using it, but please don't use the Qxt name for software restricted by DRM. - Please respect the time and effort put into the project by the developers. - If you find Qxt useful, it would be appreciated if you would include text in your application (for instance, in the About dialog) giving acknowledgement to Qxt. - If you make modifications to the source code, you must not call the modified version "Qxt." It's okay to include "Qxt" in the name, but anyone who receives the modified version needs to know that it's not the same as the version distributed by the Qxt Foundation. - We want everyone to be able to use Qxt without restrictions. - If you distribute Qxt in compiled binary form, please ensure that everyone who receives it can get the source code used to create it. - You are free to use Qxt in closed-source applications as long as you distribute Qxt in an open-source fashion. This does not require you to make your entire application open-source. - The Qxt Foundation is a non-profit, non-political organization. - Please don't use the Qxt name in any political or semi-political propaganda or publication. We don't like it. - Qxt is distributed "as-is," with no warranty. - If it makes your program crash, your computer blow up, or tiny demons fly out of your nose, please don't sue us. vokoscreen-1.9.0/libqxt/QxtGlobalShortcut000066400000000000000000000000401227001500100205340ustar00rootroot00000000000000#include "qxtglobalshortcut.h" vokoscreen-1.9.0/libqxt/cpl1.0.txt000066400000000000000000000263661227001500100167410ustar00rootroot00000000000000 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, if Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. vokoscreen-1.9.0/libqxt/lgpl-2.1.txt000066400000000000000000000635041227001500100171730ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser 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 Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "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 LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY 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 LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! vokoscreen-1.9.0/libqxt/libqxt.pri000066400000000000000000000004441227001500100172070ustar00rootroot00000000000000 INCLUDEPATH += $$PWD DEPENDPATH += $$PWD HEADERS += $$PWD/qxtglobal.h $$PWD/qxtwindowsystem.h $$PWD/qxtglobalshortcut.h $$PWD/qxtglobalshortcut_p.h SOURCES += $$PWD/qxtglobal.cpp $$PWD/qxtwindowsystem_x11.cpp $$PWD/qxtglobalshortcut_x11.cpp $$PWD/qxtglobalshortcut.cpp LIBS += -lX11vokoscreen-1.9.0/libqxt/libqxt.pro000066400000000000000000000007311227001500100172140ustar00rootroot00000000000000###################################################################### # Automatically generated by qmake (2.01a) So. Sep 2 17:10:34 2012 ###################################################################### TEMPLATE = app TARGET = DEPENDPATH += . INCLUDEPATH += . # Input HEADERS += qxtglobal.h qxtwindowsystem.h qxtglobalshortcut.h qxtglobalshortcut_p.h SOURCES += qxtglobal.cpp qxtwindowsystem_x11.cpp qxtglobalshortcut_x11.cpp qxtglobalshortcut.cpp LIBS += -lX11 vokoscreen-1.9.0/libqxt/qxtglobal.cpp000066400000000000000000000206671227001500100177020ustar00rootroot00000000000000 /**************************************************************************** ** Copyright (c) 2006 - 2011, the LibQxt project. ** See the Qxt AUTHORS file for a list of authors and copyright holders. ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in the ** documentation and/or other materials provided with the distribution. ** * Neither the name of the LibQxt project nor the ** names of its contributors may be used to endorse or promote products ** derived from this software without specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ** DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY ** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** ** *****************************************************************************/ #include "qxtglobal.h" /*! \headerfile \title Global Qxt Declarations \inmodule QxtCore \brief The header provides basic declarations and is included by all other Qxt headers. */ /*! \macro QXT_VERSION \relates This macro expands a numeric value of the form 0xMMNNPP (MM = major, NN = minor, PP = patch) that specifies Qxt's version number. For example, if you compile your application against Qxt 0.4.0, the QXT_VERSION macro will expand to 0x000400. You can use QXT_VERSION to use the latest Qt features where available. For example: \code #if QXT_VERSION >= 0x000400 qxtTabWidget->setTabMovementMode(QxtTabWidget::InPlaceMovement); #endif \endcode \sa QXT_VERSION_STR, qxtVersion() */ /*! \macro QXT_VERSION_STR \relates This macro expands to a string that specifies Qxt's version number (for example, "0.4.0"). This is the version against which the application is compiled. \sa qxtVersion(), QXT_VERSION */ /*! \relates Returns the version number of Qxt at run-time as a string (for example, "0.4.0"). This may be a different version than the version the application was compiled against. \sa QXT_VERSION_STR */ const char * qxtVersion() { return QXT_VERSION_STR; } /*! \headerfile \title The Qxt private implementation \inmodule QxtCore \brief The header provides tools for hiding details of a class. Application code generally doesn't have to be concerned about hiding its implementation details, but when writing library code it is important to maintain a constant interface, both source and binary. Maintaining a constant source interface is easy enough, but keeping the binary interface constant means moving implementation details into a private class. The PIMPL, or d-pointer, idiom is a common method of implementing this separation. QxtPimpl offers a convenient way to connect the public and private sides of your class. \section1 Getting Started Before you declare the public class, you need to make a forward declaration of the private class. The private class must have the same name as the public class, followed by the word Private. For example, a class named MyTest would declare the private class with: \code class MyTestPrivate; \endcode \section1 The Public Class Generally, you shouldn't keep any data members in the public class without a good reason. Functions that are part of the public interface should be declared in the public class, and functions that need to be available to subclasses (for calling or overriding) should be in the protected section of the public class. To connect the private class to the public class, include the QXT_DECLARE_PRIVATE macro in the private section of the public class. In the example above, the private class is connected as follows: \code private: QXT_DECLARE_PRIVATE(MyTest) \endcode Additionally, you must include the QXT_INIT_PRIVATE macro in the public class's constructor. Continuing with the MyTest example, your constructor might look like this: \code MyTest::MyTest() { // initialization QXT_INIT_PRIVATE(MyTest); } \endcode \section1 The Private Class As mentioned above, data members should usually be kept in the private class. This allows the memory layout of the private class to change without breaking binary compatibility for the public class. Functions that exist only as implementation details, or functions that need access to private data members, should be implemented here. To define the private class, inherit from the template QxtPrivate class, and include the QXT_DECLARE_PUBLIC macro in its public section. The template parameter should be the name of the public class. For example: \code class MyTestPrivate : public QxtPrivate { public: MyTestPrivate(); QXT_DECLARE_PUBLIC(MyTest) }; \endcode \section1 Accessing Private Members Use the qxt_d() function (actually a function-like object) from functions in the public class to access the private class. Similarly, functions in the private class can invoke functions in the public class by using the qxt_p() function (this one's actually a function). For example, assume that MyTest has methods named getFoobar and doBaz(), and MyTestPrivate has a member named foobar and a method named doQuux(). The code might resemble this example: \code int MyTest::getFoobar() { return qxt_d().foobar; } void MyTestPrivate::doQuux() { qxt_p().doBaz(foobar); } \endcode */ /*! * \macro QXT_DECLARE_PRIVATE(PUB) * \relates * Declares that a public class has a related private class. * * This shuold be put in the private section of the public class. The * parameter \a PUB must be the name of the public class. */ /*! * \macro QXT_DECLARE_PUBLIC(PUB) * \relates * Declares that a private class has a related public class named \a PUB. * * This may be put anywhere in the declaration of the private class. The parameter is the name of the public class. */ /*! * \macro QXT_INIT_PRIVATE(PUB) * \relates * Initializes resources owned by the private class. * * This should be called from the public class's constructor, * before qxt_d() is used for the first time. The parameter \a PUB must be * the name of the public class. */ /*! * \macro QXT_D(PUB) * \relates * Returns a reference in the current scope named "d" to the private class * associated with the public class \a PUB. * * This function is only available in a class using QXT_DECLARE_PRIVATE(). */ /*! * \macro QXT_P(PUB) * \relates * Creates a reference in the current scope named "q" to the public class * named \a PUB. * * This macro only works in a class using QXT_DECLARE_PUBLIC(). */ /*! * \fn QxtPrivate& PUB::qxt_d() * \relates * Returns a reference to the private class. * * This function is only available in a class using \a QXT_DECLARE_PRIVATE. */ /*! * \fn const QxtPrivate& PUB::qxt_d() const * \relates * Returns a const reference to the private class. * * This function is only available in a class using \a QXT_DECLARE_PRIVATE. * This overload will be automatically used in const functions. */ /*! * \fn PUB& QxtPrivate::qxt_p() * \relates * Returns a reference to the public class. * * This function is only available in a class using QXT_DECLARE_PUBLIC(). */ /*! * \fn const PUB& QxtPrivate::qxt_p() const * \relates * Returns a const reference to the public class. * * This function is only available in a class using QXT_DECLARE_PUBLIC(). * This overload will be automatically used in const functions. */ vokoscreen-1.9.0/libqxt/qxtglobal.h000066400000000000000000000156171227001500100173460ustar00rootroot00000000000000 /**************************************************************************** ** Copyright (c) 2006 - 2011, the LibQxt project. ** See the Qxt AUTHORS file for a list of authors and copyright holders. ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in the ** documentation and/or other materials provided with the distribution. ** * Neither the name of the LibQxt project nor the ** names of its contributors may be used to endorse or promote products ** derived from this software without specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ** DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY ** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** ** *****************************************************************************/ #ifndef QXTGLOBAL_H #define QXTGLOBAL_H #include #define QXT_VERSION 0x000700 #define QXT_VERSION_STR "0.7.0" //--------------------------global macros------------------------------ #ifndef QXT_NO_MACROS #ifndef _countof #define _countof(x) (sizeof(x)/sizeof(*x)) #endif #endif // QXT_NO_MACROS //--------------------------export macros------------------------------ #define QXT_DLLEXPORT DO_NOT_USE_THIS_ANYMORE #if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN) # if defined(BUILD_QXT_CORE) # define QXT_CORE_EXPORT Q_DECL_EXPORT # else # define QXT_CORE_EXPORT Q_DECL_IMPORT # endif #else # define QXT_CORE_EXPORT #endif // BUILD_QXT_CORE #if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN) # if defined(BUILD_QXT_GUI) # define QXT_GUI_EXPORT Q_DECL_EXPORT # else # define QXT_GUI_EXPORT Q_DECL_IMPORT # endif #else # define QXT_GUI_EXPORT #endif // BUILD_QXT_GUI #if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN) # if defined(BUILD_QXT_NETWORK) # define QXT_NETWORK_EXPORT Q_DECL_EXPORT # else # define QXT_NETWORK_EXPORT Q_DECL_IMPORT # endif #else # define QXT_NETWORK_EXPORT #endif // BUILD_QXT_NETWORK #if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN) # if defined(BUILD_QXT_SQL) # define QXT_SQL_EXPORT Q_DECL_EXPORT # else # define QXT_SQL_EXPORT Q_DECL_IMPORT # endif #else # define QXT_SQL_EXPORT #endif // BUILD_QXT_SQL #if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN) # if defined(BUILD_QXT_WEB) # define QXT_WEB_EXPORT Q_DECL_EXPORT # else # define QXT_WEB_EXPORT Q_DECL_IMPORT # endif #else # define QXT_WEB_EXPORT #endif // BUILD_QXT_WEB #if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN) # if defined(BUILD_QXT_BERKELEY) # define QXT_BERKELEY_EXPORT Q_DECL_EXPORT # else # define QXT_BERKELEY_EXPORT Q_DECL_IMPORT # endif #else # define QXT_BERKELEY_EXPORT #endif // BUILD_QXT_BERKELEY #if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN) # if defined(BUILD_QXT_ZEROCONF) # define QXT_ZEROCONF_EXPORT Q_DECL_EXPORT # else # define QXT_ZEROCONF_EXPORT Q_DECL_IMPORT # endif #else # define QXT_ZEROCONF_EXPORT #endif // QXT_ZEROCONF_EXPORT #if defined(BUILD_QXT_CORE) || defined(BUILD_QXT_GUI) || defined(BUILD_QXT_SQL) || defined(BUILD_QXT_NETWORK) || defined(BUILD_QXT_WEB) || defined(BUILD_QXT_BERKELEY) || defined(BUILD_QXT_ZEROCONF) # define BUILD_QXT #endif QXT_CORE_EXPORT const char* qxtVersion(); #ifndef QT_BEGIN_NAMESPACE #define QT_BEGIN_NAMESPACE #endif #ifndef QT_END_NAMESPACE #define QT_END_NAMESPACE #endif #ifndef QT_FORWARD_DECLARE_CLASS #define QT_FORWARD_DECLARE_CLASS(Class) class Class; #endif /**************************************************************************** ** This file is derived from code bearing the following notice: ** The sole author of this file, Adam Higerd, has explicitly disclaimed all ** copyright interest and protection for the content within. This file has ** been placed in the public domain according to United States copyright ** statute and case law. In jurisdictions where this public domain dedication ** is not legally recognized, anyone who receives a copy of this file is ** permitted to use, modify, duplicate, and redistribute this file, in whole ** or in part, with no restrictions or conditions. In these jurisdictions, ** this file shall be copyright (C) 2006-2008 by Adam Higerd. ****************************************************************************/ #define QXT_DECLARE_PRIVATE(PUB) friend class PUB##Private; QxtPrivateInterface qxt_d; #define QXT_DECLARE_PUBLIC(PUB) friend class PUB; #define QXT_INIT_PRIVATE(PUB) qxt_d.setPublic(this); #define QXT_D(PUB) PUB##Private& d = qxt_d() #define QXT_P(PUB) PUB& p = qxt_p() template class QxtPrivate { public: virtual ~QxtPrivate() {} inline void QXT_setPublic(PUB* pub) { qxt_p_ptr = pub; } protected: inline PUB& qxt_p() { return *qxt_p_ptr; } inline const PUB& qxt_p() const { return *qxt_p_ptr; } inline PUB* qxt_ptr() { return qxt_p_ptr; } inline const PUB* qxt_ptr() const { return qxt_p_ptr; } private: PUB* qxt_p_ptr; }; template class QxtPrivateInterface { friend class QxtPrivate; public: QxtPrivateInterface() { pvt = new PVT; } ~QxtPrivateInterface() { delete pvt; } inline void setPublic(PUB* pub) { pvt->QXT_setPublic(pub); } inline PVT& operator()() { return *static_cast(pvt); } inline const PVT& operator()() const { return *static_cast(pvt); } inline PVT * operator->() { return static_cast(pvt); } inline const PVT * operator->() const { return static_cast(pvt); } private: QxtPrivateInterface(const QxtPrivateInterface&) { } QxtPrivateInterface& operator=(const QxtPrivateInterface&) { } QxtPrivate* pvt; }; #endif // QXT_GLOBAL vokoscreen-1.9.0/libqxt/qxtglobalshortcut.cpp000066400000000000000000000147171227001500100214750ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) Qxt Foundation. Some rights reserved. ** ** This file is part of the QxtGui module of the Qxt library. ** ** This library is free software; you can redistribute it and/or modify it ** under the terms of the Common Public License, version 1.0, as published ** by IBM, and/or under the terms of the GNU Lesser General Public License, ** version 2.1, as published by the Free Software Foundation. ** ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR ** FITNESS FOR A PARTICULAR PURPOSE. ** ** You should have received a copy of the CPL and the LGPL along with this ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files ** included with the source distribution for more information. ** If you did not receive a copy of the licenses, contact the Qxt Foundation. ** ** ** ****************************************************************************/ #include "qxtglobalshortcut.h" #include "qxtglobalshortcut_p.h" #include #include bool QxtGlobalShortcutPrivate::error = false; #ifndef Q_WS_MAC int QxtGlobalShortcutPrivate::ref = 0; QAbstractEventDispatcher::EventFilter QxtGlobalShortcutPrivate::prevEventFilter = 0; #endif // Q_WS_MAC QHash, QxtGlobalShortcut*> QxtGlobalShortcutPrivate::shortcuts; QxtGlobalShortcutPrivate::QxtGlobalShortcutPrivate() : enabled(true), key(Qt::Key(0)), mods(Qt::NoModifier) { #ifndef Q_WS_MAC if (!ref++) prevEventFilter = QAbstractEventDispatcher::instance()->setEventFilter(eventFilter); #endif // Q_WS_MAC } QxtGlobalShortcutPrivate::~QxtGlobalShortcutPrivate() { #ifndef Q_WS_MAC if (!--ref) QAbstractEventDispatcher::instance()->setEventFilter(prevEventFilter); #endif // Q_WS_MAC } bool QxtGlobalShortcutPrivate::setShortcut(const QKeySequence& shortcut) { Qt::KeyboardModifiers allMods = Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier; key = shortcut.isEmpty() ? Qt::Key(0) : Qt::Key((shortcut[0] ^ allMods) & shortcut[0]); mods = shortcut.isEmpty() ? Qt::KeyboardModifiers(0) : Qt::KeyboardModifiers(shortcut[0] & allMods); const quint32 nativeKey = nativeKeycode(key); const quint32 nativeMods = nativeModifiers(mods); const bool res = registerShortcut(nativeKey, nativeMods); if (res) shortcuts.insert(qMakePair(nativeKey, nativeMods), &qxt_p()); else qWarning() << "QxtGlobalShortcut failed to register:" << QKeySequence(key + mods).toString(); return res; } bool QxtGlobalShortcutPrivate::unsetShortcut() { bool res = false; const quint32 nativeKey = nativeKeycode(key); const quint32 nativeMods = nativeModifiers(mods); if (shortcuts.value(qMakePair(nativeKey, nativeMods)) == &qxt_p()) res = unregisterShortcut(nativeKey, nativeMods); if (res) shortcuts.remove(qMakePair(nativeKey, nativeMods)); else qWarning() << "QxtGlobalShortcut failed to unregister:" << QKeySequence(key + mods).toString(); key = Qt::Key(0); mods = Qt::KeyboardModifiers(0); return res; } void QxtGlobalShortcutPrivate::activateShortcut(quint32 nativeKey, quint32 nativeMods) { QxtGlobalShortcut* shortcut = shortcuts.value(qMakePair(nativeKey, nativeMods)); if (shortcut && shortcut->isEnabled()) emit shortcut->activated(); } /*! \class QxtGlobalShortcut \inmodule QxtGui \brief The QxtGlobalShortcut class provides a global shortcut aka "hotkey". A global shortcut triggers even if the application is not active. This makes it easy to implement applications that react to certain shortcuts still if some other application is active or if the application is for example minimized to the system tray. Example usage: \code QxtGlobalShortcut* shortcut = new QxtGlobalShortcut(window); connect(shortcut, SIGNAL(activated()), window, SLOT(toggleVisibility())); shortcut->setShortcut(QKeySequence("Ctrl+Shift+F12")); \endcode \bold {Note:} Since Qxt 0.6 QxtGlobalShortcut no more requires QxtApplication. */ /*! \fn QxtGlobalShortcut::activated() This signal is emitted when the user types the shortcut's key sequence. \sa shortcut */ /*! Constructs a new QxtGlobalShortcut with \a parent. */ QxtGlobalShortcut::QxtGlobalShortcut(QObject* parent) : QObject(parent) { QXT_INIT_PRIVATE(QxtGlobalShortcut); } /*! Constructs a new QxtGlobalShortcut with \a shortcut and \a parent. */ QxtGlobalShortcut::QxtGlobalShortcut(const QKeySequence& shortcut, QObject* parent) : QObject(parent) { QXT_INIT_PRIVATE(QxtGlobalShortcut); setShortcut(shortcut); } /*! Destructs the QxtGlobalShortcut. */ QxtGlobalShortcut::~QxtGlobalShortcut() { if (qxt_d().key != 0) qxt_d().unsetShortcut(); } /*! \property QxtGlobalShortcut::shortcut \brief the shortcut key sequence \bold {Note:} Notice that corresponding key press and release events are not delivered for registered global shortcuts even if they are disabled. Also, comma separated key sequences are not supported. Only the first part is used: \code qxtShortcut->setShortcut(QKeySequence("Ctrl+Alt+A,Ctrl+Alt+B")); Q_ASSERT(qxtShortcut->shortcut() == QKeySequence("Ctrl+Alt+A")); \endcode */ QKeySequence QxtGlobalShortcut::shortcut() const { return QKeySequence(qxt_d().key | qxt_d().mods); } bool QxtGlobalShortcut::setShortcut(const QKeySequence& shortcut) { if (qxt_d().key != 0) qxt_d().unsetShortcut(); return qxt_d().setShortcut(shortcut); } /*! \property QxtGlobalShortcut::enabled \brief whether the shortcut is enabled A disabled shortcut does not get activated. The default value is \c true. \sa setDisabled() */ bool QxtGlobalShortcut::isEnabled() const { return qxt_d().enabled; } void QxtGlobalShortcut::setEnabled(bool enabled) { qxt_d().enabled = enabled; } /*! Sets the shortcut \a disabled. \sa enabled */ void QxtGlobalShortcut::setDisabled(bool disabled) { qxt_d().enabled = !disabled; } vokoscreen-1.9.0/libqxt/qxtglobalshortcut.h000066400000000000000000000053171227001500100211360ustar00rootroot00000000000000#ifndef QXTGLOBALSHORTCUT_H /**************************************************************************** ** Copyright (c) 2006 - 2011, the LibQxt project. ** See the Qxt AUTHORS file for a list of authors and copyright holders. ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in the ** documentation and/or other materials provided with the distribution. ** * Neither the name of the LibQxt project nor the ** names of its contributors may be used to endorse or promote products ** derived from this software without specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ** DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY ** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** ** *****************************************************************************/ #define QXTGLOBALSHORTCUT_H #include "qxtglobal.h" #include #include class QxtGlobalShortcutPrivate; class QXT_GUI_EXPORT QxtGlobalShortcut : public QObject { Q_OBJECT QXT_DECLARE_PRIVATE(QxtGlobalShortcut) Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled) Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut) public: explicit QxtGlobalShortcut(QObject* parent = 0); explicit QxtGlobalShortcut(const QKeySequence& shortcut, QObject* parent = 0); virtual ~QxtGlobalShortcut(); QKeySequence shortcut() const; bool setShortcut(const QKeySequence& shortcut); bool isEnabled() const; public Q_SLOTS: void setEnabled(bool enabled = true); void setDisabled(bool disabled = true); Q_SIGNALS: void activated(); }; #endif // QXTGLOBALSHORTCUT_H vokoscreen-1.9.0/libqxt/qxtglobalshortcut_p.h000066400000000000000000000060261227001500100214530ustar00rootroot00000000000000#ifndef QXTGLOBALSHORTCUT_P_H /**************************************************************************** ** Copyright (c) 2006 - 2011, the LibQxt project. ** See the Qxt AUTHORS file for a list of authors and copyright holders. ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in the ** documentation and/or other materials provided with the distribution. ** * Neither the name of the LibQxt project nor the ** names of its contributors may be used to endorse or promote products ** derived from this software without specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ** DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY ** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** ** *****************************************************************************/ #define QXTGLOBALSHORTCUT_P_H #include "qxtglobalshortcut.h" #include #include #include class QxtGlobalShortcutPrivate : public QxtPrivate { public: QXT_DECLARE_PUBLIC(QxtGlobalShortcut) QxtGlobalShortcutPrivate(); ~QxtGlobalShortcutPrivate(); bool enabled; Qt::Key key; Qt::KeyboardModifiers mods; bool setShortcut(const QKeySequence& shortcut); bool unsetShortcut(); static bool error; #ifndef Q_WS_MAC static int ref; static QAbstractEventDispatcher::EventFilter prevEventFilter; static bool eventFilter(void* message); #endif // Q_WS_MAC static void activateShortcut(quint32 nativeKey, quint32 nativeMods); private: static quint32 nativeKeycode(Qt::Key keycode); static quint32 nativeModifiers(Qt::KeyboardModifiers modifiers); static bool registerShortcut(quint32 nativeKey, quint32 nativeMods); static bool unregisterShortcut(quint32 nativeKey, quint32 nativeMods); static QHash, QxtGlobalShortcut*> shortcuts; }; #endif // QXTGLOBALSHORTCUT_P_H vokoscreen-1.9.0/libqxt/qxtglobalshortcut_x11.cpp000066400000000000000000000117661227001500100221670ustar00rootroot00000000000000#include "qxtglobalshortcut_p.h" /**************************************************************************** ** Copyright (c) 2006 - 2011, the LibQxt project. ** See the Qxt AUTHORS file for a list of authors and copyright holders. ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in the ** documentation and/or other materials provided with the distribution. ** * Neither the name of the LibQxt project nor the ** names of its contributors may be used to endorse or promote products ** derived from this software without specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ** DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY ** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** ** *****************************************************************************/ #include #include static int (*original_x_errhandler)(Display* display, XErrorEvent* event); static int qxt_x_errhandler(Display* display, XErrorEvent *event) { Q_UNUSED(display); switch (event->error_code) { case BadAccess: case BadValue: case BadWindow: if (event->request_code == 33 /* X_GrabKey */ || event->request_code == 34 /* X_UngrabKey */) { QxtGlobalShortcutPrivate::error = true; //TODO: //char errstr[256]; //XGetErrorText(dpy, err->error_code, errstr, 256); } default: return 0; } } bool QxtGlobalShortcutPrivate::eventFilter(void* message) { XEvent* event = static_cast(message); if (event->type == KeyPress) { XKeyEvent* key = (XKeyEvent*) event; activateShortcut(key->keycode, // Mod1Mask == Alt, Mod4Mask == Meta key->state & (ShiftMask | ControlMask | Mod1Mask | Mod4Mask)); } return false; } quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers) { // ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, and Mod5Mask quint32 native = 0; if (modifiers & Qt::ShiftModifier) native |= ShiftMask; if (modifiers & Qt::ControlModifier) native |= ControlMask; if (modifiers & Qt::AltModifier) native |= Mod1Mask; if (modifiers & Qt::MetaModifier) native |= Mod4Mask; // TODO: resolve these? //if (modifiers & Qt::MetaModifier) //if (modifiers & Qt::KeypadModifier) //if (modifiers & Qt::GroupSwitchModifier) return native; } quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key) { Display* display = QX11Info::display(); return XKeysymToKeycode(display, XStringToKeysym(QKeySequence(key).toString().toLatin1().data())); } bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods) { Display* display = QX11Info::display(); Window window = QX11Info::appRootWindow(); Bool owner = True; int pointer = GrabModeAsync; int keyboard = GrabModeAsync; error = false; original_x_errhandler = XSetErrorHandler(qxt_x_errhandler); XGrabKey(display, nativeKey, nativeMods, window, owner, pointer, keyboard); XGrabKey(display, nativeKey, nativeMods | Mod2Mask, window, owner, pointer, keyboard); // allow numlock XSync(display, False); XSetErrorHandler(original_x_errhandler); return !error; } bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods) { Display* display = QX11Info::display(); Window window = QX11Info::appRootWindow(); error = false; original_x_errhandler = XSetErrorHandler(qxt_x_errhandler); XUngrabKey(display, nativeKey, nativeMods, window); XUngrabKey(display, nativeKey, nativeMods | Mod2Mask, window); // allow numlock XSync(display, False); XSetErrorHandler(original_x_errhandler); return !error; } vokoscreen-1.9.0/libqxt/qxtwindowsystem.cpp000066400000000000000000000115321227001500100212050ustar00rootroot00000000000000#include "qxtwindowsystem.h" /**************************************************************************** ** Copyright (c) 2006 - 2011, the LibQxt project. ** See the Qxt AUTHORS file for a list of authors and copyright holders. ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in the ** documentation and/or other materials provided with the distribution. ** * Neither the name of the LibQxt project nor the ** names of its contributors may be used to endorse or promote products ** derived from this software without specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ** DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY ** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** ** *****************************************************************************/ #include /*! \class QxtWindowSystem \inmodule QxtWidgets \brief The QxtWindowSystem class provides means for accessing native windows. \bold {Note:} The underlying window system might or might not allow one to alter states of windows belonging to other processes. \warning QxtWindowSystem is portable in principle, but be careful while using it since you are probably about to do something non-portable. \section1 Advanced example usage: \code class NativeWindow : public QWidget { public: NativeWindow(WId wid) { QWidget::create(wid, false, false); // window, initializeWindow, destroyOldWindow } ~NativeWindow() { QWidget::destroy(false, false); // destroyWindow, destroySubWindows } }; \endcode \code WindowList windows = QxtWindowSystem::windows(); QStringList titles = QxtWindowSystem::windowTitles(); bool ok = false; QString title = QInputDialog::getItem(0, "Choose Window", "Choose a window to be hid:", titles, 0, false, &ok); if (ok) { int index = titles.indexOf(title); if (index != -1) { NativeWindow window(windows.at(index)); window.hide(); } } \endcode \bold {Note:} Currently supported platforms are \bold X11 and \bold Windows. */ /*! \fn QxtWindowSystem::windows() Returns the list of native window system identifiers. \sa QApplication::topLevelWidgets(), windowTitles() */ /*! \fn QxtWindowSystem::activeWindow() Returns the native window system identifier of the active window if any. \sa QApplication::activeWindow() */ /*! \fn QxtWindowSystem::findWindow(const QString& title) Returns the native window system identifier of the window if any with given \a title. Example usage: \code WId wid = QxtWindowSystem::findWindow("Mail - Kontact"); QPixmap screenshot = QPixmap::grabWindow(wid); \endcode \sa QWidget::find() */ /*! \fn QxtWindowSystem::windowAt(const QPoint& pos) Returns the native window system identifier of the window if any at \a pos. \sa QApplication::widgetAt() */ /*! \fn QxtWindowSystem::windowTitle(WId window) Returns the title of the native \a window. \sa QWidget::windowTitle(), windowTitles() */ /*! \fn QxtWindowSystem::windowTitles() Returns a list of native window titles. \sa QWidget::windowTitle(), windowTitle(), windows() */ /*! \fn QxtWindowSystem::windowGeometry(WId window) Returns the geometry of the native \a window. \sa QWidget::frameGeometry() */ /*! \fn QxtWindowSystem::idleTime() Returns the system "idle time" ie. the time since last user input in milliseconds. */ QStringList QxtWindowSystem::windowTitles() { WindowList windows = QxtWindowSystem::windows(); QStringList titles; foreach(WId window, windows) titles += QxtWindowSystem::windowTitle(window); return titles; } vokoscreen-1.9.0/libqxt/qxtwindowsystem.h000066400000000000000000000045221227001500100206530ustar00rootroot00000000000000#ifndef QXTWINDOWSYSTEM_H /**************************************************************************** ** Copyright (c) 2006 - 2011, the LibQxt project. ** See the Qxt AUTHORS file for a list of authors and copyright holders. ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in the ** documentation and/or other materials provided with the distribution. ** * Neither the name of the LibQxt project nor the ** names of its contributors may be used to endorse or promote products ** derived from this software without specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ** DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY ** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** ** *****************************************************************************/ #define QXTWINDOWSYSTEM_H #include #include "qxtglobal.h" typedef QList WindowList; class QXT_GUI_EXPORT QxtWindowSystem { public: static WindowList windows(); static WId activeWindow(); static WId findWindow(const QString& title); static WId windowAt(const QPoint& pos); static QString windowTitle(WId window); static QStringList windowTitles(); static QRect windowGeometry(WId window); static uint idleTime(); }; #endif // QXTWINDOWSYSTEM_H vokoscreen-1.9.0/libqxt/qxtwindowsystem_x11.cpp000066400000000000000000000150611227001500100216770ustar00rootroot00000000000000#include "qxtwindowsystem.h" /**************************************************************************** ** Copyright (c) 2006 - 2011, the LibQxt project. ** See the Qxt AUTHORS file for a list of authors and copyright holders. ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in the ** documentation and/or other materials provided with the distribution. ** * Neither the name of the LibQxt project nor the ** names of its contributors may be used to endorse or promote products ** derived from this software without specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ** DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY ** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** ** *****************************************************************************/ #include #include #include static WindowList qxt_getWindows(Atom prop) { WindowList res; Atom type = 0; int format = 0; uchar* data = 0; ulong count, after; Display* display = QX11Info::display(); Window window = QX11Info::appRootWindow(); if (XGetWindowProperty(display, window, prop, 0, 1024 * sizeof(Window) / 4, False, AnyPropertyType, &type, &format, &count, &after, &data) == Success) { Window* list = reinterpret_cast(data); for (uint i = 0; i < count; ++i) res += list[i]; if (data) XFree(data); } return res; } WindowList QxtWindowSystem::windows() { static Atom net_clients = 0; if (!net_clients) net_clients = XInternAtom(QX11Info::display(), "_NET_CLIENT_LIST_STACKING", True); return qxt_getWindows(net_clients); } WId QxtWindowSystem::activeWindow() { static Atom net_active = 0; if (!net_active) net_active = XInternAtom(QX11Info::display(), "_NET_ACTIVE_WINDOW", True); return qxt_getWindows(net_active).value(0); } WId QxtWindowSystem::findWindow(const QString& title) { Window result = 0; WindowList list = windows(); foreach (const Window &wid, list) { if (windowTitle(wid) == title) { result = wid; break; } } return result; } WId QxtWindowSystem::windowAt(const QPoint& pos) { Window result = 0; WindowList list = windows(); for (int i = list.size() - 1; i >= 0; --i) { WId wid = list.at(i); if (windowGeometry(wid).contains(pos)) { result = wid; break; } } return result; } QString QxtWindowSystem::windowTitle(WId window) { QString name; char* str = 0; if (XFetchName(QX11Info::display(), window, &str)) name = QString::fromLatin1(str); if (str) XFree(str); return name; } QRect QxtWindowSystem::windowGeometry(WId window) { int x, y; uint width, height, border, depth; Window root, child; Display* display = QX11Info::display(); XGetGeometry(display, window, &root, &x, &y, &width, &height, &border, &depth); XTranslateCoordinates(display, window, root, x, y, &x, &y, &child); static Atom net_frame = 0; if (!net_frame) net_frame = XInternAtom(QX11Info::display(), "_NET_FRAME_EXTENTS", True); QRect rect(x, y, width, height); Atom type = 0; int format = 0; uchar* data = 0; ulong count, after; if (XGetWindowProperty(display, window, net_frame, 0, 4, False, AnyPropertyType, &type, &format, &count, &after, &data) == Success) { // _NET_FRAME_EXTENTS, left, right, top, bottom, CARDINAL[4]/32 if (count == 4) { long* extents = reinterpret_cast(data); rect.adjust(-extents[0], -extents[2], extents[1], extents[3]); } if (data) XFree(data); } return rect; } typedef struct { Window window; /* screen saver window - may not exist */ int state; /* ScreenSaverOff, ScreenSaverOn, ScreenSaverDisabled*/ int kind; /* ScreenSaverBlanked, ...Internal, ...External */ unsigned long til_or_since; /* time til or since screen saver */ unsigned long idle; /* total time since last user input */ unsigned long eventMask; /* currently selected events for this client */ } XScreenSaverInfo; typedef XScreenSaverInfo* (*XScreenSaverAllocInfo)(); typedef Status (*XScreenSaverQueryInfo)(Display* display, Drawable* drawable, XScreenSaverInfo* info); static XScreenSaverAllocInfo _xScreenSaverAllocInfo = 0; static XScreenSaverQueryInfo _xScreenSaverQueryInfo = 0; uint QxtWindowSystem::idleTime() { static bool xssResolved = false; if (!xssResolved) { QLibrary xssLib(QLatin1String("Xss"), 1); if (xssLib.load()) { _xScreenSaverAllocInfo = (XScreenSaverAllocInfo) xssLib.resolve("XScreenSaverAllocInfo"); _xScreenSaverQueryInfo = (XScreenSaverQueryInfo) xssLib.resolve("XScreenSaverQueryInfo"); xssResolved = true; } } uint idle = 0; if (xssResolved) { XScreenSaverInfo* info = _xScreenSaverAllocInfo(); const int screen = QX11Info::appScreen(); Qt::HANDLE rootWindow = QX11Info::appRootWindow(screen); _xScreenSaverQueryInfo(QX11Info::display(), (Drawable*) rootWindow, info); idle = info->idle; if (info) XFree(info); } return idle; } vokoscreen-1.9.0/lineCounter.sh000077500000000000000000000002041227001500100165050ustar00rootroot00000000000000#!/bin/bash find . -name '*.cpp' -type f -print0 | xargs -0 cat | wc -l find . -name '*.h' -type f -print0 | xargs -0 cat | wc -l vokoscreen-1.9.0/main.cpp000066400000000000000000000041761227001500100153230ustar00rootroot00000000000000/* vokoscreen - A desktop recorder * Copyright (C) 2011-2013 Volker Kohaupt * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "screencast.h" //#include #include #include #include #include #include int main(int argc, char** argv) { QtSingleApplication app(argc, argv); if (app.isRunning()) { qDebug() << "[vokoscreen] vokoscreen can only be started once, vokoscreen runs"; return !app.sendMessage("aa"); } /** * qt_ muß um z.b mit "de" erweitert werden und nicht um "de_DE" dann sollte es funktionieren */ /* // Dies sollte für die fertigen qt-Dialoge sein, funktioniert aber nicht. QTranslator * qtTranslator = new QTranslator(); qtTranslator->load( "qt_" + QLocale::system().name(), QLibraryInfo::location( QLibraryInfo::TranslationsPath ) ); app.installTranslator( qtTranslator ); qDebug() << QLibraryInfo::location( QLibraryInfo::TranslationsPath ) << QLocale::system().name(); */ QTranslator translator; translator.load( "vokoscreen_" + QLocale::system().name(), ":/language" ); app.installTranslator( &translator ); qDebug(); qDebug() << "[vokoscreen]" << "Locale:" << QLocale::system().name(); int vokoscreenWidth = 580; int vokoscreenHeight = 260; screencast foo; foo.setFixedSize( vokoscreenWidth, vokoscreenHeight ); app.setActivationWindow( &foo ); foo.show(); return app.exec(); } vokoscreen-1.9.0/main.ts000066400000000000000000000160301227001500100151570ustar00rootroot00000000000000 QvkMail Mail last Video Mail one or more selected Video Send You find the Video as attachment Select one or more files QvkWebcam Noborder Border Close QvkWebcamController Webcam Device is busy Select webcam screencast Fullscreen Window Area Magnification Audio Alsa Pulse Default Codec Do not record mouse cursor Videopath Player Vokoscreen minimized when recording starts Start Stop Pause Play Send Recording time Size in KB Recording screensize Format Settings fps Open Directory %1 Countdown Play last Video Send Video Select one or more devices Actual frames per second Device %1 is busy Your Actual frames in the Settings is too heigh Go Homepage Mailinglist Support Developer Frames Beta openSUSE Beta Ubuntu Donate Program for recording Translations Sourcecode Show in systray New version available vokoscreen-1.9.0/man/000077500000000000000000000000001227001500100144365ustar00rootroot00000000000000vokoscreen-1.9.0/man/man1/000077500000000000000000000000001227001500100152725ustar00rootroot00000000000000vokoscreen-1.9.0/man/man1/vokoscreen.1.gz000066400000000000000000000011701227001500100201500ustar00rootroot00000000000000Sj@}W &$8j.}*qGԑE aIKV^%US(EH;st.3n3<>u*EB!N{YC Gp FsVE-S0C;l PvFOΧp{Od֢1A{jaw^hHa PJ %\4k*B!f!tpݣg3V(n}WVn> &釓Ӌ LC$IB7'ojHx%&ʇ|UY[J#l=|Ŧ9ȊuʓMSm(@X 08oE*65`9 6LFm c]6&^LR1)#d jOb MӺ'h#p;WVà{@|-46$ 4zΖ2)ѹ(GhZK<-h*y L-"3VZd x2^ y 7q&Թ<Nkuyݞ1"!]9}?L4\@O~6ŹCr3^&DHLXL-#c GQ*@*_*-}ڃlIK#_<#HU<\,y$7[ޣ&>wi43'oi]W}unMmUKy{@^D"bF:E0(2K ^fo;+v@p쑘?5KhQ/_xtT!LJoRݟ_XC?pϓ c+|+@M5,`TQ өJ̧Gϝzi~{6ǛackV [qH#q.Q+{hR(6y` L @:Wkj9id&DT0(kOGѨgNVoZjG77??`+N28ƫu%?yg_8{k3w`vcg/]޹|坭[jP7l|l]V1Kj OT&> ^_ MZ"Jh:8{ {L,5"Z8\sڗWRLZUzjG+O-,ة},~nŏooafDށdA~3*CA'J^赂ޓqW% ԃ!Pg")sa.# 88)cEٔDk(3I,%Pf)Z*\ 6H″ey3c6CjhkWskmQ`:Lnz;C'^Js~ o;OϏ~g/lM)u HH ! V (pn@QwсŠw:uE{Ti :W WC:5M'<NP @<0RU?f#0 esJ qh8Q6H[y7wr #?+^g LjN__ĥoi_eFh[yu,{tM8y~ŧΏGxkӷCom\N$^ )EhN2QdFCL@#垁P)B6qE Vw LJ42 { *ZcFdױ$A% X0!.lT,oeiyXVQK o"R@+*WK0 ]@E"l>AtG[cqi< mB "(Cqg]$yh'HO9{μq+_[?oފm~{vvejDHV@{)ɀ* fhJ:L$XRIt)*á!:+49&@ڑ,L>%2d_,4գߚT,Au#`&D:̻A'2@jB=TjT8I4Om?׻=xt%ށ7,@\T9aa&HJ*RMEAT2&'-b<#Ee,}CYЄo6'ҭcw'?s{ƌrw~cŝf4ʣQͧQjFhR,2-$` $D#P0ʐl*o05KrLh) > ױT+ /+j,B$gy;ؠeeij j"mQueGBs~嚑2X !bpPSd4l֬ILW6 @fk/̝"1 sV_:|x'wͺima0_vٶpj=z[om[ܵ|qVpmR8*z(s5]v# &ʼnig*<:szCdY|3t żVeꤩ͖h1~rR'js6s<@EIm-TAIB ],0{شʂ e.rUjB=In . 66Fo4egj7Tמ:u.' ZZ "Q)/Ba#{p5,C3 z3 wp+mw*#pUdg A5C)d06{JalHml`<;<3]+v,s4̢b#򮳱Xe7u޷ cvהO?Й'-.&rKR8p7*6bDm3G'qZP`o^D1%ZLJdBbWdD ,*HAnft/bTL `G߰jSff Ytģ_8?vw5_vvV`A KIMW|Aဢ9PAjTݓVb01LN~zW~-EÐ* P>-}oXd O,j1t a;u 2U$*pg1ݑe02rVVIel,D;ij Uo~uo`濻5>J/l[5TagCN `H7;y WhJOhu4XtW&`7> GYJ̅7}VfrRpVL!KT,)U2%`9+J1\vMr:Oܴ5sv.`TI8|U"3eH;dw= G,\5gG +vt_C耒Vu´ju3{&^bՂ"Ȑ qv'$AUlc,z?!kśgN+A X#3e;6.GIF G1ccNj֓}yx>~S=SV"{}A,*=sAuJj>()Ĝ^ YgWZըW êrq"oyAuBpAB!s4P\ մ.<^(=EѼIS2[qUb(&M_|x4-91ֱq~Ѵ%#@-,6 zh= J5 7PLALwYIB8{qU2iY >ay\EFY^UPՙ| yws5o(DgqS÷Y `xyV_|'VZV `KO.{~Q Rfvj7kYb6V$&$UzayBEj$ViK g4ZQ@SWW |;D=QL"E\Py nMXO)55#Ф9ue]R*P9*gƗ+[ >+wF闟厏U],N1ol%6#(TN%Δt+*eiA=ODo_IaYJ=ATv@f}iBھ0[?$u~\@`νܶe9 XOSk/u(АkF!9@@V& l_@nLbe ޒחe筃 W%-=3 VTG= N&\&Ϻmo7`\PpՆA; \a+=kB}Ȕ5,gDU/NID'9p368֫HUZ54C1#ѐĨeFk jK@ `] VLFWΜyl>p`]w#Z3k SZЈb9Hd6'Rf'|^0zp0Sl, Y.8L-$WxrF;EIzf(<.Il*dbKuӮG s 4L-jQ$Zy7OCݼDj_ʀ9(1+Ŋ$*|QE Z0u&=0}_kq}p@ʾDfw$:6qk +G6#gx΃S,ή C0fˣ'4Hi7a'Uպ)wJἤl~7VRr#Y:myid}¥ gp䍟5wxwIwQ `蝹!F|ZXtُ`UT26`DNU ]L!`nԅs=ż+ \m85;{J";h4n bHWI_m4C2fo5(g{W"@CM߽lqY٢Nt uS 2p(-JTqjpRԬCk#첢D墡Ul_^v'B̾@ Z '3ƙOc}<1zNt.~|܈L])|1^k <sQ\(NT5I;gb䲃A" p.\Eu*?B }+jL_H0hYBv[1 I)@Dl`.*@2߉ObPd!Z&m97kҏRȠOSYV.Ikaeh9칦Le ZFt;NY1+A1QW],.~1:|3{xk4z'o}q:u;BGlmanY`F'3o` f2d[X`' V?,B'bQ ,~  3uh-j> AM4SiѦ&A 2,un6fX:Q:M~3(!mڅ1@؏}!MWYZ:sg/>h%O.?'x ﰕoXVVas"i{08s, 4̙w _z3En˗0tPjR?}w+U=L'p_1 j?|@Dl ~ fII['߸PNm Ѱ%Q`"V:.~W_ҿ,CJǓ$yPJ`yyNWի &0x2< 5u!k&p v$3j RJ{OC'y!54^0,+>~nqOmXƭmy)`R\R-\gWԕw.W&M]꯼Ɛh.x94MG5&1ͯ;|y}lo kf\=CJx p^UmH[ I_~*#sm~~QƷt&=Ͷ Ox=uȷ-=iKЌ[>r&VpL9re߃̏KO aw0alJ^z1|yװ5CMa<(̫R%N<\R&5MrWuz)?|KYB?#D !Q D; <m+Oƛ+/?fa^ږ叹\UL 4J=?-e}LPLlCh0N8!r}&M4YqXAt%]\ITJyFSm0.?3E=/ϧ̇_y3xq>-Fȁ`!+d~Ԍ G,E~G 7a?ZhCŹW(Zޙ8Bzrղp`lԶ!_Sk`  ׁz'TFHin f,:QGTχ9-#XNF8d_G>ͷ&z y.e3W˩,dwg\onhT@, 1WmR_VʙXRr[Fm垔m95 %V'I8k[3&rd,zNw# WΙ{uC}=8:ƘR(qH<ۉRjIh$AJ/ٳM'ڳ8qpM#_ 矻}b0eL<z!||쑅4f;v_)32$:rfPOA [DT6uS-odt8{<;@{3tB{垞T0PBJ[ IDAT&̗q]ݾ`#b+R&ʵ~㥑cx +h~\>}Nv9gOdBvC5I:VcC7r1zۘ>l 5M6s+sy|ඏ4hhN` g|{ݺN3JI:\!̃f r / huunoǧE*vb߄Tnꑅ>?*Ua` bZ;R(Z%`}?!үe*XW GOyPu/f̌u4,,QA>.X7-r6:FvgH?R_neNRSڞжGj e*䘁0,`w2&9w 8zMSVUYGe淎uW\ޙ&L:~?ӿYl~v,:`;:ddr>;sإ $nrb7N^04R0uT.ݝN.0ƉZn]Ò;b~kge*u;rH#5(ﴽc*o%\5S,䉧 k 3"dSb!_wr ]DGJAU*!Sa 挹v/M(o.LoLv„3c~a [1T0ԽXCj-Z%C[ e۾s΍ Iɧ_ǰ%"T-H̪-h1 ;ٟ`bCV-,XI.|xH:=eE'f*+ %*IP=M|$#OfJfc$FۊRd8l4Hf`M  QFh3X˘t_sťcX|b67.`~v7k#3YGdYs nWI7[{ ګnvX*\~~06בRjh Pۓk534O % \L4>UN}O, 1@ s=^&#aGV"dqTԦkO2{LgWo~ `jH ò<A1y:u?K3Q! Pe_lPV5J>rB':&xgۗpm/C+_񓷂U S O$Vu6!NT'۴v ljQ?]SƐ"Nd8rtk8 v<"VϸNa"噭D!|7*:Wx+ ظ*Kb[V“_ߏywreڝ5jʮv.,`sb7`X3#KG~u8Y :TU%IgF{?t~ӟ#CP`]VnzBm MKE{3× m5"\"cȿHa &X7|pF<[vֲ0{C* kTf;B˫_V}A^eԪn<+M&4OFCIX*WP @2M-$@[VN_QdN6.șeon>v֫7th6{E-, F¦s 8uGG?_Mڦ~ƻͣ?&5]AU ߜ#?7埽v'۝%@SUZ3nUj ) igggu;jdK{Wtt"91gތ<7W2.-V-S"㫘d 'DT$i5G{TT|aU q8DtLA%0 `1 XfyO`N3s( 2-Z 6t8q~ gm1b[8WNawe&-angO#9PPyJ} \^{I;/v7{~O/,,/?o6VLFּ؊dY ( K i>bn[31c&?n 2@xM@&!Z!eEIr%lZ )'0ʨ.ѥ쁑M+]1 #T=]l2x#wًc1?Q4^yrRۖڵl`1-.u,̣GjXn}xǰvuaR 6mGI8pp-!3=\[ѳ^+sUDr5 <xʯoD4Ct0VIJ>$+} lr&g%5vf{^װ@K$__d)#dGVw)U1`3T5(#L-8V@ fe+@UX-!psK//a\RFeqݲ0 GЌ4HH@s4MkoVz'`ǦK߾?y/]>4~Y)~wv,&'׌Z PF%3$VWªDEPvk6:~mUIr'|Uu#w'nj(-d:WVy}qTbz?kkG~~eZ?kޱsYݭ׶n@\&=\D"eM/DɆTyGr'I3iYKOēPr6~^ߜ N3G LNưLy q= v3{2Biu*|I 7t?ڳ¦6gL(4H7ت=h]cԣ#.z??9AfN_ol.ƹJhIynĉK ͧLFsEpb-%J#"Jx30DI%Sjv4Qj.qKhr&Qz+?{\fɳS4 'wVjfTR<BF"QN}HnOz J 6O,>0s+w[-^ɬ mLn"s u'41ՉQ:}f Nz1ql:ʔ;l6%)8u(1ovW~~3o V |W<]nDjlԐ^4UbLR#E >#a3b@-.*S)UFI&_ "FJM "9 VτMHfMS|%Rj@`d8* *`Z ܂s@cս̹T+@[0 _U VY^_M>+}辱tV_&TM˄ ]=3T 54Å]}?^&_-a,f̎&t}7@Qh1d]/n*P}pfX=K: WQ7O!PSSP$B4WKSo@HT_oKChcd1v ewr J?Ɵ`nl_™W7IwgOG v%~p爥jhu 孟ۺ|f4Y@pdPݵ/vn'/WWL$J\% ks0I0W~`\,ALYLM0wA%:CaihEm"E c==N׶2MQ%AH )R30%4g ͖ޭl%RNy\T2ok6/W?XI#]|(Ԏ*Jb~(^{wyb(Nc ^gf F'\^}4TMʐw&18`U =!ƽb}-[rcz5Z$M&ۀ3R(Cݡ]=K $_v#1)q ےb# c Ν㗑[ZE]ad-:U}ʔԌЌRFf¤]AAkRv{cv9)?bg"^?e8~p3z4JD?#wb<+/6v2 G#,Th F]٭s6(/ښRPU }q6=R?0"&;T(züMMLIo:!e/FV5Km?~Cc'Tj`PA RhB`.h78|rZկUl;esn˧Ctҏu[H (0f8Iu8'a?g?dj<~cxw`{o6a41:t#Ο}/<_–lp7:xWƗl4HIN'dsf4U=GWL݁2dOJT&$|DxLML Z}}ZC2HƬ]YCy #{Q*Tdg eJ l4<⚋EZg0/j&4D- @@]LUQd0EU/E'QmV&TlMOZiMqfK8~6,+vmS%pKX "p44 sG~aψ!Z_[oWm;k*OnSQP8-W%J5!@?K Sғ=x\ȓ8g$ZX7M ]<>zTP6I ql:rQ5@0*kbԭKڜwa[^.)l_-/rHgvgl: i0.c/k*:/2hiJed1rۜgt:|~čC}`EyMJ`rCই̌RJ" EҺ#1Fe'۵JŀV02L3{.SqRQL2D23. !DMY#:l3'QT*g,gp=jBW`kQ<tZ&i΄{Je}]$yVH'DH\jMl\޴n2|E^/,,,,/LCxRxR1hf@ρ'$R'ˇJ1}[?(e̮.i 캙Dg;24Adaw#@1_[MG ZLU5 "ϠF6 E#˲"3m@Y0$6* Hw3+3J@{u6vSjcLYىj_+W LT VNnQ4L/Xa @Ti]ژ .|/>g~A`_? 4E#.>W lsMH#QA6]\|@bH1LE8QY _UQPL"MY Xפv O=,  $LE?ݟK޷7Ɍz_tQ}}Vlz!pLbUpEAF9k)%3I\@%1 8\&J"nz|@RDT!eͥGL 2 IO.j%j׻+g3Fvx!.Rpt)CtN'I'TUdߎAK 1Pҭu#g\aiKK/t`μ_ U N>mq̃lI VA0Ӱ%C8FA%enX;{sdmaD(?`j֍ d[4sZ`k(*y0uKj 8̹d=&#H?JOHRz%E.;Sߓs2ɡ= r1piuqLBo}~O, FRsqT|9WqRN܍V&2T.kj3iv?cȑ[+zY`zqwwiqlZu- T=duL:FCĩPNc ܁|JV+L!_O +U Yfax:9y:EnNi;,H,R)Pgg|qOCU_P|y;= ʠq*( 9A Z&BԽDxO +$V* WVn⩻?9IYt  ̌Ժ&L11RƗ Kơq6uÖU>]䝘25Mo'e0{QlSz_@&JrD#dPcLjG!ˣ0Ig~տwڿ{3Nlr@sdӇW^!9xcUe #BGjEJU6}# -V%Iˤ˰2鈽}~_ƚW $@v ٢Jޱ3 e$;lyA\Bx8V ' waZDKf GV?҉qi̙3KF22ɏU'Q( O/\M @~(8G^f| ,}zE4dBZ@9]Luv܂ޘOx?Z56V:K  s9]u(XhS^@`ymw?sIx16o,Mzni,&N u7PudlDqi-*]C:*SK*(ű+p!O 1oՄթ݁߳s&ǪBRPb~{b1VYE8S@*SIF:Z+;:4:A}0^xDBDa> # !:9 PÁZVZJlA V`Kar)0D΂S2$Yʄlhq;j;+yҵ!7]Cxjv ϴ`*(H}eᝁҩ//Tͻ?32KeOa&x 8 ;Ao/2ArV(*)}Ko9U=WTЩMj73ݣp>(hz4V'W6\LӋPGTsh >/|3}Z=JT}@MgzR hAɢEX֝dZwc|X!'[!t!O5*PA6q;V\7n54ԞelmÄUTaOMiH͚0)5XZosp׎>+(aa2AšUɀ5`*q9L*_~` g l"&c6 bɰ${][8 T7DckjgW7uf}YLJ|#( 6T TP{k]T3s:uй痩w.0POZF6Ւp3^n:$XɪI7/_PkET)z# LMU:{1*T5Lja"8CA,"-5{=4\t6TaRUX"HzݩSg1N*dW3T GO_U"{ywڍ2$}ÝmrhA (ťf,c:kN9`4a *^Cu #i)#W!b~v4U-iyl ڮAI*IPJU>Fb0P| f0v6(8~}߸鿧xww/2$\ƕAB랹eણWjt{v-i餔fT6$ 9~^n'Ä)JbɉʢOj$PNgMqsw;L1ŧ(6cw<׌8 ,{{z`M0 JRFd{~{j6l!:IZխriH!kT)y\gȇ{t3EҸ*M[w; ]zQcg}ɱ6]yQ@w,լfJաSzwӫ*ʌ=0mw:5Rȝ{ePnT9p.~꙯}Fݻ,DU }= @ wziLh ._̈́)g2j&6!^y)kVY9c^ ynD8xѕ=~ynۭ:EXMNP2!+Pquye4߉Tv˨w&g k3%2t^:GVbazi&g=~7yVk ՖVBSMW 6>K}36Gf{zQ+mڨP%f4RP؁C^찚A-MNtk3?UKL.gplkہ:mR#MITGTCie&V|?>1H`8[(D jK:ۊN!dž s+9NSȇ~@ 0Cx33/<}ۮNKU jgȪvغoGF:,*lo t\*̒2 ȳ0TLhjV0#[_a~S%%{ Bjny-B |54`1fxnak7uיkg0_>H\`£){FPdVU ҟ';;&Mfle8nLUhN'o ΥِbntUfk߃Zb4f0Я>LC?>ji ܳywFB:[9fkIɽ{cGA5EEN43|,:J5yqhOklȪ85n5_x qʒ//hHt{PH|i.\=`NqϓSwsu{D:PX2+,qLoϿ`4  = KDpRq<Tiu(i=T՝#3  s&BAh* K8"=?6 F`Q3:C8zo$[q] 0~u]vsuZH'/(T 基@ ( X$ pob f.ISbХ^=uS"5J{K(@T54d;g'.#830F+G?Ծ>r9Tzb]DGn~ԝ}m+H'kfL?}q*xPH\Uc-E9UZ\ՠʨ$h7}B49~dB9b\+7&2G2p\,oo\A5 M2%*;|੹{cmoٖQapltMU3@¨6=I@Y I*ҌU[԰ &Ta;Tu!c|c+Sp\;N5ڃwճ) ׷Vnwd:.1Tsɹ. jŕ7.š] C9EC'_GD>oޕ?s#@;DzScSCR^,:kLgqb JZWҾw!|i!TOY<HHbG#[&4 K{ ]cP{q8]JՍ۱Qy@Ou;k[ k?j_! K#;^w) SM'/aWC,C*cg:-wd3"Rh+ٯFSoΞT8^Ff7 ){C"g9WзJ݈}'HZk.C>OBc'y2+(ցw{ۼqO;u1j TJ ,h9ƛPCg P#-B=JP%xd4FiQM \L*Qb]lޥ D坡1Sww$mv~r{3_'i5Xґ:tǎNWs\A:cƀzTYYH,2 {ճ /U81/{DQ猢̔g {*SR;zG4`/`^~En~dwwxbG3C1h)ePəIڙ$%B?}u߁RxCiwfşg)2++#v.긷gbzSObE (V_űL/RIe7uzRMwrαQNY?%[!RNnU%5+܆s*Lي T5xK1a閫T7 qi/pӞT@G\瞤fQ+fPϊUY1Cf*1e{Xk lDd;sq0d\G> m;owpcf_^}bjPՇ%vg3*U]t5h"- IDAT@o8:*!P;N!OL^\`, CrYd0Tf'fdD}>¢,sNrMٰ3 {;(Fo<7״'`N=\*wR#Tr^쾨Q^5m j( @sO;0Z|i1 j~xufˀau@4GveB8K0H#/OHvҗLt<-˹ |p|YN43t>1Xla1V@v2N{-g n{ThWbYz1rCR_~t-ukƻEUeԙu+gn6j ۡQWt)5VkZM9ڹTʭf, (}(D d~W_(K2DQ?PJ <2੨P̰N*Q^+SNh  5㷀k z_|^}#?f ` w MUHw(qi IXJE{p tRvw@R&` ] moِ3[ߕW'\488  - ~5Ac!j[֘Fe.pDYPv"v{&9SJLͦi>ldfnr0ٜN'hЕ}=XIɕC(<|d PuB/9`gc7DIpV PJq`{ \@0~I̽ogCW__KmSr@CVb f* ŸB^ôb䍛{7_ynz7^ŤI0`6u7r8 KLW?+'PS!? Pص 5\#IgJ2 h^B:l-xpBza5ȵk5 % pQ5PW\_TUau6IJ ԨM2򭳯O? ஞ,8gټ9]\90@0#g'Q$$Bx2i`ɋ5D1dOY9^omW`4k90UӪA= 9;ͯ!Fky.(y]G%ֳ}J\O|d|nܼ1ۻv}=ػ w?N\>C=FZ`\Pђg(*fQsT> 5MZ )f,IA+c@l9 Jߓ67{ĕ*: g9.@ aK -z :t̓>9w(X~lo?ygnܼp%]XPx歯}|1x uf0eB`| ԩG t#-SPDM1:_Z ^ {;-_ޝ= 0$PUbF{k \ ٖv;l9%_u,`81[vҍo1}K`xQ$?C1R<  Cv/r=H#}."DMZA*V4̳񗝺+_:ab|O,hbz[״3~YN5ۊ[]ړN `jf e*4ʯ%b쒛i_/UkG°*>a8nwc=zw<7[NdZqxpemr׾6r)!sOa0hzGtɗ*('(c'Iynm?rFw!ʳ2O32P/ 7!gQwT؎N"ohh7BOy[.-ACh r3Fr՗NU4 ~u0,\eٯ*'lmѧ>˷50 5c*,-,ǟÎi6J4 b I["BL 3tXN#iE0Z @JN\TX!zA89cARVJ,e)^j=8 7LVg_Ğ!R:w+ 9jqw+uyNazǧg <+b3O %z^<1/ju6 8Fk[ݖU`ȪzwB;(b"1n[KRZi|.Z㰩AaծcK(]_SG./ RuG :!l4,`в_kF"YZ **]Xb<^n@~-jg׷ }U}0kd϶`c#ٵՆ!}?کjൾJQqj|ނNtkC6~<+̳#L ϶4]ۢ0UgʽNH(J}0.kGĕꇞz^|յV=-N9Q'ϩp:M((B7kIFDA_)Y9`3{ cw<3e1EԘu+ $yA<]R0]z\gDb--VQ1vX~1PB8NOνVRC#}!6рASv#q{ rYk}؁VTZaԡҁNtlukH|yzO a.r쌎 \2~9ڗ /S}`cO`+<B\8DKjWq$}.T QgILR p RV/50lejB "5i-mA.ĘNfa*IuL),R!5g}p^k1Ig>w8y79L=r&k D:g{:7:ͳ8@ԯo2y(R}#?B.Cd<R2ü.2/[4E gE!&YwY@(3ڱ0RJnK22L5=qЍ6gG?C%<3dR/YI[n逄Cf@U|TkglSC^QBQno߱"`.Yj\>J|̕YQJe/uWX4\M bPz#]}ntϳ.0DSգ{By)z",YؘGa]eT)qF? I<+$(jB//*gU sp$ xaa-}Ӏ5=%3uUbܵ2,Bpԃ=ߏSI w`._za$tos]yQum ci]"Bl2 hԏ~4PǏkg+ `heqDl4kgLUWp +S-St0B97i]]{QOw]/~Ӊ}aU|vqNcgj`4(jaSQ-n}U2:zeo%YFMͫTJӻ-0_f}V=~3XW;[?؛^61f }&ƈXWˤw3g{;tD'kZ<:յY4d&2V+j1"z\T "?Y6 _岀z_Z4 W%Y%U,qضWc Loj2Z{Dȶ & z$kxCG48#Os2 ;0o4h>q| X=HmN$8CG !,A.>_S!dP)hoo0> n:[jYCYD{\}*AJX`SU?3x,Ps L1c}^Jq} (" MBNwkMi{rǣj]kFP*`Şhj"Fun4VX# gCskۼ`(#HaA#PHeӻGLiw&t6N@b)D؂@?3 Uzـ%~iQ+d-\rU ^33WEv4`(dbq%&,:g1@! v@֒p` H"ER_b0;F =CtS|/i?c.SeYeP]ņ3Kų@ rS;jս"498-FtU\MVfD.Q&}5 P$Nj'I.r ySRAwkݳ|90>]?i^SpeMQy,yrpRSWcelqw#2P~ujߪOƑULm;h2 OACV3AZv pjpk?0'k/iu83v Kʋ JlPZ%QX,@|j D}Ε1 D͠&CuZduaX*<3ePl:h4Rt9x)?GԣUfk]xkG,Ć۾f2NCM:tSdpJ2nfJe*QYBF@_ա~|WՒY6;e=+:1 +=8=k|T'KϲYM0*0mͺ;<\܉ `.!caZF<O~Ҋ՛@ WU-xYb* 2"euL+jSz] V:CGxl!6SE>F<3="zlllEb/ӣ9zBN B`#fԻC=e is==.TA>Wg ;Lc5>*Bj8 >2ZúCzkV[ϱ ܸ“%s'dq{;a9}b:=<ٹݴDA6 v@~t̩^וC1+WJA^qŞJո,? {P\Z04oh[oJvOT&@A1\3T=qŐF+67#~^nt7OG% (SN\\>Y r$2D1Bnl%J?E1lMB& 6WԞU Ejf(~4,Qg}e/eᖮ*P\yscINZ']Pa7m-`:[Wp$Ȃ: a|mLE.6pklP>dq$,Jc!r"Qf~-]ߩQ[v8ukv],@!)Wmcb~ #m=G-ٳ<uv|fU=*e5P Su5(vO˖KCvj[ \ ҢCCM#ZwXa"VL *`ly,otL<tr~Xb E={ ]Ez3̻K01o pnj@ 3Z 502T:;LfL/0]bWb]솩 IDAT1[?~ Dݥ~A{\>M4 Lʳœ'l* uFa5%w`$畆'% *NOW~OHL?2OK=2fpOr"bl"ȭ=xl%T]qsDz}+U?;fQ/_[-`\F[}7HNѦ+SvHX+̙~d&Eԕ|*y 30#,o\`r@ ncOUBAH+HTjV@* mL7Z-/''47=٢MALBJ (.=h 4p $#bqd2hSL6QcB3%Yi5bՑ@Mo X0oܷ![kQ[DZl_Dz^ӯe{dS Ay l#RU d5}?f]SDPb;;a>2$|bwQtS51&|򩍻2j Cf}f.52qDަ6ICZ'T`0|}Nhp}Y~ZUB=V(n%gաIR/ gu-B~.=mj7̎66w.?ć޵K LG&{>.\^0Rb-k##Z t:MpћmtL6}\) pUV=wgK(G()hqP~Qi|2+x5A1Kb [tIJp4R`Gp"{ʍ_@Nc\W1G-Eً5_mP{RVUoa8lXP7uI8&\~`i6OcUB42XtxCM!Ӕtf-`eC y1:6.3(oc|;ȟ !^;8p®C\A@m!Q85o(Z=[(@gp[ؖg5\y!**HD5*Q- + +2>"lmfxdpdyl:d\xbVtN={d]+*L0e.))+4V]hX?jiX0̊.اiwA}. k`= "MHaeҩqcac ~n_)'?M=yJ^s_(ROK+t?.MpqT!8AR[Mm(c;q>SUk?X(}ms |][ =nNY[36t{BykYݻj#D'ӽ)66 vdb쳃d`'ɸ#[[h1F| jw`ZVIs/iWn_˩ՙ++MfcrCd lb¾(nɂK0lgp$?\Q&oGf+ی/ZȮ.?JeN8{P5"}mT|Xژ| !XJuX_iW 0R2X;[!3$O~(x| u <#. Gb0o]zcyJizdWB/$cllːuqTJ~[AppK?, -[&ik e#RAI {!!zWFM=,ߗk G^hodr{BtU Apr .7>YH_o1z6{ z:jN#~oGx+]v ;$o4er">+2RWwݨھ}f=ޣeh6tvWx6L'" YrtCܣV B> kQuAT@v ߅Ϣu|^,]=p.̱{!Nv֎[Ҍ]N)ֶyX]ͅh hsikc)<{:w= ܜnU F'bTRn:TITm?h0gV- Գ W B.I~LtQ-DmXmTv鎻qs~$SO=}phi`;Ϯ˷BPyJ#VGwN1&N@W)y Q\\J5?A*k9SȻS=j^5T,3r{oT_=ZW CH+pѦL{1PY&{A]ڃɨroCg7~ mעdxYoΡ T_-NnU, rcql l TA;Q#BLUFL2MK[ `)Z$݂at6NW-^Is#oPlQ-@O=*G֮jܕ/n Bw\v]q.F.7V}6 j֬hA|n,Oa ]Wyq+% Ts [:V糵u<{£Bp(&K/mxUAg c&^=4pּ{Rg:'(աJR TZ_Y.NJK]3ojCYA}tQn@+:Y@b4QfL?FǭG.b;8ͯHcPzDu\~2ErD&#)UT0@cQkͺF{,/\;y$vĕv/PUB\/TzV=Mi܄ճ?J}y=!{ (ƙ4|YR8[G.,܊i(=MshTgƐz"r4QJ,szu%[Y_W"U Cqb6ڰH-6,#o;+&q{-je` ԯ@7$3Q=H>{U,+]0ycO' b0g7j`du]0(rz DHIe8+^,9`^XjA20 mmߥ>ʬȊ*Lnhq8U7B(e.+QpNQDцDsI06Ü׾Tae<ɠ͎iUa4f:Dv*7F%G1ue.:rҰD)}GJGf/ :+lۄ%?4\IewKBV gk]VN;S?aedK:a[ ,sDt?&nV;_#qMc Rkg]}xF$^w+,]7y vy>ok! ٔYnl"km Zby6E+{=|soo '`,d߲0BʀXN`|Ī[YsG`8f o8@o5C`ň-TM R`KIL0jS 9todv2 G87>Z[a%ߖ׎S@66|!A#uD;G+QwUQ$9jGI)b*\-l`di]ӈo*TCG1.)㸟91# p=Gmf. +1f|t+@h8 cqL!eT ?d-cȘef\C*?4s@mIQhRP$3|sGVu^k|[kjUb9Epw4o}rl%3@l@7:Z]?Lj6z>ulo/8p%`@ŨRT\Kș\Y ,Ӫ.ɁV)E7P}Gu4Z Z׋-mL&CQer+H#9b5)#] ]L9cKq&h+]Vx}2i7U< C3 ҕɓs$|di= q5{sKZ&ee\w6@A|X5Woeو 9rQsI? 䜲1x֛jQ8j0wFmFl?{(,7{n9u"hG _ftG%4b* B%8\\_U3B M}߭IV+ •!ZWu0J`!BTs!-˥QA ?E7EDU C/a)+G2}=Nq孷]l= j_q4U{ \'9E.* Rw:|]X*WA[w.3xm;O.հߩe֌^'cU `B2Ky56MaqumNH!b 1 v`bk&!'^G2rc'{#gKg~7_oO}oT}P*uaUZcXzBVSx~q3] hʺNHJD ؍ژ"t!xJG*3q.gJS Gbsh[L#llOa%V⋿zv<-'T J*U>"&7x^i\42UnG|N*dpn c?N}*&B0z%I Z/=p̀xD$PT>Y:)sּMHJԅ]rJTd'ӣ{G>8ܺ|m|= lLᣂ 8D&Z*%71<ŖQ/|mu.E+oxg``aہ Gdo/ljJ+pLu:@ 0c}Tn;K[SvzI1cO^h|:F=hXjy ~8 .y QuPz wZؒV\J>b;Qs-DRPӦR/Fp5tZ97fnl&ѽ|%mݣ5E!?_G. 3TYFj9/xhx3g_7. /'w%\:xp d7t$y`2B.v%]}.bE2{ Hsu޵WQGT%yȩoH.NM DPr~5KlPZ)ϓ=m>C ( IDATSH_ aԍgϮZ7 Av,yW.'QœAM^10ak.E:Jsn !{+A>/ӟ9?7<\˓I<_ ^5 Y 6N\L1fMN͓t) *dU,*p3p20 RfolJHK9҇ȀFk7 X̵c7Lkdc[ t%p=ڤ T RFՑc<>4`>EFxk{_?;0!!kW/o//gӃ}/~[s0$z,ٱ@ȔID{k*Gf_7J!_"0V̇ubPpPZ<@Vbȍq J2{SlO(8],Xmݗb}$p~ mR)^fIH[Rp G;-Q>o?_ @ \`㿿ǯ3v <@JL!,o@Wqa*racFRvIYzRSGÈ 0mc:ۯP{9soyX& _\G#d'.,/€dB7*"K5,ԡNjɊdy]$#/w>t\F@ X.lUs@ *g)S"o} 0'gj)oIVjb|lbodA^C1qK:fCS$4<4r\*p>w0w @Olɢ/%m;O]>^*FU?6]^0ێ {L ]Q#)c,5p=+3ޡRO5#P5J0n<˪ T)&wPEHy 20ma:}Zu˯tf b9u\XR-6b;Y A OXJ_a8$Mt$>n*U*R8(Ɋ^)W@jQ] 4=c5 R#`Ć^|=k12_yFh`i]Ww)}9e$QYO<n\.GJ 0.auVb<#X/e(: Pʋݓ SCR*覚.9 =WTxDPgJXqQXAK{N:e84-lqm<|>xHĭ[7 *]lGx]?{ `NbZ0uIِyTRHkA$ܿ3AT N}ܦK.l ;.fyF#&3 Xx*YhV"8 d&9.4ԵkܳЍ61M-DWCKۄ2x_gmiB`vԝɱmYGVސMQC遍WNdE**k6nE`#HE2/ @HS^r_Cb;%bS*jCˮʽQeG۸yZyT=W{K xB9ͽ1>¡9?3w{)g 73ՠfr~ߪ 3LDQK#/id;؁NV6@!cI^W΁Kn` ^8w f- h[q HvǸ:XCƍws7>."3n%nKnG)-{jUn[:[Vn6'B@C53JjU#P7첢4tќԅt/IˬKa͡604ict7p F(GvrLF'LSttׯ~ W.nUֳ666O]tiGFF^y'eY g/"<P(l!@mQ|FSuԺ}QTb1P34d[0E1)bEw]dú~O-ƕfz+ i>mK/166fvkoc{g>o K䡵46Aat:{V["AxtA̚N7H3g>& @b,:DZmUfT=$k1ܚ*#"%(d&4#51$uYHU2IToR4ÈYBWd6ްIͿ0Oo?tzxgro| xo7h@+ 2g RJ'VE6yhn\y[PqϾċUu5`,B-p30K+ FKĜaE ,zEgoc?ND䲮IƓ&=W'j+IkŚ҈t#:I4se<շE@ h΋+W)l:vwE_FfBZ *Xs) >zH!"B6* :*PƖgE֋zT\嵑8 k൒a'24f @5L,TƐz6Iy|g.4,Giob\#_͞/GonYC hlT6 u6c 2 :7Va@% D_Yc'œ!Y3БPp@Sm( JA.;Pe6/yEȎz_2(lttxfv@]y%9PX9伖|# !8%$N,U|泙z'< PםX {'/}nOx03Pr:*aW0cT $P'FW _(e3ˬBzқf <qridp ,S2kG$^(~ `R Gc|Ul\#9 #A>sYieѸFDHi4Y<d5xú2tppq;]?n wɣa/xObsK/"+lP1 Q%xv^XfA:,M9[eaH$M JRYI`;gsִٸV0tAa>~*߸: |nuű-L&j%6FI/8iͭmL&7T-1YF]7fqjan}4`վADP YhgNl&6'9C\v^ Tޮ4<2W@U} juߘ|OslM*EK2;B=')%BUa`y+Kg l,(+;{ ɳkmE TERQmsڊ$u R8¾EX\*?hq"lmoدDV)wz2uQbm= 1hGgiz A=$?h9&)頑WYz"9s,7Q{z/*ޏw+5@vuQ 8Fp@ 5wk/Rv*E3ZK.Q'd![_Ubyu$82 ߥ$}g}(T@+#h3g%gEu:Ξ}D@oO0o80ah6ġ"j8^xc3p '4,֭OgO'{!jQAʓ uLg覝V(,(R-0|A|bdEf4RŠLJ$l0DraO)2kWt>y\~4[K,婛 Jai_WZ!h*cbIUn=rWz8ɱ[lFo*6$VEM0wUL& LF0*@htL;8Nxuy+NX0=ng^|ԌsE`lwLrNBrv :Pіdң+4+38ڥ`_nslw>Ӯ""i2ChwHfH Xg݁$Q.e2.QL,D̲- 2ĮL}|a"yͽk8b*vu`1M]%[@ lln77ub<@tJp_ŐR3jAfO2ĮFFI6Ìö;Y<(z A}$O< lYxe@v tg@%qYS?{nC' Յ$".%dE⭑ϗ: 69}8a)t?ںoQoHlfiMĶ蛋j!Ż(HsD ^qzy\H\&|| @~OR`3H.lFI9Hm6#T}ڡB*}h\+81V47oe't2qeylmm_ nI;ۧkV O=uk/gAGtHUl:Yauȵ)/EFl@b80@T&W2+9)p]-}rf)s5%Xe2a6!M&PWvPL:@8|@ODX39=x0,N -fY%\)6ɿ%3N2x)_I(K(c2he0 |F́k2~oXoo2–NSy[^ݯ_o."@ \u⎋LIiE͝j[-Љ9JdX50!v f'@ 7"A@BCbR \ç-zm,y֥:< <7- lɿ~D=%RD=H +S.NB^ thaF NV*vr(S;gqeZ6Kt [?V~mx77d~] |U([0g e8b+Or! JtPG^Pmy9!9 3@7R6 LEk] ub&5↚7D[")&z脲*!1(QfªŽ(*J`<>˸5y2BżOU봃`l\7?n4}|e9tXI VFc, lX( (9"*}l<$eےOx4R dvuu7f8{A0Nnb&v\} ~8\sQljgk\rIO50ntG<ͭ.=W?;D~8ԋ4N7nN ‰/t" ,6#LIN^Yߔ$ y; s61#d`" b;ckǵK`pmRt0X?~.ذ ⏍a3CB'wsTmdYG᳏b4JYr5Nedû~zm070p郷_/u?иQ{xR=" p{G@wgk 3v]GT憾0}ف]9КW_$B5pD*5;{1p99ݣ{0{ulΫR2o5kMԿ/ Xǰ{XH ݷRd灲\1ǸᣏꕳnͰU*R12n[5̪ f6A uzPYf/:~a>9=v\nHEJG_<֕f+ \NL C. ̃ߔ<*N.G'ΊX; OEWYnzs3'+#e%vz] sh8i"TsLnU%FNm`1H$yCtؘKcN3`;0 (]EK +6d{" ?G6)l:&,2;502.h b f,]9TA 2=r[t\.4mOtۛj{a2:aTKDE@U?2ت$jMdqЩdF%8,gg-\YK65M/I|i(1kěԎ[7_ViSCْW Tks1./̗C׮2[mo@Pn8@Ζ03dYޅ2Ueqhקv_^Ϋ6۠-(ꙵP@!VEMV.tj{N9~cԻe=cV (aRu$f#%*֚xRJsٵb8[!rZaSĿM\RhkDRȀJoOK]xzH r iMbϋ[Yyf-|!{N/"?xٌ6]}y?NI"XY@AU65DsJnEkYMsB``2}qJjavP ?$=ω :d4%a 4O(0ÇX*X֑023EUQN]rj]PJf+ 2^K"p7`7M>&! 1P"jDRwDv7Rc]|P{u|K3jTU iكPE7`_OI-jھu)"Ux]mC܌ n7 Ǡg( [7ݛ֬0Jz`L|!C PE lZM_"N5sVE*aQa;sWr[&HgN#"ߋmW?ʛo~._&߽Ods1oLp5]_l&z~fFz"yuGH{yp(9A{\H$-ҜWlY3̧,gƝB12((Ī1Na8 =iJ~ma Fԁ0^~L{UTIEDpK&GrE  ҤA4Z%@` @Bw 0|#mFx.olU[Ѿ$㤀p Iq.X:߇ c+=s!=D5J(Ag=O-M9WԇozeД)PPIJ4D4`AA $E5HwhՃJ-|۔d 6 b\"cptI Wv]΅n%pBoG 7zXgF H) A!@ 5hQ(P `@`nd 0{2x2}1x18`,ב6?S\=ґ){MYnP?|w~kzٺne 0_9J(=*.DVJdT&` U*HP VDZ  hhJؿyW04NIUwWvj?zC?ݏ0^Gus\x*180*3_щSO>I{K-,>x@kdP@$*AX-J4A hlu 0.70r;kC$?s2šC1ΕODnS\Z?NoJU@LV( fP% bRdڀH k׀5/8]R F1\ŕ@̬zO KK.ȻC˜_/E>_h-3pI b3gpM $J@+@ i(*D>*Uy Y{Nk G}ݏj|n_ @FQյ{z'Kv>|wZ4:[μw~z 8<^C0* X uͰt,YQ%blJ%cHԑm[,@_n8.قJbK:j"~'K%R hٍ; ;ߘ$3:ЕC3Ux .Bi)Z+w j ؖJrC2,4: uR/B[Y(E7<l^ ׻)YOӻ}Y=MQ|BөChn7I7 4h^H`P p ahم(?3$ہ!JxJĒy  >[ˠ?OaRtS3YmWt{V|⬄Mp\ $ Axh˾BGFsͰVļ%I*o*d|D)$EX3BMAr^F^͒me%ARш1cDLpF! H 0r@͕!)?3 `mЊ0=h9bj9  LE O2F%0nxu%MuuC-#g&Dmf|4 kbhq "-­"0QwƧ/^(êXJa=4a(Hp4fZȾƛeldWi̅ ppK5xa86\s2kW%p2䜁]pG;G@+†) &r3Ai$5x%M6éA `T.86;^a5bIx1hXxTMf-U pІpMݣP$t@ /DR8|x$ 0] }  @߸:Ryhxq{X^IRN 4bf %4y\q^wΥcΣAw %g_ED~9a] 68쨆Վvn~+'Iѭvlߊ( A?x H %|Q@R0F`! "`Re50lix@V&F3? V('>%8u:}V|7p7tQD %'043ꞕg<JwIxpN8rr0 N#Ee -ތ6Y` H.4 Q?2V \S-p> Ç݄h.'H~3gc˝x#6+U 7`քa.`U 2!XFÜ0#Gf0 ?WNJK&aB$*4ȋKbTipT߫^6T? o"Yb I^u:apVQȹM,Ա(S`YX9^ at"J mt,Ja6@,\(a q 'q'q!g˒f _eR|r1Ż>J_ t"=2ȆPOnva𸠯ο3؉ H;M>bDQ5raz9яH\  yB8wg˒&vB(I?plS~t8fp HH^x3AULNӰ}ܷUt@^z g&d8 JrlMM'g5sA#\Y$xp;-*$< >T\Eَ_G+(#z" ]9W nfH"fhT@Vî&(ˇuzqfGW45^ gsO^4p܄h ';j- 6a+`:^0ejwdɈ <`P>_5|T8,^߷1 Q>agv7 qp,F,lGATۄK/AS0g4A7ɒ&)u$_K'u{70M0Uϖ(ġePO0|l%I88T4B&lS6 HpR;a8HetTO,…}pf/TuCYϘ[,K-߅K#>ASOK0D%) :488lPY`0y*Kah0jóIxJŒL6Q%zPe 9ZN"̘nr/K(b)|Rr{:A͈ߵ᪩{w@n>X Ꭶ3L x?tIl{ 3Qj%|T3]Ntӣ)&h^X_[/f;aU>GpWA} VAq̓NC^h*PRI] F`J`Ty3Y,l–ݎ_zɒ-x*磋RA (tîFlTGPX`S `8=ҧИ&<恾,PԬR# <H 2uiKDZ'l [kN`\? JN± p`b(.QjҠ+ WPE:p+jRy"dd?l)&Zd͏u NJ|=˒-9^E3Bø[ vjrLsTC>n?9pj?P%0Uw=OJe^#Æt\t7Aibd*.,*!Y10 L=t HΎh _racd,1 3Wmx*- s`|(tp\V + UI34$kWsf'g.\|7+>s2*[jYRͮ#`#6GS`SJ$. 3Ƙ#1BEF3fp& Mºbu\ jW1ha-1Hò(*DL ͍4co z5^{ FCKɚw)^ysp# fiѿ Nr.< @ v(#:5x ymՅZm p`pvfC0ZN.c|r|oA<}d~[;JiX WC~%"!ܦ"@'2|i7AdJ&/#+:4?},!٩fPԶ8dd\^0x|7 4A#x0uh 2?O@jNv\V fF/V4|CdJ2qd>d4нBWI@ dJGgN."g&S4I`!U!)C0)I 0_ n*,IxiR`ZBh0 <~B.U.՞Cf>* W*ÕF HaNBBWݥ56J+ 4g D}i %MRfGn5 zR\0a2NJ[gٕ6(ȁ`0Jh*k^%jץu)8d^LJ]﬇{\ePk/lʅ[fF'I'4_>|3 K7 _A`{2NmJ28LX0#g6/Kֆ:ḂD*5OBAtp0u\נ-&rqD^}k0|Ksq_XW,,ܿJ߅V /D5us s]r&p"uмZY & c&FFn <d >.!:ÑGRvlHtIM㠔< } &D#a;x[IKJf(X~ 05ka0^yNfX UHK-ro;ʡ* g K)EP1؉H%3\|GkH} R_YH TEsj" tJs冋sE5U~)(Lj(Ki.` /|K%4tk0v Srr$t?|o"p{3X~ ?6qA|pE\KC,ԕrg(Ax:% ,1 #M`_ k يڍp .pz^h 5 xp|9J:N(iEFz#ka^5b xj!^0o%MmiLYKǁMǗ_@-Mlqff6   | N q`as#<Uxʁ]P< P9Whgn[XJd;o؂aK6K.7ŵіl:%I)t|X¦|8KI5FB0 \n@rIɁ[?X ʫ(` Jz)f9h&[fbY$[o*d, ߭ JD~0ǫ)ҕI(ՊȴLC] 9`UlMAŠs:MOA8eAnD:oli.K_2>slfIq5z>~[֥~W''a79xN.Sv&C R*hq0xR$t* 9pv* noٮSYNw`"i#tࠀɀm>N%`AH_'vxjJ#؎2Fv*Aq^Qp dFD $B&Bh[x.%ò.Z*ڈzb,qC}mЋm@H8"E, )esQGb@|H(S-A7lp_T{Nݰ f`"_zc -K_.$48o%^j,vR!>`UA0( HY{*O4 B@/Sr@󨬙W߽!^ J~d|c2RbvbHI2TxwzSjlKCy ]i18<t2xw1c@P4ĬPR\JHV+?BrI|}xeK/:>8;>0eCq5BچCAs_ | ( ̪&DU#U;W)0$ a)eKA0tH !7 p .KRm x-0pq{>f%ܿ4JJqfd.Ӄ_ U .#g~{j=Lh&i+ɌY!xV(ݶP`mX%y @ZNB<+ $]af4 B}>K#5A#Y+%mMIA3 d"2'm96B+t.:gF&s_? > 1A5KК7C~j((2f3 }U'ݴRng`PdxU%\.W[N?Rqx[0K8(_34=q@Z, S'w_w||l+HҴ,ۉkvD<0 ύC4Td !0PXM$!mÎ2o>MBt#ܕe;6\j@ș9)/Wdq'aecp8㦛gok3"v3M;,ǚA_\~ bƀ cpzSj)r؁9\𔁧 UГ /.h<[7!oGs^ca"Nݠuu|l]e,ZH{]ތLƷoJqC>% աIsg@kA4GsΌJqhK5w| ᕒ$ܽd !0x~޷>>RBJ 5!J.)Z6YY rZk{Os9RJxK\0bEѴWMBW} h5мaN entuZ` T|\§]$s |?6, IDATA3ȳ{O"/DBq=%pʁIS. !Q GY(r` _M?3Bh 3}ʅdl]\ʦ_)6մV E-e6\,WAPS;+єT 嗮+uk`v4_!$0{lj%Z>K_ rb[w^ +oAG. $)0RI<vO@l(_ j0& ! Ka0}/S840|_cWG%!44 n1aҁ0X;0i )'y͟4CyLL ֬V`14u;l6T֒l!t .gFF=N;MkZ5N\t=: 8EMpIG5C8Kv7F[uI`p%Pل>ptUDtqF=I2`#>H(.`ۃX q#X!`~ kpܣxa WHs)S-^$)WI;"y8 >lknCT, Q37n Alu ."u7K_k됶+͆@ #@fOH}Vσ ցJQ+!S$NAV{?#9 %x?=mxJ+'` f\p`lE,X?bOwNcNhXY;06?U?J```{joF\^0J"2"9aI5lۅXCs?5ȪDƎEodZKXf)ZUW ,zDYH-RPZELUS}صŌx9&J*ABam\5`6U~<w~%K>08m !70|Z< 3 X2@sR׭T.T t˫nP;A^TiXQ2o2F0[5⓽t0%~X]KZB) B@]PDkGSŤ?[(ԃ\94;_ Z*2EDݭ' x:CY<$-kPODVp\Ә OĆ\(ȁ㰲jTob0Re[尣V 7SHvA 8t c~1)jyX҂<Z\p5YGeȚ/d ׺/{AaxQf5w3bq,I ]B\XPuuI7j쳝вJ㚛>6mdkabB-58_;Hlm=LǣHm}%]W;h/ pŠIRH8W,!aCZ?A)| |e@WRp"ai;#&q`)J;\M.0*AyQx| V6P/xtsGJ6x XQeϻݸ3]0:V*YS)t5RA[o̩O]jI*lٖ:Dd]F4`E Ve]R&pfFef+G*X4Lϩ!tv C9(i@l-yi8gMLj rv|-u +CHݯO%p{09H.fZZʀic;~e[ Vm~߃ /"۞&qK(%4 ulJ/Q a,_[QYoN00 r~1\=\aW!l0v`6p8iſ<|d|+q$[1'`yntĞg$g2`)a3C@"]jV# иKI<ºX]ҦF7ƣ5M%0f-&RЛRIfߧ7 ?9Z6@2"fFV[CЦ tn6zN|K 4,N† . a 8Ũɶ~&9;\nJv"mß@j| nd R4|bMhAjqpƋXoCd:BhG/.e]Ѳp$fdaY`ovЄ$v@,WݻDs%̧a97aVXN39J;.JŒ-%'tpd=mm-SY)Cu9^UUBYQR=p ^dJ}]/>ĉl{5txg: k/Y /Y(ذ:•6"I tS?~ׂp ,xIS\ ,p /S]`&X{z)±j2 &xʊ+G1;q ԮF-rgFYc[qE@XAoiD^IQw4$*([CŤauC7?0=ǯe{ -UKEӺ{q'EP m"fFHj:O:[!̌RNn֦aP"̻OŦ\JjuhVDpXs+SZ B`v)Ka+}02Q^Hpr]i bvD^ H6i[fI*U/C4aԁ^]Q;19#@җA(vSWcYĻ6t[)vt80,'!3/ /H$eP2=T9tV7WP_s/gd>( G F%p F0ɐܝ9o|t|3êŰDY#+M( 5 _d-Q_@db44@dmqf]͒5a|̴zf[aeh<8%_ihr}Iq_IOZ[G7@NSwˋ\ w:^v((Odj+S75`|Fa* #@SZZiAύۭ B{B3A B'0T]nZBLӍn[tVv۳Iwjq`׀'CI !8]`ۆ|* Xc؍0%|lL4N@x DHO܇lgcBp)#^:Į\oND(+23H)2;4Swq‚h,\Xêt7,,L{B ?Auҵj淡}6k3 q}DFH/@>o* SJYXi\\E7n@AfJN. jkcqL?=~{1NkW,ߊv7/ _a3_(M7v +\C1A/|jZ "BsF|*;eMH?ܕAE#id>>il=?Gf@s,t-"z\C@UM G46 IXTΉ~X-.om6pȶILPuA[G[ y6\ pCU J rDEa(Ƽp6]WaA.lT*r.!V _'LU䂷P͚9*Bj&jg>Dy`'8-ɷ͖H!ova! f4yvCQZ>7WTڦwz'p4#Nc^^C"6W7#owgc;w68fF!u8kU自v&Q%Ò︡33%_{Wj686 mp81ɣ_;:m! YPQT6D5aPܪޛe5KlK'  Ԅ ;30 00|/$H%q؎ܛ.w^9ǾJ<NB8l}}^k}q?C~ \N|:\m@ ݨ+w„`+Y굲vx+O5Asʂ 56x-U- ;put)_'_y2QEpc58u Dod` |#!5%0raHi `FG ֕0t]":;&Vq2r;q;tEy߅<:w⸜^/dlXt&y8P)@nJ. .wD(Hk([Ts F5V;yn/vuS5vBt $A:~/=E3u<M]':{i# j7^S̑a2&xt X#{Rc#΄tU:\% 'Ic^`2 5,=#Ol#l8*4)XZN̖ +G@bHG!K 1ԉ7L1'8}$VWB3xPo'u }Z\7P ˂!i(J+D^B̄It'ThY%d·`C֨6dM XzN]m#/ qLh'w冈.f/yjnOݚυ{_y ߼|8ln%e4g%%yvR74KRPhDP^ #Rk_^r`ǃȳ{ӷ4҄[Ӱ,[@'Ch(਄v>>/#,U 6}xL؟pr z`|(#mE| lEnkRNF8$` \3)& nÈ&rA%WkWGx *c/@I% ی)4N:iM^~iϝ˷%P'v}HQGI*TP©A{,,E )@;3ba0='_CL[qMz:12BLP #ÛtF\5aY5 kض!ip 4v2tc'XSI,f+4CTp.EN 5G 5󖡡fqrgtD4c1ºAHhq4+NFQ G8\VB( ҋ'NJɥH:F$eB / eʌ%ˈ}Vyk ɡ \%W^ #~J֜2r׾lx@WN "\v,?j0?jf%+|4>E1 :}5(]++C1h|L%pcTJ2Qh̜>KZp=H! 9^=.@|x wó?ŽGhFU|ǀo2n_I k+EWEtx:08m &VXRAؐC[y& a&lAkn5up9j!ٍl|q|+v$Hnpn^14J[ryf0b1κ˕BS,M&A@R᛫`^ } 5wl0> fes!99,Cè M8Sa)({򮕠$Ʉ8i8ù[a|BW&x#keR))YUDa v%@k¯ xG¸ܫ g>y] Otb$HiuZM؛7d"R3Rq8#&tTo9z!X ZA8]t ؆1]pOJuj>}r Ris쥛0-f N]#`[SC+q; "/Jo7MS$ӒնiLG!.ÅpyRYr1T6HӌLZeU>A9OcKے/"X`7| B͊CQy=cyY7jQ:{驋۽g'?A\+F~0JSILMáD$(%!ݠWZVqz?yGSФqb˽8OGu+N5p>28tĴ틻6{Xт}G0 /xb4:h:2d#O~߭cg(4iStl hK`] ~TB! ?sq?)@"'u$ۆ ,"?gB:4AVУ _:ݿG}f4ARqجRG 24阺ו;E_"PHKlY)٤ρ9:|^5c6MAWƃ_+1m5 MZ16GdXp<%@';=d'S{H,Mpmq+jڍlDaLDꓡ, 4yz7eRgD=y@MwF '0SEkJ~ bB۷ó눻?g1"6|{3 IDAT8 `شp[6ɔ.ڈS/F<4R?5 _B+̰,1IHn1cd_I.x"gve6͒JF:Ӥ6)2 HJSsI(L AO,' 78sVLӕbJ̑M!>jBW,8եE 'd|XYW Zã3{7BsW/GP'm>-tO'iu0mڊEsh ғ`F2 "sF5wd1J&h]#gPtyM~ri%ۦnR˯~WZ79û?ʘͳަ1"MJ>ruUxk@8~0[ (gx k &eWg/du:ފϟummy%s!7ߙ 23pn?1^og= +, +,'#p AnZ81'x( }(kw59nX1 f/x YV{av4lu^)p;p\?{%ZW۟rb0 |r/3it5 [<2~pL@I]'xr`lV VC\W7v̄`=.zS b&YVkZd<اA[)}v4Q{]'tp^Bj~+*ܠn&d w">Dr??*c b_qx. $m^uM}?wſ^1JeHA> 򁘡B5@tB5(_6(Ru1G:E.,샖6i FZ'{&6CP_zNl#*ͺx ?]+*^`|2ٸ8kA ~HL!z c<*|p~u:m:|jcz{0L7LNW,(m8k2/@ dp !8k<`A.¸}9ܖWN5_czBbDIqćChX9}\8 Y 0{%lה ߣȪ'a D`\4 fRmC;ce |3>=nΖa VVVw4; PF0ܜRN|!ĥńYVވHˁS %d/. :ˏ!zFI!愈OA8Ё+e,y=U 槂iIGWOT$S=,ey bR &pލfK: JhM.0'i ״ho`b_Flw B`Gh#5 "&\V3O/1n8>?](F7$ȴL,,pj,s)ys©.XQrw9*6 txaLuBcR x`fҲI Ne'W//S魜#ǠLPU+83E@0eΆDkFTX[WKfan[|3%P'%XddɅ<Nip%'2VvCOs'`<fC%0w9xSa MӇLpZP9лP8 og|Yev[2ͥ|U\TAN@HY^Q%S 4} *Kwy}3dyO=!c@3Ow{ь>G(Fg~n-jV`;;,s>n1MMJvz`?x)0FQOrlDfj-cA" bu ꮂ΀M. *UT¯$HdI1IO?J 2 (mi l.8; .EWc-X|Ó:<sz,Z gc R`SY`B1gR_P=> M&Խ'R91yC(|xoyv=Dؕ~Mޤ_GJ s,,L4s-;A@S 8ǚ< 6lDZM'u|HJr,ӌҏ⨨JK`>xAπd%{&2V 䃯-U$may)Ix:i:!WX;1D6TEJ|?Ѣ ’ *\fba.1%3kK3t?] m>OM mTdyPW }pƩPw1ӭ}l.TX!MXf^.PArtѠS=zwCK#x;Yɽ<5xs#H<4AZb(@sBQ |e)arF`z,] 1 Y\m۬-bJ(]Z.6>X^ ^zr=*[+mG>z4 nUh6 t:7 $v'X#ˏ9N!xJh2x@;`pQoם^8CAj,D ޢ n(A,MHL^Z,)p. ON)^ܒXv5"e .`[#`K1u,볕 |,H MŰDca6kg.N6mR7AypEj vPe<3(v"͇d~w.}y0ј Ƿ,3#z¥ln 7BpfCD Yar,BT*3 =S2i\XT)+SEP -a )۲% %9Ы(-e9` n†2x{/0z▷}ۏvB}~C㠄CBRtr7H Q; wb`V"ҩ*Q.0Nl \)jd8:ʬک(P' jM}g sN><0<P4 3p x_'.D^%4CI]֠GNÒtS86*yL_n{gQ. DžUx-"iJ7BV!ïMؗ22d!aχ@P4wQh7p4m=oQBHOsi&AGOG")lh Y+ ?v?<M ^_=>eScÍRrnPVZ(*s&΂BLfrdFk|TMo.{c h  {%½_\G!I ф[P'Lw41=bh21 o&T>vT$~*jIH`''׍cZ X)aP(I;x~ ^ډC-b\+llV> "f\h|[> 4R|WJxSɬE}':tl/=z+_@`>kZZpz3RIGH8Q@{q ˧DWe 6&x'EA |}5: @cb7kIʒΑd'F`N [hvq9xK2_esC<ʭe ɽ,DzZ\FX +Pg5v.{ bag<L,4$! exBS m&<W3 'Hm ;=*^j  $ՓWV`~cj~ j^G,NY+Uˆ 87,j́"Ԗ~BB/Aú\QV/K~R׊ W:$  `\Xϥbnp$ YոS֩ҕNr3AJ0*Z4:10Gಹ0Ѝ|aӢ <Ϋr2m,eəٕj>7taaB(Dnb!HкrkߎEO})%5yku,xLQ 1qA9Q%3I\d2"ps\RS( wаؚLB/GTBn) !#22o4~<}.S{q*RmHϻ(ShE *EQ 8mq@ ^%okH$&$530ꯆr/Mx6o(I*\3 nd8ǷcwHė`dJISHz` :'ߏw3Gj}:#ŴҶfcp δ^Kr$lf>5t!Vu.xIBR 3&c,M.5mп?Tmk&"K/y)Ӑ\x$4 ~8 v^A8!ãx|GF`|ɁTK)_ ŢF5/hMO=c A ldAl1׎@C;lɱXΓÙ_ؐKЫit V/@Tԣd1 2$fĕ$Y2#=P[p<nɅ^(4ÆIxT^"͇H"t4lȇkc9Tɉ>X Aap7mGh4~*Fsp |8Il Z$B2ٽpm,*AYPnPVn `Y+!UUM;L_+ׂCˮ"8w ln<nʅ]OQfrn914`tE&tK V#uAw`G)-P% #̄ 7}I:r؉`tdLL)+a <(tܰDdg%fqV cv=v7@+Raz%!!G0ۏ"nGa4Ȏó Br [+!zKдWUKs/J<PACʰǐmh[^;wu5Өj +f͚X#a_RF`kGѥ앰Gڄ?)R .pP& *aJ(_%?rfR=j{Ӱ/Ɋ4 <*F#qhHߘlP\/8a#`a$߸wǬ|3H1-pCi5)|كx6ArȫBI`APRj;*zۅ$s£[q*UNHa33sӡa L_]9|RWRPtw#l1 `s'턂\__V%#ȧ ubI1\&!8膭.8e:,lP4NM=mH"mq|V!FQNƱ7B%Zˤ&oayx @}m@h.oljK_Z]r>%!8 @Ӛ XUWY^tz# u+ n% .9@J[$DD—.pf7 8<ҌL;!LOUEIb6U#&CDvv/1t4^ޝ|4C]LsWUBa9aIDATvCzUCY Z$DP'*u .*f돏mMpXc (%0cś ˦!Va7`<EʅZO;G2Is!bÖv8xNm,pz1SӉ#Dڎ#"JXY0L ctMЧ'_h:/T>ȡNw+jA֗2KÝ亓BAuK=qh넊$X*j1'Ye[\&4 kK ,N`,{^Cm@.Z]hFä!4L22;aw2%%fɚt`&55=GGB׀Ar$@rȏۊc @ӤY9!$8 30/y &Yf[\):jY\Bh])C# 7vq59:QYXZ4x ;bP\p3MȮ]`?jLx=(̙ !Fs%##08TUCvDL>84,GSۏQ(4fX6=(ߥw6[2jƙ{Y3{Oue]֧NfQ+VeM#%an$UVG2ȕѼ@^*|vcNZ` B {}1(PQh2á+\ShC'Ð] 7BN >7(= 3Saa-bm#Dвj|24_TKo[Ha"iB*>t!xmqGr&?V8CI[fҿ,xqn0!= up W}SXa&ln!8"`;pС&_ߝp̕a&oyKGX>OJ}S(<0ϹAJF'7&BmTYpe%,,H;!u9ff_ ߻gW| B1[tקdFbLZ6ƷppDCh'd,r#l2m{V q 7>[;g>ԭFœKmQpI,5-tq ڒ2 |JٍhhO/NjORXiDe;1? inipBƃ2{NKEl΁:MeBJ L͝a+2H|h\A|xs[*< 3A,J)RHG?n_)mЗJs*YawTJiؙV-,-fsc\\QضEm"y4)86օP> g0/D1]~ܙ0 g.8ة3' V߉,N̉' fó㘑(% J%Ik(Aܟ kMFp'`2+++l3Pe#?C 1&] $R#2\15VկBenGwgկ('`ɰ!8=q 7vw2 rIE7#V4u4YP.MsxCwk_?s];kIS#q  Yx箐6Ĵ-H/QU &A؂Ipҁn=Ӿ^{=)}A7B\6lIdX,?{+ oH/C3SL'>[VLpa%Ո vYŁ!̃"ЏKY 80u_!AjfUz3ns4΁KH"pWOqƊt'H$}KQW@FDA%2FL#FR7tȲu7t*X"a ؃9>BD{(n<Ӂt¼ %O;XBvF|+YVk *Ԭ.@Da(0chA~"7z#dDT () W"(tऩM_Pi*zL e]J$I PV͛5<[ +4=Ю% L 09< g*t˴ieE.z;>ygRG]VڪFyNL=7BT@,Mrp#9{[-a\wՌGmR06HvZ.+KBN,`E |J@AgxDtiL'7QbK^> ށLX5;=m# L(01.@)^;c_*GbWGkz'!X|ˋI F+n"͂]L%_ ar@cPzKSc1TX^M̈viо + ypW>gy2FnbyW?{NIZ>ˮ(.Í1CmQ@`]m}XoѾ>WY:K '@_qp9XS u0~ W0@F-*QrbJaK 5^g a]*@a!t 9@"׭LnGOEek.E %%ɥ[ZJSa݄:5 iz a\F Iux*i*E)8nF=}A^}vXlE٨e+K5\VLcڅ,"1"= x #plCr$-2:12 ؜G+z4A=\w+_דأ*Jg/=."O"Gѻy1o|;U>~jX#L7cz1Ǻa0 ށ<Cm5=Jmնi*W|˕>!)ky^ !xdf[?@?3vo2v"Ck#O`cz[j뮕P|tQ$BE^ߎe}.((W&`\fTT,] 5¬úr: "0Sm.zSI'|xx)\:_UCp<iMH&C A(Ho mi}'%b-B׭6xuĎ 2h+8 $of9/mpZ9TiK#) !|wNA@Rj!ZPow0Dk%R ljE8)%_3$olD|]͛}i= |z7j"p, Qioiiw,> %4P gp㗒ooMP"5jSl6KRp'aa%d\1 > "ń=~LA<sμɜBO^؛ه[1C1nr`R|Z\Jj + 9p~NF#AeYP Y޲Ϟc0ìG ~ ~sH*P-mҠҗBJQb)T|`Wv Aj. Bp>?onCLS㹩~4v"[ V(b1rxrKx"/@pˈ1]F-E(-&+2![TQUg?9`<>nN3! /~55L@J4x}7.5&#>)%^)Hw5MJʖ6N eVip!WpTt#Ox98m+lvc4fNdj%b ϣJf,w.7s w{Bk;x) AȔD"<idMJy՛L57ҝmʀKmpU^6\< C|ogI JqgZ6 n4p'CI1ɲ6H- d:ՎXb Wd*mvHJm?y~:KShn ^KvHD"D$"Hn,IENDB`vokoscreen-1.9.0/pictures/about.png000066400000000000000000000156211227001500100173460ustar00rootroot00000000000000PNG  IHDRa0wsRGBbKGD pHYs B(xtIME IDATxypŕ?%Ye['>66'f68ǂ& ^R8KjCՒ솪llJš`g9 Vgq1`#>b|o$ȶyf~S(k3~ـ>E׳ ڬ,Ӊ;wRu0F$7 @fɭy3gf\ (Hb ::YA<^JC)1uP~aEHğң  W ԙB=f -؀bHI Z,g82ǝRq <|:%pdC\;w` PnTdykB(w 6 L9k pZ= PHЪ"xj9:rz.gf~TVYNw#l(/.@`ɨ^Bl)B ӋЪC,nĜ ١=#iBH)RnĜ fe^}L79pJB@;jCuK=BS 8j];@8_+UW{̗qL98Djz7 E`L7Խ? țRr"3XB΋8ӦV&AX{.=l_jܽXW@PtX*L˨e@qzjsXǿ5W@T=UZ_0Tcw7r^l& 4VHL:k&9,vqsUAV-.q Zd{y `7+"7C#p;pRA[aE$=>d.VH>Fgs2o 8ZLmF{"ڋc;M溤UcMYdTvðƍxڴv1hhj3:VԌ}ju-6, pvBZ|B3j 6lZ%ݞ839;k\lB=ǥ]M>ǥ.}N`LpnT`F:4!bȇK& PcFiE#\]sQ\̠])C{"@i+:YRRx\!b!<vG)-ؽLI&1 Rldr/3V}a3*t3᱇VOUx^N>=_j"#$K5uױeZ7he KLG Т8QJ8[sV&p4!f Td.Uґx#kdt{{bey[-KHH%kYfHdF&R|R\s׏2 #R_m4:J(g6*LJ_1ZцT0ZeE1X` # CcM\ƤG{"@YFF PrT z9r>2sbZ o2/&M6L2&"Z0yoi"1,4`bSJf^KFlߝDF–c:ٰV5uWsk]W2%jMߺ: E/wI{T Т0MT%&r$xC4iMZ >2xU DU#ŋx#\.~b.+>ʶp&\&Y 栁Zё}>V>$0XpI(72DVܤxPzlcURf>Џt@>}(mf+"Vf l襔{aoUnG/ԢYu>Bu΃90X -JE` f^_HxEA%nK_"js4ŽĽ!AEiԖި( ة9S5U2 e[9f`~QawuKl ռ;_N fb~,j GCb= X8<#JپH-G,9 V)Qy:Fk_o` IEEZj6G.r3trXQ֍֪+ЃNm+!xСb5ٺrG'YܡfRI7Ef_=[=h")%je[9RNUIC&51\_K I.|Yw{ W A+7He5s8wpAHs`3@2ٺ[ZjmQDwff%ٷ dYvjqF%dwB)ĂM̱J}&Qq깖E΋ DpUhX\ᣕG ղOѪA +}A@^td$oF $@JJ iy7.CJ2}TrݍD|A(FXP/z\cFҞRH>-Č}wZZfkKz O;l]+`ɣ>Fsw:5b|VK43W7pYn:ݔ &46(Uz,q3[G-KZuP"}7KCjJ"څPdWk57ױ~e>H u4nZu2on]4t%Jt806h(QXiK5t`Vd)WLL j i=>s@X=~Н 2VF{ R#=ӢZ0;Uv r3|WQa,,W>h&7P_2Ųyovl_YNB6O7{9*NR{ l+ȌB"RDxo V هPo} 3M [6(}#cr(_{ l_cW#>aXk4(z E/SkpXX q4ĔfAZNNYPx@RK8b-jپaʡfP#o60e] JKKtb@p*ϣT=w|%_yzna2p3bj%1կFRrxahɇPUY&D`dN~>(VPi zjUzqD-G Ͳ^_Ekm)#΋0ȑl]3bXXC;F8Tk}o(V{]kWZR 5GQKM|<ٺR vHN2 j$jjՊXXjo^UuFtu!xx+kN2wu0Ս}mAkg Uڱ L֨Ԭ=7 S~J7t#SkYq 6>ڏ;[{} ,V!^^;v/"f ڌ6oܟ ʄ h$(q:A~YQDI}%:{#a7bmM-ʗ0LYviR*ZԪ 90${5VZn{vKRBEyUނgÁ|X-ФENўTu&*wsٱ&PeN+˺duBI.4a.a_f/P"w:HЛiIaBy\U.hs5Y S E7uy,lA)BY-)\ZHiQ5h(F6P݂%ϵ̭sؤ(d>깶 I`d LNj/[`Ы/2aZ<Őp6c7cD8Y>8>8rE@+h֚cP:tZ=Tu3=^F{B1/:jǘj+LN u2WL1ZY|sRi@"Zx(vxA(Ej?hW}yZy肋Zc`OD{H n< Ĵ=g))VF(/ҍZ]AҊG66B_Ҭ+iQ-ah5@(&CxA`ƀBo4cT2˝K{9#k?5P }ٿ'>84S4ߧt0RйC!؃liQ;^3=VDB1[W-uG%7QDr~bJEb6.f%^R7lj/Q?jwyzK6:Yw`e_ 5/yi%ٷ`燄.vA(ɩTVւDAf:p ,Hf D$Kb)Xۆ1ڟpKr{ \xT3Фvg~\=r@ɺ[HMhb56n9P ieV@GER~,"^oVϗnPc@ Ghy _Z3W,rO5ZJ3Z1 ~n0A'54TF#Fl3cWC6F/yOgDx MX ch x#MJ#Z ^ޤ"Mnzs7 56ED0ܫB aY%!7ldJB8wrA ؕ\JFX/{~]LfK~{g9{,ZGB-7Ày/09P+ümq^ L(d]gHbxW @,f)` ]C][544ٻƹ1uN`J,| @0M>84BXwsAdu%& 0a媑3؛iX%!qLkݳ3;blV=pF xYob`sw1F1|8 pn8 êl@ gjɺ9\Won6st^{Μb`O^,&s-O@&ᙫBɇdm-Jy9$\Â7",zُ,ׁS9V3OXql0ab<|w;?ljsSOb]?caΜ =foKK?v*z8s60y&ƽ|hkҁp?m0M&n-`nfo\r6L6x{d_$)J/㿃Z)M & ܔ/ I<\6ϲinaϧLxpť؄|lk˒naXP6sxR.Fx[g @v *}ax۶x'V#n`7tl_v(XvD003''6A7-$msP]\D'F{߲\NB$ D'F XpfΜD'V`q&@nOtb:*_ x&xxKp]p&x@H r`>M͊q6H<.D' .n&Jtv':Ag ph D'6HpWfDoxD{K{a>m1!mp*ܶC;n*L^1&':17~P mv<щtmD(ulBx0mWzӄD' n.|CnOtb6-mJØ`$ CNXH:# zF&T?5PS]=`"Yãj]0+yF'Я-4 ۤ@4h%#6Ij+/2RŖ3Ph?0Iǂӝ[m?‹VnU|Un"^nb7E)ˠ-ۖܢ-$t*ͤ@reR +iz0Xy 9hHӬ!b6L2հM-g8⥳[J(t 6EƕhEմ$ߙ0sy NeF+OPBsp_/㙘cBtX~ Io , Җsr l.̇Vn_s(=^oi$X~ c1{ǧf0H&l_"mV_B{Z%9}yWga5ɜgM;)}5Eulþ5b몱37؉̙{w`2XswYDwOj?m +(߁DP0je^Pم;Q[G4_똰t6^˜my<&Ik3XFp\[2;NN#5DKt3cD!luI}[KfYl`J:>u3R>$|IK:tơ$ Gh ,,1u$Ko0cm ~me Hw3gh,( I!Kn 1QJ1"!O}+<mVR+G4)5O݆^y= 6ę}gd$`-Еdܲ)S^zFDpCU[Fu0r7%$i~-H~4 E;˜xS U܊S{\;uUOX!v'b$v{/N3Z7gg k!G[쀘@5E4w@2) &ә0c}DZsl]\}CĮ)qeH%?ޖ~Y;{[Y.,EUl_:&0zaܯr[F4Ǣj1yяM^cl3h=y_ `|u Bغyyg;/HeD6хİh/ޫkkh'szn!RXV+1OYhʦ\s>]$H$-6%s>W_JÊ# `k::jdt#C'âL%h25mI{S `sƘs|J+@7ߟ ç;{LFX&?k*kpO;*6gHt{u"[WdX+8ܴĖq;IJaښVV;٣!x7\a:-YHϐ脜+y)ʜ߁+zdZpH; 4:UJϒcVؒGߊm+ʘIth>"%pR) ~|d&IVޟnJ4c_؊)xڂqbHtqkoXqti3Ν=u㤴 O5s>ba&۲\n~k ;4U>-:cӣz3*'?+ZO{Vu BLg k[YAl0L&ƋQLY䋬!* EXr ȾC௜(-0_seʱ9I[ ƬZ˒ɡzMt"ݢ#I8B\zɜ߉fUP9*_ 5]Fs m]A=1D 1C Ǣ\_v¡]~Wn!"fY\*?Y/}憽fmZb5;Nҿ!۷yF}DDu@U 8]XOG:ۣ2b{'9M;1s }Dlc*!vf٣fw 5$61oudF|Oȑ@0;)D}[v,8&5쟆 Y *O>ivd _]"KtxͰj{K GZ/ FQfX3NCNyOODLNٱBA])DRDʕP1f ,3֒JySWuOwD <˾{b֯o=FÒCpG< +uEחGa`mLL)UiYnXMXW^3D,,tsd"It$S K3>9bz=qV9X=j&tO~7GWKf3ea[Xf#u>E3;:H)`!RbE 2p=,jj00ܱT0CiC\\=j<ϑ̬Kь" Qh<:TuAy 0aUc5%HuNUCefcŒδjnזݡL:s v"ڲe0cхVdXr&̸zښ5` ̭v@vҢ l> J!ƵG2z$o=a,yW>%rͪ KDl:0Iǣ}F%z7cvB[b6t^a7AFV@Zm c6-2T hXZ8=! {u9%Vd0Qoƒ+,5,-qnP]wU6P&VڣzG3Q͟DUM\/$IҎG)%wcA !밢Wf}Rnk$p)G̛3Φ%-GG-^p%"o0^ִ-3];K%[vLzW:vTW-D~ŌVr&Dhƥn;2:[CjWGR]1hzED hLόɊXo%g}cG?6]S(L\Ig V!;DGJ(-ɗ -ۖ6SAvknN8F`dw|7nHwU]C9h3 ǯ WGa0T&_d?ܶ$Q_] dq(>;2RᒒJNխ|3~J'_#"FH--Gz߰1]VfIZfJ=?,58c[5j7э$ۂu'Lm:-4k bp%`E)XM.6h5! 20H_^#ͧl+r}/P P^NVeA:|mE倸瞂*暑` b! IIo?t{)mSxPEUNcuQo ,Bt5g?݈D7F~Lu`&AFA%&ؙ0}؍"+17 pgNN F{bɭ̮U<~aFrPW`F/;cb@wWA/2R$!ch&C߬򅃾`zϒ'o82@T^#Q` D@{j~' }> ǃ5ߡYt mۋ:mKfGF@*&AKeVfB\R hc(_|ņDb g֙ɓ6>co '%ngt!#INeCTem;즦/*vNܷ1mHT0 ʎJuE?թ{6ԩPic*CA'r!)3Q*8@%Ƴ=gF2va?],rn`a`C\ ($ͨEÝ[x['U^`5 }"3kSԨj'E IDATmJ9UtQ--ʮ4 A/ NaNx~Qf1/4q0BW|J`ZymA..#zm2 . 8OտRuVxڪQWk.nۉɪg-W [ |ܫ8;+xwx[@R\ǻ+kS=8W0])!vYP.խ"*k浌SWumc6ߙ愇üZvkV/}M[woBMa]%Ћ4PC-P?_n|k6H>EW,'B%߇_A #+@uOt@ p Ikik{Vu{AmU~E|c9c!KV[ޓʖ]5:GQzDI x,`4AW^o-9Eu,=](*b"OPs88}gPgЙ3Џ'H'o|ƪ$ \-f5P^9 䒥sD]7 ΁Qz֙i 2R`/0 Zeײ喋Nz0CXN&LYEժ){ QIb(u2$E[?-Թ׊뙆ez_]7g!jR|9MruLg3homWjt4+9?a! 'Nڗ؂%N|~tpWr!6G?,P^t+j_Y Z~`umŠme-hJ_-&O4Mj*[X{5Xs]0+usDdQsUiſSl>GRuJ4%Sx$t43 M T\4i|Е6#MuPy'3N~~݊#Z^@K cF>4p|ۤ SG}&nyϡ{:I5p)~3aA1 H+(c` BTVSSU@x!%O8.aҦtnMVe j`Ym^@0: mg*̔Dp֙ultQJĿh5i\36x9qGu d6K?}=ۧ4t,c[fWMfAaJ,2x@a)}N2z4qS=Υ>2l~a>xl Dmi}r?`6|j$i̺󨘑2輆EǧL4,Mۍ0!sk8_E{Qs`Ko`E8(WP>AjWyDwaBt& Z"qD =-&e-DbU]'9 G?D\AcDDU5Ȫ?K wn\&^gk;C* |14%ź[!zxt4? 9{hHt{>_/~×BVg֔hn?$yF/ _×-?:]U f7mN= ey;D`<@n95ҩ ;E T|_vMJHH: " n{Ҍ-.؈lN "͌ihuej/LKt*/8\X 1(tO J\"y{?o/pQ>?A͡KQs/8tzI얉1 jQx>]nt.hZ{~5=;PDl0%t$'7hu%jKze]:kYP. ̃PBDhAc|?=J@ R>E\ʧP1,m=BBhH`F8ꊅ{cz\GUŠMheuZnMOW1ocD &3C.hv W-1~Ng/ ӝ#;SւHw8 jCNkvOLԬ|['"kO=D6fn~wA#3$)e.XLrޭWu.J%(NM]9c`?H oȚP3;F,sϪ7 p,oۼ +1fbښîHHKko =OQ:%Gij+[UW0F*ybJ7  hMS+@Jt^.hѮؠji* @3n'Ǐ;/o|/oY{MeK4)P-V~GZo0pP{B A7lt bܑgܴD$}q5m%r)ϳWȞ7r$d1>GNӑyi@'rs>Ҝۥ$Q PS 5GzJCq*&EG5{|jnZ" a`1FÚaBn폁E_+"iDNZUA cU<[tժv9tjZ}~Jt;@2 ц^UT `%>vD6 1G|mE92gUy&h꼪iDdމ|&,:S$dw_E$85Gz)aOzxojpm#]*5oE0ө:"Ň݆9I42[}d֦E_Mh,V6~QO&2꯭aT윌]4-Oj/F&T4HR>ϡxT7e~߁`HQ5AT#aPUyQtj{RG5&iS_X{*]?-dM+76`Sm\cwx㉿.@ٶi- "~U^m>_egm]#]J[Uvփ| <dpݏq0Iw4ioF;qWVx쟅*~[QmurN= =K ?s⭾"Ԉ:A`$-!v)}}&U ]<[ H;R4M̚W;ϗ BQYv]ov;-0xxI,օ狡)HTǕBÓNZIQ (O[=f4IPy#?gH3P\Ov9>SS'Gay {@n2#Gԥ*I,a% <89 C 1_9oė+$jKOsA -3j$S|ި=Z#<|y˪?^g\П$b 7@2 >Da>Z2kHUuw$akuZt|t̍m4<(@:g#75}h T4Oq#UU.8 ;$-aj~[@8U$0l;Lq)GDM "aF~z}8s@܎Q1}[3iizaEG|nG&^YtmK~Z|{xJ yiSicd-7;;r@$tеeYfư[ [wZXag9 hs.KUy&6w޷-2)"ă ڍUk$z*K#9hfHo l. }_Ê LDbE)~_mz[ExmVG$p!U=TiU2jkxqxuʖ"s3!vdU1; _tst  FdBmgAmA:95SO2 +nCT,cKJRB{OfAvv+A ~]jҲۯ`UGʨUV nALt*F)vnU[zسMX[==)bhJ ~-hT UG7vVtd.bD)tS*[ncf`F#6kbU(?+q4gI5>eG M=1i~*{"Q4M$_RJ@FCu~DIAvZF@!]j҆< -@:'cyZ l*{|Q{[fB쬶e^+a%O ࠕeA s `+z|e|;2Re !]5ZLC$|!37WvON>711OO_EA |d"3yZMx  M[鍊E^5lKfi0 O0=Ұ-4 ˰"P]@{i.D0]BWix)-묻H~$IQ9_]}>#o w ;IKtf_n Q;@1qOyi馣ZAD3"_yjsYt.aW5J$As<'Z:( V9 [V$am2RZlѴ^H+jwδq}:)!6_pFZ-[KB~E(1q#]ZģyYa5F F0Ty9Y |`sG^p&XpZ4$uHM ~J.m<9(R۸W:L?לSL㰦;ZMx7wC{ E"1U,lU,qɸ/>;~pǎ}&7 qNt$%$MX(j_@k ~_4HU=#l?@A.= 7;;xZHt;p:)ij&n>uu/wQzEKZ('C@ _k~ٹ~ga|G t,h $ɡ2AO8|zbxvpNA\O#u6ڜ P[ 38|Fb60ot@|1$.&,= ^_XݐFѩ?~v0"\麬*&ÿж:&#G-?Gw舠sFAr(y҆ 5=V? kgtZtR`t]8t$`8Y^Wt]6;S I_1 f"Ծ?E9|9gL'u\H&glbi[7OjcлA/IOU0#x>{}vjZH]X{k6A bfܫО52d@ 9#IhrZH f:ڥV6<'IMhR@SB/+|6Q/!!m o;g+@MO:f9dcq_/3ֶT,H/7r$/o%]H{b }ܵ尮8!BJlF;m=񓯓'mFDпg}!,3)]d&a[*Pu a"u#*`5 3|ȧ9qew,lQ5ǜm`*r܌P9&nx3I#i?n5y9Yyb\B Wm(Jn-(W\982Z8ҦIUeBlh>ЍdܼY>/"(V:/ W>#IU*#m۴޴;kFB:lG|8&]C˛7|ihFՊ7D@ى.vk*ĉtJf׆^^xPkLKї_IDATh#:gx+\|k( ë鋅z:iő Ƽ*;2%[[8?%ڊ 8Y皪dh~VC Y?<М;F~U}>c ! g|!Jλ c?sHe0&:Q  pۂyaZVX_ƶTRԭ%:!P+.lvPpZ!3W :咕"מ^g > 8AL8ģWDGjG'Zg9ـ9!>n` n`!]}d7O5\Y~68pdB}ܶBXpGly mӞ:Ctˈ!r+'qф+wqjvHÐij|@7LTVen+|~mjh ~{ēY*[y*bj V:VQsͅ83LZ!0fKLtuF䉎 $Q_mntdΣ4"::fq=Czꓟ>Yg.ؑ1Od5M+&. iL!ϙl"qfTUv4uX֤Bf/z驟89wp<.=6~t*M!LÄ1#NNBD1mtEv%O޴#̎C% k?w6.nDa%HAeҝMsJPo|e*8r6fnQ'roeE srE;7L4ѩ_4[M[vlp]+}aV7Ԟ7AU':F`Y/Fj}ҧ#OGJ~FTXex9 ܳв)>1I[Ojy[k8Eej&0oZ7T#<̖} TwZ4eAX܎E \hI āoļ63v텦?4' @>˯[R܊^c5ğFG̎Co' ԠOiG* /!'V:LJjIUWZѱ#k"Y(>`A[5{1"lJ!afcc6']+V0?}M^$ kjBX?F:A\tZi܁+bJx\*!+K {>js gew+Vw͝P`wZiSjTtjYJ78l^tgYNePgˌihO"`n4Û>&r=>ҼT {gYMǦ-$ RWPjq7\ n|pKRBBE-QԖ&P-DHuqlX>ɾ<3;3H~ΞWC~{ &Z_}Û뼤N qfP%Iw6sv/`un> UtGB)51N4@eD%-/_XYUn3h8 `+P\H}ithl0avڿaVk*[f?sÙ!\̷wݫ_z*~Y:@i̇O{hlUJ[&: T.}ò#ftm~f#k=Uv96t:A0V_ՍU7ę].v?:l '?LIyt?.W#f#1 h]k$ҧlϨ[56m/{ʣNj5L~dЌJ&]ͮ5[kZY1k&K{6J w2Vp~hc&Kw#VW,"P3,)q,>4LNULՊ> :70k-ez+ 5BVlVx)j4tTݻV81"fO\q ==%ӡ[YNw:o?w:RIJ'dn,Z騌Șy\,ENOlc|v00LquI F9Tc!JGxsTݫPP{[؉5ۓ $sW10_F/VPD.9,wӓ l5J MH`K}s)N(>eW:xnig7E"K3F*m\!a_9zٝHQg7Bs LY|ݍej4~7 $pUsC%Vsv xtЮU N Z 6DzJ[:c:9{!z-'JV3<8Ufa1=pAb]hAZ Ғ|TPo픐ox 9z<7@x\/_pJCp<4&JkU5j]ᕹDж=K.JP=_X@(wd-Us) H{uO֊5W{!K}1;O1 dbM{A[cgRכ>/6*eZz?`/bz o,X_Tk?BZ*rpbn nc:%&䶥|w{2C`JM?wGJB˚ :C<)m \,~ʪHÓntJ5ԩ~Z5358k<m  TTuex9P+秾{ok<陜L9sOyzw$>Rk<陜,SnOU{aiIENDB`vokoscreen-1.9.0/pictures/go.png000066400000000000000000000133631227001500100166420ustar00rootroot00000000000000PNG  IHDR@@iqbKGD pHYs--imwtIME/s/IDATxڽYs\ǕwU!@pHd(9ܡ曟ܟ<;b"11chHB  P[H婈UϖτWh6Ջy;>&G^rnqM&jGD"IB?1tE4E3 d{BtloIwI:׽MD ݿ7l43u6ȌgGL{44HM0 wjDMuQ})譤TaaO4 8U,NadJVo|9== B^t n $ BWD4mz0Fn ȼp-e`PLk;x6 ~$zvWq[Zu]WauK{$NƝ=U@6"i~INE!4┰aAEibib&eu- X=k6mcYGk׉6A}g8 hwiDk lާ'"INwa똦IXu]\U9m}NhZ ۶{`@RMX!p'O`fݹ&THy!;5ڏ?g8@(("I `ddqfffq qi$<677Y__ZO P i=)1#}|[4PO4$1Q+;vQ?2]m+&IsEEJ#0ns]VVV'͒dih:_Aѵ8Hu 'Ծx}'Vyp(ˌpG~W_A%A@>q^x?~*K.C NO32ӕAj\'~ DQ4M `nny)dYU~ؘi), ۶re* RU666WI5H6n1zeeb6ytZu_ߢu8D`n:KΒdd2 \ӗ4-(Bu,ˢ\.S.q=l"P܀ߦ:ViE\-ц f0Pڸ @yq9}4r?O ^A-0MG,7Qa ɺi$DT%}y|G/ ?atK_;FZWcHkd\楗^0 Eq]7_6v[Zۏ*I+ R(f}J  #I~/~ VWW0S tlm 㘦I*jm?o! zV%|0,2==M&Q?IB DǴZ-ZfSNq%sCt} @&avv:mw&kUz+Srߨ >R =ڦ&2fooϳH.;R%8"i0۶Y\\dee=l#~-`j>0d%9HzҒ) rT?]>Çۜ>}t֪4iK{41[l ;vFt< CLTiT126Od)l4'Ȼ\_W⫯ "APQހA0 l6K>W< 8 ľmEVTQ]I9C$A8 ALawyݻwV\xT*#tz i0TD'46h=qQJ0$]nܸl<{m:aR8wNR4U u]UPB ЈJi";}> 4FS*U.4M*ZjJ_TCb0TYjMT)>Xw&<T+`L jV8r9}icXŰ\¨*74)l}^`? /vsE.]ą pl69+t: rN 0, u5i,>H:3;;˛oɏc&''{eQ4 ;*1upevWHtH7$􊛦*+=A {f\vg>՘|$3yXRr1l 鐈"fvNj¥{) vʡEY_H)]Qn4 ^HDn:v ǰs#$h)mZTP$ՓagEǎիۜ;wRth$M|-'ImO\Huҡ2q-u2Y8B$=ճmN OHkAzuK>8y$: G5 m7WE|jo ES'SEHtKd&c&籾jҾ80 5IKX>̙3g?}t./9д@qv[IR$5AnB~|fZfVKUe{J&=F'5@ / hiiIi}4RCe#gcc  S0H5i>nu],Qa5}>|{_'OR,8Rxd'yA0Sq ˈ[<͛;v1{z@ @ݦP(0??˗yl6;;˵kTB4XTGyje9]z M!D$qĤX,y2 :m TÇLLL0==ݧ\,ˢT*ĕ+Wx7* ~; JBPVYYYaccB"gLi022~#^}U0Ò*۰3 %o\~u1M9"tKL{ 8A{<3}*>omlnnr&&&XZZR^¶mΞ=;4\NiO}63VVVy&y@͗>{= {BxMZ;ÇqRj[̨@EOe8}XV7l@$/aHZgeeM/lejWo0?_4&OF&H/R׹wr+W+2tT8[y`XH&9ww?;wn)J*. q&O6~ "9Qp״Vr9<?\.PTT QvieGf;FBH}^'ȍSY8Oaj8xl[z!7>a}"8w1::C2j>簽G~ߨArԹ}2'wn&ŗY t+-};;;,//lXIr~4i.s8V_02i"eM.ENI'Nf[Ln`zlr] `kk3gΨV [eAAݝ;wy&+++t:0 X'ĩʈ#NGuM-1wC׉"B@looSSS N}i3HH_ʓ'O,K;Cce --w6Kk:7߲qC@٫lZx4/^j -0-,O?O?ɓ',?(iL}}] j忳^}/C*P6$gyy4a&IBbmmX__Wt@]_&Oh?dle{:kfu$ ocEq\B@PP=E*IxGѠhl6UUWF5MC!ag0r7N=AݍbsW7mt&]uZ!#!#ޟ$r)O le2 L{2{g?֧ l}'?ƫxMD&̹% ͤg0eGIENDB`vokoscreen-1.9.0/pictures/magnifier.png000066400000000000000000002056561227001500100202060ustar00rootroot00000000000000PNG  IHDR9rbKGD pHYs  tIME  IDATxydwU6s=d! K& |ш [@_eS((_/(l-! `Bm&dY6>߆9^8,_ x*C[՟P<<@"3೺>|g,˖ > ~}x;ou_ll$ꅘO-׳OWbO^< gv k$^AI+n>c8ccruYgm{&"(#/R3'>2(#;|t2:יGѕ7 #P7tw tgu{ƵxŊtp@ntQ͠"X[19=X]3@p ?+58 7X|O2C1:ׁ8cW''n[} '`p./sz`>x%X |`ny2x8$ҽ;08cm^jp-Q`CPM㽛8  X,?n+Y0wcE0nmxw@Z]T=GVw1;G'd橫۟2JD @U 7X&R@T_ڼrb|B!뽙۷\]rhǶۡ;fL9/tH/zrdE\q`-nw:-25.eu?6TXt>vLzGZ6C#j˱QN!K*Ę2уnOsve)>jǴ.@2]V7\8e4R qH ˶ %`[druXÀw4P/`nAL{E$a"0Bۜ~jo/cZfJy=:Ru?uy+v(8x/:P 3ñK<5Ȱ۞\>t$C 7Xy8^ȿ߭Yݽ!#[ NЭ/zXtlt 5%ۨ(0"2AR<3[d_=-ha6(*duE38q\동^eE/>i^NoV7:D_l~$p7@~tS06< ;qd+UGO (TTQld,od~[wNnxeyշ6vnۭ6C t*`)8iYUA'-տ3)dVU@n1w'pQ_lx/? *L3]/|p{/~ztԴ4Ʊ{|TDERU pEɝB۽-zξ7cV:ɳr0,iyWT) L5mǪI&!N @n[xya6Dk:ϱ lϟЩԡFtL gnNA/C:ŦO@E :̭q*Fx u*Ar&nKӪom*HX] m c-%?㖪[#TxǫH&]UM p3μ3^O//"wD;xک1tR@\s#)h 8Ł[9_5&E#R$/,[ hQjۗ iSwK.>yK@I~N#xGTp؈&N/H~c FZ: HWDqzk37|_dDVύH'Ύ×>a5 9ONtI?YU4H%.T vp@}+zB[˯hԇOLrf7:Xm%F*60( cِԌ.]“O^Z]W^S@n~lmw +PrX2o>T%i͘)"h}<- VJR6-Uub[(EN5`w'%Ж|E&>x]hkJ{ N*`Ya#Hd="-O^Q}d>%{@1 ;l?*(V7"EmeKFG8FlgJzchHx; eOV .puR,u ek m#7;_DnT^(1T ZZ,ky9%:d @i+[o$+`wu ; ;{Aau5²NGcU㣣'j-D("$inJgSz(~ KY\yG;p*N@P:is6+dy[I#ih}dж;=_n.wo0>xNʿ;`b Agu~?}7Xk\50dr=Î:`0,PK]T疧ݠΫ߂ pAC]퇔:W-,I0v#Ej:dNO)yB[G4ML^|VGGݖ ,V!!x[pq'W+2?# :c&wjq'cՏ=?W B~-WȡאַJU)[j'ݗcmg*I^~oaO{1}cI˱=(a$ТC݋ u j&߀4ߩֱu'"-L'6ٕ5ǡC[pW=|dAM_k$Gلiꫠ]yJRxT̫ Of֙6nnW$+ίc~-ӹ=:6]}C (Ыs W'Er,UH_l9XƷ|σFHڰ6wW e2LCӨY_ū05}Lێ3^Q`%-Ҏ`pp!L䡝1!B5A\H]hUy :_+QzIh:.9  ˭g䩽luDfz3ߺvE1B "vm[0Y6d-!!$fa#i0,.3͜cfI#as׷I1@̌Lc21xrF: ~\0#3lr?󖠙ŋvVmxʥֶgڅXLgb*z]]DɔYooȓ@K%*"Ln?s:Ӄ:Mi[>Yidvby-vnjU6+92SS?L w Es^-XW[}U5[\%(zi`epk *[ >+1׽z㸈0kËJEʝx9yb,jZW V6"8|؅S׶weF$ u\qMLS'SN`zC{\gP(*2G]9r4o,$)^νO659+Όc.ۧn`H\΄уٯFZҖ`ͰQੇWSG/F % 6WL Iŧi=M){^{#M VB3)-{v!SO]|c;#&OU_G`u$fR  fHʄ$`#i&b@2WjIU#h4ƾ`FX6D "/"~͟ %hpbďB12_a Bsfُ % t9lZcwtjq{?n 9smD%v1˷a d@[m*at<inIt,&7X;Z6qTV綮q;kIn7}Ka9hաI"@4Bv[~)5 Zw>/]jE<’96iā9]ĺ5ʺ" m26: כEbiyltN YS]j31TY:{guABL"a^;8jDp̘CuV7zf ueDfo8muˢ5@C0kfGm#WW*ց.Z5 NMwg\:iߕ7 K3<`} mض{J.Ȁ ThsG*Ĭ.E Fպ;XJOl'Rpx_pqbth!G B[h^P6xt;[릢IM/^b?{jgOGB:Þak|=#]XK1Y7ɥ'sjbZSdY'9ҕj]8Wkz&k9$W>܀P;/b3BE3wTb`AD n <_^AԮ}-+cPҘY2H23߮ d+ +7 o,ӌ M< o]6Z&ip YݍgdQ"Fǎ{r5Z81a89yd}NezP"̿5_ $d=`g9KrkU/; k\Rcx9mygf6/QNxo^nwVBT5oܱ{}+:*PsPfty:}]f^+F\FެȡH~q2ahyȵy̌v0L$spfoKh>)ff+9خrZjc2(m|Ől̾ X&jtM5:mpru5$y~n2Q2G6NY r!:"h *j%z.(8 q]DC犄gu ~q v}˗_]Uf4:rFR/U%^)g\@/؊ꅔ }ɌID&"f{>Z b4$rBrYH0 R W;nL#ei037t#xOrxɜ#$^~H7:ru!bWwX DR-Z*h- ZBn"<ܭNY!,~0'z:AĹuPX>{z;cCkTUTg_qU5 +|Z5 s\/]~l( HD#ff0HQ9s9+Ӌ !+ '%9s?Cyh[MMBfPK‚9 Dce#YJľICYV}WՑ@`&k%vKV&spM{EJTѾft~9[z@n7ޱ˽ƞcu>5O~G!urW*"7  ׮6#}N+2,_kQD2Q#ebE,"% (,vJ$Y~X"gg9c:O`4w3?[tN1hSifo]wXo^t.kï9`s eSͰ-*UkMD "_:guٚ \]W=Oխ= YGtc qa9 .ɻyC-*_}iUJ:pynnn0͟!* Msnv&!ɁJ\d`0-I~#Mf ұ$9QEDIPC5/ 魈YDΨ%"eZFsTH3j&X#&M7\ǶR f#/L..G SˆlnW戩dd2@&*xFhݝ IDATr9[{/'w_[o~Q1IZ*:S _H|hW7t]jO~neV/"S${sHWsλf&-3CP1Q `nUF;;Y1a)TP14bЧNf4 /dxjl4zxOM:WgJI凜G,}ףl N-x' BmV[Oy/Y\=po?LL&]]cxWX9D,3)15P!I N?MLi9uk75qW=8=+Kof@U=ۭvkhLH N;f fTUԮ]@()Kb;PR!Rː:f-y.H9+g D%WMeR_cF)Mj⁦ܛװ􅈺e`C \k>1YΆ,**;>o :=w2^&f20#v7B֩DY7@ #BJe p6omoo:}N]Jmzq.5;SOjpņbs5rpɐ#[_jbJ%#7^a PXrR"W&!i9T bXobVEkKHraI`)?g=ɡ&+yBx0&fZ!/\$b:ԁܐU?h4zL*m\iӂ!`6ٕ֝].;yWõ9{#}9;0V'r*܇/9Jwm 6P]zfu%D@`c {%b&lժ8r-{"7hV P>3txH! `.FP3ae qJ`˩R'h/ a`b,P {KjRfRE4TY X#7 ? pQl_r4IK[˥#ٜIdUg~h*mҝᅸ TQj(Q [hn^ HD '^6TW0Ê[L_#,@Q/l0r/ʎndu wkJLF5eOp˽jL_~O-8L w^bm`j)/<(rMϘK}B*Q(r?T5ߋFaA扷:7r S\L!Eƾ~uvx<@Qg'bnYrRLxĒ=r嫗tpGⱢC3L-yYYq{&![-p5SNvݷH{mLw"pҟ ^ɂAyw%Ɇ>=D5N$#(5Mu;yKdl7'uՄ7(z#te %o:Wy>kU@o\v%Ӧ~)سCeaX26dY(DͥDftB.4rq-_N鞹yy}ڹ[In @>xֹ84ܒՉdz]7t{oZc؟ l^j/f 9,1`/=AkFS&!*IxK֌>%g12s2bI|I8l3t6&p tj &"tNy@R  _]̱@HM,_bs$$ڬtN|_9;&PQ1[Elz雿Uw ,x|ԧL&z>bW3^j~[д%Ǵyv(sV}e8Cy =rqہF_ TJO=g.]N]zˍ1q:a+EKb4sKʹ5W 0!DZs"Q woݠTe(aI\.ʕ/#'( 3"J*+WouKW?Azܪo޸m7C',?n`D)[z /zRy%N${W FH{x-A3ayʀU1j3_XCS߼XQ !6`aRe Ep5STaD\i@X!rG[ïd{ٯ{?_𦧼ǯXa},oc^s?/%ufIRErte'0HiI0lb\-PH(F*Bjbyn=Kb`Z έ2$4u6%1B$̃q8sçYMmy]yQiJĴTUaEC{IG;dNjN_E clÊc(2xĊ _8vIj\]Jf΂l؝"] 21r(֖Az9*;޹`.=dUXU1W$DDstڕ.:' 1%/ȬYAXA),BC"0h.9UM*{9^wϯMkU2bp83;_ͻw՝_LL0wN4јhbM7 }-%aH A.qCͫ,ևJjiV ܢ[M:KZY|\1OLREز4q˾ +fLF%TFdF*ŇJKG7`:Lee ySڞX)h?Ocr\U*;uPe͢ kz% ̄,jJCtsϺbMY|ٌY޼lREiԔ]v3J}ꭎr]h0&gˢz:ѹNI(#$^uk^k.-(u1>)0oݰ嚍;gf|Jko9;&ٌ"E񘙛.LUu\{LfLU_)y7)Bf0U2X@}X">PQAӔ~y}[ګH9)@Fgsj.U³@zOSU 9 VG`$#0@ןHPi}vZcGe,XUPd~ _3re={ٲxhKwo3؛8O5ʆt{g!kjSrM3la]>nrvomg<;g.Bٯ:@ӝVKΏ燪  u2u?X>a$G~NMȢ(L* %TT!'z9lw- C-"-ˇeK&5A$LU%?4{5gbZtDN\J1KPr 6`TSaJ" PUML'_ܞ\BMr^ݠ0!>BATէ/Y]K6m-4+lB`kJPY;hXOZ#c CGCD r|lrs IDATL&z^.S'_JZZ{GhOY1g{7v_L(X + \NpخYhQ}+W\^i>X 9![lUH %e6y8Y," meUI$O|T߸ݗ:3CMDcn}=1V=d*VXY\fwL<\5$*.3r]’(_LMYҐDXD/zoak.ݻlf4f iE91K֛,SWolW7氶`sh(oHy|cp {f d&]c gcL(Q#@/W)S_Kf]K(b CZs+Qv7:r)Efܾiv}6l6Ŝ*aYͨjbR'u..y9Q3IV k@ 2OX]W~泳;Sf7}qUFvGZ>&. $KsTzqt IY$%/JYE@ ab e2(e УGJBZlHzuH2N)^z8WV+ի7gmsn~:o5ʼ6r$UݝsRZ6gKde7=CCX*V`YDlaF['ܡ|ނmk)#ٗMwjNk ppZlP5LC|#;j8 8L׵zXZlw"c hNbYXƆTo<3Xb̙ZXy`ad0LB]IY*dIĢt8 "rtuv3AOi'3֥\ѷz L97F)cxԩiZk>d.d0/T#/7>ZE aEXE}&6Mrc5С?Uo"rA w(Oݴ6zΉ#թ"?'""k.6[Dh~(hɜ$9j(5)9;E6X Bc9&7"~uGHdZ! 2MSLf0$H T S%L&PR%UT]* ]ߒ3>MTtAtMK9#Q%TT&Bٲhwn@OD{7Ghd8 ,냨52ͦf4X4[k'3oz`h Z" A-%)lY%9fD``pibnnhzz)|{KG͎~uo޼y3Yg^ׯ #kdF:|cO#c}NPݹxՕ;}-.>JZ`f8Zsþҳmy;6 6tN; ƹA9ⲃGkOg%VILͣYrDF`9ep9_ Zi Yj%s.c= g7? Yc#0'3ZwX5.0%7)F(E94Xu7&=Bb`G._u!l%QX(S"Z R6mWqH?Չ1M uVd%hr`5VNhj%7b^:e댭Zg}\e%jϘmN:խ_=} +˗ qB1Kӈ~9w+@Ӽ•+[;łԘJP)UA*ΊUwXwSPDIB"O>5?'ޟ{϶e߫{`izg 6ؓKKFR%{zݣ%gGG$C=PD{W'rU֓raٽwvG?8hRz* ^ogqH'4ǟ]>3s곫7Z9/WcGO>ͬm涴ie7Ҍ==|՛YO^dOޤ04ffUd*zQvgX0^C+w\=g%<'ch`ԙMlMn1k^֛M $bS- ~mdQۏ:mK :zRQA0T{M/AdTũ˫T.Xd+JZI:ɾ>RLwͬW=HVFYw={qէ.fZ}O[z{կzFTsVvzf ^,\n z]E53#)gRE6:isqoz&,@6nEO/: @gS*=h)HϵTPdyGBH U˒R`v"9 %ucDW$+"\U:XGYh>F,soY/}Nden)&!gʲ))c8زyY,4Ï8Cq\8.&nJd/?(H%Y}٪K"2+]9U2wE=hHUy ]&36d'֭ku/WKhyƑ%k.-gSf04҄݅}J:00GAT>4E C كFrY ,v@ve})8g}C{wh2-7k6c]7ZpG947gmLP*G'swU+W%)VW3VFs4w}W޷`D;9~>w. C;Dk+,px蚉Xzyz^}iWD2J3ƭ՛L͔sW>~CGD#?iUgMC tX@2>CJ$\~oMythʅ/jK+*&jtvGJ(,8,7$ϵy{p 8p\,*/.{eg0{b߿?.23\޹wَ{˴޳e|"z:;/GX luƶ~Qd\)lvqOBύ8u[l ȉ@-I= *TI`8S@vmx6X]t?9E!b-3YGg=\{V([;O k?  {X5"8eG5GTᥝw; 𔮡塵zQ}L“AЗs>!B_y{t;~Ę y9cI]Mklo#/ե .\ZKxF@tۚg-|uͮzWGx "6@!#r,˂[ȭJvzE#d[kA'tm+isa'ˡs qR^?$|-߉~ g'oNk,k܁&df$'?ox,q$0I%f"/ ]^IVSݵ_L ̯ց rbrϽ7`hbkƱ UM;uBפC6,{ ֕ sr+Ԋ[1pk8w{?Gy 8^96 츼u2}n5Ϳ @MьL7&*!mҡN>C:K@Is׷rk8v|vv7|gov# m\MlM# ֠H^0/O/ gNHaD:]5S<,B? Oye[7%ONI(媺趶ۊy}]v: ́'p f>fÞƅm~L=FeV9my5Ό #p D^DᩥiZݖlzݶq:p=JR Do3{QÁ0J9I׸ }х{Om((W5,/ZS좉8EGJANCD@.ˆ&%Eo #|d`{L.fxv%Oo\\ 4v8/.䨻 lMbV`q)o]d~/{F:"`[Wsury?3:8k>맷Yz IUyrIէJ kI5+[6HNIM-6 JlђGyiǘcW#V '`gX͋';åNXA`s+%RQl6ũ:>6v5(=\1(&|"2yT7Ǎ5ɌlleneFBKPh8<;N lt=;AQLkTgQYUDՖEL_}p~y-rEO>C0ML&8-ch#]֍n `>.'W}LS\Jhok3gG,,6 HP;6UJļཉ1z5yhZfA&Ya|YlnZ"Z44yn|ZSxKʈUwℜî$Pg/!3{n |FkaۮU$LD4hٻJG@6Vd~sOZE'ft"$elDERv v3-C J6xB`s3zx5VE hEG㺲V6R286ú6{tyZ'Cȴn?Ndxj)nljr2,hW}~gSmb|k,>dƝrCG5bt-"={ 2^9idv9E~:c0q+ݙ\6g%Cxf (oKs:v譥ۢ#*9Sb%1pmlN#vL2\"K;}k2::: ;HX[ ,fsD*yc{JM悉N2` nBZ|fN8;5|wG.7جFfު&WUlAlLÄ g .ԶukVWfFI?Ze ]fLUrz bH./n0@9k9,EUiԫ d"[sKF*lgs'2C|م k<^3 ҁaE |FKdŁJ QvN&FVHJSK$}ʠeȶSt$Kv{+Dmdr1m DgBgqkZԶ_cl^UwWF@2gX;ԮzQ}h7`lvR)yׯAqwMaG)mLu76F F6(hp[L6ME'䴹/ n|lʴ]v !jydIfdΙ I3st80)VKʌw/MNP^L4('G"4iI& I3O*;5dM.Rx;&fF4JruN;N lqכW>%[c";g kr? a:Iu3 \Ҭ#dۢی8UbLz8J z)QLn;+[#eKE.[)_SE 6`s%`Rg±yԀNɰbdZuivh>?6_t`Zv+/mLʤ6wAkEcP5ݑdK0S6ƭ44K}; 9l ZLx]\.k̈.qr;̾%ɣQ@rA9+W{7Hk["V\_KEW bD*".dT2cheY}HlRDXoЕ#f9YеV}da.'sJ yNDsm?5tec6h82A=)S7V-N( ERլCie<FgjvNkt)ΐC[x猤%R.$ۻdrVW;r:6GU [ i #heje:crw:ϴrM>RClCx5*mt0cѲ֮ЖA룋-'SdJ8K'7 Ɩ OS̞v pS8!l&9mΞ 'QIݱQ;ͤrכki u#p-LrZ栝|Bd*jpԑǪ 벲kƥ7Zbg_r#4V<s#f-6kGĤgW+S3V:cr9ӵIY6~ IDATW[t~mr{"(s4oy`m%c&T@7\]e:{5|}(;1e>CB&l8SO70|3 */53K vG%=p"v4pzo`˴C08yHǘ那,A=OfqRl^$b޲47}rBXZ-Pġr%`ආlo1O'xHo Y G,Rd\eXˮ4 &$.@o<\2>1M&ĄB4ߕd^>w[a4]rb p׎&ΖbSy/f^E0&1ŊL2e9Zf&u$/H%CLթzSi.V.ifqK}/e3"v26w@D:ci LD:Ff*VT:hN^QX phB^V_ÃŹSgE+km k&W\Q._ir푶WmC{Z]~TFJI쬖(jNoud7X7jY%]`z|sqQay +#F39 Z]s$u s}'W 1`d ɪ' 1+/uud؀;`kҸ1 !`yDQZB$*5{Ns#[J; 'wK3ԉ H$AzB68{ha33L(HE?deZ`i}VXҐHͱN&C^XN([ 4&dM u*ippsU_[e,@ڽy ǍM1,&iz:g 9rISGgu#v;Cڒ^8*swfjz ̄Z"<=yr'_ PiG$vNA+ShufquChU SphC A. \+%Y_ ssnÙʳy,S%dKH蚅M&% s%uD!.箓 n:'l%qEցi싋0ƒ"ҳKNeqS0^u2zҹż^IF*PV|Ϡ }X~59.>/ߍLl\C[pۛ=\\]/1K,H)E;$\}oe.WJJ/}qR骄.-!Ɨ&ryeK#8d+e#$ϡ IR<H1I$:/J9u%LpKp, PȖ-!)d f̈́>( &.xF%uGIl:fa刲 z3%p@V9dT0 s7I*P}ɇ3܅nff?ܽkuV;;W;mK7n >4&ȣճ>m:B=׷T8sOTǮ~aPg/)# Qo3\o_k'F%kNn& 39FcP(ƂM貔IbJEI)'xtZ&#DoFdɼ[U Lfw%.yr׾f2[4 \n %\>d0sfvZZT<慙݌wBaf:Z:]9;OFJ{˝{:N\dsVG ΰs`r;ѕKir}Y>^JWʹ?=&f+EeV~)_p2nmIĪSl]"!v[N\P@rWў ӐK5h F͉6]&`疔ܓЛ,ݙ'-l][rfp@M*k6 WfxX6]mTRM.zqduInvgYN60Q JWu^8Q8=W4Dn"$?rrF:&T.Y{·u+2nPZ]b2s+FEL󟸘$K'SNM|H!>:dMO $7 K<$Kr~7Z<l~ )l #^)A%C%c2UX󉰸|S@ ['qxaoc%'旮)l#'j'`nĹ؛fрXNV&VY8^X²X3;˞o?SC{(,QY`u5١KfW1j"hd%U} yTz)j&H$Dge"NʉhyBr6QhBc@3)1iBN@o:SY7yӷn]@&AIA6 Dh)~6TZ'8jaKUbfiw .RƇv—8=U? #x^3\4;e8ZMV[y8OSg \߾]#//%0!ii 7fs%Cks$'S}-bsRT4TYb枷]99\ټ][f)pC{:\hv@m&Oc(SMl8t2RT'E2~vOLpss; / fFρX==,VQl9 f._rv{n2 魢_Gys>/XN.l`,4 р 75ǟHetݪ($8b+YaF1<`@Yd. 1u`թ1; \b^ԙA:ʼ<Kf #D)iL5z1`z7nlKq/]Y0>Xǟ n+}Gbw\\ą;V=N -h>ue<*a ؽ n:ؖ :{_Ygݪw b mˋk4ul.%-:9A(Kl3bIbrŜXҌ( R$Oh 2C6'ALnKѼM+01L,tߩ0o~\fe UndmVvws,nXμͻy"47w g ~^ -^)+@w+Dzx䲪G#SkB@ԙgꨏ?)UK^ u K6:!9}-Ø,#YӃ@TI,  2љ$(Qc V .&, g&)!.E/8JS=VCl#Nu>Fg: @xT=O ߜK4ڪepqA3 Hl0:Ƭ,Yi`/F,sqj~b%n8M&t۹₸ .Czh%.6>6ƾ~r.p nރm}vY~Yc隨`mlnЁNbsu5XJ @AB^`c\nAuCJט H CAez>9URWT ̽3]:ras0 {TH ts;D&z^IIL̲l@$0T; l#͍Y\vו?n2pu0O.́K 9qn^q[^8\ +հnV[)SKb0?ޯtr!<ˬ>IsU9,MNF3l*,F xV+[%Oq^JbY0:+Vi)P]YWPJ4Cʝ> [sF[:!i ۂxibHeV8wUnM--m'2LTue'F"mr~wRG{]#A.J&f9qiA\ډP~pr+xM>D`.wYz~d~+SY%w|~9I`Rraon7 Ѻb"ӆDm`UC̜NHDx*sqjkj Q΅,F)']Dco3TtTl]6p PK]a3Rt_S8^]7c`+tyVnn0ٲͮY\{/]=^t)d[z; w 3qy'Jd9 G8\K*㸰840 sI 騳rv=8&SXݐ7뇲_lnImk Aq&%k.E'5[ŃV׷"VhN5WAfgdݭ05u*2Ҵr1NY"|# p+6$OE `cPf 'uT̺;ݜ0tﵨ oU2):[>㯽v"7#2Ka8X %biVuPScv˯mK$`zX\cy3lnl:{&`tMoYbI@Wz3%ՍV\:eCb6@/-[">3kSE77n(!=> D. O}|s"/S '(} eՏ/$oU2!c}#OWʎ&[:q88p\tHl#>^OXr䲗 I@D1rueuзdJ>5/ٜ5- 0CFD^ƌ@Z@WKڌ(Lu`鬘&Eņ򸏿%mWv މ4jDũu&@7&e XOG n6zX:Fr8 nM*uZL[h;vK;vr*p/3-k jQr_;fOXvxxTuDn%!~ 1*[S,(Y; R)YՍittA5tG!%d [^lŢU}q۽ p;ŗM{z2"&XDk;HJ3lZ\ rOotS#j~Ci/Ϊu{>@uU/EG\^;p|縰0\x׶Ru{åXE#\w̻q "~xݞ %?9 X<46ge+F y4eXޫ?âY"~o]eXC!kZ_ש`Wu̍90;֚ޕ *[$Vɍ 2 4rjo͈g T ۛ,.gݗ韽WVZá\\m.qH8?7J;9ʱ;K(S%_p3dtU/'eC#6դ84!b4SCٚX:zH'j*6[6@4$TT58.BGTx`c!{;r8RAFpk; {5nl"S-QӡP PEu9|2uB`q{;Nsiu'ν =?^%LsǰDpp>x02ΕnFe#eK@v};ٔ2HIk@{ǝGǹhpULk?,''5FX`L2u еfD _J՝כ;xV ȩlމ$aFml@Wuupka2wVr)Q# >N%%FJkyåQfVh^;W6Dj|֕<=-?|7^qg07\%񗜛[Y=ȭpر%8 SPz 7zW?k >bj7|`v'=W қ3K Cf55; C/rOm M*QӤJyS.TfM (+l64@]M @t ] @(v".ιuS #lpW

g|pHOcg`eoIs_5}8Oⶶ醮j/ig=l9F_J~IhtcUge5%j\nZVl[iV}/`l.A}׾7^ 7ېc|1~&wcֶ, 7O9>dSGD 8?kxGz,D—s7R e^<~|@?Ʒu^{w8=m]WzQʗ| )&X\ IDATM'̽Dzg%hUص܀.doR$Wc=T7;=;kה$MFҧZi6 V[rm.tn1jaBD>j"[vLXo#!{w]~ѽW@1woI[rZww1G2f,*\$ƜcԀMZ6(s!%\BD]#^}-?+*.2Ցhqz﹄睷¯%DƓDk{F;|t` {%=>ݶ`/A%³թK^_?<>Ͼ5-@ΐV4}MNqM|{(^C r9P)MI); 7ZrZb׹S{NmhtuOmX+~uW3&`AUϿ+^p?|uv ,t)̾|_]0ۏ3}Ǔ!tRjr/{ysvmS7-NX,i؎ŗ^@8UH.U, ";0*]%X5fԠy4ʶwW̬G*ȤE(FIX;>zD5my5XsǬS7omlwo A֕bu3䴹q8~ЃwYw_z-FkIJ_ x7߃x` $|C \1\;88ca&νtS \g&³n^5xù<&+!莖Ë9zq-L1\t]K d/=hOY݉?0ʯ ˦BI8`\k1"٦  1k]:K L3JT4sZâXYd _YrrulQ(W2ܸ gٿz^E{ȣOg\={.؉VJO]c㈹Mi_7~k@`piXm-.z^}Ǯ^K9qu\ݸ䥬T!" )V|6]tx! W^״\3a[Ec75Z; -[f)enuG \e^\089u Uo]O.l}̖ .qQ.&r |oOaN? ;3x"T@tS`ߺovکqv]o_0vI7ׁȓі7w3^zJ:YҌ:n*qIiKCYS8HOei8l-ٍ̈rxj]euղ=n$KR4=eolQIHca7Q5QZuRn8@x/~ rz ෵O7ߞV's՗FgR?u*XS-Q -Ym@gian.`ӧFZfҖvXѽTSOo;р׾bI0)@H55mN6åbƾ׿mܹy}C>DK~?c1K]=}:wpϹ;LJRxzǯ;~K|w>/Wqf^#Pc[-c\;??3M 6\Nv8lII#ľQUr!{XD/!7\A@NBv ߾1|''_zxϽw?5/DQG6mâdy\Wu-9CVke`cfM @_xA!$!$H><@_ 62` ,Z=5{~sVK,Zuvuuչ{cH\K;P6~QHKv*$ٟuKCݑnPp)%*Dm'C~)r]b&k*ɬY//B+C #==#=yczN}i[vpnj6B><P̳w{&sy ret$ǩeu&P1hbf~s/{al cz. +J`  #-(?3"6:9Z,fERkK,ΈkkՊ֓Okz*mၮ󍮆"v:"@N0%0-$ ι8"\gLVg}1k@__89pDN$5Z<1W $/{g-+8~;#ck@!C(M:-0#1T( TQ5LmrNa19q :5Zvx9?Ui] xaw,XBȒX]': }_ ^@GҎ 4Zqt;mT^טp-d.Oubx.1l̪k49DS:=>;8QcÂ`XD<-X3.sFI!YfukJw]*`OLH@3 DIhYXYmMhvk mhN _/ґ)zU1ܤ~0|!fw0XX]X?evn>` G--)T5a||iZEI.61euGS;Cm`:|BCcu 4==Vn| 6BԏQ&07pOiQ3r _Xf.U}`oJo-A%5[_->MNYwW3bHĺ~%va>yWM+`qh qpZajxi$фOqѯ})lȥ AdGruK&%HW. ¹~?xq+/&ÁЁ셯لxQ'ڷ0RC;xB|,&9ex'nsڪt/vZ-EtӲdՔۤ!QqAXso|ѓ.*v纂Ϡɪ~W '*( xÑb{B1/0%W`GbYD1G\pvDiLhUU8VV(̸AubkХ2G-{Оpgu Ŵ߇zpG;16iGěON&Wg*yޥ#ĝ_okۃmBJ0GgMx~-յ.1J#<||f/xNB\y^88Qp3yaӪbyw^/nޙ` N.9¦|jg=9n>UEV9 ߕ8NSzQi-?ppڄSG1Z:HE3BQ0^:{ve2G}غ@]!''d+7~p]a"z~Z0L$.#~`xmloˁ;DK8>>T37C)E0c֯-v`07_ȯ=ZQ"Ă!cu$.7'0T-J8gźAU} Br2|fBg55&w7rNSkjB0E05r࣫_p[;3mӮxDeobfbf;[2Wp.NO.9:`;8i<>b v`3pc, n>ﲍ#=Z3[HA7/e&gAF~N!+P {%VkH/'3io6L57%SM65<w[  ̳>&~]NyXXC nC}֦YrrvkcO)hL,+['#PxmN;_:BKq$@0@ [[~ʅkW@ܒ,tNՑfBwVe%HXPApKuH41u#%S>3zó UR]bUSys>Ps rg =||m t'%cxafCT;_W\h^Ёݡ i@/V/ u.`b$k.ܘ5\sݹo|4[ޱW|1slMtoТu$Y u w (vuV% yr2G@q2m)F1QR6,¡* :њ_MU(l5.A;/kFp)ȥ gu b:wTv~jdf)fJs8`gpCjBbґ=HN ^'69`\ap_keӲy֯3]* x]Е͙0u~[UtGb 'q68V).2eE3 HYavNh*"&7y+dubSvȃpC)ȝׁ-> ?wFWJ@J$TmML )aiv(ؒ!-: lBCZbE `B]+fF~V.԰n0ZoowS!-ϴ.\tU}7l:6¡S>L1Q֘Ө6M_Cq\ǡBM^b w1OՁir?=ZАB}xr_t+㰻s\XqGyU6,bǭ߸rp<\b^H,h̿]1an;OW )Oo<%_Rh6'f@ALMwb#匛F dwvꀅD4=+՝@ۀ:$@\RKH1 |y+§\vͲbIتj~׷8{ ҜE?P,IBVE6`U0.W\[Ie&>c8Z2r)} rQo4l٣ͫbCS=Ϭ;%53u]Bm7SR8:('߲WVk "RHNV?oǾzB>#@ DȺ@Uizs*\~\vt!l '~j~NW;JK,k)AȺ@!KI H <%.(HPÍX7h+48Qr^55a *Zr wF63m@ayOՙof]=Ty23WSj IDAT౉p-{K]ٌ4WILu|8n%2cE'i(o<^;_xeW.]GJŬf_ѓa7yD?cCcu.!% #=F+$Fz$vSa*d 3z wg2mS?l@TVB,i^nO:֦'LV161ݟmݷeR>Jr^ޤO |4u\$b~Mf{EVZVg݌RFk:3,\?t6QZ@1p[JNDX`\!3i+/_X#/#3Ql"1=g3 %>&mq@CNY']Y1]\Nb=@TQa{ߗN಼{{ֆf$c3;rGz+B ALĽ"w99⦧􊡞/XܕCC}R)ڻ5iyĎõۇ!mDV \\Kb[`y^zE5CTp(bpvj1[77>HIc0Y1bZ08OEs ;pEnñ-S;{VcyY]p߲1]xͼ=?yвҬ4!AffҖ}Gf~`lRJ8?0v.1֬fO)^=\̟fx`@w+HG5dȕך|7ղ۶+Y]XLꂇp2 ζlz$YȰ]P#@ "abT8V8Ztv3ԛzS`>ar1/b #u}} rgzy8Nim!Vg b~cʻ^5 |iFP5#aTj٬ԚJޘ63T֬[5[`ff)Wgzlo!)s]ٌە8\&'ffGD&0!Jćn~1vxG)butBt4 u w;X+0-0eWp7#'P cbYkLV&v`Ea03Ǩ7M08_o_d|pV4, a3)ȝ[H1PaX] 8h@;O<]~b{yV͏(jjfRm.6Kmlzf`2ߦY+ ͿN^R%1wwueuaǀ8ಮug }Ҳb@A\p @Jclw(M±aos ijz )h@ٴ5Ԝ>>|yexNKSK)^Y(O䔲 eds.w=~}f=Ҭfڦ)6㉃5&RDfnSDuWw[vUI vTÄ d 1Z=9.B5,\e, 5PgcٚFΨ 󕩺bC`8!XDfnd Jys헂پ~/Kgu;pɬnFLЋy_Vtk.F%logd^3ך&(Dfnzg~q}udů86E "3z,!. a# pPKGFE`OJdԥ̜dLM\3h- $C4 3Kw?a)ȝk?\eƪ'<2s)dnAVÞ㢕s\l)AA]0vőK }nکeuq[bljڴB . n U Rj]m lllSU3xffN\7JC[f# Tmg"\1zy rgzM~>=pKCzTq*w`NK~n8 'v H\ +1=s''J=ѭQJA\W͌Ժhl[,E:@Ov͝OA^dx\j O=";k.#u*k2)"yH!2BF;G Nb 8!A}PQu MjJuR1< .{kB0|`[O)ȝeIGf߅Zhcuc_BJG܀YyHO>8 rw贔"x6 Z -\Ө4s ޚi c 1` 60~gSkpve`0"?5%}<ӻZ}}sO[S$ 㩅΍}C[]J[Z|sߏ?Xk@s#+=YjFGbWbObGb ʣEa  P$/,WSӮ VIv48r ADت. a[2W.erg.jZZ_ 6eu9A {˸Ι6 He9#QԠ.=6R*uJLܪLq3PLHA!6Le6*N\~;>z֭.|@Wį?l"‘x9ܱ#sXDgйhEru@.呗X-K[ 됶k!@>+НI n܊Y9IU?orocQnZS_=Vbz{ [ɰ]wy[?ٴ^@I>NW^xuGʕfKuLA~xZڍG@ߣجQxԀsɄqVi๵:)U,!̻|P =y.uHZ.Kc`,ZJ1bZ@3`F]BPq$bz82i =𿬾tiz֭W=W*q,xc;\LpPc1KzW`(n^ d-ue4;G2K4+K=22\2cSZQr_6My3c[ʄJyJS;]ǑD}tՃˎOY^#y'̖ꘙcVZ{8{/:<m<@w&:kVKA YװBN"CN;/Л79@!G啃. AEsIkq4iɪ65-F4כv`(k0f27UN]Y1zKd2_y:fu̔-71Snb] xU]}1nI1 m̩#āg;;:*8bi $٪dLqLa!v-[N 碾b y٫lV7a/Vih55MFiNY  (VP099M{.x zr\t)ȝ^}qӟ "`fv3kbfr? |@On cx Ceؾ8gY.JvgufH,p2Cd7IpvLw벢Bs%#907ij ZlXZm2-3`oT\8,"0'9ҊgQK_u{ ?)ȥ^nSkqóljT䢄HBImsuW_LTO>_K/Յ0:^!bBCBe䬮X3HFPqQbdols),ԃ,q&?M00DaZxֿ[v|xiy#<^lOrn;tg1v+7o޸  \} ]U \Ux.ZQF%zh_1 #!#MkD\a9i*dɂNsY+FA7|hيiQͽs4s"SK'LMhvɝdҗ>|ƒ%#3 ̔{ Ұ``'El.)7`#ė0q_< , 8x8-]WTVRr%4cD";Q6ϻ\ք]Y# g|@ʡ#5bXsLmiLk-[ |S: Oű A(^TˠzgQ? ɝtIZGt40vU÷pm!6'B ru3زdļ|UpB DəA+0b0+&crOLt(ys8Ԅ@(28ao|Vp%薓S}Z31sa0:2ҏ\4}[ 3-2lvW~}_R&wFWqT'+803[ e#Aa_1 |ͱFs{ o)߯KV#6K,) 4 1kHaN-Fz7BAL)*nRX#+ BҌ [-%Neh:j\q1GLAP 1-#ix4,c9lXiU  #@6BFx'!u_x\"xsrՕg5>͘<ܡR;p޲7bq%"wq7Y~R4@9Hi:҄u4ɐI[5;] kЅ,oVGX fJڤ:Hmsۥ\րg]"WC-^n0d` 6RZrXR뭥f[(mw'^8{̤}~'zGՐܙ~Yܖ-epeWppo݃j]^Do;nG5-wᖻ3BOD>ktb!j`4 @ygîN`l̀kБ`HfBȸ@ֆYu2x3 ɌlYZbG` wg@ͷYJi ƑoCBko;1WB rg ?MUغ³& pce}3gN;6޸}^_Rq*U{ l ú'C+y.jc%dvpd"A^"4BlsndRj K3Vq̬UG=TsZÍ9c-h aeyy+fAT'L,}bL(χA~Gw?;Q}E wf> ЛݷZ_Hg7r#)cl qN0`mK8nʂ೸iS,D'J{sÞ- l+$;6$ݕw|DVIlL<۰4^L!s$ t;$PȉefYi:.0af&[#f`SڀVn-hzMem-6d<*Ab p{]"[D/3fzuo)WCZx8.a^du6d\`aHxLF;NM&_.{b~_1R43Z ظ:WvC`L*Oz6ʝ)qO`z{ C"Lj_GK rs Fw{p-R a#AX.h~fJe鲪Nlf.͊y^H|&teDZRtwBO{D[愤nmf(e*2,Ͷ xڂee-[ m)Xa!Wdmw3Azu~5[{ W~MqT rzf,?7,#bln{n~3_[F#SSs;4ębm?=CEyqCvMuSFLB$dp|QIoD&Z k(l|ԚYnX+אJi 6H:67C:t N3^ >/.ۡ/v|!xy:Dbxc ۰ M&v8*"/~Ԯ4"a01aqt$bg!!> 41)˰Bca օׂ4c}FX b @PO&|}lR;־'g`\%`e@+p(ݠ5a!B X~8j#0bzTg->ZE,Eb$A/xbZ`ޖ`fED~8Y:ٷ{ֻJ4ILG-7І\ĵ%ItKhՠض0!$#Ƽ"p #%bl`bK31d6Hw?{CWE?j=ȶ*(6ҕA06gGn jqpɆIoܸ+ ;OUjk@ /etDZI̎$5ּ)-ELKǕkIG&~}|h{ 4{!;6tad :21ʌ S~lY{L׽<8u3o^;"~!KXʍ+ܴ&v읅Жڏ\Íԗ@'AD-HAD+_$7^=ůfK6_U,kOaBc᭎#!AI3 )55J0`L ^ l^3C.~&Ak7_8.erڰvy^<_}xZURy/< H8})+88c[L*ƫ@2r" "]2ԥ"4 f6Lĥڏ7_i+BhV>b@cc9`_58/>p,E$ذbdP`"ڜAXsTv_9yxM+פUNu>C]NԝSݹ=ui9޲T nԎ}OiȬfKMܵypm!bǃx74فM U놂³L/ÌDn|ISW3H-Bbh}br d}Ь]zOpc$NsPѭu;vEOA,>?h~Ή~z O3idG__up)cX7~R4oY[{A6={-k3E9b>4nd8aQn QbB!):rв,paHϓ`Z%w}s y`z wB; [rם ˟q#uQvSvDO#z\钢 3_N5~w4^ɗ? 2bԱUߍ4/lV$ ٷHt wVʧ7k{4Wfӄ&0_kuƚY(яۉt]%TzDbݸ_~v$!vpݠEؙt:ogDoMt wVOoH>ޕx h45M:`&Y `8r])7+`k&bfv3>]+@bBd!Ð8Fh JW8]J 8a v/-=g$#A2 tZ564؃g=9n[TkHs\5˕_.7ZjïT^+զ_6Ի?x>} i- VDTv\ ZpU{.`F{&C뷍sܬi;Բ8tr+waJvfvJu\W-7Jo>QOyP-JA{PCuWhՏ8N6Ɉh5}hUGPU^+ WʵKz?HF^A f],>pDwȫH nGefK @kUE2 p !Rh.lr8H/mft\Z6Ee쨹x^ؼӡv`k 9x`_<fZ1h5 ֙cpXC{)r 96,5Cd^Y!% '@8`9B"5O|/~t7>]iz}9/?^gt"lQhXs5+VoNtV+m89Iyh 벸u:c1WӨ*s?Zf|^jMJ`>}.ZccpD)HJ26DZa4_ps҉!G@8= 6Mɝk%km!%j46aϘTkh(ZN&;Qi4[:&8v`Օ(י \ªg2 ykC5[ `߲8 =G 6YjsZyh6S*u}@4㊧t/7!j{.hjhy5rb &'-قwb3`oPg!;x1+h;;J+eofm+j!lLke؎gQX+v ])ȝɋVX-n.'ZɈ-64meAi9 hc 8:&,`2 | @~+ZFxʷL1PlFjʸ:jcxTh\ 5v uzY槁Lpь{.R7ꍘ7Vlhz;x`؛c}[Qt^8sU2s=>q[`!g`AEZY/N]p.0Z 5Ai-nt wMw>#4t?1yrݷ"cv9VW01jxGsn`1`Wܮp{VAh=g vv> J2+[MUR;'7L7o -߆V#heI/[k4%JЁ!˅I 4'@ H'[z:e0=baƶwjlt!ҕܙo۴!7f͖F3֗j2Mޱ1fTf{uO#jaHJ ?gxD4V=P `z+>m~PFQӛf(o!Y6 2auN>HDR;֮Ks764𡷏"A-Y<4Zd$`o؂REXuDۘ]<2 ,#7g~V}UP $O,0Dl /2^t,JALXl>+{PobCit60MM`w6XɈRͨ2i"OGIKkSm8z}k+c@c\s~BdQ&=(p\GHW reFdd$Q-{ 2 Js`%#G&dX87ـiuꮠy2!ēqto+er5h&lo90W7#՚FQj|Ge48{|ׁp$Vb=БY-8 W; n`u9ҕ23aMnr`i8}9!YH-cZ>G i&SMeF̜L8P 0=Z\酹0cF֥#])ȝ)k@Eo>o84_%\F"3Ln݌ 3(9 *GSHꉬ [/ zz$k%#&IG-m{Bu2ٚ4&S/90x󅿕ntLLX[/ν t%iMʜM(cVn MX{託dPf&Uϼ綱 ! @Rtfx4 WnIFNە6n0o F %j Fy]:PiTj?kS%HDoHFnR[@2N H8HO2$q9|aw9ҕ23a 7ᚷ`m{St)h"8ͦ [S1{T'H"C\0_21 fCҽ=7 L, w܈g YHjX8ځ4f#QԠ-LȲNP26d$cs 7#]);W 6,u/6XK#|0k%̘) FHHF: #ҕܙ68W`]ه/ CF|~5ì?f]E:acN^2HFD /\vW/Xdu֋;E(7-]ewR}idUk%oTU4.cm;" Pøcvhw3d-kΧp8H|K&!A 0} ڇv=cWIg&P:lL2rdƿ @pp$.X} {Df iGUoʉbڢhi+Ԇ*SsQU Z^!NFLp\$#C==w߸UqIGUa0D]wː=)ӴWS`HaP88k30(7•O66N O>CJiВ c T)IK2"B2nKF RsH抖OwC[%!Y$~3E-_M0RI- B_qXc$#*+b¦AN2bd|&͜ Hס ,?"vn֓w||bGFk cĮ}NSU*IgTQ*[ ԓYKh$74OHֹ8/^8y,(DQgօx:]F20>0VQC撑T\hS$ɼ$Äv=. ,_r{8H,@0iJ%}k1M׬ܾ;$#dȸD[?Qli^^f=_ ɵ W 7DP\ypqI759Ɇx EjU]GCKf$'(ۑ[4oE2Rhiph{S%ڸ[Mu[!E`Te F͆:,h]3Y@2KqEr-V лsz2i&:1Hj TvEf FDqE d*'qxaW%) iҼ9F''IDi64fCI,bp`;.k?eU22d6T1QQ95,%#u$tk nN+[ڃ~Q\W*D*bF~Q!ע8YL+F%>X="DqksQ`5 `pw\$.`dp ` ! lj4z) spH`MpqG6_Zea0)Gp*[vy+õWh1v-P478`j%#hf$3L*k݉wx$$6\@f,?4? N)Rxz!(Ba$s0Z4u;H`oS@7g[ҝmSUذ5M6HkwV B{$#hM20;H]נD^Νv$ګпTe/59tbi't|ߏax,Dq2^cŸjɈ&4/QC鎺";(y"j"|;dͧ*CϩSz`ܞl$25%#4EeT:sGrū^ m[qݸMdkF~߭O; 3l S2Eik4U7JMȑ $'s\@wyWgo^OPM6ojggTddh8Nĭy:_ 7Hm%V\ RkgUegSh.bLT+TkTM2b6qEYk)A5S2L`3vfǾ䧀-KBsfp snjT@yiȶ9Ɉ8BQ IDATV-[0U|}x;8C$e)h_LRVÙ38#u=nĖҼKVϧbi~0Z^]4؂dzi;8%$VW`vIx쇧P&ɜxU;h~; ?ȑJ̝f{SWAh1N;OtJ@WTˈxX3(*j*Y h"ك(;8K$Gf1 .DwY58 TOR{BT}eyٓ ddd,FN93dwڅW-=㕗-WHSëDW4W X)ZsD:H?:ꎱCDr_ iycZh[„-H+9'R7D2"435&I ޑm4^kC{\kH: [KSԴ(+<ɖ,kEQ\X[ʍV5kX]]^2"5DOs-HA= ˸}dF75jL58HÁAؼ=l E(7բB"5ҿq]HnOt w~d>N>#l0 9T8lЖF\D6UI ⲯC*wtZ[Brf<< Cz< Iђ4 UJ%YN3]F~((NS2D1KF(砙dHB$#TtK毥m\r;m9P ݅$DO,DDbF n6lrM2-*FcD1D,f4ͅPǠ+nƌ 2nanߏm @Dl{%iꎽHKuldzX26p/ckpr-Hnъ7t<B̸ᝳq=YM\f_adLaݳT= t$! TxnWo4HF99g:8}߸ݾx2} I'5q dP Aش=< -yʼn%#l0w\څWmSw8',(f,N#cPqF2"UM2"1602&k2%kyA iup8<~g!2FՃyV 1P!B"ë+ߚ6N fsu\#f u^qM$#(Psو:sphHn%[%::ݺ$PZtTCCD$#R$#cHɭ/h.J3W\Q 0:pGrO] RWk^և ~Ę2x I-5Ljqq 6IF2bɈ!V$#uZ7  wRHn'9kV d~fWChIE0˭d,5HFтd$^6LQ%osG]HA<Z2༁..% ! z $#\#=?Pر;BCҴ5I3ud[N@;j u-UFOQ'*؄xˇǰT"I5匥7V1^a֧j>d}[0ڨQ{؏stphH>'>>ftl ;;80*q-kFՒO\tDm@2ͧ:8LE ^zo ?PA|dQe&<(IFC0[tphHn92.nY.jD %͖(HF|%#;RXd ;|$׿P2.HuUNK\F!|4R ƪu5ɈRYɈTI}ny&ǿ$# @|0x;|$<@Oܹ%|yY=!HU 4ؒaۮd`wG]H !btqXY_zŅc߰Ė^#:z-NKjN2R!FHGw INpK;-P*Մ+U *gȄJ-͋$#O>SE%84^%#Rdi^ ap`;q_9{B8da*V۱'J-mɈdddLے#nT,Se44XWs6N[ (L(.wvFe$-d5(HFnXu0Xk #Q=_,펢C;DrϜ ល$ig&N?joPPIF2/u'ᘏ. y@$]+.Jk7j^qyȖ\jYFY_j&4,&Q@?НDc> '&Y0>0a2i8W',͍dD$# \#34􈊻QY⎞C;DrX|HF<,1dC i: eM2Ρ8)MZ\2R$(d%#˗\d؏@8 f[g{Q6XL*+Te!0blQ$ 9!i%|88-C N_¯b0ei^*U$'ƫ yCb D  8fHmDZՠِ븞ZO\۠@`cp,w%]]vN9#l[ =$s(ʌk{TUyk|BaJF%KW[ވW>N1.| `_mPnͨ11lHIMNjXߟjlDQ 5k6dvjڂ_ HFޛ~SPa_%]TCt dM hlZ`2H@3bvN] @ڗO믚_l0*㉧kF2Rĕ<~JF5IFꮝeA<⎚C;DrH6?Tؚk c0j颦UvsҢd'/ck1sph_NO!b|pY= [d* *{6H[]*<+D}MòAFqD:91v"9;P:p{&C^ 1rmUCGoJ%(I[5r9z_%wG]Hn{TB̸#qrBl&+n{VfQD7:.12֢ d|5v?5'N;v=ͳAFfm S9ӒXC(yTKF2_$k|x98C$l[&) ޲fC`ՍBÈ5 |0u×U2 xjwHk$5%N3VIFG5ظ5Eqͧ"$.;\7$_-v60ٳKGEކ IY9_VO|u/鎕Cܢ`B0ѝO  A?cö0}sOCPl꣸4xT ܑrph[]g\jpI4x:d7N$5R掔C܎Ƀ >63#iȎ=!\Yd12.16.(N2LiZdiZ'qpxb"d zkqF2SՌymD%U/5F2LniC4g˗s"gOwadGo5Ɉ5A)/(=|\;M|$׿ x53K%i*U eeNդGҼivG" 4sqLJ#Skuz?MSm_2ƒ5h6Gk_c.$hGA4 B@W- 4Ё[v5WYC{T`*l uD:.|;83Z_d3`itw]i=U_ReLT+U *Á1(f&iB b'bY/ ۹M8-0;|w% /M 0{FhTbS@ajiIFL$#ã1&*h 9ᚵ98UKFm K3P4uW;FP[elpYbr;=mErşkgҟdg>D ƚ5ِIňca6j;6Ha1n)88m> |MW^; 0GɆd>5I_| :[-;Z2Ђd(ccntMU"vw/U}Tu~m/[0^Q?Ւ6HZQ2 އ7c t0+@DXW LTMT+ c ߎad\!d$XKF8I_Wp$#,[{Ts f0=.GuphHN">0b u0:.*H&Q7l Ik SeJt ^$#mMr',o%OAlT?Vіd$uѶ뷅59*6H1U2 p'@rpm@Q2šMb5=\~v[4 YM-́^| 13<Njv*`ך &1(bliIF %-$I#wZ^($GD /,/,#UX#\(aݦTւdyއ;1qpx5몿S Ks`lBapAۿw)qp8qX93D=MfD)/ybMA95xh9H:%#E?G2 N 53i+|ꡇFNRҒ#Y!Rj;!/d3~|'; V$asHFz Yѿg888K `csBx۞0W}O!a18wNabu ݆;wN_Գud\ZբOw=RuL|/TRzDTb3{Bn,,*y@R4؎'RJbLDR1)PqǥR)a1sQ}l>w#k0(O KSdfհ s%>p8KAl"Mv\W>/Ȓ]-֣s03">1s-5R*L+J y<@t<yWRKt!КT]7Y-8uƮm]G""VdvIMWfGmqI03t\2ioGrvgz\IDmL$kR24B @I)c<%ͭ J"cDt@g׮]C_]#;sxf `S)%xDTF̞FcOۇ,ȥ Ɍ& ]_D䙴SOrilJfEDV65<ձl16"9k9ED)j2N4ќy.fX!9VJD$b"9B(T`3^lY>Os{:L-~ݥRx!;rͪY&#`C|u9Gwsy+AUKI(OoM Yj2T2a[ VJP3s 47GQo{:2}E,[ZCD:]ܩɭ:t` ٙDs A(Eb?&Z;U%#= ]R.kXݳ )MuR*C.GnLdS4?oDt,uWJVd["Re @́RJMaR ܻ١1p 7e˖uqR~T 8}}}'ݻ١n6̚5FFFf^ںDԭb.Dԭ ]ܡI&]Py'{|zϣ[ö XԱ, IDATy^z`V蹅=o{$ QV7u2II^2u-=KK #;\V5\Z4#8$gEp&<_h2yRV!)e җ:C_,yyJ)T*ut4O\BNMl:m- 1sש_ϐW)rH^='Nq*.ϧf :b9>~Onzt :͵EsC?m~VYw_fyּ;1`f#sD,Lў*'uV28&"DZK.U{[;(./}ǬM\*5IR4J,н>Ta)L!() B 7Y~L_GA$bĩṪ쁹=,:2RA0 v,J? 0Ḟyтg*%1kExQ=w& <`d,SV&"O35iRJNJnMl߷euΐ%].RJ#! !H$J8=" sudP#9jD#>df QDgK<L4E "VuM(K+R}և|o9=c᜞7xBQhXa-magTf YJ0 yh?*/`|`I*RTSѝӨC:u_v;Ԯ("BH);SN6 b$ң\NZ) dR0D\4sO,""MMm2cFlcG"H5?Ls }|]N?f"f׌R|7;::1wuuR(}C}|ٲeAL<::5մjwWՒU jWԀQyxY4%iUsk U4,쉉T[ͦ &+[[E-1(::fX7ӀB&DUU~~T u! 0,Jъ+&~ӟwCqw{8̽:Rj 9NnT3*$>Diɔ~&ⳟ/ a|4I-hFtVoaM?2\Te\SurzKD[ B0"@HDa{;;RJs=CwqTJͲ˨ڍJC)訮dN7Q\y 8#N I2D򏥯ªQ$3<͆DLS OtѱzU_' kp4hQgGrF7ou^I4Dj 8 48.]Zqw;'e摜'ADsvɬe-6|HSYB3\v$O[ !"jr+,2`}?j(u- {0kGFB)%M/ެmϲ6z]5Q9˓^|θXiG.Er]RϠ6L粀8\A~Ɏ䌆&54cV+Y5 X;q, {5}rytϞ=#_q98r$*㎞r<])5LǙHȈ]M ~gHt6E>,іI7-!hPw\O7O]*h-֐En)k FF64$e鼪vV) !5#R&]KФHB)03!FG8%?UJӄ}3sw{l ܠF )em͒&8k=KFw!,jQ]oNkjq ]gGt)RaL Rk[;z4]ҷ)K ׬VgTUJM0Xc_cbO]]]8&^zRBnEdrdGvi_'Z4~g&@k螘׵ku(1_ߨ&g TB>uWm5(*o5̂lQ7>-?皦vr#{+Gؐ&7.lߚ-Yq*{bZN'u)!AuĎ 4rM\fNfx߈YzP>J@)T x[\q[W[nٳg ͍T薙y^Y)UPґ(  m4]Ys? f~p 0&BcgnF)DbQkenmaDkZH)%8KRR)0RFJ%Wjdth ]IENDB`vokoscreen-1.9.0/pictures/micro.png000066400000000000000000000746071227001500100173560ustar00rootroot00000000000000PNG  IHDR S0sRGBbKGD pHYs B(xtIME 9` IDATxw$u眪xd` f(EHϒlOd[E*OgIzߓdE[% LIQ ``rsSwW:qNUW2gVsfk޻Qwny3{[VE{fQk#*mZ6҉նRJ[dn=kU;9eȎOiy~soTg.-id;/??Ki~h;vs+ "(+28|k>nl^>xikUQ»]@f]7}g?k|s--vB7o{ a׀@DMlP7$rݧڋa3Yg? 0:pԎ_{K{;mPHP}/"[0 `y&Ls9ο:DK9DW?2ȟe(GOkwӟnBrB@5 d8lÞ4ܬRӷ.g8sX',:4kOZʙsbmfAf뫷o˲<߇BA? (@7wɲ?s= 35qapoTƅ Xo\BOe?aK~6܏?\ݟw-EFjWJ!ێ!r5aY^sK_{0[9cp{[se%\8vܗ/oh-z=RB\cpb?Oxozxi[EVBBFDEJEoz&CbbX*&RF((AizV~kQ'%8PJBTp&8GZ(A(ReNn 23pJU!;ckb-Xk֣ΟBV#{6.#Wբ5~?F>[߸#@vh[Kc -&QQ`#i2(F숴]N5 w"wT![6\Y:ps.WfdݍWʛOre)yF(xPE1uP)F h=ݥuhDXr[0*Gll6MFEJ!9eg}x: KIeIJW[uN3k++nw}o8ȟz"w?};o}u^kvZTh(4:Cc S(oz>K/mR ItB"(N9u rā(|LU+#UȯPRGƄ:," 4\2V6X^<5/kԝw}un~E/ňTڨ1 WH1@"Q/CKtD$FQ|z--ĭg6\t|Ho`\ y7*S1NG=sG^ʹG[.;_{C l˽?z>o8u曗PV%5#tOT݊W<\ej\r0o@Xp6kp>5ǹ)J Tu6ݻP VJJ~8pr,!BP%bo<.\>;:"g[}o9~[PvQ)aLaVݟn .[T8|h+>Kn$"Vlʽr7~D;ԟ <*,(p()QAHqpq׼L?λ|v,ȟu7|3;sˁ]ry PcˡB "ꨏB.dBa+ y ;y\hb{k8U"BïYZ=Ţu7&C &YO9o ?Ӹpw`Oʫ>{+y@, DD\W==Mj|W\CR[t*cUUrٖ2Skս՝HYDIm8M>Z M14B<V5X KSط|3Xgs% daѢߦp8csےNJ@V])kFm>Ϩvg7.vJD֢rvnj-Hs QW |X!bt*Q%# H AiAYg>GAgr.T7V3ÿ7nסQZ2ʕk8nT֡]Wh]-9ަ,-Ȋ4/Ғ,%Kܒ%YV2 G9QA:*) p101y9((+.Kv]w?4< _KKGw~7~SN=5z;)yuZRiv`r7sun©B6q*dE8VK}+tU(O/(JҴd8*ey(K;n Cp*Ò[>[{ Q)|׉B(QN|d pz@:}•-JY%bغkGjÉ 5( =r묷MQs'r"Aw,Gȏ1t)DBn@7~QXҴ*)B Up(W)p6 2&!R9皦(NFx 3 R_{ov#ybrV)dXDZ* T!Pu UNH[)еZ$$_ )Eklqp@9-1#-F:VM>ކ䶘IK3U.:cREk%nWY_zں #"-()җcBMkʍC T#sUTQ,U={}ޭ*420iQa ١՚x.XʚY#GW^; /! G~oξ, !yQleHAEm6xa/T:+p U( EzNE> 8IcqwywbnWo8 #2!Vem, SU]']4kjvϪyUgRk"٭~Q}}ŒV6/-(q^7BiE"e#"#t0qD}no@eH( EXЯbN^+4]IͶ`ؼld wcwkLs׸b'wNFvإ7gQ{gZ^'?s!p,$!L]> IӔ4(9:Qѵ-7Ǩ lHYU`Uz>*lӀbe gxiPվiIqMŘW\hҤ,n ĐzmRYǨ~JtcǏwO"(nEYPdYg_hJF'jFԊ 2ʢ4λ'-> j5a$Tȟ[ O= V"֎}p3j_ aD>h^<9@^kowiq(vJ:/e.YSW)KlHyF,Ji8F+`1tċUyRS|\ epv-ւɰj8`EܾPQONg6;}cC4{tIb|y'.b}uyyy(-Z_פJWr" E^PEmEʢ(24#MSfLD$DsS$Wn]izs3?#N*ﻴ;/yWk:܄D(5#^L )p)I5zN\d_&~o^^ /'^q(1QJ+X]`s,) oE "#K`MRʲIhwHy\!JVA56X0 "&,[I<}STSN~ٲϰ`ؗ$M[jJΗ3bZ_5KZP>q.38w] d/T4Q~42eњzy|`qT*tmdmvMX ^$p7nfŭۚ&+maަ<¤EcKQ!<&DH+e3EZQgd5J6hmA+qD^ai@ 5Eq |Rm-.wm>fʡ';GQ||>\~///(D)_to1_%r KڀƈDzEI羯Cмa0%1IEզfNм\6S9I5I;ۀ NqBMrp.a<^`Mlgjˤݲu 'n0L>8 /Jo{vBTh 0Ip0:$5ڈ򢤰%Y EmXًQGQDHZm:mEul\z̙وn%^|䅓xO]w'喤%O֌5N$.'*&I 9ޅ9#/šKtꎛO%?v1!73 ʱ\2yI(ҔQ9(K,cssc"ѾTEtm]l.D}kN &WLv!^%7H;^{h)/9vT;EqYre4&2Dml6"Qa\ҁo1A V"N,Εt;#7["S%hWu_e׷`57'Smr#^>#bd-(Na 7CSl3Z&SA`]ħO>5 Wq]sꙦlD F´}M9( G[L K\: MGlx Z+6t:v5G7#QZxM''ïӖN0 ܆e܉}#uw;L$ñm1鞌fMy%qu83g @.W|]ᛈ0 կҊ+Frn ]j"YVEqYR%yV9DRLeai'ςe@YRUTSd*^C2yQkpSrłАj]6{KRTUFl* DkgjydTWC c.ԛAV \"grˮ(H3JLDeAg!ȠM3(! yL1F3G)+)}b=sfm`ZfwLpsn|ICMcqw=:ҌnYܖzfBp4 Z8G |/r~]#5A_ A-6!P]֘VD+q(…+u^y -4J@jCRcˤ |>Nn+d|n*۬W~b ihԉj [2qIg+xp(UMiݘ ./-"w= V3CЬ fhAG DVuE>},uP;9ۘHav(nUIeD!J't3x߈(ey7;Ο"Zkl2+U71޲hM݆mH8'r 8y(d܉0mPPႾPkıVd3 r5V{=_~GmAccGFIv rT-ܘ-vʻ]ƴy7>;>GOУnaWbW4H| VEUaHL+fO{'/B|E Pek Þأn[) kkN5ܸZܮ㙼 H ܥ9_Ar[ù;jXs$iOJ=:'w>mi :LK!*V :Hނ6>._b=8Ws uR4oQEh 9EQx-] eK25%x7{tmEԭ:0pyMprht2Wf{)R".d_W3\PoݵsG;,-pgP @r?u6/v7&!2&nښd;6C&ʶ&g;ɌتTA JкI0s9{qİ0?`0 UsKJM,OIw`.*\ىu|Dj-spG9K#ʤ1֕PJ4Cn9Cgg鷺~O|%C{QV7*w'8eA8o3](Ls]L(IP*,J8(Ξaan5 yredy-N6/%n_v[&hc\AapL>.WgCtPyLptA>I,^F7Qe">>xvA^ ts-AvTiD# evCB]V1̫}Gce1 By>2{V86ȧ{YiJw0 x~==8>R1{׿wTSadumZ6aޭ୓|Z#Q6J e"_ƱO>BюzI潗h<ރch4dҴN6*Hbai~N2BGm >CX+X|Rh-.}'/j",?۲Ww񵯔4K8?n2l2 N>p}xiiVtq|0k}iJH+U"[hz%z!i?`@=SY9uK[}uG;TB 8zyzqז$ n 5]y*Yk2 ٨.isUzK+X Ԫ}-XHiP{D=}l[Ͷ]y*MG?8 _1dsQsO~BK!wTygvM4&%9Fs:{}x{L?=ӸL" Bbnit[[I4be<~ .^&6$2,H|(yCDlp8d40\\{`}_3 r i:p~80d4nwtt:].Kϵe.-r18q vS%JD&U'xlI5,AsLFFjt';'D@GA%y-l G:s`\Kd~( ʪ>$,cHGC`Gޢ8Iu sVb@Qp*͟vُX_z)wk9psq(vCtt%sܞbɸ=XXE܀|nɢOlO~dv`ܮ z1 PF!/҈D~msaˆ6@COtp8`IuTqD,G,/ "̎5ٟ+?<"$o1d[^-Z-ZIvM+ijUIk9.kè ;XMM ^^OZǏNV;SƳ'PgmɨoTtP*x'bT[4(a nXkc78S2 bBYRk&vA# qI1q+&߷>oD9Nk.dDR3E\? &|RU*$#=^mwWvN]nUQ.#ʲonY>rj^%3Y:"S;q>xVgpqȾL (m~nKMW5Saٝ2!01ZwЦ6ZRdYIAS~ ByAѕ[/([R\,5۳Wm~t@э8%I:.PO=z>VBܮ8NB%x2WdZw#Lk6#X19[^c{| Zl1?߆Ѷ~# aZ[].,,Xi}bxieUd $Bݦ8ݽ_zXst=_6^R>/'IJ6 7|cqo g& 2Y:Y2f64sNIh)|`U)`5b2BYRt:%vHb/PТnn\P~%꯻9GDELx`x 9\z5P"><'/ 4~GsRZ_E&KL53xgMq &͙x= :UJUFQ%\:dssDE!^[e_iq\ Mpt]zsss377Y6GrM7g./P4$u,h[5, KFp>$5]eRqޕ"xU'o: R,H=rպjzFkL1DQB$=:Eڝy:ZvG c9w{?e.~ϑǟU +X3O DDBĊ8㸶M`,.nVR k-iz;[YZj֛ɋ,Ie|+|3wu)$qouC#nRtϽ ^Sw=| *'nUu\UJU2iǑoe._ ??YGVT{fA^=J0[w}X\\d~~~Oߧn$ Ƙ s|#dYZ](W8yѨ!b-Rˏ0:S<IK[dJ]]\]3C_2u" D5ZH+䫸wڴZ9̧[@@κզkՌZhU;j+}ޣ&ڊEF#ps;ȳGIZvGoy85I]Gm6n0:.|͸gVvTTŸq΢u^XA>l"Ci8"N_\6d>/ s59a}SV2 +)7Am/ swj/&u@DIJ D)Yrj 4Qd818B܄!qe8~?rl3?fn%_9 IDATfjۜGөW!o}{S*[vEWVO8B1_YIPUkE%EQogsvq@"A-F=OMEpmDAǑk%/ $UXnoKΫnөK,F C666dcc#X^/|Ǟ8˭N+.䧷eQIza5'Sn2ÑҕNUE|Mpd1nC'_{H\í3C wDUC]w $$'_8wOک7/2gWfޣ?ne9U$5R ɂW J6<QًjR@]+90{$jPǂò,0M À|>| V8SG][`@T/m#iyK0#R*aML9f^~ PNC*?#5Tҭ H4 }tGKk63%}z㊢0ZZUsڵ]ׁ1\jr0+σiU8^ r@Hhkm.A8lp<!h|$8$Z pSyV geGvh&J4_VD5-]庮hDbt7o+?-=n鑷l%D V!<(-ǁr bp ( P*֜A/FN_yix0w 3Gd M ;!,}uOP;ŧ t0TںD":z܋}/mQx o  ?~]kUk<y\.a@P}? 6lV|j#hOʬbG78dSwL_oA*KNJuoU AJ㚮 CÅǟZ=/b9xarlbƠA*@Tr\=y`80}y%H "1BN8 d#%>Ezz-PvRRq^9),0UUjUr8jJj*UUehr˯mז >} k`z+ZZዖVj+0L ;΁n@_f~p;Я##QHz99e'rbPP:Up]A. 4F2c7/Kk6+N= bYH$ JAss3@ss3RjWuP%u*W3G&+B>˲G3iy5>K'C?m`eUڶ#XUMX+VQAUTTi0gb/~/ÕZ4NX8D{CC455A*Vhii؍FU9 !f˲*8p2Vy5ZDqp9s΂")hz" nc_WQ}@e~y#h?*;Ju"e*jTſ0gE9X;P\gjy[],oJ3%R ,˪r lRR>S -_==כxP(\4G"QD+`y0lt^EU9Cpa&MO2{a>t! uV=%0Ab;70Ҋj4`T*A<_>OHz1.PD[yPZsyصcxyG$yUF3i?l߾mEcXVIL\4bҊ/`ryfw1N1 ܴiөo&̝;㜏z6@rC'{7GV9o0b>Zl-|jhh eGUcGu٭f}^2xۺXb!1$wP9XZZ};ҊEhkk̦Mٹs>=kG4:>XbaJӴĜz[QoռViZUjOG>i2?mlѢE>W 0lb&F=넥XVY5BkuX+T3qMa۷{Hҡ ˓5.zRQsEK+y8 S$S)X^ ;pV'pY>})7\ϯg>k5.V81ǁ }Yu8j"rZVB:;;?_;vx:TJ+%8WPb.A[biEQ+{PgăUZ'0] ! ,E"xG|Meܹ(Z) %iBKed\씘#8hOe _;()qs΋"}vo  xpصňsEa]+|&0JqH27M5\sݻ9l6{H?yaC\C#ҙGXeR0[EAiLӄE-_|yW_}lHLTC6޺̃B%(񞇸_,@(0fJm[ܲ,HR_^~KBݺu( ?)2{*X( #aJ],]-0XZMADp;c#kv;a!;d w`܃ڇm ⠍= Z 9HʩA6Ya *%q] 6-zq~(r 3hكuqVZC!ɀ#촛83/\ssmoD,*-cpUUA[C q\,j-Aj2-)7I9wV4Mv/߰aKsνd2y;d xb)=PdHmX H1U1W[4MeÆ 7|㇚DfQ}PSClRAbx*-lVlNkUw 0!64s ===F"h{{{2k 2AbrpOZu'A9jOeQfX,V5](#xGpx[bř۷o2I c뺟f;!:cr*#A;(8ceYZvu# 2hbdJE QH8-?qqށg4{:+"%aWǻ< m۶s:p.?ITQ c0Љ8-m;qȏtE'p/]P__gϖ\YbPp52AkNxݠwZCat-뾼k׮O*Ai% #%ۊ4sο.cJ Nś\vºVbli5)Žrr9jժlfr_x1qXyĈ8"2v*'K+'wr9\~SN9UV ڶu]|ѢE.֨ʟ$\Qpm ҊuôV1!;Ľr:MMh*~7 -[2IүVCAqǜZud_~0J+;(8'ԀRr_~;vpV  1OEiCvǜt@4t yވdxf5m8Λk֬iz&񚚚$ >>-uE_]I-Zԝda&aܲ,CЧ?x˲,7y yHo(W+R'VXP{TXKK+ӝ8 r.?GuzTϟ#dH~@lxUUC91zN9Ot#LJ"j!:{2 .oyw#95`T[ a&BţXѽr4]+|8Ow^ײ,o̙>ZHp R3{wy0ޫ( y֮w"%aq30LgE23M?x- voo?g$3Hؼy3,\q_Ք!RŎ36Wh Z#l\4rT +VXvye4Msc~wwIHp۶(ai%*uE!NS9 m=ZWF3]<{ގs]Wf yc t]?1vեҰK bcVn`"d29G7l<3]x'nweYW^)PްŠ+غuOU&]Y ÈH̩J2&kܼ'hll&H&@'\. `me˖3K/'x"_t|bewq饗cg a std=t;0̝`Vt\y+ p500wtt8b;zH>CKKK?;樵\Zq2rQF8!,5]xo.=MMMXe;WdtR} c`j_ԣ3 sQvdsJ] !>800{b?A`&M$@|~BgggK)1K+ Da>t\ѥ6uuV_,lJm} CXZcC4{AM"Xiw0`^KKo~ӗ%@,<]!/c mňm(IފD\(]+*%wj2M,{/~L|ߗV +[qQo{x@7{j OP(T*u%\ikkYV6Z_(٩صm(B HjڶM9}N:.K;>яbCqfthi5^pH[0J?nhhrc GyG"Kc"3bXi%J٧ZZ? ]G{Ŋ~1t:VhdUCCGkr۪֩ZZVtVmQ(G/}K;ok(!3ȸxG HuA2 -f,v0{R ; ^,_~ulI&nX2oiib%NÜEo0bN$rymxK+bz~ H9p /\չ{}  I/20GsYh('q]w\Cc=ny^; \~g2EQܧ~Gs8ҕ%քJxJ ^{y ^۷ߨ(Jۺ9 c)uQ9֎Er\\.ap4~'~3.Jmҕ!2np<J2\ +4Mab Whqb^KN"OK7&.?E$By6cƌU788i4M_[2dkشi;yT"4=2v[.fXΈaxV!rY,yƍ?X,b1/ɴ!2Ugl}xzIfYb;k_[reX,ޅaoh[:#ҙG[/ࠥDbļT*U$BYU׿th۶ǽ7xCzY 2}-[W_}YUUcX^6H̱1_J@35&{g} _سg3sLsΏ:(=d`?1x衇ةw]@¬CSih-]Kg\Dxwٛ8 4 %asO(\X /f~ݮbD=PP,D1"]tV;Thh3ڗCXsػw/? 5M㺮PZ;6j=~G07Rɸepp}8 2ap׳3g;w]UEGdZq j<3qށ-e zđ9sN^rpkkk9x ]$@&]jK&+`I=BV@1xfI({"8p򎠴b|+_\f ~+۶Mq(H+_ ;tCG;ҊG`eYxdRt%\i*un#lσ^w]+$aR͚5e24MsQg%Cf VqGOmz U=0WюlD\~ ;nդg,*|_ȉ'+a6 sr cߵkb>t'=/Q{;#;<ϳs:}}}w3di%Keo-Z-Z4_DC*n bD{ZmDh4ZiZeCUȐ%ք:6nܨ$s {0TyjŨں @^9;*ϳd2y5k2 ñ,}W.Hte$V?tRqպsT"8r\ ;=(8j k]@]Jс=?{þin{{pB.JL:{qyfH$SQi j* q"^~Bށ@'w>}}W^w%@&;cxbfyuywhRvZ4`@!dzBKI; i.ݹ]3feɁ 0ٳgDBMqǜ.AQ81kEAԚw`i.B={˖- r|b$@&=yǎ8∅===FUb.UZ3Ǝ #t3B]]=alhݺu;44[ZZ\ι* Ը>6mTs#%=h@XZsfzFqm/WbX,z3g [nUk1uSfm  [+zT3d[ex1c9gϞݻחw%@&خ]xa*쎹m;i[Va1ry1]]]|>ض1!KIVwy'T\USԕF#VZԡD,ƒ!tHIx.cW]a? =F;fB---J LB}}= @Pl6 044ӧO`R=o<Q fb't9siebiE bD:1cutm;DR!߶~ T*9)a1i{W(tZD.[D8=a R0ԒԺ3$ 4 _2DYf62AQx>v '{LUU(D{#OQr\򎰉yyWmw7eYիWfJ%gxxK&(wȘZ [1xo|q4%%DwB7vXgPNE0~g;88h ,<&!cRO1؃>qoAPVqQNBV6;VaaMYhq  ~#>6f EK+G-!"5]Gq;vni]pϛ7/_*ʥRɁBu.CAH$al3,˺$EЮ]w̩[ؑMFţq0`_9zl.5448n&1N2۷T*"O_H 8umk=ēcLl*wqep<777JH&awy'ۺu288ߥ*ǵVtk-AwwPR.Y ̶]w}w_*{_eM%t-Zbɂr/,~9~)z#awX,f֬Y,YBtttx .oOY ?f}}},LBrGBdlBT&FMjr}߷bٳg'Iٱq3ٳ[[[[ٳ޽'?Yxk58S|  bת)NߋG5ёP(O?e˲ʎ8m޼Ϟ=[~2ZP1cO>i_޽>$ML~jDر ;WH)8hH&JRTuufbGqĪkޝJx>2z|L>f~6w7oׯ_],2G!/yЖn0f!;֮]^[4;xW]ugɣ2 Y6kkkSLTlG"u*ym :V# sS?X,VYyd20<< iyg 4M+R2 Md%1n:'PvڥOZZ.?N9  V(UA q 'Js. MƗ.]nٲEFJTeS@===#hvڹ?(B$΋맟~^y);d}ߗbw%H@X^u|ߟ Yf=x0 uhh<}tu]/OL;ZZE`ySSU3G}}}uy9Zaa8L&]9F]wl4})LRp^ϗ,KR 2 8D"q-ZZq,˂l6 \zV-ϟe~sKܶm4MX,*1xkkiyfxE9)Be#-L&ͩT {u I\l6/W.\ 4M7:A{xx~';[ngqi* 4{(ill3 ,0cd2r,˕{zz |=˃I0m4688z`>LwRb؅T+<ϫzf`ra'?'?<XE`Hp +]ek ObqDyU,1k@.l5ci>2R2UQh]]$<Tw8c*ValYp2dUJd{{REQm.an3+0440<< \.HT2HTX۶m yբ9 A&l6 V~J`Iy/AX<"RTUqVUUr{X`KxX@J"uhhhKwwUU]m3Z^yq,*|L(CCƻ '/_ED^Yfz7oR) Bryj7r'Db{psAwqiCڝA. /ܓn.O.v&vƎx)!! Oy×a9w%˅m(Lȓn9Ev$I"ޣk,Z/H7ob6Ӊ&r{1N{/\~KړF.=@T6Xq-{.c=K{{QEN~t}4`y~{\0흧MPCipttOB ŸqT/{W^v ܼyιalgndz߁W #nw>٬/P_9'>= /QwEbg>i|$,ࣟ| 9޺y!:_zma\~> ?Oj l{B OD RL??MQ1=n߾%w޽Z_?S``"'q jik$ߦ1Ͱ1Nh$6ޣ#?7~V#= ~osmi />OS4_n垄Y=dE$ϑo+m8??w_SS__po7DUU#RǷ9i} 7nĿ/8DΑyڃp=x~>|~'?->|.W+|}z24b`ݾZ88Wx!~~SKcY'd~=m珋?_=Mh i˨\Y7*^o-̾ ߼wE8<8ι+'s9xkju1"; 3wږv74ly @Ue׫/8gpsQ v|>sM|vD%'=BzOM~}hA .ȃS JA. ?%ԍAvL$brk%!4g71] d#ðEC{^#j-һ\en%iGr ap-DkR,S;_0 $sΕa O%!Rec!;{C 4qBD= &ো9UMdK`h;'%r5!PD=żS{ ]a&q>h_/xhj}yI10.ݏN?e^`|G#C C}}a齌b]1Ē"Yr+ a9ٙ`'=aMbb;#Qq2"e v< '+DR>¯Xߚ(*aH m юA%{XQB72c"teXd OϨm {ewQ ;ɮאP? qꁻ!4Bg:}kBg(*%wђYKss7s 8Jb+J 0RÀ4QQpR/p)eDt֞p\8,ՊhO˅BŤ57OFI<lnqxeHGR( Z4vJ !S.5**ٔC\+1x%1CE Č$HrCWgDv Yyz4Yp`en zZ=Ю Q62wC8z5!0*OBrENAJ Y3/Cm` LPauc CG0hʅBv n$sǔ@XDƺXw!xB,9]t]bh{P1S3JdxDJ%BPY}Ϊ| `@ 'E {cyPh$xph!`u2ĎI4)C\ IH hbfX0z Px8;&wNO ]bT*7! '̻{A O9VTw;`׻ mXm}jRyb]уUXd+Ij&΁9 4hG/\!)11@ѾgA8@N/q^gҘz"* c(%,de,"ϣ"RnRq仒.% J |Ry1;x7FA. r=|?v,b)gAX9s-2sJ|htq%WcXF0olddI9MsbILfNl\("mS@rRb6"Q=JkH Wb ҹeb\Hu\v8iRx!Qw%*PAfV]P6x) 2NGDX^F~]<\4l060fM "AA( G<䇈 U3 Bj Ԕ_0 *mb+[gVo0lQXS'Qxe1KVZ:rE0KƀjqyE>EB$o2ܘ3{-E-D\E) p9@T$!*'%=No ȡO,hSYF u!sn B,Znu2ǟ(4襨l123/y8#B!X&hQrjSTY j ͟X[ªإa 7Gf6!tNq٨RbE SȐ$IL E]~E 9qOar%u@'<cP3J¥`QhBJ3bC gdV&ײْBnX&"Y^ AA49̏P4]tyTΏ!j+iǜt\uUD`y[S$DA)L*GF # oLdsj,(Y$B)zN Nc9qd _H'j ,rOΐ+?b08e: 3!&$ %þ C 9\L T"PC;c(()[xu ©UF6/g~xV`s%3XAGTgA&{zZ)lVz&N> fCг`` V> j3.2&< (:'#L'T[q-\0@rzlR)neRהk=yU%/LVdxm+kYbᐌî&1VȠ,2Ne [606!⼋hZ%).Cfhei%,+%D^WD}M1O@3ög8B`ʡJ:8L&mL="&C"BuE T*݇#t{Ġ`A>.8ǹ!D#BC Ӻ'@$!Qr2פ 5d9OYݓKQ,=8 .)zRP~r#C\ \idumXv_&`+] G R?ܺq?H9ި!mkIYEX `u/h`F%M+&0Z3ۨahDx6 G D7q&^y_Y֫a9}ȓP޸TA5@ַQrg%DC Vd $)w84`Z;H\40;m0簨\#6ƛZ'W "VIg t?GϢ%cl_ֹdQGCAˌwzºw<æSQEFx`*mPxMm` _jFמ t *ZkW4Mt )sqR\Iy!b`j)Ȓi;K AQd"} af!)k0FyqQIN  vNj&oj@$QMB3X ceE\͑+<GC[a,*wX9lcQfìvXwza361[lcVi%rkԄgԎ0u6jx7~m1MoRrM+dܚ'p@3x~4 ~L7@{as ,v% .)8aH(q8Pxq$2̉#s3Z0~92(@-1XWSD.kۃ7Kŋ V"'Qu`TU]A0kaED!Z j J ( M`TPd ڕӦʹ(p99B1ǡ,G 9 МGD͊0y# pO"V`5mm`ts[)X[ s=CԞٟyrW!g*G- .v@6AA&&0'] a^;4Xu`3&04<0 M  xBוSOPTb5G+B:˭{ {`ɈL-?66Q{:sAړBFĹ& ~M e"h]6"wvm10Щ>3"{#+NCWUBu|y2FʛrHRg]i. Vziq4=mTUXZ=N_úX;ªeL+F^YgQ9´vvJ Ϝ#ԕx ځH J 9 KbAKE/y%U-,@̉ $6 Ɛf) bzs ,ϯKS(:zg nc"#D.ڕejWv rqq%9GXl}'b52ܕ4,x2)!|FQ]7'^ u\m` rgHBd+1*p5q}񨉘yY.,2M=jOxhtmJ8k| ^TXv.bQA IDATitp0q88ъ-8zq*)akVmwuQiJtZj Ѷ]TjFkI8Pf4i=H~ljqdɕȩ@. )vKOHAB$~3]hcmm`-IT7%Ă!Xcfr^Yټ#SuQιDn  .FMǭDzxFNw>k Mx?MPzɵG+VWUmD])JXBj= )WqhY`35Liʶ8'AGA]*j IyBXG29!R(0LX 8n%C1 $V cQt`c5L5Q2_jW5H*IK.^-) ;PrJJԫ8\@2}Em޲sNկD $W{LV tkEh3cvwS;\]ds0-*([y伉eWoF}%XAey Md"&3xG8xB$ YS2hleo{ Y⽍Zh2#FRR凁7%^kg1Ԫor櫩HN#9sYT)Qԃ I,Nm)QM ZX,ڡxZ "в`6cmy2c (lVy0t0xw1PY? VHj})JH'I;xiCjƒ!M!pPcE-nkc^Ä (v$.k?4I_P4_acܭРKtœ Wjn$bJa(=¶WbtnzU/'g^p7'[p6!⬉8.­Z>"F`4w6uXD G3Ri2E^W}k~л`ʙ!\ 2N}" Rf'DR@HĐd2T]3 1})Ac&0zf݇jz+J ,/{`rԻ̡7Ϟ{/:}'I(rXsZ1OJ={tV;i"I]&y[S{l5y5#ѶǬ"#D "e=͋a; }ߓzڻ\ S >`h((db=H@{A TA #۬Nn{~D"Edt,Bf^r~4,2xG8 ".)t3wsB]7X#(A@}L(]Gkt=n{+o 'h_a"<9IpoMyE9pj)t{s^a4|jXj 9,V-gA > \aPU6 Xac놔$%jɃ$!k%.e^I+, #(if%A#8UC"hYD0Z8"L\=$㉝kz?M(rQ r&(o){\#.=PB2?X $bm%b\(.XwБApZu0(Ĝe.{ƲguEP;B3G=fo*)ǵ˳`ϚJ2jf\!`̱A0`%5$XLer5vB4PD q$G!kӊc/a9Œ O[HRr> ]$y$nhnMɣ  = <@Nu/1,y#XWlzm\L|ЩFj% 1*nGfGfRU5i1y9I"%H쨣1.h[yPmT9H3B{%d ~q4~U6D3C3Όn1q4q8+Lp}ZO<Ie^X'OXޠTQj(ܥ F t\ `:8V 1e+1AE|>8vb' .ץf BtOΪ P kъXYU# JHN)Dcɢ;9&쯤?}^FPD&ySc^h mzMeN fR)A.3{T06֟Nۘ=MQ=0n+՚zcZcbM,EweV.-VXƋGJQ$)laSdAό8>HpcP eRq3GQ!H1aPIoX0G`mo)h$q[qlIgBSm$I@o~֞_rePS:.f#S[L7r ;66)䤂vwC@m1TńsyoTPӂ8l3+p}8nkm% 7nͪ EM۠t7ʲИwoq0b}FQj7&DX{໠7 VQ$Z&8Gc^>1g^9֤wߜb Q$裆#+Ջ5# lzɩa9}&A4{ƁRlQ4-u!-ʰd 8(ZQB`Th&r@.i}֎2 dGWK:1JA^[_9FQjU2r.{71J J YBDVa[xWm ]5(݈v 3Z@Ak+mŸ`w!'3"M*\x|~ϫG0V}ջ$iZx޴Zq+UALεF 9ZEG:4ulќ!.,HFL"lƌ mʻ%1kwFT|^[Ib0:hw])sRF߼GdL@wǍyWjQNTjrE}YI"R hS5vpR  qH {&3aLeﴺY+.x5otYeFEF]i#" F]4Qcܐ;؀hۈ2c ଋx+qy!\EC]uܘ؄-3jњy&,*eEm-덦3/}}c>">{m^uIZ&t찵ܲaF*H:Bm4 GXP 8A/ L(^B*gq.j@FbWjHBG!gF1.5Z h(^l*Z՛R1)2t μ< To<ڢʄ =tJD7q7u$FL׷5zgW PEKJ#z9ڠyBӕ( Ag`Ы$-u5vy$$^IdIq7z)~KG*>}<òh"cBҀP3%%}t p$p $p#adGf0L}oO)5@ ^$})g[(d ,EePֹ%XuG/|I.j&`Q{4qW^CR01bb%6c iFdMރ-l!yGXSt l;MBiLk5 gצ5O&vi&d옪!J6mˡ jmzoW?M?E#(h8á&Щ"(+ƓXCF%\tp`tH YN4 ն,JPTATLle<@dgg潬Pr5XGZB,eB١dR!C4$l߄^;ksxS>h^aݪlP3&Cs`Ψ&9BZ}g-A yLyRvp, iB_odp/Aʊ]vF>Bx_Up!Ē"I4eh!q-R,qG<[j`3Aq0u8kzkGM;liZ'qrIZ7ZUMՀjq8W8]+m10SEͼs(zQWwD,@e0skj 0)U2O+} _9Y?ůK1;,huK .f!9ec4KhCbֆݓbPet9=9%n/\D ]BuBv# >Oo2SJ('\$5e_"b%|\Tr5GpQ_8ĪSu0<;Tìvx jա 1+LYǛ^eP6¶yF52PwضJ\5ǦUO0XvR~vشI)+7VWmQ.:S5-5F`N+qЫoG>^či oM3^XWTNܯYEXuF 9t}ĄxEp\[a3F⍓5&~ŋ|Q<$y)[Utp#٦׾.x^G3e٦~wr&`1q8YvXfB``[5.hs31=`KT}e,4$a9Oq+GhZm!QS!DSğx?+o6L >q8=\k tpq{^ǭY \S]JcAFeomI a]S;thg=nAFaԅ'*gaɞDU:[3Dun?jmL epqw|oU;_>Y{O\zŤBςV+_v ^6u[gMǭ |S|dϽ|ZH,;p0g ^>Ńe˃MyޞG[LkM g!|R|1Xux xA͓5:~!>z+G3_u8o>s~o\_||qoj=O=~97xhZ|4EG9kp`wOvm_g_:-fքf{' >vsg-^< ^9*Jf}k<8p0hQMܨ0e,f;8p1MTr16c8>\iA`6^GL&-c>shZ[񟽇:x w >{cy:_:£m@?¿#qy0ovx7w^#NVGS &B8q8ռZ0t2bbRyim&EK5RVљIhV+# IDATCXۣQg۴ȣy6wx[lβ{Zpo Q+i&{~|jOxt&xt/|Gȵhܼ&|dk)=#f8o>Xn s+Sm/d݁/__g^Z-^8qoB^>\||dvx;K|9Vmys->WJ6wxZIoM=NVZPUP]HA$K/RDBqr}7^z rSy6R랱TU~⛏}xqo>xoUۀ eqȚj,3{^>OV gdz_ħo-WQ;[71k|k+Mm7W9kpcQ;G ^9y׮xx l">zcoⅣ;:q,XL=oN~ }4' X 5qMĵ M(qD6q s# &B1JCf˨kŒW{>s>`fwxh<ࣇS,e]xi;5;xzmkvS|+xl^8p>g[ܚ8YwW5>r}N6̋ljnNp)vo~W]nj{KS|5&x=hqq5=i0}n"gWnply&`68]!,71S2c0&7~WIfLj:`>uh;Kk'wpwMK5^?y6>0x?k`)N^< ^:@D_?Y_8u6 't4WpeѦǧnkrmG7j(x'oqtwSD<\wyPyܜ׸}4A8\η=[yXlpB1aUYoLx_F|qk57j˘LTLo(`D=N8\ YX!.f:@y;j-wW^\|p6⼋~s+U o/7mq60Mċ,;O*-tXL4:rM5J9|D] y'"fr)q-<[q[~G h=g [vxq4T?~%zqp1:[w9N6=n'wη5}0 8~Vn/j| 1Ƕxq4\kܜO4D \}dO[*,A8Gnpq[G5>8mp40 wx?j05 Pɲkxq08L=ΖAM O{\?tk+u={:h;tд"k.26G =WQ+~/+,;ex`=cצش>{kxg{o/Tk7f5<㷦xa+]5Xa';Èp3?Jn=6/ sGtx{[|>xŝe{gMmGK%&8*wp8Ѫ)|xiްp4ƭ;LX"nNq[|<Rc9]xh6Iy;|NV}X5~oܚԐ)]uX/krGdb\[~ F-`ÙLJZp]=b2|EX</{,7;_gkW/@7@$@l\D"%9cٖ͡sXdq̳GH4 =8hQE`%z=#y"knp8NwEeEfe~7w/Fՠ?HMx"ANnotyug|7O,^0ئybF4(/a^P vB~ƣUσ.ۣ ,X7|^py3Y1nָ=RpoCO8c/H' UQC=Kא34A7Jۆ 0$Lxj4 k9h{&~e: c꜖g=LXEnBaOhQkxPj7{ 3 RmҪ9͊z'bend*g&jD5AJ3RU" *jPWt)N^iPEjT<(ɱmm |bu̩:qǻ&*✍aʿ|`4FE5xa+jԴD V*H BmIrILVM^t6s QYA34]a g. ȰJhiTAtݢ[n sU~ ABbCLMvb(1t1L5Mzyĉjgk`fb[އ9paYmغ ~rUG1'Sɵ^…K ,Wbkŝ .7z1 G/BG9X{)$'ߒ{X0,=A<@VlZiQN6Zy9- Ry^'=KAgRšUQ,8 aa1s!:ݘVd%L/;NP-~M@OiU 0 аMT רx&mk* R,"+m]Ks|Ɛ'\>O4Zۢn|r$6y솩21* ͩvWbZ+}\Os|͈ŶMocz&ƌ8D s'1g^rC'PYHA?quN+Uڐg: S(aAob:xR5M'LlQ3#3wm. yЦ2*/)-<64FU  ų D-B*8cՑ Q ϒ $+(&͊NKDQӨaiK林j+T`0L\8),QAIbQ0Yl:|im;.A0mpcȔgӎɫ݈ lxeȇOڐzϫF/P7M@Bǵyof}~DDv̊PmA/JqMl T돲9m-(K$U9 2jCѬK=4S K+^ɳjָ2پD 8-XWWM^ ٺݘņM7̈Ƀ.u.m4=egZfxrf'8%;/rZI'L7!V M/LAc0*Yɺ<}4pZPtRnUL-ng=׵(y^QB+N*+]L+;/0R cU| Mj[J9IDw½( r5ooxL/y ᾶs#6V9aRpiIʭ ^D|T/_(ďr[S' !]qԉ_ǂ ,qv+Lx&~̄gя2d^TwYDT,C1ҜrhB!`B?**Zx+r x{P ma6[ Vr&*Kde5ys-mЅ[, PԴj9/'crؼ250).0 AfT+ezBeAc LZ7M]nH4p olJolX[l)-[#>\Kׇ<2Ћ205uG݈7r9!双&GM<#r'+Ș|v "tMn bĩIB#Ej򒯰;J,0̨X:QkA*1GVma'c/H6} -%uoxp^LSwK׎XEs99O C5 t,M㑙_[Y: u;>LWY$Y"<ijtnBk􃔹^mvB&+rl .R )YB~RT\u²awxkqZٺTۦ^ֲg|b 2r<i }2%.!J/H ͙LYJkC.^,WM.ELzvCζvFJ Ŗ+[uAɊf,m]^tdc[][ ?;ze2'l15XD$yJⶏgLW,.i{l1Y.yd%\n2p"4\^"lcJI3_2rG5D,5ۨ~0\U`f8h^H(IEh~ f|Kk(CEFw([3-u<6 )x=Ӝi$+¬LnZ?ffr3\z&~\2WW۲(R R+@E܈M^`Tȷ]&u7Tmo xtQB/LyrWwKgrL^LƏ34*vFmv3]1闺W*&U؟_nbBA݃k9Pw Q__kjJ4 Up Ve$r7KӻJMExk%hPJkvЋs=E+~1陼XJ0+Xi$,-vkp3߰Xƴ=0=SZisq wnP[źSa)*{h7a̙ z .XlT-K;#N]4(wţ(޷ qL^7z!"8:_֡b,7].7Y!̕ٶK^Ha;f#喣QZ eUpi6u2YBދB2t$T8-\,AϽ S ;+4 ) ҈uMZJHN;irl1ҽ=Ӭ,K=]1:nUBö\ [N)K ?)kr0V5JTbvw>L$=zÿNXvYW{TL'|FT+Mc֐\tÌGfl bLq'*tnvF9 erbhpΈMDYbaahp I.3|f{ )hV 5A:~*h@mZnr>:nVYDK'-B$*4m}ױj8R71g'\+Ч-r˦ 2l+8r{Xku{pQźso!}S<1 -$WLz&O-5xFmhs~Byik;l czacui^ pLS^vAq~(%$UA .k$(i^|xW<$j8YsT[Vk0 P-k쒩B_AžNXVgzB]075A*Sw2W7%tWK+ JUȱ֕UGgjEtF)+uC4gPj{q9L95rc/]Ъ)ljYժ; ѫk5G'HTXsT9%N*/$eDPR Dr.N_yu98*Ыt pMdn|Z?Bx2Qn4bjӂkbJ))KSC۬{/qy7E:X[18jOd}րXDl^jM?RB^ 0UeЬ\FٚC˵3}/ X 8<2_MjvCI10Q aN$ IDAT )% Mv-ꮡG)uM- C֬q`Rpe?mAZJ3Kԓ0 mκ(Ί]W3%;Eƃl)lK@ǝ2Br_NXDI=(W5+WXl}Z!d}Ik(&T 3S5USzHk]}lqK)r{VyGN6xugO1J B>bqb:a 9TW}57͛t!xtƋC&+m!uɪŭ!MU)Ø3U8f=($+\ ix& ZK$,]6y&95p:~QL4 0N$3 ^\\$q~:&9)oŤ.eVXI5RkV|s4rjۂf|5'Vg"%6$3t*o}chxFDAA_dXaQCnem#nRܹHˏpe(N[>sHJ{/li6냘7?s~Q{;bc|IVØ\)?~v6H)0]m]<2_[kgΈt╍!+.(cOxpF?LL~ʐ n<]:~Jfbh~Tbi)^ei'Kn$s~~6|F?3A/L3g'|}χδ%\S-V/o<:_Do dksT~D7Hyϩ&ly WJ;|zk2Y脴ˬs\V3?徙 ?%R!!$g=.:'jH㜅f/04* ȨUU8N57%y^ v d%i Dś@GKһPnUqnKII7%9'WZ|c W Ur^Ϧ&X[t d3O01(8&׺q9(ֳh1]enV;դe<1:;>O.7ż& nB:d9x`ʮ 3qi{DVHLyHlxtb1Q17  +S.Ô(QA3sL4VejJdЬ+ BN7,:~uϤ;JRT咼*T/)ISPď rKVa,dXruBrn͍a̙^h%J GjWgV \[$*PJOqx8$|bhfp-n 'Jl17bKM.LV&xbYu [Cn#~lnaN9xe(ވd9]uakO.7^yx0ι|\ xx(a(7Jypʕݐ0-8?qS.6}[gr}/{!ͪI,X\4l8'J &H]&[z$/`0J9qNj2] rqy兤ǚjT\@9*\R0:%fIB*E$+hlL҉0ru` v2㚬cf&;A`$A1Su(IJ[6$ %аÞRa% ov-h:p !OVX|m\f\6 .TknAK zak>.D):!O,5҂W|]h9< - .n<0[ŏ3w"޵XgTv. A;ÜQ}*Pl͞,@k,O8\߉p-]1AչٍmDIA Ҫ F7st@*yY ĉXYH&&{Ҡ{nIJ7u񎡫.S)(.@(*pwƗׇ<6[a;L8*R܉XiڬfkO(ySfÖ`BĬ(:Q4'uK9d{@ n<}KM'9Ϝn>B,|w/Ԙ|zù /]P ޻䅍!QVRoo mF)냘".n ytAV\Aʆ2)݀w.Ӝ;#L)݀櫤y݀.aًxpJ/H$,OtG) œnB,;U.Umr}'25IN3hx띈fY HI҂g0 s )iZlvcLC4SU3|R9*Z5%PzIӂ"WEiQhȺ9=C5APN\J[~ƒSÔيITH&=A1WSxڧ*R,2=jus%}( 089r" v*~ߚ\%EˇhMxcʟ] :]"՝.O/pM/]ι+Mu:ڣ@S'yas(׺O%|{$-kBpik;jn);cpqL\вq-+;!f+, ]ы97:_C)zltc$gaiÍ]]Am=1uA1Q4-ySe"tk+@m)TnX%7K$]ZY A^ ~l_\S[|cg޳8`5PX[э9ۣz/hl_RY.@ib0y0A/͂8: GBD+q5a"j)x{[|4o yegO tWZoY:O,n9yqC Bwyp /]0<_#%/5y}wD7xz0j'K v;#>śCT3ɷV<4We܍-Ըxge3Uxig:n&S5˛#.Ѫ=5ipHsV?ff)(e̴Jc,Lڬ*qj(Z]P/ CZE'$aQq]8s50!Vhe9J+jyN %LvO-պ+ >tt/ 87n9mvtz/ff>R׺1eB2[3s(vz:ҕwnG=GqJa2\̙ lSK׻T-ʶ Nyj0>Sugpn·DYΓKMtCB~t,9?Yݵ ^9!xxƷ7tO5cvF).$\|$\ xp Bj cŖCbE5J Wn&-4ƈVŤj iTL&7v 6d15z1M(-C%=*a1ٰ S`QШ2z lMJ9T T=uH440Cuzscpa퐕ݐwNz<{_Yj\҂ ,,1uG4QJ5rЅ@hGdlp$gEi5!0Kpt c/hnWpMoB͖qVp1[׺5[g>G9g$j7`аó NuGgasm'4-^aUU`isu;͊^DՙFxcilvbUT 6:ܪ 林J7 & 4$ղs%4j~iihr THSugT Fafj<=_㹭;Ot JFJ9Qj<5baqs#+Xg"5X[Ζд짜pm|-'vjZW;\jߩH?A>&Q5uNpu KJK;k̕X|$Yl)n8Π,l];JVRpl cbF?m? ζ񍽀kpr檌⌽Q… P\ffsu/7Ua+~b4+XFL`u/kpm'`nѮX\ Z,mŖnk,OluclCcia#I ŵ46]f:?۴mLRjlLZHi:hV $. A(Si󮥑ʞٳ5IIR7^婹;ZJaaӶ 6k>Lyroxdj7f3 rk&R*9K-()hdBMww) %GfWKRm8J54\ՊrҖk h[h8߮Ru.w9SUQƍ~ȄgqÈk\:7sv{:O.~&Sw ^n &~K!-)Ǥ`:_^rasȌ id5 vBLX,qc cA[xBPt&&t 5M Aou:t ]fj6g MFgDJ>p0θ h&Ϝn5F\;QVޥ&H=v(N Hxߩ&RJ4mδtG 8 5{i.y\$<2[\h:ʹcq6I3ɍ݀GfnRfٍiδ)IJdB F?ҮZlu"N7m[67w"傝uLf Q:f= N/TI0/8 KHWH1N)k/ڤI8# Iը5 Zj:i\ШT: gatQ̤hD~;em^6sϓ3U3_Ovqu ԩ&~ikqsUv"5ɦ _:ɥ* .Z!XiL +&B KBH9,^}=9\[WRubVt,iAu^N)ۼ4}@v-6I(׏&HfLnSnKw}eiVټk^ vGx0"+'O;Äwh8ʥ63>r~ co"O .HAOlABmҮQf;?3LY>ݢbc5U1i4d0J9A|ڣ K6d8LL(' ju8Ș3,lOGHoрQ5 cVwC?Co+]$B? mRS\@H1(yC`,(PDZ D .iMjWye'cM;/l 惋MufV4W\yL+0A 3t'+\ʸodz}c|_d0IΝ;a$IJ#7}cEiJu\xOG[>PW]'MRK9Qh۩(Rn Zi&IxQv7rHWvz~Xx=CWގ:6W899Zwymz.9}Wrpqzw=>+N}$޴eǸ7LT { R*]N8y:ܸuuXŁp[Dġ1^m;Zđv-{8'[pFQ [N4t]nñ7s{QzǝCml6Z ۶) )G2>p۰;Ps0uP{ȹRL-QȹᡠN:w_;xh6_>M{Illls*S5<"˲C:I?Ꜹm+HǸ$q5~o&Yoey:e+ [[[`ia~&U۶,|Ml ޕ]vF5:κ4s<}gw iuu ]＀mͅ gx`,XZ2}{XTv<cY?ko֪ϧiYK]?2}uP 6)Oo;D;iA;ACȓw'_Eu5LOO#I Wh0?3O=uHy_1;>~8v!i$ yKYu^'1~o/ʯ~j}xjr:q-II,#cL4M 8'~xvIʻ[0!IH@ d4y^7hpU!Νl4G7A&ZxiJ$I?[]ץBׄ؎_o??~_3g'&5DZB4DyNDQxdžcYXkh&Rfe7 Nwv;z.u?s0 (Rqфo|{Nsek7#t`nnkWY\&c_q'qxTyqB P'Ӕi,KD7\?'j?S'˗_GfggjZ-&&d"I$%c8VQfgð0 hw8v n~E;i-.輐Y`;T\ƖBs)!r7tAtQRJe1M8%M$&4!#Z۶q˶ib:bommnڳYg?5Z}ho;oO|_xZj}u255]qߏ}r- wޚ o̞ IDATs9}z}y*]a0r+8_u~w~ȹ__wC'?'XV;<+NQVd" cF#0H En48Wx.z.#oxX4v|q2N-`/|,OP7~OzITU<סZض Hܼy5]Fۻ |s)(Ꙧ)O|?zr+Αs_5'򽺮lNggg텅˫T(,ɲ(JdVȏl,pls-za*#iRxy;ߜm%Ķ-^xU^|5槙uCVW7G! #(xk+ٍ^ۼǡ'ހ0 FH`>Clx'=\2{{jthgggB/getwү*=rgٿuBO陙Dn뵚zRJ9G"/ Lu̲,#3,?Q*ÕJDZql۱q2T?" 흝rKJy1Ik_wn]G[__O%4!M!h;3nmeYg C@ӴZբZҨשض$X(oZc$;wynkb?  %@(H !P@D DIB $<q5{zV~ܪ;ܞgw̕Z}nGwNs֖. ÞRH*ŘZR iTJtjyR 6iR`۟3f) V.+43F,+ Yr8m4j6`Fh MR$Am z=`sk X^YF۞sp677_]]}1unO~ӏ??jOsN<0GDjVkgt0;;vV9B`zV7.#677w̰^gho*Ug6~|ُs:S VԞ0p׃&`">VVq>m;766ȘyYK_81ќh'y}72=8ό ;;; tw@kiLC (^o,gȝFIv43cBѨ4iBihL&J ML|յ0"2oll 2,..7n@ޠ{Y)E o?nۼl«t{~$Kk=+.1sDY5MdfNQ.\h"03w:锤j͂kK| <@ns ͷ$I$0ayUbVW׆UI6c"J1$R<\[[`3K3 2gv%ȇ 䘶cԟ|r˕-x[EBz@)񭉉A?rRj _W3$sGŊcJ/Lyqccc/3??+feu"2_.^ .p [}珽?}o\___xY!sX`=Y#w]oehflPxhc~Oo}~o ry? X$oss2 !t[;OpMj4Is109cLb\4 NSR77짍-gH1059 sNrm?, RZ9?kQsc=p Sdl)p\D#v.m4Z b_kMع"ϿyyZi? qjqjS` ,u1;9-DEZFN;cށbJwuh0`D &qls%XX7 cf6ֹG˵FxcWLeyvl{Zj>7#j2̫ Ku̵;`f"*WԔi 'Z zͣ0ڗdq^{X*W=EF.wk];vxGOfO%PP<;9(&Zٷ4' 5AZFAUY %0~wlG\/#Q0.'EKAKĂVL:: W{b vAlj(Nh 5 `b+Mon @/4%KBIq$& ԇebf.x;mm@1ZݬWd xX1+xiIsڝ22&d˛nM=C DTBHT@$E [ 9Jܣ|g.L+az139p!".VσY .ℹ%&C0lQp,3s8a x2JjQ!ʾ*QЈJ̓^S JG׺^s'?"KLY~H*ZEjA@<`l0a4PG%#T E bs>Θ,#rݶKֹغU)B[Ȍ ACJk]/r@1ǥ-77bPX[xBKh)}]h"H҉ֻяvi:6 ySnM+vֹeQ^ݸtp2!XKc?1XNN|\ތ%x7 )>s`Z 7q%L<)cc CSh9@YEm֥qcfoIzahFw1JR.M')ĪB WcYq^ Zş3VO9*0($BC rPR[HRsr_̃hY7&ZwyiasxQc:r_;l#y!w^| ;JG[SMVx ~l^Y߆F{yΠ1sQZEZ^#Վ}(R96[Sk a91jSKNOeA\Ja)?h=)dYy ѷb13A0 #K8 A [iJ@0t|I֓'1o9a}ݛv؏B+*(5~zu7@PB#ȽL [O6yb?`b[)uWؗhTO3;󮤑>|\+fF$hZenJwe:SXW6:6X^l8\fTݨ/#َ0bĀ*/"F O)(Ma/ y:!ڍpkIӝ&:S?dlB)-_1/rA"ch4W^6ϫ˺I /-./> \x5Fy%Kkti5N*ldY-}r,x}@eY)`afF cLYz Igͳk/BV-=:* X^^Etڊ{%A2^!*f/n<*㤀j !Ezm[J8ZtVM%7IRK[Hnczz"'qX[[+VecbbMϭ8qIX+uγlk|* aehi&R ҚOEm{$̦SL3\G87Lp f$>0{Q2A(B5>ʂoqc }v`&6*l)&&&c![[ /y@ 7<&^@s9""8{|rk^]_ۓXMVU''mk40+{Z*<-d/ҋ;9 K Ua+9İ7~嗟7(䮇yYBH8%fqGwwiGHe(T0$9*)W$oz/6[i{A_w{=lz A>$Ie2[LZqeƀ |R*9+K_βl$ l]z((ZXVU9KWIٽ& {zZiCK,v@lW+fIcZ{C>nXiEW#V1gT&Q %L"w'EZpuYnHv̬wi*[J-zp^xF}!f6q )D&q1!' ;Gw:pJaM,wSruj^]VQF!Cj~ُ8(\ ̜D#eA;d7Mw!H{bgE@a 8W"J׮bfs^}b#3~^p<$+':ls=j\KG.F#2L ƥ:$}2 NN0jr `3J_NuǝWn1i%n~~( v-̌VD~]G%sϟ=7oFʑ_j()`)eu}Oi$eN$li D鶲)t 77UIZAr Tmhvgz"IJLPD+[ijgZϒ?fK2!~*<;9I?OnGԹ ''1f?< pxt:+0'H]"*l(\B~qR;c|[sjmlyx+swq._Q{9ډFcP;ISnWDn3cq`.EB XZ"Z}Q]en(̌a݈$2ܼy,+W Nx*Ms<,pM|tjǝs>Wھ5^QQm}\Qm&Ӯy3|9'C Q@WbKZFr &lGۛcMy[j"0js%-^惺EEFqA#2ӻ; TbC̉91")(UD+țqHkѦPyME_W0aț6$x*#}huN\:8WNd6 Vy:rY >>c`^|쿯47&(rj;};I#W]IЇS=Λk,S:`~ b61OI޴ǕT),F*Wuh c18x87o@K!,@IDAT\ryag0;8j ʋ,7-|/3v;S{@\j%YT]+y/2Y +Vkڄ^&ր#L I q*qD%tWPEIumW@Gl <4McHp FyDQ#},(xd h+ΝAWj5gf_ 8pݾmH%`rrtTGtt';:f+++hlI_ijgE8Ab//_v x^_xJx333z*<'?#oP4 KKK8<$IBKX^ b2ώ`'ǏQ!/:"#!*C?vy5+l0sVUT(A{yc<{fV]!bE94 ^`O*a~LSeɐ0 [ jX[[c5}۶ŠiH5A3 vv4 ZrIeE`agvawa7jh(X,QjnvYHM ?qg" E  t8a%o V|N.ǭzEAU!UASV jBR7_PU1i !^2 eq$x@!@4C Th.3·2:*!' 5P(t0=D؁ mXQmIEP2Lk4 ^z8㓻dT.P,v0=j@*ear\!]icA벚BPfWΦ |hD{cY:R)0wP.X3,˰m^Be P 6{,vL'XmO;* &iU\C>W(X'Ue˲c3\:)wZ"DE97xLG_.\1'  ]W}f#?B}4:+W?! ˍ ?iȑO]vRÇ|{ŋU]VecLLpt㈃^&&&055q IBML&>l콴kj T*vh $B1bamR$d=Q(M$6\WdfF Vх .af>6_{ UUY" BAuBdƭ[[4}*0R;88677}jE u+x?_ qlllѣGuk ɤ?h_Ӊ`o/H0h4L&b+;̻>x:* su^j۷occcɘn4D|~,R~jٳg4 7o<<1> '`Wi^ݻw]בdQI.^wB;d^pT|˗i&H"i{.4M^ st)cy]&R)Uh… (J( ,'C8x-zT*X__}D"Tµku?sѭ 9y))xY kXl'Cn~->|@Q4J/O?]l'8:O 0M @@iqDUUJ%eϳ _ e?w[Í/Q(?M|*K_`{;"Xanh4z RR{q5}I4Mv tXUF0""z9M7Oq6287be ~^pҳM-byaZ+$P*u1?_>h 4.{Wf襩J%{~oj:#3F1Ѷd)ɤ|LMu;ouoq*@qg g9.+`j?~O>fksm]fVak+gy%C D(I'_^?Qss \P56HNAE*aD28:Z W8>VaY2 CiF2L5x܁9Fr&&'(:(u :&&ǝ_=+Giơ]WAըd\=LLZHךY3_ Gϣ IENDB`vokoscreen-1.9.0/pictures/sem_soc_net.png000066400000000000000000001300661227001500100205330ustar00rootroot00000000000000PNG  IHDRXbKGD pHYs  tIME"' IDATxw]WykSiFҨwɲlkF2`ml&l RnB !\ner $@ bcl%VTM/Z>{F#z^z~߂17ܘscn̍17ܘscn̍17ܘscn̍17gc˖xCW_}?iuvځ6`R4 jD`)#R*#cA @w@㦛{aRl˕Rk6B\t 3_c&;@> BzϓH))+KP]_MEU9U$q옍B`ISp(sr,44cS8i0gZ Wvϝ9PmJ C*4>PczFJS3I.L/g9usiO, {B7]]wAW9oc]R,n-Y}*-[<\ p' Ey|@./)iiC)# "(J0Gs=r3NLc֥i]@[[^LJB=SEڗ-`54/nJęLn] R(E(0 sK126E:c2#-J@8z76Ty͵()L!2Q+<p 'cHO0-)*]v97_~#VJ}Rv블W;x X>0?$\˚ J)Ўv8z97…) ERtvB OJẒXbI|/j- 4)MA2YOFMH0\b|G<ɉ1 PPJ#]];wX;::v|LRbȚ+y^ļ% L0<2Ik\Ksc Ņ^A 840 _4  mnuBtrմ4!f'A4|H)*ʼn}8>&DZlJ;vE%@:;N:;wZ)Bξ\2Ut9{n=B Ķ-56A^x0\25h`C30)pX|`UĔ򤎒N\?% oO3~1IynLT3m=xpcǮj{ utth~ \Ϯ{'56aDWkZZjݻ9g9L@B3FZD@Q, H5N|QpX!99Ēڌ -ǗP}+Ti )|F°,N?JpRصg?ilvR1ԃB| qy[nUoq(]&Ҵ4x8vfWXlZY =3mkZav 9aHURQ\EebjJJ)iQPpG%rxGԌ /g)& Uql͵$s:> '_Z ֎MBBE>0z.ǟ|ۼ)= ({Yx]Nq{Re[%cz Y"0(1arK4`^B`ebY)LibYoضx+ӾPPt$ H&PP \Pd.Q϶r$ D W ;3WP_IxT#IM amR,lŮXʷۻ7? xGB;/b ㆛|5B u |'0UeTWqM;+3$X0[bt , u3]FUa= _#G,?f! [gG>,WJ-o G^^4|eAuE"󏥌HZ9rӲfF޵ks m!GPJQQU|]88'O108NeE8'9un۲&\G:l ۮ\ `H00Rcr*e졯-6 9 Q LSߏpb*֯1H&S,U?IvKP!8\7aZ,]U*_ 9f"n0狌N7ٳ=ñd2i1 ˶dUKi_"4wmݳ+o@˱u<pU/ R 5|8iH?‚3.LCǻ1L"ӱiLT:Yh6im09LJe+ !0,SViw*cuu[:E: >$B! ='+yҸ|WJ!f3&|*:8<ףP2ڛiTA{K55I.lfU`tdqB0v={>[grnYqϣ494Gb-﹙_ҩ ga;;ĕW &'|߻MlM;/vJ*],gض:]Q_]HM#J463>(SY Ǔ?^ɷn’xRjGe4Y\mxIɹNg&,OxZ]IB$f,_I}Bqfj*O"|q%d=\O0Pғ)Ƈǐ~'G8v}_\u;`#(]3 $9|c#c=9#50-7 T~8rE4{{'',Hlk4)ۦ~"V'uQ`ڤ-jhjҙqô!,_T<0җ4!eҲxe $߯-b~TR gZ[/pIwf,QOzFE%QbF^166s]];qǝޝw1ȸg !NGP)EeG !8pCLCYtn^2Y0j\ߐeC&Izzp6 !IŒrϫ2~I{{&{<=ȡC;?Ldt2î],])55U,ZJef}{^.Csm+Q >ߏ'iEW9Nd2 9 \ϣ9䟔Urˇǎ鈓?ɳy=GzClc}o5ئɢ ,YЄV-*L3on , *,N*? jkqgȏX 5PQ 2x$54E+ΟS]c23RB6ߞM7OKF\j9ǣOP/'GuR45$0LyY _@I@bI 6((ίcբ7RtqWn>}J aI&Pǚ +xFޣpT}Bu/MY^j0 ]^JJ]uyӘ ,_RF5#pz/ûeYllšm࡟;+8y%QqӀ,p2jKZܷ =ãOt~~)ReKX֬C#p'| ɑ$Y cUXDGKC%71q'ABY'>w_#FvkN:;wE}k𞏼GA F2<=rB@?w`|?P(bY&7]{9WlXa )7I1w#,A-CekکH| 2f 7;HtɫoӟQK}l~B EOi?HuL!qGt? Mq yTELCǻ5`: !W]+/<~ o}լ^:sPR͖L,!ǎ Fu4#ߠظ rwsg r9|`R)}{*%P('T1ȐQYlz6Xx\O31FSTUpJpC3ʑY|!0L37׳jUof8~<}!3RD"㊅$"$ܢ rWʁ6@"QTG@^nL2+@:)#g*<8! Cйy%[7}ftkbǬJ4beTܨ#IA208t@ຒ\# АE"Fb mR)A* c}DUd2 |$Yg,[@JE( `_FYuYiٴav̦Ptt^T:|q~/fAHf?+ߋWRmqR,;H\WuFCuol a(->s3=O[ {(ޟ N#'E.dRlLe8rbo[6n840LWz8.\1:1ŃÑ#01c06&TJ{%P *&u6QJ+Os9|^S/Kio,W: ^m#d$D0a&T6nQ9(Q50Yz ^$Aθ-X(P(q]OB~߰xX" @4 ^!XKu}-|v {aCEҙMUTV$h040 A2a=G1M?پ7U*6i嵖/ q `lJӄ KüXN+.S9. LN*cm47;0dB0ͰLv?vѱIV@<1^Q݇Ig~E,iә"l _U QV-)^ΙIl&RS<=}S2*Έ#uG=J)n}?JzP#Ѷ<'Ȟ#A4aס>rԘ-AV}_JetbI[016A_TESm%g;e ٺMQQ.p=?gKJ)sE[No}nYl]㡄8l%>" pR1;X(΁gQD IDATw CdEA0|VtYiuyYVDzz/B)(TWiIv ;li<.TT堧G ~n=7x/  [u~& K(SKN/>zG(+KRSSI.W``h鈠=vl$eQW[Iue'T䇔N{ Gm G G;&sT$cV&C%lW"}H "Bٹs>x_&o^ndBhΣcRJnx5x԰ |וWvI5jQRa*ף8 >h`b`Ll!Wp]KEY<e"%4x(RY!A>cu{cК$mks N!HH*PuD2[;!P>ߚҽoeρSgز ˚YZi Hu](%;Ţ}0H}CzhӅU"fc`ۥr֯\%Mz^J*uF<5+s7^˯ErD +K=6j<Q@zMN?"c/i r߱~v-X*ia ӄ"$(C <zMXMSPrCBwtl]w IWJX3#8!'-[ޏaxWضma [9~,l緖 RJ GRtLr=&ʅ%S #VBؼv1,:A:PiPk5k&)zzu Glw]Ey)_U&4N%z%ytAxŵuu y/}ERSiܥK%'2b9={1C/Qݓ>;ȨKQL eVO4BpFK+*.Qܽ@~gg;A{{,/>>rk$  |ծ۰,m 970q L`TaXR$dm]϶ˉuR <$F#TU$ٲq1fa%KHjeq{"8}/)ek_zA,N'!+$.ٜԔ"IcT > -)OT&m\emu!IgOscgq=m>Hwf$k̖̐mBvIcذ[)St9{?e^1kv yxՌnG3_ٹm?R{./k^i<%Ih&R{q=Ow-KJ! $41k+E|];݋ VÒDq ?}K66i0MˡiH&ߩfj"?|Ww/I&5A"PJ 7RQ(07E I$׾Nwd*Io9qW?.c N2>%wJ5\ 0']JK> $r3H꤮B%WV(% zz3RHCgJJ4ڵtl]Ƕ;drEF's870qL1"s7 P/ TmlQ ǙUz ՗i dr|_nbՒm҉d9p۷Q/ټC*[M+Z\+?.`q;C̶0w @SJr1@R\TO2#KNy\:bjuu߼*&֔3_ѱ}a;WZĊmMo'z'poIAjBɇDWWRqۯ  1n÷~+GO>xHG]dR}kw>@eAY"eDRL*b1kK(W%'OPG]ˈh(/~) Q(:H CёETto%sÖu)8w~oINZ/gT<-F/DX+6YojqrGbZ Ƒ;&V@6-̃7efI@`6 GCcwa(W3k3dMQʪ׈?,w^ fԁBG# ;.ضm/S(?XZp?mРST| ։Ʋ2H&2-Mp˳X!XZ`xDIzdJ#eD5?鬤Hĥ\H;le&߲Wm[AMe)QDZMS'p`A}})@H  HA }(OGvl᳇=$k?:uȓyo(R*F& :w1JH Mb:3(qO]lK'{..崷r'_ϼ &LkPY(ERo]x)H)"ˋ|wNw [/NM"#Y]Rs]z~z\6m\-t\`>٣JÛ;:%؃%$^UPJŀF 'ٿ EU(8M!-SRZn`Ɵ.Yt>׿h-UM=KJ~\cFi(b3'UkEoyi3A6XoEra@Jz|%RJ)oϓ,[ʍ]-gA[ee -hbE~%.ca[=eฒ8[ȅ8xz( O6_im|Vbx<3t7TOTDY!ğ:\D(HL _ҩ\(G׽gU;N~]öLSt3wß bFBWB nČR>8(" 2"f)yU#G,ӷþT}bKFƞ<8߾G̙5ha3{ Ӭ[e[g]p#}Ͼ[dשYͯ-kZ;? +ƩO' g %UmSu͏ ^r@V1COޖRXGuK\ޗ9 GH;pͳ5]r3,};5(WǕfJ׵,Y#$\a[&-#vO†5KCh/k9DHwF b2KMD̢ox?}\sݟ(/b1[Hy at2)S46Րa])Egw=_BK! !Tm\Ab5|'O$cv2ӷϼ(y+:}QTE,tmh9iƵ A@!f vfDɕ(>7.('O/B1>\I):6JrN Q:thoVb.E(a"rO):._AueKRP`8'a !##F M+&P(pL&1 ]\>a``p\If 烣YSgH0wk~ xycvMd@1He ΟgÓowJ ĶL1m-qt- Zqxt?Q(( EEhR P3̬J֯]eI6_JKH)YvfǣʴLzxG͎OC*S]d"uxS|'mMU>H,qxY$iPڌ,ReIҿ,ߴ{@/5qvtl/7 #cE:}c 梔`Q,T` \2Ž5 C*89i2"Zsy,VF2 Sz R?I0>{kUVI$$p],[Ҧ_v]Y  Rkӎ4p)Cc44?(}}C8:—Lm땗Qt<]t4C q˗)kt?u?t[@Q^nBxI/"r/55[:77\2 Of 3CgЄ))JV,m8=Oҹy%[4*KBkӺ8N_"(Qs["s@f}H?@4H<0AQY3㩴u9:4b|2d:G:#ɒN1 AsS- 4U3Mɰ7ׄ_Kijq]&'Ӝ=ۋv.2 Wx/_}x/v'Y_K|bKNy}kI)-Ĵ">pR,j\Ճ\9Z &g,ӶL Ozg@QXA (z+hm綷]pg JA}̯^Wp5sDͽiL&҉1",n*̃b W}6! F'2t7BwSv)zRߕW\E!B!Ӕ~[2mDJ+8T?}dsE:#)O P B,M&_zO&C"ϲGAHElkg_SJTK8|\hV65`LduWv!c@Ǭ((9u0z[7m踡W= b%©ыzpqmT&E@$uJPaXuJgI;x;>TƗAgI^Gػ8WlZIsS팍?]Ƌ_.T @a k/?7w} CPO}tN^(WRP_α͔N::[l.tJ19%5Y*;o2B) yNzc%RW^JT\ "ѩ\YV*}#6AC('t|XQ69g#cϝR3"Xa]RW]$κ?Y S{J {LUː.m^7Msap.4FL~?>>_y;ٖ;1"f'mN?eh,xHE6I&LnoѹX\W|#W(26pm3.199n_{PJN&rб3<7T8'!XT\`0UZ} CYsX5/}1xJ5Cҫ^? Rᡅ.'_( O:p=WOzT:邅e6!*+uww =r{qdd# Foa[1Q)K ,'XI}uYhdV&R928_Inb hlłaũ3r3+(36}V8H$szT)uuѣ7>~n|.>2 Nqa,_T@AaT+ m!x[t-e5 qR8cVpT'`at1m!"_1Ma0jU5K?Mt3 BcS=(T54Pgۥfxx ibY6}Kopܲ Lز-p" fSa#OC) IDATBԫJǴAw] JH')} Ab]mm3Lc-6'Gx9_gr5,Z7OQWo{躮9HDR]lq{<7'+Ko//d+qIMl8"ڒmQՒHQXq9gا^b*X{~~ulLi-ɵQE0?} B+߶|hJcGD4!֛pqɩ9&yqxʥm e;EH"F=0qBkCl}m[ȴ`i,$Bݽժbɗx*fGք0*u^dk$"yutL X!eǮ Ө$F.vΖ8P̃68.,3ξݣַICpvLQ~Z‹/X`\_HGmθir/ԟ6J*@kW%bRaLOe0.K.i ww&~_-K!!V\1(2P~oEYFD%Q*GS&0:n~È*2ܒ`9E& ٍFg4B ZMaZ'j]rc &Q$s(\{nU U/%T{g w' SSփe%pD`|Cr喟r)Ξb͚XM7PpYH!~|_Owu#r!FaXWW&vEeŚHf:`琌]ilz/N/3lhv[F;GB%puj.LEt`C$̈"L6dY,oՇ#%#XnGJC(q%SDb!GkZ˼E 5-13X ɩJu #!?K8-k@]".|_d$::0Ve<byoq|N/-leY{c5ۭ i@*[yy3vNv_.B /RC-T5Wr"#:,"z{fväZbnz٤cy5LҦ+<2_I$g.C¡H_=Dww'VEF8lT(\*]\.P)Xedq w+cjKE>1Mes B]B?R.6]WoR 3߶COD@ qbWm_gJ"JH@aIlfCKYfR2Q&Z2],i \s-/N&Ps7~6Z \Lц(aD#E,i_qZ%IG] ;Gs0xQ@&ɦW*u鸓b{טlM9obe4$:X=@D6cN&jEpPC؄סhb@9r;3qsIg+w:`a//h5\MbI33UQwXjnٍvkT [EFO|kJ:JЋNx%7}[(J8Q$Ml a䐩*$=`chzV,KMi,ҩN-uGꀅUu888iXDٮ6"0"A镈+4Tqvzu,Nc_iYJɡ+|/z\jUIP]8.8~\ r" NiV0 7KK(e-Rؽsq?7 x4Wt sUVU׍Gy4k h0ap@:w,Hr9p]f I1*^H!$Ev| WR̄L+M;:ڼ+{ydI4MQ)D]"HU\P[T#m#I7izViy [fnGP,8J>lV<q:_AP/1*e1|j$CE,8ox>ΟϱcWfáِ4B`낥%'ɏXI4j}{b(e\qϞcJ#s5`I\+fNָC\7;G{XW}mꤔ# TJy*Bh5`72;\Q :jXXTX늙l-`$с4¤^E{eGe3GJ\y M5㖱ՈGWf*K C,hA48ïYa&BEӝE=O=VOFA>I"Z@i'=ŸsQ=Nc{J}t4yXn2  <d8acb`51F0/?]bޮR'k{uv[qQ3bYJ.'@2>]ncظn=qybqxcNB:<}6lZp KKk%LWM%tD5dNi@ !(tC*lLP0R0wڢk;UW*Ba44K OOm; Wc,{7"Ή217Lq퇄a~ur.nϙ^o~v!YR) yP?`8}ΰd_|Lqϗ[B`k HMufݙ'J4Q.H.ò ZVtxp\+bm4133IB$5&zdGn-܅.*%fP. ڋ/ja|Gt sge(B+Q/5J9`hRBGച"wŒ鎎m#X.fVgbrqpîֳNݾFirR ە`~?c]#p'H%-~vo,O$ |dg|d`tlCv$\{V,p̭jK픐b'ZJ͒,=ґ!uRY·T5|fW1K!4k)46bcRVh 6 c )K.gh{߳BzG1vohkY5GKTk E{}C< <Ygq'w) \u5ᎆuV./ոG z(ƶFzyAT*E<{$_M6BغM+;\r E-v_B=:UfyFf.SZe (J*% HZ ^p(Z,=^DJt#U I1+;$]Ae ^QPp8LMP,j|_{=hmԓ9 qsǾ9m.W:غժ9b햙 wW\\XC_Hyב\s VűK#p8)Zc䅺H_%*ޔ9 fr/y;d<݌/,.M(..Q,s0D}?!2ShG&;N,ҳ +`NV4]] )p2&U[ !A!up](MC8f͡^uz{-S A qXp}pYFQ2l-*|YN9uvk>PXat/FzGtrD1itۗ̾zuJi"]SM&Mvܤe]c葔$"+YjmґJkQʛƑσR!W;;tncq7g8|E ߳QaiQp.р;`NX?6o8?Gl*DwO˿K< [( ogb}- \\s]T/TpQC%]>  ?tg ]?'&w CK2}9]oV/܏x = 9DZ4:#IDzLI:U=vFH%~ {vmţC$o'8lJdâ,M ݵS+ÿG{9uzRhi])QJT)5d 1Ǝ3uv@Y,RI- 9G>87>;ؙ]ݚbQS,: 6n Tm.‚da?ZvUזMg<ʆ 7\!sq{X.sgszf#=9Jy ~yvc+(%|1?|~GEAvsw.'ܳ咡Pbl ned;&Zm$^Fg&c)}uFl!틾U`:^T4IhVkT(ԕ=t6&%K ʥVUFX~9_OH"MIdHlܾslݵh+2U|M-Yn<ǎȻ4lOial[.e9gj瞫f ǁxj59{ex `&ۢ 9ýR@=t+9ؾӂU҅gl}&~ Peμch-969æ TttWIgZ#93+%)Nz%Rԛmff3UljF eZvx I.JÄeB(#u\cR u!d&儤MױXYC:۶؟Oٿ㡯Ѩk_}&`l&J-3Ç)ebt<+ IDATw/9w{t5W* /1i`qj ]L_q`~NxBcUCYK ^'8[]6o**)ch=˥%A"^n Nԗrf^_a>x0pۍWo>GL/ W&4;b:rj戄6Ro,#цad $0 8q D/PHe'摜@O ?>T*? ,-j=+`}~2$?8w4_nUQP/q @ z{&;9yJsaqAj𧔠o/?0_ K2^;]*|;7dMM <:c:I;d:w ,KwJ&:wn"HbCX`U[cײܤ id&&ڇvDLV,%QA|m/J֍m/ :1c(ff[ sOjaa5Ԍ[9}Y7WE%9Jᕫ!@p1HOډYez{鎎d}Vl/+܍{D+D tCVtmQݺ빰Oܳniy ؾm=֍^T~fv1L%#Fcb#R?:o( %}\bUߔ1)TVÑs@kPif+6_Ey\GcƼO_<>9f.m9f5GO.GYh82*Bj?= .GB ΝsYdidFC`zn Z-ʝشqm\dͲV g\zx\>k~(]嶛B/ƫRmz@0::Hp5 wmg \؉328AwDYXptaMdl @LUE,1ƱQ(G x^kap 8,V[vbX.gfzf!a~|)=q(6V6]ؿ3gml{\rjg{(ʅk["T >"xG0smhRrv]z:@;p &Q7)NMXMagJUr ^M͍HS) ~tu 3Q X9WRn72?qc|2mJ _)<<@~`Ө0BB𼀖 )0Z]V]oi{-Οs<ɏ aL͚?a1u٩&Gͷ8q$'N\XĤM</^-c,M (n z`:hnްʦ̓5 p@l*жT =z,ɿ+LMfM4j*|眤tT*np[9CYI9y_7&gԐH }>"-K@tQ W&+<`CFN111#-&'Wċ'Bf~@4J)Uڍvgw\>'79WB打|&dzj}l|mR)^/Kk9vB1~a @_Kۃr9壅jM-y025.x;z\}b#+`ottI)9vl]YLMap `VzhTR ns,9Gu+&t&^jbU1-hb^Xs1,r]kJ)6fs 5Z-/4RhYk[O={s3[3$kE}̻-GŃB}umk:aݼu'\" l/4 ?r)D,)sC>NNS*4O>pWmd^.{#nɏ/l(ґr%L,6id y_j2:Ę"SS[ˬ֨Ӵ{"Zf&%ª\ "E(kq{75qM1WbN;R #&RL'MS;@ۄs.GS|ݿnù 0LJW_}ŧN1'B_pyp[8;O$*^):ۋ60}Q7Il§>-(\6lY:nk?Q:\|['v;1yn4ZxtOMOh3z6YSX!yBcDE} ~aH K۔vkBǧ;06Kf(\zh\~M!yW&ܱ(Z[=π5Hxu1ڨNgϾ&c!hҪuӪUh,uͯ|+Srg%}~׽Ndұ?8L]\<{k5Jh·,qeMkűWr`V;5Fl!4*1ڮrq9B_"TX| Fp~rcٴa5WL>fX>NSN$-TQk. $Ijvy:Ξ}$24%J(:nؚ)p-lMa(R 2*\([iؽiJ1 x@Sp\ZѡR,UR|͚{C0$aɗ+ⵀ]wں Pc]Rr!zIJ^@ױc>ķ^.TGq|/J|JZw7y[`zpg S R{\nAKy 8tU؏W1%>޸@lڰ;,PNTf:̤,/M}Ϫd#+"_Z8{fu.䲉Ktv=$T:kW O%Tβz{~֊ v֧Ϟ`zn ad|! 7f=s1%FX?qvc,L_ 9/P:iJBmO1510[ʗ}7jS.! ybu;b$G2sf F U zMppg,8^I%qeϕ٪a!nصOM1@i>5y-hCEfOf*r;-Br+cVT=Q.-4r/LɎ+qq!SWОfNld~`X0ND!d$=! _J1 W9%v&2[]JQ^6[|x?  O2>u}DQ18:}]BK< ؼ; ,6|-D\8O4Wo֑+x,- rx;㜛Z+F, LJwݸJ13G&)nFVYĠ 4o2bYq*:D\1[D,{))d |a f/^՛3ԟ\ 9J,_"ŒNZw%ls.{Xͺ _avHH =%Жf/Q~B9ޘ"WkٛZlh!*pApl|v25z xuK"`. z<6噘O0_a~[k`7ogvssDH){$,nڱ)dAq 6Vӡ||M7rz9F+#K9)WP/}tHAεS\N2 +װu9Y*YZ3O={/P$[Em7 r0 ~-{JiA!/_Od_T_u*_=D+1;h޶o=RZǦi{A fGO{8:2/.ɗN`i$٣\c b.0H7喽9rfF(|0ML[$wؼqmum("sK{nLoEs.;4@u2ƨ#Khđu$elXokk5v %h GZ%Mq-3=KO3qf yE?ؾMJޭNѮҩx'?p{~oڌ !dt8_II4,s͖R4!`≰,,q]=^榺i׋^JϮClEMN/[뮝kBꃍݥX5d;j' x$Qh֒\8;o=V.M\G{,$+JkVUBe~z}vL5= ?xg_oCNk+Mfhh| 9j;;O1 ;Jk\٥cGhlh0bn|#hOS=JO|(fۺAy@qL4bs\w{LUY1Ī!+F^]H͒o>tv)X8 ) 69Gr C^V )` ?ox;&6lk ^ȕOۂHowkrH~[/+7G1.btJl9u/ao<9@unB9?yNLynX.|$MO6lޫ KuZS(J(hk5#8:w?tFvF aav66gpdd]fs.5_+g411+&Jt 졗)$442tu;O_f}i鋚OX%fOɱy"Hǔ_Ja=q gRcCX-'0FĆ ΍= QԿnM|({\qϏv5m+s UꘚEiMAϡCS$~5aTH{ vɉY~E*<{XmTX^}a Նxuu :"-YɅj|d*-x(1dܕbXP(][-\Wp~nCo/݆s笃+PA710y{Kv\o?wj30WB>;=Efg|ǿ@ƾc֯qf&z/> #ݴ}әoplF+W2;vZHzMѲRۃ Ө u" ^d|@=p>@;6:b$\mzܱív@"*.|E0/D4t@ċM&ezt?[fbr1>DV 8Xo}yuFX` I>YX';yc~t ]c>~/? ;%RG[ኵ hOiNMV955L6ЬT.111OTMUR**u2_ |" 4㡧_fpǴ߻uw߹?L6::T"ߛuL=L*T"l:"Y"u'`]4LZ!?ʡX4|kk%ucܴ5=#:<5s@G hi)*N1p)Tab.7'L,uoC)h/? KveDdv/qxɤ;-)\DHVIv6~ \K&#DEsb MGfwBh&kAvIH6 Q)DfE+%Hs1z 9'TWZV(@IY,XVT)qz;a&K+DywLTgڡn>pUyVۉvD5\ɹ&^guAH3d IDATSH+FNXsĢ(mI2n^[P( Loc֯jyK yzx֜P3+Ѐkim) Qݒ~CīpW!R,,nS50:X!{K\uu*afQXQ3SdWqeH{F\.YsDBAeJ/i5FݡQwUmIT2^@QU/jHs-#9^mwG j>5y7]MuBp:l̴-?gR1:0$q D>SGmjb=spjb1ZŊr4"$zX IǰH^#eV޾nlYwd|ejS?aHW@2bXcӵx<Պju¨N)\G05^9W]+AnS{=teL4jЬ;FCШKjU}>{ !_ZUr5 R(F%ڵσu CبQ+O"Gb䅐aeHs9OURi7m)e}]A8y'ZJF򨟛kjQ2sd }.6$yo޲ :͋Lpqӵ>ҹečۇjS?"V06t5/prbن HcRfq*Y4ײnHO,Y E{u%͆Րkj:4F] {h4 zz5oc 33Zݡڬ/ []%Rza !c*6Ew˖-_X.kr&&?3:z^;zn旐<.5Zwhv DF6Nǹ|F3Q&7"KMCO$N {pt|/Ԗb'شRf+@ەl_˕)]@SkyG8,F ݜAFlhڞYEEMNt`^&$jtEDںH9R&aFSҪڈ5kz>qk^}_7Mcc_{$u{{O, BPSRʒi9HYvRV\I䪤O8U˥8.*[Q%$JDK|J$HA~{3?vO>ZH{Qzgg1s9\ҵZM:g}3/MMm4y׻n"~ P]ZE~|K~(a 0sQm$#6ZD+tkQRi$CI_ݙꤧ`ξ42׋rϜ]KLp :ZG|0ZC8qhH"e3%\cc|)!  fZ@j xfadDomLzBr9qxd8V;GJۮnJBCZG^8hSιB(u+++GUԧjbp0Z6_8cßHKK?8 wxM ^|`s(lwFJEHϤN:t=7$k a^-" vM#3Iymڅq(E/+M㺩anoW5ўl螱(A+Xm6C4"h2UPnMcdg4APVzk| J4֡nݭwH14DApmpae_ GfZ797^"(!B8rE&cpyF+ F!%0._hA+!6<?:*d'OD [* ȅRQ,9PPt|J(r Rv&_iZ_eBȾ}dz5!$R2!#s>kZ,H m[(SD|+Rȹ$Kξ M'Q\ar͏$ä"XݬJM R)oQ(195Ԛͳ㤩fb 8\M uA)ܸw7B!BDIRy8t8aj7|ʢ\iO9^ !tvؙ3 yz ^|ӹXKe /:]KCy!m!%D R}aywkWZб, C!m}&R@a) {?%2BHR(PljDx>OWQ {J#PQ뱸zb0i0/!}0ɩq 9d2.7t)[ue[w/L$6|'^&s~j' G%HSKB(Po71(uVo!œ f\xO)|9 )I"_EEW=Hkg3.et!qųJJ1Is0=1$ 1R?gϿtȑ?˹ #Eů▏\dûr PF孩.6B>] fN+솃2ٚMvФޥoz{w5߁a5g*xu E=cyLr( 2 /_1fp|Z}ATP4LhǝI+2B;w"3Y64r|OnͫzrIk{{}4w)$$Vo7IȮP.ym V H g_%x`>; ]SKCA~ t ~G EQJ#G&"&{H) Pa|ߗfSTU933#ͦh_ {WcǎVVV36ܻ)EEd-uE| 6h2Q?*E%IS* QLLMZ)2Lba^.!l0<8`$*Ţı[Wo0(C6j@ |@p |ߠђ(YwޡA7k|1`Z6h @i|Ayv"FJi#&?纨ie RJR ", d r,ggge'zjfmj^%SkM@Oّ'oB)*rM^Qtq2z[¨Cn y-5= )fgژ>u+G +i_!E>hjT ZF$ ͢^ HAp]?%ɣEGHoj@0 @iĉt ԠUDZAЩZܫ#.XPPJ)ٷ/l,[pȔi%RR\renF!岜RJ6lL޴҇1If\RJ,,,h)5]^>RidJARwOYQȸ |hG\-f$v[qbj-t@ zYf.j=DrNSqXͯhFrNZѓMqW oC؆B@#|c ,;PszoטxǝL_2x77:HD(e=d+Ǟ=ޣW*RJIu%B9WAv-\ZZrjf{̫ Efiϝ3/ UldR Mml^-f ԨAIOx  CŮ0mn })t㑔fT ή7L $0001b|2=oߏ[nӹTH[WAD}neZ R>fն*z^3g|BaˍalCB j E^0,HCXY&&mLZ =1PRwnzBXnb@ԑ&AR9SaAC0x" 5 5ZRwg.EиSz=y*ƍ79g5XX dQݻZ2rfɂX)Z KYXB P/T*bffFR燘k!}P$kg=8_,Nݕ0z`Z9Fw*7Oƀ !(MwE8H1 KAW t (`:@$Iw[{É-+=rI=K04FF}q]}Cc18$-o]4|PNFRJ1899 šW^177'R]l+![l9i##ޗV 7.`hb0RN &FRO2F{tLNz C(&*1`,+maRX a}E`Ob:-SR8scp:[\qu?s6J7T !ۋr &>?'Q q pq!< '7:4$jఌ"!#׃'jxVKKKbyyYkbyIBD5fCw^ǎj 2b9}uz~ "6`FX=ERqe4r*R#jy:7zcbI%$\!), M(&6 9>p n~ Q뉸%EGF;D`5FI4C!VVZmF͆eʮK敃fش=xcPRJi!R*;5\sUnVﱕd,'?kܭ.s,jK_:q'N 2 l=ݻP(@AV50* u.w^ I1H!L tf+b:(QXز":)wy'&F :81F?y^2)smB7?B&S[-SJ)""RJa}v-{jz.VVVܜZPuJ5![\d>JhDetd&3tq2$^ܭ9C yY1L4K1~cӧ> BhBJ)b#~n#W0 yVKT*>77'잙r9dEu,-9Ƽ)q8:.!;>L]:C FsR!ScI)zsoZƘ达ן!]θ^ cZ[RƆ;{N"9I{g(o~9+Ӧ]:f\PJR Jj;p~{9>CCj=>HyoHW-}0 ynZ6f+H5lwN꺥ƿ$cQq>}RH;tm"P, Po.ulv@LWf!{X)&`VA*실xïݸJ"T +|4>g"&`,,u-bs1!<^sn"$ jh|@HlN0 `GW?^o4#bJkcG\)Zp)ehrxlj5\^^/\s[9 E/Mwyo}1QRql:(h%5:*A;ZO.q`H~ UQHmx]F>x޷F: ]1,m[AsE;j¥4Pr.(f)!fty&!+r>?65mf$Zk04shC!Zs9R jz=(|pܹsZPIDATGb {fnqo=622JM=HSr]/M:po`t ?1>BTB:DzCz+Rɚn|CYv;'T9b΃kQ;1#Ъn:6GO\NNYP4HbhE~6nvNN1`آ:OޏELͶdK:R)C0HPZk@t-aAV6 nV k3f ^88C;44TLE qJeW; ]5@E!72 wgX 0i3t18zhn?w#ᧉmCw_|르In*=pf9D+o0Ju(=#f Ă֟dJ]RjcRj,H4,Y1@zIImmhaJ%X\\ /^(lb7{gݽ{$!GyhT*<3G0˯a'0>X al6K%0qI?ǯ jE@;/:)7}S#uQ+kpEW2jG]Zѯ6G[!x:}"9!b@KljDlj ŚW*ej#1&#T*{J4M^Vج@q VF: Ŏ{TnB`4,fe0 IIƔ"a(hny̚_Q4f7)Dh*i<쫸8_F&XLG9ZAK-%PvP@"5$9 (s@lh];)J;u8$4t`L*hmRpaaAߡ7`+6@zyL={xxxԦL48(#PF ]RJDK Lƅ093==7l R J;ٛ#Qb!1hJY_zIr.7du]Nq2)tXIV$18yRB_-|;$Y \[ zZ˿|//zM7O2 2 f1@$"SބElN})& bUjDVKKKR8kݵ ?D`lFJLȑ#cGE 4 9==={I/2cc7-vgq-Lnv1oRwRɬ&Q[hZJRa]yfsaVY ޿_L&Cr\bI8NHz$>M{cp qmyJMe*e`EAa/<3آU JTB>6C-$낦xҡAuj5Ll)&IL, .cq8JJGY|T!0A$ZjU !z}ܩ 0fѺtz^f&zǦ5Mf8c}X6\ c#تyEo0 A`Z;c0`6ϱFVcye6;lvbڌc\мF;̬~3 ;}~[q1G?j;WO"v6`f\~뻝fg3v;cg쌝3v;cg쌝3v;cgl>IENDB`vokoscreen-1.9.0/pictures/start.png000066400000000000000000000126721227001500100173740ustar00rootroot00000000000000PNG  IHDR@@iqbKGD pHYs--imwtIME4gAGIDATxśio[יw很j%yvcdLܤR$E1fu"(LS$vȖeY%ʦEyA+J뤥pMy }+Hs?{Ngf@7tnlM6s<-=S蝈q FfbHA44K#nʼn[q4K,LL,,u7ifl71~I^X7H 2>NeDuIK Ro !# /c,cUVVYXfmtD~vO3w}͡αoʡwudG=<<\<~͡ Kĩ맘?zq$sڶeYX8(b1lq[񿚦iX,EUT_E%:ܟύn+ (ѥLߛo0dɓ0e-Z,ضmdYFUU,zx<='o,ˢbeav;CӴ()<+P^/>ie[;|=r ]حcǷ, 휘8x(y2㌌QODž ^<0X__guuZFuPY?͉om&ȗ`xm/Ǒ< pܝw]:Bfgg}CӴ@eY޹ p'۶t:ϳ@ LH$v@PTdEƗ}nWӗ dZ׆y77հ$+vayX,R(HR@eY޵YeYIdccǏHDuRTa%,-Ͼq7nfy譣mC5p4iZ(JJBX$L.&[@C $LF^Ç,..RV O>!I@ Ak />|U-lru{HDy)|LESO1}gvKꙣV,LNNriJ|L&g»*z˲Hӻ|}밻>fi4lmmaYUWEuT\e?M^d,ZC6QN:PxQWX,ƽ{uF#1< 3iDr̙3g~!dkYfoΒl&#G@῟Kz[2_A5Tlog\#Gp>zTWo͛jM,iX)YQP| 7RhN 2Ro9ףZ1lxD9 @yGTRP*Jebv|-Oqf9@F~ 3M8|pR];a+<:Fw?p?~mۻp`/؋yW}4{^3`F6|zr/ Q%@{MjX{m.$~;~2??iQ /13fTT"`eeM0 #i~0u],Brڤ `fcAT{-tg*ast:t(MNNN |:|5Kv0&nmkr"]rۣ!pɔhp~P'|v1MsgNX) 3i$ iamD]n/ ?G=TU HN0p=Ce >_'L)-0>q+[4@DhT$"*BfOpXeJ1CCC5hN $,^/C "VE X4\oX;/@;y\x>'NNg%G:AR6PI@Ԧ"yc6kkk4u1r  ʣG{qyfffzawQ_Ɠ滴KMZV;inevux O. "9y$.\'J^v;:AoAxrD3) 0 VWWD5u{A p |X,F.wWܗ[z>h"L ,0[#[?)jQ٠R압TVœ'OhA&XjAޜpN>ͯk߫j)C$`Zj5ɪAk4.8AqϦirMt]'L8NcP`x i8ܹsT*@ bp"ꫯ0 c''G֘Lض͍7O~BTj nN%@UUaxxGr9Ξ=(D_G_,jW1hۻNag)dG&fll,ѷ F JAAX._j5VAVFS<ڥ6MRPDa"G>=^ D8oߦX,R6-a&(23|ᇜ3\ D_e$_QiP=U5z&dWs5ݽ{I( 躾ò}Q%gϞ?O>wr?oҋ7I!72÷Qlv5:t|>oi`j~GM:ý{Oz*m$z6=I9 \^=Bⵓpķddк>$%$ϫ(/x~?3 NuFGGT*RT m"LnY^^faaeVWWd8( c{Ww_wxƣ3zm#!;&<ux<d22LppB^EZ0 miZAVWx)K2SfGϭ8Q?O1z}Bz |peo`!S#i3+(Gg묿ҿ/x5/pdM)^  @kiHScESj o8}WeW}EwsY9B{95&>:+ jwIڼ_MỚDs.<`g;?\X'Hm[# g"yTSŗސΒ|$։u4FAdt\e%-Mgց-a_vMi֞)IENDB`vokoscreen-1.9.0/pictures/stop.png000066400000000000000000000117771227001500100172310ustar00rootroot00000000000000PNG  IHDR@@iqbKGD pHYs--imwtIME-xIDATxśioוZz_E4M-ke)Ac>3 +B`+$K%S4MdSMR{͇[],v {{:=UByɇ׫`vJ%a>ϳizv6af kY_ۦOSC6 rmfjT*t+ :R 0+/p /pT;jϞQ(zTy/ @]0.\^3l/.Қ57k(A!JBE!TPPkFdVm76١rp@n4~rO? ib׮qU7BC 5EI]QWۼ}o~?u?O@V|}" #SU } |Ǘ `K44M;zM@UQT=Y^ _}{Wn_£s؞S!x^,88xhN&u]<Ë+>kad@uB]GUۜ{A& /Jt"ߜ=ˍ_'33jB`uQU])˘i@l#"A;0, q,`a^YnIF92%S5 Itr/3xDwNl< @4*f3g033C6EӴ & x!,bwwmv*@uUAU1WTK3=͍wшpHVܹsf'aۏ2 bp]pȃX]]r1*jr=s<}rȮegz9{a8Nl˲V,--1;;K^VQ(fz " %!8ضMףn^4) 1GAqx}moy{1_. &eym4Y\\^.6TkJ %&Lw߱F"b g,7~A~;(7u"F8CTUe~~zyr\. yǓw? oydun߾&~0 2n]Wߧ< *!>WBs]lƲ,|7իPըT**/nL>\|Vkrf kBHW^jpe_+ $!{q9SSSJXX_ demA^\.#<;0EuU+)&Z;&Gvxxxi,,,033C\T*M]Prwj!5^۷osxx_CSvM.-E=F ޼q Ϟ0CQGUUvFjJTpoߧ,D. 'sxd(t]pg#DZ:ﳼ .aB^>ϗ++˨5---qʕ?/4m"_|l6~8aXCr/WVx]*LxiK c$шzkZRD&^&-AVi(N0e6N`p_(K]uֺ"p~&C%(0 r KKKyd" /429lێHKWVVz|'Gɗd \\_hYG& ~dj6٫V P8s F#.bkk+9?. bUUmeVVVP2 F"F#NTUdثVj6iz; @\YC( m 8| c&-nܸA&!8'"M "Di? Au0 ҥK*hβ)6 @Xfs\Ĉ6.a z!"%~9@ISUh5c0DӴ8}z[oŭ[""WTbv{"JhiR*ܛdO$5AhC$d/u-IlRfIu]LUQl4hСiW`kŏ4#Ŷ槓%w: aIHQh l8y6ha Iɲ!rVc\imfYXX ɤ)i>>i%*A˟ lr8w rVvBn. 1;;iII9I`5@!\ReH !ÅD1V Ba04σu]Zf2 FfI B GXIk%!S,u=;HEH`hX>v2˄'۶'ٷqI Q(WK Q&~\MӢ:!|%A>kȱ(Bi mf\P2 8>O<[.rDnB%$24CljIpXEN+B믿suAArٞ鴮8Q!r~E5Zȥ!v&%%2Mh4:lƶ߈Ƈ\F7 #q_$JjIIt ם( =IГ6$'r(t2_|ϳv `.i@޶1H-EIMH Ww\"“ +iX[Lsԇk `wwﳶv,O$diQZ?A`uu;w}4N((aH}8uQt7(uǏg2lJd0M[__'RTh6ryZ>=)Ksurioo?ՉuycQOP86(dZeTF҃>|H^wߍN|c<-iuܿpHRmU 8I1=9s>WZ-W*<.cA equ8~p?$5?ew}޽˟g|ߧX,][QXvj1Zv1|33Q( Z 3:pR %]bi>>ez~)}acyh>y.ﯯ T-pozz<&' 2aA`0`ccU666ގc$Kf;, >x]r`$mO=;jn@?>D!i$S#I">/zrT**+o/qP"Gf^TPƫ+=F./YRKAe^WCh/xws(O:Nj|LX }_Oy0ۍ8ɎɶE  v.zé)uVu5 QAh)er|RhDq&~tv<-xϳϳ[,P`4uce2 u+M'yKz5bf0`ߧ9 KQ?>0 e 30G jT1jWg| rp@9PvMU~IENDB`vokoscreen-1.9.0/pictures/system-software-update.png000066400000000000000000000443131227001500100226700ustar00rootroot00000000000000PNG  IHDR>asBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<HHIDATx} EWgf>Y'C@Q.EP\<}WpU+|,*k&d2 H2e Y{6B5D/ ? _L羾RC[8HIumגuuuܻ$ 2I'2{߻뛭Z.Zd'OD"<{%%en0r7jj]<tڊ㬮H'I!匿W6{=mzb8rd=qy||c0Tپ}/ bqڷoVz҆d*,~ѢOp =!i0}Ԋ20q#ZFR50 ( ^E@Y115>30-9 &f+#]wc{$BMG|?cu,[\_N;[t -jf|I3bD膆LqڷldW zZi 6NǔX8-"8BEN(zQDQ1HE#Hs-l)l+]curvՆ_[9gFAh_UÇcnxefF'.oynC|{[ Hu;F38k:8 5eWʭD/<2(?~r84ZcmFwjrUR}DПłIaʙ1ԣC7bOiu?g%/_Go/;W߻Y:UN8_PA1<;5KZn׷äi="tʿˏ>p#'M%^xӦ!Ԍ+'} Vt;ٌ"ϪBS%QTdFaV࡭?D՟/n?jO}~:pgV*%6 G_!5OM·V Qm?_.V@j, ?q~yFxM WE 07J z4ymO|?Ibk֗1rq|r3qFń[W{~%#e&H+p-w^uylikkJ ˽πV|<5qK@MװCU)iI!ЀVgaa³bD>%'~L3L;#xp=X+wBal 4Vf=O6N8Xoi[a3_I(oil=|7GW)=! )D'vnwt)TmUu=8TmϿ~]e,sEu'ηYt⪩ n)-e/ξrSxG O^t'^ p5J, 5W^y[o>5o>a6nYu( „)GDz쳰yY߷PEQUա.2``Zna#ONy6eWIƥ/3^f6F}Q烮e5~0N&SQs/~w{V`Pܟַw/'OPћ_?|!Nw:N}"= @ <\ZC!<))Uڄqceg;/&&TQ1y8Has ~H|Z`b?6ks_}u]tt`WkT?N;l9%:jTڻև+EG.B&sbD5qAHA>)ԗ @ ׺Re>'v WT; sgew`ʥ8P{b) صk0-Yg}^xlܫ? = c !LkpmwmZ ~Iar}Ԧrl.Act4u/CTh6\ Þ ǯ+д3&AJooNU$1ŋxѢoTSi_o?r4l]=~X!k#bsa^50IR3 C7 !6Yc%1vÁ$ zsxn ϬGp!bGkÉ69_3+zϽ/\-󰲾N??>1r{pE(90&7aVַS4x@~P,/nAͣE^EQSHYqԙL1JժL/_*)Jx%޻)ø?ՖRYMl*@Sq7 ><9㌳&;~V2KX'_ZQ4WK!bBx:n|s42S8H^S) MMQtxaR]G܌"RM@ )j,^dDy1q;9oWo[l  c9Xoo9 4 RP֨%9SLO~%$|}PQ .vɞ0B%K`:k*+" < 0vQ.|1 ^&z>-qYnʾUҡ$Rn&/uQ ^7R}iϒVA~{{{P*NQPJuY)=A|[;Xe!HGጲ9/\33H Ԏ*>V2BַE7VW2l B}/?__~;j뵿Tm8K;`>&Sa#+IyϷ&"|;<=3Fn[_=dɒΜ3g3rnA:ٟ[IԽxJm{QyV-bviebfcBXkbV.wqL_YB*J2-{e?m9!'f=N!{eQE2I7d[#4PDQ"8ckBFBX{@gDK}@9A#'@uzޣKVM:0fjpZ@AA{bD"_(a۶iX Ouܫ4k:=.u#JȊ.~0L7ˮx)ɽv x [#ɑ:3 C5LI)LEL(8! 뀭c3?׮f6Qdyd{sr5N̔(0HqUD0kA&5~7&4nf*L5ba[N5srHHID LS~^(e"S>GϞ6\W.k-y8c<̲GMM>ĭaL*/5 3F*{T~ہmY 9Ů6$rXr48B^cv=a7kVbЪebi_|1ij Cz{{jΪY!MΈb<Uv=Um+a-3eIDg!rQǙ@8=Lyvl2M\6 ߃ C¨jꐆhD6R2*Gp z2CXs9>xG1%j:\^2]+,KZ rmGBðql5WiX) n빰< H+KG']T8SHA /D L\Nw0+dgZNnp鮮]{5A(>!իPG\CζUzQ@\5 Ƭ'On88m( V2 e8gO48^@ҙC$ΝJ8χKe) )`S._~MM*y 8m*T`6⭐OYf!%J?, x (4xTs]b[H T[\*LOk Y 5>o"j-'a WRvlDR$<xC("HϟqCո1LSIoK&Sх* %yf`֬9i(5v/WwI _چw( JEf {OU0\_\/ey8hw|}ث9L>9k_g p\tMl\ٸͼԍy~%IJ {IU7@p[=`-2$c<B٨=U}=.(wUͷ]M=0>s-,J`UAtOifFzYK!MLV7F DP8,+l{P)1:&ǼX̀ QpYEHmx^,vkā%c!ϦJ{ojء.+z5=x:9FPy GЋ>u!UA2&@2'OP`t8) e(KGxJ+jn'HPĵO{ނ:C&x-܄r,B(BH39EU|!H֬SxGHm6bDEm@FD4"*^>~^TMxR2g~zd2cŠ=ѱdXfQEHVꒅ F)Qv.&=oRdфבN#Huwca(rKBd p&mtXMo d^1^y|Ӧ[<8jTs:'hHLU%#$>HS#L !O=,!fs0/^#v)(UJ%% ƷnΞk ɗrK#X\=NhOiy{cΡtOH?6ZDvNs=s0!D;z\ CT4!Ё@ # WG$E&Hydj>0C&t<׉gg8U".}+r lov*My+I8}Ɔ>5ǂC,lZBH6JDQ;e#ɶgr%hN$ ݑ~A#dlDa96X{-$::x==AG0 ʆ^ s9q܁T <\Qiz:0ǛNC!{t7j02ݲT=QxfV*3$q<\b6sAjWA!HQ܊wE \$nq]C<Ut3<"UmrRinz>c1j9s lEw{Z$uW 49w|=+b6֝2L4D!,D#8XLc]]uHe1(.Yv [h D;QƸF.RFE[eBǁcK;IKS 3# H~tIP=G|~w,ʅ8C(MADȥ&0_`٥KD?C|bm Xua[T[}#|0U *C-j2 3JIX,yXӷUH ˞=Rao!ҿG#*u$lJPr.~P(2m'JfC2Wή"> $4fGv)#[X;ѪO=!1F 09dT( ťkܒ{ԗa{ud.,C?i6,_~,z xp Nj>p tph[jE"דǍ̃cThѲeG)PQ1$|׮GPc0*Wfd2"N޹ݓۉfWt_Xsl4Ɍ%"+B(N|g.`SOK ٶm6)}l+#hG ֔ %/}~!s?M |SyiĪk/~q׎;n<]vXcPN>%DWj|?*򜠨`$*́R$`J?*?@|5(Q-^;(wZQ|!yјe5hOjE{ xOa-5, [2أh28?(*I/ nl_n.^> 2ꤓʔD LWqEIPe8zw@eRԠ!5\a.JE!WfƪkNҥq&:5F zVY%y 3v+y&^cp eTC!П M4wO?~2 93?~_sj5/y7n >Fϵ$Ǻł`d"a_[6W2 r ۋOՠ_+l1o=3g!<0m}%CL }D"On=`ށI@X~;}篟CЄq-U~z_5|_E柼iv")fh "_{tæ7:Z8R :%CI99^y̑ɴKoo:|j? z- @Lv̈́@__ cG 'ooP ʛcAL)ƮCD G&! e``[ЁĞpad윎7 @VCMu5ˠQWg70ϕժ˼{u5:r҆ӵ&SJDL@S'Sq~@08ùߣ?> $^>1i3go\{r޴M}>hpxѢ9h[eo?2jZXwd̃̿2k ]G!3;v A LfanH HoQ]P(jOLuDl*؂,AT Ȕ Yx /G#mm $ UwxG^!вE_3Z?4J{nZS.}|2 8Ex[n{啗'nJQq删SpС䝝YHr&ZU.6:Jj{ëUTz6"_j6LN%s!?:B\wU (}K/9.Ƃ?8exEb0+0@ f t7~VH.m) 1n?wE/?[o|{It5F(:XwVE b0XUcntRmM(Q()Rr;Ly\xg8v=~t3_(j_=A~\re̟hF +~m+/.ATXxA\dxU ;؟u? a }w ߺ@̠I&PZ&biux(J{mIܳ M Ml=T*tt/4̋m>c҄(k_O>~U/\z%̚'^pNW^Bio?b~pEt,7x{|T5`,qY_\q5 T}mF!M66jקTm\S*9öeR2v!\5{k Gü>j mڵ^(`e1|OəL69j|᳟cc#NOЀN`*A))!yeWŹGk틵 R`/X=ߝ]urb#zEjhj `W 3z3 ,j#R HQ>|c~mP=w@u;0ަ!#^抓>g_>(:*M$RJ"D&. kˏdPD9CQdVA# `jyou=e@DLhˢ q^7x=Â}g*@ AX1fh^3 !@>@IJ2s]TcX {oG NiddB|Rh.zT z3\=~^j7pe`kϗ_޴Eۧv.Y@QCHdz(4"0H'uw,_-Z8EAی# Z\A;o䯸Gۃkvj)q9NҹkAS4eQm8 !$EL A McCh=h ?ヮ'n{nsCG@GR%m6:5pZ] ߉P3BU&_UΞ֞FP iڬk5m2٥ 1ѹ ~ۊmn?'`X$w[4SO''д\Zmێu]s 1O=6ZolM3`|?/wEx&yK..oѼoñ0\? 1zwϊI*m64Pr)i_|{[S;Rqww?gH6cekU Ȣ3@wfn\C*>/'s穠gIph)QDe`~ h0) ?2t;̅´ ~{>)a{8Bl!cY2$^au̞ظ4/[jF7޼aԸä>H+D MpxE$k[HLS8˸48xrg񸥄DL>ާaR!a= xW׬1o3' G"RLLC1s ~.sz Oc񥫯^{m8H.h\0SODĊ5m)cQWs=w}=+dٲe3y䱕Pi$eyRs=|m'&JõI}ku}iŬel3,Bp :ꨎE [u;rƍ зpJGضo~[gYfEN83b{@ zsN ?;"_OyjJijŊ'x^x\qZ/bz?{l[=ikIS1W0fÙrjVqb.WDP:nq73crRټy'0c;_T=rDﲥ/Lg^xm6Cк6#-'țNHa/oT*5 6~}m@_wX~L7 #nd 4)N %/~=(7?vyHi{IDK_oK6zdwɒ>cM;C9cn5bOkm߸i3p[n|'T0)WUT;a98;;㻛ۈm6cۑ44w`\]SUv_Oy?JUm4~k_G1H'Kh&D1 PEb o0MJtۆݱ l ۈm68D >'P24B-B>nO6r˭grc<̦@ϛ'^3fhK1 tY: T`>'kwg?Cmm3 ٳ{0Q~~Ȣҿ.S8TbJB0*zǶ e&Oڟ 5&ךG Tɢӧ tk#@2OwVn34M~Hkk.`]=xkHf0dKƹ3&DXw 0Sn05-CK8F39ރekn"axS Z1sTG xǛ `NQm山QbQ)>GKB`MM{NifͨVSfRuD ڧsMPZyfmiҞ01jSw4=me;zQN6UUs͖b[[x j34eM44ai=V?ZclH`bIENDB`vokoscreen-1.9.0/pictures/tools.png000066400000000000000000001243601227001500100173750ustar00rootroot00000000000000PNG  IHDRXsRGBbKGD pHYs  tIME 2ge IDATxwdy{*=a! 9 YHlI aK+, ĀdI!{ږw{^K@a0{:J'q sLUTWzs|?>g^obʁ ^Kmǯ,8^&17cNj׭{`j߿]d _S~jQL&Q9s3XvU0Fvߺ[o@ {gz>q@g,R9 kHy L萵ADƁ?u5]dU-v;`嗜 ll:Fb9NrUL1,pumgۿyp ?j#[q*vme!623CT_z.U$AID1u}{^nۿ!\t7_ȯ2ny[ݶqD 86 Ǩx 2qQzl8=xwQmʧ1}GMb(w9zDɿۭA`t`1jxgkJcWLۦ41vAgژ 0 0u1AA°m#v`y$GIT"J&grhI$@?x-#FlMiDybmL\'Wn0vk1 ؗ7| ޯUm"uwnbKᡮ[^,?Ϧ1N)ApjZrjw<ëE:p0vemb 4[K{ENͰ/ӳ̥EGwu'Hd ?AS}UF4m뗟(p4/>ſ `\qgۮmߜN>J']c :xg5O<ϣVyjt[yTk5\638NڻvW^A˪q"ѯHT}Pb.b0b  @UڎC,%DIazTk-Hı `6U<<7=8.ırIw$N2k7ŧ+gd+.,|OnW L7sN?sE_ˤH\l²,ql;oض8m۸#)EON(uo2صG|Yq؋eoRPlk' pV~ Ae{ь?*\ ǰ<<*D, ]R+{vbD[X2ĉctA kۅ0֫Z|r?q͍zD2#vxW|Zk:MjB1>1ej5_fnjq^U/[?WqAm_ K%"f(cY]}>b X1PuY,h/`gJXH&JƱc6fd@ Za;׆JD%ℓ+Mq?mMrӽ{#b޻M|ku<|e}R mIloY7ZΊ=t˗fUkXQ؄ ==?;aM~7Ap9{} d^gV`LheǭaۨEYr,{Ie7A1 0 _A-˲3>8eQxgm )Fe;1ڇ҈ws`ZLxr'_x?°bt˗n5mc[8h<,LedܣΛw%_w)/!kDZ>$ڃ AݷQ'rzhzjb~#J!E,bCY.b%<Q${αm hPM(/''W{:Ir*S?čF=?ԭ==]twXt!Zk0ZQTI,"M7~wa#Y& CB|G yws}?LVSZ 3ȞO&c|uzŇ fQP$~(E|L=0`  0l;cE(Zۇʤ xCԪ.-)bn[ }nʏ=#,[OTH6t\q\֔c;^,~ض% 7"XJHR9 I "0͖_'~[|?xϷ9PJbahyYcDkm,˒D"qşnm\ރ A<9S;8lFYA7A&q#T1b!V T $:DQc nz?}T*Sl!!D Mղ *5i鹸T?~=-rӽA=likm|.c[m5'sio+L%`sf̢(;:>!O>Bu>jrS"Faguսwq}ws/$V׭{xتs H: ?QbA $OϸˎŘ18JR$`-#.vb,b-m׷uꇘ;ϋON2ezj,ܾna:Yw- <@ҧfFY9q5>WOXr/\A(aQ54ED {@h !a!ASb͙^ /wYnMc J.(QR!ۗ/1Y7 4A4K.A=TǮ; eD:ߥ }IbT # EHs/~ &*4Oo#K,$jCul Jr.vkB _=KK1 n^w]Z")Y0!B6? qABU +fmKFNƘ $Z XEƘߍy'gS8Z]]E$ug9L8  bJ] mit((o_ؙJeœtx<'*Xyxnk.iv sp!VqqbFW= ggϻeWx{ |qE?x̵ MD#m[tͤ FkC$](ԫ͛H'剧_Z?3y;ͷq t],ZnK="JJR3?;ZʃTi+\_b{]F"s0}2b5@ V6_SOXvHb 69Te'`AP#X}UɰDԻ V>eK"cz#$Oٛ;Wb*;0=`|1-7\8OXIlT:G& ,?1^T \hb#ؑ\9W1n%݋Pn Z_C[re!0d 9jC[A{/#V!5K!fA tZZyO6k<}׈o8+&{>UERk|2YW*^7Oe& Wo`^x_|3n mSKR|.C"|T$]Y sBDrز 3s`8?7nψoYJ && &")eAT2A)9~(گO?(ɽ^pU$6ûF GuzV0F yW_!x0#*1.w0Scէ~ǞUv?_c2)gTvQ"q'4{ѤN5b)RߘM-=fTT~wyo~\{ӭ7\# ZI&J䅄A@.!S<=[AM /vw3]q\6Db"H]\N"&{X**T"c.΃\|los{:lwNG^ÍC,(y(nŠCO0m|GtO1jÕHHƟzeTe*q#J0W"f-rC6T!o[?\ IuyՠKN17;9OrG>abr|6#]mB73;Vqy;肉̗ʧ(%R,tB!eg hB7n#OHi4w >xƼug{_sYb><{(+ [nZ8?}' %Y+x!© ǩgqQ.R/@4b#~҉`}UXKc;u++].|/*Q[4䕒XF!Ȭ:z!fǦHLoG$d4X]ㄏpB )[ t6Oƙ~7!1>DO!kLoOl:2+d`OeFPDL:e:tYZ!%{_o$VW/{Ȩ?Q*{'ņƘ'9Dz+z(uJa6eV1̃4.S`}KѨR2`rca37q~㌼;e~j3b:G?#8%QN\̍W}zI֪M7=  uwϰQmE NZj:HjyTk:0:"y0>9-S3 .%"vMt4$!Lpa?C,BY*ZRX1tk=Hݷ'&ƒ !26J#Tw a(`4ksWzԑLw~Bm׮ŕ/vZs:0)u\V:Hk7p5;p0uh圳/S!6u3WT<,(E^AoOTuZ0N$bTE7Rǵ:h<~,f)/)*?.f=|kYxRn:C0091d [E,ݷm ۱lk;Jb-bLe!:ee/3L FM VV_8D>1=;:ˆ}}Mmb?ǔE YLl7v[wbt`]?qo 3۩MLug$N$FR h'H*W)vs,#c)EK!O<CD(+u3HQjK%X-bj̕*c`x wZouE XuDZaebK֯edtrKX#R ;jv*{ߕIəF?Esrb11b3Mɥ5LM Lm;C ї) X ʲ= lf=/`4bFc[ffVBHlƄ4PmLHo-' 3s7qDS$w~B NQ-e.p_|z5GrCI?gTXj!d4L\.qh|r7eYuݠk0С^Q!6RbKeZ_v z'ő>Φ}m^>xڇDzmxyr/jjHPk  \|L9Fv&1;^efh#B{ʦ.zdMbpZP,Fr( rm60cLla6t` Q. 33^U~,",EM@qYڎq3J$8&q:1v>GLV T6/(q1/=36#1{񳳥sKe:85KaPn!JkVb2,S*+C]7f fS1O\W^i[n羷 {ﺃo1wc&"vjg^(c.O²Y")%y̽?@2[܈㈲T*)eyFNP0r-.V:!+q0nkMF"H|OegNuPV$ FL3~ Uz^;1P82?67>͓8p=\e汇FN+T0ʮi[ wb1;[Շo 99:8d7R,ݞM⠵YB>GFn= ZCcDdgg}qe'J[/Γqy?nom)XJPW/m5bIXwDGRrϏ u|ѱٕHqm3R\sB!arJ`o8n{/vUk){ ? ?} ZWDȬ4Abr-8I D^@[r$0=)ftt:>~QqQ̿4b;xSh3TNzn#*`֫}yy i IDATrY_F K!ɕu%t LFFi?T&CԦFvbBfD+)( IqbB`(e2Zrƿcycః-ȫg%CT40R5X|.KoOkV.gáfenejzjET&Ab1bZo1SgOqy3=1/{\[;bG$:Fn SB e_Hjdλ_nm?SlϯHcYV.-FRi?d!'C1`dȬYKsA,8QנEc+Kut5ϝۊH$0`vm24Ir)5 15=V<ʦ<4c_-AET::55%HH0!G~Dg`D۾ĺ6 1{ԡ/ϩJ₾%麞jcp]T2I*ml¶ZmŋNA|,F;bl ۲PJmnSDs!OuG.nhcH]V\,r~1mt"zOaphRī6^{.>o.>agɯlcvh)%M!'my" BPxs},jfX`?W0yVBk=XQQcj4@e nOcᇘŠpFםcJ`|PV6a z)Ktㇻ{+JNLO&a=^Ee8jyW,1B3oj<5/Vym|;xB Z4j1}aQk}>ZsAҩg|Ri4{@[k,"Tg?aEC"e ժ} <En~tj[]ye 8`wqY&̢lp[{jGt@bgh.YzilK}t`F Uy 妐d_$KTps:N/ԮHq/T*5+ CN>;ۛg[%,,h7)ܑ=tǸ4-ӳXTFۋ|脣HK϶YAѡ&pTfD,e&Yb8DPeeҬaádBqԏuQ̾節D 2J ?eKz O\zJ{ lt\ff{uـ! wU/ ≃?O+f3oS]@zU7U,#/ &)Q-=*|bB فJG _*R|c˻H/dU|,¦8ϠCۚA]@H0:aL*~߽э?WAxԪe&34K6Y(hY3̛}<˾g,Hꦚ&h3Al_`:XdpxK& WNWyɩpnqlZt}\@!j{ǨiE0 +G Cyrh;tzUh"^RIj۟ U݉rHcHn6DLdV/prv=ba:FՑB?@BeTB (c)}-W^QKf7A`ĉ938<ͤq]۲E zߡd ٥Zl[Ȱ}Kk24-[e)0ߜQZщ?{p)Oxlśճ$]ي:+eFwLcj>YF|U/}acsƟ$ZDYvp,dﳌnAJVD Z'8:Z^TqQ2фK}+:p3 Fx h 'Pi͠b6t,Rhsl6Gw:Q.W.7"J,%_֐ͤXɆC Oʫ37_"J`VM YHE ZEƚ)5M`f ˨72RbFǧdl|{$@W wS0pZ85ӥ2IcR~rgR=qr< S#e92nN::M 6:O,.҃6E}r8v #-E7ʓzb4a-@.6r$ M<뗣\djAէ:hRo.o*>Eɽ7[o3Fv =17_oW_A W?;wi/P"O;$;W f'<%qH^I|EzNe#jxPמ2Fjjqv,c1s#dQrY؜+l T#C$ᢼ1T"/RHA} }'_'u(7Y"ޓGe06Wp?{׾=?'{ߨdYw!j](y'"8M<#PdR 3#O2=3e[䲙)ON-]>aE 7kxZ [Z[ aٹy^|^sY@ H_~v:9X*L e&Fj Yb$^OuYcIT .([/0m 'kKQX 3e LREqL/Fr+]Cø (]Hb305DJY?w}s;ڟeZ=:>YÉ&~fec0,A\!JJ{[ 33slyzEvRVsǩ(׾D-:Yo`ySϲ4 e,u١rwM5@:5~pj:9_-"䘇?8L-E| ֣ 1I,9ah_^\,ZG=FpBX QqAyD$hc4G>&Q:aj0S;ǑD ::M`RX sQhؘ1xtϙFEϲqy%)I<$aF> ltbOoأ A!ZlADؾsm /meFƘcHSc11P7$P18*`rIAJOxqɌ']'7E_rZ~%O36`ScCd۲V!b5~*㓄"ZX6S`䢺Kx"]Ga[>NuާcM :?~:HRʛDIDŐy^ M =DwM;a4jPKqo27r;/ʕgff{BCV."sK+(\ M qw'30ؼ@Retl=.}e܃ǣB̿fLxCn5's]Sk^|O@Hv ]zZ ó!'3B\iv>5l5d[I߀Y3sQ V&5mF$;Q{fhDXרgxЏZxtȖ~*>uLI@S'U@QHtg̟, չgQ(1bp,N?|nрEY4/Ӽ ;w-*a4aLM;ɣOש|ҩ$n}B5r}o:^,ԾkZɩy}?\7}s9i1lgJri4DN%C|ZRG}Ѩ0+㦒K՝d1L%;RuY<&43('8=L_C{jX'qye7؎B,(G )|55]O֋Ӎ73_t7~;=^Ϳsrj:f b$:Ύ6N=XD:67|iJ^-Lo vԳiL3$\Ƹ-ˢ\}xy^ݶ{U-I2FBJB,b] W"T[D@P,THKH&Lsgf"eե̹9Iy}>}d29Rh gxL(oԀaQJ)׶2:\1D7-@hJ\W^GeK- HI Kd1"E!P9ԫ/b а @Mw,P'UN٢>#6ƐKF*LZq$E0PF9Q$%CZt׋Gs<~xhGCK&]ʤ_yR;ҿQlp*WAqIK^SYd@I{v^$}<B79ȧcc8tCG8rѱ$QZRǣ]b?2>]{+/{OM޴Hn~N܋RۅR*gXyXY#;I,pt'죧RR uv.?r¶rȺ"T|LZHٴIimeBW-1yB^t2e90!d QTЦ.斠-E?I*` E!ҷnyڂ0IJ_W/NRNF'8e200H3 d}\!QFFhv7@?E,ȶm ٹljfphOqQ d0(2٬xW6 }L9x3Xכ޻nME3R^JTE2BMts`[g,ѝt+(,8 5B)I:NW25xYeF3&u͂al lx(ë)g.kae-q4I !PcUw'snxf:e`h$ZȠx.Ϝ'80$|jE>Lg$c=1iE.\ ;86]=}4淯ntΊ3i&lbRlKώu]z?+g9ܾi2n9ꄷ<(4iI+ hi x:]`LcKz,ހ ۮpHӦ9U sG'W'ZDӄK'K{@*k9Gޖ(۵t6–K f^nis4#a1p؁[7N 0~204Rt<3WOg.D PMwJ?HWWT|C?`~Ody# IDATqb߁l۹.zzK"pUEфl|yȱKrgu 7?M^{[SI(A"Z$RmG/DhǭDK;VnKKfпGMJj"x$6QxA躎@Jghkkk'gg^ֿ??j; @Q-Z]R}B0!/ stF zuWJ GH[9 M|>#?YmK </2ce9Dr6ʒhBR5#-}JөB,yGw[o޲,Zx<.n9&ݻwj0,pY%Ckm N\>#A]ᾉ#p?0ǧcmcMbÙíkȃqo LJS-mW.߮:W(Qt@RC`H'Y)dւKx<#FoK^:Gjƶ!Vp@2qnK:V- {DzNЖ(t,(*ѶgK <>[ Zsz}뾛a<:00te.8ox<̨ԕiT>"LɺtsʼnʅC F sQyIIAA~_4)y(r\ٴd*/Sw=sI[ }wuէ=:[@D(4h"qqd;gEHiMܔHHSǴ$ &&DU0uW[a-[XlA}$:^SB}qc?! *Ӳ 9R ])/-K(+-zVJ#  184S#GЏ#oҵ?%sGB v_wڟo;@rBJJT)T̊qlV"#:}*`% D$&pLW0mLFڇ?8ذA8@a+Oޥ3FvH!`l e9<[+x4%M,P訇oYtϼC-GfPx^,[<9 +TҝM;za#C!b0a;/_-U&iU ~?qJP#s׮@REkP~q:MG*5j-:F:-ITjeKXÄC>䅠,hp@t>yNDM޼SǕ/ O4,;Ave?k-A ^zi=WRSӄRTUe]L 'aJ@PCH5F3hʫi!9G M@I3>6HϾ~LKzy54OeIx| GCZ]8LH<]+#fgK{2j۲'Q[:vhy40^<ze~ޜP&,O^pHiYQb16' P|<µ%1-HWnSIgF6VDG̀e@*磼7] cxHaz QDJIwOTxVxQH&F QD i[RwhW6#+׬૷Jx窹wOh bw^ G 4c YF tևM0`Z]PHwz.DM"00D[p5%T3?>**KiSϢsL{ 'wT*S|O>ޢpp S5~$nRR<SRcBG\q|Koq[~BǮ^#uxC>*)*R݉4hS5f {ciDA&E>Z:?槸"Hi+BJ#x`h%%U?ö)!3{t-ô*mcOhNJ 6sfaŀ|كiZI-8g0 X2iZI`Aa 뮺~%@zhtvW2)[ly[ %umB':e3 *[)\=FCxC~ʪy4h2Ea`SR~o9OɸHE nL650cZ5iV`{]? ,7o{=4GtR7qe׉JI%l)frt,4 7B\ɧ )䚿!7_$ⶃ[Pm)4뺦)[=А$R$UhF)_UO464 5 .{mIC*-){0}AD4D:- KNPz.Efs~e#&{KTZLƂLQєD&j*0=9 ey?BA1WMt ?Ny'mR:x<p!FҜ~r}'TbxP ebhxd*4̫_wߋ_o{L @׿Ϭ !;6or`__,?AO&!=ey ,a$9 Ab#)lb/V?Uʏ1r]b2 YXϼT`fl+pt'ٔ^CJW-E=R)B l=rчK$Qy} uF-q䰁D|h4*k mPsv% =;`vOγTGQS%]J)LTp094ͫ0 U(nᇼYe)ma֣ 8H?d!>~.w+U_%#Zwmg/zw/%BEB<LbtJ"Mk.K:82G>w3&-V,1mh$siWOQs,'?}\p14 (ǰ8r8C|{y_a&Bsl ?Lk{c)ƒiRig6?2.9by9)>z7fƻ Sx'GIdm-JRJ5M)u]-$` cP /'V'y#_OV#1!RJ"/nEao!䆯m,Ϟ–v}tQ`*ˋ H>ŧ.l&0БV3Ju]3u~߀˦S]kknRhT@V$GQ4CkO4ʹFCa72bz\;7Q(Ƣ0ƆD"!rYHk7̛3~Wض*)}Ӈi~JK(/-"vP4-ɱnN?D,v/] b8ٖLg|ֻBT@R}G[>DRn(29!> Pq@QG07Fes.xIo`T~BHЍmI,e0?iYKwOw^p.XVws^`OII5e!Wk<kfɢ&,n9:>2ums[(TJO` 5~<~!|l|$Җę¬ZYBr90W%``p|yo^*.m-CSYQJ4r'xkqn+/TٹP&NveO}S$h-lhVQsI`8)DQn5=R -ۦ(ԕ˨kNԑ$VX´ ~=85U$bl;pm=,?V-ŰBeGvn襫SmJ'RX*)ZuuWu,65-,DXTWVj ̬F8f.ljIn}fp߾:T<ƶ]r9GGIqӫˉÓ5!8ŒEMd̕[R>t5[6`4?_䊟qsr_,7iYa~U+R]Y;L۾'-nV-%ggYkێ}tviGiI1U$Q̪vS?{g)5RҲc o\'F:wpϥOȫt RH)WX!mIMuO^NuU  q=ą4ͭ߼rRsF理2J -9͜S 3^Aΰhh}b=ZQ([ؤXq~x$Z^L)宛nߘR^)UXsBLä~ N[ʊ2TtN]~Unw^P`Oq"N*1'wK*ZۻYv|֜rmG8-஧*MSkkyzCG"@B37Rj*pؖMCLN]bu=}^V-_L,W;(bXiUĢh[7eŅl߱Ty~R]䆇 c $id^~g;5J"nw^͚OSr,~,]4Y3x]9n߹4M TSRsZ^ֶnfϪ3N'Dm-, d{pjofDB9eꎽSO >3r.ȇ_|>ERmX]M"BIrIټSE# cpr2>Ʋ%MTUmN ;()NP7k:P0`6=}vr.jt?aٳgi̽Nv&{BΗ$zOBZ,u---?ٱc_|1;v"Wxu-"|)WaZ63N% A45ؼ˖n)Kˮ}wt" RTn4BnU*QmUiSiY@Cطmoa9>lie:_ D@y"w"X~c{$S䏎 !zB!%$u3O!p՝RxI+30U4o5ATe7mݎh(H4anL¡uA6VKFZͦ[9A-D rFRNE,&LM/;[ZD0tmG,"@8rܾ}xۆh qC ,Ӣnv-睽PБ9g4-qaႹ̞9ͩV&)%;M%éz98L{8sJV,_D0 ~Ybm,N>"s RNi#Rm*xDO{k5j)--e޽.\BYsŏ~#.bΝSb ǁ$sHTs9SIifycl۱0- 8J#E  LvF;yיӲ 4J*o¶O5c$&OavFh$#`אg={URZZZڹs'V};yp|\ʑR8֬e1 5>@*n,hCIQ]{8oa˶]NZ%PX,̼YNJM6gY g+s=ǰ&>E4"2%أ }zsg],Y D"ۉD"yykZZZc"; "y?`>d IDAT\\_sKc7ƹu̞12[e/蚓V EgOБv8$V,_t5 0r&oi!E;06sއ*{A]S#{;*ɹ>CO@AUU%%%ڵKx^4MSJYMMMMx衇w:H)plG>aS ٿ?'`Ν;ё |Zuի~oHMBż992,e1^DooY'?tܲnPO"cޜYDB!g٩`ͩ8|{WGmezٿBp]ccʚ}QN; ʽ^ 2JIfϜΩ+dsn4.322{3kX07532:FӼz䴓WP7Dz M((ڊ.'i|uC=d@Mqj * ۶8aa#+N\D8&s- {Oh=i5y ^S Jaq'09e[ˢr<:,.u),^8VfBRٿSĖ-'5D$}~jgͦ>LӘ+',YF6!zX^jjiiTy^rS/c]774rf ;{hgR'=ն-zjҙ ['PkNÄ#6-Nr,"W^ƶ% sdF#0`Pi5}t1<<|ҥK3KSy+Um~> !;䀣i^=',G84Ll0RI)1sF %lݾѱ3W" r҉(J -Rdfs~ƒ)v>=iBtܲ;_hgϝuݯ=dEbѻ>OE)jٲe"JuV'}/6"sYGW1 #;{<߷Q!es$I"BQ]]2RֽK|;m~׿U7FJJXwR3X<% s\!-۾]Om-{H,;1<'.Y@iI+;#~x<:}}ө,Tń@&^{}y_򇎷;;co?]KN\a뚛+x<|sStZG ŅG%pOAT6VUWޞo}nU7JJ?3 i(UQJ1%F®km@02䎻 l߱`0w6Rc&K4 ]u`12,L$\ʌjG(ДmKyNhk/]}? p֭P,GF)%aRbTt&K*%fǶfjjgq$OƀK0# 啗^@)m[TUV"M4 !;2*ź)pox} J$KQNEb,7y&vZӧUqQ44MjUQUQǣxhƱ.1- Ӳ0 G sE!-{h̵>y獷ok6l@ss36l`Æ ?KiRJb r[ndYi:#t*jgz L M׏Kd6l.K(bEJRxڹ%)ɯs _WcMΛ=cc'y|VSIEy)=d2Y,ۦH4"<]=:^.möm,²,?Xԭ*ڴί&S^͓\Ar饗Z)U,u]XB ]hPR^QܦmFwJ9Yut;Up&t Lq79ֻi}WcQmIȨDܱYV3UB8λ5k $1LD‘s4AGg7BB).Nˤ8qZ{_=Xd [neɒ% XRi|_Vm>H#=I6PVʇ><| @A ATM,^a 4MDR^MyogںX,wKVJ**JY<xԱ<+hV9Mefm shktcIFƒض$ɑ8y}:V[`&LL&K$bZu[e۶ز}]_Uk/ҥKinncJۥd2quq>N:gLsR|yO3o \/QRR1I>N[iH{
( wțxۆ~xMh#Κ*4!!mK`Z6?x1*˩,әu^ݼ^L$LLKH29}ds3Y2eL,@ׄhnM[{ǒ/36GN)u۶ڵkEL;e&߿w#Oq4.|*t]ybigK&!0!mҒ -ó ?xc!`DQ\C"PY^Vyc۶Ga,ݶ%_TU2s4{̕ }湗Mx8c ¡ PP(i 2.Q[C@i&^ټMku.jnn4M/}K⧏>B,&  _75t۾B*悋]{{|Tz;A$g\̤k]k׮eS$nB! EThQrܴ)=R4̢) 4+[C4rXǃi8T_ R:s˲1͙ʵm)^oo_weG )SJnuK.d:T)%9508(l /Є >zVJN8^fP݂D eгP YuΒ%K~~޷l[ K7ܺ? xMfTb5PVZ-P|q*+ʘQ[MWOUe\UD"F|^ƒ%ƴ,,faϫw)(/5yp䧊׆ &g\rI8նmj*9[]6^~7̜5UaX (w`ZS^>""evi-Z;oڵl޼y_\yq(D"ilCJ7g6%pݘƷ|aJJ7qEK?.4VD"QJL8̩9NSݲm_d7F]7h֮]˅0ɔK3 >ȜƅIb0h]"F@fUR'_/|_Trzzc!uf֕#\2&pArwe%4Ϡw1-߼*CãHyKx )UNg{TcYv*@lz}<ڱ:Z}577d6m] \{g?v4F9 E>HQڛr:Reeeb6ۙdι;v]~|ߞJs+-hXqZHX0"m# 2Xg8j,rs˯53844Ü~I%H&aZMeӔeb˶]ku}6ϙ[fb, #R3;7cϠ~<Ԟ-3NBDBN]Bigp Y~}ہop\V\r,AӜ)QRi(/+AP$)J Ng管0B4eN:>wkr9 !x<"ͪT*%xAƾgo9@X%qbR)RT$HDJJYj.\ԝwV$ojGnJŢ (+q՝!'{(+MP]UȘBԳ/3<2`P֬$/'Xes{CUekcW65cm^s'fOΟ? 4RoVnay.{uH$N"@3iTIp$@̲/^;-I7kxǹs}-Ex<9ow_N1Ϝ#T{0% g`hxqk&vwBŢ H [K=i5H[%cw\{tF웳yvWr-ZrVt!` Cť_y3G?t}diT[=\_}}w+++/3guuu̚5 ߏi:tۋx⮺d2-It'{=(s(@80 *KK]mMC ?0&}g^CIs=}3DBI|Z-L&{~BU+liOvL??S)0,Zz x<$? I4ɧU7޶!J?Hlu P7/:̾eo BqjVUjݫҪQV nuC\@AAA@aIY'3sϽ;0NE0ܹ39}TJ* YN(-F0J`KëU`V;&!^v'^ pW\ ՜j @Vuu =x͓?l!Oxx+=|e " N$V5aUU0lذZ0QsLZx=͜f]I:ٌqJQ(xd](.G e+ƫ#g ј(C8c΄bNVg}nN%=zܛy㳳ܪ4SS/ƓMsٯDQ~.P@v+.{6fSޮ x}hjn嗍5ٞ Qx:S?EO!֭_9s޽{B)j'q\I0 8'औ^YQQYf[oO'¢3Lqvd\0(+EQA^YD"QgΛr9P޳BH|@)ŧs:mrX 87v4{0Ka>S<}d=dUUO8R5I$UUUoTVV$.`˕vNpιE ѬI~Lyf&Fx ^κ)Jd_b<9EiqB@0-@YRdo>EQ媯|ƥ΍ra^D1x4lvFm[M9&G&sh4bX*2Hs4M+4A͟>}zh$? @/|-X rvpN7#3SQ80dA4}=vTztVO|CSxCB "<|~\8oU q}bqܕ3G5|ֿ2EQ'-=o`fq1Vť={z4dnV=LSł+8wk4yrfi1u8QhTITFg-B7<,~=a! NjF\uEU ]ul zޛXΕ{8$vHtnnCtq'I:}h=&5{?reB?rnBq 2{ ?'ͬ{6zN=!@@,`ɲW v9qh4ZF@KK|d4{w`Vš7L{[;z?ݲ_:[ZUU՜S($ ) cÇ|rYeKU-ߝYf%]ky9ȒR /<Չ#ov Etp/נ!hx^sAڎP8qc΂U7R][;?x͚ IDAT%\ ǓU]]᜗b $]qgW(vZv]YhE :w &rQD(NHaܷtQ\TUUy (*#?0n74ӱ?~'j:l޶`%pYrIс睑ѕmnl޶scnVܺ~-PeHzZ79Ijcpfb2J\Uy9cWoq}18 1N|r_N :8 s0ON԰bc5z3L!wEOÇǩ hHzE]}~y:p]|Mxwv0.##UU-NL ;!,apȲaQC4@Ra4/).iSI8"zf cY.ڽh I cpp:l3qDq `Hrkwz{Ec;CKQkUUUs+++O ؝ %Q\i78k E^W5c *`̸K^.-)]cx B4@ \;9TUcQlݾ fOVd<ٴ VsQu.lZp͘sOgn](..P*DQ7BMB;PR`uT#S U2?n}y**zp9 /- ?+*J 2jbEo۱߸ucl҃Cxx5ٳQ'ajUJ>}``QWΆTv<>@ӶO*cE5b:{cdl3gαA;|f(4o"0DQDy"溓;/|XDO+qR `JTIrUعg/&\2&y\ɚ7,rg+ݜ$#J7k! *(H355h#4V 6(\s jjLϞ.=R ~ sRPB- r<}$7'; i&G8b E4%xb>t.{Ճ֖6w&\|~pn߅mzscnj퉧gt#$ M_'5|46,Bv[:.lK}䓏rrl/1w\L8 'y ?j|\o a4PVZl+ #HEb1G1J QֳXOpMjTWeΙ{n3lP~ki4 H"X0DT-iFCx>yߝNO"sl ގ5ȾhlD_?/j5!y9r8  f܊bp5}dc/[clP|q\,6x@r??uMO:/QtJ߬Dvbڗ,Ud ; , Q6-fpPQ$ˈ@ֺDBAH@ H6~ 9TTT|HHjBX$1|*{$M&x|z#[{2\Y_rAxoر͝;woz?J\~ b5r#͜;ޯG~ ~qyBGBC kߌFb7=Inqj'bɒ%|ڵ &}ֶi ͵7~vT 6SF,g9jԨQSO=uϔ)Sԟ͛U0lHLFi 1k@}{pkJ)d^G4Kt힪]4%V-ڽʇ9 [=I[M8g~Xg.Ri|ѧa޻`]O d(wCy7 ]wEÆ {h4F(? C99Y.g{Ca,_,,1\԰c᧤/lfhy$#R,->8HFTUo ]'wrONY^}VokV$?5{ko$(.)%.;wpO5jԫwy'VZu$9c$& #RJ8v.$d2MU'za=8[98 FyTAnNjv*  R:v95bƭF[]Z78[NB;;; g{C}_u S36m܀ɏ?XV̛7rqEQ^Ny駏,I?=:8YNdY&. E 8v+rsܰZ,3 dJ yy]#^jB%Nz[)np2w\y_|?xcN;p8].pG9\X`ڒuy$9ogڴiS( BiU(L9'$!+ˉ(.ʇcVlO  -X|'8%K<$Iҿ.?kmҥK{DdÇsIQ< FI`@>:1DnEZ𺽍zݦU]|ҽr~fR[[=sZOiǂap\ANN5jSG&Md|<8 4no#MG *#'}P0 Tݕ6/YSjn8a````` iq">Dlߤ^s,}sÑZR.L&7ot:Gbf:-r4)Oh³YY2 سwlbbb  D8AIQr'K/Ys\rFIMx~Ҏ3 M\EH;Ռ $m=%;;$ cFEy(.GA~.v+6+6v;\N;.F#TMj)D46ϖ.ҋ~zǶA-NØ2 )sRLri&x8BnxWq3̦4˜2,)s))e0;;8N$(b,dΜ9}] .ܢm渔 ABR?a^U˝/ցnK/.fSc"n]<2}C|0kq0Xضnݺe 1[qq1V(3gFgϞujtoNfZS"fG&yڶiCu]ݞ=kѐK)%Ih,\""DQ(DSU%^{Iwy{ݛolЯo]718Nz.^w,RMH);2|R2=Τ3͐ :svtt7oTJib />}G[lc{uT s+j`lX#GO_XT6Ƥ}BAggpH]j7o QɓBՔs_mXqfH]hW! DnLi칙#뻺@.̜ܹ >)sbS·xzvTB/6(qιi׭ԴՕeYfQ SxPӾހ3F9M[I0 nW`c%<')sS&dx-O[3RKԬ VⵉuCP/\llllAAD+:)CMLo(c`WnbaQi^^ee999 ƴxx8B1G=kgm:3prvu+0 l{ |ǚt]_8b8$իTXX6nܨ|绽^oKDq88De*ǃ3ЯҒ"( D q1Fc{Ex{2{h*-mʶk׬EQ3i]&4 q } E`dr1Cx^ȷ<`BxKxIR攕 rhd$m۶) ,߮nJRLhC]x.R p̗Lr,iP*0EQ0dAz^MH4#Ѩ:' (1q6enhjl{vA-X`@:^SEG@]p0g!Ul6СC+mnsf37͚bEU͛f;c,%eN5M5!v}Ņy1M4#AS5DH(&RAbe&A D}EiDӴ#pUUv_hậ7e{yoK3asK+.tf!C b 0ɧ R\^^n YYYh4r, X,j2l6r-[`/_55*Մxn롑9)8 JkwבV5FL&`wh$F2QJ(D%de `"p$;;d/#}4C 6xsA[.x%jA9O>!6Fh)`69Np8`.UVV򖖖܍/BPaɣ?շO{ȠAјȯ"o#3XFLFb6HLF?og]NF^4ȳ=ʲzU3ۺ@{hߝօ* qoy$+ O=AEqJ)lfDlF$sŋKJKK}śqxƫ MFJ6k1l݃]u p9e Ѥg&z-L&HF$ ~4z1b`Ȳ|{ ;;AϻpI #㆓$%%%|7o(DQLdePӹ|Wh4簊6 ef0BX0b`` 1Y 3 cMc,Xh4EaM,dNP~^*$j4sPKWz!|XrE%yIcGN~"klld>B¢([lϚ5+f͚#K'\)GтzVE8!, /Vad 2b BCÏ`0J$JBX,H,bz2vqS#F}Ժ+(r}%Q ^|zkgu6Emٴ3uvv$H!Z|f̘0b%Ƌ5U f$EQ!?![-ι[ b20S̺\CRT,늯ߟ+UMOpL2>x:wi3kyn;x-<|<صm>LE۶m!ӧ~(.-Ok73CVB=OP} {qdm|M=ON{ s`0|or0})~|Uz}[|-!!wuz)<_.(o#@[{ڼ / n:^(:uĵn8Qu' H,3?=7Sc(=0>[asTU5&a5Af.眙&-?/DќF]xA:o3<ɓ'[eY*{?rʦOZ=Zl؉#>/x>ϧjʕ++_  7< :V5˯nX^4IDATyYfT:y)/7'`}?RMfOwcWnV<쳸۲(y[2ʄW([nE:|bwpph4Z'bR͘1㰃5[CeP`Zqͯ/;˕AHU ~5{"oe AJ\v\#N-z#Ľ M~h[~ѫ(n,E/~N*+qmw`sZX:ax:^LnzΝIf!g##ђH$*K‚<9T$*J ?(y|1-BFxѧ`2 =J YIQ>TB_-8B$I5BccKG}CcO<Ȼ9'w}y?| s6V6xƍ[6`bh $**bMMM*!CDP0SL,AE1rP1$vlq+PPb6W%YỂohBupgg+(ߝUƃu_Kdt~ҤI>^dp CqIѴw36=^w^uƌ 7܀YfbM6+G"I Y`6pճ$2j /Uʒmp J=[<>\NaLkm7t[GfTrXrsrqwFWf2`"  0x$I34!p2sO3 55_U3B 끁ɲzv3Gw^^GNغI+Z9\ff4Ί ̞]X, -_d׷2]|xֳgO_Ű|#joʿl2(-NIzCلEp:I0xj$\b6yش[բOE9rsHTn$Qzz#O$ef +f6|MT(zdZ#V 9.hٌ}կ3?C$"ngXU~}Uxx̝۶Z%ɶ܋1ـ!@&$|I!r/d[%J+m߽9̽{W)=׼nw9|r`q,ű8Xcq,ű8Xcq,4{?Zϐ!/+U1JkDQHK#`ḏQMEQEQ&4:!4Q%Ghm0zHatFE:QZG֟{XsW*הz8tu_Ek"Whm6DQ4Fz֑ ?DAu5ƣHZ"3(F#E?:zoWhQj_32\:R5tO"$Һ'toC6nH_@ i=EzBk=FVk?ڧnl/~xQbiRꍎTIG.BHcH.Qd#a׬A @﫭F)?K%?U!||_Eg?waQѝ~-&XzJ~Gv)%RZG)q8@hc0b8%RJ?6A."y%kh˓MZc-aHFQDLN1zh}صg/S`-Z(iG94(H5S)yUzÃ_⭿(M󾭜yIT#J)v4Ah 4("m0`m oebfѱ)feFF'щjd|q!X,60ưj$y; N[ևRLα<};v!4R'I0G=,|C:z Ώ~[~祋s8zJ)b0X)8@R5@P()UjJMΰot"S3M r S]TXbX2]mtl` =mtie;2{g33f E0s=\i s(R.);J׾|{-ox 7UlSRR>G)կY*)`PJ.821=Ǿ313lDTZ#@70 Z+.߿쇁)XcQl֧#=p_ˇlR#cڳcx 8UJ ݎT=1U?^E&[䎻P1ߓR^8*3aRBSCp^T<lݱXtbV5`p`[z|"=&Ěh.MSRyaR=fz=P,x=XKQ(_XjR5yWًHx&7ޖvzToniR)RZjAFٺcT@,!:0ZE!ZGT%'(NS.̀MOP*1UbA9.K8.KR1]jG"qM2Ƣ%Nq+ٸ~,NXcQN%8JGK_tK{"" ٿK{!|-wBJyQb67)I<Ҿ5?Ğ|Rb雗8)$RIrU+L0;M8ӓc*%'j)$7H&w`)|;]ttӗ(ct8-v68J11K9f }]gdtCQk^IA)UG.\{/_o|rTOHT ~'ˑS+U0{dX& #GMBxvSLObdף򦻹Y/"@/{A$gK)RRZENk3~c0w$ϭ5DQ0,*aIJ9Z"'q>C &M `67|6c!1wcSq\e>"ŎBI^p[ng;v鵝JSR~710R峤Rif l> ؖ?$DIRfnz'ww1=qۮKIwc9lO!1QG  ~E""]#4U(6-nް%ȵwjrZ5KE,nep?˓G)W`l38Mds=r<3?=~oBRD[XBJyebcOgZ G5%RSy{8ct'ݫw,#Owrh&SJd K&dLkuHdjQ 4[gO+XD2" 78;`IWq*) Q^B1KձxϿEw?W^(W%7JI)stvviͭw?'G$BzRÝ_{ 9v/9i@))$Z?$ DGLl[H:6L. >?녷Zd)ܸUK)WjLLNcmƉhcb/z ?孼1׽o}7I)d\.t{q=ۨ!J&Ӡf0dvr-'w%Њp\bbjxJLHBJ PLP͉glOgc0-]Ê>?x.|wBݢQaq='F5MxK'cֻyrLѽۀr6ȥE<R""TkT% @:3g @<C">լY1Jqhm#ERK_p/W[~㔁I%/i5<ϥp烏gjA5Y&gع^ߘE`xfl W,aHFBMDV)'K;Yf^2L#)61:ڲ~:)kj8HՏ%?xK.]sA?w '!}bPL&C_s2v/r%1:#>r7Xb)$4Ȋc!bq=.>8B{"XY:Y'B*JxF::Z׼_ J;RCRV*)ǡ|[=#v϶O TTdcrB%ofkbt3a ğ24Ǚ-(˸ŗ;!c'"az;cZ8P* HG-U#Reyl |_r}ìR=Hp9rԂJoz]Dgϱ[P6DQP(" CڑӝZCggוhau%$oKSB&'&aaPV(! q DHP"ulWRuD)ǯ%-FauW͟|y_o/WI{;cdHJ7^0ZK\ql7qѐz &zrܴkmc#c5 |A#RId2!oP"ËA!ZSՙ+XphbǓx> cW*TU&r`^榦I<{IŘRyəQ5:8~1HcǮZJ_W33DQ/y/_r_rU_/H>@9\6GOOw޷B!9oS.ƳYЩ"E`,vxNaǒ=\/ ;R4$DKpُ~kg+nR:RJۖωٹɩ7R<~kx6E})O!F 6SV,J$R4s]\uFCS[[6hIIlj[&Y ӹ,Icsc}I%̟"R1:61Ogd9:)/phR*P)f 抓K鯬R^(^asb룻k{<|Zd-=oa ԍ+x Ofhl3VJ%gi\4T5 D'IRHR)uFY>i#ZxO:L(%;v;l1-OIkݍ-"ʕ J]Oc}!~*㺸B V۽-BXu_  *"3s"\~ /x[p"ͭcV ё0;;k"a[W|o]>EG)Rw8Jy]]< #~须nf7g\qA)''~@ wb;N\|.RYrZqOy56Xk֦̕DզCD -h1;EAwbl!<PB{ܻ&Wo}[" 㬀XA[1Hh{?tf ,d,Ƙ^+o_˟/T*J)\ǥƘY#J9lv_ȶ 2 t@Da y^=qcb&3y3>m,AI_ZsI)|#⺇kt3&106IwPḮGG(Iζ[q,kZMoHMYJ`qE*!۽c exC:8W[mLMN4SMHA=0[M&祯{ݽؖI' a bxDk}>ُ}ϸC>9vB=RJn1>=ˁIH|R~G-,:WwJ S,ahXvK.> e})VOI>!W*W*ʕfܴ"q]u(^Ah0Mnb8-*H7yT0,W`mqP68sSR4aQǀQRq?0u+f}<41\ezbc4Rɣ$N=2;7%xޫބ.01XQVmEmbJU6߮:[Ii;:;DRg ohKZx-T<@bvJq䜳^q~z:RbP(Q,&iS~@+e:C\%I)ܤQ&Nw(4>Bj53%ETSCxcÈz9K.~#1ZJ1qf|DRqσ2>5J!)z! O2t%/W;&-X9<@R"tL^l4~{?ߕR~O)di!DI1>"%{0 w7|*RzH,qW5krΥ9~NBb\8d>my<ύZmj+U0Hr qf Oq6(AFaN̯zP%bs.N-gzT*՜[Sla VX~7aZQuɦ}xIzt7jlt][N\ ڬ^Q(MpqE^IEAWGK:(fZ}} 7I)u]?fI`~6.pRa7$\/ ZC7]x2gid2iz:_B&S(˔e<#͒f\ ֪T1SzNS)\i40j.fcsu\jʞ'055QfffطoR4ssj5F\Z80<4k)H/_J:fp`%?G_?V$L5kti.}8-N=ͮ~ܸKN^Z7H)ӳR9p5֛n"Fm qF@RX;l}1Z75M[֧T,(B/>e+;}J _VR噘P,ͷL5m('EF\7TPR*UMtv5xà ˦ 9**OwG;^*n3sj:Zr m\Y!HSVcMv IDAT(9mm㦛nf֭E*dwʕ*j)s=ʕ2;woaD$]"SPTm{cGAh68\đcj .ox='x+V,oh\!؈Tz-X.Sְ@[.&֚ٹ"jk0?19=ǓQǾ _~{PV6 řpeo|^ʟ8d3isi굲"3e~WНy;_o(SJYKلVCutݫT. >d.4ڈ"@_,_FwWr9 \q( mRJLatr]WqmwoZRfHSa4[7 ,cKjR(6+1"zo)aMLdPYPEQuqy7=ϗ$*' R)**b%ɐfqzK**Lljmatl*. l{ cDQHRZ7$Se؍1/1o_GQ#|r濒RTRQ*WE5|ϸq=R!iój>0I@|%gsΤ±Wf r4&&0K6&"M01=~;Q195\D=q7m;TMf 6P%奨L%M'\Y(WTk5,QRzpʦ(<4Y: C°NPlz+$M)%9}7+Fi7#(B|QPSiSVkU(-stvw_ĊhmXz]뺌"Bцњѱq&fȤ}hɩf je&MjYvp\ɩigWb!T*ٿovk Z{.U-Ms,iWn0=6D {hA@`RI)ff(J!e3} -0N{>C\?Dl^ęo#3ctD(i1Fks~o'oMy[xyic(WjI>y?(GEggo|.}ֳf O ,<* {Zth%ݸCX$Akvg^4n֚Ǭd{6.c!yA))lS &a(u(/iq:58vfJ@NmqKǺ㏧Z:7O&qmgؤK|Z}M+AAHuCɆO/{1r ^@ x%aulmER"u\rqCBXsO)ʔ+U2ijA@XfXzǬKJ)5v7+>$yyݻZ': Cqm1w7A:Ӄ10tWUd2ir,gn:%]\v:Gǘ+0G_/BJff6Y)dˌOb!ޖGk\ֆ!T<8.\^Q"A 04f[S'-n"j~#3~X5$M:x7nyskaFX*޿REru\^8шHyKz269El{'9c SZLFgFΛ(k:}J?5kݻ6ih)T/9]tqޙ=06%d3i 2{GJ峄IT\6m놯z[aphIKJf9X~ 21)@45xcm㴘W%o}iHt"J@T*ŋ/{ CaHOq֩'ݱ-.%a+粰'@ETjud*FBV'ɐNH%q]d3iMLbyJ>OOj7;Bz X2HEBzM-İtR!`_/'nXS&8mYij%Wuv-?s~c%8;8 "s"fp]twd|j˙cjb,GiW25O<#r[d}wpi\isZ/o߷q@8^tel8x:}!841(RtF:.I>۷ms4?x|N?[n;Tg Gh'Zr RJ*BK64'K#";ekc9yM&2m\iִ2lFֱ&hR?g m,_,;R֬"biv]l5xy$]_y+ٽE)E\?ۼAͦsT+5ffpTJ1[(b Jr9o,eF3jms1 hmo}D>=Vhf'ġe+).:LRMLXEPx}QȊeôQ{ Xʕ ܧGc !_w###,Ho$34x|8bxޞ QT!q`0$к1AKfh]C2Q4MD4Z0&gIoX6HG{Hp4ۜ&q-:nu[Md&h1AZco`cۻ'iB9YuPNqJeTOePN&W|„yH$5O~+VF_o'V՗?_FK1zPk_{vD q$8n'ol{a㻸Ez=Od3YCH NHg)Zb*\Q.{ˉhhqi&R/҃RqKj-YvbL!2k YYvaZS1Y-% >moz-]|!Z|6Ҟb^EBۦIeg>qM,1 l i]fݻ803:!$lg|r ui\azf|6'g\n("ޤ'i#g@.6m16Dp׍`I/y+ s榍+A~R|x|.V'fJpuW}0qZqӄL:,F;Ԃ& n3|Ik?" t,H!S1kU(r4=cnHc¤Vx ['ǒ_Zsyu2 Q71fLR?رcg>t~-c$T"&h*cD595%Sh#:kYAOW'^J@i?"F̱oLP cpVw:h{~1Ɛ[ۻHqA*웚$+P[^%]}-[kݽ2.1$B+ү [=ncGq:mn lɓghSZ4sְ+ZupX9WK jTccV=tv_v&Bb6.yYn\ d̹3[,I:KOD8* U;dT-gg?!R'R.-aO0 Pd,Jʙ066RPHỴХIZw9>)[ۻdYFefzM676vZ҄>K 9v^p%C/wGn(&qCo3;3I+m-JSv}wv?ߟۿ."C%Pt.(7C!Ab@7Ȃa'fh Bp +l}GG"AR%;ֆv;er|㧖 ϓ=WCÍ" (ubآ((-_k к @]Moz-.~  ra-FsO봙kS/ai!)l 8خ#1|{7n`NS;=vvviwZt;vw{hcg{|ȹzǟ=RrdŹY'H F<ޕm]xn`0db+o}Ytu7?S ΒggY) lAgx_6ÛXmꀨh%U_Qk nqQ{UW*/w;);OuC]Ry=RDkhCUZko N][,KcXYYCk$֌u;^Z`۹ pTR*o.W=T8lXS+R'|7#"7kD!LN%s7 ϐ7ziGcǮowZ)RLRaWM=h*f׈{?uw'vn{b̎YBtFD#ZRvg8N]u>C gXE1se{{(R+23=M$A_% -@/78bfzLME3 Xq*gϜqF4ҥ5i:No{JNSZAHǎ; IM#U |'x p7uܷMa UEnN9z$I>L^w!>ox-۟S%ScH)ݝO7ұ"_H 1.}'0&C&5X~tKc_A;6hZWO,}PIW,XbgO1ϯt^2h)]u39)P%.R'U.6jlZ\N${>웙8,!x؇?REj F4M#&.8d1޳uxRkQ(~mܙ Jmv$7Œ|G˫,IHẛoo7115O*Ī#5v;x;=3^q06] rU۷ځ+(xF3DųDbX1nhKts%0/I ʉW eď؏z6HRϝC)If?`iqBIQZYcml$|t&Lbia~3;ȖϝCKhkˠg~'X@y/o!MS!rE7/^ٽ6Q<1tr`io%dgFd4oz_x쟟_O&3EkMYEҁxM~G31H*&:l֚btP4IQU!jŒsxYqy#} GJ耑Ash_[E`Moll2U(4KFm sڒ3V܆jCg#OoR wn҉(ONMw{3191[VhXպF6ֆ07 16$c Ý[6wvؠJ4~YI]`0kRſ :O5/ÎH=|g}$I)]ɉL:BQ'f0f)$~B2BءO4R IYVm ʢ@(Oy}=W_{-=o^4336kZ-&X]`Yc508A !+LNG'O s)`$q̃ KRIދ4,$J#amM]F#'C`->ޭ;82>¹|󙤗D%*ck:]QO`8 c╷r׫nرCL{כbe}}پFam`41>'j1s~$I<Ն1R-ZRBU$V~+νB`aK$ILgqȲ!w.kIS7NN)6E霅HqjT<4g5EU2^mZ${[7|]ۭ:I]̀']@IY{ʅ-^Ѵdm_0exgFK:!i#I+Y/vfBX@W"z.Hk%iG zOy O $sjir"Nct^."]a*]}SLOO1Lw 6Ώ#w9>!N8^ʭk :f >5vَ K)ЙiBog;O}|sT0{0id/D|Ýw|+vc Po)%iɋs+k-{-MF]RGy?c;1Z( IYlP;=A7m|P^BP8wxQϿ- 6 3Ώdg78(co$v"<ZdHV1[;dE}h]\(%X",ڹҍnRoOlڍ,;h&Fij-S܏r?~FpX{ LXK?5&'x-/5wʝ㴽Z$g.+Q#&@ڤ~_XoAyLH[( A^F#HbxJXtb[ ZR aU+E1'N<ߦjy?VimY(90jc$(N21֥( 6v*xbyT|G˄J8,X!D:2aNXR=IHrc$CE0k vT\Y"{w}hRj Ysy6v1LozN; 'D?s_pεjA{٠]4<+W*{ڿnK&V5r m/'nEB'OJuArX:/iA8N)#}{Dn!$ݮS\p^[c9xTR,kean4mb[`?ȜrQ;_{ VT&/hۡ+#dfB (6d( X@I⡇/ i{b΅z}7N1g6ϟ8͙+[]gmcMΜ_g8Ba)Q@it/;;?@*.yJzK7iQԥ7/55&bk$} D }~)1 c]4f}cm irbܭDښ4Rp_ 0}_՞H}PgO><'|H5Ś/]]41*Hՠs9eSNVO?8<8U,/GH)E.'/'8s gt(f0̜1!HHw,[K*PMnZ'ZRƹ8[QUIzSO%c}+vjsLM(:@i А_:hjZ( k-~occ,tꉲ%V_",jh1# kA !6 |5td+!MG{s NM ȲVc`ffvu% gāyYA$E.we `CTiCY:B)n(fX D& ~ 'R]x*WjĨM}FPd 'X^^{ug*(.l;{t6dXŅ)ڞGI&SM /s"h&4ik.b"_ Y `tFYn=5!Qj",rgPMFX+CWZͮ!?0>J*DkZ;kq1/ciU@61a@p<(Y͐;'yçV{U%R:ԗ:Qnf{#R&>?w6819Ql,[ow7# jQ:ܿdݣM"KDhcG^4"gw{ Т~#'S[ &&eC!bd: F?HhdHCG+H:vo~<בRjzt}Yk/IԭEaIcaw02svs<:R (gl5S;S:ɠ[e H(EDF t;:|6<1Yv}p CjfX]X^^ ]`S2Ul=5 6mt8{5hJy6ۻ޺ygy+u16|>F{,>c z95j- Mё@0e tӘ(5VO qC\$\xҒp$Iʧ>~kkH!d1xM}Ꮹ$M $& 985⯚aFCޏQj2z<)GA͐")\#:uZo /MgI[Ot#z"AoKe7:h+㋥T/i)\0 hQ?`b_#W-1R(6vwIH!y$P}͗,FXhbUGY"֖8h$臃°(8ީ2 -6@1tq8vD`(i6DO|J)ֈ.CXڲnN-hlZQH5F]Gmd&$gòLYd.k\fI aF)PSj #=:\! sTց9•ڴBeoo@Ρle +'=ޣ.B~nAck+F6$k++=sypGe0">'ϜIR֖p@ryQ:Oy PUq.e̥Y'ةm',<`(2E1,)D XZhhyv $21u7\M_.VYGh(,[Gp! P,02ϯrvw_] 5#瘞E&I4IFE#fv9zAO>Fa%֑2%Nf ULښ's 4[׌icNwL-cSAz6Š^2@;yW JhJRz,9;y6n9~ ?]їT^k-)FAȾinB"cI(?:eu>lCcxCKʣ:x!zvmfXk;=ģO<5Y 79Ӝ;{mΝ[ݒlmu6&Z<"E`-0}XKG@! YEXRjp,YQKLLLfEyvJyYHF1̆I/%RI׹_˙ϳz80*kȭUk!O.q< N r+8FQ$qX:H-D8w / G5vkmp((zCLij1"2:A^# ˲!^.S6xFXr,FuJvAVxZ[RvvvاN0>X/ >īx9rEoj phi0gImLWJxĺ=1c9e_e `FG7. 8|(cZ%C[[`,KنvHnO}+z^QETUl."ݰV+AXAF(!7fň(5\"#4ίi1rP% /dМDmU4q%.iQ^S: _ˀEٰ5~㐵8UUsY4;k_Efg&9WFQeSӾ'Ɓ*@wzwVd8 ,D* 5ÜW&MOvJ>VhZ[])RJϜjʸH.QAڬӐf@XN~*Eh6}Ņ ]}쓬$_ y'h)^}eӐQưA웞8vl3: E[\-(tzjO0GJ1G.Wʳ'΅Ȩ(啥.@6GB!շe¨(XJmx2^qܤX*)K} pa`-u (,+q7kM*X ykL_Rsj7^a䨠uҔ$iAƩ+N戯?̞7'&m¬Jmcm!*7%\ӢX cI/W|FƑlZLVTNaU oZmCnLi_Kzh, 5jTjIe>qS2ݴ}YqH^\.Qr?`K.zIvW[3{Wl-ۦ<!ѐn͑0؃?3m434Pvʌ c_^6'HQ೪!i,J3Qo5 XF EvO7A7cTXqG7s@4 ?Cz.h]B5V"ܢCΟ==~8v6)%E?? wk-vummE~tڋ;UGw H˅iU}s:mSp>9klԏjئ5˻ m0@$U"Fmebۺeۼ\@;ovJD/vG,HKcQq7~!ۛ[<|+/Y 2Zia],ۨBd;NU.| #0MM#]nrW]j"'҃i󪵮Ş .$#}~_<8xhצ BWR)N<'^xε0yG/ HY=SSX6&MI &F q!Q/FfEwsۑtzfD;i^r2jJ'@M["TE Q趦& mk [v 3pdUtK6u#d7ҭ,HK/$M BWW)˜N~]oZTwskJͮ4D)fD+=҅TԮ!ܪFB0 ͉JXP'@jaUwGPt [hX4JV0> ,~7t_\ZfoP'11 Aa;=.4esm-L ~5;[[X/Z-arPh=RK4N $H1o*vTj:̞to]C`HDTJP֨<|!W=:v qAZdŹ* jvmv[J  ^)L$I|S!Ib/ 2bߩTT44=26| #2 ƦiFh8=쳔2LjD։"cj4,|oelCcYJ&u;;]UqX[J5k3X݄4F3r$]ռ"IO%IF:{=^ @;|XF* [uF`S# wNT`׊05!`O{_y%~?xuB6!=nH:h, G :ˇLjQC;`4'tC=RͲ՟3- iɧ[nZ0=5}Nĝ ,GWھk x yֳk@ɍojFݸ^obMm?j,Toi3:`I{7ʜ^R)ART6+DM:NN]́hyTXUÆ_68#Ug64|fm4<#\~׾ l~2oQC|G^vH}دM'6*ˑM΄t1Uשyؑ4OR".ugMZ7d5RغQ9^\VT8N5Nx2asc3 0X/_QN]$mcZ?-%GTٗU1( !UKų>`8dl|ݝ9UbєhPHX95y0Ӱ/6QxeѧՎ8r  BDs!J=F;FwSj=ekTJ\Iov'~'O8`]z/^?,46f^UJHlo³O=3O=ÙgpȉǑS#SbƱ/\hX[!Ι*UE`<5QgmTԙ_`bb*PWkC5‹h5k8WBR9jp"i]#dAvw7ȚF3t.jUC!%V(HMWR0;bLLYxQ*AE?Խ t:)7|+|뿞qlhC 2Pſn'w|I%'5{{]Zaf3g(x}ӟǟ''`5eBnw᩻7co%**p5,kՆڅ)= `.wmfFZ!NE{cn~g~oWyǃoPԚ(v;˱cW٥CJYQQNUU/2lE)E=Nm+OڱYw]yQ7*kc@N~" <ŀ`#N#CRͣ5N+e O_+2кe([S3xܙH,5i!رTH\#ϖh]H|x)[>$Á{%H9G9kKΟ[?Ǜy7~h΍HÜ͝f_tjjrooo|۷ ~Gym'qy׫կq_&敗%W6G~$gO!ǑUTE#eGbbӋ+Z(tzYa񶃵 P4 N$6E6l)Q k| G,0<u*`v-&g7%l7)o)"V{c1o-P^'Ip68Y yoeh-m,qu`9qטb*ʢP_&P'F>O?v>iRĪMt(v]6]5hLhẅ́(w6#e \59W{# E[eIx=x7fNe>RXW(ܓ~$E]zxH8ilyb;]/{xpMSy5B{ItAAh<*|c W@M@t'Iӄ<[[[a6Y< 6҄$^3Rk4eSE99I&1gW7YQ; E|O}Y: Z1tVcLIQlct;[G]|m5~(M@az鈚"if! WB CheK-\&=jv c y(4VcȕW8 &V$3^NJѴUkP?IP Z( iSH/?V4^!`0cPEM~4&?ST LLV~?^)ÔNO6E=a6E FAH?]*\a2Y ð+T$E͡+<56mf0D1z_#Z!(&ˆ Q*fbbc ҭm.~1e}{l> 'R0yu*n6%Ig}ɸewەP"*Fio0䳏?0/Byby>l>lll2;؂3 C6Q20죋~X̕IG)LZ#:*Yt#!5MGsciml8XK 7? OYk8a8gSSa,@wS,=2DxmAnB؍3M4bjr;pjT'l.beBL58r>4?oqOz/FAZ)|9"F,NuQ4 ϶۝V C*m7r,;o!If+,q^#紙.rzxRus O{j:p贰VFm]ge=oƙQ`PCC;NBW]mM`us 4HCdMVbtN]Sb='׊|3B +3n" 5U)=$<_B{'_8p =֢$NyXZDe-$9=E݀M.Fgԁo7%H  n55iJrhw\cb|(NGY~SukIJ_k;2J1nAɉwp%tGWEQS˭B'Vu~ؘG$eO&CoLN6\mxĴ:K(' SJ%^;/J>~|ήl왙ʃCA<ij|3M~*a͘u8?pn)DDإ̫m mx|8!d #Uu"Z0>@u+qp5W9R Ϻ# / 2'md*gN?ݟc*dİ5Ic쟟'@%)ip̀H٭Vl'}Zzg} ̋:e jJu8xzj6S.}5! !t^/C~gW clyO<'Ϲp6{C208t^RJtz;6OXRj;7Fwڣ(~ $=grzm4SnRd(i^~v|ČRʵ/I O(l@Yj?g9}~N?H(?zg+SFE]PލuIx{?rǃ1h{Rkf&77ψnmdh`89™kmc^6'*ʝ]έnsP1K u;?5.$]Mp"SVHˤlν!֖!=Q܏^yCY`q~?C`vwyӟS} ~yklw:㔺d8=m,>ScJnse] 遦;$ʵn}r]#}f"yR-|~^EۡJۏ|c4LkW謩t a<{k# eIreo'&1FE]b`Sj擨h3s}M]uFEQDbcwU$^o|K;,<[Mow(Q*03__-Od[.RHu߻=(bj|<‹K[ ȹ$NGOTcbmA@wDt*e8$m/p`wu.. RUUW%FǭAEicK/= x;"p;E8RP8s]8Zj/RjMugj^+N!,A;)8,::WBR;[cIZJnoc=@cgq{u֮SϜ.r7r 1zp$˄BBr B 1FdWɲUgv]?{9\~L=sf^ܖ0t(P8iE/Q.@(TV$T'PՉ c+<2ބL Ť]Fsa*Z]3igQnxRزa(vR:pPHD`qb  6wU *$bXBRPVE(>0d2!ϙP6yL GQN7]vjބ`yqT)`{zt#PKd)5lT/65/;nF)n1j ʥ" /77*:g lٴcc#д0bS!^.]VW:AdX$ UMpaX\c@0 BAȠvj8-^u&'H0̀@JNMTYPRD.!bY(EDؿg^xyi#@9sq9IJS( 9O> iiW_;8|UI@׻@͠Fj<WljKYJ2"&z1 Ŭ9Pʿ;i\>&ZC 0 ^Npq捶P\| E@DFn@ ř0/RYbΦall޸? qڃ+xΡ%s"*xrLK! A_}&Xl&ቊd&h"jS*mؐ*> 7{[7oFijjx'0rh}(twL@8 H3pT2[@@@/=[lTW W^Uȍk 1huxޣ Sq믃ʔw+`hv(&.zz>cڽㅻ?;o<\,g#ðR P*'HTkBW\8sp8 yRRh-3~)Ρ]-bPc?1]jlS1{N?8cgqhT w*l*7Z ?~+/a維0LaJɴiS)ԪUCܧnÆuܢO{. z kW&QSuGC p[H>[ׁaPn)Ó%W*] x % ݽkbꚆecxMWDPqh4`Rt9u]|_ox=(~пaP4,pMVJ!F5,Z0/q]p՝(ueb e| RALU+VBB!JMU^$Aĩܘ5 GAZ?1<4E~Wl@&C:i2Q8!ߊ>xqjYaw P(S'JM!H;2xbXCӲ1>B؏P5=Ѝ7qcD"v`. caTKXRBjnݦ֣Z)fPDy DZ\#dN,[ 7Bnj2̠{*@i9j8ÊШ|<+5]xf͞ Cא-+zE"$b+ўBa_?b ҐJu4m) ]pΐJvðl/[O[nm),X"@)[XpC#)u=F6OpA{F~Ie^lKR5ZfWOW\*NaAl? !Шh`iilGD XvoAz](s& ; uPk l~ @_OLaǛƘY+Dmaū`<,jo6ۍ+Ab2*FGrP>M]-ƽ߻< 3\~>rnE+t2Ue}6oVlakR(GL^lMkxۻPVn R|٨#Y/;~a7F4-0b Wl!F'?c eOÖT*J7*>Q Q4Vx Oy+.eXh>6؇th#`FHjc%ч}?cL*N6U~ WQ{i - bԪp7>s_+n LKRY26FƋdsx'`Z2V~ bYU ,u*w:A ٽ`){n{KoR d? ܷ\3T+kѨ%z,z]XzUco(Cn =0avhM{bd)pHw. B^@ww͟0{]\'ԩzDBW`#ٷصJNc [8Զ 28b>YEb`09+S8tRCx𼉶 <1jVxύGo{|χHM2pEXVkbl4Αˢ c xWT^4pRtP'y_C[/K<HN'S ,;EFۄiːgLRE*x0>wFT, x$@a҅8ӑM3c;t+j;;#R2qw|Z,d aZд 4= bXWY+%;)iFa`ك0<&G0gImBTr3XeU})HgR=ЇBW?]N{6DEC.ڠhO%{r-°<8CܒL 5 TH^C1h6xjy n6_~Wh:7zoP ߏ0r;5vnrqO+43ӿT|emAv"ju@7 8jR[ǏFpi'#v2Vz7l;wԔW< f,λ aA80:ѢVhLI:+ {dv]TיFTK[k]hQߧ*rQ[H{ai< uI1h/~S{p+pg!λ EZO? ;pk-} cOt \@&_ #Os MiRBׅM[eoA:vnc°lr 8C7Xm0{pʢ(W#K \"+yt!)g q5`(UZ\aAG;N6y|=T0 ٘ii0fA?i{L-O1p[д4t#ntz"n3ςeSt9&-H;˷3!F'X4oiĮ=agNpusR%Kh4BK?1gV?f ub۞1}L=,ҙ|=vnً[)kȂږ~ztr-ckiw'vz$-wލ5WV^Bca٨iԠ놜h𻆆1wKCZ)w3ছnD:ºu_,8<κXW8]x~ŽYru`PJ0ʈ%װ{C:̪pfZ V4- M) 5Ę͂WZ`\WERaTKX~+⅘, tVLe\p231vpaX..]|+a&<ϋ0D_7z𣇟 *Mٔ|Olu^y0<߇0  r G'Cs{r4{ߍ?kgnu-՛LVE/܁C0 r]mMR[aHQ$q;^"| -TB^XkD"* +9ccxA?^HY[t!5D*!81C48Qk8OK=Trs0}^t|,7w8gg$5RH m]7uxz0r`"5A#-O+ u+UguBe̘M u A }QODGщ2Ɗ՗{~,y!6MsYpo܏#ElA\W*|/ĎMhiEF2NB %g,Yo]| R(sNz n(K" piX8t˶URadl .9l; |SQ#A/dNϖ٤N4TnΌ#Oqp= ]/ah6U*aKudx*lQ SI\g cAo7R)[q+CRſ|> c5 ׫ ?\ӄșnז~y1pTT<׉D<,?<﷑c"* !F֥Qw}RA:ݏh"t-M˃k)YU3LrUb4A^.ST59DsЌnFAy`3)bhNY=QUj I{.2iHlP e[0-oy ߹o-JV('Pa6y _s+t"vۈ H#bTCs^192/6}gH  Q>#H^CVJ}} EzNBM&}ΡT"I!ɓb>6ALd=':Mv ]}Ry7 _ k=8OA4"B2XB\wp9]-`\@"yۏO$A5$)#ew0^i5`Ou*e(IH$L " ߋ t>c )06:ҖM0FI lᚭ^ +}}> LI68+0wf X4Ry$﹘CN#WBZzwo.AdOUzѥ;|3g:ng'ė. 2#ԗ/xێO$wu~ uB\1Ӵ+kZ)g ;\еUjONWreӱ'ըd"-^Q2->ʨ)pЮ_Kx;Q}]}=g_z8551fLKc@1m!1iD߀%3-|  PBOџ)5?Uhԫ \n co 8%|a#L+ln =•C‹LDo?5:j$f6&̤1$Qu-^:cF3%ia*Fl[rj*Ngc'Y$8>h#)F-TN$6?}7q̈́4v= չO0O0 9k.ƴ9ĴD1)"~ νo#bߔA ۤi9? }gpܕWgJ1ƅaCQ4Lˊ!duwx0jFJZh]pMú6nXHi] x rSnDY,9ݛfwUm+SV3 ]e64'[z^™篐D}'rHZݪ$KxxcT%R4ςnrh 7YjT};ƾ? ^ @ط!j@<29T)իSrI v1~[s~"f(A}uߡ}>xeS$N;FK|h_~oQJ]j6j(MA! D_0ȱlXF­aOc3B MJLMD]B #UL)4<ĩF3$ .\Y ڔO\+Uʺ(PQ`)z%Tp7X%~ޥR/ ŧ\laƍڡ}2ɿ_v!WFDlp5%#bመ`t톇>Wߊ z|$pB0y.':M J8De)]]ydR6v]۶C((kqTnG,25A#qj*⋉V,AA78{r*dqҢEx1ݽDVCLAJNɚ<J Z\ӐdP,mۙO?K]c !6zxo|ؙ~,9badtbL.g:PƵ׈c~ܨB/W)ubJ8jomd , OXNBPZA,LF:aXwoiȤSȤSȦmY945+Ёal۶۶DfBmpMW ,-`鬄@JDr>@{^ O'-E 10؏|lRZQoސB:sźaZF"ٸ 2.8*D;nG ugg%q>@7jbӯJճKOC8G6Ad%,zFiqfZ&Hz ).LRB$, so]}k> ?Z!x}AaD.U(Mi6,JsH?Q+cdKȦ3Hm t:LF:%ANٰ-i e>4{駟Îs11QfDVlfjKG W<0Q> 9spIXz2diXM8& @ z(c"T5uJyҴ=w|o{/޻!Zu6l~pe0\'֬ry=ӥtT>1 "+0v͆^I?7"]y B̗Y32j@]=0,;vf Y+!h!lD:5@lӲ`V`ee3n! lͦ۶ar04a8[# C0F= =b(t²L g^HCסF_HD0Ta.taJiZ1躉|wf(`Hq8 EDS6>% y`_#%uC ;FP(Hl$f\G$h #D8veaAql"( !Q=}Ԫe4ri`20m[~@5aR>T LZ]ɤp2Xq=I \Džp]~q]8qQwoEu A ]Ru]kvjuuRRҵ|8Cn٨^T:+iJ*|rUk>}iLj ٙk:8k$j"2W2-b BB?iޣoE݉_uCX LM%+F5N !ÃOR}+0oV/z۶ 1aC1"/%&Q}QT&E4b``qS '?=]yvY;^\(S ^sȺn|w/yp x8"V&FD/5\x薣 SGpWW>N(OlYؖzM;FxBL |JZ59ToXz[;ƭ^F!UrҫJ `D!XeR1ţZTu\tm?ڊ+oc~ $ʚի^q`6Bs.R,D+#E,sh `r {0Le@7/" XrӏwٖU |,҂DUBY ۶-r`_f;lz-Vu!|Ͼ]?};:zEb:i6ШUyi0-[6giz#A8{e0ׅ׍\$Л 8ҝUl\+ח^ /! ]5˲`:2) i m5MINbxq+,TQYd1D)6=ǁj30L \UVN!|cUcMq\xГ`\ĸuCeD ēʕz{ t6#o&unYs. 'ehjsБNga2cЕJ6ccv_7Ü `zo1aUV~˵j9)R4Qu`T,nMW^/F͌Iʤ.kmQ7)P&& YҚ 0?wouUƺeصS]r͛[|Y}ղ3+ښ) b pu8: #' fM CtpMk$#S/`R;;" cкmR? V*%c .SB}Q2m%T.𥭛~'vݹeb; :w/Kt|-y)c6=5V1M?GSqѰ0Hq⸃1瞨{D1֧C}#V^GkP S-^wT=c<\D#jr&F봽< `]SBd{|icנ[t -(lԷuOaX Gx-z4 1ոVbrD,bDVD01 -⢌EbkD\ ޓ|շJ@ 3k+gbcأn}˅xkLnYG#(HU}υy\50r n*:jTC7u as-犭߾Es'G_{}h}S은;;9Ltn87og#N }}ucgLrƹ`+ Ϟ]"^a]g$ ڟ} G6PiYJtex`EeV*#ad< _:$ Î&#y"S<6|(Va Jic_ڽm/<=)Χ?׎41Ώ vJ3Ѕ<_y=P Mгpٵp':9Ng|wF7Lc9:wѲ3f-3Lӄ=~OCLkBu܊!Z:YQ- eƧ6oԪXMQ[ ;Z4 Gr329Lz-qKgh97` *ŽwUJvB`]=o',J8w3y"c УB^OIN~ϖc& p$`LѼW 4([d%t67kIKz~-;c' jj4Y)MN ;^6EHE7ӽ>G6&8zn$n4=5':*\ιNRՅAyȹ9ba{M'b.+"q! )!Ag v ЎhSD,;e<7kn.$H M7MCyGpBY@HDQ6r# Blxh<9^㐃)63U 6HZ#H'rSٮZvH4ܰiq\π#Jc5{јذcZcCߣJo-Dzgz; Pi3D3u+6!Z!RO,pTLXcqT| 6՟x'enfM]ub,T;ɹn5+ޏ`qM59R0~,.t`gSΫ%ԑ `*;U{{H tcԓ`;ZIpPLRt8x o{E'9 `h秺$'o;c)ɦX%Y(SezűmcGSSc3a~D%,N== |00I3'\)~4nY0Czw:PSN2hcL'4C 1Gk9ւɇK0Et_ ;L# :v&<ʤѺab9NCGp3;ڠRra]gXP p [;)Йܪ=(-Ln?LX#<>Nl'ۉvb;Nl'ۉvb{, ZgnIENDB`vokoscreen-1.9.0/pictures/vokoscreen.png000066400000000000000000001304241227001500100204110ustar00rootroot00000000000000PNG  IHDRm&psRGBbKGD pHYs B(xtIME » IDATxy$Uh[뫵MZU֊4 l=^cs<9 `f0 K@B $]U-uW/յv-շ{珈ȌF 3s2###3{w#̾vv}bs?s0*XH(0s ֚$7x7S_8`;̬n{PDS~Dp<9.-f `ĉ[6h7mx|Q;y$;z `mj=3p8~wiii@ HqEwR"s˒HD$hЙ3g=:bD(y/@kRR` B&bŁJLQ~afty./Eݿ'J@1g8<#RTAK^/?w#RUz=3;,_؊܅K'gO:HEd`D ]9zh![; Boll$DDk޳ _IX4!"!@H@X@ETEva.H"jG ʇ8 79hD$D"@D" |b,,|뉙 "Tꊘ41V*b{ [+wxfQBD"+$">rc&STEA";;;+L)N'paK<ujS$HR/IZ/qa,2X:FΉ((Xt}+1KCl)@)I!QJ )Bhn6k7jnjnhilh׌475#uZ5r"b8/X}Ke$,^5dw8sc'*Mrf/% ٌxԩS"ID[v=zh_gUnts @MQ|ToE sN3g{g MĩCx#I,ODɣ|R6 'O[5"ZGc"R%RBlGsi777{DDn;m^[fڨb>CN1KShƞf=} KgIm@# E9$c+q %d|=38H9̀$3 bëVb;DlYZF(EIR$*k!z|= :ue7k$Ҷ/b&3e!rʴɵ n²`7IGD>O`:u=zʹ&e̢HQ ;J2@y2AA66ԚoF%\Ho粿jRPAu" =0MӸVMz/.Ԓͭ4HRR'bRFj PA3cM#B)9Nf2iydf}8 RQٹ2wXJ֣$ ʤ+q% NlYi '2(w @90F$5Hf"l&q^ g &{ΔgN7u2vq.Mc8 Ł!_ Àє!K?V$fzFaf \t: ^xr-}\yF48ub}AѸT K^~VI ew'w$}Ip N<.Nd쒉 dsnhh)L8 ,Yeґ<$FJ,a=dg&L D(A#MY*wA[=mv](UH~8A*f졕`?teqi73)T*Hj\SyǴo_3V*ˆ[ǒD̂$B#DTc Χݗ`/z5Jf0r.h}VVϝ_߫rNqTihvոF4Ή'QJ,7 sϭW;h$J+",K'AzXA9D*g)jUȥc p£\DTڒR$D$"T_i I1TQL40c @^[XRVֳHJT5ޯ|*iLW@VNM$DM 1S-"pijfBnp GxwN薃DiA;<0Ϟ@JvSȏ|&#+R 05TS%Vj:d@kO$bû&dYh kQSLXYjbP9 3|7!NY*Ӫ،ؼΕ)2R$d6P7.3Rqe r $9`pj91RgRx!7LT9},Dj9@l^Y3u0uιvii1AzwbQy 0Ha^\TNl*jOfUZ@ hX{KYscwУ^ Fj- {&f/̀Y++%v."rV>G*q`recg`0V=2-eu|X'ȢR|R;p% AQ P7Q^ PX> _x1ns*& qqNa=3z=ku@ w+oԍĬwIٯczE&3#*gBrW1?q!0$ @1u7u DZ?rem.?y fo(eA`6♯Ž[?ꛝEɬx<2U| Ax2fn,Ցh BCCcmbT$,HahJ%P 1P^B HqRC7:e";:ݨ , T㐝Zk(DFnmpHzh3L[jm@,{pL֡X4KG )I)_1nj4hiiQy9{*gJXz;[ti]+u.W*hٙ=䖻=0aDׯ]kW|ÏF{,UmL4L /tC+3T)$-6TB[P%3`ZTA KCOZk(:&X' s:fG$ruuM~n-m^rKPNOEZ#(E,YLVY7Km{3U@!+,Z9Ǵid~*2AP$B)~~ގ{A|Z18Ƈv'1#ZZ!:^oy}bˆ܂u~_+7.:DSbdvRQ&},!*}&ۥJ5JVb2T%ȥjRe֫pJy b/;t܈ou#goZmIb+"R;~xfZ)#baIVWW, Ií嵸aaDbDh&LP(%4Ipc%1Hh;Sk_x Vax3V7=8~!7nA.);lv 6*3qy #H0'?q|>}-x> 9JXvv( Be?έVjsO<_8gT Yn"5bPK{c3o!\'ydo!̨O/̼:+2PJ; u_y}8~VHA#NR" p /"P#zHRg{t 0$#tmB:y v6.eo`ْRxRzxdBRa we5Tr2vH0{xK_LY,(mU lo6@*8Lf?gFe,̠}{j-\ZϞ.AB%А2xO{DBt莻^]|7 fsO୅g790o(cvw{q__ . *YIKB7E"!l0q _rW.O,5o Ruv+ HSI2>0>7*N=B  $g954DiksW7S'~p::C |x=o]ߚ}!fAw>1ÖZ  XA) Z TC=›b$8.R2?H[[56_4P* IFzıd f(yg*{KH~ԤLg$sZW&hz%(v.#O2Vz) ? ė nܽYLntrڵ35fQLpm/LM޷c~ =0ę3gqя|ss{!$ ػw^=5b(-`&X `juއ p5< #)IΑ@3Hݞ٧ueU,[>xLUeAȴJbS%e *Y XZL%7W-$<Ĥ2Y=q9B6mXB/8qJҼ7H:+,dC? ɂCXKAݞ$LLvbi:GSH9V9'2#CwhFNO-'݇0jA^^xǻ߄G|VD (SO?~7c}:s [p/!NY\ =0ctw!

_W=[TO&0xWN!%ک?ť (5ĘK{e}?Ԅ4A &5͗.^ykC^_`@Z4`ȫbn2MX*5iIA0y`zYݎ3Bsݠ@e-U!JVaZ8o!YHf$IFI'^D)QPy;EO3Tsmj~) }[@AAo~;o=Ka(Ru=8w<u@ "hڕfID_߇FJ y?aE>sA E'CVX<¨(jǟ܅=hp}}M^Gp;zM3}g īFA:v|NYTIacJsƤdW0N̉N |n]dJCD٫qHRn)r!S0yR.]t}_b$ )D!?t,ߢ/݇Z&B8|IzK\2!HxCߏd#ΡVO󻿃 g/ꀔH֮^4ǨbmJT7UPGc6~mcZ $g1 zĉK* lv 8 kЪg4J(JeuRL5nݨq"DTg`u7s,||MU0LˣS s͈i2St;YJGyfn1Q"9)A &ۮ&Œl7Tݔ Q-DRrr.C@ǟUGDJ-Rj?ffwk׮q@Ep`kڑzC-i&4Z|"Tt@XN/W.Gg:+x[@V"u4?B*ڂy8M֭>ac<YXٻGn8 h8wT @$ ~_,LЂDbP'DXhՠLA[7Wn\~f?È>=Y^>xȫLÖqy$])Qnz=EH 2݁+ ASH]6ON3ZdP @əq+ɚ<~қUSX=7 ^dR)J/I%+15 k@13.^Zzԛ{ 쑤yA3hxFFG?O|?ݙD!t HQk(+/Qz⃏/s^xFM0qaE1~0H0Ń9F.#I`(ӄKװKXYCo}!e,^cG_ u=8hՆAhǿF1i-@m L+_c0KMzIWlk>d>F᳅Oͩr3}*L;*r^ R݄E*#M2;#_.5tf ")AuaS/.niEDzgWrHROw"SMғU86]t,ýw;E=/DQ#M8 \s]a"H- R0eVG.b:i <`#7o~j7њ%x߃ҵ#Q3O?( nDhHYXZaL ͩ%ߒ}S<ܦdCICilK׽٪VLB`LRՂe"=cmЋe!F+*tTQINtpO&D؊uFM{3%D RzEݮ֦QM,#ݨ)PfIB7%$I9xU&س0 ",.#07뤣Uљ{~X + Q4Y]GhZh5hkhhF6Ow-wa8@8ׅ ZiawdQ 9+i7ЬGv-SnK>iuXEأ#wi<61Ӹ32Hs&QsV&(4S$D* ˒ /qQ?tFH ~͹ո \ڑ ȨSpIQ"r5.% hŹ e'Vz7CV)ǬqX4E0.r9EؿX8A 1YЍ0g+$Y{FZ8զ?=:Z&71  4juu,,G o{wܽ=x,aiyPAy=< DZKh6Q!J(]"vPA$ Z E1_,uBR2]?"B%RI<_MkKFsצG-Ou֗]^( M~&QkI-ͦ$g;_VVO{|/xZ|k5܍~@ iC^QzBQXQAIhz.ڀHTrS%вup&f+HpLp,R(KGD R I{jԬx'@wZjQ&>k.zR\ȼiTҬQo2f+NK'rη+}&ɖYI 糁筅4ⵑfg!)R$* yGɅy]"88X:eOb)\Vn0>YTنbv39@ ^lmm%^oEQSDX\&Mk1PM)5^uǻxCBn?|.th3>h݂)j2ʾ;j~0^YރVn?J /A > }%iDDyM-CeHʀeY*K bIʺa0Y*1& 5TӐ#w q8 gEjVL=35LB;F#M#wNαcƏ9RQ0/t~s)ffnrsǬe$V%e\cR[‡q IDATh6L53% ,$Y²,pqY88)ac,@:n$l٧þ{1=9z6֌8m6!PkwZocyK +xY< ?y$K!p9߉-!(j⎻oƁwvl# uB#qF! %(3Y*32Mv;bƒ>"]ϖTAaьq7=O"̌ A㰒ϑ$N5JLcܿ҆lҨ3iqq>lKXQE P7h8 A#ai&ύk.<;zmF'6:juaC`>5v9eYh5.qft=-TuD|S|LOKܨ86[\m\EqEy@YipA\:1zvLBCF y+=uШkqO6%ƝǤh HUR7}Z`FX@ⴸ՛e766Ib()Ll az3a2' %)~LBZw!Low9G }5{(A#%%/q!N*o>1PVQPStamDq9€[ FH>dy_B/z~en7lC#Vl۴CY__ѐ"{hIyƱcp%6$n;8\11lc ^>uAclAp|qcFO&+{#qj~-{MmC+ J&_0;f0c 1Uv#P+ԒdeIRP3Ъ[[уRSNUrڿdZ#W Ő`'퇌mٸT* N ? $!::mn|U5u\]Ȅ:NPoz~,kQsf^jF1,Nݤ#ػsgpA13^={VX+*,+3Lg`y]vƋ!OcD6# ѩ,n*Z:N8aL!%E.aA R 4ru#FZ'KG wK,]~;155C֜4RпLSEнy^wv]{Gm#[MLò,||B*L/,~wP,# n^DyW/}NEvp0&F{܊<#/=wyזQw2mVc,+3FM̳,W2/[_I̱$\9b LY4FHc2FXƐ2FYHD ӻD|¶")$nɧ<i m.脀%%azzǷd_|ѺQ8W1΄7iCOFJTk)aXS! Ma]Hq]v O"#ns/bm 55=e"@2jHe-hxꅯG">ymmo߉?C{~7~DOÕ+R&*4Rwq2w܋8@,{zͯgzrזz^mFm|O寠uh? bǗ__Z8H[q2ƛc{j9#lp U#@2<Ҩg(BL0ȰZ<-'.<֋;i9KDJ:F؍hΙΓQ}ڟ0ݬPZʾvb V1E[\Z`}y,8@Dt!3mtҥݻwܟvub{,֌n{ρ5ţ3LB(w纗^^\Yc%nwC~'_=< $P, _Մk:?aBnÿ1a'߾@O4ܙ퀽ͨ, Y(w,&աh9sس`Ck)Ptźi ~0҇l:-1ӽdXkؽk>t$Bm\]ܢ|T+"oʰ!l$M#\}㱒Cc:f,]Gfsۍ.!|ʕMf]Ah=^3 &^wyl3b՛8=;+ʏ׬VARǩݬu]ʛ!BJo=LL %tBR LjL7^y.<2-h(Ccz ?W~勨5Z;/珟N9~M M8XNӌ|@kNCt~?oަ> V6[ua*wCIʲ`;ɡ .Z6Z6Zlj[pyEq i(OPz9m~1Pwvb(XXZz[+בQ.;v?rHFHo5hf捍0u9-j4=n 6DX\m7M![τ/Fv)f"ZGEXuJ%U&s B.R)(U@h@BATN MA|ɟ~w0|!rR 鯟oxe .ckfjvcs Mไ)=ȩhu%릇oF2Ie CZ]["^[G^Gn€NR4H| Ebff3cdy`VQo};Έ#zO`bI55^B=WV%ft[ Hg"-m6]Rt>w,#J{_9CRVE\/VRN+d"!p"~ʚ@-] A %?x7? n:21}':k5ڹ_˨SsU\x|n*;xfYCxfb% ?#l q]tÈ^:z/^cj{Gr9 M?|νyφRldʹ 8]ɓhAgā8}jO<%R[ jkU EKc7:m*S\Fa|n 9AeY|xh̦D&8'?rL`D|Q:}-`}}5Zm۷>fg52R+aracc/_Ɖ'pY EjX[[;np曹hy%@H+ȷ J (%xi=rˆIKwʍ F"rMJg!Vǧ9E`1ewCOHW[?tE8֫{F 3_z1iۂv$4;oJ4!z#Œ,v%*ǹ4>A;w7nl9=JBna\]ʅU\[^Itnֹ4VRe^Iot:l@p E8"'gfYI'J%`I~ WayRxᏒW(W,W_Ǐ"VWh;瞻#mAgWTM\++ # ;wggN}혛ç>)sZ}]g;Bٙ5Ѧs1h0)֘..vݽ^^Rڍ G3^\\lh#癁mSvh)`0ǚenyW5?ĆYElB쌨<5U/Y@*YJPKRuƒ똻AvJEJxКަ;:%B[`RJ\P*m&mֈ#xh7Ф Ss`g(o~JGS,xCaϞ=򗿌7888y Awu*W=%=A *üzUԃk)nܨ _~\R,KEOƕZ]PCk@#Mhg]+4ǒP;3bkbgn,)Z'SNCQLٙ~&)aOLF']!!8v)0ZC*Ҷx+S41 aYAA4f<_3ԥ~;P.eǯ*---bcc'CV[~gΜO3ZzSW|I9*h0Xt贻מƝw//0$JvNgOlB"=Tlzs,ItBsHhm1bX1fֽa!>|#Ȳefdu[AWnarsCe#N[v5=sEl4HH8cLdMn.ݶqwB&!-C*,U%0 c4 \a|Ҳ`Vx$ʹl6iinŅ3ڏ)Ycӳ:_3P1V]\ b00 Ƥn8%J B&>X0 dyI&c.F `B&/H$MMu SJƃ7NU/A{!^|E,//auur ^j|n!D2 O)#BTRJH%#<˂RRɺ8eRϔefy B$$%-H e?i4ZWB>[lμFAa5$!RH.# ][!(]$ >q5|M, ,d-6FlĆZ#0r"୚a1rή3]5YҲ +4t~$X~0;[n`e{6`$vVenץ_W&sIħa7_|!8 pvHR6LAJ R,+ޒJFYPԁRJ )$ (>b_ &/}4M,//…0P4o9&f]tF`qe)aʘ\! 07}h_sέgqvH;H}Eͣ|@ *KxreȠZ5<66 8R]I\AZV&$I4X"vls?#,P4 6y捿v)-,,믿.z)o~l4ֵQ:% d dKRiPX`YJ&?w%$PTXRdGdU0R),-WʫoR~j5jq5VY6E6N}!|5Nt:aR&"Znh%3ﻑm:C'LZ YZ3O:J 9Mp" ,YB*;@Fl_1<%?hZt+ J = D#6ĚG b6L؋ue;; s:x_Bنm=r%+Ӳ*IsJ~"AL3`Ѯ-K~- 0pn '] ᥣh]8 A)][pA:u V+* [JRcu˟=́<啹$`K 1-VY7HN ^zɾQb~0蓕Z-En][K&ԍ W4GhG<lZ0ŚArPsnfFodA2Iu֯mdYjKh "yhZxSpyC%@%PVZ.Y6l+),ۆpq=8N!q]s=8n^[*PstY}z/!v ~?CRړgCGEzV,h;b{T.X##B@DAQ!=HF9CPeff^\\\dRV6LR ,:-l?K5]h:EC:x3oF@:DIpSPM7g 3CsR^%@#CL 1 >c+hiiUt:T*k&*e A@BAH6 T,+p]/׃mm'M`+˶`[.JKJryY~Az̿ ru_?6660u/JHJW1 } c%Bci`H.*TW\i(@}f@7[Z3)AX^ds%ڤb||vȕW~J;eVnEC:C( _SLmeVW۴I\`co{rtm `5tt:8p\7Ē5B 48/&smgy>B¶\ׁ e;P?+UBa_簺gwa'O)%|Ian7@$clקn(rk%NJ\mr+QLDnd41BzI37xcYJ)0juߌv76qfx$ 7ɇ?傇DF=.l$Y-3=f b#K^ޅ*(a9F!WUanw}7jX\ZIkn"aZ.1~\Yqzo,㕗^yo{shի :7|nv P7n|mCaj'RvmvЇFFQx6 IoхN'˅ }YiͥKBfimw(N86#^UPQ>eGd\ci0 lg(?롻snd= 7n|@A7P;5-a˲~TWV Ä.J%qʷ7Q6V9lۆ z|E:y/x챏X?8{Eئr@3"@I}!!Hv=^kL:1oq m۶}h#Bt]R28m.Sre o_n{-'{ t y7pV`MDmv(ֈb m*i|L3 C9KÇ.ن0yrRlA A8' _pGt8i֮JV`!ľ} +(%m ~Kx;q.; Ip<yqT*DQnqAu]8}u\&ec2tqN[ɂm)u̎)~H CXLH(0dz2F/R8nwzX$7cFX&ceL2pI]QƧgq`4p͕kp]m#v4(JF)5u7!P*.`-IIF`cnH4|uOd DZs^;׫mVD|,()bdOĐr bbb|s%piQ% { FYD6ɤ%=Xy3u3*бN䤳>JPy!؁oADwR `I) t:m$Fr A8S$tZ=ecM jΣX*u/\ƥ5>+)l!u )e)QhkKPUe6N`;;ߨ+4oN˪Y`VVV)5pKJ!F0oƺW R %mYuGhmĮ1).`䧯W<0?Ĉ&=wQ8Q#ֺO7~Xc%Bj`se؅D%$CX{>Ƕ`5C()mv NV [IFJ!cLMA)vb,.v9>lCcIs_gt%`AL^WNn CEH9$ :f+#SwJ̫wmm-4l}m)Lv@gvozGtf 4Dfа0h8jrs C~VMDAddeԀ#-rSkiy1 2 qBJ<|??3!U䄔L̡"޳NbZl6h4ZPAԳ71 sx@8e)x^`rrޏX8B qղ-qf3AՈ-ѩYܧ' ]r=\B`rm ;kDtFHvzhn4ڶ0cmwLqpU~MM3R2)89{-CA14àމFQeSͤˊ1a nR˗/bpsYx剤 K ~ V~s{'?mz 4~7~ߚlˆm[mWߋ5赫pR+ל+˂{m z hXH2HF!H~q[-/\m{Hd/.읎|0pEzcc#H! B'n+ 4;km }KRRSA;?ɦ!eC<W+'2 csVfه$I8T GhaԿ$ ymr|DJDG}SSVY<14O!?#8? 8xJ;Nom.;οsKK 6v|= R)V 5m\> v X*06™3o#c4hw$\Hp43Ν5cJ[\q.ҋqs#3T %d)i^>hԕOjG ܳʳu1$0_~ѻЉ] s~If/HzoQ?!cڬ׃x( l֢V, Z{vU0mmr]?<>OM~jǁ?~vTǛ/>. -ݲl":~ eX,46RP(v\XJ1`@)+-oDB3, :ԭ(DQb! 5X墂y7N( uN r6/ٴŅkKq,CX7 .4~a~  E d' A 3Xw >r%Q\DaֆLuIȲW" -N@$f88vN^Z9uNV`No5^/\}Õ/sܸ2ڭNځNҊՄHy,lr'|bfRԒ4-]7ҫ $?W(r*]OZaqStX)ݍ `upе|e؄z;d\bT/33mzׯƙ, VݙnsYkK30>K5Vد&`4=ƯK}(ߘhZr][U.,Mt1qZt:7Ў|>O}oa0:IPPΠ8Û^7.`TҒ&Iʫ/Bi-aB |{Y!O??Fez ?djmq{x :HU7nid<>qT.ִƍSi^F ݹpޤJEu(gY4I(TW%lKqi?3+ZPC8yO ,8x䣋xD,W^s=ӧNO=9gG AiZr#)]qlRpMQ)3P5G#J>Oc|JkI|'IR*KFfU%Zi;,K+Qe"X'WfR*:_/Clnn ;GnEU@Z;DVw*6NBJATU [疃K^Pr5o."{9x!tCj97_GVajn뜠\Vd^?≷X,B[r-f7QQM}oo`o*>}fYD T̊"RJUÅď8afhJ@-$]Uqat|2p}dY7NCT.d +ߵa=~LB_t̍*ꎙy4ڈ?;-ZbH Nh8o4>V'25#v99wh||jR3 e,Bβt^.rj{9q.9G'".]߆|{x FeQ6rApY09 |F +ԯRUڵkԧ>f`0áLg3nP=< Z^j-H:eAOD$V݊ 槣V (b|PJXIZ~G[T)zso*+^U6N8]ω74>U4n.뙪 \dEPkY +sBAjݒ³Dz>bss__1O=(s(cd1ZNPS|'`ٗQs0F׿[\h4§>)\v ֶx I/[o6vYY=RHPk ^a殈3Yo:oeooZV¥tݝB7\5,jp~~sE*jʈjrjtB^DIYX&65vY`YAYpz>ٿLT666+w|>x{t|$B,ލ ~xH YbE .]677]0MYg]Lijg+gv2o}@2v& 'e* oﭭOz[cJ)5E0W p=uXJk\!xcU=YpþV[V{ǝE91/Z粵E'N!^{5/"^ylmVʏ\>m8+댧ukr.br{`k_:~[[[.D&Ln^'6:qNř(UڢƇVk`NFLD~qWzwu3ăm `V "'>8Bz'h~i9R!pR%*Tu7Fٶ#׫M5"ڷބ+a$(3W~v/f]چR.F1~W~?3Gw 9R0JŽU,"D%p1>u a 6h"񈦛fO/|2⮝ YOZ,PIB0Jt3EX1l1+GJ 9Ϳװbkk ^[[[7`D7ob},w; 6dEƥ1_: FO!"H urK !dH$՝6>PgyġDnu2Lt:-n;(u=;(aBbj5eb1լA٣41ϖ/$X0 4HZ-H&ɑs.TVk_z$Y+s̍ԩSߖpt{K7hX' 0Ƽ&ő_U24j r*ъ9+d&{za~E%,م|]\:Mit)ؠxdnwpW_^R)Xka7D@g|?GV H>l>|:(<'Dmݵ)h%옪G`sئKo;ZS:`#Q|5;%$Iу>xVVhrpNׇU .lAi=6L:v*\r k\w54]ėEHXlZaM`<9h1z/vtJݡV-'OM̦|<_T\Z? Y-y(X"p=C`L9*\9,sm7ѧ& 9@ b2(((MD8xe.M#%zP!"V̗ۓJU3 E j!n˙!,"k׮!?/ъTVF;DU3ba +{a:SYRS,&.Ne?8h7;,ױiT￝_IZlsn NOV ~XZ0i Ε,I~[xLEKX sYnc5IHPTKttE ҩ5)+.b'򭿾6k~ʸW P"WѸЛ*5W?8; rO/33+ŋ#]!,4RY(Ehv$.U g?i%b9qᲲ>u ya*:KgK_p?=J֏$$_Z'YPeJSRi*iP|Ɗ 5ZD1(yQ`<3r3lU_t֗$n D鎨/:B TV*ӹjD&\^|=H+S% j`06xq]?(ҭ͖ u矟}Cz[0Toe"⃃0y*~6m%q1NF\Nv\MԊZ*6$^JM jCN=YI&R2s'r޷RXC0S[UmV0q;n'l1W ZjMAS!Z D [r [CEae272^.e]ѭ ZC@tD}Qi<]!$"D%"? JkSwpcv:r ʢXJ'h͋#y,$L:JSO=u k뵐-dYRČ&<oKQSr=XNKC-J8ӯ A* WbP#(E :vmiXOl8QhL>UbQ.ݻ so$VG]D caca;0tk ;䴽Xg=QI_Tc{i_TE #HXAHwEQ ݬ4UO WUX@ɫOE-i#PUP3S Q͢D@/@AdpEJ5e|t8$Y!z+rccX#9D*cltQE-kńI\v98'HB;ʐb@=I*RcJsdsq / t̝ݫ+xRn7a(@6կn=SoL쮄QoL|I2Tjfg{s'k䅕VK@QZ-pWebE@1uJAV2 Ex.tDx9i~KXF4^HG"bTKYq 63[lʢi"Vi9tKHgк-T0 K䣥[9DZj kFXhoo"W.\ȭ>83{[OPD8Y"D$/?UT:ߛZFpfJBe JC, ҥ!iQ\מ_9ڥУBAXr -B -$ Mڐ,.)P(t <.y#LWBUf ÔFa5 u,foxmOLs| D<nS,1C`Z|WsAm̔YDzȭ/RKZ :VP>ԪTTkIk׉W]%} *H\x*fralnz[50zW!;h$$PBJC@ DWN?HT?"-X"mp5`3[)Z9-vv)FwZ4VPEf$PoWŷ= CXռp`/ s3py#M޳\bAV~lTZP*|5!(D<}-y,tlp@ ȭ,F˲.r LU&RQU<ƃ[fTDV%;0I9"PѸX吥FGHՆ /GDwąg%ek4UUXy(M(d`^ Y{$˗gpq?SۛqqSpʄ"80_VF*ׅ rMU>tߕzI:*ho%^ 3ԭ,%l=o9\4\hIMK &"IdL!+E[>,F(p*ք4'Jq@$U4%N%&N%iB&$i)qNi:(d `y!q,jԅ ?#wn;)Z&fK2$2saYȲ2+g[ 1|9$a"`&PhY`!,Us9 KPAM_ٯ',J8HXI%ElSMip8*[)q+Q幌8J ѪD$$$J}$)Z҄$|L *ǩ eEAQyNs5UDKtEd(dVb#DPJ^Ɠ1Ο.DtIcrb1ܱ2n<q(l^:/(_3RާDbZjeۂBzYR-TG+*Tc*wBBE HNJt2Tne-r.oZ; :Za,ʫSBDtBkE$Z"VV H(ETρ$$+=)8UY$Ӑ4!δ,!)W`H(TkE(*KC^p\>T& R"q@KOFV~nΜ^oXD$,Rzg/GtZsTEhͭWa/u~'w'7QQ(=d2)s.I$ 0襜ij9V$BHED$C-R/DZ$Kɵ2i)nejʈLs*ng۩VFδke$LVR*HJt9EH48)]Gք|\su n6ްQIEe?B PǾ%oY@߾Y'g0?[eIE?~ VeHPDd<$Qh?kn]HDVhWӠ$XIDATDke:X/jEONVz1I9u 2E&%j/m҂ڟիWgZ3-5vj)ճRiXkJ)ND§'F_dzw$XYw/E`cx6~7NS7t:fF$&u$RJQ+?0GP?RI I]>4 lJ"})j#"X߷>}s7~Cb5ZqbHD/^KνZJc kmaO +#7֊cV[k-܃W.s.vk(^]kՎunG\+B;ݲ(D$>D(dI-9_\s^qtDq;Dkg}vESbq #Oob8 .]ykc!6~cƘ1fX,rb<7t>LL&xk2X[;(GQ2- o~7 nwx_WJhcY\㱠?PK~i pJ=0Ƥ^o^;p.fvT^:n?:{KC]j~_G0 j[fn% J.6+ V0C(gk;cfvΝFes/1^OvXTb0SJ99Sﻺx},gY/`0moo/$)^^Vq>lYbW)gEQ(( *Fc𷊙)JDT{Qx<ߏ"w-9^Az`i|UQG9}j} ^èÚ+a8r Ļ F}7VcTQa5S nYn] T }\tAEyw=Gxc<p8h4:w,6666wvvpt:Nλ g]9 9(t*V $IHu?d'+t-&""TQ첶&Qv9Ԫ)8Vw0o={6yǨh47osN{w}Hgz~#rVHWA,ס Cg\ApK/d^z߯f~?'[cAѠUq-<~>;w@,Aۅ'nZW۹NΚB 7z)ԇo.Gf{Wz^\vSMVI6)W//XA~{pXkZJIQ!ɡ Vsp{%Nx;V.\/vݞZn^ -Â5EkR\6?c9Vwn&IXhJCPq+[vh!hOvݬ3n7=,ZwTaJ~ٰo层dNkъ`7ҷUܢqՕ:r, mDuN8)\lV{.Fi6K&WJᓟ׎XAޑ-2(6޶wZn(+Hb=E]xQ B?_e._c^ .T yB~xGXA~z?|RA9$Xvtk8Vcy綝>}:HݥYswj]w['J)r:uԗEXAމM'$I2\5kѷH,ʚ%I)sEXAމme=qD%6NlďI=s[ES33[kIT,pxf8`00YeYEeѓɤ5tJ.sSFb{b OD{`*x$y1]E( mI-cLfķgzj}O?Vgp8pc8^Ou:tNW/.]]ti~|>/EX,bQEaBcjE]Qc^W|'"gf9rεED P9nDž`s9w9wGιsnW9g.]c+gy'ߤpA2 "71(zEQcyZ{s(ƘEQ֦EQ( 1Hd(Xq`.ess 3_^eι}5/yYD*$׾v獋vڏlӈ(YOlIENDB`vokoscreen-1.9.0/preparing.sh000077500000000000000000000023631227001500100162150ustar00rootroot00000000000000#!/bin/bash echo ================== echo Remove ffmpeg logs echo ================== rm *.log echo ============ echo Make main.ts echo ============ lupdate -locations none -recursive ./ -ts main.ts echo ====================== echo Download language pack echo ====================== tx pull -a echo ========================= echo Remove old screencast.qrc echo ========================= rm screencast.qrc echo ===================== echo Create screencast.qrc echo ===================== ########## # Pictures ########## echo '' > screencast.qrc echo "" >> screencast.qrc array=''$( ls -al pictures/*.png | sed 's/ \+/ /g' | cut -d " " -f 9 | sed 's/ \+/ /g')'' # ":" is separatorr echo $array | sed 's: :\n:g' >> screencast.qrc ################ # language packs ################ array=''$( ls -al language/*.ts | sed 's/ \+/ /g' | cut -d " " -f 9 | sed 's/ \+/ /g')'' # ":" is separatorr echo $array | sed 's: :\n:g' >> screencast.qrc sed -i 's/.ts/.qm/g' screencast.qrc ######### # VERSION ######### echo 'VERSION' >> screencast.qrc echo '' >> screencast.qrc echo '' >> screencast.qrc echo ========== echo Script end echo ========== vokoscreen-1.9.0/regionselection.cpp000066400000000000000000001125211227001500100175620ustar00rootroot00000000000000/* vokoscreen - A desktop recorder * Copyright (C) 2011-2013 Volker Kohaupt * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "regionselection.h" #include using namespace std; // Double Buffering //http://books.google.de/books?id=T373zcyFfvoC&pg=PA168&lpg=PA168&dq=qt+double+buffering&source=bl&ots=Wavv6fM_7D&sig=eOilngWo3WQzrrRPcoP4oOycWbE&hl=de&sa=X&ei=_hgAUoKNIcjwsgaiiIHgCw&ved=0CDEQ6AEwAA#v=onepage&q=qt%20double%20buffering&f=false /** * int x : * int y : * int width : * int height : * int framewidth : */ regionselection::regionselection() { handlePressed = NoHandle; handleUnderMouse = NoHandle; painter = new QPainter(); // Muß in die vokoscreen.conf von Hand eingetragen werden. Keine GUI Unterstützung. // NoShowInTaskBar=1 QSettings settings( "vokoscreen", "vokoscreen" ); settings.beginGroup( "Area" ); if ( settings.value( "NoShowInTaskBar", 1 ).toUInt() == 1 ) { setWindowFlags( Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::ToolTip ); Setting_Area_NoShowInTaskBar = 1; } else { setWindowFlags( Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint ); Setting_Area_NoShowInTaskBar = 0; } settings.endGroup(); if( QX11Info::isCompositingManagerRunning() ) setAttribute( Qt::WA_TranslucentBackground, true ); setMouseTracking( true ); borderLeft = 20; borderTop = 20; borderRight = 20; borderBottom = 20; // Von außen bis Mitte blauer Rahmen // Breite blauer Rahmen frameWidth = 4; radius = 20; penWidth = 2; penHalf = penWidth / 2; // Framelock lockFrame( false ); } regionselection::~regionselection() { } void regionselection::saveSettings() { QSettings settings( "vokoscreen", "vokoscreen" ); settings.beginGroup( "Area" ); settings.setValue( "NoShowInTaskBar", Setting_Area_NoShowInTaskBar ); settings.endGroup(); } void regionselection::cleanRecordArea( bool state ) { if ( state ) { QRegion regionWidget( 0, 0, width(), height(), QRegion::Rectangle ); QRegion regionRecord( borderLeft + frameWidth / 2, borderTop + frameWidth / 2, width() - borderLeft - borderRight - frameWidth, height() - borderTop - borderBottom - frameWidth, QRegion::Rectangle ); QRegion region = regionWidget.subtract( regionRecord ); setMask( region ); } else { clearMask(); } } void regionselection::HandleTopLeft() { QColor color, arrow; if ( isFrameLocked() ) { color = Qt::red; arrow = Qt::red; } else { color = Qt::green; arrow = Qt::black; } QBrush brush( color, Qt::SolidPattern ); painter->setBrush( brush ); painter->setPen( QPen( Qt::black, penWidth ) ); QRectF rectangle = QRectF( borderLeft - radius + penHalf, borderTop - radius + penHalf, 2 * radius, 2 * radius ); int startAngle = 0 * 16; int spanAngle = 270 * 16; painter->drawPie( rectangle, startAngle, spanAngle ); // Begin Pfeil zeichnen double h = 2 * radius / 3; painter->setPen( QPen( arrow, 2 ) ); QPainterPath * painterPath = new QPainterPath(); painterPath->moveTo( borderLeft - frameWidth / 2 , borderTop - frameWidth / 2 ); painterPath->lineTo( borderLeft - h + penHalf, borderTop - h + penHalf ); painterPath->lineTo( borderLeft - h + penHalf + 7, borderTop - h + penHalf + 3 ); painterPath->lineTo( borderLeft - h + penHalf + 3, borderTop - h + penHalf + 7 ); painterPath->lineTo( borderLeft - h + penHalf, borderTop - h + penHalf ); painter->drawPath( *painterPath ); } void regionselection::HandleTopMiddle() { QColor color, arrow; if ( isFrameLocked() ) { color = Qt::red; arrow = Qt::red; } else { color = Qt::green; arrow = Qt::black; } QBrush brush( color, Qt::SolidPattern ); painter->setBrush( brush ); painter->setPen( QPen( Qt::black, penWidth ) ); QRectF rectangle = QRectF( ( width() - borderLeft - borderRight ) / 2 + borderLeft - radius, borderTop - radius + penHalf, 2 * radius, 2 * radius ); int startAngle = 0 * 16; int spanAngle = 180 * 16; painter->drawPie( rectangle, startAngle, spanAngle ); painter->setPen( QPen( arrow, 2 ) ); QPainterPath * painterPath = new QPainterPath(); painterPath->moveTo( ( width() - borderLeft - borderRight ) / 2 + borderLeft, borderTop ); painterPath->lineTo( ( width() - borderLeft - borderRight ) / 2 + borderLeft, borderTop - radius + penWidth + penHalf ); painterPath->lineTo( ( width() - borderLeft - borderRight ) / 2 + borderLeft - 3, borderTop - radius + penWidth+7 ); painterPath->lineTo( ( width() - borderLeft - borderRight ) / 2 + borderLeft + 3, borderTop - radius + penWidth+7 ); painterPath->lineTo( ( width() - borderLeft - borderRight ) / 2 + borderLeft, borderTop - radius + penWidth + penHalf ); painter->drawPath( *painterPath ); } void regionselection::HandleTopRight() { QColor color, arrow; if ( isFrameLocked() ) { color = Qt::red; arrow = Qt::red; } else { color = Qt::green; arrow = Qt::black; } QBrush brush( color, Qt::SolidPattern ); painter->setBrush( brush ); painter->setPen( QPen( Qt::black, penWidth ) ); QRectF rectangle = QRectF( width() - borderRight - radius - penHalf, borderTop - radius + penHalf, 2 * radius, 2 * radius ); int startAngle = 180 * 16; int spanAngle = -270 * 16; painter->drawPie( rectangle, startAngle, spanAngle ); // Begin Pfeil zeichnen double h = 2 * radius / 3; painter->setPen( QPen( arrow, 2 ) ); QPainterPath * painterPath = new QPainterPath(); painterPath->moveTo( width() - borderRight + frameWidth / 2 , borderTop - frameWidth / 2 ); painterPath->lineTo( width() - borderRight + h - penWidth / 2, borderTop - h + penWidth / 2 ); painterPath->lineTo( width() - borderRight + h - 7 , borderTop - h + 3 ); painterPath->lineTo( width() - borderRight + h - 3 , borderTop - h + 7 ); painterPath->lineTo( width() - borderRight + h - penWidth , borderTop - h + penWidth ); painterPath->setFillRule( Qt::OddEvenFill ); painter->drawPath( *painterPath ); // End Pfeil zeichnen } void regionselection::HandleRightMiddle() { QColor color, arrow; if ( isFrameLocked() ) { color = Qt::red; arrow = Qt::red; } else { color = Qt::green; arrow = Qt::black; } QBrush brush( color, Qt::SolidPattern ); painter->setBrush( brush ); painter->setPen( QPen( Qt::black, penWidth ) ); QRectF rectangle = QRectF( width() - borderRight - radius - penHalf, ( height() - borderTop - borderBottom ) / 2 + borderTop - radius, 2 * radius, 2 * radius ); int startAngle = 90 * 16; int spanAngle = -180 * 16; painter->drawPie( rectangle, startAngle, spanAngle ); // Begin Pfeil zeichnen painter->setPen( QPen( arrow, 2 ) ); QPainterPath * painterPath = new QPainterPath(); painterPath->moveTo( width() - borderRight + frameWidth / 2 , ( height() - borderTop - borderBottom ) / 2 + borderTop ); painterPath->lineTo( width() - borderRight + radius - penWidth - 1, ( height() - borderTop - borderBottom ) / 2 + borderTop ); painterPath->lineTo( width() - borderRight + radius - penWidth - 7, ( height() - borderTop - borderBottom ) / 2 + borderTop + 3 ); painterPath->lineTo( width() - borderRight + radius - penWidth - 7, ( height() - borderTop - borderBottom ) / 2 + borderTop - 3 ); painterPath->lineTo( width() - borderRight + radius - penWidth - 1, ( height() - borderTop - borderBottom ) / 2 + borderTop ); painterPath->setFillRule( Qt::OddEvenFill ); painter->drawPath( *painterPath ); // End Pfeil zeichnen } void regionselection::HandleBottomRight() { QColor color, arrow; if ( isFrameLocked() ) { color = Qt::red; arrow = Qt::red; } else { color = Qt::green; arrow = Qt::black; } QBrush brush( color, Qt::SolidPattern ); painter->setBrush( brush ); painter->setPen( QPen( Qt::black, penWidth ) ); QRectF rectangle = QRectF( width() - borderRight - radius - penHalf, height() - borderBottom - radius - penHalf, 2 * radius, 2 * radius ); int startAngle = 90 * 16; int spanAngle = -270 * 16; painter->drawPie( rectangle, startAngle, spanAngle ); // Begin Pfeil zeichnen double h = 2 * radius / 3; painter->setPen( QPen( arrow, 2 ) ); QPainterPath * painterPath = new QPainterPath(); painterPath->moveTo( width() - borderRight + frameWidth / 2 , height() - borderBottom + frameWidth / 2 ); painterPath->lineTo( width() - borderRight + h - penWidth / 2, height() - borderBottom + h - penWidth / 2 ); painterPath->lineTo( width() - borderRight + h - 7 , height() - borderBottom + h - 3 ); painterPath->lineTo( width() - borderRight + h - 3 , height() - borderBottom + h - 7 ); painterPath->lineTo( width() - borderRight + h - penWidth / 2, height() - borderBottom + h - penWidth / 2); painterPath->setFillRule( Qt::OddEvenFill ); painter->drawPath( *painterPath ); // End Pfeil zeichnen } void regionselection::HandleBottomMiddle() { QColor color, arrow; if ( isFrameLocked() ) { color = Qt::red; arrow = Qt::red; } else { color = Qt::green; arrow = Qt::black; } QBrush brush( color, Qt::SolidPattern ); painter->setBrush( brush ); painter->setPen( QPen( Qt::black, penWidth ) ); QRectF rectangle = QRectF( ( width() - borderLeft - borderRight ) / 2 + borderLeft - radius, height() - borderBottom - radius - penHalf, 2 * radius, 2 * radius ); int startAngle = 0 * 16; int spanAngle = -180 * 16; painter->drawPie( rectangle, startAngle, spanAngle ); // Begin Pfeil zeichnen painter->setPen( QPen( arrow, 2 ) ); QPainterPath * painterPath = new QPainterPath(); painterPath->moveTo( ( width() - borderLeft - borderRight ) / 2 + borderLeft, height() - borderBottom ); painterPath->lineTo( ( width() - borderLeft - borderRight ) / 2 + borderLeft, height() - borderBottom + radius - penWidth - 1 ); painterPath->lineTo( ( width() - borderLeft - borderRight ) / 2 + borderLeft - 3, height() - borderBottom + radius - penWidth - 7 ); painterPath->lineTo( ( width() - borderLeft - borderRight ) / 2 + borderLeft + 3, height() - borderBottom + radius - penWidth - 7 ); painterPath->lineTo( ( width() - borderLeft - borderRight ) / 2 + borderLeft, height() - borderBottom + radius - penWidth - 1 ); painterPath->setFillRule( Qt::OddEvenFill ); painter->drawPath( *painterPath ); // End Pfeil zeichnen } void regionselection::HandleBottomLeft() { QColor color, arrow; if ( isFrameLocked() ) { color = Qt::red; arrow = Qt::red; } else { color = Qt::green; arrow = Qt::black; } QBrush brush( color, Qt::SolidPattern ); painter->setBrush( brush ); painter->setPen( QPen( Qt::black, penWidth ) ); QRectF rectangle = QRectF( borderLeft - radius + penHalf, height() - borderBottom - radius - penHalf, 2 * radius, 2 * radius ); int startAngle = 90 * 16; int spanAngle = 270 * 16; painter->drawPie( rectangle, startAngle, spanAngle ); // Begin Pfeil zeichnen painter->setPen( QPen( arrow, 2 ) ); double h = 2 * radius / 3; QPainterPath * painterPath = new QPainterPath(); painterPath->moveTo( borderLeft - frameWidth / 2, height() - borderBottom + frameWidth / 2 ); painterPath->lineTo( borderLeft - h + penHalf, height() - borderBottom + h - penHalf ); painterPath->lineTo( borderLeft - h + 3, height() - borderBottom + h - 7 ); painterPath->lineTo( borderLeft - h + 7, height() - borderBottom + h - 3 ); painterPath->lineTo( borderLeft - h + penHalf, height() - borderBottom + h - penHalf ); painterPath->setFillRule( Qt::OddEvenFill ); painter->drawPath( *painterPath ); // End Pfeil zeichnen } void regionselection::HandleLeftMiddle() { QColor color, arrow; if ( isFrameLocked() ) { color = Qt::red; arrow = Qt::red; } else { color = Qt::green; arrow = Qt::black; } QBrush brush( color, Qt::SolidPattern ); painter->setBrush( brush ); painter->setPen( QPen( Qt::black, penWidth ) ); QRectF rectangle = QRectF( borderLeft - radius + penHalf, ( height() - borderTop - borderBottom ) / 2 + borderTop - radius, 2 * radius, 2 * radius ); int startAngle = 90 * 16; int spanAngle = 180 * 16; painter->drawPie( rectangle, startAngle, spanAngle ); // Begin Pfeil zeichnen painter->setPen( QPen( arrow, 2 ) ); QPainterPath * painterPath = new QPainterPath(); painterPath->moveTo( borderLeft - frameWidth / 2, ( height() - borderTop - borderBottom ) / 2 + borderTop ); painterPath->lineTo( borderLeft - radius + penWidth, ( height() - borderTop - borderBottom ) / 2 + borderTop ); painterPath->lineTo( borderLeft - radius + penWidth + 7, ( height() - borderTop - borderBottom ) / 2 + borderTop + 3 ); painterPath->lineTo( borderLeft - radius + penWidth + 7, ( height() - borderTop - borderBottom ) / 2 + borderTop - 3 ); painterPath->lineTo( borderLeft - radius + penWidth, ( height() - borderTop - borderBottom ) / 2 + borderTop ); painterPath->setFillRule( Qt::OddEvenFill ); painter->drawPath( *painterPath ); // End Pfeil zeichnen } void regionselection::HandleMiddle() { QColor color, arrow; if ( isFrameLocked() ) { color = Qt::red; arrow = Qt::red; } else { color = Qt::green; arrow = Qt::black; } QBrush brush( color, Qt::SolidPattern ); painter->setBrush( brush ); painter->setPen( QPen( Qt::black, penWidth ) ); QRect rect( ( width() - borderLeft - borderRight ) / 2 + borderLeft - radius, ( height() - borderTop - borderBottom ) / 2 + borderTop - radius, 2 * radius, 2 * radius ); painter->drawEllipse ( rect ); //Begin Pfeil zeichnen painter->setPen( QPen( arrow, 2 ) ); QPainterPath * painterPath = new QPainterPath(); //arrow left painterPath->moveTo( ( width() - borderLeft - borderRight ) / 2 + borderLeft, ( height() - borderTop - borderBottom ) / 2 + borderTop ); painterPath->lineTo( ( width() - borderLeft - borderRight ) / 2 + borderLeft - radius + penWidth, ( height() - borderTop - borderBottom ) / 2 + borderTop ); painterPath->lineTo( ( width() - borderLeft - borderRight ) / 2 + borderLeft - radius + penWidth + 7,( height() - borderTop - borderBottom ) / 2 + borderTop + 3 ); painterPath->lineTo( ( width() - borderLeft - borderRight ) / 2 + borderLeft - radius + penWidth + 7,( height() - borderTop - borderBottom ) / 2 + borderTop - 3 ); painterPath->lineTo( ( width() - borderLeft - borderRight ) / 2 + borderLeft - radius + penWidth, ( height() - borderTop - borderBottom ) / 2 + borderTop ); //arrow top painterPath->moveTo( ( width() - borderLeft - borderRight ) / 2 + borderLeft, ( height() - borderTop - borderBottom ) / 2 + borderTop ); painterPath->lineTo( ( width() - borderLeft - borderRight ) / 2 + borderLeft, ( height() - borderTop - borderBottom ) / 2 + borderTop - radius + penWidth ); painterPath->lineTo( ( width() - borderLeft - borderRight ) / 2 + borderLeft + 3, ( height() - borderTop - borderBottom ) / 2 + borderTop - radius + penWidth + 7 ); painterPath->lineTo( ( width() - borderLeft - borderRight ) / 2 + borderLeft - 3, ( height() - borderTop - borderBottom ) / 2 + borderTop - radius + penWidth + 7 ); painterPath->lineTo( ( width() - borderLeft - borderRight ) / 2 + borderLeft, ( height() - borderTop - borderBottom ) / 2 + borderTop - radius + penWidth ); //arrow right painterPath->moveTo( ( width() - borderLeft - borderRight ) / 2 + borderLeft, ( height() - borderTop - borderBottom ) / 2 + borderTop ); painterPath->lineTo( ( width() - borderLeft - borderRight ) / 2 + borderLeft + radius - penWidth, ( height() - borderTop - borderBottom ) / 2 + borderTop ); painterPath->lineTo( ( width() - borderLeft - borderRight ) / 2 + borderLeft + radius - penWidth - 7, ( height() - borderTop - borderBottom ) / 2 + borderTop + 3 ); painterPath->lineTo( ( width() - borderLeft - borderRight ) / 2 + borderLeft + radius - penWidth - 7, ( height() - borderTop - borderBottom ) / 2 + borderTop - 3 ); painterPath->lineTo( ( width() - borderLeft - borderRight ) / 2 + borderLeft + radius - penWidth, ( height() - borderTop - borderBottom ) / 2 + borderTop ); //arrow bottom painterPath->moveTo( ( width() - borderLeft - borderRight ) / 2 + borderLeft, ( height() - borderTop - borderBottom ) / 2 + borderTop ); painterPath->lineTo( ( width() - borderLeft - borderRight ) / 2 + borderLeft, ( height() - borderTop - borderBottom ) / 2 + borderTop + radius - penWidth ); painterPath->lineTo( ( width() - borderLeft - borderRight ) / 2 + borderLeft + 3, ( height() - borderTop - borderBottom ) / 2 + borderTop + radius - penWidth - 7 ); painterPath->lineTo( ( width() - borderLeft - borderRight ) / 2 + borderLeft - 3, ( height() - borderTop - borderBottom ) / 2 + borderTop + radius - penWidth - 7 ); painterPath->lineTo( ( width() - borderLeft - borderRight ) / 2 + borderLeft, ( height() - borderTop - borderBottom ) / 2 + borderTop + radius - penWidth ); painterPath->setFillRule( Qt::OddEvenFill ); painter->drawPath( *painterPath ); // End Pfeil zeichnen rect.setLeft( rect.left() - 2 ); rect.setTop( rect.top() - 2 ); rect.setWidth( rect.width() + 2 ); rect.setHeight( rect.height() + 2 ); setHandleMiddleForMask( rect ); } void regionselection::setHandleMiddleForMask( QRect rec ) { HandleMiddleForMask = rec; } QRect regionselection::getHandleMiddleForMask() { return HandleMiddleForMask; } void regionselection::printSize() { QString widthHeigtSize = QString::number( getWidth() ) + " x " + QString::number( getHeight() ); QFont font; font.setPointSize( 14 ); painter->setFont( font ); QFontMetrics fontMetrics( font ); int pixelWidth = fontMetrics.width( widthHeigtSize ); QRect rect( ( width() - borderLeft - borderRight ) / 2 + borderLeft - pixelWidth / 2 - 5, ( height() - borderTop - borderBottom ) / 2 + borderTop - 2 * radius - 20, pixelWidth + 10, 16 + 10 ); QBrush brush( Qt::yellow, Qt::SolidPattern ); painter->setBrush( brush ); painter->setPen( QPen( Qt::black, penWidth ) ); painter->drawRoundedRect( rect, 7, 7 ); painter->drawText( rect, Qt::AlignCenter, widthHeigtSize ); rect.setLeft( rect.left() - 2 ); rect.setTop( rect.top() - 2 ); rect.setWidth( rect.width() + 2 ); rect.setHeight( rect.height() + 2 ); setPrintSizeRectForMask( rect ); } void regionselection::setPrintSizeRectForMask( QRect rec ) { printSizeRectForMask = rec; } QRect regionselection::getPrintSizeRectForMask() { return printSizeRectForMask; } void regionselection::paintEvent( QPaintEvent *event ) { (void)event; painter->begin( this ); // Maskiert den Bereich für PrintSize und HandleMiddle if ( !isFrameLocked() ) { printSize(); HandleMiddle(); // Widget clearMask(); QRegion RegionWidget( 0, 0, width(), height() ); // RecordArea QRegion RegionArea ( borderLeft + frameWidth / 2, borderTop + frameWidth / 2, width() - ( borderLeft + frameWidth / 2 ) - ( borderRight + frameWidth / 2 ), height() - ( borderTop + frameWidth / 2 ) - ( borderBottom + frameWidth / 2 ) ); // subtract the record Area QRegion RegionNew = RegionWidget.subtract( RegionArea ); // Retrieves and merge display-area-size in record Area QRegion r1 = RegionNew.united( getPrintSizeRectForMask() ); // HandleMiddle // Retrieves and merge HandleMiddle in record Area r1 = r1.united( getHandleMiddleForMask() ); setMask( r1 ); } //painter->begin( this ); painter->setRenderHints( QPainter::Antialiasing, true ); HandleTopLeft(); HandleTopMiddle(); HandleTopRight(); HandleRightMiddle(); HandleBottomRight(); HandleBottomMiddle(); HandleBottomLeft(); HandleLeftMiddle(); HandleMiddle(); printSize(); // Blue Frame painter->setPen( QPen( Qt::blue, frameWidth ) ); // Left Line painter->drawLine( borderLeft, borderTop, borderLeft, height() - borderBottom ); // Top Line painter->drawLine( borderLeft, borderTop, width() - borderRight, borderTop ); // Right Line painter->drawLine( width() - borderRight, borderTop, width() - borderRight, height() - borderBottom ); // Bottome Line painter->drawLine( borderLeft, height() - borderBottom, width() - borderRight, height() - borderBottom ); painter->end(); event->accept(); } void regionselection::lockFrame( bool status ) { frameLocked = status; qDebug() << "[vokoscreen][Regional selection] Frame locked:" << status; qDebug(); handlingFrameLock(); } bool regionselection::isFrameLocked() { return frameLocked; } void regionselection::handlingFrameLock() { repaint(); } /** * Return x from window */ int regionselection::getX() { return this->x(); } /** * Return y from window */ int regionselection::getY() { return this->y(); } /** * Return x from record area */ int regionselection::getXRecordArea() { return this->x() + borderLeft + frameWidth / 2; } /** * Return y from record area */ int regionselection::getYRecordArea() { return this->y() + borderTop + frameWidth / 2; } /** * Return height from record area */ int regionselection::getHeight() { return this->height() - borderTop - borderBottom - frameWidth; } /** * Return width from record Area */ int regionselection::getWidth() { return this->width() - borderLeft - borderRight - frameWidth; } /*! MouseMove fuer das bewegen des Fensters und Ränder \param event QMouseEvent Mouse Event */ void regionselection::mouseMoveEvent( QMouseEvent *event ) { if ( isFrameLocked() ) return; switch ( handlePressed ) { case NoHandle : break; case TopLeft : moveTopLeft( event ); break; case TopMiddle : moveTopMiddle( event ); break; case TopRight : moveTopRight( event ); break; case RightMiddle : moveRightMiddle( event ); break; case BottomRight : moveBottomRight( event ); break; case BottomMiddle: moveBottomMiddle( event ); break; case BottomLeft : moveBottomLeft( event ); break; case LeftMiddle : moveLeftMiddle( event ); break; case Middle : moveMiddle( event ); break; return; } if ( ( event->x() > ( borderLeft - radius ) ) and ( event->x() < ( borderLeft + radius ) ) and ( event->y() > ( borderTop - radius ) ) and ( event->y() < ( borderTop + radius) ) ) { setCursor( Qt::SizeFDiagCursor ); handleUnderMouse = TopLeft; return; } if ( ( event->x() > ( width() - borderLeft - borderRight ) / 2 + borderLeft - radius ) and ( event->x() < ( width() - borderLeft - borderRight ) / 2 + borderLeft + radius ) and ( event->y() > borderTop - radius ) and ( event->y() < borderTop ) ) { setCursor( Qt::SizeVerCursor ); handleUnderMouse = TopMiddle; return; } if ( ( event->x() > width() - borderRight - radius ) and ( event->x() < width() - borderRight + radius ) and ( event->y() > borderTop - radius ) and ( event->y() < borderTop + radius ) ) { setCursor( Qt::SizeBDiagCursor ); handleUnderMouse = TopRight; return; } if ( ( event->x() > width() - borderRight ) and ( event->x() < width() - borderRight + radius ) and ( event->y() > ( ( height() - borderTop - borderBottom ) / 2 + borderTop - radius ) ) and ( event->y() < ( ( height() - borderTop - borderBottom ) / 2 + borderTop + radius ) ) ) { setCursor( Qt::SizeHorCursor ); handleUnderMouse = RightMiddle; return; } if ( ( event->x() > width() - borderRight - radius ) and ( event->x() < width() - borderRight + radius ) and ( event->y() > height() - borderBottom - radius ) and ( event->y() < height() - borderBottom + radius ) ) { setCursor( Qt::SizeFDiagCursor ); handleUnderMouse = BottomRight; return; } if ( ( event->x() > ( width() - borderLeft - borderRight ) / 2 + borderLeft - radius ) and ( event->x() < ( width() - borderLeft - borderRight ) / 2 + borderLeft + radius ) and ( event->y() < height() - borderBottom + radius ) and ( event->y() > height() - borderBottom ) ) { setCursor( Qt::SizeVerCursor ); handleUnderMouse = BottomMiddle; return; } if ( ( event->x() > ( borderLeft - radius ) ) and ( event->x() < ( borderLeft + radius ) ) and ( event->y() > ( height() - borderBottom - radius ) ) and ( event->y() < height() ) ) { setCursor( Qt::SizeBDiagCursor ); handleUnderMouse = BottomLeft; return; } if ( ( event->x() > ( borderLeft - radius ) ) and ( event->x() < ( borderLeft + radius ) ) and ( event->y() > ( ( height() - borderTop - borderBottom ) / 2 + borderTop - radius ) ) and ( event->y() < ( ( height() - borderTop - borderBottom ) / 2 + borderTop + radius ) ) ) { setCursor( Qt::SizeHorCursor ); handleUnderMouse = LeftMiddle; return; } if ( ( event->x() > ( width() - borderLeft - borderRight ) / 2 + borderLeft - radius ) and ( event->x() < ( width() - borderLeft - borderRight ) / 2 + borderLeft + radius ) and ( event->y() > ( ( height() - borderTop - borderBottom ) / 2 + borderTop - radius ) ) and ( event->y() < ( ( height() - borderTop - borderBottom ) / 2 + borderTop + radius ) ) ) { setCursor( Qt::SizeAllCursor ); handleUnderMouse = Middle; return; } handleUnderMouse = NoHandle; unsetCursor(); event->accept(); } void regionselection::moveTopLeft( QMouseEvent *event ) { // Globale Mauskoordinaten int mouseGlobalX = event->globalX(); int mouseGlobalY = event->globalY(); // Alte Widget Koordinaten int widgetX = geometry().x(); int widgetY = geometry().y(); int widgetWidth = geometry().width(); int widgetHeight = geometry().height(); // Minimale Größe des Widget begrenzen if ( mouseGlobalY >= widgetY + widgetHeight + currentMouseLocalY - 200 ) mouseGlobalY = widgetY + widgetHeight + currentMouseLocalY - 200; if ( mouseGlobalX >= widgetX + widgetWidth + currentMouseLocalX - 200 ) mouseGlobalX = widgetX + widgetWidth + currentMouseLocalX - 200; // Maximale Größe begrenzen if ( mouseGlobalY - currentMouseLocalY < 0 ) mouseGlobalY = widgetY + currentMouseLocalY; if ( mouseGlobalX - currentMouseLocalX < 0 ) mouseGlobalX = widgetX + currentMouseLocalX; // Neue Geometry des Dialogfenster setzen this->setGeometry( mouseGlobalX - currentMouseLocalX, mouseGlobalY - currentMouseLocalY, widgetWidth + ( widgetX - mouseGlobalX + currentMouseLocalX ), widgetHeight + ( widgetY - mouseGlobalY + currentMouseLocalY ) ); event->accept(); } void regionselection::moveTopMiddle( QMouseEvent *event ) { // Globale Mauskoordinaten int mouseGlobalY = event->globalY(); // Alte Globale Widget Koordinaten int widgetX = geometry().x(); int widgetY = geometry().y(); int widgetWidth = geometry().width(); int widgetHeight = geometry().height(); // Minimale Größe des Widget begrenzen if ( mouseGlobalY >= widgetY + widgetHeight + currentMouseLocalY - 200 ) mouseGlobalY = widgetY + widgetHeight + currentMouseLocalY - 200; // Maximale Größe begrenzen if ( mouseGlobalY - currentMouseLocalY < 0 ) mouseGlobalY = widgetY + currentMouseLocalY; // Neue Geometry des HauptWidget setzen this->setGeometry( widgetX, mouseGlobalY - currentMouseLocalY, widgetWidth, widgetHeight + ( widgetY - mouseGlobalY + currentMouseLocalY ) ); } void regionselection::moveTopRight( QMouseEvent *event ) { // Globale Mauskoordinaten int mouseGlobalX = event->globalX(); int mouseGlobalY = event->globalY(); // Alte Widget Koordinaten int widgetX = geometry().x(); int widgetY = geometry().y(); int widgetHeight = geometry().height(); int widgetWidth = geometry().width(); // Minimale Größe des Widget begrenzen if ( mouseGlobalX <= widgetX + 200 - currentMouseRightLocalX ) mouseGlobalX = widgetX + 200 - currentMouseRightLocalX; if ( mouseGlobalY >= widgetY + widgetHeight + currentMouseLocalY - 200 ) mouseGlobalY = widgetY + widgetHeight + currentMouseLocalY - 200; // Maximale Größe begrenzen if ( mouseGlobalY - currentMouseLocalY < 0 ) mouseGlobalY = widgetY + currentMouseLocalY; QDesktopWidget *desk = QApplication::desktop(); //if ( mouseGlobalX + currentMouseRightLocalX > desk->screenGeometry().width() ) if ( mouseGlobalX + currentMouseRightLocalX > desk->width() ) mouseGlobalX = widgetX + widgetWidth - currentMouseRightLocalX; // Neue Geometry des Fenster setzen this->setGeometry( widgetX, mouseGlobalY - currentMouseLocalY, currentWidgetWidth + ( mouseGlobalX - ( widgetX + currentMouseLocalX ) ), widgetHeight + ( widgetY - mouseGlobalY + currentMouseLocalY ) ); } void regionselection::moveRightMiddle( QMouseEvent *event ) { // Globale Mauskoordinaten int mouseGlobalX = event->globalX(); // Alte Widget Koordinaten int widgetX = geometry().x(); int widgetY = geometry().y(); int widgetHeight = geometry().height(); int widgetWidth = geometry().width(); // Minimale Größe des Widget begrenzen if ( mouseGlobalX <= widgetX + 200 - currentMouseRightLocalX ) mouseGlobalX = widgetX + 200 - currentMouseRightLocalX; // Maximale größe begrenzen QDesktopWidget *desk = QApplication::desktop(); //if ( mouseGlobalX + currentMouseRightLocalX > desk->screenGeometry().width() ) if ( mouseGlobalX + currentMouseRightLocalX > desk->width() ) mouseGlobalX = widgetX + widgetWidth - currentMouseRightLocalX; this->setGeometry( widgetX, widgetY, currentWidgetWidth + ( mouseGlobalX - ( widgetX + currentMouseLocalX ) ), widgetHeight ); } void regionselection::moveBottomRight( QMouseEvent *event ) { // Globale Mauskoordinaten int mouseGlobalX = event->globalX(); int mouseGlobalY = event->globalY(); // Alte Widget Koordinaten int widgetX = geometry().x(); int widgetY = geometry().y(); int widgetWidth = geometry().width(); int widgetHeight = geometry().height(); // Minimale Größe des Widget begrenzen if ( mouseGlobalX <= widgetX + 200 - currentMouseRightLocalX ) mouseGlobalX = widgetX + 200 - currentMouseRightLocalX; if ( mouseGlobalY <= widgetY + 200 - currentMouseRightLocalY ) mouseGlobalY = widgetY + 200 - currentMouseRightLocalY; // Maximale größe begrenzen QDesktopWidget *desk = QApplication::desktop(); //if ( mouseGlobalX + currentMouseRightLocalX > desk->screenGeometry().width() ) if ( mouseGlobalX + currentMouseRightLocalX > desk->width() ) mouseGlobalX = widgetX + widgetWidth - currentMouseRightLocalX; //if ( mouseGlobalY + currentMouseRightLocalY > desk->screenGeometry().height() ) if ( mouseGlobalY + currentMouseRightLocalY > desk->height() ) mouseGlobalY = widgetY + widgetHeight - currentMouseRightLocalY; this->setGeometry( widgetX, widgetY, currentWidgetWidth + ( mouseGlobalX - ( widgetX + currentMouseLocalX ) ), currentWidgetHeight + ( mouseGlobalY - ( widgetY + currentMouseLocalY ) ) ); } void regionselection::moveBottomMiddle( QMouseEvent *event ) { // Globale Mauskoordinaten int mouseGlobalY = event->globalY(); // Alte Widget Koordinaten int widgetX = geometry().x(); int widgetY = geometry().y(); int widgetWidth = geometry().width(); int widgetHeight = geometry().height(); // Minimale Größe des Widget begrenzen if ( mouseGlobalY <= widgetY + 200 - currentMouseRightLocalY ) mouseGlobalY = widgetY + 200 - currentMouseRightLocalY; // Maximale größe begrenzen QDesktopWidget *desk = QApplication::desktop(); //if ( mouseGlobalY + currentMouseRightLocalY > desk->screenGeometry().height() ) if ( mouseGlobalY + currentMouseRightLocalY > desk->height() ) mouseGlobalY = widgetY + widgetHeight - currentMouseRightLocalY; this->setGeometry( widgetX, widgetY, widgetWidth, currentWidgetHeight + ( mouseGlobalY - ( widgetY + currentMouseLocalY ) ) ); } void regionselection::moveBottomLeft( QMouseEvent *event ) { // Globale Mauskoordinaten int mouseGlobalX = event->globalX(); int mouseGlobalY = event->globalY(); // Alte Widget Koordinaten int widgetX = geometry().x(); int widgetY = geometry().y(); int widgetWidth = geometry().width(); int widgetHeight = geometry().height(); // Minimale Größe des Widget begrenzen if ( mouseGlobalY <= widgetY + 200 - currentMouseRightLocalY ) mouseGlobalY = widgetY + 200 - currentMouseRightLocalY; if ( mouseGlobalX >= widgetX + widgetWidth + currentMouseLocalX - 200 ) mouseGlobalX = widgetX + widgetWidth + currentMouseLocalX - 200; // Maximale Größe des Widget begrenzen if ( mouseGlobalX - currentMouseLocalX < 0 ) mouseGlobalX = widgetX + currentMouseLocalX; QDesktopWidget *desk = QApplication::desktop(); //if ( mouseGlobalY + currentMouseRightLocalY > desk->screenGeometry().height() ) if ( mouseGlobalY + currentMouseRightLocalY > desk->height() ) mouseGlobalY = widgetY + widgetHeight - currentMouseRightLocalY; this->setGeometry( mouseGlobalX - currentMouseLocalX, widgetY, widgetWidth + ( widgetX - mouseGlobalX + currentMouseLocalX ), currentWidgetHeight + ( mouseGlobalY - ( widgetY + currentMouseLocalY ) ) ); } void regionselection::moveLeftMiddle( QMouseEvent *event ) { // Globale Mauskoordinaten int mouseGlobalX = event->globalX(); // Alte Widget Koordinaten int widgetX = geometry().x(); int widgetY = geometry().y(); int widgetWidth = geometry().width(); int widgetHeight = geometry().height(); // Minimale Größe des Widget begrenzen if ( mouseGlobalX >= widgetX + widgetWidth + currentMouseLocalX - 200 ) mouseGlobalX = widgetX + widgetWidth + currentMouseLocalX - 200; // Maximale Größe des Widget begrenzen if ( mouseGlobalX - currentMouseLocalX < 0 ) mouseGlobalX = widgetX + currentMouseLocalX; // Neue Geometry des Dialogfenster setzen this->setGeometry( mouseGlobalX - currentMouseLocalX, widgetY, widgetWidth + ( widgetX - mouseGlobalX + currentMouseLocalX ), widgetHeight ); } void regionselection::moveMiddle( QMouseEvent *event ) { // Globale Mauskoordinaten int mouseGlobalX = event->globalX(); int mouseGlobalY = event->globalY(); // Alte Widget Koordinaten int widgetX = geometry().x(); int widgetY = geometry().y(); int widgetWidth = geometry().width(); int widgetHeight = geometry().height(); QDesktopWidget *desk = QApplication::desktop(); if ( desk->screenCount() < 2 ) { // Das Verschieben begrenzen // Top if ( mouseGlobalY - currentMouseLocalY < 0 ) mouseGlobalY = widgetY + currentMouseLocalY; // Right //QDesktopWidget *desk = QApplication::desktop(); //if ( mouseGlobalX + currentMouseRightLocalX > desk->screenGeometry().width() ) if ( mouseGlobalX + currentMouseRightLocalX > desk->width() ) mouseGlobalX = widgetX + widgetWidth - currentMouseRightLocalX; // Bottom //if ( mouseGlobalY + currentMouseRightLocalY > desk->screenGeometry().height() ) if ( mouseGlobalY + currentMouseRightLocalY > desk->height() ) mouseGlobalY = widgetY + widgetHeight - currentMouseRightLocalY; // Left if ( mouseGlobalX - currentMouseLocalX < 0 ) mouseGlobalX = widgetX + currentMouseLocalX; } move( mouseGlobalX - currentMouseLocalX, mouseGlobalY - currentMouseLocalY ); } void regionselection::mousePressEvent( QMouseEvent *event ) { // Position bei klick im Fenster festhalten currentMouseLocalX = event->x(); currentMouseLocalY = event->y(); //Abstand von Rechte Seite Widget bis Cursor currentMouseRightLocalX = width() - currentMouseLocalX; currentMouseRightLocalY = height() - currentMouseLocalY; currentWidgetWidth = geometry().width(); currentWidgetHeight = geometry().height(); switch ( handleUnderMouse ) { case NoHandle : handlePressed = NoHandle; break; case TopLeft : handlePressed = TopLeft; break; case TopMiddle : handlePressed = TopMiddle; break; case TopRight : handlePressed = TopRight; break; case RightMiddle : handlePressed = RightMiddle; break; case BottomRight : handlePressed = BottomRight; break; case BottomMiddle: handlePressed = BottomMiddle; break; case BottomLeft : handlePressed = BottomLeft; break; case LeftMiddle : handlePressed = LeftMiddle; break; case Middle : handlePressed = Middle; break; } event->accept(); } void regionselection::mouseReleaseEvent( QMouseEvent * event ) { (void)event; handlePressed = NoHandle; event->accept(); } vokoscreen-1.9.0/regionselection.h000066400000000000000000000062461227001500100172350ustar00rootroot00000000000000/* vokoscreen - A desktop recorder * Copyright (C) 2011-2012 Volker Kohaupt * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef regionselection_H #define regionselection_H #include #include #include #include #include #include #include #include #include #include #include class regionselection : public QDialog { Q_OBJECT public: regionselection(); regionselection( QWidget *parent ); virtual ~regionselection(); void lockFrame( bool status = true ); bool isFrameLocked(); int borderLeft; int borderTop; int borderRight; int borderBottom; int frameWidth; public slots: int getX(); int getY(); int getHeight(); int getWidth(); void cleanRecordArea( bool state ); int getXRecordArea(); int getYRecordArea(); void saveSettings(); private slots: void moveTopLeft ( QMouseEvent *event ); void moveTopMiddle ( QMouseEvent *event ); void moveTopRight ( QMouseEvent *event ); void moveRightMiddle ( QMouseEvent *event ); void moveBottomRight ( QMouseEvent *event ); void moveBottomMiddle( QMouseEvent *event ); void moveBottomLeft ( QMouseEvent *event ); void moveLeftMiddle ( QMouseEvent *event ); void moveMiddle ( QMouseEvent *event ); void HandleTopLeft(); void HandleTopMiddle(); void HandleTopRight(); void HandleRightMiddle(); void HandleBottomRight(); void HandleBottomMiddle(); void HandleBottomLeft(); void HandleLeftMiddle(); void HandleMiddle(); void printSize(); void setPrintSizeRectForMask( QRect rec ); QRect getPrintSizeRectForMask(); void setHandleMiddleForMask( QRect rec ); QRect getHandleMiddleForMask(); protected: void mouseMoveEvent( QMouseEvent *event ); void mousePressEvent( QMouseEvent *event ); void mouseReleaseEvent ( QMouseEvent * event ); void paintEvent( QPaintEvent *event ); QPainter * painter; private: enum Handle { NoHandle, TopLeft, TopMiddle, TopRight, RightMiddle, BottomRight, BottomMiddle, BottomLeft, LeftMiddle, Middle }; int radius; int penWidth; int penHalf; bool frameLocked; void handlingFrameLock(); int currentMouseLocalX; int currentMouseLocalY; int currentMouseRightLocalX; int currentMouseRightLocalY; int currentWidgetWidth; int currentWidgetHeight; int currentWidgetY; int currentbottomY; Handle handlePressed; Handle handleUnderMouse; QRect printSizeRectForMask; QRect HandleMiddleForMask; int Setting_Area_NoShowInTaskBar; }; #endif vokoscreen-1.9.0/rpm/000077500000000000000000000000001227001500100144615ustar00rootroot00000000000000vokoscreen-1.9.0/rpm/vokoscreen.spec000066400000000000000000000022431227001500100175140ustar00rootroot00000000000000Summary: Screencasting Name: vokoscreen Version: 1.8.6 Release: 0 License: GPL-2.0 Group: Productivity/Multimedia/CD/Record URL: http://www.kohaupt-online.de/hp # screencast::ffmpeg Requires: ffmpeg # screencast::mkvmerge Requires: mkvtoolnix BuildRequires: libqt4-devel alsa-devel opencv-devel BuildRoot: %{_tmppath}/%{name}-%{version}-build Source: %{name}-%{version}.tar.gz %description vokoscreen is an easy to use screencast creator to record educational videos, live recordings of browser, installation, videoconferences, etc. %prep # Quellen entpacken und vorbereiten %setup %build make %install install -D -m 755 vokoscreen %{buildroot}%{_bindir}/vokoscreen install -D -m 644 applications/%{name}.png %{buildroot}%{_datadir}/pixmaps/%{name}.png install -D -m 644 applications/%{name}.desktop %{buildroot}%{_datadir}/applications/%{name}.desktop install -D -m 644 man/man1/%{name}.1.gz %{buildroot}%{_mandir}/man1/%{name}.1.gz %files %defattr(-, root, root) %{_bindir}/vokoscreen %{_datadir}/pixmaps/%{name}.png %{_datadir}/applications/%{name}.desktop %{_mandir}/man1/%{name}.1.gz %changelog * Sun Mar 21 2012 Volker Kohaupt 1.6.3 - new Version vokoscreen-1.9.0/screencast.cpp000066400000000000000000002525501227001500100165320ustar00rootroot00000000000000/* vokoscreen - A desktop recorder * Copyright (C) 2011-2014 Volker Kohaupt * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "screencast.h" using namespace std; screencast::screencast() { QSettings versionSettings(":/VERSION", QSettings::IniFormat ); versionSettings.beginGroup("Info"); bool beta = versionSettings.value( "Beta" ).toBool(); QString Beta; if ( beta ) Beta = " Beta"; else Beta = ""; ProgName = versionSettings.value( "Progname" ).toString(); Version = versionSettings.value( "Version" ).toString() + Beta; versionSettings.endGroup(); homepage = "" + tr( "Homepage" ) + ""; QString mailingliste = "" + tr( "Mailinglist" ) + "" ); email = "" + tr( "Support" ) + "" ); QString emaildeveloper = "" + tr( "Developer" ) + "" ); screencast::setWindowTitle( ProgName + " " + Version ); QIcon icon; icon.addFile( QString::fromUtf8( ":/pictures/vokoscreen.png" ), QSize(), QIcon::Normal, QIcon::Off ); screencast::setWindowIcon( icon ); qDebug() << "[vokoscreen]" << "Version:" << Version; qDebug() << "[vokoscreen]" << "Qt Version: " << qVersion(); QvkAlsaDevice inBox ; qDebug() << "[vokoscreen]" << "asoundlib Version:" << inBox.getAlsaVersion(); //qDebug() << "[vokoscreen]" << "ffmpeg Version:" << getFfmpegVersion(); qDebug(); searchExternalPrograms(); pause = false; firststartWininfo = false; QWidget *centralWidget = new QWidget( this ); centralWidget->setObjectName( QString::fromUtf8( "centralWidget" ) ); this->setCentralWidget( centralWidget ); tabWidget = new QTabWidget( centralWidget ); tabWidget->setGeometry( 120, 0, 450, 190 ); tabWidget->setIconSize( QSize( 40, 40 ) ); // Tab 1 Screen options *************************************************** QFrame *frame = new QFrame( this ); frame->setGeometry( 120, 10, 300, 200 ); frame->show(); tabWidget->addTab( frame, "" ); tabWidget->setTabIcon( 0, QIcon( ":/pictures/monitor.png" ) ); QFont qfont = frame->font(); qfont.setPixelSize( 12 ); frame->setFont( qfont ); FullScreenRadioButton = new QRadioButton( frame ); FullScreenRadioButton->setGeometry( QRect( 20, 15, 120, 21 ) ); FullScreenRadioButton->setText( tr( "Fullscreen" ) ); FullScreenRadioButton->setChecked( true ); connect( FullScreenRadioButton, SIGNAL( clicked() ), SLOT( clickedScreenSize() ) ); WindowRadioButton = new QRadioButton( frame ); WindowRadioButton->setGeometry( QRect( 20, 40, 85, 21 ) ); WindowRadioButton->setText( tr( "Window" ) ); connect( WindowRadioButton, SIGNAL( clicked() ), SLOT( clickedScreenSize() ) ); AreaRadioButton = new QRadioButton( frame ); AreaRadioButton->setGeometry( QRect( 20, 65, 85, 21 ) ); AreaRadioButton->setText( tr( "Area" ) ); connect( AreaRadioButton, SIGNAL( clicked() ), SLOT( clickedScreenSize() ) ); MagnifierCheckBox = new QCheckBox( frame ); MagnifierCheckBox->setText( tr( "Magnification" ) ); MagnifierCheckBox->setGeometry( QRect( 160, 15, 120, 21 ) ); MagnifierCheckBox->setToolTip( "CTRL+SHIFT+F9" ); MagnifierCheckBox->show(); QPushButton *MagnifierDialogPushButton = new QPushButton( frame ); MagnifierDialogPushButton->setGeometry( 270, 15, 20, 21 ); MagnifierDialogPushButton->setText( "..." ); MagnifierDialogPushButton->show(); connect( MagnifierDialogPushButton, SIGNAL( clicked() ), SLOT( MagnifierDialog() ) ); webcamCheckBox = new QvkWebcamController( frame ); webcamCheckBox->setGeometry( 160, 40, 120, 21 ); QLabel *CountdownLabel = new QLabel( frame ); CountdownLabel->setGeometry( 160, 110, 80, 25 ); CountdownLabel->setText( tr( "Countdown" ) ); CountdownLabel->show(); CountdownSpinBox = new QSpinBox( frame ); CountdownSpinBox->setGeometry( 250, 110, 50, 21 ); CountdownSpinBox->setMinimum( 0 ); CountdownSpinBox->setMaximum( 999 ); CountdownSpinBox->setSingleStep( 1 ); CountdownSpinBox->setValue( 0 ); CountdownSpinBox->show(); // Tab 2 Audio options **************************************** TabWidgetAudioFrame = new QFrame( this ); TabWidgetAudioFrame->setGeometry( 120, 0, 300, 290 ); TabWidgetAudioFrame->show(); tabWidget->addTab( TabWidgetAudioFrame, "" ); tabWidget->setTabIcon( 1, QIcon( ":/pictures/micro.png" ) ); qfont = TabWidgetAudioFrame->font(); qfont.setPixelSize( 12 ); TabWidgetAudioFrame->setFont( qfont ); AudioOnOffCheckbox = new QCheckBox( TabWidgetAudioFrame ); AudioOnOffCheckbox->setGeometry( 10, 0, 100, 25 ); AudioOnOffCheckbox->setText( tr( "Audio" ) ); AudioOnOffCheckbox->show(); connect( AudioOnOffCheckbox, SIGNAL( stateChanged( int ) ), SLOT( stateChangedAudio( int ) ) ); AlsaRadioButton= new QRadioButton( TabWidgetAudioFrame ); AlsaRadioButton->setGeometry( 25, 110, 100, 25 ); AlsaRadioButton->setText( tr( "Alsa" ) ); AlsaRadioButton->show(); connect( AlsaRadioButton, SIGNAL( clicked( bool ) ), SLOT( clickedAudioAlsa( bool ) ) ); AlsaHwComboBox = new QComboBox( TabWidgetAudioFrame ); AlsaHwComboBox->setGeometry( 90, 110, 345, 25 ); AlsaHwComboBox->show(); Pulseframe = new QFrame(); PulseDeviceRadioButton = new QRadioButton( TabWidgetAudioFrame ); PulseDeviceRadioButton->setGeometry( 25, 20, 345, 25 ); PulseDeviceRadioButton->setText( tr( "Pulse" ) ); PulseDeviceRadioButton->show(); connect( PulseDeviceRadioButton, SIGNAL( clicked( bool ) ), SLOT( clickedAudioPulse( bool ) ) ); // Tab 3 Video options ************************************************** TabWidgetVideoOptionFrame = new QFrame( this ); TabWidgetVideoOptionFrame->setGeometry( 120, 0, 300, 200 ); TabWidgetVideoOptionFrame->show(); tabWidget->addTab( TabWidgetVideoOptionFrame, "" ); tabWidget->setTabIcon( 2, QIcon( ":/pictures/videooptionen.png" ) ); qfont = TabWidgetVideoOptionFrame->font(); qfont.setPixelSize( 12 ); TabWidgetVideoOptionFrame->setFont( qfont ); QLabel *VideoOptionLabel = new QLabel( TabWidgetVideoOptionFrame ); VideoOptionLabel->setGeometry( 20, 10, 50, 25 ); //VideoOptionLabel->setAlignment( Qt::AlignRight ); VideoOptionLabel->setText( tr( "Frames" ) ); VideoOptionLabel->show(); FrameSpinBox = new QSpinBox( TabWidgetVideoOptionFrame ); FrameSpinBox->setGeometry( QRect( 80, 10, 50, 25 ) ); FrameSpinBox->setMinimum( 1 ); FrameSpinBox->setMaximum( 99 ); FrameSpinBox->setSingleStep( 1 ); FrameSpinBox->setValue( 25 ); FrameSpinBox->show(); connect( FrameSpinBox, SIGNAL( valueChanged( int ) ), SLOT( valueChangedFrames( int ) ) ); QPushButton *FrameStandardButton = new QPushButton( TabWidgetVideoOptionFrame ); FrameStandardButton->setText( tr( "Default" ) ); FrameStandardButton->setGeometry( 360, 10, 70, 25 ); FrameStandardButton->show(); connect( FrameStandardButton, SIGNAL( clicked() ), SLOT( setFrameStandardSpinbox() ) ); QLabel *VideocodecOptionLabel = new QLabel( TabWidgetVideoOptionFrame ); VideocodecOptionLabel->setGeometry( 20, 40, 50, 25 ); VideocodecOptionLabel->setText( tr( "Codec" ) ); VideocodecOptionLabel->show(); VideocodecComboBox = new QComboBox( TabWidgetVideoOptionFrame ); VideocodecComboBox->setGeometry( 80, 40, 80, 25 ); VideocodecComboBox->show(); VideocodecComboBox->addItem( "mpeg4" ); VideocodecComboBox->addItem( "libx264" ); connect( VideocodecComboBox, SIGNAL( currentIndexChanged( int ) ), SLOT( currentIndexChangedCodec( int ) ) ); QLabel *VideoContainerLabel = new QLabel(TabWidgetVideoOptionFrame ); VideoContainerLabel->setGeometry( 175, 40, 50, 25 ); VideoContainerLabel->setText( tr( "Format" ) ); VideoContainerLabel->show(); VideoContainerComboBox = new QComboBox( TabWidgetVideoOptionFrame ); VideoContainerComboBox->setGeometry( 230, 40, 70, 25 ); VideoContainerComboBox->addItem( "avi" ); VideoContainerComboBox->addItem( "mkv" ); VideoContainerComboBox->show(); connect( VideoContainerComboBox, SIGNAL( currentIndexChanged( int ) ), SLOT( currentIndexChangedFormat( int ) ) ); QPushButton *VideocodecStandardButton = new QPushButton( TabWidgetVideoOptionFrame ); VideocodecStandardButton->setText( tr( "Default" ) ); VideocodecStandardButton->setGeometry( 360, 40, 70, 25 ); VideocodecStandardButton->show(); connect( VideocodecStandardButton, SIGNAL( clicked() ), SLOT( setVideocodecStandardComboBox() ) ); HideMouseCheckbox = new QCheckBox( TabWidgetVideoOptionFrame ); HideMouseCheckbox->setGeometry( 20, 70, 300, 25 ); HideMouseCheckbox->setText( tr( "Do not record mouse cursor" ) ); HideMouseCheckbox->show(); // Tab 4 Miscellaneous options ************************************************** TabWidgetMiscellaneousFrame = new QFrame( this ); TabWidgetMiscellaneousFrame->setGeometry( 120, 0, 300, 200 ); TabWidgetMiscellaneousFrame->show(); tabWidget->addTab(TabWidgetMiscellaneousFrame, "" ); tabWidget->setTabIcon( 3, QIcon( ":/pictures/tools.png" ) ); qfont = TabWidgetMiscellaneousFrame->font(); qfont.setPixelSize( 12 ); TabWidgetMiscellaneousFrame->setFont( qfont ); QLabel *SaveVideoPathLabel = new QLabel( TabWidgetMiscellaneousFrame ); SaveVideoPathLabel->setGeometry( 30, 30, 100, 25 ); SaveVideoPathLabel->setText( tr( "Videopath" ) ); SaveVideoPathLabel->show(); SaveVideoPathLineEdit = new QLineEdit( TabWidgetMiscellaneousFrame ); SaveVideoPathLineEdit->setGeometry( 140, 30, 210, 25 ); SaveVideoPathLineEdit->setReadOnly( true ); SaveVideoPathLineEdit->show(); QPushButton *SaveVideoPathPushButton = new QPushButton( TabWidgetMiscellaneousFrame ); SaveVideoPathPushButton->setGeometry( 350, 30, 20, 25); SaveVideoPathPushButton->setText( "..." ); SaveVideoPathPushButton->show(); connect( SaveVideoPathPushButton, SIGNAL(clicked() ), SLOT( saveVideoPath() ) ); QLabel *VideoPlayerLabel = new QLabel(TabWidgetMiscellaneousFrame); VideoPlayerLabel->setGeometry( 30, 60, 100, 25 ); VideoPlayerLabel->setText( tr( "Player" ) ); VideoPlayerLabel->show(); VideoplayerComboBox = new QComboBox( TabWidgetMiscellaneousFrame ); VideoplayerComboBox->setGeometry( 140, 60, 210, 25 ); VideoplayerComboBox->show(); MinimizedCheckBox = new QCheckBox( TabWidgetMiscellaneousFrame ); MinimizedCheckBox->setGeometry( 30, 85, 350, 25 ); MinimizedCheckBox->setText( tr( "Vokoscreen minimized when recording starts" ) ); MinimizedCheckBox->show(); SystrayCheckBox = new QCheckBox( TabWidgetMiscellaneousFrame ); SystrayCheckBox->setGeometry( 30, 110, 350, 25 ); SystrayCheckBox->setText( tr( "Show in systray" ) ); SystrayCheckBox->setCheckState( Qt::Checked ); SystrayCheckBox->show(); connect( SystrayCheckBox, SIGNAL( stateChanged( int ) ), SLOT( stateChangedSystray( int ) ) ); // Tab 5 About ********************************************************* QFrame *TabWidgetAboutFrame = new QFrame(this); TabWidgetAboutFrame->show(); tabWidget->addTab( TabWidgetAboutFrame, "" ); tabWidget->setTabIcon( 4, QIcon( ":/pictures/about.png" ) ); tabWidget->show(); qfont = TabWidgetAboutFrame->font(); qfont.setPixelSize( 12 ); TabWidgetAboutFrame->setFont( qfont ); int labelWidth = tabWidget->width() / 2; int leftSide = 0; int rightSide = tabWidget->width() / 2; QLabel* labelWebSite = new QLabel( TabWidgetAboutFrame ); labelWebSite->setGeometry( leftSide, 10, labelWidth, 22 ); labelWebSite->setText( homepage ); labelWebSite->setOpenExternalLinks( true ); labelWebSite->setAlignment( Qt::AlignCenter ); labelWebSite->show(); QLabel* labelMailinglisteMail = new QLabel( TabWidgetAboutFrame ); labelMailinglisteMail->setText( mailingliste ); labelMailinglisteMail->setGeometry( leftSide, 30, labelWidth, 22 ); labelMailinglisteMail->setOpenExternalLinks( true ); labelMailinglisteMail->setAlignment( Qt::AlignCenter ); labelMailinglisteMail->show(); QLabel* labelMail = new QLabel( TabWidgetAboutFrame ); labelMail->setGeometry( leftSide, 50, labelWidth, 22 ); labelMail->setText( email ); labelMail->setOpenExternalLinks( true ); labelMail->setAlignment( Qt::AlignCenter ); labelMail->show(); QLabel* labelDeveLoperMail = new QLabel( TabWidgetAboutFrame ); labelDeveLoperMail->setText( emaildeveloper ); labelDeveLoperMail->setGeometry( leftSide, 70, labelWidth, 22 ); labelDeveLoperMail->setOpenExternalLinks( true ); labelDeveLoperMail->setAlignment( Qt::AlignCenter ); labelDeveLoperMail->show(); QLabel* labelLanguageUrl = new QLabel( TabWidgetAboutFrame ); labelLanguageUrl->setText( "" + tr( "Translations" ) + "" ); labelLanguageUrl->setGeometry( rightSide, 10, labelWidth, 22 ); labelLanguageUrl->setOpenExternalLinks( true ); labelLanguageUrl->setAlignment( Qt::AlignCenter ); labelLanguageUrl->show(); QLabel* labelSourcecodeUrl = new QLabel( TabWidgetAboutFrame ); labelSourcecodeUrl->setText( "" + tr( "Sourcecode" ) + "" ); labelSourcecodeUrl->setGeometry( rightSide, 30, labelWidth, 22 ); labelSourcecodeUrl->setOpenExternalLinks( true ); labelSourcecodeUrl->setAlignment( Qt::AlignCenter ); labelSourcecodeUrl->show(); QLabel* labelOpensuseBetaUrl = new QLabel( TabWidgetAboutFrame ); labelOpensuseBetaUrl->setText( "" + tr( "Beta openSUSE" ) + "" ); labelOpensuseBetaUrl->setGeometry( rightSide, 50, labelWidth, 22 ); labelOpensuseBetaUrl->setOpenExternalLinks( true ); labelOpensuseBetaUrl->setAlignment( Qt::AlignCenter ); labelOpensuseBetaUrl->show(); QLabel* labelUbuntuBetaUrl = new QLabel( TabWidgetAboutFrame ); labelUbuntuBetaUrl->setText( "" + tr( "Beta Ubuntu" ) + "" ); labelUbuntuBetaUrl->setGeometry( rightSide, 70, labelWidth, 22 ); labelUbuntuBetaUrl->setOpenExternalLinks( true ); labelUbuntuBetaUrl->setAlignment( Qt::AlignCenter ); labelUbuntuBetaUrl->show(); QLabel * labelDonateUrl = new QLabel( TabWidgetAboutFrame ); labelDonateUrl->setText( "" + tr( "Donate" ) + "" ); labelDonateUrl->setGeometry( 0, 100, tabWidget->width(), 22 ); labelDonateUrl->setOpenExternalLinks( true ); labelDonateUrl->setAlignment( Qt::AlignCenter ); labelDonateUrl->show(); creditsQPushButton = new QPushButton( TabWidgetAboutFrame ); creditsQPushButton->setGeometry( 400, 95, 40, 40 ); QIcon creditsIcon; creditsIcon.addFile( ":/pictures/community.png", QSize(), QIcon::Normal, QIcon::On ); creditsQPushButton->setIconSize( QSize( 30, 30 ) ); creditsQPushButton->setIcon( creditsIcon ); creditsQPushButton->show(); connect( creditsQPushButton, SIGNAL( clicked() ), SLOT( showCredits() ) ); // End Tabs ************************************************************* recordButton = new QPushButton( centralWidget ); recordButton->setText( tr( "Start" ) ); recordButton->setToolTip( "CTRL+SHIFT+F10" ); qfont = recordButton->font(); qfont.setPixelSize( 14 ); qfont.setBold( true ); recordButton->setFont( qfont ); recordButton->setGeometry( 170, 200, 70, 30 ); recordButton->show(); connect( recordButton, SIGNAL( clicked() ), SLOT( preRecord() ) ); StopButton = new QPushButton( centralWidget ); StopButton->setText( tr( "Stop" ) ); StopButton->setToolTip( "CTRL+SHIFT+F11" ); qfont = StopButton->font(); qfont.setPixelSize( 14 ); qfont.setBold( true ); StopButton->setFont( qfont ); StopButton->setGeometry( 240, 200, 70, 30 ); StopButton->setEnabled( false ); StopButton->show(); connect( StopButton, SIGNAL( clicked() ), SLOT( Stop() ) ); PauseButton = new QPushButton( centralWidget ); PauseButton->setText( tr( "Pause" ) ); PauseButton->setToolTip( "CTRL+SHIFT+F12" ); qfont = PauseButton->font(); qfont.setPixelSize( 14 ); qfont.setBold( true ); PauseButton->setFont( qfont ); PauseButton->setGeometry( 310, 200, 70, 30 ); PauseButton->setCheckable( true ); PauseButton->setEnabled( false ); if ( needProgram( "mkvmerge" ) ) PauseButton->show(); else PauseButton->hide(); connect( PauseButton, SIGNAL( clicked() ), SLOT( Pause() ) ); PlayButton = new QPushButton( centralWidget ); PlayButton->setText( tr( "Play" ) ); PlayButton->setToolTip( tr( "Play last Video" ) ); qfont = PlayButton->font(); qfont.setPixelSize( 14 ); qfont.setBold( true ); PlayButton->setFont( qfont ); PlayButton->setGeometry( 380, 200, 70, 30 ); PlayButton->show(); connect( PlayButton, SIGNAL( clicked() ), SLOT( play() ) ); sendPushButton = new QPushButton( centralWidget ); sendPushButton->setGeometry( 450, 200, 70, 30 ); qfont = sendPushButton->font(); qfont.setPixelSize( 14 ); qfont.setBold( true ); sendPushButton->setFont( qfont ); sendPushButton->setText( tr( "Send" ) ); sendPushButton->setToolTip( tr( "Send Video" ) ); connect( sendPushButton, SIGNAL( clicked() ), SLOT( send() ) ); if ( needProgram( "xdg-email" ) ) sendPushButton->setEnabled( true ); else sendPushButton->setEnabled( false ); QTimer::singleShot( 15000, &version, SLOT( doDownload() ) ); connect( &version, SIGNAL( versionDownloadFinish() ), SLOT( buttonVersion() ) ); updateButton = new QPushButton( centralWidget ); updateButton->setGeometry( 530, 190, 45, 45 ); updateButton->setIcon( QIcon( ":/pictures/system-software-update.png" ) ); updateButton->setIconSize( QSize( 35, 35 ) ); updateButton->setToolTip( tr( "New version available" ) ); updateButton->hide(); connect( updateButton, SIGNAL( clicked() ), SLOT( showHomepage() ) ); QLabel* label = new QLabel( centralWidget ); label->setText(""); label->setGeometry( QRect( 0, 0, 123, 240) ); label->setAlignment( Qt::AlignCenter ); label->show(); QImage* qImage = new QImage( ":/pictures/VokoCola.png" ); label->setPixmap(QPixmap::fromImage( *qImage, Qt::AutoColor) ); label->setScaledContents( true ); // Statusbar statusBarProgForRecord = new QLabel(); statusBarProgForRecord->setText( recordApplikation ); statusBarProgForRecord->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); statusBarProgForRecord->setToolTip( tr ( "Program for recording" ) ); statusBarLabelTime = new QLabel(); statusBarLabelTime->setText( "00:00:00" ); statusBarLabelTime->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); statusBarLabelTime->setToolTip( tr ( "Recording time" ) ); statusBarLabelFps = new QLabel(); statusBarLabelFps->setText( "0" ); statusBarLabelFps->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); statusBarLabelFps->setToolTip( tr( "Actual frames per second" ) ); statusBarLabelSize = new QLabel(); statusBarLabelSize->setText( "0" ); statusBarLabelSize->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); statusBarLabelSize->setToolTip( tr( "Size in KB" ) ); statusbarLabelScreenSize = new QLabel(); statusbarLabelScreenSize->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); statusbarLabelScreenSize->setToolTip( tr( "Recording screensize" ) ); statusBarLabelCodec = new QLabel(); statusBarLabelCodec->setText( VideocodecComboBox->currentText() ); statusBarLabelCodec->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); statusBarLabelCodec->setToolTip( tr( "Codec" ) ); statusBarLabelFormat = new QLabel(); statusBarLabelFormat->setText( VideoContainerComboBox->currentText() ); statusBarLabelFormat->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); statusBarLabelFormat->setToolTip( tr( "Format" ) ); statusBarLabelAudio = new QLabel(); statusBarLabelAudio->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); statusBarLabelAudio->setToolTip( tr( "Audio" ) ); statusBarLabelFpsSettings = new QLabel(); statusBarLabelFpsSettings->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); statusBarLabelFpsSettings->setToolTip( tr( "Settings fps" ) ); QStatusBar *statusBar = new QStatusBar( this ); setStatusBar( statusBar ); QLabel * LabelTemp = new QLabel(); statusBar->addWidget( LabelTemp, 120 ); statusBar->addWidget( statusBarProgForRecord, 0 ); statusBar->addWidget( statusBarLabelTime, 0); statusBar->addWidget( statusBarLabelFps, 0 ); statusBar->addWidget( statusBarLabelSize, 0 ); statusBar->addWidget( statusbarLabelScreenSize, 0 ); statusBar->addWidget( statusBarLabelCodec, 0 ); statusBar->addWidget( statusBarLabelFormat, 0 ); statusBar->addWidget( statusBarLabelAudio, 0 ); statusBar->addWidget( statusBarLabelFpsSettings, 0 ); QLabel * LabelTemp1 = new QLabel(); statusBar->addWidget( LabelTemp1, 40 ); statusBar->show(); qfont = statusBar->font(); qfont.setPixelSize( 12 ); statusBar->setFont( qfont ); qDebug() << "[vokoscreen]" << "---Begin search Videoplayer---"; QStringList playerList = QStringList() << "kaffeine" << "vlc" << "gnome-mplayer" << "ffplay" << "avplay" << "totem" << "pia" << "xine" << "gxine" << "gmplayer" << "kplayer" << "smplayer" << "smplayer2" << "dragon" << "banshee"; playerList.sort(); QString playerName; QString resultString( qgetenv( "PATH" ) ); QStringList pathList = resultString.split( ":" ); for ( int x = 0; x < playerList.size(); ++x ) { for ( int i = 0; i < pathList.size(); ++i ) { playerName = pathList.at( i ); playerName = playerName.append( QDir::separator() ).append( playerList.at( x ) ); if ( QFile::exists( playerName ) ) { qDebug() << "[vokoscreen]" << "Find Videoplayer :" << playerName; VideoplayerComboBox->addItem( playerList.at( x ), playerName ); break; } } } qDebug() << "[vokoscreen]" << "---End search Videoplayer---"; qDebug(); // Einstellungen aus .conf einlesen QSettings settings( ProgName, ProgName ); // Dient nur zum anlegen des Profils damit ffmpeglog erstellt werden kann settings.beginGroup("vokoscreen"); settings.setValue("Version", Version); settings.endGroup(); settings.beginGroup( "Audio" ); AudioOnOffCheckbox->setCheckState( Qt::CheckState( settings.value( "AudioOnOff", 2 ).toUInt() ) ); settings.endGroup(); settings.beginGroup("Alsa" ); AlsaRadioButton->setChecked( settings.value( "Alsa", false ).toBool() ); settings.endGroup(); settings.beginGroup("Pulse"); PulseDeviceRadioButton->setChecked( settings.value( "Pulse", true ).toBool() ); settings.endGroup(); settings.beginGroup("Record"); FullScreenRadioButton->setChecked( settings.value( "FullScreen", true ).toBool() ); WindowRadioButton->setChecked( settings.value( "Window", false ).toBool() ); AreaRadioButton->setChecked( settings.value( "Area", false ).toBool() ); settings.endGroup(); settings.beginGroup( "Miscellaneous" ); QDir Dir; if ( Dir.exists( settings.value( "VideoPath", PathMoviesLocation() ).toString() ) ) SaveVideoPathLineEdit->setText( settings.value( "VideoPath", PathMoviesLocation() ).toString() ); else PathMoviesLocation(); int x = VideoplayerComboBox->findText( settings.value( "Videoplayer" ).toString(),Qt::MatchExactly ); if ( x == -1 ) VideoplayerComboBox->setCurrentIndex( 0 ); else VideoplayerComboBox->setCurrentIndex( x ); MinimizedCheckBox->setCheckState( Qt::CheckState( settings.value( "Minimized", 0 ).toUInt() ) ); CountdownSpinBox->setValue( settings.value( "Countdown", 0 ).toUInt() ); settings.endGroup(); settings.beginGroup( "Videooptions" ); FrameSpinBox->setValue( settings.value( "Frames", 25 ).toInt() ); VideocodecComboBox->setCurrentIndex( VideocodecComboBox->findText( settings.value( "Videocodec", "mpeg4" ).toString() ) ); VideoContainerComboBox->setCurrentIndex( VideoContainerComboBox->findText( settings.value( "Format", "mkv" ).toString() ) ); HideMouseCheckbox->setCheckState( Qt::CheckState( settings.value( "HideMouse").toUInt() ) ); settings.endGroup(); settings.beginGroup( "GUI" ); setGeometry( settings.value( "X", "100" ).toUInt(), settings.value( "Y", "100" ).toUInt(), width(), height() ); tabWidget->setCurrentIndex ( settings.value( "Tab", "0" ).toUInt() ); settings.endGroup(); // Statusbar stateChangedAudio( AudioOnOffCheckbox->checkState() ); statusBarLabelFpsSettings->setText( QString::number( FrameSpinBox->value() ) ); SystemCall = new QProcess( this ); connect( AudioOnOffCheckbox, SIGNAL( clicked() ), SLOT( AudioOnOff() ) ); connect( AlsaRadioButton, SIGNAL( clicked() ), SLOT( AudioOnOff() ) ); connect( PulseDeviceRadioButton, SIGNAL( clicked() ), SLOT( AudioOnOff() ) ); connect( SystemCall, SIGNAL( stateChanged ( QProcess::ProcessState) ),this, SLOT( stateChanged( QProcess::ProcessState) ) ); connect( SystemCall, SIGNAL( error( QProcess::ProcessError) ), this, SLOT( error( QProcess::ProcessError) ) ); connect( SystemCall, SIGNAL( readyReadStandardError() ), this, SLOT( readyReadStandardError() ) ); connect( SystemCall, SIGNAL( readyReadStandardOutput() ), this, SLOT( readyReadStandardOutput() ) ); windowMoveTimer = new QTimer( this ); connect( windowMoveTimer, SIGNAL( timeout() ), this, SLOT( windowMove() ) ); // Area ein-ausblenden wenn Radiobutton immer wieder angecklickt wird connect( AreaRadioButton, SIGNAL( clicked() ), SLOT( AreaOnOff() ) ); connect( FullScreenRadioButton, SIGNAL( clicked() ), SLOT( AreaOnOff() ) ); connect( WindowRadioButton, SIGNAL( clicked() ), SLOT( AreaOnOff() ) ); settings.beginGroup( "Area" ); myregionselection = new regionselection(); myregionselection->setGeometry ( settings.value( "X", 200 ).toUInt(), settings.value( "Y", 200 ).toUInt(), settings.value( "Width", 200 ).toUInt() + myregionselection->borderLeft + myregionselection->borderRight + myregionselection->frameWidth, settings.value( "Height", 200 ).toUInt() + myregionselection->borderTop + myregionselection->borderBottom + myregionselection->frameWidth ); myregionselection->close(); settings.endGroup(); connect( MagnifierCheckBox, SIGNAL( clicked() ), SLOT( showMagnifier() ) ); magnifier = new QvkMagnifier(); magnifier->close(); connect( magnifier, SIGNAL( closeMagnifier() ), SLOT( uncheckMagnifier() ) ); // Clean vokoscreen temp QDir dir( PathTempLocation() ); QStringList stringList = dir.entryList( QDir::Files, QDir::Time | QDir::Reversed ); for ( int i = 0; i < stringList.size(); ++i ) dir.remove( PathTempLocation().append( QDir::separator() ).append( stringList.at( i ) ) ); makeAsoundrc(); AudioOnOff(); pulseUnloadModule(); SystemTrayIconGreen = new QSystemTrayIcon( QIcon::fromTheme( "media-playback-start", QIcon( ":/pictures/start.png" ) ) ); SystemTrayIconGreen->setToolTip( tr( "Start" ) ); SystemTrayIconRed = new QSystemTrayIcon( QIcon::fromTheme( "media-playback-stop", QIcon ( ":/pictures/stop.png" ) ) ); SystemTrayIconRed->setToolTip( tr( "Stop" ) ); SystemTrayIconYellow = new QSystemTrayIcon( QIcon::fromTheme( "media-playback-pause", QIcon ( ":/pictures/pause.png" ) ) ); SystemTrayIconYellow->setToolTip( tr( "Pause" ) ); SystemTrayIconBlue = new QSystemTrayIcon( QIcon::fromTheme( "media-skip-forward", QIcon ( ":/pictures/go.png" ) ) ); SystemTrayIconBlue->setToolTip( tr( "Go" ) ); settings.beginGroup( "GUI" ); SystrayCheckBox->setCheckState( Qt::CheckState( settings.value( "Systray", 2 ).toUInt() ) ); stateChangedSystray( Qt::CheckState( settings.value( "Systray", 2 ).toUInt() ) ); settings.endGroup(); connect( SystemTrayIconGreen, SIGNAL( activated ( QSystemTrayIcon::ActivationReason ) ), this, SLOT( SystemTrayStart( QSystemTrayIcon::ActivationReason ) ) ); connect( SystemTrayIconRed, SIGNAL( activated ( QSystemTrayIcon::ActivationReason ) ), this, SLOT( SystemTrayStop( QSystemTrayIcon::ActivationReason ) ) ); connect( SystemTrayIconYellow, SIGNAL( activated ( QSystemTrayIcon::ActivationReason ) ), this, SLOT( SystemTrayPause( QSystemTrayIcon::ActivationReason ) ) ); connect( SystemTrayIconBlue, SIGNAL( activated ( QSystemTrayIcon::ActivationReason ) ), this, SLOT( SystemTrayGo( QSystemTrayIcon::ActivationReason ) ) ); shortcutMagnifier = new QxtGlobalShortcut( this ); connect( shortcutMagnifier, SIGNAL( activated() ), this, SLOT( ShortcutMagnifier() ) ); shortcutMagnifier->setShortcut( QKeySequence( "Ctrl+Shift+F9" ) ); shortcutStart = new QxtGlobalShortcut( this ); connect( shortcutStart, SIGNAL( activated() ), this, SLOT( preRecord() ) ); shortcutStart->setShortcut( QKeySequence( "Ctrl+Shift+F10" ) ); shortcutStop = new QxtGlobalShortcut( this ); connect( shortcutStop, SIGNAL( activated() ), this, SLOT( Stop() ) ); shortcutStop->setShortcut( QKeySequence( "Ctrl+Shift+F11" ) ); shortcutStop->setEnabled( false ); shortcutPause = new QxtGlobalShortcut( this ); connect( shortcutPause, SIGNAL( activated() ), this, SLOT( ShortcutPause() ) ); shortcutPause->setShortcut( QKeySequence( "Ctrl+Shift+F12" ) ); QvkAlsaWatcher * myAlsaWatcher = new QvkAlsaWatcher(); connect( myAlsaWatcher, SIGNAL( changed( QStringList ) ), this, SLOT( AlsaWatcherEvent( QStringList ) ) ); QFileSystemWatcher * VideoFileSystemWatcher = new QFileSystemWatcher(); VideoFileSystemWatcher->addPath( SaveVideoPathLineEdit->displayText() ); connect( VideoFileSystemWatcher, SIGNAL( directoryChanged( const QString& ) ), this, SLOT( myVideoFileSystemWatcher( const QString ) ) ); myVideoFileSystemWatcher( "" ); clickedScreenSize(); AreaOnOff(); } screencast::~screencast() { } void screencast::buttonVersion() { QString localVersion = Version; if ( version.isNewVersionAvailable( localVersion, version.getRemoteVersion() ) ) updateButton->show(); else updateButton->hide(); } void screencast::showHomepage() { QDesktopServices::openUrl( QUrl( "http://www.kohaupt-online.de/hp", QUrl::StrictMode ) ); } void screencast::showCredits() { creditsQPushButton->setEnabled( false ); credits = new QvkCredits(); credits->show(); connect( credits, SIGNAL( closeCredits() ), SLOT( creditsCloseEvent() ) ); } /** * Wird aufgerufen wenn das credits Fenster geschloßen und dabei * das SIGNAL closeCredits in der Klasse QvkCredits ausgelösst wird */ void screencast::creditsCloseEvent() { creditsQPushButton->setEnabled( true ); delete credits; } void screencast::stateChangedSystray( int state ) { if ( state == Qt::Unchecked ) { SystemTrayIconGreen->hide(); SystemTrayIconRed->hide(); SystemTrayIconYellow->hide(); SystemTrayIconBlue->hide(); } if ( state == Qt::Checked ) { SystemTrayIconGreen->show(); SystemTrayIconRed->hide(); SystemTrayIconYellow->hide(); SystemTrayIconBlue->hide(); } } void screencast::send() { QvkMail *vkMail = new QvkMail( this ); (void)vkMail; } void screencast::clickedRecordButtonScreenSize() { if ( FullScreenRadioButton->isChecked() ) statusbarLabelScreenSize->setText( "F:" + getRecordWidth() + "x" + getRecordHeight() ); if ( WindowRadioButton->isChecked() ) statusbarLabelScreenSize->setText( "W:" + getRecordWidth() + "x" + getRecordHeight() ); if ( AreaRadioButton->isChecked() ) statusbarLabelScreenSize->setText( "A:" + getRecordWidth() + "x" + getRecordHeight() ); } /** * Statusbar */ void screencast::clickedScreenSize() { if ( FullScreenRadioButton->isChecked() ) statusbarLabelScreenSize->setText( "F" ); if ( WindowRadioButton->isChecked() ) statusbarLabelScreenSize->setText( "W" ); if ( AreaRadioButton->isChecked() ) statusbarLabelScreenSize->setText( "A" ); } /** * Statusbar */ void screencast::valueChangedFrames( int i ) { (void)i; statusBarLabelFpsSettings->setText( QString::number( FrameSpinBox->value() ) ); } /** * Statusbar */ void screencast::stateChangedAudio( int state ) { if ( state == Qt::Unchecked ) statusBarLabelAudio->setText( "off" ); if ( state == Qt::Checked ) { if ( AlsaRadioButton->isChecked() ) statusBarLabelAudio->setText( "Alsa" ); if ( PulseDeviceRadioButton->isChecked() ) statusBarLabelAudio->setText( "Pulse" ); } } /** * Statusbar */ void screencast::clickedAudioAlsa( bool checked ) { if ( checked ) statusBarLabelAudio->setText( "Alsa" ); } /** * Statusbar */ void screencast::clickedAudioPulse( bool checked ) { if ( checked == true ) statusBarLabelAudio->setText( "Pulse" ); } /** * Statusbar */ void screencast::currentIndexChangedCodec( int index ) { (void)index; statusBarLabelCodec->setText( VideocodecComboBox->currentText() ); } /** * Statusbar */ void screencast::currentIndexChangedFormat( int index ) { (void)index; statusBarLabelFormat->setText( VideoContainerComboBox->currentText() ); } void screencast::MagnifierDialog() { magnifier->getDialogMagnifier( this ); } void screencast::myVideoFileSystemWatcher( const QString & path ) { (void)path; QDir Dira( PathMoviesLocation() ); QStringList filters; filters << "vokoscreen*"; QStringList List = Dira.entryList( filters, QDir::Files, QDir::Time ); if ( List.isEmpty() ) { PlayButton->setEnabled( false ); sendPushButton->setEnabled( false ); } else { PlayButton->setEnabled( true ); sendPushButton->setEnabled( true ); } } /* QString boolToStr( bool boo ) { return ( ( true == boo ) ? "true" : "false" ); } */ /** * CardxList beinhaltet "card0", "card1" ... * */ void screencast::AlsaWatcherEvent( QStringList CardxList ) { qDebug() << "[vokoscreen] ---Begin search Alsa capture device---"; AlsaHwComboBox->clear(); AlsaDeviceList.clear(); // Für jede card wird eine Instanz erzeugt und in AlsaDeviceList abgelegt for( int i = 0; i <= CardxList.count() - 1; i++ ) { QvkAlsaDevice * alsaDevice = new QvkAlsaDevice( CardxList[ i ] ); AlsaDeviceList.append( alsaDevice ); AlsaHwComboBox->addItem( AlsaDeviceList.at( i )->getAlsaName() , i ); } QSettings settings( ProgName, ProgName ); settings.beginGroup( "Alsa" ); int x = AlsaHwComboBox->findText( settings.value( "NameCaptureCard" ).toString(),Qt::MatchExactly ); AlsaHwComboBox->setCurrentIndex( x ); settings.endGroup(); qDebug() << "[vokoscreen] ---End search Alsa capture device---"; qDebug(); settings.beginGroup( "Pulse" ); PulseMultipleChoice(); for ( int x = 0; x < 10; x++ ) for ( int i = 0; i < getPulseInputDevicesCount(); i++ ) { QCheckBox *aa = getCheckBoxPulseDevice( i ); if ( aa->text() == settings.value( "NameCaptureCard-" + QString::number( x + 1 ) ).toString() ) aa->setCheckState( Qt::Checked ); } settings.endGroup(); } void screencast::WindowMinimized() { setWindowState( Qt::WindowMinimized ); } /** * Wird beim beenden von vokoscreen aufgerufen */ void screencast::closeEvent( QCloseEvent * event ) { (void)event; Stop(); saveSettings(); myregionselection->close(); magnifier->close(); if ( webcamCheckBox->isVisible() ) webcamCheckBox->webcamClose(); } void screencast::saveSettings() { QSettings settings( ProgName, ProgName ); settings.clear(); settings.beginGroup( "vokoscreen" ); settings.setValue( "Version", Version ); settings.endGroup(); settings.beginGroup( "Audio" ); settings.setValue( "AudioOnOff", AudioOnOffCheckbox->checkState() ); settings.endGroup(); settings.beginGroup( "Alsa" ); settings.setValue( "Alsa", AlsaRadioButton->isChecked() ); settings.setValue( "NameCaptureCard", AlsaHwComboBox->currentText() ); settings.endGroup(); settings.beginGroup( "Pulse" ); settings.setValue( "Pulse", PulseDeviceRadioButton->isChecked() ); for ( int i = 1; i < getCountCheckedPulseDevices() + 1; i++ ) settings.setValue( "NameCaptureCard-" + QString::number( i ), getPulseDeviceName( i ) ); settings.endGroup(); settings.beginGroup( "Record" ); settings.setValue( "FullScreen", FullScreenRadioButton->isChecked() ); settings.setValue( "Window", WindowRadioButton->isChecked() ); settings.setValue( "Area", AreaRadioButton->isChecked() ); settings.endGroup(); settings.beginGroup( "Miscellaneous" ); settings.setValue( "VideoPath", SaveVideoPathLineEdit->displayText() ); settings.setValue( "Videoplayer", VideoplayerComboBox->currentText() ); settings.setValue( "Minimized", MinimizedCheckBox->checkState() ); settings.setValue( "Countdown", CountdownSpinBox->value() ); settings.endGroup(); settings.beginGroup( "Videooptions" ); settings.setValue( "Frames", FrameSpinBox->value() ); settings.setValue( "Videocodec", VideocodecComboBox->currentText() ); settings.setValue( "Format", VideoContainerComboBox->currentText() ); settings.setValue( "HideMouse", HideMouseCheckbox->checkState() ); settings.endGroup(); settings.beginGroup( "GUI" ); settings.setValue( "X", x() ); settings.setValue( "Y", y() ); settings.setValue( "Tab", tabWidget->currentIndex() ); settings.setValue( "Systray", SystrayCheckBox->checkState() ); settings.endGroup(); settings.beginGroup( "Area" ); settings.setValue( "X", myregionselection->getX() ); settings.setValue( "Y", myregionselection->getY() ); settings.setValue( "Width", myregionselection->getWidth() ); settings.setValue( "Height", myregionselection->getHeight() ); settings.endGroup(); webcamCheckBox->saveSettings(); myregionselection->saveSettings(); } void screencast::ShortcutMagnifier() { MagnifierCheckBox->click(); } void screencast::showMagnifier() { if ( MagnifierCheckBox->isChecked() ) magnifier->show(); else magnifier->close(); } void screencast::uncheckMagnifier() { if ( MagnifierCheckBox->checkState() == Qt::Checked ) MagnifierCheckBox->click(); } void screencast::ShortcutPause() { PauseButton->click(); } void screencast::SystemTrayStart( QSystemTrayIcon::ActivationReason reason ) { if ( reason == QSystemTrayIcon::Trigger ) { SystemTrayIconGreen->hide(); recordButton->click(); } } void screencast::SystemTrayStop( QSystemTrayIcon::ActivationReason reason ) { if ( reason == QSystemTrayIcon::Trigger ) StopButton->click(); } void screencast::SystemTrayPause( QSystemTrayIcon::ActivationReason reason ) { if ( reason == QSystemTrayIcon::Trigger ) PauseButton->click(); } void screencast::SystemTrayGo( QSystemTrayIcon::ActivationReason reason ) { if ( reason == QSystemTrayIcon::Trigger ) PauseButton->click(); } void screencast::AreaOnOff() { if ( FullScreenRadioButton->isChecked() or WindowRadioButton->isChecked() ) myregionselection->close(); if ( AreaRadioButton->isChecked() ) { myregionselection->close(); myregionselection->show(); } } /** * Search program foo in PATH */ QString getFileWithPath( QString ProgName ) { QString find; QString prog; QString resultString( qgetenv( "PATH" ) ); QStringList pathList = resultString.split( ":" ); for ( int i = 0; i < pathList.size(); ++i ) { prog = pathList.at( i ) + QDir::separator() + ProgName; if ( QFile::exists( prog ) ) { find = prog; break; } } return find; } /** * Looking for external programs */ void screencast::searchExternalPrograms() { qDebug() << "[vokoscreen]" << "---Begin Search external tools---"; QString Prog = "ffmpeg"; QFileInfo info( getFileWithPath( Prog ) ); if ( info.isSymLink() ) { QString fileName = info.symLinkTarget(); QFileInfo fileInfo( fileName ); qDebug() << "[vokoscreen]" << getFileWithPath( Prog ) << "is a link and pointing to"<< fileName; if ( fileInfo.baseName() == "avconv" ) { recordApplikation = "avconv"; qDebug() << "[vokoscreen] use avconv as ffmpeg-link"; } } else { if ( needProgram( "avconv" ) ) { recordApplikation = "avconv"; qDebug() << "[vokoscreen]" << "Find avconv" << "Version:" << getAvconvVersion(); } else { if ( needProgram( "ffmpeg" ) ) { recordApplikation = "ffmpeg"; qDebug() << "[vokoscreen]" << "Find ffmpeg" << "Version:" << getFfmpegVersion(); } } } if ( needProgram("pactl") ) qDebug() << "[vokoscreen]" << "Find pactl"; else qDebug() << "[vokoscreen]" << "Error: pactl is not found, this is an PulseAudio-utils tool. Please install pactl"; if ( needProgram("mkvmerge") ) qDebug() << "[vokoscreen]" << "Find mkvmerge"; else qDebug() << "[vokoscreen]" << "Error: mkvmerge is not found, this is an mkvtoolnix tool. Please install mkvmerge"; qDebug() << "[vokoscreen]" << "---End search external tools---"; qDebug(); } /** * Set standard video codec and options */ void screencast::setVideocodecStandardComboBox() { VideocodecComboBox->setCurrentIndex( VideocodecComboBox->findText( "mpeg4", Qt::MatchExactly ) ); VideoContainerComboBox->setCurrentIndex( VideoContainerComboBox->findText( "mkv", Qt::MatchExactly ) ); } /** * Set standard fps */ void screencast::setFrameStandardSpinbox() { FrameSpinBox->setValue( 25 ); } /** * Erstellt ~/.asoundrc wenn nicht im Userhome vorhanden * -Die .asoundrc sollte nur erstellt werden wenn der Start von ffmpeg fehlschägt. * Hint: Abfrage muß noch eingebaut werden. */ void screencast::makeAsoundrc() { QString homeLocation = QDesktopServices::storageLocation( QDesktopServices:: QDesktopServices::HomeLocation ); QString asoundrc = homeLocation + "/.asoundrc"; qDebug() << "[vokoscreen]" << "---Begin search PulseAudio Plugin---"; QFile qFile( asoundrc ); if ( not qFile.exists() ) { qFile.open( QIODevice::WriteOnly ); qDebug() << "[vokoscreen] File not found .asound for PulseAudio Plugin"; qDebug() << "[vokoscreen] Create file .asound for PulseAudio Plugin"; QTextStream out( &qFile ); out << "# create by vokoscreen " << Version << "\n"; out << "\n"; out << "pcm.pulse {\n"; out << " type pulse\n"; out << "}\n"; out << "\n"; out << "ctl.pulse {\n"; out << " type pulse\n"; out << "}\n"; out << "\n"; qFile.flush(); qFile.close(); } else qDebug() << "[vokoscreen] Found file .asound for PulseAudio Plugin"; qDebug() << "[vokoscreen]" << "---End search PulseAudio Plugin---"; qDebug(); } void screencast::saveVideoPath() { QString dir = QFileDialog::getExistingDirectory( this, tr( "Open Directory" ), QDesktopServices::storageLocation( QDesktopServices::HomeLocation ), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks ); if ( dir > "" ) SaveVideoPathLineEdit->setText( dir ); } void screencast::readyReadStandardError() { int s = beginTime.secsTo( QDateTime::currentDateTime() ); int HH = s / 3600; int MM = ( s- ( s / 3600 ) * 3600 ) / 60; int SS = s % 60; QTime myTime( HH, MM, SS); QString time = myTime.toString ( "hh:mm:ss"); statusBarLabelTime->setText( time ); QString output = SystemCall->readAllStandardError(); if ( output.contains( "fps=", Qt::CaseInsensitive ) ) { int x = output.indexOf( "fps" ); statusBarLabelFps->setText( output.mid( x + 4, 3 ).replace( " ", "" ) ); } // int fps = statusBarLabelFps->text().toUInt(); if ( fps >= FrameSpinBox->value() ) { statusBarLabelFps->setToolTip( tr( "Actual frames per second" ) ); statusBarLabelFps->setAutoFillBackground( true ); QPalette pal( statusBarLabelFps->palette() ); pal.setColor( QPalette::Foreground, Qt::black ); pal.setColor( QPalette::Background, Qt::green ); statusBarLabelFps->setPalette( pal ); } if ( fps < FrameSpinBox->value() ) { statusBarLabelFps->setToolTip( tr( "Your Actual frames in the Settings is too heigh" ) ); statusBarLabelFps->setAutoFillBackground( true ); QPalette pal( statusBarLabelFps->palette() ); if ( pal.color( QPalette::Background ) == Qt::red ) { pal.setColor( QPalette::Foreground, Qt::black ); pal.setColor( QPalette::Background, Qt::yellow ); } else { pal.setColor( QPalette::Foreground, Qt::black ); pal.setColor( QPalette::Background, Qt::red ); } statusBarLabelFps->setPalette( pal ); } QFileInfo fileInfo( PathTempLocation() + QDir::separator() + nameInMoviesLocation ); statusBarLabelSize->setText( QString::number( fileInfo.size() / 1024 ) ); } void screencast::readyReadStandardOutput() { // qDebug() << SystemCall->readAllStandardOutput(); } /** * Je nach Prozessstaus von ffmpeg werden die Widget enabled bzw. disabled */ void screencast::stateChanged ( QProcess::ProcessState newState ) { if ( ( newState == QProcess::Running ) and ( pause == false) ) { StopButton->setEnabled(true); PauseButton->setEnabled(true); recordButton->setEnabled(false); PlayButton->setEnabled(false); FullScreenRadioButton->setEnabled( false ); WindowRadioButton->setEnabled( false ); AreaRadioButton->setEnabled( false ); TabWidgetAudioFrame->setEnabled(false); TabWidgetMiscellaneousFrame->setEnabled(false); TabWidgetVideoOptionFrame->setEnabled( false ); if ( SystrayCheckBox->checkState() == Qt::Checked ) { SystemTrayIconGreen->hide(); SystemTrayIconYellow->show(); SystemTrayIconRed->show(); SystemTrayIconBlue->hide(); } } if ((newState == QProcess::NotRunning) and (pause == false)) { StopButton->setEnabled(false); PauseButton->setEnabled(false); recordButton->setEnabled(true); FullScreenRadioButton->setEnabled( true ); WindowRadioButton->setEnabled( true ); AreaRadioButton->setEnabled( true ); TabWidgetAudioFrame->setEnabled(true); TabWidgetMiscellaneousFrame->setEnabled(true); TabWidgetVideoOptionFrame->setEnabled( true ); if ( SystrayCheckBox->checkState() == Qt::Checked ) { SystemTrayIconGreen->show(); SystemTrayIconYellow->hide(); SystemTrayIconRed->hide(); SystemTrayIconBlue->hide(); } if ( MagnifierCheckBox->isChecked() ) MagnifierCheckBox->click(); } if ((newState == QProcess::NotRunning) and (pause == true) and ( PauseButton->isChecked() )) { StopButton->setEnabled(false); PauseButton->setEnabled(true); recordButton->setEnabled(false); PlayButton->setEnabled(false); FullScreenRadioButton->setEnabled( false ); WindowRadioButton->setEnabled( false ); AreaRadioButton->setEnabled( false ); TabWidgetAudioFrame->setEnabled(false); TabWidgetMiscellaneousFrame->setEnabled(false); TabWidgetVideoOptionFrame->setEnabled( false ); if ( SystrayCheckBox->checkState() == Qt::Checked ) { SystemTrayIconGreen->hide(); SystemTrayIconRed->hide(); SystemTrayIconYellow->hide(); SystemTrayIconBlue->show(); } } if ((newState == QProcess::Running) and (pause == true) and ( not PauseButton->isChecked() )) { StopButton->setEnabled(true); PauseButton->setEnabled(true); recordButton->setEnabled(false); PlayButton->setEnabled(false); FullScreenRadioButton->setEnabled( false ); WindowRadioButton->setEnabled( false ); AreaRadioButton->setEnabled( false ); TabWidgetAudioFrame->setEnabled(false); TabWidgetMiscellaneousFrame->setEnabled(false); TabWidgetVideoOptionFrame->setEnabled( false ); if ( SystrayCheckBox->checkState() == Qt::Checked ) { SystemTrayIconGreen->hide(); SystemTrayIconYellow->show(); SystemTrayIconRed->show(); SystemTrayIconBlue->hide(); } } if ( ( newState == QProcess::NotRunning ) and ( pause == true ) and ( not PauseButton->isChecked() ) ) { StopButton->setEnabled(false); PauseButton->setEnabled(false); recordButton->setEnabled(true); FullScreenRadioButton->setEnabled( true ); WindowRadioButton->setEnabled( true ); AreaRadioButton->setEnabled( true ); TabWidgetAudioFrame->setEnabled(true); TabWidgetMiscellaneousFrame->setEnabled(true); TabWidgetVideoOptionFrame->setEnabled( true ); if ( SystrayCheckBox->checkState() == Qt::Checked ) { SystemTrayIconGreen->show(); SystemTrayIconRed->hide(); SystemTrayIconYellow->hide(); SystemTrayIconBlue->hide(); } } if (newState == QProcess::Running) { qDebug(); qDebug() << "[vokoscreen] ffmpeg is running and is ready for reading and writing"; } if (newState == QProcess::NotRunning) { qDebug(); qDebug() << "[vokoscreen] ffmpeg is not running"; //Enables the customarea rectangle again. (Is diabled in record() ) if(!PauseButton->isChecked()){ myregionselection->lockFrame(false); } } } void screencast::error( QProcess::ProcessError error ) { // Kann mann testen in dem man den ffmpeg aus der Processliste tötet if ( error == QProcess::Crashed ) { // remove crashed directory QSettings settings1( ProgName, ProgName ); QFileInfo settingsPath1( settings1.fileName() ); QFile file1( settingsPath1.absolutePath() ); QString workDirectory1 = file1.fileName(); QDir Dir1( "" ); Dir1.setCurrent( workDirectory1 ); if ( Dir1.cd( "crashed" ) ) { QStringList stringList1 = Dir1.entryList( QDir::Files, QDir::NoSort ); for ( int i = 0; i < stringList1.count(); ++i ) Dir1.remove( stringList1[ i ] ); } // Move ffmpeg.log, vokoscreen.log, vokoscreen.conf in directory crashed QSettings settings( ProgName, ProgName ); QFileInfo settingsPath( settings.fileName() ); QFile file( settingsPath.absolutePath() ); QString workDirectory = file.fileName(); QDir Dir( "" ); Dir.setCurrent( workDirectory ); Dir.mkdir( "crashed" ); QStringList stringList = Dir.entryList( QDir::Files, QDir::NoSort ); for ( int i = 0; i < stringList.count(); ++i ) QFile::copy( workDirectory + QDir::separator() + stringList[ i ], workDirectory + QDir::separator() + "crashed" + QDir::separator() + stringList[ i ]); QString crashedtext = "[vokoscreen] ffmpeg is crashed on "; QDateTime dateTime = QDateTime::currentDateTime(); QString time = dateTime.toString( "hh:mm" ); QString day = dateTime.toString( "dddd" ); qDebug(); qDebug() << "********************************************************"; qDebug() << crashedtext + day + ", " + time; qDebug() << "********************************************************"; QMessageBox msgBox; msgBox.setIcon( QMessageBox::Critical ); msgBox.setText( crashedtext + day + ", " + time ); msgBox.exec(); } // Noch nicht getestet if ( error == QProcess::FailedToStart ) { qDebug() << "The process could not be started. Either the is called program is not installed, or the ffmpeg or avconv call Faulty or you have not over sufficient permissions to to the program."; QMessageBox msgBox; msgBox.setText( "The process could not be started. Either the is called program is not installed, or the ffmpeg or avconv call Faulty or you have not over sufficient permissions to to the program." ); msgBox.exec(); } } /** * Search program foo in PATH */ bool screencast::needProgram( QString ProgName ) { bool find = false; QString prog; QString resultString( qgetenv( "PATH" ) ); QStringList pathList = resultString.split( ":" ); for ( int i = 0; i < pathList.size(); ++i ) { prog = pathList.at( i ) + QDir::separator() + ProgName; if ( QFile::exists( prog ) ) { find = true; break; } } return find; } void screencast::moveWindowPause() { pause = true; PauseButton->setChecked( true ); PauseButton->setText( tr( "Go" ) ); SystemCall->terminate(); SystemCall->waitForFinished(); pulseUnloadModule(); } void screencast::moveWindowGo() { PauseButton->setChecked( false ); PauseButton->setText( tr ( "Pause" ) ); startRecord( PathTempLocation() + QDir::separator() + PauseNameInTmpLocation() ); } void screencast::Pause() { if ( FullScreenRadioButton->isChecked() or AreaRadioButton->isChecked() ) { pause = true; if ( PauseButton->isChecked() ) { shortcutStop->setEnabled( false ); windowMoveTimer->stop(); PauseButton->setText( tr ( "Go" ) ); SystemCall->terminate(); SystemCall->waitForFinished(); pulseUnloadModule(); } else { QVariant aa = AlsaHwComboBox->itemData( AlsaHwComboBox->currentIndex() ); QvkAlsaDevice *inBox = AlsaDeviceList.at( aa.toInt() ); if ( inBox->isbusy() and AlsaRadioButton->isChecked() ) { QMessageBox msgBox; QString message; message.append( tr( "Device %1 is busy" ).arg( inBox->getAlsaHw() ) ); msgBox.setText( message ); msgBox.exec(); PauseButton->click(); return; } shortcutStop->setEnabled( true ); PauseButton->setText( tr( "Pause" ) ); startRecord( PathTempLocation() + QDir::separator() + PauseNameInTmpLocation() ); } } if ( WindowRadioButton->isChecked() ) { pause = true; if ( PauseButton->isChecked() ) { shortcutStop->setEnabled( false ); windowMoveTimer->stop(); PauseButton->setText( tr ( "Go" ) ); SystemCall->terminate(); SystemCall->waitForFinished(); pulseUnloadModule(); } else { QVariant aa = AlsaHwComboBox->itemData( AlsaHwComboBox->currentIndex() ); QvkAlsaDevice *inBox = AlsaDeviceList.at( aa.toInt() ); if ( inBox->isbusy() and AlsaRadioButton->isChecked() ) { QMessageBox msgBox; QString message; message.append( tr( "Device %1 is busy" ).arg( inBox->getAlsaHw() ) ); msgBox.setText( message ); msgBox.exec(); PauseButton->click(); return; } shortcutStop->setEnabled( true ); PauseButton->setText( tr( "Pause" ) ); startRecord( PathTempLocation() + QDir::separator() + PauseNameInTmpLocation() ); windowMoveTimer->start(); } } } /** * Play last screencast with Videoplayer */ void screencast::play() { if ( MagnifierCheckBox->isChecked() ) MagnifierCheckBox->click(); QVariant aa = VideoplayerComboBox->itemData( VideoplayerComboBox->currentIndex() ); // get userdata from ComboBox QString player = aa.toString(); player = player.replace( "\n", "" ); QDir Dira( PathMoviesLocation() ); QStringList filters; filters << "vokoscreen*"; QStringList List = Dira.entryList( filters, QDir::Files, QDir::Time ); if ( List.isEmpty() ) { QProcess *SystemCall = new QProcess( this ); SystemCall->start( player ); } else { QProcess *SystemCall = new QProcess( this ); SystemCall->start( player + " " + PathMoviesLocation() + QDir::separator() + List.at( 0 ) ); } } QString screencast::getAvconvVersion() { QProcess Process; Process.start("avconv -version"); Process.waitForFinished(); QString avconvVersion = Process.readAllStandardOutput(); Process.close(); QStringList list = avconvVersion.split( "\n" ); list = list[ 0 ].split( " " ); return list[ 1 ]; } /** * Versionsnummer von ffmpeg aufbereiten so diese mit "kleiner gleich" bzw. "größer gleich" ausgewertet werden kann */ QString screencast::getFfmpegVersion() { QProcess Process; Process.start("ffmpeg -version"); Process.waitForFinished(); QString ffmpegversion = Process.readAllStandardOutput(); Process.close(); QStringList list = ffmpegversion.split( "\n" ); ffmpegversion = list[ 0 ]; ffmpegversion.replace(QRegExp( "[A-Z a-z ]" ), "" ); // major list.clear(); list = ffmpegversion.split( "." ); if ( list.count() == 1 ) list.append( "00" ); if ( list.count() == 2 ) list.append( "00" ); // major QString major; if ( list[ 0 ].size() < 2 ) major = list[ 0 ].prepend( "0" ); else major = list[ 0 ]; //minor QString minor; if ( list.count() > 1 ) { if ( list[ 1 ].size() < 2 ) minor = list[ 1 ].prepend( "0" ); else minor = list[ 1 ]; } //patch QString patch; if ( list.count() > 2 ) { if ( list[ 2 ].size() < 2 ) patch = list[ 2 ].prepend( "0" ); else patch = list[ 2 ]; } return major + "." + minor + "." + patch; } void screencast::windowMove() { // Begin Window is closed QStringList stringList; QList list = QxtWindowSystem::windows() ; for( int i = 0; i < list.count(); i++) stringList << QString::number( list[ i ] ); if ( !stringList.contains( QString::number( moveWindowID ) ) ) { windowMoveTimer->stop(); StopButton->click(); return; } // End Window is closed // Wenn Versatzwert kleiner null ist QString x = QString::number( QxtWindowSystem::windowGeometry( moveWindowID ).x() ); int xx = x.toInt(); if ( xx < 0 ) x = "0"; QString y = QString::number( QxtWindowSystem::windowGeometry( moveWindowID ).y() ); int yy = y.toInt(); if ( yy < 0 ) y = "0"; if ( ( deltaXMove != x ) or ( deltaYMove != y ) ) if ( SystemCall->state() == QProcess::Running ) moveWindowPause(); if ( ( deltaXMove == x ) and ( deltaYMove == y ) ) if ( ( SystemCall->state() == QProcess::NotRunning ) ) { QStringList result = ffmpegString.split( ":0." ); QString str1 = result[ 0 ]; QString str2 = result[ 1 ]; result.clear(); result = str2.split( " " ); result[ 0 ] = ":0.0+" + x + "," + y; str2 = ""; for ( int i = 0; i < result.count(); i++ ) str2.append( result.at( i ) + " " ); ffmpegString = str1 + str2.trimmed() + " "; moveWindowGo(); } deltaXMove = x; deltaYMove = y; } /** * */ int screencast::getPulseInputDevicesCount() { QProcess *Process = new QProcess( this ); QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); env.insert("LANG", "c"); Process->setProcessEnvironment(env); Process->start( "pactl list" ); Process->waitForFinished(); QString output = Process->readAllStandardOutput(); Process->close(); delete Process; QStringList list = output.split( "\n" ); QStringList result = list.filter( "Source #", Qt::CaseInsensitive ); return result.count(); } /** * */ QString screencast::getPulseInputName( int value ) { QProcess *Process = new QProcess( this ); QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); env.insert("LANG", "c"); Process->setProcessEnvironment(env); Process->start( "pactl list" ); Process->waitForFinished(); QString output = QString::fromUtf8(Process->readAllStandardOutput()); Process->close(); delete Process; QStringList list = output.split( "\n" ); QStringList result = list.filter( "Source #", Qt::CaseInsensitive ); QString SourceNummber = result[ value - 1 ]; int index = list.indexOf( SourceNummber ); QString name = list[ index + 3 ]; QStringList resultList = name.split( ":" ); name = resultList[ 1 ].trimmed(); return name; } /** * Get Pulse Devicname */ QString screencast::getPulseInputDevices( int value ) { QProcess *Process = new QProcess( this ); QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); env.insert("LANG", "c"); Process->setProcessEnvironment(env); Process->start( "pactl list" ); Process->waitForFinished(); QString output = Process->readAllStandardOutput(); Process->close(); delete Process; QStringList list = output.split( "\n" ); QStringList result = list.filter( "Source #", Qt::CaseInsensitive ); QString SourceNummber = result[ value - 1 ]; int index = list.indexOf( SourceNummber ); QString device = list[ index + 2 ]; QStringList resultList = device.split( ":" ); device = resultList[ 1 ].trimmed(); return device; } /** * Get Pulse Samplerate */ QString screencast::getPulseSample( int value ) { QProcess *Process = new QProcess( this ); QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); env.insert("LANG", "c"); Process->setProcessEnvironment(env); Process->start( "pactl list" ); Process->waitForFinished(); QString output = Process->readAllStandardOutput(); Process->close(); delete Process; QStringList list = output.split( "\n" ); QStringList result = list.filter( "Source #", Qt::CaseInsensitive ); QString SourceNummber = result[ value - 1 ]; int index = list.indexOf( SourceNummber ); QString device = list[ index + 5 ]; QStringList resultList = device.split( ":" ); list.clear(); QString aa = resultList[ 1 ].trimmed(); list = aa.split( " " ); result.clear(); result = list.filter( "Hz", Qt::CaseInsensitive ); QString sample = result[ 0 ].replace("Hz",""); return sample; } /** * Englisch: * Return Samplerate from checked Device * Pulse: The lowest rate sampler for the selected device is used * * German: * Gibt Samplerrate von ausgewählten Geräten zurück. * Pulse: Wenn mehrere Geräte ausgewählt wurden wird die niedrigste Samplerrate herangezogen */ QString screencast::mySample() { QString ret = "48000"; if ( PulseDeviceRadioButton->isChecked() ) { QList listQFrame = Pulseframe->findChildren(); QCheckBox *inBox; QString Sample; QStringList list; for ( int i = 0; i < listQFrame.count(); i++ ) { inBox = listQFrame.at( i ); if ( inBox->checkState() == Qt::Checked ) list.append( getPulseSample( i + 1 ) ); } list.sort(); if ( not list.empty() ) ret = list.first(); } if ( AlsaRadioButton->isChecked() ) { // Aus der ComboBox das ausgewählte Device holen QVariant aa = AlsaHwComboBox->itemData( AlsaHwComboBox->currentIndex() ); QvkAlsaDevice *inBox = AlsaDeviceList.at( aa.toInt() ); ret = inBox->getAlsaSample(); } return ret; } void screencast::AudioOnOff() { if ( AudioOnOffCheckbox->checkState() == Qt::Checked ) { AlsaRadioButton->setEnabled( true ); PulseDeviceRadioButton->setEnabled( true ); if ( PulseDeviceRadioButton->isChecked() ) Pulseframe->setEnabled( true ); else Pulseframe->setEnabled( false ); if ( AlsaRadioButton->isChecked() ) AlsaHwComboBox->setEnabled( true ); else AlsaHwComboBox->setEnabled( false ); } else { AlsaRadioButton->setEnabled( false ); AlsaHwComboBox->setEnabled( false ); // PulseRadioButton->setEnabled( false ); Pulseframe->setEnabled( false ); PulseDeviceRadioButton->setEnabled( false ); } } /** * Erstellt eine Scrollarea mit einem Frame * in dem die Checkboxen gesetzt werden * * In setAccessibleName steht das Pulse Device */ void screencast::PulseMultipleChoice() { qDebug() << "[vokoscreen]" << "---Begin search PulseAudio Capture Devices---"; QList listQScrollArea = TabWidgetAudioFrame->findChildren(); if ( listQScrollArea.count() > 0 ) { delete scrollAreaPulse; listQScrollArea.clear(); } if ( listQScrollArea.count() == 0 ) { Pulseframe = new QFrame(); scrollAreaPulse = new QScrollArea( TabWidgetAudioFrame ); scrollAreaPulse->setWidget( Pulseframe ); scrollAreaPulse->setHorizontalScrollBarPolicy ( Qt::ScrollBarAlwaysOff ); scrollAreaPulse->setGeometry( 90, 20, 345, 80 ); scrollAreaPulse->show(); Pulseframe->setGeometry( 90, 20, 320, 100 ); // Mit den letzten Zahlen werden die scrollAreaPulsebalken geregelt // 90, 45, 320, 100 Pulseframe->show(); for ( int i = 0; i < getPulseInputDevicesCount(); ++i ) { namePulse = new QCheckBox( Pulseframe ); namePulse->setGeometry( QRect( 0, i * 20, 400, 21 ) ); namePulse->setText( getPulseInputName( i + 1 ) ); namePulse->setAccessibleName( getPulseInputDevices( i + 1 ) ); namePulse->setToolTip( tr ( "Select one or more devices" ) ); namePulse->show(); qDebug() << "[vokoscreen]" << "Find CaptureCard:" << namePulse->text() << "with device:" << namePulse->accessibleName(); } } AudioOnOff(); qDebug() << "[vokoscreen]" << "---End search PulseAudio Capture Devices---"; qDebug(); } QString screencast::PathMoviesLocation() { QString Path; if ( SaveVideoPathLineEdit->displayText() > "" ) Path = SaveVideoPathLineEdit->displayText(); else { if ( QDesktopServices::storageLocation( QDesktopServices::MoviesLocation).isEmpty() ) { Path = QDesktopServices::storageLocation( QDesktopServices:: QDesktopServices::HomeLocation ); SaveVideoPathLineEdit->setText(Path); } else { Path = QDesktopServices::storageLocation( QDesktopServices::MoviesLocation ); SaveVideoPathLineEdit->setText( Path ); } } return Path; } QString screencast::PathTempLocation() { // Doppelter ProgName um Eindeutigkeit in tmp zuerreichen QString tmpName = ProgName + "-" + ProgName; QString tempPathProg = QDesktopServices::storageLocation ( QDesktopServices::TempLocation ) + QDir::separator() + tmpName; QDir dirTempPathProg( tempPathProg ); if ( not dirTempPathProg.exists() ) { QString tempPath = QDesktopServices::storageLocation ( QDesktopServices::TempLocation ); QDir dirTempPath( tempPath ); dirTempPath.mkdir( tmpName ); } return tempPathProg; } /** * Return the new screencastname */ QString screencast::NameInMoviesLocation() { return "vokoscreen-" + QDateTime::currentDateTime().toString( "yyyy-MM-dd_hh-mm-ss" ) + "." + VideoContainerComboBox->currentText(); } /** * Return the new pausename */ QString screencast::PauseNameInTmpLocation() { QString myFilename = "screencast-pause"; QString myFilenameExtension = "." + VideoContainerComboBox->currentText(); QString myName = PathTempLocation() + QDir::separator() + myFilename + myFilenameExtension; QFile *myFile = new QFile( myName ); uint x = 0; do { x++; myFile->setFileName( PathTempLocation() + QDir::separator() + myFilename + "-" + QString().number( x ) + myFilenameExtension ); myName = myFile->fileName(); } while ( myFile->exists() ); return myFilename + "-" + QString().number( x ) + myFilenameExtension; } QString screencast::myAlsa() { QString value; if ( AudioOnOffCheckbox->checkState() == Qt::Checked ) { if ( AlsaRadioButton->isChecked() ) { QVariant aa = AlsaHwComboBox->itemData( AlsaHwComboBox->currentIndex() ); QvkAlsaDevice *inBox = AlsaDeviceList.at( aa.toInt() ); if ( AlsaHwComboBox->currentIndex() > -1 ) value = "-f alsa -ac " + inBox->getChannel() + " -i " + inBox->getAlsaHw() + " "; else value = ""; } if ( PulseDeviceRadioButton->isChecked() ) { QCheckBox *box; int counter = 0; QList listQFrame = Pulseframe->findChildren(); if ( listQFrame.count() > 0 ) for ( int i = 0; i < listQFrame.count(); i++ ) { box = listQFrame.at( i ); if ( box->checkState() == Qt::Checked ) counter++; } if ( counter > 0 ) value = "-f alsa -i pulse "; else value = ""; } } else value = ""; return value; } void screencast::pulseUnloadModule() { qDebug() << ""; qDebug() << "[vokoscreen] ---Begin Pulse unload Module---"; QProcess Process; QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); env.insert("LANG", "c"); Process.setProcessEnvironment(env); Process.start( "pactl list" ); Process.waitForFinished(); QString output = Process.readAllStandardOutput(); Process.close(); QStringList list = output.split( "\n" ); QStringList modulNumberList; QString str; QString strLog; for ( int i = 0; i < list.count(); i++ ) { str = list[ i ]; if ( str.contains("vokoscreenMix", Qt::CaseInsensitive) ) { str = list[ i - 2 ]; if ( str.contains("Module", Qt::CaseInsensitive) ) { str.replace("Module #", ""); str.replace("\n", ""); modulNumberList.insert ( 0, str ); } } } for ( int i = 0; i < modulNumberList.count(); i++ ) { Process.start("pactl unload-module " + modulNumberList[ i ] ); Process.waitForFinished(); Process.close(); qDebug() << "[vokoscreen] pactl unload-module number" << modulNumberList[ i ] ; } qDebug() << "[vokoscreen] ---End Pulse unload Module---"; qDebug() << ""; } /** * Returns Checkbox from Pulse device * */ QCheckBox * screencast::getCheckBoxPulseDevice( int value ) { QList listQFrame = Pulseframe->findChildren(); QCheckBox *inBox; inBox = listQFrame.at( value ); return inBox; } /** * Returns xte checked pulse devicename */ QString screencast::getPulseDeviceName( int value ) { QList listQFrame = Pulseframe->findChildren(); QCheckBox *inBox; int x = 1; QString name; for ( int i = 0; i < listQFrame.count(); i++ ) { inBox = listQFrame.at( i ); if ( inBox->checkState() == Qt::Checked ) { if ( x == value ) name = inBox->text(); x++; } } return name; } /** * Returns count checked pulse devices */ int screencast::getCountCheckedPulseDevices() { QList listQFrame = Pulseframe->findChildren(); QCheckBox *inBox; int x = 0; for ( int i = 0; i < listQFrame.count(); i++ ) { inBox = listQFrame.at( i ); if ( inBox->checkState() == Qt::Checked ) x++; } return x; } /** * Return checked Pulse Device */ const QString screencast::myPulseDevice() { QList listQFrame = Pulseframe->findChildren(); QCheckBox *box; QList integerList; QString ret; for ( int i = 0; i < listQFrame.count(); i++ ) { box = listQFrame.at( i ); if ( box->checkState() == Qt::Checked ) integerList.append( i ); } if ( integerList.count() == 0 ) ret = ""; if ( integerList.count() == 1 ) { box = listQFrame[ integerList[ 0 ] ]; ret = box->accessibleName(); } if ( integerList.count() > 1 ) ret = "vokoscreenMix.monitor"; return ret; } QString screencast::myAcodec() { QString acodec; if ( ( AudioOnOffCheckbox->checkState() == Qt::Checked ) and ( AlsaRadioButton->isChecked() ) and ( AlsaHwComboBox->currentText() > "" ) ) return " -acodec libmp3lame"; if ( ( AudioOnOffCheckbox->checkState() == Qt::Checked ) and ( PulseDeviceRadioButton->isChecked() ) and ( myPulseDevice() > "" ) ) return " -acodec libmp3lame"; return ""; } QString screencast::noMouse() { if ( HideMouseCheckbox->checkState() == Qt::Checked ) return "+nomouse"; else return ""; } void screencast::preRecord() { if ( AlsaRadioButton->isChecked() and AudioOnOffCheckbox->isChecked() ) { QVariant aa = AlsaHwComboBox->itemData( AlsaHwComboBox->currentIndex() ); QvkAlsaDevice *inBox = AlsaDeviceList.at( aa.toInt() ); if ( inBox->isbusy() ) { QMessageBox msgBox; msgBox.setIcon( QMessageBox::Information ); QString message; message.append( tr( "Device %1 is busy" ).arg( inBox->getAlsaHw() ) ); msgBox.setText( message ); msgBox.exec(); return; } else { // Kanäle werden kurz vor der Aufnahme ermittelt inBox->setChannel(); } } if ( WindowRadioButton->isChecked() ) if ( firststartWininfo == false ) { vkWinInfo = new QvkWinInfo(); connect( vkWinInfo, SIGNAL( windowChanged() ), this, SLOT( record() ) ); return; } record(); } void screencast::setRecordWidth( QString value ) { screenRecordWidth = value; } QString screencast::getRecordWidth() { return screenRecordWidth; } void screencast::setRecordHeight( QString value ) { screenRecordHeight = value; } QString screencast::getRecordHeight() { return screenRecordHeight; } void screencast::Countdown() { if ( CountdownSpinBox->value() > 0 ) { recordButton->setEnabled( false ); QDesktopWidget *desk = QApplication::desktop(); int Width = 250; int Height = 250;; int x = ( desk->screenGeometry().width() / 2 ) - ( Width / 2 ); int y = ( desk->screenGeometry().height() / 2 ) -( Height / 2 ); QFrame * countdownDialog = new QFrame(); countdownDialog->setGeometry( x, y, Width, Height ); countdownDialog->setWindowFlags( Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint ); if( QX11Info::isCompositingManagerRunning() ) countdownDialog->setAttribute( Qt::WA_TranslucentBackground, true ); countdownDialog->show(); QFont qfont;; qfont.setPixelSize( 200 ); QLabel * label = new QLabel( countdownDialog ); label->setGeometry( 0, 0, Width, Height ); label->setAlignment( Qt::AlignCenter ); countdownDialog->setFont( qfont ); label->show(); QPalette pal( label->palette() ); pal.setColor( QPalette::Foreground, Qt::red); label->setPalette( pal ); for ( int i = CountdownSpinBox->value(); i >= 1; i-- ) { label->setText( "" ); QCoreApplication::processEvents( QEventLoop::AllEvents ); label->setText( QString::number( i ) ); QCoreApplication::processEvents( QEventLoop::AllEvents ); label->update(); for ( int ii = 1; ii <= 10; ii++) { QCoreApplication::processEvents( QEventLoop::AllEvents ); QTest::qSleep( 100 ); } } // Der Desktopanimation "Langsames ausblenden" entgegenwirken label->setText( "" ); QCoreApplication::processEvents( QEventLoop::AllEvents ); label->hide(); QCoreApplication::processEvents( QEventLoop::AllEvents ); countdownDialog->close(); } } void screencast::record() { Countdown(); shortcutStart->setEnabled( false ); shortcutStop->setEnabled( true ); if ( MinimizedCheckBox->checkState() == Qt::Checked ) WindowMinimized(); if ( FullScreenRadioButton->isChecked() ) { QDesktopWidget *desk = QApplication::desktop(); setRecordWidth( tr( "%1" ).arg( desk->screenGeometry().width() ) ); setRecordHeight( tr( "%1" ).arg( desk->screenGeometry().height() ) ); } QString deltaX = "0"; QString deltaY = "0"; if ( WindowRadioButton->isChecked() and ( firststartWininfo == false) ) { setRecordWidth( vkWinInfo->width() ); setRecordHeight( vkWinInfo->height() ); QDesktopWidget *desk = QApplication::desktop(); if ( getRecordWidth().toInt() >= desk->screenGeometry().width() ) { deltaX = "0"; setRecordWidth( QString::number( desk->screenGeometry().width() ) ); } else deltaX = QString::number( vkWinInfo->x().toUInt() ); if ( getRecordHeight().toUInt() >= QString::number( desk->screenGeometry().height() ).toUInt() ) { deltaY = "0"; setRecordHeight( QString::number( desk->screenGeometry().height() ) ); } else deltaY = QString::number( vkWinInfo->y().toUInt() ); moveWindowID = vkWinInfo->getWinID(); deltaXMove = deltaX; deltaYMove = deltaY; windowMoveTimer->start( 120 ); firststartWininfo = true; } if ( AreaRadioButton->isChecked() ) { setRecordWidth( QString().number( myregionselection->getWidth() ) ); setRecordHeight( QString().number( myregionselection->getHeight() ) ); deltaX = QString().number( myregionselection->getXRecordArea() ); deltaY = QString().number( myregionselection->getYRecordArea() ); myregionselection->cleanRecordArea( true ); //Makes the rectangle unmovable and unresizeable (Is enabled yet again when process finished) myregionselection->lockFrame( true ); } // -report wird erst ab ffmpeg version 0.9 unterstützt QString myReport = ""; if ( recordApplikation == "ffmpeg" ) { if ( getFfmpegVersion() >= "00.09.00" ) myReport = "-report "; else myReport = ""; qDebug() << "[vokoscreen]" << "Report :" << myReport; } // set working directory for writing and delete the ffmpegLog from Profil directory QSettings settings( ProgName, ProgName ); QFileInfo settingsPath( settings.fileName() ); QFile file( settingsPath.absolutePath() ); QString workDirectory = file.fileName(); QDir Dir( "" ); Dir.setCurrent( workDirectory ); // bestehendes ffmpegLog löschen QDir Dira( "" ); QStringList filters; filters << "ffmpeg*"; QStringList List = Dira.entryList(filters, QDir::Files, QDir::Name ); QFile FfmpegFile; for (int i = 0; i < List.size(); ++i) FfmpegFile.remove( List.at(i) ); // evtl. müßte hier erst mal nachgeschaut werden ob Temp leer ist. // Clean vokoscreen temp QDir dir( PathTempLocation() ); QStringList stringList = dir.entryList( QDir::Files, QDir::Time | QDir::Reversed ); for ( int i = 0; i < stringList.size(); ++i ) dir.remove( PathTempLocation().append(QDir::separator() ).append(stringList.at( i ) ) ); // frame rate QString frame = "-r " + QString().number( FrameSpinBox->value() ); // Videocodec QString myVcodec = VideocodecComboBox->currentText(); if ( myVcodec == "libx264" ) { // Number of pixels must be divisible by two int intRecordX = getRecordWidth().toInt(); if ( ( intRecordX % 2 ) == 1 ) setRecordWidth( QString().number( --intRecordX ) ); // Number of pixels must be divisible by two int intRecordY = getRecordHeight().toInt(); if ( ( intRecordY % 2 ) == 1 ) setRecordHeight( QString().number( --intRecordY ) ); myVcodec = "libx264 -preset veryfast"; // Standard //myVcodec = "libx264 -preset medium"; //myVcodec = "libx264 -preset veryslow"; } nameInMoviesLocation = NameInMoviesLocation(); QString quality; if ( ( getFfmpegVersion() < "01.01.00" ) and ( recordApplikation == "ffmpeg" ) ) quality = " -sameq "; else quality = " -qscale 1 "; clickedRecordButtonScreenSize(); ffmpegString = recordApplikation + " " + myReport + myAlsa() + "-f x11grab " + frame + " -s " + getRecordWidth() + "x" + getRecordHeight() + " -i :0.0+" + deltaX + "," + deltaY + noMouse() + " -pix_fmt yuv420p" // Neu das funktioniert sehr gut, ohne ca. 80 fps, mit 99fps bei eingestellten 99fps und preset medium aber nur unter opensuse, unter Ubuntu 13.04 keine Veränderung + " -vcodec " + myVcodec + myAcodec() //+ " -ab 256k " //********************************************Neu //+ " -ar 48000 " //********************************************Neu + " -ar " + mySample() + quality + frame + " "; startRecord( PathTempLocation() + QDir::separator() + nameInMoviesLocation ); QFile FileVokoscreenLog(settingsPath.absolutePath() + QDir::separator() + ProgName + ".log"); if ( !FileVokoscreenLog.open( QIODevice::WriteOnly ) ) qDebug() << "Datei konnte nicht angelegt werden: " << FileVokoscreenLog.errorString(); QTextStream stream( &FileVokoscreenLog ); stream << ProgName << " Version: " << Version << "\n"; stream << "Record resolution: " << getRecordWidth() << "x" << getRecordHeight() << "\n"; stream << "Alsa string: " << myAlsa() << "\n"; stream << "Qt Version: " << qVersion() << "\n"; if ( recordApplikation == "ffmpeg" ) stream << "ffmpeg Version: " << getFfmpegVersion() << "\n"; if ( recordApplikation == "avconv" ) stream << "avconv Version: " << getAvconvVersion() << "\n"; stream << "Record String: " << ffmpegString << PathMoviesLocation() << QDir::separator() << nameInMoviesLocation << "\n"; } void screencast::startRecord( QString RecordPathName ) { qDebug() << "[vokoscreen]"<< "ffmpegcommand :" << ffmpegString + RecordPathName; if ( PulseDeviceRadioButton->isChecked() ) { QProcess Process; QString value = myPulseDevice(); if ( value == "vokoscreenMix.monitor" ) { Process.start("pactl load-module module-null-sink sink_name=vokoscreenMix"); Process.waitForFinished(); QString modulNumber = Process.readAllStandardOutput(); Process.close(); qDebug(); qDebug() << "[vokoscreen] ---Begin Pulse loade module---"; modulNumber.replace("\n", ""); qDebug() << "[vokoscreen] pactl load-module module-null-sink sink_name=vokoscreenMix " << modulNumber; QList listQFrame = Pulseframe->findChildren(); QCheckBox *box; QList integerList; for ( int i = 0; i < listQFrame.count(); i++ ) { box = listQFrame.at( i ); if ( box->checkState() == Qt::Checked ) integerList.append( i ); } for ( int i = 0; i < integerList.count(); i++ ) { box = listQFrame[ integerList[ i ] ]; Process.start("pactl load-module module-loopback source=" + box->accessibleName() + " sink=vokoscreenMix"); Process.waitForFinished(); QString modulNumber = Process.readAllStandardOutput(); modulNumber.replace("\n", ""); Process.close(); qDebug() << "[vokoscreen] pactl load-module module-loopback source=" << box->accessibleName() << "sink=vokoscreenMix number" << modulNumber; } qDebug() << "[vokoscreen] ---End Pulse loade module---"; qDebug(); } if ( value > "" ) { QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); env.insert( "PULSE_SOURCE", value ); SystemCall->setProcessEnvironment( env ); } } SystemCall->start( ffmpegString + RecordPathName ); // Recordtime Statusbar beginTime = QDateTime::currentDateTime(); } void screencast::Stop() { myregionselection->cleanRecordArea( false ); shortcutStart->setEnabled( true ); shortcutStop->setEnabled( false ); if ( SystemCall->state() == QProcess::Running ) { SystemCall->terminate(); SystemCall->waitForFinished(); } if ( pause ) { QString mergeString = "/usr/bin/mkvmerge "; QDir dir( PathTempLocation() ); QStringList stringList = dir.entryList(QDir::Files, QDir::Time | QDir::Reversed); for ( int i = 0; i < stringList.size(); ++i ) if ( i == 0 ) mergeString.append( PathTempLocation() ).append( QDir::separator() ).append( stringList.at( i ) ); else mergeString.append( " + " ).append( PathTempLocation() ).append( QDir::separator() ).append( stringList.at( i ) ); mergeString.append( " -o " ).append( PathMoviesLocation() + QDir::separator() + nameInMoviesLocation ); /* // Unter der Sprache Arabisch funktioniert mkvmerge nicht QProcessEnvironment env = QProcessEnvironment::systemEnvironment();// Test env.insert("LANG", "ro_MD");// Test SystemCall->setProcessEnvironment(env); //Test */ SystemCall->start( mergeString ); SystemCall->waitForFinished(); /* QString mkvAusgabe = SystemCall->readAllStandardOutput(); // Test SystemCall->close(); / Test qDebug() << "*****************Test*****" << mkvAusgabe; /Test */ for ( int i = 0; i < stringList.size(); ++i ) dir.remove( PathTempLocation().append( QDir::separator() ).append( stringList.at( i ) ) ); qDebug() << "[vokoscreen]" << "Mergestring :" << mergeString; } else { QString FileInTemp = PathTempLocation() + QDir::separator() + nameInMoviesLocation; QFile::copy ( FileInTemp, PathMoviesLocation() + QDir::separator() + nameInMoviesLocation ); QFile::remove ( FileInTemp ); } QDir dir; dir.rmdir( PathTempLocation() ); pause = false; windowMoveTimer->stop(); firststartWininfo = false; pulseUnloadModule(); } //#include "screencast.moc" vokoscreen-1.9.0/screencast.h000066400000000000000000000156071227001500100161770ustar00rootroot00000000000000/* vokoscreen - A desktop recorder * Copyright (C) 2011-2013 Volker Kohaupt * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef screencast_H #define screencast_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "regionselection.h" #include "QvkMagnifier.h" #include "QvkWebcamController.h" #include "QvkAlsaDevice.h" #include "QvkMail.h" #include "QvkAlsaWatcher.h" #include "QvkWinInfo.h" #include "QvkCredits.h" #include "QvkVersion.h" #include #include #include class screencast : public QMainWindow { Q_OBJECT public: screencast(); virtual ~screencast(); QString getFfmpegVersion(); QString getAvconvVersion(); QString ProgName; QString Version; QString email; QString homepage; QString ffmpegString; QString nameInMoviesLocation; QString winID; QString deltaXMove; QString deltaYMove; bool pause; QStringList MoveWindowlist; bool firststartWininfo; bool moveWindow; QMainWindow * TestFrame; QString recordApplikation; QvkCredits * credits; public: QvkVersion version; public slots: private slots: void Stop(void); void record(void); void play(); void Countdown(); void PulseMultipleChoice(); void AudioOnOff(); void Pause(); void startRecord( QString RecordPathName ); QString myAlsa(); QString myAcodec(); void searchExternalPrograms(); void preRecord(); const QString myPulseDevice(); int getCountCheckedPulseDevices(); QString getPulseDeviceName( int value ); int getPulseInputDevicesCount(); QCheckBox * getCheckBoxPulseDevice( int value ); QString getPulseInputName( int value ); QString getPulseInputDevices( int value ); QString getPulseSample( int value ); void pulseUnloadModule(); QString mySample(); QString noMouse(); void windowMove(); void moveWindowPause(); void moveWindowGo(); // Tab Videooptionen void setFrameStandardSpinbox(); void setVideocodecStandardComboBox(); QString PathMoviesLocation(); QString PathTempLocation(); QString NameInMoviesLocation(); QString PauseNameInTmpLocation(); void saveVideoPath(); void makeAsoundrc(); bool needProgram( QString ProgName ); void stateChanged( QProcess::ProcessState newState ); void error ( QProcess::ProcessError error ); void readyReadStandardError(); void readyReadStandardOutput(); void saveSettings(); void WindowMinimized(); void stateChangedSystray( int ); void SystemTrayStart( QSystemTrayIcon::ActivationReason ); void SystemTrayStop( QSystemTrayIcon::ActivationReason ); void SystemTrayPause( QSystemTrayIcon::ActivationReason reason ); void SystemTrayGo( QSystemTrayIcon::ActivationReason reason ); void AreaOnOff(); void showMagnifier(); void MagnifierDialog(); void ShortcutPause(); void ShortcutMagnifier(); void uncheckMagnifier(); void send(); void AlsaWatcherEvent( QStringList CardxList ); void myVideoFileSystemWatcher( const QString & path ); void currentIndexChangedCodec( int index ); void currentIndexChangedFormat( int index ); void stateChangedAudio( int state ); void clickedAudioAlsa( bool checked ); void clickedAudioPulse( bool checked ); void valueChangedFrames( int i ); void clickedScreenSize(); void clickedRecordButtonScreenSize(); void setRecordWidth( QString value ); QString getRecordWidth(); void setRecordHeight( QString value ); QString getRecordHeight(); void showCredits(); void creditsCloseEvent(); void showHomepage(); void buttonVersion(); private: QTabWidget *tabWidget; QPushButton *StopButton; QPushButton *recordButton; QProcess *SystemCall; QRadioButton *AlsaRadioButton; QComboBox *AlsaHwComboBox; QCheckBox *AudioOnOffCheckbox; QRadioButton * FullScreenRadioButton; QRadioButton * WindowRadioButton; QRadioButton *AreaRadioButton; QCheckBox *MagnifierCheckBox; QvkWebcamController *webcamCheckBox; QSpinBox * CountdownSpinBox; QLabel *ChannelLabel; QComboBox *VideoplayerComboBox; QPushButton *PlayButton; QPushButton *PauseButton; QFrame *TabWidgetAudioFrame; QLabel *recordTimeLabel; QLineEdit *SaveVideoPathLineEdit; QRadioButton *PulseDeviceRadioButton; QFrame *TabWidgetMiscellaneousFrame; QFrame *TabWidgetVideoOptionFrame; QFrame *TabWidgetSocialFrame; QSpinBox *FrameSpinBox; QComboBox *VideocodecComboBox; QComboBox *VideoContainerComboBox; QCheckBox *HideMouseCheckbox; QCheckBox *MinimizedCheckBox; QTimer *windowMoveTimer; QFrame *Pulseframe; QScrollArea *scrollAreaPulse; QCheckBox *namePulse; QCheckBox *SystrayCheckBox; QSystemTrayIcon *SystemTrayIconGreen; QSystemTrayIcon *SystemTrayIconRed; QSystemTrayIcon *SystemTrayIconYellow; QSystemTrayIcon *SystemTrayIconBlue; QvkMagnifier *magnifier; regionselection *myregionselection; QvkWebcam *webcam; QxtGlobalShortcut *shortcutMagnifier; QxtGlobalShortcut *shortcutPause; QxtGlobalShortcut *shortcutStart; QxtGlobalShortcut *shortcutStop; QvkWinInfo *vkWinInfo; WId moveWindowID; QPushButton *sendPushButton; QList AlsaDeviceList; QLabel * statusBarLabelTime; QLabel * statusBarLabelFps; QLabel * statusBarLabelSize; QLabel * statusBarLabelCodec; QLabel * statusBarLabelFormat; QLabel * statusBarLabelAudio; QLabel * statusBarLabelFpsSettings; QLabel * statusbarLabelScreenSize; QLabel * statusBarProgForRecord; QString screenRecordWidth; QString screenRecordHeight; //int leftFrameBorder; //int topFrameBorder; QDateTime beginTime; QPushButton * creditsQPushButton; QPushButton * updateButton; protected: void closeEvent( QCloseEvent * event ); }; #endif // screencast_H vokoscreen-1.9.0/screencast.qrc000066400000000000000000000032101227001500100165200ustar00rootroot00000000000000 pictures/about.png pictures/community.png pictures/go.png pictures/magnifier.png pictures/micro.png pictures/monitor.png pictures/pause.png pictures/Scroll.png pictures/sem_soc_net.png pictures/start.png pictures/stop.png pictures/system-software-update.png pictures/tools.png pictures/videooptionen.png pictures/VokoCola.png pictures/vokoscreen.png language/vokoscreen_ar.qm language/vokoscreen_ast.qm language/vokoscreen_ca.qm language/vokoscreen_cs_CZ.qm language/vokoscreen_da_DK.qm language/vokoscreen_de_AT.qm language/vokoscreen_de_CH.qm language/vokoscreen_de_DE.qm language/vokoscreen_es_ES.qm language/vokoscreen_es.qm language/vokoscreen_fr_FR.qm language/vokoscreen_hu.qm language/vokoscreen_it_CH.qm language/vokoscreen_it_IT.qm language/vokoscreen_nl_NL.qm language/vokoscreen_pl_PL.qm language/vokoscreen_pt_BR.qm language/vokoscreen_ro_RO.qm language/vokoscreen_ro.qm language/vokoscreen_ru.qm language/vokoscreen_sv_SE.qm language/vokoscreen_tr_TR.qm language/vokoscreen_vi.qm language/vokoscreen_zh_CN.qm language/vokoscreen_zh_TW.qm VERSION vokoscreen-1.9.0/send/000077500000000000000000000000001227001500100146145ustar00rootroot00000000000000vokoscreen-1.9.0/send/QvkMail.cpp000066400000000000000000000067101227001500100166700ustar00rootroot00000000000000 #include "QvkMail.h" using namespace std; QvkMail::QvkMail() { } QvkMail::QvkMail( QWidget *object ) { dialog = new QDialog( object ); dialog->setFixedSize( 450, 200 ); QFont qfont = dialog->font(); qfont.setPixelSize( 12 ); dialog->setFont( qfont ); QLabel* label = new QLabel( dialog ); label->setText(""); label->setGeometry( QRect( 20, 30, 150, 150) ); label->setAlignment( Qt::AlignCenter ); label->show(); QImage* qImage = new QImage( ":pictures/sem_soc_net.png" ); label->setPixmap( QPixmap::fromImage( *qImage, Qt::AutoColor ) ); label->setScaledContents( true ); mailRadioButton = new QRadioButton( dialog ); mailRadioButton->setGeometry( QRect( 200, 60, 200, 21 ) ); mailRadioButton->setText( tr( "Mail last Video" ) ); mailRadioButton->setChecked( true ); mailSelectedRadioButton = new QRadioButton( dialog ); mailSelectedRadioButton->setGeometry( QRect( 200, 90, 300, 21 ) ); mailSelectedRadioButton->setText( tr( "Mail one or more selected Video" ) ); QPushButton * sendPushbutton = new QPushButton( dialog ); sendPushbutton->setGeometry( 200, 170, 80, 30 ); sendPushbutton->setText( tr( "Send" ) ); sendPushbutton->show(); connect( sendPushbutton, SIGNAL( clicked() ), this, SLOT( selection() ) ); dialog->exec(); } QvkMail::~QvkMail() { } void QvkMail::selection() { if ( mailRadioButton->isChecked() ) startMailClientWithLastFile( lastMovie() ); if ( mailSelectedRadioButton->isChecked() ) startMailClientWithSelectedFiles( selectedMail() ); } void QvkMail::startMailClientWithLastFile( QString file ) { if ( file > "" ) { // The body String like not Space QString bodyString = tr( "You find the Video as attachment" ); QString processString = "xdg-email --utf8 --attach " + file + " --body \"" + bodyString + "\""; qDebug() << "[vokoscreen]" << "startMailClientWithLastFile:" << processString; QProcess Process; Process.startDetached( processString ); Process.close(); } dialog->close(); } void QvkMail::startMailClientWithSelectedFiles( QStringList fileList ) { // The body String like not Space QString bodyString = tr( "You find the Video as attachment" ); QString files; for ( int i = 1; i <= fileList.count(); i++ ) { files = files + " --attach "; files = files + fileList[ i - 1 ] ; } if ( not fileList.empty()) { QString processString = "xdg-email --utf8" + files + " --body \"" + bodyString + "\""; qDebug() << "[vokoscreen]" << "startMailClientWithSelectedFiles:" << processString; QProcess Process; Process.startDetached( processString ); Process.close(); } dialog->close(); } QString QvkMail::lastMovie() { QDir dir( QDesktopServices::storageLocation( QDesktopServices::MoviesLocation ) ); QStringList filters; filters << "vokoscreen*"; QStringList List = dir.entryList( filters, QDir::Files, QDir::Time ); if ( List.isEmpty() ) return ""; else return dir.filePath( List.first() ); } QStringList QvkMail::selectedMail() { QString a = QDesktopServices::storageLocation( QDesktopServices::MoviesLocation ); QStringList files = QFileDialog::getOpenFileNames( dialog, tr( "Select one or more files" ), QDesktopServices::storageLocation( QDesktopServices::MoviesLocation ) , "*.*" ); return files; } vokoscreen-1.9.0/send/QvkMail.h000066400000000000000000000012751227001500100163360ustar00rootroot00000000000000#ifndef QvkMail_H #define QvkMail_H #include #include #include #include #include #include #include #include class QvkMail: public QObject { Q_OBJECT public: QvkMail(); virtual ~QvkMail(); QvkMail( QWidget *object ); public slots: private slots: void startMailClientWithLastFile( QString file ); void startMailClientWithSelectedFiles( QStringList fileList ); QString lastMovie(); void selection(); QStringList selectedMail(); signals: protected: private: QDialog * dialog; QRadioButton * mailRadioButton; QRadioButton * mailSelectedRadioButton; }; #endif vokoscreen-1.9.0/send/send.pri000066400000000000000000000001751227001500100162640ustar00rootroot00000000000000INCLUDEPATH += $$PWD DEPENDPATH += $$PWD HEADERS += $$PWD/QvkMail.h SOURCES += $$PWD/QvkMail.cpp vokoscreen-1.9.0/vokoscreen.1000066400000000000000000000021001227001500100161140ustar00rootroot00000000000000'\" t .\" ** The above line should force tbl to be a preprocessor ** .\" Man page for vokoscreen .\" .\" Copyright (C), 2012, Dominique Lasserre .\" .\" You may distribute under the terms of the GNU General Public .\" License as specified in the file COPYING that comes with the main .\" distribution. .\" .TH VOKOSCREEN 1 "2012-12-31" "vokoscreen Manual" .SH NAME vokoscreen \- simple screencast creator .SH SYNOPSIS Usage: \fBvokoscreen\fR .SH DESCRIPTION \fPvokoscreen\fP is an easy to use screencast creator to record educational videos, live recordings of browser, installation, videoconferences, etc. It uses ffgtk functionality and also supports recording of audio (over pulseaudio or alsa). .SH FILES Settings are stored under $XDG_CONFIG_HOME which is generally $HOME/.config. In this documentation ~ is used. .TP .I ~/.config/vokoscreen/vokoscreen.conf Configuration file stores audio settings, standard player, video path. .TP .I ~/.config/vokoscreen/vokoscreen.log Log file stores information about the last execution of vokoscreen. .SH BUGS Report bugs to . vokoscreen-1.9.0/vokoscreen.pro000066400000000000000000000033361227001500100165700ustar00rootroot00000000000000TEMPLATE = app TARGET = vokoscreen # Input HEADERS += screencast.h \ regionselection.h \ QvkMagnifier.h \ QvkWinInfo.h \ QvkCredits.h \ QvkVersion.h SOURCES += main.cpp \ screencast.cpp \ regionselection.cpp \ QvkMagnifier.cpp \ QvkWinInfo.cpp \ QvkCredits.cpp \ QvkVersion.cpp RESOURCES += screencast.qrc TRANSLATIONS = $$files(language/vokoscreen_*.ts) # language packages !isEmpty(TRANSLATIONS) { isEmpty(QMAKE_LRELEASE) { win32:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]\lrelease.exe else:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]/lrelease } isEmpty(TS_DIR):TS_DIR = language TSQM.name = lrelease ${QMAKE_FILE_IN} TSQM.input = TRANSLATIONS TSQM.output = $$TS_DIR/${QMAKE_FILE_BASE}.qm TSQM.commands = $$QMAKE_LRELEASE ${QMAKE_FILE_IN} TSQM.CONFIG = no_link QMAKE_EXTRA_COMPILERS += TSQM PRE_TARGETDEPS += compiler_TSQM_make_all } else:message(No translation files in project) # Install paths image.path = /usr/share/pixmaps image.files += applications/vokoscreen.png desktop.path = /usr/share/applications desktop.files += applications/vokoscreen.desktop man.path = /usr/share man.files += man target.path = /usr/bin INSTALLS += target image desktop man # Clean target QMAKE_CLEAN += $$TARGET */*~ CONFIG += link_pkgconfig # QtSingleApplication include(QtSingleApplication/qtsingleapplication.pri) # libqxt include(libqxt/libqxt.pri) # audio include(audio/audio.pri) PKGCONFIG += alsa # send include(send/send.pri) # webcam include(webcam/webcam.pri) PKGCONFIG += opencv #include(QtZip-src/QtZip.pri) #PKGCONFIG += zlib CONFIG += qtestlib #system( ls ) vokoscreen-1.9.0/webcam/000077500000000000000000000000001227001500100151215ustar00rootroot00000000000000vokoscreen-1.9.0/webcam/CLASSES000066400000000000000000000003551227001500100161440ustar00rootroot00000000000000 Qvkwebcam QvkwebcamWatcher | | --------------------- | | QvkWebcamController | | vokoscreenvokoscreen-1.9.0/webcam/QvkWebcam.cpp000066400000000000000000000171471227001500100175170ustar00rootroot00000000000000#include "QvkWebcam.h" #include "QvkWebcamController.h" using namespace std; QvkWebcam::QvkWebcam() { //qDebug() << "Begin QvkWebcam::QvkWebcam( int deviceNumber ) *****************************"; setWindowTitle( "vokoscreen webcam"); label = new QLabel( this ); label->setAlignment( Qt::AlignCenter ); label->setScaledContents( true ); label->show(); QSettings settings( "vokoscreen", "vokoscreen" ); settings.beginGroup( "Webcam" ); setValueBorder( settings.value( "Border", true ).toBool() ); setValueX( settings.value( "X", 100 ).toUInt() ); setValueY( settings.value( "Y", 100 ).toUInt() ); setValueWidth( settings.value( "Width", 320 ).toUInt() ); setValueHeight( settings.value( "Height", 240 ).toUInt() ); setDeviceNumber( settings.value( "Number", 0 ).toUInt() ); settings.endGroup(); setGeometry( getValueX(), getValueY(), getValueWidth(), getValueHeight() ); } /** * Wird von vokoscreen.cpp -> QvkWebcamController aufgerufen */ void QvkWebcam::saveSettings() { QSettings settings( "vokoscreen", "vokoscreen" ); settings.beginGroup( "Webcam" ); settings.setValue( "Border",getValueBorder() ); settings.setValue( "X", x() ); settings.setValue( "Y", y() ); settings.setValue( "Width", width() ); settings.setValue( "Height", height() ); settings.setValue( "Number", getDeviceNumber() ); settings.endGroup(); } void QvkWebcam::setValueBorder( bool value ) { border = value; } void QvkWebcam::setValueX( int value ) { X = value; } void QvkWebcam::setValueY( int value ) { Y = value; } void QvkWebcam::setValueWidth( int value ) { Width = value; } void QvkWebcam::setValueHeight( int value ) { Height = value; } bool QvkWebcam::getValueBorder() { return border; } int QvkWebcam::getValueX() { return X; } int QvkWebcam::getValueY() { return Y; } int QvkWebcam::getValueWidth() { return Width; } int QvkWebcam::getValueHeight() { return Height; } QvkWebcam::~QvkWebcam() { //qDebug() << "Begin QvkWebcam::~QvkWebcam() *****************************"; //qDebug() << "End QvkWebcam::~QvkWebcam() *****************************"; } /** * closeEvent wird ausgelößt wenn das webcamfenster geschloßen wird */ void QvkWebcam::closeEvent( QCloseEvent * event ) { //qDebug() << "Begin void QvkWebcam::closeEvent( QCloseEvent * event ) *****************************"; (void)event; emit closeWebcam(); //qDebug() << "End void QvkWebcam::closeEvent( QCloseEvent * event ) *****************************"; } void QvkWebcam::moveEvent( QMoveEvent * event ) { //qDebug() << "End void QvkWebcam::moveEvent( QMoveEvent * event ) *****************************"; (void) event; setValueX( x() ); setValueY( y() ); } /** * */ void QvkWebcam::setClose() { //qDebug() << "Begin void QvkWebcam::setClose() *****************************"; killTimer( idTimer ); cvReleaseCapture(&source); //qDebug() << "End void QvkWebcam::setClose() *****************************"; } /** * Wird vom Popupmenue aufgerufen */ void QvkWebcam::closeMenue() { killTimer( idTimer ); cvReleaseCapture(&source); close(); } bool QvkWebcam::isBusy() { source = cvCaptureFromCAM( getDeviceNumber() ); if ( source == NULL ) { cvReleaseCapture(&source); return true; } else { cvReleaseCapture(&source); return false; } } void QvkWebcam::showWebcam() { //qDebug() << "Begin void QvkWebcam::showWebcam() *****************************"; source = cvCaptureFromCAM( getDeviceNumber() ); idTimer = startTimer( 25 ); if ( getValueBorder() ) setBorder(); else setNoBorder(); setGeometry( getValueX(), getValueY(), getValueWidth(), getValueHeight() ); //qDebug() << "End void QvkWebcam::showWebcam() *****************************"; } void QvkWebcam::contextMenuEvent( QContextMenuEvent *event ) { //qDebug() << "Begin void QvkWebcam::contextMenuEvent( QContextMenuEvent *event ) *****************************"; QAction * action160x120 = new QAction( "160 x 120", this ); connect( action160x120, SIGNAL( triggered() ), this, SLOT( set160x120() ) ); QAction * action320x240 = new QAction( "320 x 240", this ); connect( action320x240, SIGNAL( triggered() ), this, SLOT( set320x240() ) ); QAction * action640x480 = new QAction( "640 x 480", this ); connect( action640x480, SIGNAL( triggered() ), this, SLOT( set640x480() ) ); QAction * actionNoBorder = new QAction( tr ( "Noborder" ), this ); connect( actionNoBorder, SIGNAL( triggered() ), this, SLOT( setNoBorder() ) ); QAction * actionBorder = new QAction( tr ( "Border" ), this ); connect( actionBorder, SIGNAL( triggered() ), this, SLOT( setBorder() ) ); QAction * actionClose = new QAction( tr ( "Close" ), this ); connect( actionClose, SIGNAL( triggered() ), this, SLOT( closeMenue() ) ); QMenu menu( this ); menu.addAction( action160x120 ); menu.addAction( action320x240 ); menu.addAction( action640x480 ); menu.addSeparator(); menu.addAction( actionNoBorder ); menu.addAction( actionBorder ); menu.addSeparator(); menu.addAction( actionClose ); menu.exec( event->globalPos() ); } void QvkWebcam::set160x120() { setGeometry( x(), y(), 160, 120 ); setValueWidth( 160 ); setValueHeight( 120 ); } void QvkWebcam::set320x240() { setGeometry( x(), y(), 320, 240 ); setValueWidth( 320 ); setValueHeight( 240 ); } void QvkWebcam::set640x480() { setGeometry( x(), y(), 640, 480 ); setValueWidth( 640 ); setValueHeight( 480 ); } void QvkWebcam::setNoBorder() { setWindowFlags( Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint ); show(); setValueBorder( false ); } void QvkWebcam::setBorder() { setWindowFlags( Qt::WindowTitleHint | Qt::WindowStaysOnTopHint ); show(); setValueBorder( true ); } void QvkWebcam::setDeviceNumber( int value ) { deviceNumber = value; } int QvkWebcam::getDeviceNumber() { return deviceNumber; } void QvkWebcam::resizeEvent ( QResizeEvent * ) { label->setGeometry( 0, 0, this->width(), this->height() ); } void QvkWebcam::timerEvent( QTimerEvent* ) { image = cvQueryFrame( source ); label->setPixmap( QPixmap::fromImage( ConvertImage( image ) ) ); //cvShowImage("Livebild", image); } /* QImage ConvertImage( IplImage *source ) { QImage dummy; if ( source->depth != IPL_DEPTH_8U || source->nChannels != 3 ) return dummy; // Bilddaten übernehmen unsigned char * data = ( unsigned char * ) source->imageData; // QImage mit Originaldaten erstellen QImage ret( data, source->width, source->height, QImage::Format_RGB888 ); // Kanäle (BGR -> RGB) und Format (RGB888 -> RGB32) ändern return ret.rgbSwapped().convertToFormat( QImage::Format_RGB32 ); } */ QImage QvkWebcam::ConvertImage(IplImage *source) { int cvIndex, cvLineStart; QImage ret; if(source->depth != IPL_DEPTH_8U || source->nChannels != 3) return ret; QImage temp(source->width, source->height, QImage::Format_RGB32); ret = temp; cvIndex = 0; cvLineStart = 0; for (int y = 0; y < source->height; y++) { unsigned char red,green,blue; cvIndex = cvLineStart; for (int x = 0; x < source->width; x++) { red = source->imageData[cvIndex+2]; green = source->imageData[cvIndex+1]; blue = source->imageData[cvIndex+0]; ret.setPixel(x,y,qRgb(red, green, blue)); cvIndex += 3; } cvLineStart += source->widthStep; } return ret; } vokoscreen-1.9.0/webcam/QvkWebcam.h000066400000000000000000000030461227001500100171550ustar00rootroot00000000000000#ifndef QvkWebcam_H #define QvkWebcam_H //#include #include #include #include #include #include #include #include #include class QvkWebcam : public QMainWindow { Q_OBJECT public: QvkWebcam(); virtual ~QvkWebcam(); void showWebcam(); int getDeviceNumber(); void setDeviceNumber( int value ); private: QLabel *label; QImage ConvertImage( IplImage *source ); IplImage *image; CvCapture *source; int deviceNumber; int idTimer; bool border; int X; int Y; int Width; int Height; public slots: void setClose(); bool isBusy(); void saveSettings(); private slots: void set160x120(); void set320x240(); void set640x480(); void setNoBorder(); void setBorder(); void closeMenue(); void setValueBorder( bool value ); void setValueX( int value ); void setValueY( int value ); void setValueWidth( int value ); void setValueHeight( int value ); bool getValueBorder(); int getValueX(); int getValueY(); int getValueWidth(); int getValueHeight(); protected: void timerEvent( QTimerEvent* ); void resizeEvent( QResizeEvent * ); // closeEvent wird ausgelößt wenn Videofenster geschloßen wird void closeEvent( QCloseEvent * event ); void contextMenuEvent( QContextMenuEvent *event ); void moveEvent( QMoveEvent * event ); signals: void closeWebcam(); }; #endif vokoscreen-1.9.0/webcam/QvkWebcamController.cpp000066400000000000000000000111021227001500100215440ustar00rootroot00000000000000#include "QvkWebcamController.h" QvkWebcamController::QvkWebcamController( QWidget * value ) { //qDebug() << "Begin QvkWebcamController::QvkWebcamController( QWidget * value ) ***************************"; checkBox = new QCheckBox( value ); checkBox->setText( tr( "Webcam" ) ); checkBox->show(); connect( checkBox, SIGNAL( clicked() ), SLOT( webcam() ) ); comboBoxCount = new QComboBox( value ); comboBoxCount->setGeometry( 250, 40, 40, 21 ); comboBoxCount->setToolTip( tr ( "Select webcam" ) ); comboBoxCount->show(); myWebcamWatcher = new QvkWebcamWatcher(); connect( myWebcamWatcher, SIGNAL( changed( QStringList ) ), this, SLOT( webcamChangedEvent( QStringList ) ) ); connect( myWebcamWatcher, SIGNAL( added( QStringList, QStringList ) ), this, SLOT( webcamAddedEvent( QStringList, QStringList ) ) ); connect( myWebcamWatcher, SIGNAL( removed( QStringList, QString ) ), this, SLOT( webcamRemovedEvent( QStringList, QString ) ) ); myWebcamWatcher->myfileSystemWatcher( "/dev/" ); if ( myWebcamWatcher->getWebcamCount() == 0 ) { checkBox->setEnabled( false ); comboBoxCount->setEnabled( false ); } vkWebcam = new QvkWebcam(); connect( vkWebcam, SIGNAL( closeWebcam() ), this, SLOT( webcamCloseEvent() ) ); //qDebug() << "End QvkWebcamController::QvkWebcamController( QWidget * value ) ***************************"; } QvkWebcamController::~QvkWebcamController( void ) { } void QvkWebcamController::saveSettings() { vkWebcam->saveSettings(); } void QvkWebcamController::setGeometry( int x, int y, int width, int height ) { checkBox->setGeometry( x, y, width, height ); } /** * Wird vom Destruktor von vokoscreen aufgerufen */ void QvkWebcamController::webcamClose() { checkBox->click(); } /** * Wird aufgerufen wenn ein Gerät hinzugefügt wird */ void QvkWebcamController::webcamAddedEvent( QStringList deviceList, QStringList addedDevices ) { (void)deviceList; (void)addedDevices; //qDebug() << "[vokoscreen] webcam added:" << addedDevices; } /** * Wird aufgerufen wenn ein Gerät entfernt wird */ void QvkWebcamController::webcamRemovedEvent( QStringList deviceList, QString removedDevice ) { (void)deviceList; (void)removedDevice; //qDebug() << "[vokoscreen] webcam removed:" << removedDevice; if ( vkWebcam->isVisible() ) vkWebcam->close(); } bool QvkWebcamController::isVisible() { return vkWebcam->isVisible(); } /** * Wird aufgerufen wenn Gerät hinzugefügt oder entfernt wird */ void QvkWebcamController::webcamChangedEvent( QStringList deviceList ) { comboBoxCount->clear(); for( int x = 0; x < myWebcamWatcher->getWebcamCount(); x++ ) { comboBoxCount->addItem( deviceList[x].right( 1 ) ); } if ( deviceList.empty() ) { checkBox->setEnabled( false ); checkBox->setCheckState( Qt::CheckState( Qt::Unchecked ) ); comboBoxCount->setEnabled( false ); } else { checkBox->setEnabled( true ); comboBoxCount->setEnabled( true ); } //qDebug() << "[vokoscreen] changed"; } /** * Wird aufgerufen wenn das Webcam Fenster geschloßen und dabei * das SIGNAL closeWebcam in der Klasse QvkWebcam ausgelösst wird */ void QvkWebcamController::webcamCloseEvent() { //qDebug() << "Begin void QvkWebcamController::webcamCloseEvent() ***************************"; vkWebcam->setClose(); checkBox->setCheckState( Qt::CheckState( Qt::Unchecked ) ); //qDebug() << "End void QvkWebcamController::webcamCloseEvent() ***************************"; comboBoxCount->setEnabled( true ); } /** * Wird aufgerufen wenn die checkbox betätigt wird */ void QvkWebcamController::webcam() { //qDebug() << "Begin void QvkWebcamController::webcam() ***************************"; vkWebcam->setDeviceNumber( comboBoxCount->currentText().toUInt() ); if ( vkWebcam->isVisible() ) { } else if ( vkWebcam->isBusy() ) { QMessageBox msgBox; QString message; message.append( tr( "Device is busy" ) ); msgBox.setText( message ); msgBox.exec(); checkBox->setCheckState( Qt::CheckState( Qt::Unchecked ) ); return; } if ( checkBox->isChecked() ) { comboBoxCount->setEnabled( false ); vkWebcam->setDeviceNumber( comboBoxCount->currentText().toUInt() ); vkWebcam->showWebcam(); vkWebcam->show(); } else { comboBoxCount->setEnabled( true ); vkWebcam->close(); } //qDebug() << "End void QvkWebcamController::webcam() ***************************"; } vokoscreen-1.9.0/webcam/QvkWebcamController.h000066400000000000000000000016511227001500100212210ustar00rootroot00000000000000#ifndef QvkWebcamController_H #define QvkWebcamController_H #include "QvkWebcam.h" #include "QvkWebcamWatcher.h" #include #include #include class QvkWebcamController : public QObject { Q_OBJECT public: QvkWebcamController( QWidget * frame ); virtual ~QvkWebcamController(); QvkWebcamWatcher * myWebcamWatcher; public slots: void webcamChangedEvent( QStringList deviceList ); void webcamAddedEvent( QStringList deviceList, QStringList addedDevices ); void webcamRemovedEvent( QStringList deviceList, QString removedDevice ); void setGeometry( int x, int y, int width, int height); void webcamClose(); bool isVisible(); void saveSettings(); private slots: void webcam(); void webcamCloseEvent(); private: QvkWebcam * vkWebcam; QCheckBox *checkBox; QComboBox *comboBoxCount; protected: }; #endif vokoscreen-1.9.0/webcam/QvkWebcamWatcher.cpp000066400000000000000000000036271227001500100210330ustar00rootroot00000000000000#include "QvkWebcamWatcher.h" #include using namespace std; /** * Die Metohoden werden nur aufgerufen wenn sich in /dev/ was geändert hat */ QvkWebcamWatcher::QvkWebcamWatcher() { webcamCount = 0; QFileSystemWatcher * fileSystemWatcher = new QFileSystemWatcher(); fileSystemWatcher->addPath( "/dev/" ); connect( fileSystemWatcher, SIGNAL( directoryChanged( QString ) ), this, SLOT( myfileSystemWatcher( QString ) ) ); } QvkWebcamWatcher::~QvkWebcamWatcher() { } int QvkWebcamWatcher::getWebcamCount() { return webcamCount; } /** * Return added devices * */ QStringList QvkWebcamWatcher::addedDevices() { QStringList addedList; int x; for ( x = 0; x < deviceList.count(); x++ ) if ( not oldDeviceList.contains( deviceList[ x ] ) ) addedList << deviceList[ x ]; return addedList; } /** * Return removed device */ QString QvkWebcamWatcher::removedDevice() { QStringList removedList; int x; for ( x = 0; x < oldDeviceList.count(); x++ ) { removedList = deviceList.filter( oldDeviceList[ x ] ); if ( removedList.empty() ) break; } return oldDeviceList[ x ]; } void QvkWebcamWatcher::myfileSystemWatcher( QString path ) { QDir dir( path ); QStringList filters; filters << "video*"; deviceList = dir.entryList( filters, QDir::System, QDir::Time ); deviceList.sort(); // removed device if ( deviceList.count() < webcamCount ) { //qDebug() << "removed device:" << removedDevice(); webcamCount = deviceList.count(); emit changed( deviceList ); emit removed( deviceList, removedDevice() ); } // added device if ( deviceList.count() > webcamCount ) { //qDebug() << "added devices:" << addedDevices(); webcamCount = deviceList.count(); emit changed( deviceList ); emit added( deviceList, addedDevices() ); } if ( oldDeviceList.count() != deviceList.count() ) oldDeviceList = deviceList; } vokoscreen-1.9.0/webcam/QvkWebcamWatcher.h000066400000000000000000000012661227001500100204750ustar00rootroot00000000000000#ifndef QvkWebcamWatcher_H #define QvkWebcamWatcher_H #include #include #include class QvkWebcamWatcher: public QObject { Q_OBJECT public: QvkWebcamWatcher(); virtual ~QvkWebcamWatcher(); public slots: void myfileSystemWatcher( QString path ); int getWebcamCount(); private slots: QStringList addedDevices(); QString removedDevice(); signals: void changed( QStringList deviceList ); void removed( QStringList deviceList, QString string ); void added( QStringList deviceList, QStringList stringList ); protected: private: QStringList deviceList; QStringList oldDeviceList; int webcamCount; }; #endif vokoscreen-1.9.0/webcam/webcam.pri000066400000000000000000000005031227001500100170710ustar00rootroot00000000000000INCLUDEPATH += $$PWD DEPENDPATH += $$PWD HEADERS += $$PWD/QvkWebcam.h \ $$PWD/QvkWebcamController.h \ $$PWD/QvkWebcamWatcher.h SOURCES += $$PWD/QvkWebcam.cpp \ $$PWD/QvkWebcamController.cpp \ $$PWD/QvkWebcamWatcher.cpp